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