1 //===-- SystemZDisassembler.cpp - Disassembler for SystemZ ------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "SystemZ.h" 11 #include "llvm/MC/MCDisassembler/MCDisassembler.h" 12 #include "llvm/MC/MCFixedLenDisassembler.h" 13 #include "llvm/MC/MCInst.h" 14 #include "llvm/MC/MCSubtargetInfo.h" 15 #include "llvm/Support/TargetRegistry.h" 16 17 using namespace llvm; 18 19 #define DEBUG_TYPE "systemz-disassembler" 20 21 typedef MCDisassembler::DecodeStatus DecodeStatus; 22 23 namespace { 24 class SystemZDisassembler : public MCDisassembler { 25 public: 26 SystemZDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx) 27 : MCDisassembler(STI, Ctx) {} 28 ~SystemZDisassembler() override {} 29 30 DecodeStatus getInstruction(MCInst &instr, uint64_t &Size, 31 ArrayRef<uint8_t> Bytes, uint64_t Address, 32 raw_ostream &VStream, 33 raw_ostream &CStream) const override; 34 }; 35 } // end anonymous namespace 36 37 static MCDisassembler *createSystemZDisassembler(const Target &T, 38 const MCSubtargetInfo &STI, 39 MCContext &Ctx) { 40 return new SystemZDisassembler(STI, Ctx); 41 } 42 43 extern "C" void LLVMInitializeSystemZDisassembler() { 44 // Register the disassembler. 45 TargetRegistry::RegisterMCDisassembler(TheSystemZTarget, 46 createSystemZDisassembler); 47 } 48 49 /// tryAddingSymbolicOperand - trys to add a symbolic operand in place of the 50 /// immediate Value in the MCInst. 51 /// 52 /// @param Value - The immediate Value, has had any PC adjustment made by 53 /// the caller. 54 /// @param isBranch - If the instruction is a branch instruction 55 /// @param Address - The starting address of the instruction 56 /// @param Offset - The byte offset to this immediate in the instruction 57 /// @param Width - The byte width of this immediate in the instruction 58 /// 59 /// If the getOpInfo() function was set when setupForSymbolicDisassembly() was 60 /// called then that function is called to get any symbolic information for the 61 /// immediate in the instruction using the Address, Offset and Width. If that 62 /// returns non-zero then the symbolic information it returns is used to create 63 /// an MCExpr and that is added as an operand to the MCInst. If getOpInfo() 64 /// returns zero and isBranch is true then a symbol look up for immediate Value 65 /// is done and if a symbol is found an MCExpr is created with that, else 66 /// an MCExpr with the immediate Value is created. This function returns true 67 /// if it adds an operand to the MCInst and false otherwise. 68 static bool tryAddingSymbolicOperand(int64_t Value, bool isBranch, 69 uint64_t Address, uint64_t Offset, 70 uint64_t Width, MCInst &MI, 71 const void *Decoder) { 72 const MCDisassembler *Dis = static_cast<const MCDisassembler*>(Decoder); 73 return Dis->tryAddingSymbolicOperand(MI, Value, Address, isBranch, 74 Offset, Width); 75 } 76 77 static DecodeStatus decodeRegisterClass(MCInst &Inst, uint64_t RegNo, 78 const unsigned *Regs, unsigned Size) { 79 assert(RegNo < Size && "Invalid register"); 80 RegNo = Regs[RegNo]; 81 if (RegNo == 0) 82 return MCDisassembler::Fail; 83 Inst.addOperand(MCOperand::createReg(RegNo)); 84 return MCDisassembler::Success; 85 } 86 87 static DecodeStatus DecodeGR32BitRegisterClass(MCInst &Inst, uint64_t RegNo, 88 uint64_t Address, 89 const void *Decoder) { 90 return decodeRegisterClass(Inst, RegNo, SystemZMC::GR32Regs, 16); 91 } 92 93 static DecodeStatus DecodeGRH32BitRegisterClass(MCInst &Inst, uint64_t RegNo, 94 uint64_t Address, 95 const void *Decoder) { 96 return decodeRegisterClass(Inst, RegNo, SystemZMC::GRH32Regs, 16); 97 } 98 99 static DecodeStatus DecodeGR64BitRegisterClass(MCInst &Inst, uint64_t RegNo, 100 uint64_t Address, 101 const void *Decoder) { 102 return decodeRegisterClass(Inst, RegNo, SystemZMC::GR64Regs, 16); 103 } 104 105 static DecodeStatus DecodeGR128BitRegisterClass(MCInst &Inst, uint64_t RegNo, 106 uint64_t Address, 107 const void *Decoder) { 108 return decodeRegisterClass(Inst, RegNo, SystemZMC::GR128Regs, 16); 109 } 110 111 static DecodeStatus DecodeADDR64BitRegisterClass(MCInst &Inst, uint64_t RegNo, 112 uint64_t Address, 113 const void *Decoder) { 114 return decodeRegisterClass(Inst, RegNo, SystemZMC::GR64Regs, 16); 115 } 116 117 static DecodeStatus DecodeFP32BitRegisterClass(MCInst &Inst, uint64_t RegNo, 118 uint64_t Address, 119 const void *Decoder) { 120 return decodeRegisterClass(Inst, RegNo, SystemZMC::FP32Regs, 16); 121 } 122 123 static DecodeStatus DecodeFP64BitRegisterClass(MCInst &Inst, uint64_t RegNo, 124 uint64_t Address, 125 const void *Decoder) { 126 return decodeRegisterClass(Inst, RegNo, SystemZMC::FP64Regs, 16); 127 } 128 129 static DecodeStatus DecodeFP128BitRegisterClass(MCInst &Inst, uint64_t RegNo, 130 uint64_t Address, 131 const void *Decoder) { 132 return decodeRegisterClass(Inst, RegNo, SystemZMC::FP128Regs, 16); 133 } 134 135 static DecodeStatus DecodeVR32BitRegisterClass(MCInst &Inst, uint64_t RegNo, 136 uint64_t Address, 137 const void *Decoder) { 138 return decodeRegisterClass(Inst, RegNo, SystemZMC::VR32Regs, 32); 139 } 140 141 static DecodeStatus DecodeVR64BitRegisterClass(MCInst &Inst, uint64_t RegNo, 142 uint64_t Address, 143 const void *Decoder) { 144 return decodeRegisterClass(Inst, RegNo, SystemZMC::VR64Regs, 32); 145 } 146 147 static DecodeStatus DecodeVR128BitRegisterClass(MCInst &Inst, uint64_t RegNo, 148 uint64_t Address, 149 const void *Decoder) { 150 return decodeRegisterClass(Inst, RegNo, SystemZMC::VR128Regs, 32); 151 } 152 153 template<unsigned N> 154 static DecodeStatus decodeUImmOperand(MCInst &Inst, uint64_t Imm) { 155 if (!isUInt<N>(Imm)) 156 return MCDisassembler::Fail; 157 Inst.addOperand(MCOperand::createImm(Imm)); 158 return MCDisassembler::Success; 159 } 160 161 template<unsigned N> 162 static DecodeStatus decodeSImmOperand(MCInst &Inst, uint64_t Imm) { 163 if (!isUInt<N>(Imm)) 164 return MCDisassembler::Fail; 165 Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm))); 166 return MCDisassembler::Success; 167 } 168 169 static DecodeStatus decodeAccessRegOperand(MCInst &Inst, uint64_t Imm, 170 uint64_t Address, 171 const void *Decoder) { 172 return decodeUImmOperand<4>(Inst, Imm); 173 } 174 175 static DecodeStatus decodeU1ImmOperand(MCInst &Inst, uint64_t Imm, 176 uint64_t Address, const void *Decoder) { 177 return decodeUImmOperand<1>(Inst, Imm); 178 } 179 180 static DecodeStatus decodeU2ImmOperand(MCInst &Inst, uint64_t Imm, 181 uint64_t Address, const void *Decoder) { 182 return decodeUImmOperand<2>(Inst, Imm); 183 } 184 185 static DecodeStatus decodeU3ImmOperand(MCInst &Inst, uint64_t Imm, 186 uint64_t Address, const void *Decoder) { 187 return decodeUImmOperand<3>(Inst, Imm); 188 } 189 190 static DecodeStatus decodeU4ImmOperand(MCInst &Inst, uint64_t Imm, 191 uint64_t Address, const void *Decoder) { 192 return decodeUImmOperand<4>(Inst, Imm); 193 } 194 195 static DecodeStatus decodeU6ImmOperand(MCInst &Inst, uint64_t Imm, 196 uint64_t Address, const void *Decoder) { 197 return decodeUImmOperand<6>(Inst, Imm); 198 } 199 200 static DecodeStatus decodeU8ImmOperand(MCInst &Inst, uint64_t Imm, 201 uint64_t Address, const void *Decoder) { 202 return decodeUImmOperand<8>(Inst, Imm); 203 } 204 205 static DecodeStatus decodeU12ImmOperand(MCInst &Inst, uint64_t Imm, 206 uint64_t Address, const void *Decoder) { 207 return decodeUImmOperand<12>(Inst, Imm); 208 } 209 210 static DecodeStatus decodeU16ImmOperand(MCInst &Inst, uint64_t Imm, 211 uint64_t Address, const void *Decoder) { 212 return decodeUImmOperand<16>(Inst, Imm); 213 } 214 215 static DecodeStatus decodeU32ImmOperand(MCInst &Inst, uint64_t Imm, 216 uint64_t Address, const void *Decoder) { 217 return decodeUImmOperand<32>(Inst, Imm); 218 } 219 220 static DecodeStatus decodeS8ImmOperand(MCInst &Inst, uint64_t Imm, 221 uint64_t Address, const void *Decoder) { 222 return decodeSImmOperand<8>(Inst, Imm); 223 } 224 225 static DecodeStatus decodeS16ImmOperand(MCInst &Inst, uint64_t Imm, 226 uint64_t Address, const void *Decoder) { 227 return decodeSImmOperand<16>(Inst, Imm); 228 } 229 230 static DecodeStatus decodeS32ImmOperand(MCInst &Inst, uint64_t Imm, 231 uint64_t Address, const void *Decoder) { 232 return decodeSImmOperand<32>(Inst, Imm); 233 } 234 235 template<unsigned N> 236 static DecodeStatus decodePCDBLOperand(MCInst &Inst, uint64_t Imm, 237 uint64_t Address, 238 bool isBranch, 239 const void *Decoder) { 240 assert(isUInt<N>(Imm) && "Invalid PC-relative offset"); 241 uint64_t Value = SignExtend64<N>(Imm) * 2 + Address; 242 243 if (!tryAddingSymbolicOperand(Value, isBranch, Address, 2, N / 8, 244 Inst, Decoder)) 245 Inst.addOperand(MCOperand::createImm(Value)); 246 247 return MCDisassembler::Success; 248 } 249 250 static DecodeStatus decodePC16DBLBranchOperand(MCInst &Inst, uint64_t Imm, 251 uint64_t Address, 252 const void *Decoder) { 253 return decodePCDBLOperand<16>(Inst, Imm, Address, true, Decoder); 254 } 255 256 static DecodeStatus decodePC32DBLBranchOperand(MCInst &Inst, uint64_t Imm, 257 uint64_t Address, 258 const void *Decoder) { 259 return decodePCDBLOperand<32>(Inst, Imm, Address, true, Decoder); 260 } 261 262 static DecodeStatus decodePC32DBLOperand(MCInst &Inst, uint64_t Imm, 263 uint64_t Address, 264 const void *Decoder) { 265 return decodePCDBLOperand<32>(Inst, Imm, Address, false, Decoder); 266 } 267 268 static DecodeStatus decodeBDAddr12Operand(MCInst &Inst, uint64_t Field, 269 const unsigned *Regs) { 270 uint64_t Base = Field >> 12; 271 uint64_t Disp = Field & 0xfff; 272 assert(Base < 16 && "Invalid BDAddr12"); 273 Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base])); 274 Inst.addOperand(MCOperand::createImm(Disp)); 275 return MCDisassembler::Success; 276 } 277 278 static DecodeStatus decodeBDAddr20Operand(MCInst &Inst, uint64_t Field, 279 const unsigned *Regs) { 280 uint64_t Base = Field >> 20; 281 uint64_t Disp = ((Field << 12) & 0xff000) | ((Field >> 8) & 0xfff); 282 assert(Base < 16 && "Invalid BDAddr20"); 283 Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base])); 284 Inst.addOperand(MCOperand::createImm(SignExtend64<20>(Disp))); 285 return MCDisassembler::Success; 286 } 287 288 static DecodeStatus decodeBDXAddr12Operand(MCInst &Inst, uint64_t Field, 289 const unsigned *Regs) { 290 uint64_t Index = Field >> 16; 291 uint64_t Base = (Field >> 12) & 0xf; 292 uint64_t Disp = Field & 0xfff; 293 assert(Index < 16 && "Invalid BDXAddr12"); 294 Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base])); 295 Inst.addOperand(MCOperand::createImm(Disp)); 296 Inst.addOperand(MCOperand::createReg(Index == 0 ? 0 : Regs[Index])); 297 return MCDisassembler::Success; 298 } 299 300 static DecodeStatus decodeBDXAddr20Operand(MCInst &Inst, uint64_t Field, 301 const unsigned *Regs) { 302 uint64_t Index = Field >> 24; 303 uint64_t Base = (Field >> 20) & 0xf; 304 uint64_t Disp = ((Field & 0xfff00) >> 8) | ((Field & 0xff) << 12); 305 assert(Index < 16 && "Invalid BDXAddr20"); 306 Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base])); 307 Inst.addOperand(MCOperand::createImm(SignExtend64<20>(Disp))); 308 Inst.addOperand(MCOperand::createReg(Index == 0 ? 0 : Regs[Index])); 309 return MCDisassembler::Success; 310 } 311 312 static DecodeStatus decodeBDLAddr12Len8Operand(MCInst &Inst, uint64_t Field, 313 const unsigned *Regs) { 314 uint64_t Length = Field >> 16; 315 uint64_t Base = (Field >> 12) & 0xf; 316 uint64_t Disp = Field & 0xfff; 317 assert(Length < 256 && "Invalid BDLAddr12Len8"); 318 Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base])); 319 Inst.addOperand(MCOperand::createImm(Disp)); 320 Inst.addOperand(MCOperand::createImm(Length + 1)); 321 return MCDisassembler::Success; 322 } 323 324 static DecodeStatus decodeBDVAddr12Operand(MCInst &Inst, uint64_t Field, 325 const unsigned *Regs) { 326 uint64_t Index = Field >> 16; 327 uint64_t Base = (Field >> 12) & 0xf; 328 uint64_t Disp = Field & 0xfff; 329 assert(Index < 32 && "Invalid BDVAddr12"); 330 Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base])); 331 Inst.addOperand(MCOperand::createImm(Disp)); 332 Inst.addOperand(MCOperand::createReg(SystemZMC::VR128Regs[Index])); 333 return MCDisassembler::Success; 334 } 335 336 static DecodeStatus decodeBDAddr32Disp12Operand(MCInst &Inst, uint64_t Field, 337 uint64_t Address, 338 const void *Decoder) { 339 return decodeBDAddr12Operand(Inst, Field, SystemZMC::GR32Regs); 340 } 341 342 static DecodeStatus decodeBDAddr32Disp20Operand(MCInst &Inst, uint64_t Field, 343 uint64_t Address, 344 const void *Decoder) { 345 return decodeBDAddr20Operand(Inst, Field, SystemZMC::GR32Regs); 346 } 347 348 static DecodeStatus decodeBDAddr64Disp12Operand(MCInst &Inst, uint64_t Field, 349 uint64_t Address, 350 const void *Decoder) { 351 return decodeBDAddr12Operand(Inst, Field, SystemZMC::GR64Regs); 352 } 353 354 static DecodeStatus decodeBDAddr64Disp20Operand(MCInst &Inst, uint64_t Field, 355 uint64_t Address, 356 const void *Decoder) { 357 return decodeBDAddr20Operand(Inst, Field, SystemZMC::GR64Regs); 358 } 359 360 static DecodeStatus decodeBDXAddr64Disp12Operand(MCInst &Inst, uint64_t Field, 361 uint64_t Address, 362 const void *Decoder) { 363 return decodeBDXAddr12Operand(Inst, Field, SystemZMC::GR64Regs); 364 } 365 366 static DecodeStatus decodeBDXAddr64Disp20Operand(MCInst &Inst, uint64_t Field, 367 uint64_t Address, 368 const void *Decoder) { 369 return decodeBDXAddr20Operand(Inst, Field, SystemZMC::GR64Regs); 370 } 371 372 static DecodeStatus decodeBDLAddr64Disp12Len8Operand(MCInst &Inst, 373 uint64_t Field, 374 uint64_t Address, 375 const void *Decoder) { 376 return decodeBDLAddr12Len8Operand(Inst, Field, SystemZMC::GR64Regs); 377 } 378 379 static DecodeStatus decodeBDVAddr64Disp12Operand(MCInst &Inst, uint64_t Field, 380 uint64_t Address, 381 const void *Decoder) { 382 return decodeBDVAddr12Operand(Inst, Field, SystemZMC::GR64Regs); 383 } 384 385 #include "SystemZGenDisassemblerTables.inc" 386 387 DecodeStatus SystemZDisassembler::getInstruction(MCInst &MI, uint64_t &Size, 388 ArrayRef<uint8_t> Bytes, 389 uint64_t Address, 390 raw_ostream &OS, 391 raw_ostream &CS) const { 392 // Get the first two bytes of the instruction. 393 Size = 0; 394 if (Bytes.size() < 2) 395 return MCDisassembler::Fail; 396 397 // The top 2 bits of the first byte specify the size. 398 const uint8_t *Table; 399 if (Bytes[0] < 0x40) { 400 Size = 2; 401 Table = DecoderTable16; 402 } else if (Bytes[0] < 0xc0) { 403 Size = 4; 404 Table = DecoderTable32; 405 } else { 406 Size = 6; 407 Table = DecoderTable48; 408 } 409 410 // Read any remaining bytes. 411 if (Bytes.size() < Size) 412 return MCDisassembler::Fail; 413 414 // Construct the instruction. 415 uint64_t Inst = 0; 416 for (uint64_t I = 0; I < Size; ++I) 417 Inst = (Inst << 8) | Bytes[I]; 418 419 return decodeInstruction(Table, MI, Inst, Address, this, STI); 420 } 421