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