1 //===- SparcDisassembler.cpp - Disassembler for Sparc -----------*- 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 // This file is part of the Sparc Disassembler. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #define DEBUG_TYPE "sparc-disassembler" 15 16 #include "Sparc.h" 17 #include "SparcRegisterInfo.h" 18 #include "SparcSubtarget.h" 19 #include "llvm/MC/MCDisassembler.h" 20 #include "llvm/MC/MCFixedLenDisassembler.h" 21 #include "llvm/Support/MemoryObject.h" 22 #include "llvm/Support/TargetRegistry.h" 23 24 using namespace llvm; 25 26 typedef MCDisassembler::DecodeStatus DecodeStatus; 27 28 namespace { 29 30 /// SparcDisassembler - a disassembler class for Sparc. 31 class SparcDisassembler : public MCDisassembler { 32 public: 33 /// Constructor - Initializes the disassembler. 34 /// 35 SparcDisassembler(const MCSubtargetInfo &STI, const MCRegisterInfo *Info) : 36 MCDisassembler(STI), RegInfo(Info) 37 {} 38 virtual ~SparcDisassembler() {} 39 40 const MCRegisterInfo *getRegInfo() const { return RegInfo.get(); } 41 42 /// getInstruction - See MCDisassembler. 43 virtual DecodeStatus getInstruction(MCInst &instr, 44 uint64_t &size, 45 const MemoryObject ®ion, 46 uint64_t address, 47 raw_ostream &vStream, 48 raw_ostream &cStream) const; 49 private: 50 OwningPtr<const MCRegisterInfo> RegInfo; 51 }; 52 53 } 54 55 namespace llvm { 56 extern Target TheSparcTarget, TheSparcV9Target; 57 } 58 59 static MCDisassembler *createSparcDisassembler( 60 const Target &T, 61 const MCSubtargetInfo &STI) { 62 return new SparcDisassembler(STI, T.createMCRegInfo("")); 63 } 64 65 66 extern "C" void LLVMInitializeSparcDisassembler() { 67 // Register the disassembler. 68 TargetRegistry::RegisterMCDisassembler(TheSparcTarget, 69 createSparcDisassembler); 70 TargetRegistry::RegisterMCDisassembler(TheSparcV9Target, 71 createSparcDisassembler); 72 } 73 74 75 76 static const unsigned IntRegDecoderTable[] = { 77 SP::G0, SP::G1, SP::G2, SP::G3, 78 SP::G4, SP::G5, SP::G6, SP::G7, 79 SP::O0, SP::O1, SP::O2, SP::O3, 80 SP::O4, SP::O5, SP::O6, SP::O7, 81 SP::L0, SP::L1, SP::L2, SP::L3, 82 SP::L4, SP::L5, SP::L6, SP::L7, 83 SP::I0, SP::I1, SP::I2, SP::I3, 84 SP::I4, SP::I5, SP::I6, SP::I7 }; 85 86 static const unsigned FPRegDecoderTable[] = { 87 SP::F0, SP::F1, SP::F2, SP::F3, 88 SP::F4, SP::F5, SP::F6, SP::F7, 89 SP::F8, SP::F9, SP::F10, SP::F11, 90 SP::F12, SP::F13, SP::F14, SP::F15, 91 SP::F16, SP::F17, SP::F18, SP::F19, 92 SP::F20, SP::F21, SP::F22, SP::F23, 93 SP::F24, SP::F25, SP::F26, SP::F27, 94 SP::F28, SP::F29, SP::F30, SP::F31 }; 95 96 static const unsigned DFPRegDecoderTable[] = { 97 SP::D0, SP::D16, SP::D1, SP::D17, 98 SP::D2, SP::D18, SP::D3, SP::D19, 99 SP::D4, SP::D20, SP::D5, SP::D21, 100 SP::D6, SP::D22, SP::D7, SP::D23, 101 SP::D8, SP::D24, SP::D9, SP::D25, 102 SP::D10, SP::D26, SP::D11, SP::D27, 103 SP::D12, SP::D28, SP::D13, SP::D29, 104 SP::D14, SP::D30, SP::D15, SP::D31 }; 105 106 static const unsigned QFPRegDecoderTable[] = { 107 SP::Q0, SP::Q8, ~0U, ~0U, 108 SP::Q1, SP::Q9, ~0U, ~0U, 109 SP::Q2, SP::Q10, ~0U, ~0U, 110 SP::Q3, SP::Q11, ~0U, ~0U, 111 SP::Q4, SP::Q12, ~0U, ~0U, 112 SP::Q5, SP::Q13, ~0U, ~0U, 113 SP::Q6, SP::Q14, ~0U, ~0U, 114 SP::Q7, SP::Q15, ~0U, ~0U } ; 115 116 static DecodeStatus DecodeIntRegsRegisterClass(MCInst &Inst, 117 unsigned RegNo, 118 uint64_t Address, 119 const void *Decoder) { 120 if (RegNo > 31) 121 return MCDisassembler::Fail; 122 unsigned Reg = IntRegDecoderTable[RegNo]; 123 Inst.addOperand(MCOperand::CreateReg(Reg)); 124 return MCDisassembler::Success; 125 } 126 127 static DecodeStatus DecodeI64RegsRegisterClass(MCInst &Inst, 128 unsigned RegNo, 129 uint64_t Address, 130 const void *Decoder) { 131 if (RegNo > 31) 132 return MCDisassembler::Fail; 133 unsigned Reg = IntRegDecoderTable[RegNo]; 134 Inst.addOperand(MCOperand::CreateReg(Reg)); 135 return MCDisassembler::Success; 136 } 137 138 139 static DecodeStatus DecodeFPRegsRegisterClass(MCInst &Inst, 140 unsigned RegNo, 141 uint64_t Address, 142 const void *Decoder) { 143 if (RegNo > 31) 144 return MCDisassembler::Fail; 145 unsigned Reg = FPRegDecoderTable[RegNo]; 146 Inst.addOperand(MCOperand::CreateReg(Reg)); 147 return MCDisassembler::Success; 148 } 149 150 151 static DecodeStatus DecodeDFPRegsRegisterClass(MCInst &Inst, 152 unsigned RegNo, 153 uint64_t Address, 154 const void *Decoder) { 155 if (RegNo > 31) 156 return MCDisassembler::Fail; 157 unsigned Reg = DFPRegDecoderTable[RegNo]; 158 Inst.addOperand(MCOperand::CreateReg(Reg)); 159 return MCDisassembler::Success; 160 } 161 162 163 static DecodeStatus DecodeQFPRegsRegisterClass(MCInst &Inst, 164 unsigned RegNo, 165 uint64_t Address, 166 const void *Decoder) { 167 if (RegNo > 31) 168 return MCDisassembler::Fail; 169 170 unsigned Reg = QFPRegDecoderTable[RegNo]; 171 if (Reg == ~0U) 172 return MCDisassembler::Fail; 173 Inst.addOperand(MCOperand::CreateReg(Reg)); 174 return MCDisassembler::Success; 175 } 176 177 static DecodeStatus DecodeLoadInt(MCInst &Inst, unsigned insn, uint64_t Address, 178 const void *Decoder); 179 static DecodeStatus DecodeLoadFP(MCInst &Inst, unsigned insn, uint64_t Address, 180 const void *Decoder); 181 static DecodeStatus DecodeLoadDFP(MCInst &Inst, unsigned insn, uint64_t Address, 182 const void *Decoder); 183 static DecodeStatus DecodeLoadQFP(MCInst &Inst, unsigned insn, uint64_t Address, 184 const void *Decoder); 185 static DecodeStatus DecodeStoreInt(MCInst &Inst, unsigned insn, 186 uint64_t Address, const void *Decoder); 187 static DecodeStatus DecodeStoreFP(MCInst &Inst, unsigned insn, 188 uint64_t Address, const void *Decoder); 189 static DecodeStatus DecodeStoreDFP(MCInst &Inst, unsigned insn, 190 uint64_t Address, const void *Decoder); 191 static DecodeStatus DecodeStoreQFP(MCInst &Inst, unsigned insn, 192 uint64_t Address, const void *Decoder); 193 static DecodeStatus DecodeCall(MCInst &Inst, unsigned insn, 194 uint64_t Address, const void *Decoder); 195 196 #include "SparcGenDisassemblerTables.inc" 197 198 /// readInstruction - read four bytes from the MemoryObject 199 /// and return 32 bit word. 200 static DecodeStatus readInstruction32(const MemoryObject ®ion, 201 uint64_t address, 202 uint64_t &size, 203 uint32_t &insn) { 204 uint8_t Bytes[4]; 205 206 // We want to read exactly 4 Bytes of data. 207 if (region.readBytes(address, 4, Bytes) == -1) { 208 size = 0; 209 return MCDisassembler::Fail; 210 } 211 212 // Encoded as a big-endian 32-bit word in the stream. 213 insn = (Bytes[3] << 0) | 214 (Bytes[2] << 8) | 215 (Bytes[1] << 16) | 216 (Bytes[0] << 24); 217 218 return MCDisassembler::Success; 219 } 220 221 222 DecodeStatus 223 SparcDisassembler::getInstruction(MCInst &instr, 224 uint64_t &Size, 225 const MemoryObject &Region, 226 uint64_t Address, 227 raw_ostream &vStream, 228 raw_ostream &cStream) const { 229 uint32_t Insn; 230 231 DecodeStatus Result = readInstruction32(Region, Address, Size, Insn); 232 if (Result == MCDisassembler::Fail) 233 return MCDisassembler::Fail; 234 235 236 // Calling the auto-generated decoder function. 237 Result = decodeInstruction(DecoderTableSparc32, instr, Insn, Address, 238 this, STI); 239 240 if (Result != MCDisassembler::Fail) { 241 Size = 4; 242 return Result; 243 } 244 245 return MCDisassembler::Fail; 246 } 247 248 249 typedef DecodeStatus (*DecodeFunc)(MCInst &MI, unsigned insn, uint64_t Address, 250 const void *Decoder); 251 252 static DecodeStatus DecodeMem(MCInst &MI, unsigned insn, uint64_t Address, 253 const void *Decoder, 254 bool isLoad, DecodeFunc DecodeRD) { 255 unsigned rd = fieldFromInstruction(insn, 25, 5); 256 unsigned rs1 = fieldFromInstruction(insn, 14, 5); 257 bool isImm = fieldFromInstruction(insn, 13, 1); 258 unsigned rs2 = 0; 259 unsigned simm13 = 0; 260 if (isImm) 261 simm13 = SignExtend32<13>(fieldFromInstruction(insn, 0, 13)); 262 else 263 rs2 = fieldFromInstruction(insn, 0, 5); 264 265 DecodeStatus status; 266 if (isLoad) { 267 status = DecodeRD(MI, rd, Address, Decoder); 268 if (status != MCDisassembler::Success) 269 return status; 270 } 271 272 // Decode rs1. 273 status = DecodeIntRegsRegisterClass(MI, rs1, Address, Decoder); 274 if (status != MCDisassembler::Success) 275 return status; 276 277 // Decode imm|rs2. 278 if (isImm) 279 MI.addOperand(MCOperand::CreateImm(simm13)); 280 else { 281 status = DecodeIntRegsRegisterClass(MI, rs2, Address, Decoder); 282 if (status != MCDisassembler::Success) 283 return status; 284 } 285 286 if (!isLoad) { 287 status = DecodeRD(MI, rd, Address, Decoder); 288 if (status != MCDisassembler::Success) 289 return status; 290 } 291 return MCDisassembler::Success; 292 } 293 294 static DecodeStatus DecodeLoadInt(MCInst &Inst, unsigned insn, uint64_t Address, 295 const void *Decoder) { 296 return DecodeMem(Inst, insn, Address, Decoder, true, 297 DecodeIntRegsRegisterClass); 298 } 299 300 static DecodeStatus DecodeLoadFP(MCInst &Inst, unsigned insn, uint64_t Address, 301 const void *Decoder) { 302 return DecodeMem(Inst, insn, Address, Decoder, true, 303 DecodeFPRegsRegisterClass); 304 } 305 306 static DecodeStatus DecodeLoadDFP(MCInst &Inst, unsigned insn, uint64_t Address, 307 const void *Decoder) { 308 return DecodeMem(Inst, insn, Address, Decoder, true, 309 DecodeDFPRegsRegisterClass); 310 } 311 312 static DecodeStatus DecodeLoadQFP(MCInst &Inst, unsigned insn, uint64_t Address, 313 const void *Decoder) { 314 return DecodeMem(Inst, insn, Address, Decoder, true, 315 DecodeQFPRegsRegisterClass); 316 } 317 318 static DecodeStatus DecodeStoreInt(MCInst &Inst, unsigned insn, 319 uint64_t Address, const void *Decoder) { 320 return DecodeMem(Inst, insn, Address, Decoder, false, 321 DecodeIntRegsRegisterClass); 322 } 323 324 static DecodeStatus DecodeStoreFP(MCInst &Inst, unsigned insn, uint64_t Address, 325 const void *Decoder) { 326 return DecodeMem(Inst, insn, Address, Decoder, false, 327 DecodeFPRegsRegisterClass); 328 } 329 330 static DecodeStatus DecodeStoreDFP(MCInst &Inst, unsigned insn, 331 uint64_t Address, const void *Decoder) { 332 return DecodeMem(Inst, insn, Address, Decoder, false, 333 DecodeDFPRegsRegisterClass); 334 } 335 336 static DecodeStatus DecodeStoreQFP(MCInst &Inst, unsigned insn, 337 uint64_t Address, const void *Decoder) { 338 return DecodeMem(Inst, insn, Address, Decoder, false, 339 DecodeQFPRegsRegisterClass); 340 } 341 342 static bool tryAddingSymbolicOperand(int64_t Value, bool isBranch, 343 uint64_t Address, uint64_t Offset, 344 uint64_t Width, MCInst &MI, 345 const void *Decoder) { 346 const MCDisassembler *Dis = static_cast<const MCDisassembler*>(Decoder); 347 return Dis->tryAddingSymbolicOperand(MI, Value, Address, isBranch, 348 Offset, Width); 349 } 350 351 static DecodeStatus DecodeCall(MCInst &MI, unsigned insn, 352 uint64_t Address, const void *Decoder) { 353 unsigned tgt = fieldFromInstruction(insn, 0, 30); 354 tgt <<= 2; 355 if (!tryAddingSymbolicOperand(tgt+Address, false, Address, 356 0, 30, MI, Decoder)) 357 MI.addOperand(MCOperand::CreateImm(tgt)); 358 return MCDisassembler::Success; 359 } 360