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