LLVM API Documentation

MipsDisassembler.cpp
Go to the documentation of this file.
00001 //===- MipsDisassembler.cpp - Disassembler for Mips -------------*- 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 Mips Disassembler.
00011 //
00012 //===----------------------------------------------------------------------===//
00013 
00014 #include "Mips.h"
00015 #include "MipsRegisterInfo.h"
00016 #include "MipsSubtarget.h"
00017 #include "llvm/MC/MCDisassembler.h"
00018 #include "llvm/MC/MCFixedLenDisassembler.h"
00019 #include "llvm/MC/MCInst.h"
00020 #include "llvm/MC/MCSubtargetInfo.h"
00021 #include "llvm/Support/MathExtras.h"
00022 #include "llvm/Support/MemoryObject.h"
00023 #include "llvm/Support/TargetRegistry.h"
00024 
00025 using namespace llvm;
00026 
00027 typedef MCDisassembler::DecodeStatus DecodeStatus;
00028 
00029 namespace {
00030 
00031 /// MipsDisassemblerBase - a disasembler class for Mips.
00032 class MipsDisassemblerBase : public MCDisassembler {
00033 public:
00034   /// Constructor     - Initializes the disassembler.
00035   ///
00036   MipsDisassemblerBase(const MCSubtargetInfo &STI, const MCRegisterInfo *Info,
00037                        bool bigEndian) :
00038     MCDisassembler(STI), RegInfo(Info), isBigEndian(bigEndian) {}
00039 
00040   virtual ~MipsDisassemblerBase() {}
00041 
00042   const MCRegisterInfo *getRegInfo() const { return RegInfo; }
00043 
00044 private:
00045   const MCRegisterInfo *RegInfo;
00046 protected:
00047   bool isBigEndian;
00048 };
00049 
00050 /// MipsDisassembler - a disasembler class for Mips32.
00051 class MipsDisassembler : public MipsDisassemblerBase {
00052 public:
00053   /// Constructor     - Initializes the disassembler.
00054   ///
00055   MipsDisassembler(const MCSubtargetInfo &STI, const MCRegisterInfo *Info,
00056                    bool bigEndian) :
00057     MipsDisassemblerBase(STI, Info, bigEndian) {}
00058 
00059   /// getInstruction - See MCDisassembler.
00060   virtual DecodeStatus getInstruction(MCInst &instr,
00061                                       uint64_t &size,
00062                                       const MemoryObject &region,
00063                                       uint64_t address,
00064                                       raw_ostream &vStream,
00065                                       raw_ostream &cStream) const;
00066 };
00067 
00068 
00069 /// Mips64Disassembler - a disasembler class for Mips64.
00070 class Mips64Disassembler : public MipsDisassemblerBase {
00071 public:
00072   /// Constructor     - Initializes the disassembler.
00073   ///
00074   Mips64Disassembler(const MCSubtargetInfo &STI, const MCRegisterInfo *Info,
00075                      bool bigEndian) :
00076     MipsDisassemblerBase(STI, Info, bigEndian) {}
00077 
00078   /// getInstruction - See MCDisassembler.
00079   virtual DecodeStatus getInstruction(MCInst &instr,
00080                                       uint64_t &size,
00081                                       const MemoryObject &region,
00082                                       uint64_t address,
00083                                       raw_ostream &vStream,
00084                                       raw_ostream &cStream) const;
00085 };
00086 
00087 } // end anonymous namespace
00088 
00089 // Forward declare these because the autogenerated code will reference them.
00090 // Definitions are further down.
00091 static DecodeStatus DecodeCPU64RegsRegisterClass(MCInst &Inst,
00092                                                  unsigned RegNo,
00093                                                  uint64_t Address,
00094                                                  const void *Decoder);
00095 
00096 static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst,
00097                                                  unsigned RegNo,
00098                                                  uint64_t Address,
00099                                                  const void *Decoder);
00100 
00101 static DecodeStatus DecodeCPURegsRegisterClass(MCInst &Inst,
00102                                                unsigned RegNo,
00103                                                uint64_t Address,
00104                                                const void *Decoder);
00105 
00106 static DecodeStatus DecodeDSPRegsRegisterClass(MCInst &Inst,
00107                                                unsigned RegNo,
00108                                                uint64_t Address,
00109                                                const void *Decoder);
00110 
00111 static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
00112                                              unsigned RegNo,
00113                                              uint64_t Address,
00114                                              const void *Decoder);
00115 
00116 static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
00117                                              unsigned RegNo,
00118                                              uint64_t Address,
00119                                              const void *Decoder);
00120 
00121 static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
00122                                            unsigned RegNo,
00123                                            uint64_t Address,
00124                                            const void *Decoder);
00125 
00126 static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
00127                                               unsigned Insn,
00128                                               uint64_t Address,
00129                                               const void *Decoder);
00130 
00131 static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
00132                                               unsigned RegNo,
00133                                               uint64_t Address,
00134                                               const void *Decoder);
00135 
00136 static DecodeStatus DecodeHWRegs64RegisterClass(MCInst &Inst,
00137                                                 unsigned Insn,
00138                                                 uint64_t Address,
00139                                                 const void *Decoder);
00140 
00141 static DecodeStatus DecodeACRegsDSPRegisterClass(MCInst &Inst,
00142                                                  unsigned RegNo,
00143                                                  uint64_t Address,
00144                                                  const void *Decoder);
00145 
00146 static DecodeStatus DecodeHIRegsDSPRegisterClass(MCInst &Inst,
00147                                                  unsigned RegNo,
00148                                                  uint64_t Address,
00149                                                  const void *Decoder);
00150 
00151 static DecodeStatus DecodeLORegsDSPRegisterClass(MCInst &Inst,
00152                                                  unsigned RegNo,
00153                                                  uint64_t Address,
00154                                                  const void *Decoder);
00155 
00156 static DecodeStatus DecodeBranchTarget(MCInst &Inst,
00157                                        unsigned Offset,
00158                                        uint64_t Address,
00159                                        const void *Decoder);
00160 
00161 static DecodeStatus DecodeBC1(MCInst &Inst,
00162                               unsigned Insn,
00163                               uint64_t Address,
00164                               const void *Decoder);
00165 
00166 
00167 static DecodeStatus DecodeJumpTarget(MCInst &Inst,
00168                                      unsigned Insn,
00169                                      uint64_t Address,
00170                                      const void *Decoder);
00171 
00172 static DecodeStatus DecodeMem(MCInst &Inst,
00173                               unsigned Insn,
00174                               uint64_t Address,
00175                               const void *Decoder);
00176 
00177 static DecodeStatus DecodeFMem(MCInst &Inst, unsigned Insn,
00178                                uint64_t Address,
00179                                const void *Decoder);
00180 
00181 static DecodeStatus DecodeSimm16(MCInst &Inst,
00182                                  unsigned Insn,
00183                                  uint64_t Address,
00184                                  const void *Decoder);
00185 
00186 static DecodeStatus DecodeCondCode(MCInst &Inst,
00187                                    unsigned Insn,
00188                                    uint64_t Address,
00189                                    const void *Decoder);
00190 
00191 static DecodeStatus DecodeInsSize(MCInst &Inst,
00192                                   unsigned Insn,
00193                                   uint64_t Address,
00194                                   const void *Decoder);
00195 
00196 static DecodeStatus DecodeExtSize(MCInst &Inst,
00197                                   unsigned Insn,
00198                                   uint64_t Address,
00199                                   const void *Decoder);
00200 
00201 namespace llvm {
00202 extern Target TheMipselTarget, TheMipsTarget, TheMips64Target,
00203               TheMips64elTarget;
00204 }
00205 
00206 static MCDisassembler *createMipsDisassembler(
00207                        const Target &T,
00208                        const MCSubtargetInfo &STI) {
00209   return new MipsDisassembler(STI, T.createMCRegInfo(""), true);
00210 }
00211 
00212 static MCDisassembler *createMipselDisassembler(
00213                        const Target &T,
00214                        const MCSubtargetInfo &STI) {
00215   return new MipsDisassembler(STI, T.createMCRegInfo(""), false);
00216 }
00217 
00218 static MCDisassembler *createMips64Disassembler(
00219                        const Target &T,
00220                        const MCSubtargetInfo &STI) {
00221   return new Mips64Disassembler(STI, T.createMCRegInfo(""), true);
00222 }
00223 
00224 static MCDisassembler *createMips64elDisassembler(
00225                        const Target &T,
00226                        const MCSubtargetInfo &STI) {
00227   return new Mips64Disassembler(STI, T.createMCRegInfo(""), false);
00228 }
00229 
00230 extern "C" void LLVMInitializeMipsDisassembler() {
00231   // Register the disassembler.
00232   TargetRegistry::RegisterMCDisassembler(TheMipsTarget,
00233                                          createMipsDisassembler);
00234   TargetRegistry::RegisterMCDisassembler(TheMipselTarget,
00235                                          createMipselDisassembler);
00236   TargetRegistry::RegisterMCDisassembler(TheMips64Target,
00237                                          createMips64Disassembler);
00238   TargetRegistry::RegisterMCDisassembler(TheMips64elTarget,
00239                                          createMips64elDisassembler);
00240 }
00241 
00242 
00243 #include "MipsGenDisassemblerTables.inc"
00244 
00245   /// readInstruction - read four bytes from the MemoryObject
00246   /// and return 32 bit word sorted according to the given endianess
00247 static DecodeStatus readInstruction32(const MemoryObject &region,
00248                                       uint64_t address,
00249                                       uint64_t &size,
00250                                       uint32_t &insn,
00251                                       bool isBigEndian) {
00252   uint8_t Bytes[4];
00253 
00254   // We want to read exactly 4 Bytes of data.
00255   if (region.readBytes(address, 4, (uint8_t*)Bytes, NULL) == -1) {
00256     size = 0;
00257     return MCDisassembler::Fail;
00258   }
00259 
00260   if (isBigEndian) {
00261     // Encoded as a big-endian 32-bit word in the stream.
00262     insn = (Bytes[3] <<  0) |
00263            (Bytes[2] <<  8) |
00264            (Bytes[1] << 16) |
00265            (Bytes[0] << 24);
00266   }
00267   else {
00268     // Encoded as a small-endian 32-bit word in the stream.
00269     insn = (Bytes[0] <<  0) |
00270            (Bytes[1] <<  8) |
00271            (Bytes[2] << 16) |
00272            (Bytes[3] << 24);
00273   }
00274 
00275   return MCDisassembler::Success;
00276 }
00277 
00278 DecodeStatus
00279 MipsDisassembler::getInstruction(MCInst &instr,
00280                                  uint64_t &Size,
00281                                  const MemoryObject &Region,
00282                                  uint64_t Address,
00283                                  raw_ostream &vStream,
00284                                  raw_ostream &cStream) const {
00285   uint32_t Insn;
00286 
00287   DecodeStatus Result = readInstruction32(Region, Address, Size,
00288                                           Insn, isBigEndian);
00289   if (Result == MCDisassembler::Fail)
00290     return MCDisassembler::Fail;
00291 
00292   // Calling the auto-generated decoder function.
00293   Result = decodeInstruction(DecoderTableMips32, instr, Insn, Address,
00294                              this, STI);
00295   if (Result != MCDisassembler::Fail) {
00296     Size = 4;
00297     return Result;
00298   }
00299 
00300   return MCDisassembler::Fail;
00301 }
00302 
00303 DecodeStatus
00304 Mips64Disassembler::getInstruction(MCInst &instr,
00305                                    uint64_t &Size,
00306                                    const MemoryObject &Region,
00307                                    uint64_t Address,
00308                                    raw_ostream &vStream,
00309                                    raw_ostream &cStream) const {
00310   uint32_t Insn;
00311 
00312   DecodeStatus Result = readInstruction32(Region, Address, Size,
00313                                           Insn, isBigEndian);
00314   if (Result == MCDisassembler::Fail)
00315     return MCDisassembler::Fail;
00316 
00317   // Calling the auto-generated decoder function.
00318   Result = decodeInstruction(DecoderTableMips6432, instr, Insn, Address,
00319                              this, STI);
00320   if (Result != MCDisassembler::Fail) {
00321     Size = 4;
00322     return Result;
00323   }
00324   // If we fail to decode in Mips64 decoder space we can try in Mips32
00325   Result = decodeInstruction(DecoderTableMips32, instr, Insn, Address,
00326                              this, STI);
00327   if (Result != MCDisassembler::Fail) {
00328     Size = 4;
00329     return Result;
00330   }
00331 
00332   return MCDisassembler::Fail;
00333 }
00334 
00335 static unsigned getReg(const void *D, unsigned RC, unsigned RegNo) {
00336   const MipsDisassemblerBase *Dis = static_cast<const MipsDisassemblerBase*>(D);
00337   return *(Dis->getRegInfo()->getRegClass(RC).begin() + RegNo);
00338 }
00339 
00340 static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst,
00341                                                  unsigned RegNo,
00342                                                  uint64_t Address,
00343                                                  const void *Decoder) {
00344 
00345   return MCDisassembler::Fail;
00346 
00347 }
00348 
00349 static DecodeStatus DecodeCPU64RegsRegisterClass(MCInst &Inst,
00350                                                  unsigned RegNo,
00351                                                  uint64_t Address,
00352                                                  const void *Decoder) {
00353 
00354   if (RegNo > 31)
00355     return MCDisassembler::Fail;
00356 
00357   unsigned Reg = getReg(Decoder, Mips::CPU64RegsRegClassID, RegNo);
00358   Inst.addOperand(MCOperand::CreateReg(Reg));
00359   return MCDisassembler::Success;
00360 }
00361 
00362 static DecodeStatus DecodeCPURegsRegisterClass(MCInst &Inst,
00363                                                unsigned RegNo,
00364                                                uint64_t Address,
00365                                                const void *Decoder) {
00366   if (RegNo > 31)
00367     return MCDisassembler::Fail;
00368   unsigned Reg = getReg(Decoder, Mips::CPURegsRegClassID, RegNo);
00369   Inst.addOperand(MCOperand::CreateReg(Reg));
00370   return MCDisassembler::Success;
00371 }
00372 
00373 static DecodeStatus DecodeDSPRegsRegisterClass(MCInst &Inst,
00374                                                unsigned RegNo,
00375                                                uint64_t Address,
00376                                                const void *Decoder) {
00377   return DecodeCPURegsRegisterClass(Inst, RegNo, Address, Decoder);
00378 }
00379 
00380 static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
00381                                              unsigned RegNo,
00382                                              uint64_t Address,
00383                                              const void *Decoder) {
00384   if (RegNo > 31)
00385     return MCDisassembler::Fail;
00386 
00387   unsigned Reg = getReg(Decoder, Mips::FGR64RegClassID, RegNo);
00388   Inst.addOperand(MCOperand::CreateReg(Reg));
00389   return MCDisassembler::Success;
00390 }
00391 
00392 static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
00393                                              unsigned RegNo,
00394                                              uint64_t Address,
00395                                              const void *Decoder) {
00396   if (RegNo > 31)
00397     return MCDisassembler::Fail;
00398 
00399   unsigned Reg = getReg(Decoder, Mips::FGR32RegClassID, RegNo);
00400   Inst.addOperand(MCOperand::CreateReg(Reg));
00401   return MCDisassembler::Success;
00402 }
00403 
00404 static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
00405                                            unsigned RegNo,
00406                                            uint64_t Address,
00407                                            const void *Decoder) {
00408   Inst.addOperand(MCOperand::CreateReg(RegNo));
00409   return MCDisassembler::Success;
00410 }
00411 
00412 static DecodeStatus DecodeMem(MCInst &Inst,
00413                               unsigned Insn,
00414                               uint64_t Address,
00415                               const void *Decoder) {
00416   int Offset = SignExtend32<16>(Insn & 0xffff);
00417   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
00418   unsigned Base = fieldFromInstruction(Insn, 21, 5);
00419 
00420   Reg = getReg(Decoder, Mips::CPURegsRegClassID, Reg);
00421   Base = getReg(Decoder, Mips::CPURegsRegClassID, Base);
00422 
00423   if(Inst.getOpcode() == Mips::SC){
00424     Inst.addOperand(MCOperand::CreateReg(Reg));
00425   }
00426 
00427   Inst.addOperand(MCOperand::CreateReg(Reg));
00428   Inst.addOperand(MCOperand::CreateReg(Base));
00429   Inst.addOperand(MCOperand::CreateImm(Offset));
00430 
00431   return MCDisassembler::Success;
00432 }
00433 
00434 static DecodeStatus DecodeFMem(MCInst &Inst,
00435                                unsigned Insn,
00436                                uint64_t Address,
00437                                const void *Decoder) {
00438   int Offset = SignExtend32<16>(Insn & 0xffff);
00439   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
00440   unsigned Base = fieldFromInstruction(Insn, 21, 5);
00441 
00442   Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg);
00443   Base = getReg(Decoder, Mips::CPURegsRegClassID, Base);
00444 
00445   Inst.addOperand(MCOperand::CreateReg(Reg));
00446   Inst.addOperand(MCOperand::CreateReg(Base));
00447   Inst.addOperand(MCOperand::CreateImm(Offset));
00448 
00449   return MCDisassembler::Success;
00450 }
00451 
00452 
00453 static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
00454                                               unsigned RegNo,
00455                                               uint64_t Address,
00456                                               const void *Decoder) {
00457   // Currently only hardware register 29 is supported.
00458   if (RegNo != 29)
00459     return  MCDisassembler::Fail;
00460   Inst.addOperand(MCOperand::CreateReg(Mips::HWR29));
00461   return MCDisassembler::Success;
00462 }
00463 
00464 static DecodeStatus DecodeCondCode(MCInst &Inst,
00465                                    unsigned Insn,
00466                                    uint64_t Address,
00467                                    const void *Decoder) {
00468   int CondCode = Insn & 0xf;
00469   Inst.addOperand(MCOperand::CreateImm(CondCode));
00470   return MCDisassembler::Success;
00471 }
00472 
00473 static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
00474                                               unsigned RegNo,
00475                                               uint64_t Address,
00476                                               const void *Decoder) {
00477   if (RegNo > 30 || RegNo %2)
00478     return MCDisassembler::Fail;
00479 
00480   ;
00481   unsigned Reg = getReg(Decoder, Mips::AFGR64RegClassID, RegNo /2);
00482   Inst.addOperand(MCOperand::CreateReg(Reg));
00483   return MCDisassembler::Success;
00484 }
00485 
00486 static DecodeStatus DecodeHWRegs64RegisterClass(MCInst &Inst,
00487                                                 unsigned RegNo,
00488                                                 uint64_t Address,
00489                                                 const void *Decoder) {
00490   //Currently only hardware register 29 is supported
00491   if (RegNo != 29)
00492     return  MCDisassembler::Fail;
00493   Inst.addOperand(MCOperand::CreateReg(Mips::HWR29_64));
00494   return MCDisassembler::Success;
00495 }
00496 
00497 static DecodeStatus DecodeACRegsDSPRegisterClass(MCInst &Inst,
00498                                                  unsigned RegNo,
00499                                                  uint64_t Address,
00500                                                  const void *Decoder) {
00501   if (RegNo >= 4)
00502     return MCDisassembler::Fail;
00503 
00504   unsigned Reg = getReg(Decoder, Mips::ACRegsDSPRegClassID, RegNo);
00505   Inst.addOperand(MCOperand::CreateReg(Reg));
00506   return MCDisassembler::Success;
00507 }
00508 
00509 static DecodeStatus DecodeHIRegsDSPRegisterClass(MCInst &Inst,
00510                                                  unsigned RegNo,
00511                                                  uint64_t Address,
00512                                                  const void *Decoder) {
00513   if (RegNo >= 4)
00514     return MCDisassembler::Fail;
00515 
00516   unsigned Reg = getReg(Decoder, Mips::HIRegsDSPRegClassID, RegNo);
00517   Inst.addOperand(MCOperand::CreateReg(Reg));
00518   return MCDisassembler::Success;
00519 }
00520 
00521 static DecodeStatus DecodeLORegsDSPRegisterClass(MCInst &Inst,
00522                                                  unsigned RegNo,
00523                                                  uint64_t Address,
00524                                                  const void *Decoder) {
00525   if (RegNo >= 4)
00526     return MCDisassembler::Fail;
00527 
00528   unsigned Reg = getReg(Decoder, Mips::LORegsDSPRegClassID, RegNo);
00529   Inst.addOperand(MCOperand::CreateReg(Reg));
00530   return MCDisassembler::Success;
00531 }
00532 
00533 static DecodeStatus DecodeBranchTarget(MCInst &Inst,
00534                                        unsigned Offset,
00535                                        uint64_t Address,
00536                                        const void *Decoder) {
00537   unsigned BranchOffset = Offset & 0xffff;
00538   BranchOffset = SignExtend32<18>(BranchOffset << 2) + 4;
00539   Inst.addOperand(MCOperand::CreateImm(BranchOffset));
00540   return MCDisassembler::Success;
00541 }
00542 
00543 static DecodeStatus DecodeBC1(MCInst &Inst,
00544                               unsigned Insn,
00545                               uint64_t Address,
00546                               const void *Decoder) {
00547   unsigned BranchOffset = Insn & 0xffff;
00548   BranchOffset = SignExtend32<18>(BranchOffset << 2) + 4;
00549   Inst.addOperand(MCOperand::CreateImm(BranchOffset));
00550   return MCDisassembler::Success;
00551 }
00552 
00553 static DecodeStatus DecodeJumpTarget(MCInst &Inst,
00554                                      unsigned Insn,
00555                                      uint64_t Address,
00556                                      const void *Decoder) {
00557 
00558   unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 2;
00559   Inst.addOperand(MCOperand::CreateImm(JumpOffset));
00560   return MCDisassembler::Success;
00561 }
00562 
00563 
00564 static DecodeStatus DecodeSimm16(MCInst &Inst,
00565                                  unsigned Insn,
00566                                  uint64_t Address,
00567                                  const void *Decoder) {
00568   Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Insn)));
00569   return MCDisassembler::Success;
00570 }
00571 
00572 static DecodeStatus DecodeInsSize(MCInst &Inst,
00573                                   unsigned Insn,
00574                                   uint64_t Address,
00575                                   const void *Decoder) {
00576   // First we need to grab the pos(lsb) from MCInst.
00577   int Pos = Inst.getOperand(2).getImm();
00578   int Size = (int) Insn - Pos + 1;
00579   Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size)));
00580   return MCDisassembler::Success;
00581 }
00582 
00583 static DecodeStatus DecodeExtSize(MCInst &Inst,
00584                                   unsigned Insn,
00585                                   uint64_t Address,
00586                                   const void *Decoder) {
00587   int Size = (int) Insn  + 1;
00588   Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size)));
00589   return MCDisassembler::Success;
00590 }