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 #include "Sparc.h" 15 #include "SparcRegisterInfo.h" 16 #include "SparcSubtarget.h" 17 #include "llvm/MC/MCDisassembler/MCDisassembler.h" 18 #include "llvm/MC/MCFixedLenDisassembler.h" 19 #include "llvm/MC/MCInst.h" 20 #include "llvm/MC/MCContext.h" 21 #include "llvm/MC/MCAsmInfo.h" 22 #include "llvm/Support/TargetRegistry.h" 23 24 using namespace llvm; 25 26 #define DEBUG_TYPE "sparc-disassembler" 27 28 typedef MCDisassembler::DecodeStatus DecodeStatus; 29 30 namespace { 31 32 /// A disassembler class for Sparc. 33 class SparcDisassembler : public MCDisassembler { 34 public: 35 SparcDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx) 36 : MCDisassembler(STI, Ctx) {} 37 virtual ~SparcDisassembler() {} 38 39 DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size, 40 ArrayRef<uint8_t> Bytes, uint64_t Address, 41 raw_ostream &VStream, 42 raw_ostream &CStream) const override; 43 }; 44 } 45 46 namespace llvm { 47 extern Target TheSparcTarget, TheSparcV9Target, TheSparcelTarget; 48 } 49 50 static MCDisassembler *createSparcDisassembler(const Target &T, 51 const MCSubtargetInfo &STI, 52 MCContext &Ctx) { 53 return new SparcDisassembler(STI, Ctx); 54 } 55 56 57 extern "C" void LLVMInitializeSparcDisassembler() { 58 // Register the disassembler. 59 TargetRegistry::RegisterMCDisassembler(TheSparcTarget, 60 createSparcDisassembler); 61 TargetRegistry::RegisterMCDisassembler(TheSparcV9Target, 62 createSparcDisassembler); 63 TargetRegistry::RegisterMCDisassembler(TheSparcelTarget, 64 createSparcDisassembler); 65 } 66 67 static const unsigned IntRegDecoderTable[] = { 68 SP::G0, SP::G1, SP::G2, SP::G3, 69 SP::G4, SP::G5, SP::G6, SP::G7, 70 SP::O0, SP::O1, SP::O2, SP::O3, 71 SP::O4, SP::O5, SP::O6, SP::O7, 72 SP::L0, SP::L1, SP::L2, SP::L3, 73 SP::L4, SP::L5, SP::L6, SP::L7, 74 SP::I0, SP::I1, SP::I2, SP::I3, 75 SP::I4, SP::I5, SP::I6, SP::I7 }; 76 77 static const unsigned FPRegDecoderTable[] = { 78 SP::F0, SP::F1, SP::F2, SP::F3, 79 SP::F4, SP::F5, SP::F6, SP::F7, 80 SP::F8, SP::F9, SP::F10, SP::F11, 81 SP::F12, SP::F13, SP::F14, SP::F15, 82 SP::F16, SP::F17, SP::F18, SP::F19, 83 SP::F20, SP::F21, SP::F22, SP::F23, 84 SP::F24, SP::F25, SP::F26, SP::F27, 85 SP::F28, SP::F29, SP::F30, SP::F31 }; 86 87 static const unsigned DFPRegDecoderTable[] = { 88 SP::D0, SP::D16, SP::D1, SP::D17, 89 SP::D2, SP::D18, SP::D3, SP::D19, 90 SP::D4, SP::D20, SP::D5, SP::D21, 91 SP::D6, SP::D22, SP::D7, SP::D23, 92 SP::D8, SP::D24, SP::D9, SP::D25, 93 SP::D10, SP::D26, SP::D11, SP::D27, 94 SP::D12, SP::D28, SP::D13, SP::D29, 95 SP::D14, SP::D30, SP::D15, SP::D31 }; 96 97 static const unsigned QFPRegDecoderTable[] = { 98 SP::Q0, SP::Q8, ~0U, ~0U, 99 SP::Q1, SP::Q9, ~0U, ~0U, 100 SP::Q2, SP::Q10, ~0U, ~0U, 101 SP::Q3, SP::Q11, ~0U, ~0U, 102 SP::Q4, SP::Q12, ~0U, ~0U, 103 SP::Q5, SP::Q13, ~0U, ~0U, 104 SP::Q6, SP::Q14, ~0U, ~0U, 105 SP::Q7, SP::Q15, ~0U, ~0U } ; 106 107 static const unsigned FCCRegDecoderTable[] = { 108 SP::FCC0, SP::FCC1, SP::FCC2, SP::FCC3 }; 109 110 static const unsigned ASRRegDecoderTable[] = { 111 SP::Y, SP::ASR1, SP::ASR2, SP::ASR3, 112 SP::ASR4, SP::ASR5, SP::ASR6, SP::ASR7, 113 SP::ASR8, SP::ASR9, SP::ASR10, SP::ASR11, 114 SP::ASR12, SP::ASR13, SP::ASR14, SP::ASR15, 115 SP::ASR16, SP::ASR17, SP::ASR18, SP::ASR19, 116 SP::ASR20, SP::ASR21, SP::ASR22, SP::ASR23, 117 SP::ASR24, SP::ASR25, SP::ASR26, SP::ASR27, 118 SP::ASR28, SP::ASR29, SP::ASR30, SP::ASR31}; 119 120 static const unsigned PRRegDecoderTable[] = { 121 SP::TPC, SP::TNPC, SP::TSTATE, SP::TT, SP::TICK, SP::TBA, SP::PSTATE, 122 SP::TL, SP::PIL, SP::CWP, SP::CANSAVE, SP::CANRESTORE, SP::CLEANWIN, 123 SP::OTHERWIN, SP::WSTATE 124 }; 125 126 static const uint16_t IntPairDecoderTable[] = { 127 SP::G0_G1, SP::G2_G3, SP::G4_G5, SP::G6_G7, 128 SP::O0_O1, SP::O2_O3, SP::O4_O5, SP::O6_O7, 129 SP::L0_L1, SP::L2_L3, SP::L4_L5, SP::L6_L7, 130 SP::I0_I1, SP::I2_I3, SP::I4_I5, SP::I6_I7, 131 }; 132 133 static DecodeStatus DecodeIntRegsRegisterClass(MCInst &Inst, 134 unsigned RegNo, 135 uint64_t Address, 136 const void *Decoder) { 137 if (RegNo > 31) 138 return MCDisassembler::Fail; 139 unsigned Reg = IntRegDecoderTable[RegNo]; 140 Inst.addOperand(MCOperand::createReg(Reg)); 141 return MCDisassembler::Success; 142 } 143 144 static DecodeStatus DecodeI64RegsRegisterClass(MCInst &Inst, 145 unsigned RegNo, 146 uint64_t Address, 147 const void *Decoder) { 148 if (RegNo > 31) 149 return MCDisassembler::Fail; 150 unsigned Reg = IntRegDecoderTable[RegNo]; 151 Inst.addOperand(MCOperand::createReg(Reg)); 152 return MCDisassembler::Success; 153 } 154 155 156 static DecodeStatus DecodeFPRegsRegisterClass(MCInst &Inst, 157 unsigned RegNo, 158 uint64_t Address, 159 const void *Decoder) { 160 if (RegNo > 31) 161 return MCDisassembler::Fail; 162 unsigned Reg = FPRegDecoderTable[RegNo]; 163 Inst.addOperand(MCOperand::createReg(Reg)); 164 return MCDisassembler::Success; 165 } 166 167 168 static DecodeStatus DecodeDFPRegsRegisterClass(MCInst &Inst, 169 unsigned RegNo, 170 uint64_t Address, 171 const void *Decoder) { 172 if (RegNo > 31) 173 return MCDisassembler::Fail; 174 unsigned Reg = DFPRegDecoderTable[RegNo]; 175 Inst.addOperand(MCOperand::createReg(Reg)); 176 return MCDisassembler::Success; 177 } 178 179 180 static DecodeStatus DecodeQFPRegsRegisterClass(MCInst &Inst, 181 unsigned RegNo, 182 uint64_t Address, 183 const void *Decoder) { 184 if (RegNo > 31) 185 return MCDisassembler::Fail; 186 187 unsigned Reg = QFPRegDecoderTable[RegNo]; 188 if (Reg == ~0U) 189 return MCDisassembler::Fail; 190 Inst.addOperand(MCOperand::createReg(Reg)); 191 return MCDisassembler::Success; 192 } 193 194 static DecodeStatus DecodeFCCRegsRegisterClass(MCInst &Inst, unsigned RegNo, 195 uint64_t Address, 196 const void *Decoder) { 197 if (RegNo > 3) 198 return MCDisassembler::Fail; 199 Inst.addOperand(MCOperand::createReg(FCCRegDecoderTable[RegNo])); 200 return MCDisassembler::Success; 201 } 202 203 static DecodeStatus DecodeASRRegsRegisterClass(MCInst &Inst, unsigned RegNo, 204 uint64_t Address, 205 const void *Decoder) { 206 if (RegNo > 31) 207 return MCDisassembler::Fail; 208 Inst.addOperand(MCOperand::createReg(ASRRegDecoderTable[RegNo])); 209 return MCDisassembler::Success; 210 } 211 212 static DecodeStatus DecodePRRegsRegisterClass(MCInst &Inst, unsigned RegNo, 213 uint64_t Address, 214 const void *Decoder) { 215 if (RegNo >= array_lengthof(PRRegDecoderTable)) 216 return MCDisassembler::Fail; 217 Inst.addOperand(MCOperand::createReg(PRRegDecoderTable[RegNo])); 218 return MCDisassembler::Success; 219 } 220 221 static DecodeStatus DecodeIntPairRegisterClass(MCInst &Inst, unsigned RegNo, 222 uint64_t Address, const void *Decoder) { 223 DecodeStatus S = MCDisassembler::Success; 224 225 if (RegNo > 31) 226 return MCDisassembler::Fail; 227 228 if ((RegNo & 1)) 229 S = MCDisassembler::SoftFail; 230 231 unsigned RegisterPair = IntPairDecoderTable[RegNo/2]; 232 Inst.addOperand(MCOperand::createReg(RegisterPair)); 233 return S; 234 } 235 236 static DecodeStatus DecodeLoadInt(MCInst &Inst, unsigned insn, uint64_t Address, 237 const void *Decoder); 238 static DecodeStatus DecodeLoadIntPair(MCInst &Inst, unsigned insn, uint64_t Address, 239 const void *Decoder); 240 static DecodeStatus DecodeLoadFP(MCInst &Inst, unsigned insn, uint64_t Address, 241 const void *Decoder); 242 static DecodeStatus DecodeLoadDFP(MCInst &Inst, unsigned insn, uint64_t Address, 243 const void *Decoder); 244 static DecodeStatus DecodeLoadQFP(MCInst &Inst, unsigned insn, uint64_t Address, 245 const void *Decoder); 246 static DecodeStatus DecodeStoreInt(MCInst &Inst, unsigned insn, 247 uint64_t Address, const void *Decoder); 248 static DecodeStatus DecodeStoreIntPair(MCInst &Inst, unsigned insn, 249 uint64_t Address, const void *Decoder); 250 static DecodeStatus DecodeStoreFP(MCInst &Inst, unsigned insn, 251 uint64_t Address, const void *Decoder); 252 static DecodeStatus DecodeStoreDFP(MCInst &Inst, unsigned insn, 253 uint64_t Address, const void *Decoder); 254 static DecodeStatus DecodeStoreQFP(MCInst &Inst, unsigned insn, 255 uint64_t Address, const void *Decoder); 256 static DecodeStatus DecodeCall(MCInst &Inst, unsigned insn, 257 uint64_t Address, const void *Decoder); 258 static DecodeStatus DecodeSIMM13(MCInst &Inst, unsigned insn, 259 uint64_t Address, const void *Decoder); 260 static DecodeStatus DecodeJMPL(MCInst &Inst, unsigned insn, uint64_t Address, 261 const void *Decoder); 262 static DecodeStatus DecodeReturn(MCInst &MI, unsigned insn, uint64_t Address, 263 const void *Decoder); 264 static DecodeStatus DecodeSWAP(MCInst &Inst, unsigned insn, uint64_t Address, 265 const void *Decoder); 266 267 #include "SparcGenDisassemblerTables.inc" 268 269 /// Read four bytes from the ArrayRef and return 32 bit word. 270 static DecodeStatus readInstruction32(ArrayRef<uint8_t> Bytes, uint64_t Address, 271 uint64_t &Size, uint32_t &Insn, 272 bool IsLittleEndian) { 273 // We want to read exactly 4 Bytes of data. 274 if (Bytes.size() < 4) { 275 Size = 0; 276 return MCDisassembler::Fail; 277 } 278 279 Insn = IsLittleEndian 280 ? (Bytes[0] << 0) | (Bytes[1] << 8) | (Bytes[2] << 16) | 281 (Bytes[3] << 24) 282 : (Bytes[3] << 0) | (Bytes[2] << 8) | (Bytes[1] << 16) | 283 (Bytes[0] << 24); 284 285 return MCDisassembler::Success; 286 } 287 288 DecodeStatus SparcDisassembler::getInstruction(MCInst &Instr, uint64_t &Size, 289 ArrayRef<uint8_t> Bytes, 290 uint64_t Address, 291 raw_ostream &VStream, 292 raw_ostream &CStream) const { 293 uint32_t Insn; 294 bool isLittleEndian = getContext().getAsmInfo()->isLittleEndian(); 295 DecodeStatus Result = 296 readInstruction32(Bytes, Address, Size, Insn, isLittleEndian); 297 if (Result == MCDisassembler::Fail) 298 return MCDisassembler::Fail; 299 300 // Calling the auto-generated decoder function. 301 Result = 302 decodeInstruction(DecoderTableSparc32, Instr, Insn, Address, this, STI); 303 304 if (Result != MCDisassembler::Fail) { 305 Size = 4; 306 return Result; 307 } 308 309 return MCDisassembler::Fail; 310 } 311 312 313 typedef DecodeStatus (*DecodeFunc)(MCInst &MI, unsigned insn, uint64_t Address, 314 const void *Decoder); 315 316 static DecodeStatus DecodeMem(MCInst &MI, unsigned insn, uint64_t Address, 317 const void *Decoder, 318 bool isLoad, DecodeFunc DecodeRD) { 319 unsigned rd = fieldFromInstruction(insn, 25, 5); 320 unsigned rs1 = fieldFromInstruction(insn, 14, 5); 321 bool isImm = fieldFromInstruction(insn, 13, 1); 322 bool hasAsi = fieldFromInstruction(insn, 23, 1); // (in op3 field) 323 unsigned asi = fieldFromInstruction(insn, 5, 8); 324 unsigned rs2 = 0; 325 unsigned simm13 = 0; 326 if (isImm) 327 simm13 = SignExtend32<13>(fieldFromInstruction(insn, 0, 13)); 328 else 329 rs2 = fieldFromInstruction(insn, 0, 5); 330 331 DecodeStatus status; 332 if (isLoad) { 333 status = DecodeRD(MI, rd, Address, Decoder); 334 if (status != MCDisassembler::Success) 335 return status; 336 } 337 338 // Decode rs1. 339 status = DecodeIntRegsRegisterClass(MI, rs1, Address, Decoder); 340 if (status != MCDisassembler::Success) 341 return status; 342 343 // Decode imm|rs2. 344 if (isImm) 345 MI.addOperand(MCOperand::createImm(simm13)); 346 else { 347 status = DecodeIntRegsRegisterClass(MI, rs2, Address, Decoder); 348 if (status != MCDisassembler::Success) 349 return status; 350 } 351 352 if (hasAsi) 353 MI.addOperand(MCOperand::createImm(asi)); 354 355 if (!isLoad) { 356 status = DecodeRD(MI, rd, Address, Decoder); 357 if (status != MCDisassembler::Success) 358 return status; 359 } 360 return MCDisassembler::Success; 361 } 362 363 static DecodeStatus DecodeLoadInt(MCInst &Inst, unsigned insn, uint64_t Address, 364 const void *Decoder) { 365 return DecodeMem(Inst, insn, Address, Decoder, true, 366 DecodeIntRegsRegisterClass); 367 } 368 369 static DecodeStatus DecodeLoadIntPair(MCInst &Inst, unsigned insn, uint64_t Address, 370 const void *Decoder) { 371 return DecodeMem(Inst, insn, Address, Decoder, true, 372 DecodeIntPairRegisterClass); 373 } 374 375 static DecodeStatus DecodeLoadFP(MCInst &Inst, unsigned insn, uint64_t Address, 376 const void *Decoder) { 377 return DecodeMem(Inst, insn, Address, Decoder, true, 378 DecodeFPRegsRegisterClass); 379 } 380 381 static DecodeStatus DecodeLoadDFP(MCInst &Inst, unsigned insn, uint64_t Address, 382 const void *Decoder) { 383 return DecodeMem(Inst, insn, Address, Decoder, true, 384 DecodeDFPRegsRegisterClass); 385 } 386 387 static DecodeStatus DecodeLoadQFP(MCInst &Inst, unsigned insn, uint64_t Address, 388 const void *Decoder) { 389 return DecodeMem(Inst, insn, Address, Decoder, true, 390 DecodeQFPRegsRegisterClass); 391 } 392 393 static DecodeStatus DecodeStoreInt(MCInst &Inst, unsigned insn, 394 uint64_t Address, const void *Decoder) { 395 return DecodeMem(Inst, insn, Address, Decoder, false, 396 DecodeIntRegsRegisterClass); 397 } 398 399 static DecodeStatus DecodeStoreIntPair(MCInst &Inst, unsigned insn, 400 uint64_t Address, const void *Decoder) { 401 return DecodeMem(Inst, insn, Address, Decoder, false, 402 DecodeIntPairRegisterClass); 403 } 404 405 static DecodeStatus DecodeStoreFP(MCInst &Inst, unsigned insn, uint64_t Address, 406 const void *Decoder) { 407 return DecodeMem(Inst, insn, Address, Decoder, false, 408 DecodeFPRegsRegisterClass); 409 } 410 411 static DecodeStatus DecodeStoreDFP(MCInst &Inst, unsigned insn, 412 uint64_t Address, const void *Decoder) { 413 return DecodeMem(Inst, insn, Address, Decoder, false, 414 DecodeDFPRegsRegisterClass); 415 } 416 417 static DecodeStatus DecodeStoreQFP(MCInst &Inst, unsigned insn, 418 uint64_t Address, const void *Decoder) { 419 return DecodeMem(Inst, insn, Address, Decoder, false, 420 DecodeQFPRegsRegisterClass); 421 } 422 423 static bool tryAddingSymbolicOperand(int64_t Value, bool isBranch, 424 uint64_t Address, uint64_t Offset, 425 uint64_t Width, MCInst &MI, 426 const void *Decoder) { 427 const MCDisassembler *Dis = static_cast<const MCDisassembler*>(Decoder); 428 return Dis->tryAddingSymbolicOperand(MI, Value, Address, isBranch, 429 Offset, Width); 430 } 431 432 static DecodeStatus DecodeCall(MCInst &MI, unsigned insn, 433 uint64_t Address, const void *Decoder) { 434 unsigned tgt = fieldFromInstruction(insn, 0, 30); 435 tgt <<= 2; 436 if (!tryAddingSymbolicOperand(tgt+Address, false, Address, 437 0, 30, MI, Decoder)) 438 MI.addOperand(MCOperand::createImm(tgt)); 439 return MCDisassembler::Success; 440 } 441 442 static DecodeStatus DecodeSIMM13(MCInst &MI, unsigned insn, 443 uint64_t Address, const void *Decoder) { 444 unsigned tgt = SignExtend32<13>(fieldFromInstruction(insn, 0, 13)); 445 MI.addOperand(MCOperand::createImm(tgt)); 446 return MCDisassembler::Success; 447 } 448 449 static DecodeStatus DecodeJMPL(MCInst &MI, unsigned insn, uint64_t Address, 450 const void *Decoder) { 451 452 unsigned rd = fieldFromInstruction(insn, 25, 5); 453 unsigned rs1 = fieldFromInstruction(insn, 14, 5); 454 unsigned isImm = fieldFromInstruction(insn, 13, 1); 455 unsigned rs2 = 0; 456 unsigned simm13 = 0; 457 if (isImm) 458 simm13 = SignExtend32<13>(fieldFromInstruction(insn, 0, 13)); 459 else 460 rs2 = fieldFromInstruction(insn, 0, 5); 461 462 // Decode RD. 463 DecodeStatus status = DecodeIntRegsRegisterClass(MI, rd, Address, Decoder); 464 if (status != MCDisassembler::Success) 465 return status; 466 467 // Decode RS1. 468 status = DecodeIntRegsRegisterClass(MI, rs1, Address, Decoder); 469 if (status != MCDisassembler::Success) 470 return status; 471 472 // Decode RS1 | SIMM13. 473 if (isImm) 474 MI.addOperand(MCOperand::createImm(simm13)); 475 else { 476 status = DecodeIntRegsRegisterClass(MI, rs2, Address, Decoder); 477 if (status != MCDisassembler::Success) 478 return status; 479 } 480 return MCDisassembler::Success; 481 } 482 483 static DecodeStatus DecodeReturn(MCInst &MI, unsigned insn, uint64_t Address, 484 const void *Decoder) { 485 486 unsigned rs1 = fieldFromInstruction(insn, 14, 5); 487 unsigned isImm = fieldFromInstruction(insn, 13, 1); 488 unsigned rs2 = 0; 489 unsigned simm13 = 0; 490 if (isImm) 491 simm13 = SignExtend32<13>(fieldFromInstruction(insn, 0, 13)); 492 else 493 rs2 = fieldFromInstruction(insn, 0, 5); 494 495 // Decode RS1. 496 DecodeStatus status = DecodeIntRegsRegisterClass(MI, rs1, Address, Decoder); 497 if (status != MCDisassembler::Success) 498 return status; 499 500 // Decode RS2 | SIMM13. 501 if (isImm) 502 MI.addOperand(MCOperand::createImm(simm13)); 503 else { 504 status = DecodeIntRegsRegisterClass(MI, rs2, Address, Decoder); 505 if (status != MCDisassembler::Success) 506 return status; 507 } 508 return MCDisassembler::Success; 509 } 510 511 static DecodeStatus DecodeSWAP(MCInst &MI, unsigned insn, uint64_t Address, 512 const void *Decoder) { 513 514 unsigned rd = fieldFromInstruction(insn, 25, 5); 515 unsigned rs1 = fieldFromInstruction(insn, 14, 5); 516 unsigned isImm = fieldFromInstruction(insn, 13, 1); 517 bool hasAsi = fieldFromInstruction(insn, 23, 1); // (in op3 field) 518 unsigned asi = fieldFromInstruction(insn, 5, 8); 519 unsigned rs2 = 0; 520 unsigned simm13 = 0; 521 if (isImm) 522 simm13 = SignExtend32<13>(fieldFromInstruction(insn, 0, 13)); 523 else 524 rs2 = fieldFromInstruction(insn, 0, 5); 525 526 // Decode RD. 527 DecodeStatus status = DecodeIntRegsRegisterClass(MI, rd, Address, Decoder); 528 if (status != MCDisassembler::Success) 529 return status; 530 531 // Decode RS1. 532 status = DecodeIntRegsRegisterClass(MI, rs1, Address, Decoder); 533 if (status != MCDisassembler::Success) 534 return status; 535 536 // Decode RS1 | SIMM13. 537 if (isImm) 538 MI.addOperand(MCOperand::createImm(simm13)); 539 else { 540 status = DecodeIntRegsRegisterClass(MI, rs2, Address, Decoder); 541 if (status != MCDisassembler::Success) 542 return status; 543 } 544 545 if (hasAsi) 546 MI.addOperand(MCOperand::createImm(asi)); 547 548 return MCDisassembler::Success; 549 } 550