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) { 51 assert(RegNo < 16 && "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); 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); 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); 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); 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); 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); 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); 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); 105 } 106 107 template<unsigned N> 108 static DecodeStatus decodeUImmOperand(MCInst &Inst, uint64_t Imm) { 109 assert(isUInt<N>(Imm) && "Invalid immediate"); 110 Inst.addOperand(MCOperand::CreateImm(Imm)); 111 return MCDisassembler::Success; 112 } 113 114 template<unsigned N> 115 static DecodeStatus decodeSImmOperand(MCInst &Inst, uint64_t Imm) { 116 assert(isUInt<N>(Imm) && "Invalid immediate"); 117 Inst.addOperand(MCOperand::CreateImm(SignExtend64<N>(Imm))); 118 return MCDisassembler::Success; 119 } 120 121 static DecodeStatus decodeAccessRegOperand(MCInst &Inst, uint64_t Imm, 122 uint64_t Address, 123 const void *Decoder) { 124 return decodeUImmOperand<4>(Inst, Imm); 125 } 126 127 static DecodeStatus decodeU4ImmOperand(MCInst &Inst, uint64_t Imm, 128 uint64_t Address, const void *Decoder) { 129 return decodeUImmOperand<4>(Inst, Imm); 130 } 131 132 static DecodeStatus decodeU6ImmOperand(MCInst &Inst, uint64_t Imm, 133 uint64_t Address, const void *Decoder) { 134 return decodeUImmOperand<6>(Inst, Imm); 135 } 136 137 static DecodeStatus decodeU8ImmOperand(MCInst &Inst, uint64_t Imm, 138 uint64_t Address, const void *Decoder) { 139 return decodeUImmOperand<8>(Inst, Imm); 140 } 141 142 static DecodeStatus decodeU16ImmOperand(MCInst &Inst, uint64_t Imm, 143 uint64_t Address, const void *Decoder) { 144 return decodeUImmOperand<16>(Inst, Imm); 145 } 146 147 static DecodeStatus decodeU32ImmOperand(MCInst &Inst, uint64_t Imm, 148 uint64_t Address, const void *Decoder) { 149 return decodeUImmOperand<32>(Inst, Imm); 150 } 151 152 static DecodeStatus decodeS8ImmOperand(MCInst &Inst, uint64_t Imm, 153 uint64_t Address, const void *Decoder) { 154 return decodeSImmOperand<8>(Inst, Imm); 155 } 156 157 static DecodeStatus decodeS16ImmOperand(MCInst &Inst, uint64_t Imm, 158 uint64_t Address, const void *Decoder) { 159 return decodeSImmOperand<16>(Inst, Imm); 160 } 161 162 static DecodeStatus decodeS32ImmOperand(MCInst &Inst, uint64_t Imm, 163 uint64_t Address, const void *Decoder) { 164 return decodeSImmOperand<32>(Inst, Imm); 165 } 166 167 template<unsigned N> 168 static DecodeStatus decodePCDBLOperand(MCInst &Inst, uint64_t Imm, 169 uint64_t Address) { 170 assert(isUInt<N>(Imm) && "Invalid PC-relative offset"); 171 Inst.addOperand(MCOperand::CreateImm(SignExtend64<N>(Imm) * 2 + Address)); 172 return MCDisassembler::Success; 173 } 174 175 static DecodeStatus decodePC16DBLOperand(MCInst &Inst, uint64_t Imm, 176 uint64_t Address, 177 const void *Decoder) { 178 return decodePCDBLOperand<16>(Inst, Imm, Address); 179 } 180 181 static DecodeStatus decodePC32DBLOperand(MCInst &Inst, uint64_t Imm, 182 uint64_t Address, 183 const void *Decoder) { 184 return decodePCDBLOperand<32>(Inst, Imm, Address); 185 } 186 187 static DecodeStatus decodeBDAddr12Operand(MCInst &Inst, uint64_t Field, 188 const unsigned *Regs) { 189 uint64_t Base = Field >> 12; 190 uint64_t Disp = Field & 0xfff; 191 assert(Base < 16 && "Invalid BDAddr12"); 192 Inst.addOperand(MCOperand::CreateReg(Base == 0 ? 0 : Regs[Base])); 193 Inst.addOperand(MCOperand::CreateImm(Disp)); 194 return MCDisassembler::Success; 195 } 196 197 static DecodeStatus decodeBDAddr20Operand(MCInst &Inst, uint64_t Field, 198 const unsigned *Regs) { 199 uint64_t Base = Field >> 20; 200 uint64_t Disp = ((Field << 12) & 0xff000) | ((Field >> 8) & 0xfff); 201 assert(Base < 16 && "Invalid BDAddr20"); 202 Inst.addOperand(MCOperand::CreateReg(Base == 0 ? 0 : Regs[Base])); 203 Inst.addOperand(MCOperand::CreateImm(SignExtend64<20>(Disp))); 204 return MCDisassembler::Success; 205 } 206 207 static DecodeStatus decodeBDXAddr12Operand(MCInst &Inst, uint64_t Field, 208 const unsigned *Regs) { 209 uint64_t Index = Field >> 16; 210 uint64_t Base = (Field >> 12) & 0xf; 211 uint64_t Disp = Field & 0xfff; 212 assert(Index < 16 && "Invalid BDXAddr12"); 213 Inst.addOperand(MCOperand::CreateReg(Base == 0 ? 0 : Regs[Base])); 214 Inst.addOperand(MCOperand::CreateImm(Disp)); 215 Inst.addOperand(MCOperand::CreateReg(Index == 0 ? 0 : Regs[Index])); 216 return MCDisassembler::Success; 217 } 218 219 static DecodeStatus decodeBDXAddr20Operand(MCInst &Inst, uint64_t Field, 220 const unsigned *Regs) { 221 uint64_t Index = Field >> 24; 222 uint64_t Base = (Field >> 20) & 0xf; 223 uint64_t Disp = ((Field & 0xfff00) >> 8) | ((Field & 0xff) << 12); 224 assert(Index < 16 && "Invalid BDXAddr20"); 225 Inst.addOperand(MCOperand::CreateReg(Base == 0 ? 0 : Regs[Base])); 226 Inst.addOperand(MCOperand::CreateImm(SignExtend64<20>(Disp))); 227 Inst.addOperand(MCOperand::CreateReg(Index == 0 ? 0 : Regs[Index])); 228 return MCDisassembler::Success; 229 } 230 231 static DecodeStatus decodeBDLAddr12Len8Operand(MCInst &Inst, uint64_t Field, 232 const unsigned *Regs) { 233 uint64_t Length = Field >> 16; 234 uint64_t Base = (Field >> 12) & 0xf; 235 uint64_t Disp = Field & 0xfff; 236 assert(Length < 256 && "Invalid BDLAddr12Len8"); 237 Inst.addOperand(MCOperand::CreateReg(Base == 0 ? 0 : Regs[Base])); 238 Inst.addOperand(MCOperand::CreateImm(Disp)); 239 Inst.addOperand(MCOperand::CreateImm(Length + 1)); 240 return MCDisassembler::Success; 241 } 242 243 static DecodeStatus decodeBDAddr32Disp12Operand(MCInst &Inst, uint64_t Field, 244 uint64_t Address, 245 const void *Decoder) { 246 return decodeBDAddr12Operand(Inst, Field, SystemZMC::GR32Regs); 247 } 248 249 static DecodeStatus decodeBDAddr32Disp20Operand(MCInst &Inst, uint64_t Field, 250 uint64_t Address, 251 const void *Decoder) { 252 return decodeBDAddr20Operand(Inst, Field, SystemZMC::GR32Regs); 253 } 254 255 static DecodeStatus decodeBDAddr64Disp12Operand(MCInst &Inst, uint64_t Field, 256 uint64_t Address, 257 const void *Decoder) { 258 return decodeBDAddr12Operand(Inst, Field, SystemZMC::GR64Regs); 259 } 260 261 static DecodeStatus decodeBDAddr64Disp20Operand(MCInst &Inst, uint64_t Field, 262 uint64_t Address, 263 const void *Decoder) { 264 return decodeBDAddr20Operand(Inst, Field, SystemZMC::GR64Regs); 265 } 266 267 static DecodeStatus decodeBDXAddr64Disp12Operand(MCInst &Inst, uint64_t Field, 268 uint64_t Address, 269 const void *Decoder) { 270 return decodeBDXAddr12Operand(Inst, Field, SystemZMC::GR64Regs); 271 } 272 273 static DecodeStatus decodeBDXAddr64Disp20Operand(MCInst &Inst, uint64_t Field, 274 uint64_t Address, 275 const void *Decoder) { 276 return decodeBDXAddr20Operand(Inst, Field, SystemZMC::GR64Regs); 277 } 278 279 static DecodeStatus decodeBDLAddr64Disp12Len8Operand(MCInst &Inst, 280 uint64_t Field, 281 uint64_t Address, 282 const void *Decoder) { 283 return decodeBDLAddr12Len8Operand(Inst, Field, SystemZMC::GR64Regs); 284 } 285 286 #include "SystemZGenDisassemblerTables.inc" 287 288 DecodeStatus SystemZDisassembler::getInstruction(MCInst &MI, uint64_t &Size, 289 ArrayRef<uint8_t> Bytes, 290 uint64_t Address, 291 raw_ostream &OS, 292 raw_ostream &CS) const { 293 // Get the first two bytes of the instruction. 294 Size = 0; 295 if (Bytes.size() < 2) 296 return MCDisassembler::Fail; 297 298 // The top 2 bits of the first byte specify the size. 299 const uint8_t *Table; 300 if (Bytes[0] < 0x40) { 301 Size = 2; 302 Table = DecoderTable16; 303 } else if (Bytes[0] < 0xc0) { 304 Size = 4; 305 Table = DecoderTable32; 306 } else { 307 Size = 6; 308 Table = DecoderTable48; 309 } 310 311 // Read any remaining bytes. 312 if (Bytes.size() < Size) 313 return MCDisassembler::Fail; 314 315 // Construct the instruction. 316 uint64_t Inst = 0; 317 for (uint64_t I = 0; I < Size; ++I) 318 Inst = (Inst << 8) | Bytes[I]; 319 320 return decodeInstruction(Table, MI, Inst, Address, this, STI); 321 } 322