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