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