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.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 uint16_t IntPairDecoderTable[] = { 121 SP::G0_G1, SP::G2_G3, SP::G4_G5, SP::G6_G7, 122 SP::O0_O1, SP::O2_O3, SP::O4_O5, SP::O6_O7, 123 SP::L0_L1, SP::L2_L3, SP::L4_L5, SP::L6_L7, 124 SP::I0_I1, SP::I2_I3, SP::I4_I5, SP::I6_I7, 125 }; 126 127 static DecodeStatus DecodeIntRegsRegisterClass(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 static DecodeStatus DecodeI64RegsRegisterClass(MCInst &Inst, 139 unsigned RegNo, 140 uint64_t Address, 141 const void *Decoder) { 142 if (RegNo > 31) 143 return MCDisassembler::Fail; 144 unsigned Reg = IntRegDecoderTable[RegNo]; 145 Inst.addOperand(MCOperand::createReg(Reg)); 146 return MCDisassembler::Success; 147 } 148 149 150 static DecodeStatus DecodeFPRegsRegisterClass(MCInst &Inst, 151 unsigned RegNo, 152 uint64_t Address, 153 const void *Decoder) { 154 if (RegNo > 31) 155 return MCDisassembler::Fail; 156 unsigned Reg = FPRegDecoderTable[RegNo]; 157 Inst.addOperand(MCOperand::createReg(Reg)); 158 return MCDisassembler::Success; 159 } 160 161 162 static DecodeStatus DecodeDFPRegsRegisterClass(MCInst &Inst, 163 unsigned RegNo, 164 uint64_t Address, 165 const void *Decoder) { 166 if (RegNo > 31) 167 return MCDisassembler::Fail; 168 unsigned Reg = DFPRegDecoderTable[RegNo]; 169 Inst.addOperand(MCOperand::createReg(Reg)); 170 return MCDisassembler::Success; 171 } 172 173 174 static DecodeStatus DecodeQFPRegsRegisterClass(MCInst &Inst, 175 unsigned RegNo, 176 uint64_t Address, 177 const void *Decoder) { 178 if (RegNo > 31) 179 return MCDisassembler::Fail; 180 181 unsigned Reg = QFPRegDecoderTable[RegNo]; 182 if (Reg == ~0U) 183 return MCDisassembler::Fail; 184 Inst.addOperand(MCOperand::createReg(Reg)); 185 return MCDisassembler::Success; 186 } 187 188 static DecodeStatus DecodeFCCRegsRegisterClass(MCInst &Inst, unsigned RegNo, 189 uint64_t Address, 190 const void *Decoder) { 191 if (RegNo > 3) 192 return MCDisassembler::Fail; 193 Inst.addOperand(MCOperand::createReg(FCCRegDecoderTable[RegNo])); 194 return MCDisassembler::Success; 195 } 196 197 static DecodeStatus DecodeASRRegsRegisterClass(MCInst &Inst, unsigned RegNo, 198 uint64_t Address, 199 const void *Decoder) { 200 if (RegNo > 31) 201 return MCDisassembler::Fail; 202 Inst.addOperand(MCOperand::createReg(ASRRegDecoderTable[RegNo])); 203 return MCDisassembler::Success; 204 } 205 206 static DecodeStatus DecodeIntPairRegisterClass(MCInst &Inst, unsigned RegNo, 207 uint64_t Address, const void *Decoder) { 208 DecodeStatus S = MCDisassembler::Success; 209 210 if (RegNo > 31) 211 return MCDisassembler::Fail; 212 213 if ((RegNo & 1)) 214 S = MCDisassembler::SoftFail; 215 216 unsigned RegisterPair = IntPairDecoderTable[RegNo/2]; 217 Inst.addOperand(MCOperand::createReg(RegisterPair)); 218 return S; 219 } 220 221 static DecodeStatus DecodeLoadInt(MCInst &Inst, unsigned insn, uint64_t Address, 222 const void *Decoder); 223 static DecodeStatus DecodeLoadIntPair(MCInst &Inst, unsigned insn, uint64_t Address, 224 const void *Decoder); 225 static DecodeStatus DecodeLoadFP(MCInst &Inst, unsigned insn, uint64_t Address, 226 const void *Decoder); 227 static DecodeStatus DecodeLoadDFP(MCInst &Inst, unsigned insn, uint64_t Address, 228 const void *Decoder); 229 static DecodeStatus DecodeLoadQFP(MCInst &Inst, unsigned insn, uint64_t Address, 230 const void *Decoder); 231 static DecodeStatus DecodeStoreInt(MCInst &Inst, unsigned insn, 232 uint64_t Address, const void *Decoder); 233 static DecodeStatus DecodeStoreIntPair(MCInst &Inst, unsigned insn, 234 uint64_t Address, const void *Decoder); 235 static DecodeStatus DecodeStoreFP(MCInst &Inst, unsigned insn, 236 uint64_t Address, const void *Decoder); 237 static DecodeStatus DecodeStoreDFP(MCInst &Inst, unsigned insn, 238 uint64_t Address, const void *Decoder); 239 static DecodeStatus DecodeStoreQFP(MCInst &Inst, unsigned insn, 240 uint64_t Address, const void *Decoder); 241 static DecodeStatus DecodeCall(MCInst &Inst, unsigned insn, 242 uint64_t Address, const void *Decoder); 243 static DecodeStatus DecodeSIMM13(MCInst &Inst, unsigned insn, 244 uint64_t Address, const void *Decoder); 245 static DecodeStatus DecodeJMPL(MCInst &Inst, unsigned insn, uint64_t Address, 246 const void *Decoder); 247 static DecodeStatus DecodeReturn(MCInst &MI, unsigned insn, uint64_t Address, 248 const void *Decoder); 249 static DecodeStatus DecodeSWAP(MCInst &Inst, unsigned insn, uint64_t Address, 250 const void *Decoder); 251 252 #include "SparcGenDisassemblerTables.inc" 253 254 /// Read four bytes from the ArrayRef and return 32 bit word. 255 static DecodeStatus readInstruction32(ArrayRef<uint8_t> Bytes, uint64_t Address, 256 uint64_t &Size, uint32_t &Insn, 257 bool IsLittleEndian) { 258 // We want to read exactly 4 Bytes of data. 259 if (Bytes.size() < 4) { 260 Size = 0; 261 return MCDisassembler::Fail; 262 } 263 264 Insn = IsLittleEndian 265 ? (Bytes[0] << 0) | (Bytes[1] << 8) | (Bytes[2] << 16) | 266 (Bytes[3] << 24) 267 : (Bytes[3] << 0) | (Bytes[2] << 8) | (Bytes[1] << 16) | 268 (Bytes[0] << 24); 269 270 return MCDisassembler::Success; 271 } 272 273 DecodeStatus SparcDisassembler::getInstruction(MCInst &Instr, uint64_t &Size, 274 ArrayRef<uint8_t> Bytes, 275 uint64_t Address, 276 raw_ostream &VStream, 277 raw_ostream &CStream) const { 278 uint32_t Insn; 279 bool isLittleEndian = getContext().getAsmInfo()->isLittleEndian(); 280 DecodeStatus Result = 281 readInstruction32(Bytes, Address, Size, Insn, isLittleEndian); 282 if (Result == MCDisassembler::Fail) 283 return MCDisassembler::Fail; 284 285 // Calling the auto-generated decoder function. 286 Result = 287 decodeInstruction(DecoderTableSparc32, Instr, Insn, Address, this, STI); 288 289 if (Result != MCDisassembler::Fail) { 290 Size = 4; 291 return Result; 292 } 293 294 return MCDisassembler::Fail; 295 } 296 297 298 typedef DecodeStatus (*DecodeFunc)(MCInst &MI, unsigned insn, uint64_t Address, 299 const void *Decoder); 300 301 static DecodeStatus DecodeMem(MCInst &MI, unsigned insn, uint64_t Address, 302 const void *Decoder, 303 bool isLoad, DecodeFunc DecodeRD) { 304 unsigned rd = fieldFromInstruction(insn, 25, 5); 305 unsigned rs1 = fieldFromInstruction(insn, 14, 5); 306 bool isImm = fieldFromInstruction(insn, 13, 1); 307 bool hasAsi = fieldFromInstruction(insn, 23, 1); // (in op3 field) 308 unsigned asi = fieldFromInstruction(insn, 5, 8); 309 unsigned rs2 = 0; 310 unsigned simm13 = 0; 311 if (isImm) 312 simm13 = SignExtend32<13>(fieldFromInstruction(insn, 0, 13)); 313 else 314 rs2 = fieldFromInstruction(insn, 0, 5); 315 316 DecodeStatus status; 317 if (isLoad) { 318 status = DecodeRD(MI, rd, Address, Decoder); 319 if (status != MCDisassembler::Success) 320 return status; 321 } 322 323 // Decode rs1. 324 status = DecodeIntRegsRegisterClass(MI, rs1, Address, Decoder); 325 if (status != MCDisassembler::Success) 326 return status; 327 328 // Decode imm|rs2. 329 if (isImm) 330 MI.addOperand(MCOperand::createImm(simm13)); 331 else { 332 status = DecodeIntRegsRegisterClass(MI, rs2, Address, Decoder); 333 if (status != MCDisassembler::Success) 334 return status; 335 } 336 337 if (hasAsi) 338 MI.addOperand(MCOperand::createImm(asi)); 339 340 if (!isLoad) { 341 status = DecodeRD(MI, rd, Address, Decoder); 342 if (status != MCDisassembler::Success) 343 return status; 344 } 345 return MCDisassembler::Success; 346 } 347 348 static DecodeStatus DecodeLoadInt(MCInst &Inst, unsigned insn, uint64_t Address, 349 const void *Decoder) { 350 return DecodeMem(Inst, insn, Address, Decoder, true, 351 DecodeIntRegsRegisterClass); 352 } 353 354 static DecodeStatus DecodeLoadIntPair(MCInst &Inst, unsigned insn, uint64_t Address, 355 const void *Decoder) { 356 return DecodeMem(Inst, insn, Address, Decoder, true, 357 DecodeIntPairRegisterClass); 358 } 359 360 static DecodeStatus DecodeLoadFP(MCInst &Inst, unsigned insn, uint64_t Address, 361 const void *Decoder) { 362 return DecodeMem(Inst, insn, Address, Decoder, true, 363 DecodeFPRegsRegisterClass); 364 } 365 366 static DecodeStatus DecodeLoadDFP(MCInst &Inst, unsigned insn, uint64_t Address, 367 const void *Decoder) { 368 return DecodeMem(Inst, insn, Address, Decoder, true, 369 DecodeDFPRegsRegisterClass); 370 } 371 372 static DecodeStatus DecodeLoadQFP(MCInst &Inst, unsigned insn, uint64_t Address, 373 const void *Decoder) { 374 return DecodeMem(Inst, insn, Address, Decoder, true, 375 DecodeQFPRegsRegisterClass); 376 } 377 378 static DecodeStatus DecodeStoreInt(MCInst &Inst, unsigned insn, 379 uint64_t Address, const void *Decoder) { 380 return DecodeMem(Inst, insn, Address, Decoder, false, 381 DecodeIntRegsRegisterClass); 382 } 383 384 static DecodeStatus DecodeStoreIntPair(MCInst &Inst, unsigned insn, 385 uint64_t Address, const void *Decoder) { 386 return DecodeMem(Inst, insn, Address, Decoder, false, 387 DecodeIntPairRegisterClass); 388 } 389 390 static DecodeStatus DecodeStoreFP(MCInst &Inst, unsigned insn, uint64_t Address, 391 const void *Decoder) { 392 return DecodeMem(Inst, insn, Address, Decoder, false, 393 DecodeFPRegsRegisterClass); 394 } 395 396 static DecodeStatus DecodeStoreDFP(MCInst &Inst, unsigned insn, 397 uint64_t Address, const void *Decoder) { 398 return DecodeMem(Inst, insn, Address, Decoder, false, 399 DecodeDFPRegsRegisterClass); 400 } 401 402 static DecodeStatus DecodeStoreQFP(MCInst &Inst, unsigned insn, 403 uint64_t Address, const void *Decoder) { 404 return DecodeMem(Inst, insn, Address, Decoder, false, 405 DecodeQFPRegsRegisterClass); 406 } 407 408 static bool tryAddingSymbolicOperand(int64_t Value, bool isBranch, 409 uint64_t Address, uint64_t Offset, 410 uint64_t Width, MCInst &MI, 411 const void *Decoder) { 412 const MCDisassembler *Dis = static_cast<const MCDisassembler*>(Decoder); 413 return Dis->tryAddingSymbolicOperand(MI, Value, Address, isBranch, 414 Offset, Width); 415 } 416 417 static DecodeStatus DecodeCall(MCInst &MI, unsigned insn, 418 uint64_t Address, const void *Decoder) { 419 unsigned tgt = fieldFromInstruction(insn, 0, 30); 420 tgt <<= 2; 421 if (!tryAddingSymbolicOperand(tgt+Address, false, Address, 422 0, 30, MI, Decoder)) 423 MI.addOperand(MCOperand::createImm(tgt)); 424 return MCDisassembler::Success; 425 } 426 427 static DecodeStatus DecodeSIMM13(MCInst &MI, unsigned insn, 428 uint64_t Address, const void *Decoder) { 429 unsigned tgt = SignExtend32<13>(fieldFromInstruction(insn, 0, 13)); 430 MI.addOperand(MCOperand::createImm(tgt)); 431 return MCDisassembler::Success; 432 } 433 434 static DecodeStatus DecodeJMPL(MCInst &MI, unsigned insn, uint64_t Address, 435 const void *Decoder) { 436 437 unsigned rd = fieldFromInstruction(insn, 25, 5); 438 unsigned rs1 = fieldFromInstruction(insn, 14, 5); 439 unsigned isImm = fieldFromInstruction(insn, 13, 1); 440 unsigned rs2 = 0; 441 unsigned simm13 = 0; 442 if (isImm) 443 simm13 = SignExtend32<13>(fieldFromInstruction(insn, 0, 13)); 444 else 445 rs2 = fieldFromInstruction(insn, 0, 5); 446 447 // Decode RD. 448 DecodeStatus status = DecodeIntRegsRegisterClass(MI, rd, Address, Decoder); 449 if (status != MCDisassembler::Success) 450 return status; 451 452 // Decode RS1. 453 status = DecodeIntRegsRegisterClass(MI, rs1, Address, Decoder); 454 if (status != MCDisassembler::Success) 455 return status; 456 457 // Decode RS1 | SIMM13. 458 if (isImm) 459 MI.addOperand(MCOperand::createImm(simm13)); 460 else { 461 status = DecodeIntRegsRegisterClass(MI, rs2, Address, Decoder); 462 if (status != MCDisassembler::Success) 463 return status; 464 } 465 return MCDisassembler::Success; 466 } 467 468 static DecodeStatus DecodeReturn(MCInst &MI, unsigned insn, uint64_t Address, 469 const void *Decoder) { 470 471 unsigned rs1 = fieldFromInstruction(insn, 14, 5); 472 unsigned isImm = fieldFromInstruction(insn, 13, 1); 473 unsigned rs2 = 0; 474 unsigned simm13 = 0; 475 if (isImm) 476 simm13 = SignExtend32<13>(fieldFromInstruction(insn, 0, 13)); 477 else 478 rs2 = fieldFromInstruction(insn, 0, 5); 479 480 // Decode RS1. 481 DecodeStatus status = DecodeIntRegsRegisterClass(MI, rs1, Address, Decoder); 482 if (status != MCDisassembler::Success) 483 return status; 484 485 // Decode RS2 | SIMM13. 486 if (isImm) 487 MI.addOperand(MCOperand::createImm(simm13)); 488 else { 489 status = DecodeIntRegsRegisterClass(MI, rs2, Address, Decoder); 490 if (status != MCDisassembler::Success) 491 return status; 492 } 493 return MCDisassembler::Success; 494 } 495 496 static DecodeStatus DecodeSWAP(MCInst &MI, unsigned insn, uint64_t Address, 497 const void *Decoder) { 498 499 unsigned rd = fieldFromInstruction(insn, 25, 5); 500 unsigned rs1 = fieldFromInstruction(insn, 14, 5); 501 unsigned isImm = fieldFromInstruction(insn, 13, 1); 502 bool hasAsi = fieldFromInstruction(insn, 23, 1); // (in op3 field) 503 unsigned asi = fieldFromInstruction(insn, 5, 8); 504 unsigned rs2 = 0; 505 unsigned simm13 = 0; 506 if (isImm) 507 simm13 = SignExtend32<13>(fieldFromInstruction(insn, 0, 13)); 508 else 509 rs2 = fieldFromInstruction(insn, 0, 5); 510 511 // Decode RD. 512 DecodeStatus status = DecodeIntRegsRegisterClass(MI, rd, Address, Decoder); 513 if (status != MCDisassembler::Success) 514 return status; 515 516 // Decode RS1. 517 status = DecodeIntRegsRegisterClass(MI, rs1, Address, Decoder); 518 if (status != MCDisassembler::Success) 519 return status; 520 521 // Decode RS1 | SIMM13. 522 if (isImm) 523 MI.addOperand(MCOperand::createImm(simm13)); 524 else { 525 status = DecodeIntRegsRegisterClass(MI, rs2, Address, Decoder); 526 if (status != MCDisassembler::Success) 527 return status; 528 } 529 530 if (hasAsi) 531 MI.addOperand(MCOperand::createImm(asi)); 532 533 return MCDisassembler::Success; 534 } 535