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/MCContext.h" 20 #include "llvm/MC/MCAsmInfo.h" 21 #include "llvm/Support/TargetRegistry.h" 22 23 using namespace llvm; 24 25 #define DEBUG_TYPE "sparc-disassembler" 26 27 typedef MCDisassembler::DecodeStatus DecodeStatus; 28 29 namespace { 30 31 /// A disassembler class for Sparc. 32 class SparcDisassembler : public MCDisassembler { 33 public: 34 SparcDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx) 35 : MCDisassembler(STI, Ctx) {} 36 virtual ~SparcDisassembler() {} 37 38 DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size, 39 ArrayRef<uint8_t> Bytes, uint64_t Address, 40 raw_ostream &VStream, 41 raw_ostream &CStream) const override; 42 }; 43 } 44 45 namespace llvm { 46 extern Target TheSparcTarget, TheSparcV9Target, TheSparcelTarget; 47 } 48 49 static MCDisassembler *createSparcDisassembler(const Target &T, 50 const MCSubtargetInfo &STI, 51 MCContext &Ctx) { 52 return new SparcDisassembler(STI, Ctx); 53 } 54 55 56 extern "C" void LLVMInitializeSparcDisassembler() { 57 // Register the disassembler. 58 TargetRegistry::RegisterMCDisassembler(TheSparcTarget, 59 createSparcDisassembler); 60 TargetRegistry::RegisterMCDisassembler(TheSparcV9Target, 61 createSparcDisassembler); 62 TargetRegistry::RegisterMCDisassembler(TheSparcelTarget, 63 createSparcDisassembler); 64 } 65 66 static const unsigned IntRegDecoderTable[] = { 67 SP::G0, SP::G1, SP::G2, SP::G3, 68 SP::G4, SP::G5, SP::G6, SP::G7, 69 SP::O0, SP::O1, SP::O2, SP::O3, 70 SP::O4, SP::O5, SP::O6, SP::O7, 71 SP::L0, SP::L1, SP::L2, SP::L3, 72 SP::L4, SP::L5, SP::L6, SP::L7, 73 SP::I0, SP::I1, SP::I2, SP::I3, 74 SP::I4, SP::I5, SP::I6, SP::I7 }; 75 76 static const unsigned FPRegDecoderTable[] = { 77 SP::F0, SP::F1, SP::F2, SP::F3, 78 SP::F4, SP::F5, SP::F6, SP::F7, 79 SP::F8, SP::F9, SP::F10, SP::F11, 80 SP::F12, SP::F13, SP::F14, SP::F15, 81 SP::F16, SP::F17, SP::F18, SP::F19, 82 SP::F20, SP::F21, SP::F22, SP::F23, 83 SP::F24, SP::F25, SP::F26, SP::F27, 84 SP::F28, SP::F29, SP::F30, SP::F31 }; 85 86 static const unsigned DFPRegDecoderTable[] = { 87 SP::D0, SP::D16, SP::D1, SP::D17, 88 SP::D2, SP::D18, SP::D3, SP::D19, 89 SP::D4, SP::D20, SP::D5, SP::D21, 90 SP::D6, SP::D22, SP::D7, SP::D23, 91 SP::D8, SP::D24, SP::D9, SP::D25, 92 SP::D10, SP::D26, SP::D11, SP::D27, 93 SP::D12, SP::D28, SP::D13, SP::D29, 94 SP::D14, SP::D30, SP::D15, SP::D31 }; 95 96 static const unsigned QFPRegDecoderTable[] = { 97 SP::Q0, SP::Q8, ~0U, ~0U, 98 SP::Q1, SP::Q9, ~0U, ~0U, 99 SP::Q2, SP::Q10, ~0U, ~0U, 100 SP::Q3, SP::Q11, ~0U, ~0U, 101 SP::Q4, SP::Q12, ~0U, ~0U, 102 SP::Q5, SP::Q13, ~0U, ~0U, 103 SP::Q6, SP::Q14, ~0U, ~0U, 104 SP::Q7, SP::Q15, ~0U, ~0U } ; 105 106 static const unsigned FCCRegDecoderTable[] = { 107 SP::FCC0, SP::FCC1, SP::FCC2, SP::FCC3 }; 108 109 static DecodeStatus DecodeIntRegsRegisterClass(MCInst &Inst, 110 unsigned RegNo, 111 uint64_t Address, 112 const void *Decoder) { 113 if (RegNo > 31) 114 return MCDisassembler::Fail; 115 unsigned Reg = IntRegDecoderTable[RegNo]; 116 Inst.addOperand(MCOperand::CreateReg(Reg)); 117 return MCDisassembler::Success; 118 } 119 120 static DecodeStatus DecodeI64RegsRegisterClass(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 132 static DecodeStatus DecodeFPRegsRegisterClass(MCInst &Inst, 133 unsigned RegNo, 134 uint64_t Address, 135 const void *Decoder) { 136 if (RegNo > 31) 137 return MCDisassembler::Fail; 138 unsigned Reg = FPRegDecoderTable[RegNo]; 139 Inst.addOperand(MCOperand::CreateReg(Reg)); 140 return MCDisassembler::Success; 141 } 142 143 144 static DecodeStatus DecodeDFPRegsRegisterClass(MCInst &Inst, 145 unsigned RegNo, 146 uint64_t Address, 147 const void *Decoder) { 148 if (RegNo > 31) 149 return MCDisassembler::Fail; 150 unsigned Reg = DFPRegDecoderTable[RegNo]; 151 Inst.addOperand(MCOperand::CreateReg(Reg)); 152 return MCDisassembler::Success; 153 } 154 155 156 static DecodeStatus DecodeQFPRegsRegisterClass(MCInst &Inst, 157 unsigned RegNo, 158 uint64_t Address, 159 const void *Decoder) { 160 if (RegNo > 31) 161 return MCDisassembler::Fail; 162 163 unsigned Reg = QFPRegDecoderTable[RegNo]; 164 if (Reg == ~0U) 165 return MCDisassembler::Fail; 166 Inst.addOperand(MCOperand::CreateReg(Reg)); 167 return MCDisassembler::Success; 168 } 169 170 static DecodeStatus DecodeFCCRegsRegisterClass(MCInst &Inst, unsigned RegNo, 171 uint64_t Address, 172 const void *Decoder) { 173 if (RegNo > 3) 174 return MCDisassembler::Fail; 175 Inst.addOperand(MCOperand::CreateReg(FCCRegDecoderTable[RegNo])); 176 return MCDisassembler::Success; 177 } 178 179 180 static DecodeStatus DecodeLoadInt(MCInst &Inst, unsigned insn, uint64_t Address, 181 const void *Decoder); 182 static DecodeStatus DecodeLoadFP(MCInst &Inst, unsigned insn, uint64_t Address, 183 const void *Decoder); 184 static DecodeStatus DecodeLoadDFP(MCInst &Inst, unsigned insn, uint64_t Address, 185 const void *Decoder); 186 static DecodeStatus DecodeLoadQFP(MCInst &Inst, unsigned insn, uint64_t Address, 187 const void *Decoder); 188 static DecodeStatus DecodeStoreInt(MCInst &Inst, unsigned insn, 189 uint64_t Address, const void *Decoder); 190 static DecodeStatus DecodeStoreFP(MCInst &Inst, unsigned insn, 191 uint64_t Address, const void *Decoder); 192 static DecodeStatus DecodeStoreDFP(MCInst &Inst, unsigned insn, 193 uint64_t Address, const void *Decoder); 194 static DecodeStatus DecodeStoreQFP(MCInst &Inst, unsigned insn, 195 uint64_t Address, const void *Decoder); 196 static DecodeStatus DecodeCall(MCInst &Inst, unsigned insn, 197 uint64_t Address, const void *Decoder); 198 static DecodeStatus DecodeSIMM13(MCInst &Inst, unsigned insn, 199 uint64_t Address, const void *Decoder); 200 static DecodeStatus DecodeJMPL(MCInst &Inst, unsigned insn, uint64_t Address, 201 const void *Decoder); 202 static DecodeStatus DecodeReturn(MCInst &MI, unsigned insn, uint64_t Address, 203 const void *Decoder); 204 static DecodeStatus DecodeSWAP(MCInst &Inst, unsigned insn, uint64_t Address, 205 const void *Decoder); 206 207 #include "SparcGenDisassemblerTables.inc" 208 209 /// Read four bytes from the ArrayRef and return 32 bit word. 210 static DecodeStatus readInstruction32(ArrayRef<uint8_t> Bytes, uint64_t Address, 211 uint64_t &Size, uint32_t &Insn, 212 bool IsLittleEndian) { 213 // We want to read exactly 4 Bytes of data. 214 if (Bytes.size() < 4) { 215 Size = 0; 216 return MCDisassembler::Fail; 217 } 218 219 Insn = IsLittleEndian 220 ? (Bytes[0] << 0) | (Bytes[1] << 8) | (Bytes[2] << 16) | 221 (Bytes[3] << 24) 222 : (Bytes[3] << 0) | (Bytes[2] << 8) | (Bytes[1] << 16) | 223 (Bytes[0] << 24); 224 225 return MCDisassembler::Success; 226 } 227 228 DecodeStatus SparcDisassembler::getInstruction(MCInst &Instr, uint64_t &Size, 229 ArrayRef<uint8_t> Bytes, 230 uint64_t Address, 231 raw_ostream &VStream, 232 raw_ostream &CStream) const { 233 uint32_t Insn; 234 bool isLittleEndian = getContext().getAsmInfo()->isLittleEndian(); 235 DecodeStatus Result = 236 readInstruction32(Bytes, Address, Size, Insn, isLittleEndian); 237 if (Result == MCDisassembler::Fail) 238 return MCDisassembler::Fail; 239 240 // Calling the auto-generated decoder function. 241 Result = 242 decodeInstruction(DecoderTableSparc32, Instr, Insn, Address, this, STI); 243 244 if (Result != MCDisassembler::Fail) { 245 Size = 4; 246 return Result; 247 } 248 249 return MCDisassembler::Fail; 250 } 251 252 253 typedef DecodeStatus (*DecodeFunc)(MCInst &MI, unsigned insn, uint64_t Address, 254 const void *Decoder); 255 256 static DecodeStatus DecodeMem(MCInst &MI, unsigned insn, uint64_t Address, 257 const void *Decoder, 258 bool isLoad, DecodeFunc DecodeRD) { 259 unsigned rd = fieldFromInstruction(insn, 25, 5); 260 unsigned rs1 = fieldFromInstruction(insn, 14, 5); 261 bool isImm = fieldFromInstruction(insn, 13, 1); 262 unsigned rs2 = 0; 263 unsigned simm13 = 0; 264 if (isImm) 265 simm13 = SignExtend32<13>(fieldFromInstruction(insn, 0, 13)); 266 else 267 rs2 = fieldFromInstruction(insn, 0, 5); 268 269 DecodeStatus status; 270 if (isLoad) { 271 status = DecodeRD(MI, rd, Address, Decoder); 272 if (status != MCDisassembler::Success) 273 return status; 274 } 275 276 // Decode rs1. 277 status = DecodeIntRegsRegisterClass(MI, rs1, Address, Decoder); 278 if (status != MCDisassembler::Success) 279 return status; 280 281 // Decode imm|rs2. 282 if (isImm) 283 MI.addOperand(MCOperand::CreateImm(simm13)); 284 else { 285 status = DecodeIntRegsRegisterClass(MI, rs2, Address, Decoder); 286 if (status != MCDisassembler::Success) 287 return status; 288 } 289 290 if (!isLoad) { 291 status = DecodeRD(MI, rd, Address, Decoder); 292 if (status != MCDisassembler::Success) 293 return status; 294 } 295 return MCDisassembler::Success; 296 } 297 298 static DecodeStatus DecodeLoadInt(MCInst &Inst, unsigned insn, uint64_t Address, 299 const void *Decoder) { 300 return DecodeMem(Inst, insn, Address, Decoder, true, 301 DecodeIntRegsRegisterClass); 302 } 303 304 static DecodeStatus DecodeLoadFP(MCInst &Inst, unsigned insn, uint64_t Address, 305 const void *Decoder) { 306 return DecodeMem(Inst, insn, Address, Decoder, true, 307 DecodeFPRegsRegisterClass); 308 } 309 310 static DecodeStatus DecodeLoadDFP(MCInst &Inst, unsigned insn, uint64_t Address, 311 const void *Decoder) { 312 return DecodeMem(Inst, insn, Address, Decoder, true, 313 DecodeDFPRegsRegisterClass); 314 } 315 316 static DecodeStatus DecodeLoadQFP(MCInst &Inst, unsigned insn, uint64_t Address, 317 const void *Decoder) { 318 return DecodeMem(Inst, insn, Address, Decoder, true, 319 DecodeQFPRegsRegisterClass); 320 } 321 322 static DecodeStatus DecodeStoreInt(MCInst &Inst, unsigned insn, 323 uint64_t Address, const void *Decoder) { 324 return DecodeMem(Inst, insn, Address, Decoder, false, 325 DecodeIntRegsRegisterClass); 326 } 327 328 static DecodeStatus DecodeStoreFP(MCInst &Inst, unsigned insn, uint64_t Address, 329 const void *Decoder) { 330 return DecodeMem(Inst, insn, Address, Decoder, false, 331 DecodeFPRegsRegisterClass); 332 } 333 334 static DecodeStatus DecodeStoreDFP(MCInst &Inst, unsigned insn, 335 uint64_t Address, const void *Decoder) { 336 return DecodeMem(Inst, insn, Address, Decoder, false, 337 DecodeDFPRegsRegisterClass); 338 } 339 340 static DecodeStatus DecodeStoreQFP(MCInst &Inst, unsigned insn, 341 uint64_t Address, const void *Decoder) { 342 return DecodeMem(Inst, insn, Address, Decoder, false, 343 DecodeQFPRegsRegisterClass); 344 } 345 346 static bool tryAddingSymbolicOperand(int64_t Value, bool isBranch, 347 uint64_t Address, uint64_t Offset, 348 uint64_t Width, MCInst &MI, 349 const void *Decoder) { 350 const MCDisassembler *Dis = static_cast<const MCDisassembler*>(Decoder); 351 return Dis->tryAddingSymbolicOperand(MI, Value, Address, isBranch, 352 Offset, Width); 353 } 354 355 static DecodeStatus DecodeCall(MCInst &MI, unsigned insn, 356 uint64_t Address, const void *Decoder) { 357 unsigned tgt = fieldFromInstruction(insn, 0, 30); 358 tgt <<= 2; 359 if (!tryAddingSymbolicOperand(tgt+Address, false, Address, 360 0, 30, MI, Decoder)) 361 MI.addOperand(MCOperand::CreateImm(tgt)); 362 return MCDisassembler::Success; 363 } 364 365 static DecodeStatus DecodeSIMM13(MCInst &MI, unsigned insn, 366 uint64_t Address, const void *Decoder) { 367 unsigned tgt = SignExtend32<13>(fieldFromInstruction(insn, 0, 13)); 368 MI.addOperand(MCOperand::CreateImm(tgt)); 369 return MCDisassembler::Success; 370 } 371 372 static DecodeStatus DecodeJMPL(MCInst &MI, unsigned insn, uint64_t Address, 373 const void *Decoder) { 374 375 unsigned rd = fieldFromInstruction(insn, 25, 5); 376 unsigned rs1 = fieldFromInstruction(insn, 14, 5); 377 unsigned isImm = fieldFromInstruction(insn, 13, 1); 378 unsigned rs2 = 0; 379 unsigned simm13 = 0; 380 if (isImm) 381 simm13 = SignExtend32<13>(fieldFromInstruction(insn, 0, 13)); 382 else 383 rs2 = fieldFromInstruction(insn, 0, 5); 384 385 // Decode RD. 386 DecodeStatus status = DecodeIntRegsRegisterClass(MI, rd, Address, Decoder); 387 if (status != MCDisassembler::Success) 388 return status; 389 390 // Decode RS1. 391 status = DecodeIntRegsRegisterClass(MI, rs1, Address, Decoder); 392 if (status != MCDisassembler::Success) 393 return status; 394 395 // Decode RS1 | SIMM13. 396 if (isImm) 397 MI.addOperand(MCOperand::CreateImm(simm13)); 398 else { 399 status = DecodeIntRegsRegisterClass(MI, rs2, Address, Decoder); 400 if (status != MCDisassembler::Success) 401 return status; 402 } 403 return MCDisassembler::Success; 404 } 405 406 static DecodeStatus DecodeReturn(MCInst &MI, unsigned insn, uint64_t Address, 407 const void *Decoder) { 408 409 unsigned rs1 = fieldFromInstruction(insn, 14, 5); 410 unsigned isImm = fieldFromInstruction(insn, 13, 1); 411 unsigned rs2 = 0; 412 unsigned simm13 = 0; 413 if (isImm) 414 simm13 = SignExtend32<13>(fieldFromInstruction(insn, 0, 13)); 415 else 416 rs2 = fieldFromInstruction(insn, 0, 5); 417 418 // Decode RS1. 419 DecodeStatus status = DecodeIntRegsRegisterClass(MI, rs1, Address, Decoder); 420 if (status != MCDisassembler::Success) 421 return status; 422 423 // Decode RS2 | SIMM13. 424 if (isImm) 425 MI.addOperand(MCOperand::CreateImm(simm13)); 426 else { 427 status = DecodeIntRegsRegisterClass(MI, rs2, Address, Decoder); 428 if (status != MCDisassembler::Success) 429 return status; 430 } 431 return MCDisassembler::Success; 432 } 433 434 static DecodeStatus DecodeSWAP(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