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