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