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/MemoryObject.h" 16 #include "llvm/Support/TargetRegistry.h" 17 18 using namespace llvm; 19 20 #define DEBUG_TYPE "systemz-disassembler" 21 22 typedef MCDisassembler::DecodeStatus DecodeStatus; 23 24 namespace { 25 class SystemZDisassembler : public MCDisassembler { 26 public: 27 SystemZDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx) 28 : MCDisassembler(STI, Ctx) {} 29 virtual ~SystemZDisassembler() {} 30 31 // Override MCDisassembler. 32 DecodeStatus getInstruction(MCInst &instr, uint64_t &size, 33 const MemoryObject ®ion, uint64_t address, 34 raw_ostream &vStream, 35 raw_ostream &cStream) const override; 36 }; 37 } // end anonymous namespace 38 39 static MCDisassembler *createSystemZDisassembler(const Target &T, 40 const MCSubtargetInfo &STI, 41 MCContext &Ctx) { 42 return new SystemZDisassembler(STI, Ctx); 43 } 44 45 extern "C" void LLVMInitializeSystemZDisassembler() { 46 // Register the disassembler. 47 TargetRegistry::RegisterMCDisassembler(TheSystemZTarget, 48 createSystemZDisassembler); 49 } 50 51 static DecodeStatus decodeRegisterClass(MCInst &Inst, uint64_t RegNo, 52 const unsigned *Regs) { 53 assert(RegNo < 16 && "Invalid register"); 54 RegNo = Regs[RegNo]; 55 if (RegNo == 0) 56 return MCDisassembler::Fail; 57 Inst.addOperand(MCOperand::CreateReg(RegNo)); 58 return MCDisassembler::Success; 59 } 60 61 static DecodeStatus DecodeGR32BitRegisterClass(MCInst &Inst, uint64_t RegNo, 62 uint64_t Address, 63 const void *Decoder) { 64 return decodeRegisterClass(Inst, RegNo, SystemZMC::GR32Regs); 65 } 66 67 static DecodeStatus DecodeGRH32BitRegisterClass(MCInst &Inst, uint64_t RegNo, 68 uint64_t Address, 69 const void *Decoder) { 70 return decodeRegisterClass(Inst, RegNo, SystemZMC::GRH32Regs); 71 } 72 73 static DecodeStatus DecodeGR64BitRegisterClass(MCInst &Inst, uint64_t RegNo, 74 uint64_t Address, 75 const void *Decoder) { 76 return decodeRegisterClass(Inst, RegNo, SystemZMC::GR64Regs); 77 } 78 79 static DecodeStatus DecodeGR128BitRegisterClass(MCInst &Inst, uint64_t RegNo, 80 uint64_t Address, 81 const void *Decoder) { 82 return decodeRegisterClass(Inst, RegNo, SystemZMC::GR128Regs); 83 } 84 85 static DecodeStatus DecodeADDR64BitRegisterClass(MCInst &Inst, uint64_t RegNo, 86 uint64_t Address, 87 const void *Decoder) { 88 return decodeRegisterClass(Inst, RegNo, SystemZMC::GR64Regs); 89 } 90 91 static DecodeStatus DecodeFP32BitRegisterClass(MCInst &Inst, uint64_t RegNo, 92 uint64_t Address, 93 const void *Decoder) { 94 return decodeRegisterClass(Inst, RegNo, SystemZMC::FP32Regs); 95 } 96 97 static DecodeStatus DecodeFP64BitRegisterClass(MCInst &Inst, uint64_t RegNo, 98 uint64_t Address, 99 const void *Decoder) { 100 return decodeRegisterClass(Inst, RegNo, SystemZMC::FP64Regs); 101 } 102 103 static DecodeStatus DecodeFP128BitRegisterClass(MCInst &Inst, uint64_t RegNo, 104 uint64_t Address, 105 const void *Decoder) { 106 return decodeRegisterClass(Inst, RegNo, SystemZMC::FP128Regs); 107 } 108 109 template<unsigned N> 110 static DecodeStatus decodeUImmOperand(MCInst &Inst, uint64_t Imm) { 111 assert(isUInt<N>(Imm) && "Invalid immediate"); 112 Inst.addOperand(MCOperand::CreateImm(Imm)); 113 return MCDisassembler::Success; 114 } 115 116 template<unsigned N> 117 static DecodeStatus decodeSImmOperand(MCInst &Inst, uint64_t Imm) { 118 assert(isUInt<N>(Imm) && "Invalid immediate"); 119 Inst.addOperand(MCOperand::CreateImm(SignExtend64<N>(Imm))); 120 return MCDisassembler::Success; 121 } 122 123 static DecodeStatus decodeAccessRegOperand(MCInst &Inst, uint64_t Imm, 124 uint64_t Address, 125 const void *Decoder) { 126 return decodeUImmOperand<4>(Inst, Imm); 127 } 128 129 static DecodeStatus decodeU4ImmOperand(MCInst &Inst, uint64_t Imm, 130 uint64_t Address, const void *Decoder) { 131 return decodeUImmOperand<4>(Inst, Imm); 132 } 133 134 static DecodeStatus decodeU6ImmOperand(MCInst &Inst, uint64_t Imm, 135 uint64_t Address, const void *Decoder) { 136 return decodeUImmOperand<6>(Inst, Imm); 137 } 138 139 static DecodeStatus decodeU8ImmOperand(MCInst &Inst, uint64_t Imm, 140 uint64_t Address, const void *Decoder) { 141 return decodeUImmOperand<8>(Inst, Imm); 142 } 143 144 static DecodeStatus decodeU16ImmOperand(MCInst &Inst, uint64_t Imm, 145 uint64_t Address, const void *Decoder) { 146 return decodeUImmOperand<16>(Inst, Imm); 147 } 148 149 static DecodeStatus decodeU32ImmOperand(MCInst &Inst, uint64_t Imm, 150 uint64_t Address, const void *Decoder) { 151 return decodeUImmOperand<32>(Inst, Imm); 152 } 153 154 static DecodeStatus decodeS8ImmOperand(MCInst &Inst, uint64_t Imm, 155 uint64_t Address, const void *Decoder) { 156 return decodeSImmOperand<8>(Inst, Imm); 157 } 158 159 static DecodeStatus decodeS16ImmOperand(MCInst &Inst, uint64_t Imm, 160 uint64_t Address, const void *Decoder) { 161 return decodeSImmOperand<16>(Inst, Imm); 162 } 163 164 static DecodeStatus decodeS32ImmOperand(MCInst &Inst, uint64_t Imm, 165 uint64_t Address, const void *Decoder) { 166 return decodeSImmOperand<32>(Inst, Imm); 167 } 168 169 template<unsigned N> 170 static DecodeStatus decodePCDBLOperand(MCInst &Inst, uint64_t Imm, 171 uint64_t Address) { 172 assert(isUInt<N>(Imm) && "Invalid PC-relative offset"); 173 Inst.addOperand(MCOperand::CreateImm(SignExtend64<N>(Imm) * 2 + Address)); 174 return MCDisassembler::Success; 175 } 176 177 static DecodeStatus decodePC16DBLOperand(MCInst &Inst, uint64_t Imm, 178 uint64_t Address, 179 const void *Decoder) { 180 return decodePCDBLOperand<16>(Inst, Imm, Address); 181 } 182 183 static DecodeStatus decodePC32DBLOperand(MCInst &Inst, uint64_t Imm, 184 uint64_t Address, 185 const void *Decoder) { 186 return decodePCDBLOperand<32>(Inst, Imm, Address); 187 } 188 189 static DecodeStatus decodeBDAddr12Operand(MCInst &Inst, uint64_t Field, 190 const unsigned *Regs) { 191 uint64_t Base = Field >> 12; 192 uint64_t Disp = Field & 0xfff; 193 assert(Base < 16 && "Invalid BDAddr12"); 194 Inst.addOperand(MCOperand::CreateReg(Base == 0 ? 0 : Regs[Base])); 195 Inst.addOperand(MCOperand::CreateImm(Disp)); 196 return MCDisassembler::Success; 197 } 198 199 static DecodeStatus decodeBDAddr20Operand(MCInst &Inst, uint64_t Field, 200 const unsigned *Regs) { 201 uint64_t Base = Field >> 20; 202 uint64_t Disp = ((Field << 12) & 0xff000) | ((Field >> 8) & 0xfff); 203 assert(Base < 16 && "Invalid BDAddr20"); 204 Inst.addOperand(MCOperand::CreateReg(Base == 0 ? 0 : Regs[Base])); 205 Inst.addOperand(MCOperand::CreateImm(SignExtend64<20>(Disp))); 206 return MCDisassembler::Success; 207 } 208 209 static DecodeStatus decodeBDXAddr12Operand(MCInst &Inst, uint64_t Field, 210 const unsigned *Regs) { 211 uint64_t Index = Field >> 16; 212 uint64_t Base = (Field >> 12) & 0xf; 213 uint64_t Disp = Field & 0xfff; 214 assert(Index < 16 && "Invalid BDXAddr12"); 215 Inst.addOperand(MCOperand::CreateReg(Base == 0 ? 0 : Regs[Base])); 216 Inst.addOperand(MCOperand::CreateImm(Disp)); 217 Inst.addOperand(MCOperand::CreateReg(Index == 0 ? 0 : Regs[Index])); 218 return MCDisassembler::Success; 219 } 220 221 static DecodeStatus decodeBDXAddr20Operand(MCInst &Inst, uint64_t Field, 222 const unsigned *Regs) { 223 uint64_t Index = Field >> 24; 224 uint64_t Base = (Field >> 20) & 0xf; 225 uint64_t Disp = ((Field & 0xfff00) >> 8) | ((Field & 0xff) << 12); 226 assert(Index < 16 && "Invalid BDXAddr20"); 227 Inst.addOperand(MCOperand::CreateReg(Base == 0 ? 0 : Regs[Base])); 228 Inst.addOperand(MCOperand::CreateImm(SignExtend64<20>(Disp))); 229 Inst.addOperand(MCOperand::CreateReg(Index == 0 ? 0 : Regs[Index])); 230 return MCDisassembler::Success; 231 } 232 233 static DecodeStatus decodeBDLAddr12Len8Operand(MCInst &Inst, uint64_t Field, 234 const unsigned *Regs) { 235 uint64_t Length = Field >> 16; 236 uint64_t Base = (Field >> 12) & 0xf; 237 uint64_t Disp = Field & 0xfff; 238 assert(Length < 256 && "Invalid BDLAddr12Len8"); 239 Inst.addOperand(MCOperand::CreateReg(Base == 0 ? 0 : Regs[Base])); 240 Inst.addOperand(MCOperand::CreateImm(Disp)); 241 Inst.addOperand(MCOperand::CreateImm(Length + 1)); 242 return MCDisassembler::Success; 243 } 244 245 static DecodeStatus decodeBDAddr32Disp12Operand(MCInst &Inst, uint64_t Field, 246 uint64_t Address, 247 const void *Decoder) { 248 return decodeBDAddr12Operand(Inst, Field, SystemZMC::GR32Regs); 249 } 250 251 static DecodeStatus decodeBDAddr32Disp20Operand(MCInst &Inst, uint64_t Field, 252 uint64_t Address, 253 const void *Decoder) { 254 return decodeBDAddr20Operand(Inst, Field, SystemZMC::GR32Regs); 255 } 256 257 static DecodeStatus decodeBDAddr64Disp12Operand(MCInst &Inst, uint64_t Field, 258 uint64_t Address, 259 const void *Decoder) { 260 return decodeBDAddr12Operand(Inst, Field, SystemZMC::GR64Regs); 261 } 262 263 static DecodeStatus decodeBDAddr64Disp20Operand(MCInst &Inst, uint64_t Field, 264 uint64_t Address, 265 const void *Decoder) { 266 return decodeBDAddr20Operand(Inst, Field, SystemZMC::GR64Regs); 267 } 268 269 static DecodeStatus decodeBDXAddr64Disp12Operand(MCInst &Inst, uint64_t Field, 270 uint64_t Address, 271 const void *Decoder) { 272 return decodeBDXAddr12Operand(Inst, Field, SystemZMC::GR64Regs); 273 } 274 275 static DecodeStatus decodeBDXAddr64Disp20Operand(MCInst &Inst, uint64_t Field, 276 uint64_t Address, 277 const void *Decoder) { 278 return decodeBDXAddr20Operand(Inst, Field, SystemZMC::GR64Regs); 279 } 280 281 static DecodeStatus decodeBDLAddr64Disp12Len8Operand(MCInst &Inst, 282 uint64_t Field, 283 uint64_t Address, 284 const void *Decoder) { 285 return decodeBDLAddr12Len8Operand(Inst, Field, SystemZMC::GR64Regs); 286 } 287 288 #include "SystemZGenDisassemblerTables.inc" 289 290 DecodeStatus SystemZDisassembler::getInstruction(MCInst &MI, uint64_t &Size, 291 const MemoryObject &Region, 292 uint64_t Address, 293 raw_ostream &os, 294 raw_ostream &cs) const { 295 // Get the first two bytes of the instruction. 296 uint8_t Bytes[6]; 297 Size = 0; 298 if (Region.readBytes(Address, 2, Bytes) == -1) 299 return MCDisassembler::Fail; 300 301 // The top 2 bits of the first byte specify the size. 302 const uint8_t *Table; 303 if (Bytes[0] < 0x40) { 304 Size = 2; 305 Table = DecoderTable16; 306 } else if (Bytes[0] < 0xc0) { 307 Size = 4; 308 Table = DecoderTable32; 309 } else { 310 Size = 6; 311 Table = DecoderTable48; 312 } 313 314 // Read any remaining bytes. 315 if (Size > 2 && Region.readBytes(Address + 2, Size - 2, Bytes + 2) == -1) 316 return MCDisassembler::Fail; 317 318 // Construct the instruction. 319 uint64_t Inst = 0; 320 for (uint64_t I = 0; I < Size; ++I) 321 Inst = (Inst << 8) | Bytes[I]; 322 323 return decodeInstruction(Table, MI, Inst, Address, this, STI); 324 } 325