LLVM API Documentation

SparcDisassembler.cpp
Go to the documentation of this file.
00001 //===- SparcDisassembler.cpp - Disassembler for Sparc -----------*- C++ -*-===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file is part of the Sparc Disassembler.
00011 //
00012 //===----------------------------------------------------------------------===//
00013 
00014 #include "Sparc.h"
00015 #include "SparcRegisterInfo.h"
00016 #include "SparcSubtarget.h"
00017 #include "llvm/MC/MCDisassembler.h"
00018 #include "llvm/MC/MCFixedLenDisassembler.h"
00019 #include "llvm/Support/MemoryObject.h"
00020 #include "llvm/Support/TargetRegistry.h"
00021 
00022 using namespace llvm;
00023 
00024 #define DEBUG_TYPE "sparc-disassembler"
00025 
00026 typedef MCDisassembler::DecodeStatus DecodeStatus;
00027 
00028 namespace {
00029 
00030 /// SparcDisassembler - a disassembler class for Sparc.
00031 class SparcDisassembler : public MCDisassembler {
00032 public:
00033   /// Constructor     - Initializes the disassembler.
00034   ///
00035   SparcDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx) :
00036     MCDisassembler(STI, Ctx)
00037   {}
00038   virtual ~SparcDisassembler() {}
00039 
00040   /// getInstruction - See MCDisassembler.
00041   DecodeStatus getInstruction(MCInst &instr,
00042                               uint64_t &size,
00043                               const MemoryObject &region,
00044                               uint64_t address,
00045                               raw_ostream &vStream,
00046                               raw_ostream &cStream) const override;
00047 };
00048 
00049 }
00050 
00051 namespace llvm {
00052   extern Target TheSparcTarget, TheSparcV9Target;
00053 }
00054 
00055 static MCDisassembler *createSparcDisassembler(
00056                        const Target &T,
00057                        const MCSubtargetInfo &STI,
00058                        MCContext &Ctx) {
00059   return new SparcDisassembler(STI, Ctx);
00060 }
00061 
00062 
00063 extern "C" void LLVMInitializeSparcDisassembler() {
00064   // Register the disassembler.
00065   TargetRegistry::RegisterMCDisassembler(TheSparcTarget,
00066                                          createSparcDisassembler);
00067   TargetRegistry::RegisterMCDisassembler(TheSparcV9Target,
00068                                          createSparcDisassembler);
00069 }
00070 
00071 
00072 
00073 static const unsigned IntRegDecoderTable[] = {
00074   SP::G0,  SP::G1,  SP::G2,  SP::G3,
00075   SP::G4,  SP::G5,  SP::G6,  SP::G7,
00076   SP::O0,  SP::O1,  SP::O2,  SP::O3,
00077   SP::O4,  SP::O5,  SP::O6,  SP::O7,
00078   SP::L0,  SP::L1,  SP::L2,  SP::L3,
00079   SP::L4,  SP::L5,  SP::L6,  SP::L7,
00080   SP::I0,  SP::I1,  SP::I2,  SP::I3,
00081   SP::I4,  SP::I5,  SP::I6,  SP::I7 };
00082 
00083 static const unsigned FPRegDecoderTable[] = {
00084   SP::F0,   SP::F1,   SP::F2,   SP::F3,
00085   SP::F4,   SP::F5,   SP::F6,   SP::F7,
00086   SP::F8,   SP::F9,   SP::F10,  SP::F11,
00087   SP::F12,  SP::F13,  SP::F14,  SP::F15,
00088   SP::F16,  SP::F17,  SP::F18,  SP::F19,
00089   SP::F20,  SP::F21,  SP::F22,  SP::F23,
00090   SP::F24,  SP::F25,  SP::F26,  SP::F27,
00091   SP::F28,  SP::F29,  SP::F30,  SP::F31 };
00092 
00093 static const unsigned DFPRegDecoderTable[] = {
00094   SP::D0,   SP::D16,  SP::D1,   SP::D17,
00095   SP::D2,   SP::D18,  SP::D3,   SP::D19,
00096   SP::D4,   SP::D20,  SP::D5,   SP::D21,
00097   SP::D6,   SP::D22,  SP::D7,   SP::D23,
00098   SP::D8,   SP::D24,  SP::D9,   SP::D25,
00099   SP::D10,  SP::D26,  SP::D11,  SP::D27,
00100   SP::D12,  SP::D28,  SP::D13,  SP::D29,
00101   SP::D14,  SP::D30,  SP::D15,  SP::D31 };
00102 
00103 static const unsigned QFPRegDecoderTable[] = {
00104   SP::Q0,  SP::Q8,   ~0U,  ~0U,
00105   SP::Q1,  SP::Q9,   ~0U,  ~0U,
00106   SP::Q2,  SP::Q10,  ~0U,  ~0U,
00107   SP::Q3,  SP::Q11,  ~0U,  ~0U,
00108   SP::Q4,  SP::Q12,  ~0U,  ~0U,
00109   SP::Q5,  SP::Q13,  ~0U,  ~0U,
00110   SP::Q6,  SP::Q14,  ~0U,  ~0U,
00111   SP::Q7,  SP::Q15,  ~0U,  ~0U } ;
00112 
00113 static const unsigned FCCRegDecoderTable[] = {
00114   SP::FCC0, SP::FCC1, SP::FCC2, SP::FCC3 };
00115 
00116 static DecodeStatus DecodeIntRegsRegisterClass(MCInst &Inst,
00117                                                unsigned RegNo,
00118                                                uint64_t Address,
00119                                                const void *Decoder) {
00120   if (RegNo > 31)
00121     return MCDisassembler::Fail;
00122   unsigned Reg = IntRegDecoderTable[RegNo];
00123   Inst.addOperand(MCOperand::CreateReg(Reg));
00124   return MCDisassembler::Success;
00125 }
00126 
00127 static DecodeStatus DecodeI64RegsRegisterClass(MCInst &Inst,
00128                                                unsigned RegNo,
00129                                                uint64_t Address,
00130                                                const void *Decoder) {
00131   if (RegNo > 31)
00132     return MCDisassembler::Fail;
00133   unsigned Reg = IntRegDecoderTable[RegNo];
00134   Inst.addOperand(MCOperand::CreateReg(Reg));
00135   return MCDisassembler::Success;
00136 }
00137 
00138 
00139 static DecodeStatus DecodeFPRegsRegisterClass(MCInst &Inst,
00140                                               unsigned RegNo,
00141                                               uint64_t Address,
00142                                               const void *Decoder) {
00143   if (RegNo > 31)
00144     return MCDisassembler::Fail;
00145   unsigned Reg = FPRegDecoderTable[RegNo];
00146   Inst.addOperand(MCOperand::CreateReg(Reg));
00147   return MCDisassembler::Success;
00148 }
00149 
00150 
00151 static DecodeStatus DecodeDFPRegsRegisterClass(MCInst &Inst,
00152                                                unsigned RegNo,
00153                                                uint64_t Address,
00154                                                const void *Decoder) {
00155   if (RegNo > 31)
00156     return MCDisassembler::Fail;
00157   unsigned Reg = DFPRegDecoderTable[RegNo];
00158   Inst.addOperand(MCOperand::CreateReg(Reg));
00159   return MCDisassembler::Success;
00160 }
00161 
00162 
00163 static DecodeStatus DecodeQFPRegsRegisterClass(MCInst &Inst,
00164                                                unsigned RegNo,
00165                                                uint64_t Address,
00166                                                const void *Decoder) {
00167   if (RegNo > 31)
00168     return MCDisassembler::Fail;
00169 
00170   unsigned Reg = QFPRegDecoderTable[RegNo];
00171   if (Reg == ~0U)
00172     return MCDisassembler::Fail;
00173   Inst.addOperand(MCOperand::CreateReg(Reg));
00174   return MCDisassembler::Success;
00175 }
00176 
00177 static DecodeStatus DecodeFCCRegsRegisterClass(MCInst &Inst, unsigned RegNo,
00178                                                uint64_t Address,
00179                                                const void *Decoder) {
00180   if (RegNo > 3)
00181     return MCDisassembler::Fail;
00182   Inst.addOperand(MCOperand::CreateReg(FCCRegDecoderTable[RegNo]));
00183   return MCDisassembler::Success;
00184 }
00185 
00186 
00187 static DecodeStatus DecodeLoadInt(MCInst &Inst, unsigned insn, uint64_t Address,
00188                                   const void *Decoder);
00189 static DecodeStatus DecodeLoadFP(MCInst &Inst, unsigned insn, uint64_t Address,
00190                                  const void *Decoder);
00191 static DecodeStatus DecodeLoadDFP(MCInst &Inst, unsigned insn, uint64_t Address,
00192                                   const void *Decoder);
00193 static DecodeStatus DecodeLoadQFP(MCInst &Inst, unsigned insn, uint64_t Address,
00194                                   const void *Decoder);
00195 static DecodeStatus DecodeStoreInt(MCInst &Inst, unsigned insn,
00196                                    uint64_t Address, const void *Decoder);
00197 static DecodeStatus DecodeStoreFP(MCInst &Inst, unsigned insn,
00198                                   uint64_t Address, const void *Decoder);
00199 static DecodeStatus DecodeStoreDFP(MCInst &Inst, unsigned insn,
00200                                    uint64_t Address, const void *Decoder);
00201 static DecodeStatus DecodeStoreQFP(MCInst &Inst, unsigned insn,
00202                                    uint64_t Address, const void *Decoder);
00203 static DecodeStatus DecodeCall(MCInst &Inst, unsigned insn,
00204                                uint64_t Address, const void *Decoder);
00205 static DecodeStatus DecodeSIMM13(MCInst &Inst, unsigned insn,
00206                                  uint64_t Address, const void *Decoder);
00207 static DecodeStatus DecodeJMPL(MCInst &Inst, unsigned insn, uint64_t Address,
00208                                const void *Decoder);
00209 static DecodeStatus DecodeReturn(MCInst &MI, unsigned insn, uint64_t Address,
00210                                  const void *Decoder);
00211 static DecodeStatus DecodeSWAP(MCInst &Inst, unsigned insn, uint64_t Address,
00212                                const void *Decoder);
00213 
00214 #include "SparcGenDisassemblerTables.inc"
00215 
00216 /// readInstruction - read four bytes from the MemoryObject
00217 /// and return 32 bit word.
00218 static DecodeStatus readInstruction32(const MemoryObject &region,
00219                                       uint64_t address,
00220                                       uint64_t &size,
00221                                       uint32_t &insn) {
00222   uint8_t Bytes[4];
00223 
00224   // We want to read exactly 4 Bytes of data.
00225   if (region.readBytes(address, 4, Bytes) == -1) {
00226     size = 0;
00227     return MCDisassembler::Fail;
00228   }
00229 
00230   // Encoded as a big-endian 32-bit word in the stream.
00231   insn = (Bytes[3] <<  0) |
00232     (Bytes[2] <<  8) |
00233     (Bytes[1] << 16) |
00234     (Bytes[0] << 24);
00235 
00236   return MCDisassembler::Success;
00237 }
00238 
00239 
00240 DecodeStatus
00241 SparcDisassembler::getInstruction(MCInst &instr,
00242                                  uint64_t &Size,
00243                                  const MemoryObject &Region,
00244                                  uint64_t Address,
00245                                  raw_ostream &vStream,
00246                                  raw_ostream &cStream) const {
00247   uint32_t Insn;
00248 
00249   DecodeStatus Result = readInstruction32(Region, Address, Size, Insn);
00250   if (Result == MCDisassembler::Fail)
00251     return MCDisassembler::Fail;
00252 
00253 
00254   // Calling the auto-generated decoder function.
00255   Result = decodeInstruction(DecoderTableSparc32, instr, Insn, Address,
00256                              this, STI);
00257 
00258   if (Result != MCDisassembler::Fail) {
00259     Size = 4;
00260     return Result;
00261   }
00262 
00263   return MCDisassembler::Fail;
00264 }
00265 
00266 
00267 typedef DecodeStatus (*DecodeFunc)(MCInst &MI, unsigned insn, uint64_t Address,
00268                                    const void *Decoder);
00269 
00270 static DecodeStatus DecodeMem(MCInst &MI, unsigned insn, uint64_t Address,
00271                               const void *Decoder,
00272                               bool isLoad, DecodeFunc DecodeRD) {
00273   unsigned rd = fieldFromInstruction(insn, 25, 5);
00274   unsigned rs1 = fieldFromInstruction(insn, 14, 5);
00275   bool isImm = fieldFromInstruction(insn, 13, 1);
00276   unsigned rs2 = 0;
00277   unsigned simm13 = 0;
00278   if (isImm)
00279     simm13 = SignExtend32<13>(fieldFromInstruction(insn, 0, 13));
00280   else
00281     rs2 = fieldFromInstruction(insn, 0, 5);
00282 
00283   DecodeStatus status;
00284   if (isLoad) {
00285     status = DecodeRD(MI, rd, Address, Decoder);
00286     if (status != MCDisassembler::Success)
00287       return status;
00288   }
00289 
00290   // Decode rs1.
00291   status = DecodeIntRegsRegisterClass(MI, rs1, Address, Decoder);
00292   if (status != MCDisassembler::Success)
00293     return status;
00294 
00295   // Decode imm|rs2.
00296   if (isImm)
00297     MI.addOperand(MCOperand::CreateImm(simm13));
00298   else {
00299     status = DecodeIntRegsRegisterClass(MI, rs2, Address, Decoder);
00300     if (status != MCDisassembler::Success)
00301       return status;
00302   }
00303 
00304   if (!isLoad) {
00305     status = DecodeRD(MI, rd, Address, Decoder);
00306     if (status != MCDisassembler::Success)
00307       return status;
00308   }
00309   return MCDisassembler::Success;
00310 }
00311 
00312 static DecodeStatus DecodeLoadInt(MCInst &Inst, unsigned insn, uint64_t Address,
00313                                   const void *Decoder) {
00314   return DecodeMem(Inst, insn, Address, Decoder, true,
00315                    DecodeIntRegsRegisterClass);
00316 }
00317 
00318 static DecodeStatus DecodeLoadFP(MCInst &Inst, unsigned insn, uint64_t Address,
00319                                  const void *Decoder) {
00320   return DecodeMem(Inst, insn, Address, Decoder, true,
00321                    DecodeFPRegsRegisterClass);
00322 }
00323 
00324 static DecodeStatus DecodeLoadDFP(MCInst &Inst, unsigned insn, uint64_t Address,
00325                                   const void *Decoder) {
00326   return DecodeMem(Inst, insn, Address, Decoder, true,
00327                    DecodeDFPRegsRegisterClass);
00328 }
00329 
00330 static DecodeStatus DecodeLoadQFP(MCInst &Inst, unsigned insn, uint64_t Address,
00331                                   const void *Decoder) {
00332   return DecodeMem(Inst, insn, Address, Decoder, true,
00333                    DecodeQFPRegsRegisterClass);
00334 }
00335 
00336 static DecodeStatus DecodeStoreInt(MCInst &Inst, unsigned insn,
00337                                    uint64_t Address, const void *Decoder) {
00338   return DecodeMem(Inst, insn, Address, Decoder, false,
00339                    DecodeIntRegsRegisterClass);
00340 }
00341 
00342 static DecodeStatus DecodeStoreFP(MCInst &Inst, unsigned insn, uint64_t Address,
00343                                   const void *Decoder) {
00344   return DecodeMem(Inst, insn, Address, Decoder, false,
00345                    DecodeFPRegsRegisterClass);
00346 }
00347 
00348 static DecodeStatus DecodeStoreDFP(MCInst &Inst, unsigned insn,
00349                                    uint64_t Address, const void *Decoder) {
00350   return DecodeMem(Inst, insn, Address, Decoder, false,
00351                    DecodeDFPRegsRegisterClass);
00352 }
00353 
00354 static DecodeStatus DecodeStoreQFP(MCInst &Inst, unsigned insn,
00355                                    uint64_t Address, const void *Decoder) {
00356   return DecodeMem(Inst, insn, Address, Decoder, false,
00357                    DecodeQFPRegsRegisterClass);
00358 }
00359 
00360 static bool tryAddingSymbolicOperand(int64_t Value,  bool isBranch,
00361                                      uint64_t Address, uint64_t Offset,
00362                                      uint64_t Width, MCInst &MI,
00363                                      const void *Decoder) {
00364   const MCDisassembler *Dis = static_cast<const MCDisassembler*>(Decoder);
00365   return Dis->tryAddingSymbolicOperand(MI, Value, Address, isBranch,
00366                                        Offset, Width);
00367 }
00368 
00369 static DecodeStatus DecodeCall(MCInst &MI, unsigned insn,
00370                                uint64_t Address, const void *Decoder) {
00371   unsigned tgt = fieldFromInstruction(insn, 0, 30);
00372   tgt <<= 2;
00373   if (!tryAddingSymbolicOperand(tgt+Address, false, Address,
00374                                 0, 30, MI, Decoder))
00375     MI.addOperand(MCOperand::CreateImm(tgt));
00376   return MCDisassembler::Success;
00377 }
00378 
00379 static DecodeStatus DecodeSIMM13(MCInst &MI, unsigned insn,
00380                                  uint64_t Address, const void *Decoder) {
00381   unsigned tgt = SignExtend32<13>(fieldFromInstruction(insn, 0, 13));
00382   MI.addOperand(MCOperand::CreateImm(tgt));
00383   return MCDisassembler::Success;
00384 }
00385 
00386 static DecodeStatus DecodeJMPL(MCInst &MI, unsigned insn, uint64_t Address,
00387                                const void *Decoder) {
00388 
00389   unsigned rd = fieldFromInstruction(insn, 25, 5);
00390   unsigned rs1 = fieldFromInstruction(insn, 14, 5);
00391   unsigned isImm = fieldFromInstruction(insn, 13, 1);
00392   unsigned rs2 = 0;
00393   unsigned simm13 = 0;
00394   if (isImm)
00395     simm13 = SignExtend32<13>(fieldFromInstruction(insn, 0, 13));
00396   else
00397     rs2 = fieldFromInstruction(insn, 0, 5);
00398 
00399   // Decode RD.
00400   DecodeStatus status = DecodeIntRegsRegisterClass(MI, rd, Address, Decoder);
00401   if (status != MCDisassembler::Success)
00402     return status;
00403 
00404   // Decode RS1.
00405   status = DecodeIntRegsRegisterClass(MI, rs1, Address, Decoder);
00406   if (status != MCDisassembler::Success)
00407     return status;
00408 
00409   // Decode RS1 | SIMM13.
00410   if (isImm)
00411     MI.addOperand(MCOperand::CreateImm(simm13));
00412   else {
00413     status = DecodeIntRegsRegisterClass(MI, rs2, Address, Decoder);
00414     if (status != MCDisassembler::Success)
00415       return status;
00416   }
00417   return MCDisassembler::Success;
00418 }
00419 
00420 static DecodeStatus DecodeReturn(MCInst &MI, unsigned insn, uint64_t Address,
00421                                  const void *Decoder) {
00422 
00423   unsigned rs1 = fieldFromInstruction(insn, 14, 5);
00424   unsigned isImm = fieldFromInstruction(insn, 13, 1);
00425   unsigned rs2 = 0;
00426   unsigned simm13 = 0;
00427   if (isImm)
00428     simm13 = SignExtend32<13>(fieldFromInstruction(insn, 0, 13));
00429   else
00430     rs2 = fieldFromInstruction(insn, 0, 5);
00431 
00432   // Decode RS1.
00433   DecodeStatus status = DecodeIntRegsRegisterClass(MI, rs1, Address, Decoder);
00434   if (status != MCDisassembler::Success)
00435     return status;
00436 
00437   // Decode RS2 | SIMM13.
00438   if (isImm)
00439     MI.addOperand(MCOperand::CreateImm(simm13));
00440   else {
00441     status = DecodeIntRegsRegisterClass(MI, rs2, Address, Decoder);
00442     if (status != MCDisassembler::Success)
00443       return status;
00444   }
00445   return MCDisassembler::Success;
00446 }
00447 
00448 static DecodeStatus DecodeSWAP(MCInst &MI, unsigned insn, uint64_t Address,
00449                                const void *Decoder) {
00450 
00451   unsigned rd = fieldFromInstruction(insn, 25, 5);
00452   unsigned rs1 = fieldFromInstruction(insn, 14, 5);
00453   unsigned isImm = fieldFromInstruction(insn, 13, 1);
00454   unsigned rs2 = 0;
00455   unsigned simm13 = 0;
00456   if (isImm)
00457     simm13 = SignExtend32<13>(fieldFromInstruction(insn, 0, 13));
00458   else
00459     rs2 = fieldFromInstruction(insn, 0, 5);
00460 
00461   // Decode RD.
00462   DecodeStatus status = DecodeIntRegsRegisterClass(MI, rd, Address, Decoder);
00463   if (status != MCDisassembler::Success)
00464     return status;
00465 
00466   // Decode RS1.
00467   status = DecodeIntRegsRegisterClass(MI, rs1, Address, Decoder);
00468   if (status != MCDisassembler::Success)
00469     return status;
00470 
00471   // Decode RS1 | SIMM13.
00472   if (isImm)
00473     MI.addOperand(MCOperand::CreateImm(simm13));
00474   else {
00475     status = DecodeIntRegsRegisterClass(MI, rs2, Address, Decoder);
00476     if (status != MCDisassembler::Success)
00477       return status;
00478   }
00479   return MCDisassembler::Success;
00480 }