171928e68SAkira Hatanaka //===- MipsDisassembler.cpp - Disassembler for Mips -------------*- C++ -*-===//
271928e68SAkira Hatanaka //
371928e68SAkira Hatanaka //                     The LLVM Compiler Infrastructure
471928e68SAkira Hatanaka //
571928e68SAkira Hatanaka // This file is distributed under the University of Illinois Open Source
671928e68SAkira Hatanaka // License. See LICENSE.TXT for details.
771928e68SAkira Hatanaka //
871928e68SAkira Hatanaka //===----------------------------------------------------------------------===//
971928e68SAkira Hatanaka //
1071928e68SAkira Hatanaka // This file is part of the Mips Disassembler.
1171928e68SAkira Hatanaka //
1271928e68SAkira Hatanaka //===----------------------------------------------------------------------===//
1371928e68SAkira Hatanaka 
1471928e68SAkira Hatanaka #include "Mips.h"
1571928e68SAkira Hatanaka #include "MipsSubtarget.h"
169bf2b567SAkira Hatanaka #include "MipsRegisterInfo.h"
1771928e68SAkira Hatanaka #include "llvm/MC/EDInstInfo.h"
1871928e68SAkira Hatanaka #include "llvm/MC/MCDisassembler.h"
19*ecaef49fSJim Grosbach #include "llvm/MC/MCFixedLenDisassembler.h"
2071928e68SAkira Hatanaka #include "llvm/Support/MemoryObject.h"
2171928e68SAkira Hatanaka #include "llvm/Support/TargetRegistry.h"
2271928e68SAkira Hatanaka #include "llvm/MC/MCSubtargetInfo.h"
2371928e68SAkira Hatanaka #include "llvm/MC/MCInst.h"
2471928e68SAkira Hatanaka #include "llvm/Support/MathExtras.h"
2571928e68SAkira Hatanaka 
2671928e68SAkira Hatanaka #include "MipsGenEDInfo.inc"
2771928e68SAkira Hatanaka 
2871928e68SAkira Hatanaka using namespace llvm;
2971928e68SAkira Hatanaka 
3071928e68SAkira Hatanaka typedef MCDisassembler::DecodeStatus DecodeStatus;
3171928e68SAkira Hatanaka 
32cb3e98cfSBenjamin Kramer namespace {
33cb3e98cfSBenjamin Kramer 
349bf2b567SAkira Hatanaka /// MipsDisassemblerBase - a disasembler class for Mips.
359bf2b567SAkira Hatanaka class MipsDisassemblerBase : public MCDisassembler {
3671928e68SAkira Hatanaka public:
3771928e68SAkira Hatanaka   /// Constructor     - Initializes the disassembler.
3871928e68SAkira Hatanaka   ///
399bf2b567SAkira Hatanaka   MipsDisassemblerBase(const MCSubtargetInfo &STI, const MCRegisterInfo *Info,
409bf2b567SAkira Hatanaka                        bool bigEndian) :
419bf2b567SAkira Hatanaka     MCDisassembler(STI), RegInfo(Info), isBigEndian(bigEndian) {}
4271928e68SAkira Hatanaka 
439bf2b567SAkira Hatanaka   virtual ~MipsDisassemblerBase() {}
449bf2b567SAkira Hatanaka 
459bf2b567SAkira Hatanaka   /// getEDInfo - See MCDisassembler.
469bf2b567SAkira Hatanaka   const EDInstInfo *getEDInfo() const;
479bf2b567SAkira Hatanaka 
489bf2b567SAkira Hatanaka   const MCRegisterInfo *getRegInfo() const { return RegInfo; }
499bf2b567SAkira Hatanaka 
509bf2b567SAkira Hatanaka private:
519bf2b567SAkira Hatanaka   const MCRegisterInfo *RegInfo;
529bf2b567SAkira Hatanaka protected:
539bf2b567SAkira Hatanaka   bool isBigEndian;
549bf2b567SAkira Hatanaka };
559bf2b567SAkira Hatanaka 
569bf2b567SAkira Hatanaka /// MipsDisassembler - a disasembler class for Mips32.
579bf2b567SAkira Hatanaka class MipsDisassembler : public MipsDisassemblerBase {
589bf2b567SAkira Hatanaka public:
599bf2b567SAkira Hatanaka   /// Constructor     - Initializes the disassembler.
609bf2b567SAkira Hatanaka   ///
619bf2b567SAkira Hatanaka   MipsDisassembler(const MCSubtargetInfo &STI, const MCRegisterInfo *Info,
629bf2b567SAkira Hatanaka                    bool bigEndian) :
639bf2b567SAkira Hatanaka     MipsDisassemblerBase(STI, Info, bigEndian) {}
6471928e68SAkira Hatanaka 
6571928e68SAkira Hatanaka   /// getInstruction - See MCDisassembler.
669bf2b567SAkira Hatanaka   virtual DecodeStatus getInstruction(MCInst &instr,
6771928e68SAkira Hatanaka                                       uint64_t &size,
6871928e68SAkira Hatanaka                                       const MemoryObject &region,
6971928e68SAkira Hatanaka                                       uint64_t address,
7071928e68SAkira Hatanaka                                       raw_ostream &vStream,
7171928e68SAkira Hatanaka                                       raw_ostream &cStream) const;
7271928e68SAkira Hatanaka };
7371928e68SAkira Hatanaka 
7471928e68SAkira Hatanaka 
7571928e68SAkira Hatanaka /// Mips64Disassembler - a disasembler class for Mips64.
769bf2b567SAkira Hatanaka class Mips64Disassembler : public MipsDisassemblerBase {
7771928e68SAkira Hatanaka public:
7871928e68SAkira Hatanaka   /// Constructor     - Initializes the disassembler.
7971928e68SAkira Hatanaka   ///
809bf2b567SAkira Hatanaka   Mips64Disassembler(const MCSubtargetInfo &STI, const MCRegisterInfo *Info,
819bf2b567SAkira Hatanaka                      bool bigEndian) :
829bf2b567SAkira Hatanaka     MipsDisassemblerBase(STI, Info, bigEndian) {}
8371928e68SAkira Hatanaka 
8471928e68SAkira Hatanaka   /// getInstruction - See MCDisassembler.
859bf2b567SAkira Hatanaka   virtual DecodeStatus getInstruction(MCInst &instr,
8671928e68SAkira Hatanaka                                       uint64_t &size,
8771928e68SAkira Hatanaka                                       const MemoryObject &region,
8871928e68SAkira Hatanaka                                       uint64_t address,
8971928e68SAkira Hatanaka                                       raw_ostream &vStream,
9071928e68SAkira Hatanaka                                       raw_ostream &cStream) const;
9171928e68SAkira Hatanaka };
9271928e68SAkira Hatanaka 
93cb3e98cfSBenjamin Kramer } // end anonymous namespace
94cb3e98cfSBenjamin Kramer 
959bf2b567SAkira Hatanaka const EDInstInfo *MipsDisassemblerBase::getEDInfo() const {
9671928e68SAkira Hatanaka   return instInfoMips;
9771928e68SAkira Hatanaka }
9871928e68SAkira Hatanaka 
9971928e68SAkira Hatanaka // Forward declare these because the autogenerated code will reference them.
10071928e68SAkira Hatanaka // Definitions are further down.
10171928e68SAkira Hatanaka static DecodeStatus DecodeCPU64RegsRegisterClass(MCInst &Inst,
10271928e68SAkira Hatanaka                                                  unsigned RegNo,
10371928e68SAkira Hatanaka                                                  uint64_t Address,
10471928e68SAkira Hatanaka                                                  const void *Decoder);
10571928e68SAkira Hatanaka 
10671928e68SAkira Hatanaka static DecodeStatus DecodeCPURegsRegisterClass(MCInst &Inst,
10771928e68SAkira Hatanaka                                                unsigned RegNo,
10871928e68SAkira Hatanaka                                                uint64_t Address,
10971928e68SAkira Hatanaka                                                const void *Decoder);
11071928e68SAkira Hatanaka 
11171928e68SAkira Hatanaka static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
11271928e68SAkira Hatanaka                                              unsigned RegNo,
11371928e68SAkira Hatanaka                                              uint64_t Address,
11471928e68SAkira Hatanaka                                              const void *Decoder);
11571928e68SAkira Hatanaka 
11671928e68SAkira Hatanaka static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
11771928e68SAkira Hatanaka                                              unsigned RegNo,
11871928e68SAkira Hatanaka                                              uint64_t Address,
11971928e68SAkira Hatanaka                                              const void *Decoder);
12071928e68SAkira Hatanaka 
12171928e68SAkira Hatanaka static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
12271928e68SAkira Hatanaka                                            unsigned RegNo,
12371928e68SAkira Hatanaka                                            uint64_t Address,
12471928e68SAkira Hatanaka                                            const void *Decoder);
12571928e68SAkira Hatanaka 
12671928e68SAkira Hatanaka static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
12771928e68SAkira Hatanaka                                               unsigned Insn,
12871928e68SAkira Hatanaka                                               uint64_t Address,
12971928e68SAkira Hatanaka                                               const void *Decoder);
13071928e68SAkira Hatanaka 
13171928e68SAkira Hatanaka static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
13271928e68SAkira Hatanaka                                               unsigned RegNo,
13371928e68SAkira Hatanaka                                               uint64_t Address,
13471928e68SAkira Hatanaka                                               const void *Decoder);
13571928e68SAkira Hatanaka 
13671928e68SAkira Hatanaka static DecodeStatus DecodeHWRegs64RegisterClass(MCInst &Inst,
13771928e68SAkira Hatanaka                                                 unsigned Insn,
13871928e68SAkira Hatanaka                                                 uint64_t Address,
13971928e68SAkira Hatanaka                                                 const void *Decoder);
14071928e68SAkira Hatanaka 
14171928e68SAkira Hatanaka static DecodeStatus DecodeBranchTarget(MCInst &Inst,
14271928e68SAkira Hatanaka                                        unsigned Offset,
14371928e68SAkira Hatanaka                                        uint64_t Address,
14471928e68SAkira Hatanaka                                        const void *Decoder);
14571928e68SAkira Hatanaka 
14671928e68SAkira Hatanaka static DecodeStatus DecodeBC1(MCInst &Inst,
14771928e68SAkira Hatanaka                               unsigned Insn,
14871928e68SAkira Hatanaka                               uint64_t Address,
14971928e68SAkira Hatanaka                               const void *Decoder);
15071928e68SAkira Hatanaka 
15171928e68SAkira Hatanaka 
15271928e68SAkira Hatanaka static DecodeStatus DecodeJumpTarget(MCInst &Inst,
15371928e68SAkira Hatanaka                                      unsigned Insn,
15471928e68SAkira Hatanaka                                      uint64_t Address,
15571928e68SAkira Hatanaka                                      const void *Decoder);
15671928e68SAkira Hatanaka 
15771928e68SAkira Hatanaka static DecodeStatus DecodeMem(MCInst &Inst,
15871928e68SAkira Hatanaka                               unsigned Insn,
15971928e68SAkira Hatanaka                               uint64_t Address,
16071928e68SAkira Hatanaka                               const void *Decoder);
16171928e68SAkira Hatanaka 
16271928e68SAkira Hatanaka static DecodeStatus DecodeFMem(MCInst &Inst, unsigned Insn,
16371928e68SAkira Hatanaka                                uint64_t Address,
16471928e68SAkira Hatanaka                                const void *Decoder);
16571928e68SAkira Hatanaka 
16671928e68SAkira Hatanaka static DecodeStatus DecodeSimm16(MCInst &Inst,
16771928e68SAkira Hatanaka                                  unsigned Insn,
16871928e68SAkira Hatanaka                                  uint64_t Address,
16971928e68SAkira Hatanaka                                  const void *Decoder);
17071928e68SAkira Hatanaka 
17171928e68SAkira Hatanaka static DecodeStatus DecodeCondCode(MCInst &Inst,
17271928e68SAkira Hatanaka                                    unsigned Insn,
17371928e68SAkira Hatanaka                                    uint64_t Address,
17471928e68SAkira Hatanaka                                    const void *Decoder);
17571928e68SAkira Hatanaka 
17671928e68SAkira Hatanaka static DecodeStatus DecodeInsSize(MCInst &Inst,
17771928e68SAkira Hatanaka                                   unsigned Insn,
17871928e68SAkira Hatanaka                                   uint64_t Address,
17971928e68SAkira Hatanaka                                   const void *Decoder);
18071928e68SAkira Hatanaka 
18171928e68SAkira Hatanaka static DecodeStatus DecodeExtSize(MCInst &Inst,
18271928e68SAkira Hatanaka                                   unsigned Insn,
18371928e68SAkira Hatanaka                                   uint64_t Address,
18471928e68SAkira Hatanaka                                   const void *Decoder);
18571928e68SAkira Hatanaka 
18671928e68SAkira Hatanaka namespace llvm {
18771928e68SAkira Hatanaka extern Target TheMipselTarget, TheMipsTarget, TheMips64Target,
18871928e68SAkira Hatanaka               TheMips64elTarget;
18971928e68SAkira Hatanaka }
19071928e68SAkira Hatanaka 
19171928e68SAkira Hatanaka static MCDisassembler *createMipsDisassembler(
19271928e68SAkira Hatanaka                        const Target &T,
19371928e68SAkira Hatanaka                        const MCSubtargetInfo &STI) {
1949bf2b567SAkira Hatanaka   return new MipsDisassembler(STI, T.createMCRegInfo(""), true);
19571928e68SAkira Hatanaka }
19671928e68SAkira Hatanaka 
19771928e68SAkira Hatanaka static MCDisassembler *createMipselDisassembler(
19871928e68SAkira Hatanaka                        const Target &T,
19971928e68SAkira Hatanaka                        const MCSubtargetInfo &STI) {
2009bf2b567SAkira Hatanaka   return new MipsDisassembler(STI, T.createMCRegInfo(""), false);
20171928e68SAkira Hatanaka }
20271928e68SAkira Hatanaka 
20371928e68SAkira Hatanaka static MCDisassembler *createMips64Disassembler(
20471928e68SAkira Hatanaka                        const Target &T,
20571928e68SAkira Hatanaka                        const MCSubtargetInfo &STI) {
2069bf2b567SAkira Hatanaka   return new Mips64Disassembler(STI, T.createMCRegInfo(""), true);
20771928e68SAkira Hatanaka }
20871928e68SAkira Hatanaka 
20971928e68SAkira Hatanaka static MCDisassembler *createMips64elDisassembler(
21071928e68SAkira Hatanaka                        const Target &T,
21171928e68SAkira Hatanaka                        const MCSubtargetInfo &STI) {
2129bf2b567SAkira Hatanaka   return new Mips64Disassembler(STI, T.createMCRegInfo(""), false);
21371928e68SAkira Hatanaka }
21471928e68SAkira Hatanaka 
21571928e68SAkira Hatanaka extern "C" void LLVMInitializeMipsDisassembler() {
21671928e68SAkira Hatanaka   // Register the disassembler.
21771928e68SAkira Hatanaka   TargetRegistry::RegisterMCDisassembler(TheMipsTarget,
21871928e68SAkira Hatanaka                                          createMipsDisassembler);
21971928e68SAkira Hatanaka   TargetRegistry::RegisterMCDisassembler(TheMipselTarget,
22071928e68SAkira Hatanaka                                          createMipselDisassembler);
22171928e68SAkira Hatanaka   TargetRegistry::RegisterMCDisassembler(TheMips64Target,
22271928e68SAkira Hatanaka                                          createMips64Disassembler);
22371928e68SAkira Hatanaka   TargetRegistry::RegisterMCDisassembler(TheMips64elTarget,
22471928e68SAkira Hatanaka                                          createMips64elDisassembler);
22571928e68SAkira Hatanaka }
22671928e68SAkira Hatanaka 
22771928e68SAkira Hatanaka 
22871928e68SAkira Hatanaka #include "MipsGenDisassemblerTables.inc"
22971928e68SAkira Hatanaka 
23071928e68SAkira Hatanaka   /// readInstruction - read four bytes from the MemoryObject
23171928e68SAkira Hatanaka   /// and return 32 bit word sorted according to the given endianess
23271928e68SAkira Hatanaka static DecodeStatus readInstruction32(const MemoryObject &region,
23371928e68SAkira Hatanaka                                       uint64_t address,
23471928e68SAkira Hatanaka                                       uint64_t &size,
23571928e68SAkira Hatanaka                                       uint32_t &insn,
23671928e68SAkira Hatanaka                                       bool isBigEndian) {
23771928e68SAkira Hatanaka   uint8_t Bytes[4];
23871928e68SAkira Hatanaka 
23971928e68SAkira Hatanaka   // We want to read exactly 4 Bytes of data.
24071928e68SAkira Hatanaka   if (region.readBytes(address, 4, (uint8_t*)Bytes, NULL) == -1) {
24171928e68SAkira Hatanaka     size = 0;
24271928e68SAkira Hatanaka     return MCDisassembler::Fail;
24371928e68SAkira Hatanaka   }
24471928e68SAkira Hatanaka 
24571928e68SAkira Hatanaka   if (isBigEndian) {
24671928e68SAkira Hatanaka     // Encoded as a big-endian 32-bit word in the stream.
24771928e68SAkira Hatanaka     insn = (Bytes[3] <<  0) |
24871928e68SAkira Hatanaka            (Bytes[2] <<  8) |
24971928e68SAkira Hatanaka            (Bytes[1] << 16) |
25071928e68SAkira Hatanaka            (Bytes[0] << 24);
25171928e68SAkira Hatanaka   }
25271928e68SAkira Hatanaka   else {
25371928e68SAkira Hatanaka     // Encoded as a small-endian 32-bit word in the stream.
25471928e68SAkira Hatanaka     insn = (Bytes[0] <<  0) |
25571928e68SAkira Hatanaka            (Bytes[1] <<  8) |
25671928e68SAkira Hatanaka            (Bytes[2] << 16) |
25771928e68SAkira Hatanaka            (Bytes[3] << 24);
25871928e68SAkira Hatanaka   }
25971928e68SAkira Hatanaka 
26071928e68SAkira Hatanaka   return MCDisassembler::Success;
26171928e68SAkira Hatanaka }
26271928e68SAkira Hatanaka 
26371928e68SAkira Hatanaka DecodeStatus
26471928e68SAkira Hatanaka MipsDisassembler::getInstruction(MCInst &instr,
26571928e68SAkira Hatanaka                                  uint64_t &Size,
26671928e68SAkira Hatanaka                                  const MemoryObject &Region,
26771928e68SAkira Hatanaka                                  uint64_t Address,
26871928e68SAkira Hatanaka                                  raw_ostream &vStream,
26971928e68SAkira Hatanaka                                  raw_ostream &cStream) const {
27071928e68SAkira Hatanaka   uint32_t Insn;
27171928e68SAkira Hatanaka 
27271928e68SAkira Hatanaka   DecodeStatus Result = readInstruction32(Region, Address, Size,
27371928e68SAkira Hatanaka                                           Insn, isBigEndian);
27471928e68SAkira Hatanaka   if (Result == MCDisassembler::Fail)
27571928e68SAkira Hatanaka     return MCDisassembler::Fail;
27671928e68SAkira Hatanaka 
27771928e68SAkira Hatanaka   // Calling the auto-generated decoder function.
278*ecaef49fSJim Grosbach   Result = decodeInstruction(DecoderTableMips32, instr, Insn, Address,
279*ecaef49fSJim Grosbach                              this, STI);
28071928e68SAkira Hatanaka   if (Result != MCDisassembler::Fail) {
28171928e68SAkira Hatanaka     Size = 4;
28271928e68SAkira Hatanaka     return Result;
28371928e68SAkira Hatanaka   }
28471928e68SAkira Hatanaka 
28571928e68SAkira Hatanaka   return MCDisassembler::Fail;
28671928e68SAkira Hatanaka }
28771928e68SAkira Hatanaka 
28871928e68SAkira Hatanaka DecodeStatus
28971928e68SAkira Hatanaka Mips64Disassembler::getInstruction(MCInst &instr,
29071928e68SAkira Hatanaka                                    uint64_t &Size,
29171928e68SAkira Hatanaka                                    const MemoryObject &Region,
29271928e68SAkira Hatanaka                                    uint64_t Address,
29371928e68SAkira Hatanaka                                    raw_ostream &vStream,
29471928e68SAkira Hatanaka                                    raw_ostream &cStream) const {
29571928e68SAkira Hatanaka   uint32_t Insn;
29671928e68SAkira Hatanaka 
29771928e68SAkira Hatanaka   DecodeStatus Result = readInstruction32(Region, Address, Size,
29871928e68SAkira Hatanaka                                           Insn, isBigEndian);
29971928e68SAkira Hatanaka   if (Result == MCDisassembler::Fail)
30071928e68SAkira Hatanaka     return MCDisassembler::Fail;
30171928e68SAkira Hatanaka 
30271928e68SAkira Hatanaka   // Calling the auto-generated decoder function.
303*ecaef49fSJim Grosbach   Result = decodeInstruction(DecoderTableMips6432, instr, Insn, Address,
304*ecaef49fSJim Grosbach                              this, STI);
30571928e68SAkira Hatanaka   if (Result != MCDisassembler::Fail) {
30671928e68SAkira Hatanaka     Size = 4;
30771928e68SAkira Hatanaka     return Result;
30871928e68SAkira Hatanaka   }
30971928e68SAkira Hatanaka   // If we fail to decode in Mips64 decoder space we can try in Mips32
310*ecaef49fSJim Grosbach   Result = decodeInstruction(DecoderTableMips32, instr, Insn, Address,
311*ecaef49fSJim Grosbach                              this, STI);
31271928e68SAkira Hatanaka   if (Result != MCDisassembler::Fail) {
31371928e68SAkira Hatanaka     Size = 4;
31471928e68SAkira Hatanaka     return Result;
31571928e68SAkira Hatanaka   }
31671928e68SAkira Hatanaka 
31771928e68SAkira Hatanaka   return MCDisassembler::Fail;
31871928e68SAkira Hatanaka }
31971928e68SAkira Hatanaka 
3209bf2b567SAkira Hatanaka static unsigned getReg(const void *D, unsigned RC, unsigned RegNo) {
3219bf2b567SAkira Hatanaka   const MipsDisassemblerBase *Dis = static_cast<const MipsDisassemblerBase*>(D);
3229bf2b567SAkira Hatanaka   return *(Dis->getRegInfo()->getRegClass(RC).begin() + RegNo);
3239bf2b567SAkira Hatanaka }
3249bf2b567SAkira Hatanaka 
32571928e68SAkira Hatanaka static DecodeStatus DecodeCPU64RegsRegisterClass(MCInst &Inst,
32671928e68SAkira Hatanaka                                                  unsigned RegNo,
32771928e68SAkira Hatanaka                                                  uint64_t Address,
32871928e68SAkira Hatanaka                                                  const void *Decoder) {
32971928e68SAkira Hatanaka 
33071928e68SAkira Hatanaka   if (RegNo > 31)
33171928e68SAkira Hatanaka     return MCDisassembler::Fail;
33271928e68SAkira Hatanaka 
3339bf2b567SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::CPU64RegsRegClassID, RegNo);
3349bf2b567SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
33571928e68SAkira Hatanaka   return MCDisassembler::Success;
33671928e68SAkira Hatanaka }
33771928e68SAkira Hatanaka 
33871928e68SAkira Hatanaka static DecodeStatus DecodeCPURegsRegisterClass(MCInst &Inst,
33971928e68SAkira Hatanaka                                                unsigned RegNo,
34071928e68SAkira Hatanaka                                                uint64_t Address,
34171928e68SAkira Hatanaka                                                const void *Decoder) {
34271928e68SAkira Hatanaka   if (RegNo > 31)
34371928e68SAkira Hatanaka     return MCDisassembler::Fail;
3449bf2b567SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::CPURegsRegClassID, RegNo);
3459bf2b567SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
34671928e68SAkira Hatanaka   return MCDisassembler::Success;
34771928e68SAkira Hatanaka }
34871928e68SAkira Hatanaka 
34971928e68SAkira Hatanaka static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
35071928e68SAkira Hatanaka                                              unsigned RegNo,
35171928e68SAkira Hatanaka                                              uint64_t Address,
35271928e68SAkira Hatanaka                                              const void *Decoder) {
35371928e68SAkira Hatanaka   if (RegNo > 31)
35471928e68SAkira Hatanaka     return MCDisassembler::Fail;
35571928e68SAkira Hatanaka 
3569bf2b567SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::FGR64RegClassID, RegNo);
3579bf2b567SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
35871928e68SAkira Hatanaka   return MCDisassembler::Success;
35971928e68SAkira Hatanaka }
36071928e68SAkira Hatanaka 
36171928e68SAkira Hatanaka static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
36271928e68SAkira Hatanaka                                              unsigned RegNo,
36371928e68SAkira Hatanaka                                              uint64_t Address,
36471928e68SAkira Hatanaka                                              const void *Decoder) {
36571928e68SAkira Hatanaka   if (RegNo > 31)
36671928e68SAkira Hatanaka     return MCDisassembler::Fail;
36771928e68SAkira Hatanaka 
3689bf2b567SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::FGR32RegClassID, RegNo);
3699bf2b567SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
37071928e68SAkira Hatanaka   return MCDisassembler::Success;
37171928e68SAkira Hatanaka }
37271928e68SAkira Hatanaka 
37371928e68SAkira Hatanaka static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
37471928e68SAkira Hatanaka                                            unsigned RegNo,
37571928e68SAkira Hatanaka                                            uint64_t Address,
37671928e68SAkira Hatanaka                                            const void *Decoder) {
37771928e68SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(RegNo));
37871928e68SAkira Hatanaka   return MCDisassembler::Success;
37971928e68SAkira Hatanaka }
38071928e68SAkira Hatanaka 
38171928e68SAkira Hatanaka static DecodeStatus DecodeMem(MCInst &Inst,
38271928e68SAkira Hatanaka                               unsigned Insn,
38371928e68SAkira Hatanaka                               uint64_t Address,
38471928e68SAkira Hatanaka                               const void *Decoder) {
38571928e68SAkira Hatanaka   int Offset = SignExtend32<16>(Insn & 0xffff);
386*ecaef49fSJim Grosbach   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
387*ecaef49fSJim Grosbach   unsigned Base = fieldFromInstruction(Insn, 21, 5);
3889bf2b567SAkira Hatanaka 
3899bf2b567SAkira Hatanaka   Reg = getReg(Decoder, Mips::CPURegsRegClassID, Reg);
3909bf2b567SAkira Hatanaka   Base = getReg(Decoder, Mips::CPURegsRegClassID, Base);
39171928e68SAkira Hatanaka 
39271928e68SAkira Hatanaka   if(Inst.getOpcode() == Mips::SC){
3939bf2b567SAkira Hatanaka     Inst.addOperand(MCOperand::CreateReg(Reg));
39471928e68SAkira Hatanaka   }
39571928e68SAkira Hatanaka 
3969bf2b567SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
3979bf2b567SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Base));
39871928e68SAkira Hatanaka   Inst.addOperand(MCOperand::CreateImm(Offset));
39971928e68SAkira Hatanaka 
40071928e68SAkira Hatanaka   return MCDisassembler::Success;
40171928e68SAkira Hatanaka }
40271928e68SAkira Hatanaka 
40371928e68SAkira Hatanaka static DecodeStatus DecodeFMem(MCInst &Inst,
40471928e68SAkira Hatanaka                                unsigned Insn,
40571928e68SAkira Hatanaka                                uint64_t Address,
40671928e68SAkira Hatanaka                                const void *Decoder) {
40771928e68SAkira Hatanaka   int Offset = SignExtend32<16>(Insn & 0xffff);
408*ecaef49fSJim Grosbach   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
409*ecaef49fSJim Grosbach   unsigned Base = fieldFromInstruction(Insn, 21, 5);
41071928e68SAkira Hatanaka 
4119bf2b567SAkira Hatanaka   Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg);
4129bf2b567SAkira Hatanaka   Base = getReg(Decoder, Mips::CPURegsRegClassID, Base);
4139bf2b567SAkira Hatanaka 
4149bf2b567SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
4159bf2b567SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Base));
41671928e68SAkira Hatanaka   Inst.addOperand(MCOperand::CreateImm(Offset));
41771928e68SAkira Hatanaka 
41871928e68SAkira Hatanaka   return MCDisassembler::Success;
41971928e68SAkira Hatanaka }
42071928e68SAkira Hatanaka 
42171928e68SAkira Hatanaka 
42271928e68SAkira Hatanaka static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
42371928e68SAkira Hatanaka                                               unsigned RegNo,
42471928e68SAkira Hatanaka                                               uint64_t Address,
42571928e68SAkira Hatanaka                                               const void *Decoder) {
42671928e68SAkira Hatanaka   // Currently only hardware register 29 is supported.
42771928e68SAkira Hatanaka   if (RegNo != 29)
42871928e68SAkira Hatanaka     return  MCDisassembler::Fail;
42971928e68SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Mips::HWR29));
43071928e68SAkira Hatanaka   return MCDisassembler::Success;
43171928e68SAkira Hatanaka }
43271928e68SAkira Hatanaka 
43371928e68SAkira Hatanaka static DecodeStatus DecodeCondCode(MCInst &Inst,
43471928e68SAkira Hatanaka                                    unsigned Insn,
43571928e68SAkira Hatanaka                                    uint64_t Address,
43671928e68SAkira Hatanaka                                    const void *Decoder) {
43771928e68SAkira Hatanaka   int CondCode = Insn & 0xf;
43871928e68SAkira Hatanaka   Inst.addOperand(MCOperand::CreateImm(CondCode));
43971928e68SAkira Hatanaka   return MCDisassembler::Success;
44071928e68SAkira Hatanaka }
44171928e68SAkira Hatanaka 
44271928e68SAkira Hatanaka static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
44371928e68SAkira Hatanaka                                               unsigned RegNo,
44471928e68SAkira Hatanaka                                               uint64_t Address,
44571928e68SAkira Hatanaka                                               const void *Decoder) {
4469bf2b567SAkira Hatanaka   if (RegNo > 30 || RegNo %2)
44771928e68SAkira Hatanaka     return MCDisassembler::Fail;
44871928e68SAkira Hatanaka 
4499bf2b567SAkira Hatanaka   ;
4509bf2b567SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::AFGR64RegClassID, RegNo /2);
4519bf2b567SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
45271928e68SAkira Hatanaka   return MCDisassembler::Success;
45371928e68SAkira Hatanaka }
45471928e68SAkira Hatanaka 
45571928e68SAkira Hatanaka static DecodeStatus DecodeHWRegs64RegisterClass(MCInst &Inst,
45671928e68SAkira Hatanaka                                                 unsigned RegNo,
45771928e68SAkira Hatanaka                                                 uint64_t Address,
45871928e68SAkira Hatanaka                                                 const void *Decoder) {
45971928e68SAkira Hatanaka   //Currently only hardware register 29 is supported
46071928e68SAkira Hatanaka   if (RegNo != 29)
46171928e68SAkira Hatanaka     return  MCDisassembler::Fail;
4629bf2b567SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Mips::HWR29_64));
46371928e68SAkira Hatanaka   return MCDisassembler::Success;
46471928e68SAkira Hatanaka }
46571928e68SAkira Hatanaka 
46671928e68SAkira Hatanaka static DecodeStatus DecodeBranchTarget(MCInst &Inst,
46771928e68SAkira Hatanaka                                        unsigned Offset,
46871928e68SAkira Hatanaka                                        uint64_t Address,
46971928e68SAkira Hatanaka                                        const void *Decoder) {
47071928e68SAkira Hatanaka   unsigned BranchOffset = Offset & 0xffff;
47171928e68SAkira Hatanaka   BranchOffset = SignExtend32<18>(BranchOffset << 2) + 4;
47271928e68SAkira Hatanaka   Inst.addOperand(MCOperand::CreateImm(BranchOffset));
47371928e68SAkira Hatanaka   return MCDisassembler::Success;
47471928e68SAkira Hatanaka }
47571928e68SAkira Hatanaka 
47671928e68SAkira Hatanaka static DecodeStatus DecodeBC1(MCInst &Inst,
47771928e68SAkira Hatanaka                               unsigned Insn,
47871928e68SAkira Hatanaka                               uint64_t Address,
47971928e68SAkira Hatanaka                               const void *Decoder) {
48071928e68SAkira Hatanaka   unsigned BranchOffset = Insn & 0xffff;
48171928e68SAkira Hatanaka   BranchOffset = SignExtend32<18>(BranchOffset << 2) + 4;
48271928e68SAkira Hatanaka   Inst.addOperand(MCOperand::CreateImm(BranchOffset));
48371928e68SAkira Hatanaka   return MCDisassembler::Success;
48471928e68SAkira Hatanaka }
48571928e68SAkira Hatanaka 
48671928e68SAkira Hatanaka static DecodeStatus DecodeJumpTarget(MCInst &Inst,
48771928e68SAkira Hatanaka                                      unsigned Insn,
48871928e68SAkira Hatanaka                                      uint64_t Address,
48971928e68SAkira Hatanaka                                      const void *Decoder) {
49071928e68SAkira Hatanaka 
491*ecaef49fSJim Grosbach   unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 2;
49271928e68SAkira Hatanaka   Inst.addOperand(MCOperand::CreateImm(JumpOffset));
49371928e68SAkira Hatanaka   return MCDisassembler::Success;
49471928e68SAkira Hatanaka }
49571928e68SAkira Hatanaka 
49671928e68SAkira Hatanaka 
49771928e68SAkira Hatanaka static DecodeStatus DecodeSimm16(MCInst &Inst,
49871928e68SAkira Hatanaka                                  unsigned Insn,
49971928e68SAkira Hatanaka                                  uint64_t Address,
50071928e68SAkira Hatanaka                                  const void *Decoder) {
50171928e68SAkira Hatanaka   Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Insn)));
50271928e68SAkira Hatanaka   return MCDisassembler::Success;
50371928e68SAkira Hatanaka }
50471928e68SAkira Hatanaka 
50571928e68SAkira Hatanaka static DecodeStatus DecodeInsSize(MCInst &Inst,
50671928e68SAkira Hatanaka                                   unsigned Insn,
50771928e68SAkira Hatanaka                                   uint64_t Address,
50871928e68SAkira Hatanaka                                   const void *Decoder) {
50971928e68SAkira Hatanaka   // First we need to grab the pos(lsb) from MCInst.
51071928e68SAkira Hatanaka   int Pos = Inst.getOperand(2).getImm();
51171928e68SAkira Hatanaka   int Size = (int) Insn - Pos + 1;
51271928e68SAkira Hatanaka   Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size)));
51371928e68SAkira Hatanaka   return MCDisassembler::Success;
51471928e68SAkira Hatanaka }
51571928e68SAkira Hatanaka 
51671928e68SAkira Hatanaka static DecodeStatus DecodeExtSize(MCInst &Inst,
51771928e68SAkira Hatanaka                                   unsigned Insn,
51871928e68SAkira Hatanaka                                   uint64_t Address,
51971928e68SAkira Hatanaka                                   const void *Decoder) {
52071928e68SAkira Hatanaka   int Size = (int) Insn  + 1;
52171928e68SAkira Hatanaka   Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size)));
52271928e68SAkira Hatanaka   return MCDisassembler::Success;
52371928e68SAkira Hatanaka }
524