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 static DecodeStatus DecodeSIMM13(MCInst &Inst, unsigned insn, 196 uint64_t Address, const void *Decoder); 197 198 #include "SparcGenDisassemblerTables.inc" 199 200 /// readInstruction - read four bytes from the MemoryObject 201 /// and return 32 bit word. 202 static DecodeStatus readInstruction32(const MemoryObject ®ion, 203 uint64_t address, 204 uint64_t &size, 205 uint32_t &insn) { 206 uint8_t Bytes[4]; 207 208 // We want to read exactly 4 Bytes of data. 209 if (region.readBytes(address, 4, Bytes) == -1) { 210 size = 0; 211 return MCDisassembler::Fail; 212 } 213 214 // Encoded as a big-endian 32-bit word in the stream. 215 insn = (Bytes[3] << 0) | 216 (Bytes[2] << 8) | 217 (Bytes[1] << 16) | 218 (Bytes[0] << 24); 219 220 return MCDisassembler::Success; 221 } 222 223 224 DecodeStatus 225 SparcDisassembler::getInstruction(MCInst &instr, 226 uint64_t &Size, 227 const MemoryObject &Region, 228 uint64_t Address, 229 raw_ostream &vStream, 230 raw_ostream &cStream) const { 231 uint32_t Insn; 232 233 DecodeStatus Result = readInstruction32(Region, Address, Size, Insn); 234 if (Result == MCDisassembler::Fail) 235 return MCDisassembler::Fail; 236 237 238 // Calling the auto-generated decoder function. 239 Result = decodeInstruction(DecoderTableSparc32, instr, Insn, Address, 240 this, STI); 241 242 if (Result != MCDisassembler::Fail) { 243 Size = 4; 244 return Result; 245 } 246 247 return MCDisassembler::Fail; 248 } 249 250 251 typedef DecodeStatus (*DecodeFunc)(MCInst &MI, unsigned insn, uint64_t Address, 252 const void *Decoder); 253 254 static DecodeStatus DecodeMem(MCInst &MI, unsigned insn, uint64_t Address, 255 const void *Decoder, 256 bool isLoad, DecodeFunc DecodeRD) { 257 unsigned rd = fieldFromInstruction(insn, 25, 5); 258 unsigned rs1 = fieldFromInstruction(insn, 14, 5); 259 bool isImm = fieldFromInstruction(insn, 13, 1); 260 unsigned rs2 = 0; 261 unsigned simm13 = 0; 262 if (isImm) 263 simm13 = SignExtend32<13>(fieldFromInstruction(insn, 0, 13)); 264 else 265 rs2 = fieldFromInstruction(insn, 0, 5); 266 267 DecodeStatus status; 268 if (isLoad) { 269 status = DecodeRD(MI, rd, Address, Decoder); 270 if (status != MCDisassembler::Success) 271 return status; 272 } 273 274 // Decode rs1. 275 status = DecodeIntRegsRegisterClass(MI, rs1, Address, Decoder); 276 if (status != MCDisassembler::Success) 277 return status; 278 279 // Decode imm|rs2. 280 if (isImm) 281 MI.addOperand(MCOperand::CreateImm(simm13)); 282 else { 283 status = DecodeIntRegsRegisterClass(MI, rs2, Address, Decoder); 284 if (status != MCDisassembler::Success) 285 return status; 286 } 287 288 if (!isLoad) { 289 status = DecodeRD(MI, rd, Address, Decoder); 290 if (status != MCDisassembler::Success) 291 return status; 292 } 293 return MCDisassembler::Success; 294 } 295 296 static DecodeStatus DecodeLoadInt(MCInst &Inst, unsigned insn, uint64_t Address, 297 const void *Decoder) { 298 return DecodeMem(Inst, insn, Address, Decoder, true, 299 DecodeIntRegsRegisterClass); 300 } 301 302 static DecodeStatus DecodeLoadFP(MCInst &Inst, unsigned insn, uint64_t Address, 303 const void *Decoder) { 304 return DecodeMem(Inst, insn, Address, Decoder, true, 305 DecodeFPRegsRegisterClass); 306 } 307 308 static DecodeStatus DecodeLoadDFP(MCInst &Inst, unsigned insn, uint64_t Address, 309 const void *Decoder) { 310 return DecodeMem(Inst, insn, Address, Decoder, true, 311 DecodeDFPRegsRegisterClass); 312 } 313 314 static DecodeStatus DecodeLoadQFP(MCInst &Inst, unsigned insn, uint64_t Address, 315 const void *Decoder) { 316 return DecodeMem(Inst, insn, Address, Decoder, true, 317 DecodeQFPRegsRegisterClass); 318 } 319 320 static DecodeStatus DecodeStoreInt(MCInst &Inst, unsigned insn, 321 uint64_t Address, const void *Decoder) { 322 return DecodeMem(Inst, insn, Address, Decoder, false, 323 DecodeIntRegsRegisterClass); 324 } 325 326 static DecodeStatus DecodeStoreFP(MCInst &Inst, unsigned insn, uint64_t Address, 327 const void *Decoder) { 328 return DecodeMem(Inst, insn, Address, Decoder, false, 329 DecodeFPRegsRegisterClass); 330 } 331 332 static DecodeStatus DecodeStoreDFP(MCInst &Inst, unsigned insn, 333 uint64_t Address, const void *Decoder) { 334 return DecodeMem(Inst, insn, Address, Decoder, false, 335 DecodeDFPRegsRegisterClass); 336 } 337 338 static DecodeStatus DecodeStoreQFP(MCInst &Inst, unsigned insn, 339 uint64_t Address, const void *Decoder) { 340 return DecodeMem(Inst, insn, Address, Decoder, false, 341 DecodeQFPRegsRegisterClass); 342 } 343 344 static bool tryAddingSymbolicOperand(int64_t Value, bool isBranch, 345 uint64_t Address, uint64_t Offset, 346 uint64_t Width, MCInst &MI, 347 const void *Decoder) { 348 const MCDisassembler *Dis = static_cast<const MCDisassembler*>(Decoder); 349 return Dis->tryAddingSymbolicOperand(MI, Value, Address, isBranch, 350 Offset, Width); 351 } 352 353 static DecodeStatus DecodeCall(MCInst &MI, unsigned insn, 354 uint64_t Address, const void *Decoder) { 355 unsigned tgt = fieldFromInstruction(insn, 0, 30); 356 tgt <<= 2; 357 if (!tryAddingSymbolicOperand(tgt+Address, false, Address, 358 0, 30, MI, Decoder)) 359 MI.addOperand(MCOperand::CreateImm(tgt)); 360 return MCDisassembler::Success; 361 } 362 363 static DecodeStatus DecodeSIMM13(MCInst &MI, unsigned insn, 364 uint64_t Address, const void *Decoder) { 365 unsigned tgt = SignExtend32<13>(fieldFromInstruction(insn, 0, 13)); 366 MI.addOperand(MCOperand::CreateImm(tgt)); 367 return MCDisassembler::Success; 368 } 369