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 const unsigned FCCRegDecoderTable[] = { 117 SP::FCC0, SP::FCC1, SP::FCC2, SP::FCC3 }; 118 119 static DecodeStatus DecodeIntRegsRegisterClass(MCInst &Inst, 120 unsigned RegNo, 121 uint64_t Address, 122 const void *Decoder) { 123 if (RegNo > 31) 124 return MCDisassembler::Fail; 125 unsigned Reg = IntRegDecoderTable[RegNo]; 126 Inst.addOperand(MCOperand::CreateReg(Reg)); 127 return MCDisassembler::Success; 128 } 129 130 static DecodeStatus DecodeI64RegsRegisterClass(MCInst &Inst, 131 unsigned RegNo, 132 uint64_t Address, 133 const void *Decoder) { 134 if (RegNo > 31) 135 return MCDisassembler::Fail; 136 unsigned Reg = IntRegDecoderTable[RegNo]; 137 Inst.addOperand(MCOperand::CreateReg(Reg)); 138 return MCDisassembler::Success; 139 } 140 141 142 static DecodeStatus DecodeFPRegsRegisterClass(MCInst &Inst, 143 unsigned RegNo, 144 uint64_t Address, 145 const void *Decoder) { 146 if (RegNo > 31) 147 return MCDisassembler::Fail; 148 unsigned Reg = FPRegDecoderTable[RegNo]; 149 Inst.addOperand(MCOperand::CreateReg(Reg)); 150 return MCDisassembler::Success; 151 } 152 153 154 static DecodeStatus DecodeDFPRegsRegisterClass(MCInst &Inst, 155 unsigned RegNo, 156 uint64_t Address, 157 const void *Decoder) { 158 if (RegNo > 31) 159 return MCDisassembler::Fail; 160 unsigned Reg = DFPRegDecoderTable[RegNo]; 161 Inst.addOperand(MCOperand::CreateReg(Reg)); 162 return MCDisassembler::Success; 163 } 164 165 166 static DecodeStatus DecodeQFPRegsRegisterClass(MCInst &Inst, 167 unsigned RegNo, 168 uint64_t Address, 169 const void *Decoder) { 170 if (RegNo > 31) 171 return MCDisassembler::Fail; 172 173 unsigned Reg = QFPRegDecoderTable[RegNo]; 174 if (Reg == ~0U) 175 return MCDisassembler::Fail; 176 Inst.addOperand(MCOperand::CreateReg(Reg)); 177 return MCDisassembler::Success; 178 } 179 180 static DecodeStatus DecodeFCCRegsRegisterClass(MCInst &Inst, unsigned RegNo, 181 uint64_t Address, 182 const void *Decoder) { 183 if (RegNo > 3) 184 return MCDisassembler::Fail; 185 Inst.addOperand(MCOperand::CreateReg(FCCRegDecoderTable[RegNo])); 186 return MCDisassembler::Success; 187 } 188 189 190 static DecodeStatus DecodeLoadInt(MCInst &Inst, unsigned insn, uint64_t Address, 191 const void *Decoder); 192 static DecodeStatus DecodeLoadFP(MCInst &Inst, unsigned insn, uint64_t Address, 193 const void *Decoder); 194 static DecodeStatus DecodeLoadDFP(MCInst &Inst, unsigned insn, uint64_t Address, 195 const void *Decoder); 196 static DecodeStatus DecodeLoadQFP(MCInst &Inst, unsigned insn, uint64_t Address, 197 const void *Decoder); 198 static DecodeStatus DecodeStoreInt(MCInst &Inst, unsigned insn, 199 uint64_t Address, const void *Decoder); 200 static DecodeStatus DecodeStoreFP(MCInst &Inst, unsigned insn, 201 uint64_t Address, const void *Decoder); 202 static DecodeStatus DecodeStoreDFP(MCInst &Inst, unsigned insn, 203 uint64_t Address, const void *Decoder); 204 static DecodeStatus DecodeStoreQFP(MCInst &Inst, unsigned insn, 205 uint64_t Address, const void *Decoder); 206 static DecodeStatus DecodeCall(MCInst &Inst, unsigned insn, 207 uint64_t Address, const void *Decoder); 208 static DecodeStatus DecodeSIMM13(MCInst &Inst, unsigned insn, 209 uint64_t Address, const void *Decoder); 210 static DecodeStatus DecodeJMPL(MCInst &Inst, unsigned insn, uint64_t Address, 211 const void *Decoder); 212 static DecodeStatus DecodeReturn(MCInst &MI, unsigned insn, uint64_t Address, 213 const void *Decoder); 214 static DecodeStatus DecodeSWAP(MCInst &Inst, unsigned insn, uint64_t Address, 215 const void *Decoder); 216 217 #include "SparcGenDisassemblerTables.inc" 218 219 /// readInstruction - read four bytes from the MemoryObject 220 /// and return 32 bit word. 221 static DecodeStatus readInstruction32(const MemoryObject ®ion, 222 uint64_t address, 223 uint64_t &size, 224 uint32_t &insn) { 225 uint8_t Bytes[4]; 226 227 // We want to read exactly 4 Bytes of data. 228 if (region.readBytes(address, 4, Bytes) == -1) { 229 size = 0; 230 return MCDisassembler::Fail; 231 } 232 233 // Encoded as a big-endian 32-bit word in the stream. 234 insn = (Bytes[3] << 0) | 235 (Bytes[2] << 8) | 236 (Bytes[1] << 16) | 237 (Bytes[0] << 24); 238 239 return MCDisassembler::Success; 240 } 241 242 243 DecodeStatus 244 SparcDisassembler::getInstruction(MCInst &instr, 245 uint64_t &Size, 246 const MemoryObject &Region, 247 uint64_t Address, 248 raw_ostream &vStream, 249 raw_ostream &cStream) const { 250 uint32_t Insn; 251 252 DecodeStatus Result = readInstruction32(Region, Address, Size, Insn); 253 if (Result == MCDisassembler::Fail) 254 return MCDisassembler::Fail; 255 256 257 // Calling the auto-generated decoder function. 258 Result = decodeInstruction(DecoderTableSparc32, instr, Insn, Address, 259 this, STI); 260 261 if (Result != MCDisassembler::Fail) { 262 Size = 4; 263 return Result; 264 } 265 266 return MCDisassembler::Fail; 267 } 268 269 270 typedef DecodeStatus (*DecodeFunc)(MCInst &MI, unsigned insn, uint64_t Address, 271 const void *Decoder); 272 273 static DecodeStatus DecodeMem(MCInst &MI, unsigned insn, uint64_t Address, 274 const void *Decoder, 275 bool isLoad, DecodeFunc DecodeRD) { 276 unsigned rd = fieldFromInstruction(insn, 25, 5); 277 unsigned rs1 = fieldFromInstruction(insn, 14, 5); 278 bool isImm = fieldFromInstruction(insn, 13, 1); 279 unsigned rs2 = 0; 280 unsigned simm13 = 0; 281 if (isImm) 282 simm13 = SignExtend32<13>(fieldFromInstruction(insn, 0, 13)); 283 else 284 rs2 = fieldFromInstruction(insn, 0, 5); 285 286 DecodeStatus status; 287 if (isLoad) { 288 status = DecodeRD(MI, rd, Address, Decoder); 289 if (status != MCDisassembler::Success) 290 return status; 291 } 292 293 // Decode rs1. 294 status = DecodeIntRegsRegisterClass(MI, rs1, Address, Decoder); 295 if (status != MCDisassembler::Success) 296 return status; 297 298 // Decode imm|rs2. 299 if (isImm) 300 MI.addOperand(MCOperand::CreateImm(simm13)); 301 else { 302 status = DecodeIntRegsRegisterClass(MI, rs2, Address, Decoder); 303 if (status != MCDisassembler::Success) 304 return status; 305 } 306 307 if (!isLoad) { 308 status = DecodeRD(MI, rd, Address, Decoder); 309 if (status != MCDisassembler::Success) 310 return status; 311 } 312 return MCDisassembler::Success; 313 } 314 315 static DecodeStatus DecodeLoadInt(MCInst &Inst, unsigned insn, uint64_t Address, 316 const void *Decoder) { 317 return DecodeMem(Inst, insn, Address, Decoder, true, 318 DecodeIntRegsRegisterClass); 319 } 320 321 static DecodeStatus DecodeLoadFP(MCInst &Inst, unsigned insn, uint64_t Address, 322 const void *Decoder) { 323 return DecodeMem(Inst, insn, Address, Decoder, true, 324 DecodeFPRegsRegisterClass); 325 } 326 327 static DecodeStatus DecodeLoadDFP(MCInst &Inst, unsigned insn, uint64_t Address, 328 const void *Decoder) { 329 return DecodeMem(Inst, insn, Address, Decoder, true, 330 DecodeDFPRegsRegisterClass); 331 } 332 333 static DecodeStatus DecodeLoadQFP(MCInst &Inst, unsigned insn, uint64_t Address, 334 const void *Decoder) { 335 return DecodeMem(Inst, insn, Address, Decoder, true, 336 DecodeQFPRegsRegisterClass); 337 } 338 339 static DecodeStatus DecodeStoreInt(MCInst &Inst, unsigned insn, 340 uint64_t Address, const void *Decoder) { 341 return DecodeMem(Inst, insn, Address, Decoder, false, 342 DecodeIntRegsRegisterClass); 343 } 344 345 static DecodeStatus DecodeStoreFP(MCInst &Inst, unsigned insn, uint64_t Address, 346 const void *Decoder) { 347 return DecodeMem(Inst, insn, Address, Decoder, false, 348 DecodeFPRegsRegisterClass); 349 } 350 351 static DecodeStatus DecodeStoreDFP(MCInst &Inst, unsigned insn, 352 uint64_t Address, const void *Decoder) { 353 return DecodeMem(Inst, insn, Address, Decoder, false, 354 DecodeDFPRegsRegisterClass); 355 } 356 357 static DecodeStatus DecodeStoreQFP(MCInst &Inst, unsigned insn, 358 uint64_t Address, const void *Decoder) { 359 return DecodeMem(Inst, insn, Address, Decoder, false, 360 DecodeQFPRegsRegisterClass); 361 } 362 363 static bool tryAddingSymbolicOperand(int64_t Value, bool isBranch, 364 uint64_t Address, uint64_t Offset, 365 uint64_t Width, MCInst &MI, 366 const void *Decoder) { 367 const MCDisassembler *Dis = static_cast<const MCDisassembler*>(Decoder); 368 return Dis->tryAddingSymbolicOperand(MI, Value, Address, isBranch, 369 Offset, Width); 370 } 371 372 static DecodeStatus DecodeCall(MCInst &MI, unsigned insn, 373 uint64_t Address, const void *Decoder) { 374 unsigned tgt = fieldFromInstruction(insn, 0, 30); 375 tgt <<= 2; 376 if (!tryAddingSymbolicOperand(tgt+Address, false, Address, 377 0, 30, MI, Decoder)) 378 MI.addOperand(MCOperand::CreateImm(tgt)); 379 return MCDisassembler::Success; 380 } 381 382 static DecodeStatus DecodeSIMM13(MCInst &MI, unsigned insn, 383 uint64_t Address, const void *Decoder) { 384 unsigned tgt = SignExtend32<13>(fieldFromInstruction(insn, 0, 13)); 385 MI.addOperand(MCOperand::CreateImm(tgt)); 386 return MCDisassembler::Success; 387 } 388 389 static DecodeStatus DecodeJMPL(MCInst &MI, unsigned insn, uint64_t Address, 390 const void *Decoder) { 391 392 unsigned rd = fieldFromInstruction(insn, 25, 5); 393 unsigned rs1 = fieldFromInstruction(insn, 14, 5); 394 unsigned isImm = fieldFromInstruction(insn, 13, 1); 395 unsigned rs2 = 0; 396 unsigned simm13 = 0; 397 if (isImm) 398 simm13 = SignExtend32<13>(fieldFromInstruction(insn, 0, 13)); 399 else 400 rs2 = fieldFromInstruction(insn, 0, 5); 401 402 // Decode RD. 403 DecodeStatus status = DecodeIntRegsRegisterClass(MI, rd, Address, Decoder); 404 if (status != MCDisassembler::Success) 405 return status; 406 407 // Decode RS1. 408 status = DecodeIntRegsRegisterClass(MI, rs1, Address, Decoder); 409 if (status != MCDisassembler::Success) 410 return status; 411 412 // Decode RS1 | SIMM13. 413 if (isImm) 414 MI.addOperand(MCOperand::CreateImm(simm13)); 415 else { 416 status = DecodeIntRegsRegisterClass(MI, rs2, Address, Decoder); 417 if (status != MCDisassembler::Success) 418 return status; 419 } 420 return MCDisassembler::Success; 421 } 422 423 static DecodeStatus DecodeReturn(MCInst &MI, unsigned insn, uint64_t Address, 424 const void *Decoder) { 425 426 unsigned rs1 = fieldFromInstruction(insn, 14, 5); 427 unsigned isImm = fieldFromInstruction(insn, 13, 1); 428 unsigned rs2 = 0; 429 unsigned simm13 = 0; 430 if (isImm) 431 simm13 = SignExtend32<13>(fieldFromInstruction(insn, 0, 13)); 432 else 433 rs2 = fieldFromInstruction(insn, 0, 5); 434 435 // Decode RS1. 436 DecodeStatus status = DecodeIntRegsRegisterClass(MI, rs1, Address, Decoder); 437 if (status != MCDisassembler::Success) 438 return status; 439 440 // Decode RS2 | SIMM13. 441 if (isImm) 442 MI.addOperand(MCOperand::CreateImm(simm13)); 443 else { 444 status = DecodeIntRegsRegisterClass(MI, rs2, Address, Decoder); 445 if (status != MCDisassembler::Success) 446 return status; 447 } 448 return MCDisassembler::Success; 449 } 450 451 static DecodeStatus DecodeSWAP(MCInst &MI, unsigned insn, uint64_t Address, 452 const void *Decoder) { 453 454 unsigned rd = fieldFromInstruction(insn, 25, 5); 455 unsigned rs1 = fieldFromInstruction(insn, 14, 5); 456 unsigned isImm = fieldFromInstruction(insn, 13, 1); 457 unsigned rs2 = 0; 458 unsigned simm13 = 0; 459 if (isImm) 460 simm13 = SignExtend32<13>(fieldFromInstruction(insn, 0, 13)); 461 else 462 rs2 = fieldFromInstruction(insn, 0, 5); 463 464 // Decode RD. 465 DecodeStatus status = DecodeIntRegsRegisterClass(MI, rd, Address, Decoder); 466 if (status != MCDisassembler::Success) 467 return status; 468 469 // Decode RS1. 470 status = DecodeIntRegsRegisterClass(MI, rs1, Address, Decoder); 471 if (status != MCDisassembler::Success) 472 return status; 473 474 // Decode RS1 | SIMM13. 475 if (isImm) 476 MI.addOperand(MCOperand::CreateImm(simm13)); 477 else { 478 status = DecodeIntRegsRegisterClass(MI, rs2, Address, Decoder); 479 if (status != MCDisassembler::Success) 480 return status; 481 } 482 return MCDisassembler::Success; 483 } 484