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/Support/TargetRegistry.h" 20 21using namespace llvm; 22 23#define DEBUG_TYPE "sparc-disassembler" 24 25typedef MCDisassembler::DecodeStatus DecodeStatus; 26 27namespace { 28 29/// A disassembler class for Sparc. 30class SparcDisassembler : public MCDisassembler { 31public: 32 SparcDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx) 33 : MCDisassembler(STI, Ctx) {} 34 virtual ~SparcDisassembler() {} 35 36 DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size, 37 ArrayRef<uint8_t> Bytes, uint64_t Address, 38 raw_ostream &VStream, 39 raw_ostream &CStream) const override; 40}; 41 42} 43 44namespace llvm { 45 extern Target TheSparcTarget, TheSparcV9Target; 46} 47 48static MCDisassembler *createSparcDisassembler( 49 const Target &T, 50 const MCSubtargetInfo &STI, 51 MCContext &Ctx) { 52 return new SparcDisassembler(STI, Ctx); 53} 54 55 56extern "C" void LLVMInitializeSparcDisassembler() { 57 // Register the disassembler. 58 TargetRegistry::RegisterMCDisassembler(TheSparcTarget, 59 createSparcDisassembler); 60 TargetRegistry::RegisterMCDisassembler(TheSparcV9Target, 61 createSparcDisassembler); 62} 63 64 65 66static 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 76static 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 86static 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 96static 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 106static const unsigned FCCRegDecoderTable[] = { 107 SP::FCC0, SP::FCC1, SP::FCC2, SP::FCC3 }; 108 109static 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 120static 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 132static 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 144static 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 156static 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 170static 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 180static DecodeStatus DecodeLoadInt(MCInst &Inst, unsigned insn, uint64_t Address, 181 const void *Decoder); 182static DecodeStatus DecodeLoadFP(MCInst &Inst, unsigned insn, uint64_t Address, 183 const void *Decoder); 184static DecodeStatus DecodeLoadDFP(MCInst &Inst, unsigned insn, uint64_t Address, 185 const void *Decoder); 186static DecodeStatus DecodeLoadQFP(MCInst &Inst, unsigned insn, uint64_t Address, 187 const void *Decoder); 188static DecodeStatus DecodeStoreInt(MCInst &Inst, unsigned insn, 189 uint64_t Address, const void *Decoder); 190static DecodeStatus DecodeStoreFP(MCInst &Inst, unsigned insn, 191 uint64_t Address, const void *Decoder); 192static DecodeStatus DecodeStoreDFP(MCInst &Inst, unsigned insn, 193 uint64_t Address, const void *Decoder); 194static DecodeStatus DecodeStoreQFP(MCInst &Inst, unsigned insn, 195 uint64_t Address, const void *Decoder); 196static DecodeStatus DecodeCall(MCInst &Inst, unsigned insn, 197 uint64_t Address, const void *Decoder); 198static DecodeStatus DecodeSIMM13(MCInst &Inst, unsigned insn, 199 uint64_t Address, const void *Decoder); 200static DecodeStatus DecodeJMPL(MCInst &Inst, unsigned insn, uint64_t Address, 201 const void *Decoder); 202static DecodeStatus DecodeReturn(MCInst &MI, unsigned insn, uint64_t Address, 203 const void *Decoder); 204static 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. 210static DecodeStatus readInstruction32(ArrayRef<uint8_t> Bytes, uint64_t Address, 211 uint64_t &Size, uint32_t &Insn) { 212 // We want to read exactly 4 Bytes of data. 213 if (Bytes.size() < 4) { 214 Size = 0; 215 return MCDisassembler::Fail; 216 } 217 218 // Encoded as a big-endian 32-bit word in the stream. 219 Insn = 220 (Bytes[3] << 0) | (Bytes[2] << 8) | (Bytes[1] << 16) | (Bytes[0] << 24); 221 222 return MCDisassembler::Success; 223} 224 225DecodeStatus SparcDisassembler::getInstruction(MCInst &Instr, uint64_t &Size, 226 ArrayRef<uint8_t> Bytes, 227 uint64_t Address, 228 raw_ostream &VStream, 229 raw_ostream &CStream) const { 230 uint32_t Insn; 231 232 DecodeStatus Result = readInstruction32(Bytes, Address, Size, Insn); 233 if (Result == MCDisassembler::Fail) 234 return MCDisassembler::Fail; 235 236 237 // Calling the auto-generated decoder function. 238 Result = 239 decodeInstruction(DecoderTableSparc32, Instr, Insn, Address, this, STI); 240 241 if (Result != MCDisassembler::Fail) { 242 Size = 4; 243 return Result; 244 } 245 246 return MCDisassembler::Fail; 247} 248 249 250typedef DecodeStatus (*DecodeFunc)(MCInst &MI, unsigned insn, uint64_t Address, 251 const void *Decoder); 252 253static DecodeStatus DecodeMem(MCInst &MI, unsigned insn, uint64_t Address, 254 const void *Decoder, 255 bool isLoad, DecodeFunc DecodeRD) { 256 unsigned rd = fieldFromInstruction(insn, 25, 5); 257 unsigned rs1 = fieldFromInstruction(insn, 14, 5); 258 bool isImm = fieldFromInstruction(insn, 13, 1); 259 unsigned rs2 = 0; 260 unsigned simm13 = 0; 261 if (isImm) 262 simm13 = SignExtend32<13>(fieldFromInstruction(insn, 0, 13)); 263 else 264 rs2 = fieldFromInstruction(insn, 0, 5); 265 266 DecodeStatus status; 267 if (isLoad) { 268 status = DecodeRD(MI, rd, Address, Decoder); 269 if (status != MCDisassembler::Success) 270 return status; 271 } 272 273 // Decode rs1. 274 status = DecodeIntRegsRegisterClass(MI, rs1, Address, Decoder); 275 if (status != MCDisassembler::Success) 276 return status; 277 278 // Decode imm|rs2. 279 if (isImm) 280 MI.addOperand(MCOperand::CreateImm(simm13)); 281 else { 282 status = DecodeIntRegsRegisterClass(MI, rs2, Address, Decoder); 283 if (status != MCDisassembler::Success) 284 return status; 285 } 286 287 if (!isLoad) { 288 status = DecodeRD(MI, rd, Address, Decoder); 289 if (status != MCDisassembler::Success) 290 return status; 291 } 292 return MCDisassembler::Success; 293} 294 295static DecodeStatus DecodeLoadInt(MCInst &Inst, unsigned insn, uint64_t Address, 296 const void *Decoder) { 297 return DecodeMem(Inst, insn, Address, Decoder, true, 298 DecodeIntRegsRegisterClass); 299} 300 301static DecodeStatus DecodeLoadFP(MCInst &Inst, unsigned insn, uint64_t Address, 302 const void *Decoder) { 303 return DecodeMem(Inst, insn, Address, Decoder, true, 304 DecodeFPRegsRegisterClass); 305} 306 307static DecodeStatus DecodeLoadDFP(MCInst &Inst, unsigned insn, uint64_t Address, 308 const void *Decoder) { 309 return DecodeMem(Inst, insn, Address, Decoder, true, 310 DecodeDFPRegsRegisterClass); 311} 312 313static DecodeStatus DecodeLoadQFP(MCInst &Inst, unsigned insn, uint64_t Address, 314 const void *Decoder) { 315 return DecodeMem(Inst, insn, Address, Decoder, true, 316 DecodeQFPRegsRegisterClass); 317} 318 319static DecodeStatus DecodeStoreInt(MCInst &Inst, unsigned insn, 320 uint64_t Address, const void *Decoder) { 321 return DecodeMem(Inst, insn, Address, Decoder, false, 322 DecodeIntRegsRegisterClass); 323} 324 325static DecodeStatus DecodeStoreFP(MCInst &Inst, unsigned insn, uint64_t Address, 326 const void *Decoder) { 327 return DecodeMem(Inst, insn, Address, Decoder, false, 328 DecodeFPRegsRegisterClass); 329} 330 331static DecodeStatus DecodeStoreDFP(MCInst &Inst, unsigned insn, 332 uint64_t Address, const void *Decoder) { 333 return DecodeMem(Inst, insn, Address, Decoder, false, 334 DecodeDFPRegsRegisterClass); 335} 336 337static DecodeStatus DecodeStoreQFP(MCInst &Inst, unsigned insn, 338 uint64_t Address, const void *Decoder) { 339 return DecodeMem(Inst, insn, Address, Decoder, false, 340 DecodeQFPRegsRegisterClass); 341} 342 343static bool tryAddingSymbolicOperand(int64_t Value, bool isBranch, 344 uint64_t Address, uint64_t Offset, 345 uint64_t Width, MCInst &MI, 346 const void *Decoder) { 347 const MCDisassembler *Dis = static_cast<const MCDisassembler*>(Decoder); 348 return Dis->tryAddingSymbolicOperand(MI, Value, Address, isBranch, 349 Offset, Width); 350} 351 352static DecodeStatus DecodeCall(MCInst &MI, unsigned insn, 353 uint64_t Address, const void *Decoder) { 354 unsigned tgt = fieldFromInstruction(insn, 0, 30); 355 tgt <<= 2; 356 if (!tryAddingSymbolicOperand(tgt+Address, false, Address, 357 0, 30, MI, Decoder)) 358 MI.addOperand(MCOperand::CreateImm(tgt)); 359 return MCDisassembler::Success; 360} 361 362static DecodeStatus DecodeSIMM13(MCInst &MI, unsigned insn, 363 uint64_t Address, const void *Decoder) { 364 unsigned tgt = SignExtend32<13>(fieldFromInstruction(insn, 0, 13)); 365 MI.addOperand(MCOperand::CreateImm(tgt)); 366 return MCDisassembler::Success; 367} 368 369static DecodeStatus DecodeJMPL(MCInst &MI, unsigned insn, uint64_t Address, 370 const void *Decoder) { 371 372 unsigned rd = fieldFromInstruction(insn, 25, 5); 373 unsigned rs1 = fieldFromInstruction(insn, 14, 5); 374 unsigned isImm = fieldFromInstruction(insn, 13, 1); 375 unsigned rs2 = 0; 376 unsigned simm13 = 0; 377 if (isImm) 378 simm13 = SignExtend32<13>(fieldFromInstruction(insn, 0, 13)); 379 else 380 rs2 = fieldFromInstruction(insn, 0, 5); 381 382 // Decode RD. 383 DecodeStatus status = DecodeIntRegsRegisterClass(MI, rd, Address, Decoder); 384 if (status != MCDisassembler::Success) 385 return status; 386 387 // Decode RS1. 388 status = DecodeIntRegsRegisterClass(MI, rs1, Address, Decoder); 389 if (status != MCDisassembler::Success) 390 return status; 391 392 // Decode RS1 | SIMM13. 393 if (isImm) 394 MI.addOperand(MCOperand::CreateImm(simm13)); 395 else { 396 status = DecodeIntRegsRegisterClass(MI, rs2, Address, Decoder); 397 if (status != MCDisassembler::Success) 398 return status; 399 } 400 return MCDisassembler::Success; 401} 402 403static DecodeStatus DecodeReturn(MCInst &MI, unsigned insn, uint64_t Address, 404 const void *Decoder) { 405 406 unsigned rs1 = fieldFromInstruction(insn, 14, 5); 407 unsigned isImm = fieldFromInstruction(insn, 13, 1); 408 unsigned rs2 = 0; 409 unsigned simm13 = 0; 410 if (isImm) 411 simm13 = SignExtend32<13>(fieldFromInstruction(insn, 0, 13)); 412 else 413 rs2 = fieldFromInstruction(insn, 0, 5); 414 415 // Decode RS1. 416 DecodeStatus status = DecodeIntRegsRegisterClass(MI, rs1, Address, Decoder); 417 if (status != MCDisassembler::Success) 418 return status; 419 420 // Decode RS2 | 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 431static DecodeStatus DecodeSWAP(MCInst &MI, unsigned insn, uint64_t Address, 432 const void *Decoder) { 433 434 unsigned rd = fieldFromInstruction(insn, 25, 5); 435 unsigned rs1 = fieldFromInstruction(insn, 14, 5); 436 unsigned isImm = fieldFromInstruction(insn, 13, 1); 437 unsigned rs2 = 0; 438 unsigned simm13 = 0; 439 if (isImm) 440 simm13 = SignExtend32<13>(fieldFromInstruction(insn, 0, 13)); 441 else 442 rs2 = fieldFromInstruction(insn, 0, 5); 443 444 // Decode RD. 445 DecodeStatus status = DecodeIntRegsRegisterClass(MI, rd, Address, Decoder); 446 if (status != MCDisassembler::Success) 447 return status; 448 449 // Decode RS1. 450 status = DecodeIntRegsRegisterClass(MI, rs1, Address, Decoder); 451 if (status != MCDisassembler::Success) 452 return status; 453 454 // Decode RS1 | SIMM13. 455 if (isImm) 456 MI.addOperand(MCOperand::CreateImm(simm13)); 457 else { 458 status = DecodeIntRegsRegisterClass(MI, rs2, Address, Decoder); 459 if (status != MCDisassembler::Success) 460 return status; 461 } 462 return MCDisassembler::Success; 463} 464