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.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 static DecodeStatus decodeRegisterClass(MCInst &Inst, uint64_t RegNo, 50 const unsigned *Regs, unsigned Size) { 51 assert(RegNo < Size && "Invalid register"); 52 RegNo = Regs[RegNo]; 53 if (RegNo == 0) 54 return MCDisassembler::Fail; 55 Inst.addOperand(MCOperand::createReg(RegNo)); 56 return MCDisassembler::Success; 57 } 58 59 static DecodeStatus DecodeGR32BitRegisterClass(MCInst &Inst, uint64_t RegNo, 60 uint64_t Address, 61 const void *Decoder) { 62 return decodeRegisterClass(Inst, RegNo, SystemZMC::GR32Regs, 16); 63 } 64 65 static DecodeStatus DecodeGRH32BitRegisterClass(MCInst &Inst, uint64_t RegNo, 66 uint64_t Address, 67 const void *Decoder) { 68 return decodeRegisterClass(Inst, RegNo, SystemZMC::GRH32Regs, 16); 69 } 70 71 static DecodeStatus DecodeGR64BitRegisterClass(MCInst &Inst, uint64_t RegNo, 72 uint64_t Address, 73 const void *Decoder) { 74 return decodeRegisterClass(Inst, RegNo, SystemZMC::GR64Regs, 16); 75 } 76 77 static DecodeStatus DecodeGR128BitRegisterClass(MCInst &Inst, uint64_t RegNo, 78 uint64_t Address, 79 const void *Decoder) { 80 return decodeRegisterClass(Inst, RegNo, SystemZMC::GR128Regs, 16); 81 } 82 83 static DecodeStatus DecodeADDR64BitRegisterClass(MCInst &Inst, uint64_t RegNo, 84 uint64_t Address, 85 const void *Decoder) { 86 return decodeRegisterClass(Inst, RegNo, SystemZMC::GR64Regs, 16); 87 } 88 89 static DecodeStatus DecodeFP32BitRegisterClass(MCInst &Inst, uint64_t RegNo, 90 uint64_t Address, 91 const void *Decoder) { 92 return decodeRegisterClass(Inst, RegNo, SystemZMC::FP32Regs, 16); 93 } 94 95 static DecodeStatus DecodeFP64BitRegisterClass(MCInst &Inst, uint64_t RegNo, 96 uint64_t Address, 97 const void *Decoder) { 98 return decodeRegisterClass(Inst, RegNo, SystemZMC::FP64Regs, 16); 99 } 100 101 static DecodeStatus DecodeFP128BitRegisterClass(MCInst &Inst, uint64_t RegNo, 102 uint64_t Address, 103 const void *Decoder) { 104 return decodeRegisterClass(Inst, RegNo, SystemZMC::FP128Regs, 16); 105 } 106 107 static DecodeStatus DecodeVR32BitRegisterClass(MCInst &Inst, uint64_t RegNo, 108 uint64_t Address, 109 const void *Decoder) { 110 return decodeRegisterClass(Inst, RegNo, SystemZMC::VR32Regs, 32); 111 } 112 113 static DecodeStatus DecodeVR64BitRegisterClass(MCInst &Inst, uint64_t RegNo, 114 uint64_t Address, 115 const void *Decoder) { 116 return decodeRegisterClass(Inst, RegNo, SystemZMC::VR64Regs, 32); 117 } 118 119 static DecodeStatus DecodeVR128BitRegisterClass(MCInst &Inst, uint64_t RegNo, 120 uint64_t Address, 121 const void *Decoder) { 122 return decodeRegisterClass(Inst, RegNo, SystemZMC::VR128Regs, 32); 123 } 124 125 template<unsigned N> 126 static DecodeStatus decodeUImmOperand(MCInst &Inst, uint64_t Imm) { 127 if (!isUInt<N>(Imm)) 128 return MCDisassembler::Fail; 129 Inst.addOperand(MCOperand::createImm(Imm)); 130 return MCDisassembler::Success; 131 } 132 133 template<unsigned N> 134 static DecodeStatus decodeSImmOperand(MCInst &Inst, uint64_t Imm) { 135 if (!isUInt<N>(Imm)) 136 return MCDisassembler::Fail; 137 Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm))); 138 return MCDisassembler::Success; 139 } 140 141 static DecodeStatus decodeAccessRegOperand(MCInst &Inst, uint64_t Imm, 142 uint64_t Address, 143 const void *Decoder) { 144 return decodeUImmOperand<4>(Inst, Imm); 145 } 146 147 static DecodeStatus decodeU1ImmOperand(MCInst &Inst, uint64_t Imm, 148 uint64_t Address, const void *Decoder) { 149 return decodeUImmOperand<1>(Inst, Imm); 150 } 151 152 static DecodeStatus decodeU2ImmOperand(MCInst &Inst, uint64_t Imm, 153 uint64_t Address, const void *Decoder) { 154 return decodeUImmOperand<2>(Inst, Imm); 155 } 156 157 static DecodeStatus decodeU3ImmOperand(MCInst &Inst, uint64_t Imm, 158 uint64_t Address, const void *Decoder) { 159 return decodeUImmOperand<3>(Inst, Imm); 160 } 161 162 static DecodeStatus decodeU4ImmOperand(MCInst &Inst, uint64_t Imm, 163 uint64_t Address, const void *Decoder) { 164 return decodeUImmOperand<4>(Inst, Imm); 165 } 166 167 static DecodeStatus decodeU6ImmOperand(MCInst &Inst, uint64_t Imm, 168 uint64_t Address, const void *Decoder) { 169 return decodeUImmOperand<6>(Inst, Imm); 170 } 171 172 static DecodeStatus decodeU8ImmOperand(MCInst &Inst, uint64_t Imm, 173 uint64_t Address, const void *Decoder) { 174 return decodeUImmOperand<8>(Inst, Imm); 175 } 176 177 static DecodeStatus decodeU12ImmOperand(MCInst &Inst, uint64_t Imm, 178 uint64_t Address, const void *Decoder) { 179 return decodeUImmOperand<12>(Inst, Imm); 180 } 181 182 static DecodeStatus decodeU16ImmOperand(MCInst &Inst, uint64_t Imm, 183 uint64_t Address, const void *Decoder) { 184 return decodeUImmOperand<16>(Inst, Imm); 185 } 186 187 static DecodeStatus decodeU32ImmOperand(MCInst &Inst, uint64_t Imm, 188 uint64_t Address, const void *Decoder) { 189 return decodeUImmOperand<32>(Inst, Imm); 190 } 191 192 static DecodeStatus decodeS8ImmOperand(MCInst &Inst, uint64_t Imm, 193 uint64_t Address, const void *Decoder) { 194 return decodeSImmOperand<8>(Inst, Imm); 195 } 196 197 static DecodeStatus decodeS16ImmOperand(MCInst &Inst, uint64_t Imm, 198 uint64_t Address, const void *Decoder) { 199 return decodeSImmOperand<16>(Inst, Imm); 200 } 201 202 static DecodeStatus decodeS32ImmOperand(MCInst &Inst, uint64_t Imm, 203 uint64_t Address, const void *Decoder) { 204 return decodeSImmOperand<32>(Inst, Imm); 205 } 206 207 template<unsigned N> 208 static DecodeStatus decodePCDBLOperand(MCInst &Inst, uint64_t Imm, 209 uint64_t Address) { 210 assert(isUInt<N>(Imm) && "Invalid PC-relative offset"); 211 Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm) * 2 + Address)); 212 return MCDisassembler::Success; 213 } 214 215 static DecodeStatus decodePC16DBLOperand(MCInst &Inst, uint64_t Imm, 216 uint64_t Address, 217 const void *Decoder) { 218 return decodePCDBLOperand<16>(Inst, Imm, Address); 219 } 220 221 static DecodeStatus decodePC32DBLOperand(MCInst &Inst, uint64_t Imm, 222 uint64_t Address, 223 const void *Decoder) { 224 return decodePCDBLOperand<32>(Inst, Imm, Address); 225 } 226 227 static DecodeStatus decodeBDAddr12Operand(MCInst &Inst, uint64_t Field, 228 const unsigned *Regs) { 229 uint64_t Base = Field >> 12; 230 uint64_t Disp = Field & 0xfff; 231 assert(Base < 16 && "Invalid BDAddr12"); 232 Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base])); 233 Inst.addOperand(MCOperand::createImm(Disp)); 234 return MCDisassembler::Success; 235 } 236 237 static DecodeStatus decodeBDAddr20Operand(MCInst &Inst, uint64_t Field, 238 const unsigned *Regs) { 239 uint64_t Base = Field >> 20; 240 uint64_t Disp = ((Field << 12) & 0xff000) | ((Field >> 8) & 0xfff); 241 assert(Base < 16 && "Invalid BDAddr20"); 242 Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base])); 243 Inst.addOperand(MCOperand::createImm(SignExtend64<20>(Disp))); 244 return MCDisassembler::Success; 245 } 246 247 static DecodeStatus decodeBDXAddr12Operand(MCInst &Inst, uint64_t Field, 248 const unsigned *Regs) { 249 uint64_t Index = Field >> 16; 250 uint64_t Base = (Field >> 12) & 0xf; 251 uint64_t Disp = Field & 0xfff; 252 assert(Index < 16 && "Invalid BDXAddr12"); 253 Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base])); 254 Inst.addOperand(MCOperand::createImm(Disp)); 255 Inst.addOperand(MCOperand::createReg(Index == 0 ? 0 : Regs[Index])); 256 return MCDisassembler::Success; 257 } 258 259 static DecodeStatus decodeBDXAddr20Operand(MCInst &Inst, uint64_t Field, 260 const unsigned *Regs) { 261 uint64_t Index = Field >> 24; 262 uint64_t Base = (Field >> 20) & 0xf; 263 uint64_t Disp = ((Field & 0xfff00) >> 8) | ((Field & 0xff) << 12); 264 assert(Index < 16 && "Invalid BDXAddr20"); 265 Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base])); 266 Inst.addOperand(MCOperand::createImm(SignExtend64<20>(Disp))); 267 Inst.addOperand(MCOperand::createReg(Index == 0 ? 0 : Regs[Index])); 268 return MCDisassembler::Success; 269 } 270 271 static DecodeStatus decodeBDLAddr12Len8Operand(MCInst &Inst, uint64_t Field, 272 const unsigned *Regs) { 273 uint64_t Length = Field >> 16; 274 uint64_t Base = (Field >> 12) & 0xf; 275 uint64_t Disp = Field & 0xfff; 276 assert(Length < 256 && "Invalid BDLAddr12Len8"); 277 Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base])); 278 Inst.addOperand(MCOperand::createImm(Disp)); 279 Inst.addOperand(MCOperand::createImm(Length + 1)); 280 return MCDisassembler::Success; 281 } 282 283 static DecodeStatus decodeBDVAddr12Operand(MCInst &Inst, uint64_t Field, 284 const unsigned *Regs) { 285 uint64_t Index = Field >> 16; 286 uint64_t Base = (Field >> 12) & 0xf; 287 uint64_t Disp = Field & 0xfff; 288 assert(Index < 32 && "Invalid BDVAddr12"); 289 Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base])); 290 Inst.addOperand(MCOperand::createImm(Disp)); 291 Inst.addOperand(MCOperand::createReg(SystemZMC::VR128Regs[Index])); 292 return MCDisassembler::Success; 293 } 294 295 static DecodeStatus decodeBDAddr32Disp12Operand(MCInst &Inst, uint64_t Field, 296 uint64_t Address, 297 const void *Decoder) { 298 return decodeBDAddr12Operand(Inst, Field, SystemZMC::GR32Regs); 299 } 300 301 static DecodeStatus decodeBDAddr32Disp20Operand(MCInst &Inst, uint64_t Field, 302 uint64_t Address, 303 const void *Decoder) { 304 return decodeBDAddr20Operand(Inst, Field, SystemZMC::GR32Regs); 305 } 306 307 static DecodeStatus decodeBDAddr64Disp12Operand(MCInst &Inst, uint64_t Field, 308 uint64_t Address, 309 const void *Decoder) { 310 return decodeBDAddr12Operand(Inst, Field, SystemZMC::GR64Regs); 311 } 312 313 static DecodeStatus decodeBDAddr64Disp20Operand(MCInst &Inst, uint64_t Field, 314 uint64_t Address, 315 const void *Decoder) { 316 return decodeBDAddr20Operand(Inst, Field, SystemZMC::GR64Regs); 317 } 318 319 static DecodeStatus decodeBDXAddr64Disp12Operand(MCInst &Inst, uint64_t Field, 320 uint64_t Address, 321 const void *Decoder) { 322 return decodeBDXAddr12Operand(Inst, Field, SystemZMC::GR64Regs); 323 } 324 325 static DecodeStatus decodeBDXAddr64Disp20Operand(MCInst &Inst, uint64_t Field, 326 uint64_t Address, 327 const void *Decoder) { 328 return decodeBDXAddr20Operand(Inst, Field, SystemZMC::GR64Regs); 329 } 330 331 static DecodeStatus decodeBDLAddr64Disp12Len8Operand(MCInst &Inst, 332 uint64_t Field, 333 uint64_t Address, 334 const void *Decoder) { 335 return decodeBDLAddr12Len8Operand(Inst, Field, SystemZMC::GR64Regs); 336 } 337 338 static DecodeStatus decodeBDVAddr64Disp12Operand(MCInst &Inst, uint64_t Field, 339 uint64_t Address, 340 const void *Decoder) { 341 return decodeBDVAddr12Operand(Inst, Field, SystemZMC::GR64Regs); 342 } 343 344 #include "SystemZGenDisassemblerTables.inc" 345 346 DecodeStatus SystemZDisassembler::getInstruction(MCInst &MI, uint64_t &Size, 347 ArrayRef<uint8_t> Bytes, 348 uint64_t Address, 349 raw_ostream &OS, 350 raw_ostream &CS) const { 351 // Get the first two bytes of the instruction. 352 Size = 0; 353 if (Bytes.size() < 2) 354 return MCDisassembler::Fail; 355 356 // The top 2 bits of the first byte specify the size. 357 const uint8_t *Table; 358 if (Bytes[0] < 0x40) { 359 Size = 2; 360 Table = DecoderTable16; 361 } else if (Bytes[0] < 0xc0) { 362 Size = 4; 363 Table = DecoderTable32; 364 } else { 365 Size = 6; 366 Table = DecoderTable48; 367 } 368 369 // Read any remaining bytes. 370 if (Bytes.size() < Size) 371 return MCDisassembler::Fail; 372 373 // Construct the instruction. 374 uint64_t Inst = 0; 375 for (uint64_t I = 0; I < Size; ++I) 376 Inst = (Inst << 8) | Bytes[I]; 377 378 return decodeInstruction(Table, MI, Inst, Address, this, STI); 379 } 380