Home | History | Annotate | Download | only in Disassembler
      1 //===- MipsDisassembler.cpp - Disassembler for Mips -------------*- 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 Mips Disassembler.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 #include "Mips.h"
     15 #include "MipsSubtarget.h"
     16 #include "MipsRegisterInfo.h"
     17 #include "llvm/MC/EDInstInfo.h"
     18 #include "llvm/MC/MCDisassembler.h"
     19 #include "llvm/MC/MCFixedLenDisassembler.h"
     20 #include "llvm/Support/MemoryObject.h"
     21 #include "llvm/Support/TargetRegistry.h"
     22 #include "llvm/MC/MCSubtargetInfo.h"
     23 #include "llvm/MC/MCInst.h"
     24 #include "llvm/Support/MathExtras.h"
     25 
     26 #include "MipsGenEDInfo.inc"
     27 
     28 using namespace llvm;
     29 
     30 typedef MCDisassembler::DecodeStatus DecodeStatus;
     31 
     32 namespace {
     33 
     34 /// MipsDisassemblerBase - a disasembler class for Mips.
     35 class MipsDisassemblerBase : public MCDisassembler {
     36 public:
     37   /// Constructor     - Initializes the disassembler.
     38   ///
     39   MipsDisassemblerBase(const MCSubtargetInfo &STI, const MCRegisterInfo *Info,
     40                        bool bigEndian) :
     41     MCDisassembler(STI), RegInfo(Info), isBigEndian(bigEndian) {}
     42 
     43   virtual ~MipsDisassemblerBase() {}
     44 
     45   /// getEDInfo - See MCDisassembler.
     46   const EDInstInfo *getEDInfo() const;
     47 
     48   const MCRegisterInfo *getRegInfo() const { return RegInfo; }
     49 
     50 private:
     51   const MCRegisterInfo *RegInfo;
     52 protected:
     53   bool isBigEndian;
     54 };
     55 
     56 /// MipsDisassembler - a disasembler class for Mips32.
     57 class MipsDisassembler : public MipsDisassemblerBase {
     58 public:
     59   /// Constructor     - Initializes the disassembler.
     60   ///
     61   MipsDisassembler(const MCSubtargetInfo &STI, const MCRegisterInfo *Info,
     62                    bool bigEndian) :
     63     MipsDisassemblerBase(STI, Info, bigEndian) {}
     64 
     65   /// getInstruction - See MCDisassembler.
     66   virtual DecodeStatus getInstruction(MCInst &instr,
     67                                       uint64_t &size,
     68                                       const MemoryObject &region,
     69                                       uint64_t address,
     70                                       raw_ostream &vStream,
     71                                       raw_ostream &cStream) const;
     72 };
     73 
     74 
     75 /// Mips64Disassembler - a disasembler class for Mips64.
     76 class Mips64Disassembler : public MipsDisassemblerBase {
     77 public:
     78   /// Constructor     - Initializes the disassembler.
     79   ///
     80   Mips64Disassembler(const MCSubtargetInfo &STI, const MCRegisterInfo *Info,
     81                      bool bigEndian) :
     82     MipsDisassemblerBase(STI, Info, bigEndian) {}
     83 
     84   /// getInstruction - See MCDisassembler.
     85   virtual DecodeStatus getInstruction(MCInst &instr,
     86                                       uint64_t &size,
     87                                       const MemoryObject &region,
     88                                       uint64_t address,
     89                                       raw_ostream &vStream,
     90                                       raw_ostream &cStream) const;
     91 };
     92 
     93 } // end anonymous namespace
     94 
     95 const EDInstInfo *MipsDisassemblerBase::getEDInfo() const {
     96   return instInfoMips;
     97 }
     98 
     99 // Forward declare these because the autogenerated code will reference them.
    100 // Definitions are further down.
    101 static DecodeStatus DecodeCPU64RegsRegisterClass(MCInst &Inst,
    102                                                  unsigned RegNo,
    103                                                  uint64_t Address,
    104                                                  const void *Decoder);
    105 
    106 static DecodeStatus DecodeCPURegsRegisterClass(MCInst &Inst,
    107                                                unsigned RegNo,
    108                                                uint64_t Address,
    109                                                const void *Decoder);
    110 
    111 static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
    112                                              unsigned RegNo,
    113                                              uint64_t Address,
    114                                              const void *Decoder);
    115 
    116 static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
    117                                              unsigned RegNo,
    118                                              uint64_t Address,
    119                                              const void *Decoder);
    120 
    121 static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
    122                                            unsigned RegNo,
    123                                            uint64_t Address,
    124                                            const void *Decoder);
    125 
    126 static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
    127                                               unsigned Insn,
    128                                               uint64_t Address,
    129                                               const void *Decoder);
    130 
    131 static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
    132                                               unsigned RegNo,
    133                                               uint64_t Address,
    134                                               const void *Decoder);
    135 
    136 static DecodeStatus DecodeHWRegs64RegisterClass(MCInst &Inst,
    137                                                 unsigned Insn,
    138                                                 uint64_t Address,
    139                                                 const void *Decoder);
    140 
    141 static DecodeStatus DecodeBranchTarget(MCInst &Inst,
    142                                        unsigned Offset,
    143                                        uint64_t Address,
    144                                        const void *Decoder);
    145 
    146 static DecodeStatus DecodeBC1(MCInst &Inst,
    147                               unsigned Insn,
    148                               uint64_t Address,
    149                               const void *Decoder);
    150 
    151 
    152 static DecodeStatus DecodeJumpTarget(MCInst &Inst,
    153                                      unsigned Insn,
    154                                      uint64_t Address,
    155                                      const void *Decoder);
    156 
    157 static DecodeStatus DecodeMem(MCInst &Inst,
    158                               unsigned Insn,
    159                               uint64_t Address,
    160                               const void *Decoder);
    161 
    162 static DecodeStatus DecodeFMem(MCInst &Inst, unsigned Insn,
    163                                uint64_t Address,
    164                                const void *Decoder);
    165 
    166 static DecodeStatus DecodeSimm16(MCInst &Inst,
    167                                  unsigned Insn,
    168                                  uint64_t Address,
    169                                  const void *Decoder);
    170 
    171 static DecodeStatus DecodeCondCode(MCInst &Inst,
    172                                    unsigned Insn,
    173                                    uint64_t Address,
    174                                    const void *Decoder);
    175 
    176 static DecodeStatus DecodeInsSize(MCInst &Inst,
    177                                   unsigned Insn,
    178                                   uint64_t Address,
    179                                   const void *Decoder);
    180 
    181 static DecodeStatus DecodeExtSize(MCInst &Inst,
    182                                   unsigned Insn,
    183                                   uint64_t Address,
    184                                   const void *Decoder);
    185 
    186 namespace llvm {
    187 extern Target TheMipselTarget, TheMipsTarget, TheMips64Target,
    188               TheMips64elTarget;
    189 }
    190 
    191 static MCDisassembler *createMipsDisassembler(
    192                        const Target &T,
    193                        const MCSubtargetInfo &STI) {
    194   return new MipsDisassembler(STI, T.createMCRegInfo(""), true);
    195 }
    196 
    197 static MCDisassembler *createMipselDisassembler(
    198                        const Target &T,
    199                        const MCSubtargetInfo &STI) {
    200   return new MipsDisassembler(STI, T.createMCRegInfo(""), false);
    201 }
    202 
    203 static MCDisassembler *createMips64Disassembler(
    204                        const Target &T,
    205                        const MCSubtargetInfo &STI) {
    206   return new Mips64Disassembler(STI, T.createMCRegInfo(""), true);
    207 }
    208 
    209 static MCDisassembler *createMips64elDisassembler(
    210                        const Target &T,
    211                        const MCSubtargetInfo &STI) {
    212   return new Mips64Disassembler(STI, T.createMCRegInfo(""), false);
    213 }
    214 
    215 extern "C" void LLVMInitializeMipsDisassembler() {
    216   // Register the disassembler.
    217   TargetRegistry::RegisterMCDisassembler(TheMipsTarget,
    218                                          createMipsDisassembler);
    219   TargetRegistry::RegisterMCDisassembler(TheMipselTarget,
    220                                          createMipselDisassembler);
    221   TargetRegistry::RegisterMCDisassembler(TheMips64Target,
    222                                          createMips64Disassembler);
    223   TargetRegistry::RegisterMCDisassembler(TheMips64elTarget,
    224                                          createMips64elDisassembler);
    225 }
    226 
    227 
    228 #include "MipsGenDisassemblerTables.inc"
    229 
    230   /// readInstruction - read four bytes from the MemoryObject
    231   /// and return 32 bit word sorted according to the given endianess
    232 static DecodeStatus readInstruction32(const MemoryObject &region,
    233                                       uint64_t address,
    234                                       uint64_t &size,
    235                                       uint32_t &insn,
    236                                       bool isBigEndian) {
    237   uint8_t Bytes[4];
    238 
    239   // We want to read exactly 4 Bytes of data.
    240   if (region.readBytes(address, 4, (uint8_t*)Bytes, NULL) == -1) {
    241     size = 0;
    242     return MCDisassembler::Fail;
    243   }
    244 
    245   if (isBigEndian) {
    246     // Encoded as a big-endian 32-bit word in the stream.
    247     insn = (Bytes[3] <<  0) |
    248            (Bytes[2] <<  8) |
    249            (Bytes[1] << 16) |
    250            (Bytes[0] << 24);
    251   }
    252   else {
    253     // Encoded as a small-endian 32-bit word in the stream.
    254     insn = (Bytes[0] <<  0) |
    255            (Bytes[1] <<  8) |
    256            (Bytes[2] << 16) |
    257            (Bytes[3] << 24);
    258   }
    259 
    260   return MCDisassembler::Success;
    261 }
    262 
    263 DecodeStatus
    264 MipsDisassembler::getInstruction(MCInst &instr,
    265                                  uint64_t &Size,
    266                                  const MemoryObject &Region,
    267                                  uint64_t Address,
    268                                  raw_ostream &vStream,
    269                                  raw_ostream &cStream) const {
    270   uint32_t Insn;
    271 
    272   DecodeStatus Result = readInstruction32(Region, Address, Size,
    273                                           Insn, isBigEndian);
    274   if (Result == MCDisassembler::Fail)
    275     return MCDisassembler::Fail;
    276 
    277   // Calling the auto-generated decoder function.
    278   Result = decodeInstruction(DecoderTableMips32, instr, Insn, Address,
    279                              this, STI);
    280   if (Result != MCDisassembler::Fail) {
    281     Size = 4;
    282     return Result;
    283   }
    284 
    285   return MCDisassembler::Fail;
    286 }
    287 
    288 DecodeStatus
    289 Mips64Disassembler::getInstruction(MCInst &instr,
    290                                    uint64_t &Size,
    291                                    const MemoryObject &Region,
    292                                    uint64_t Address,
    293                                    raw_ostream &vStream,
    294                                    raw_ostream &cStream) const {
    295   uint32_t Insn;
    296 
    297   DecodeStatus Result = readInstruction32(Region, Address, Size,
    298                                           Insn, isBigEndian);
    299   if (Result == MCDisassembler::Fail)
    300     return MCDisassembler::Fail;
    301 
    302   // Calling the auto-generated decoder function.
    303   Result = decodeInstruction(DecoderTableMips6432, instr, Insn, Address,
    304                              this, STI);
    305   if (Result != MCDisassembler::Fail) {
    306     Size = 4;
    307     return Result;
    308   }
    309   // If we fail to decode in Mips64 decoder space we can try in Mips32
    310   Result = decodeInstruction(DecoderTableMips32, instr, Insn, Address,
    311                              this, STI);
    312   if (Result != MCDisassembler::Fail) {
    313     Size = 4;
    314     return Result;
    315   }
    316 
    317   return MCDisassembler::Fail;
    318 }
    319 
    320 static unsigned getReg(const void *D, unsigned RC, unsigned RegNo) {
    321   const MipsDisassemblerBase *Dis = static_cast<const MipsDisassemblerBase*>(D);
    322   return *(Dis->getRegInfo()->getRegClass(RC).begin() + RegNo);
    323 }
    324 
    325 static DecodeStatus DecodeCPU64RegsRegisterClass(MCInst &Inst,
    326                                                  unsigned RegNo,
    327                                                  uint64_t Address,
    328                                                  const void *Decoder) {
    329 
    330   if (RegNo > 31)
    331     return MCDisassembler::Fail;
    332 
    333   unsigned Reg = getReg(Decoder, Mips::CPU64RegsRegClassID, RegNo);
    334   Inst.addOperand(MCOperand::CreateReg(Reg));
    335   return MCDisassembler::Success;
    336 }
    337 
    338 static DecodeStatus DecodeCPURegsRegisterClass(MCInst &Inst,
    339                                                unsigned RegNo,
    340                                                uint64_t Address,
    341                                                const void *Decoder) {
    342   if (RegNo > 31)
    343     return MCDisassembler::Fail;
    344   unsigned Reg = getReg(Decoder, Mips::CPURegsRegClassID, RegNo);
    345   Inst.addOperand(MCOperand::CreateReg(Reg));
    346   return MCDisassembler::Success;
    347 }
    348 
    349 static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
    350                                              unsigned RegNo,
    351                                              uint64_t Address,
    352                                              const void *Decoder) {
    353   if (RegNo > 31)
    354     return MCDisassembler::Fail;
    355 
    356   unsigned Reg = getReg(Decoder, Mips::FGR64RegClassID, RegNo);
    357   Inst.addOperand(MCOperand::CreateReg(Reg));
    358   return MCDisassembler::Success;
    359 }
    360 
    361 static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
    362                                              unsigned RegNo,
    363                                              uint64_t Address,
    364                                              const void *Decoder) {
    365   if (RegNo > 31)
    366     return MCDisassembler::Fail;
    367 
    368   unsigned Reg = getReg(Decoder, Mips::FGR32RegClassID, RegNo);
    369   Inst.addOperand(MCOperand::CreateReg(Reg));
    370   return MCDisassembler::Success;
    371 }
    372 
    373 static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
    374                                            unsigned RegNo,
    375                                            uint64_t Address,
    376                                            const void *Decoder) {
    377   Inst.addOperand(MCOperand::CreateReg(RegNo));
    378   return MCDisassembler::Success;
    379 }
    380 
    381 static DecodeStatus DecodeMem(MCInst &Inst,
    382                               unsigned Insn,
    383                               uint64_t Address,
    384                               const void *Decoder) {
    385   int Offset = SignExtend32<16>(Insn & 0xffff);
    386   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
    387   unsigned Base = fieldFromInstruction(Insn, 21, 5);
    388 
    389   Reg = getReg(Decoder, Mips::CPURegsRegClassID, Reg);
    390   Base = getReg(Decoder, Mips::CPURegsRegClassID, Base);
    391 
    392   if(Inst.getOpcode() == Mips::SC){
    393     Inst.addOperand(MCOperand::CreateReg(Reg));
    394   }
    395 
    396   Inst.addOperand(MCOperand::CreateReg(Reg));
    397   Inst.addOperand(MCOperand::CreateReg(Base));
    398   Inst.addOperand(MCOperand::CreateImm(Offset));
    399 
    400   return MCDisassembler::Success;
    401 }
    402 
    403 static DecodeStatus DecodeFMem(MCInst &Inst,
    404                                unsigned Insn,
    405                                uint64_t Address,
    406                                const void *Decoder) {
    407   int Offset = SignExtend32<16>(Insn & 0xffff);
    408   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
    409   unsigned Base = fieldFromInstruction(Insn, 21, 5);
    410 
    411   Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg);
    412   Base = getReg(Decoder, Mips::CPURegsRegClassID, Base);
    413 
    414   Inst.addOperand(MCOperand::CreateReg(Reg));
    415   Inst.addOperand(MCOperand::CreateReg(Base));
    416   Inst.addOperand(MCOperand::CreateImm(Offset));
    417 
    418   return MCDisassembler::Success;
    419 }
    420 
    421 
    422 static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
    423                                               unsigned RegNo,
    424                                               uint64_t Address,
    425                                               const void *Decoder) {
    426   // Currently only hardware register 29 is supported.
    427   if (RegNo != 29)
    428     return  MCDisassembler::Fail;
    429   Inst.addOperand(MCOperand::CreateReg(Mips::HWR29));
    430   return MCDisassembler::Success;
    431 }
    432 
    433 static DecodeStatus DecodeCondCode(MCInst &Inst,
    434                                    unsigned Insn,
    435                                    uint64_t Address,
    436                                    const void *Decoder) {
    437   int CondCode = Insn & 0xf;
    438   Inst.addOperand(MCOperand::CreateImm(CondCode));
    439   return MCDisassembler::Success;
    440 }
    441 
    442 static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
    443                                               unsigned RegNo,
    444                                               uint64_t Address,
    445                                               const void *Decoder) {
    446   if (RegNo > 30 || RegNo %2)
    447     return MCDisassembler::Fail;
    448 
    449   ;
    450   unsigned Reg = getReg(Decoder, Mips::AFGR64RegClassID, RegNo /2);
    451   Inst.addOperand(MCOperand::CreateReg(Reg));
    452   return MCDisassembler::Success;
    453 }
    454 
    455 static DecodeStatus DecodeHWRegs64RegisterClass(MCInst &Inst,
    456                                                 unsigned RegNo,
    457                                                 uint64_t Address,
    458                                                 const void *Decoder) {
    459   //Currently only hardware register 29 is supported
    460   if (RegNo != 29)
    461     return  MCDisassembler::Fail;
    462   Inst.addOperand(MCOperand::CreateReg(Mips::HWR29_64));
    463   return MCDisassembler::Success;
    464 }
    465 
    466 static DecodeStatus DecodeBranchTarget(MCInst &Inst,
    467                                        unsigned Offset,
    468                                        uint64_t Address,
    469                                        const void *Decoder) {
    470   unsigned BranchOffset = Offset & 0xffff;
    471   BranchOffset = SignExtend32<18>(BranchOffset << 2) + 4;
    472   Inst.addOperand(MCOperand::CreateImm(BranchOffset));
    473   return MCDisassembler::Success;
    474 }
    475 
    476 static DecodeStatus DecodeBC1(MCInst &Inst,
    477                               unsigned Insn,
    478                               uint64_t Address,
    479                               const void *Decoder) {
    480   unsigned BranchOffset = Insn & 0xffff;
    481   BranchOffset = SignExtend32<18>(BranchOffset << 2) + 4;
    482   Inst.addOperand(MCOperand::CreateImm(BranchOffset));
    483   return MCDisassembler::Success;
    484 }
    485 
    486 static DecodeStatus DecodeJumpTarget(MCInst &Inst,
    487                                      unsigned Insn,
    488                                      uint64_t Address,
    489                                      const void *Decoder) {
    490 
    491   unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 2;
    492   Inst.addOperand(MCOperand::CreateImm(JumpOffset));
    493   return MCDisassembler::Success;
    494 }
    495 
    496 
    497 static DecodeStatus DecodeSimm16(MCInst &Inst,
    498                                  unsigned Insn,
    499                                  uint64_t Address,
    500                                  const void *Decoder) {
    501   Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Insn)));
    502   return MCDisassembler::Success;
    503 }
    504 
    505 static DecodeStatus DecodeInsSize(MCInst &Inst,
    506                                   unsigned Insn,
    507                                   uint64_t Address,
    508                                   const void *Decoder) {
    509   // First we need to grab the pos(lsb) from MCInst.
    510   int Pos = Inst.getOperand(2).getImm();
    511   int Size = (int) Insn - Pos + 1;
    512   Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size)));
    513   return MCDisassembler::Success;
    514 }
    515 
    516 static DecodeStatus DecodeExtSize(MCInst &Inst,
    517                                   unsigned Insn,
    518                                   uint64_t Address,
    519                                   const void *Decoder) {
    520   int Size = (int) Insn  + 1;
    521   Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size)));
    522   return MCDisassembler::Success;
    523 }
    524