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"
159bf2b567SAkira Hatanaka #include "MipsRegisterInfo.h"
16ed0881b2SChandler Carruth #include "MipsSubtarget.h"
1771928e68SAkira Hatanaka #include "llvm/MC/MCDisassembler.h"
18ecaef49fSJim Grosbach #include "llvm/MC/MCFixedLenDisassembler.h"
19ed0881b2SChandler Carruth #include "llvm/MC/MCInst.h"
20ed0881b2SChandler Carruth #include "llvm/MC/MCSubtargetInfo.h"
21ed0881b2SChandler Carruth #include "llvm/Support/MathExtras.h"
2271928e68SAkira Hatanaka #include "llvm/Support/MemoryObject.h"
2371928e68SAkira Hatanaka #include "llvm/Support/TargetRegistry.h"
2471928e68SAkira Hatanaka 
2571928e68SAkira Hatanaka using namespace llvm;
2671928e68SAkira Hatanaka 
2771928e68SAkira Hatanaka typedef MCDisassembler::DecodeStatus DecodeStatus;
2871928e68SAkira Hatanaka 
29cb3e98cfSBenjamin Kramer namespace {
30cb3e98cfSBenjamin Kramer 
319bf2b567SAkira Hatanaka /// MipsDisassemblerBase - a disasembler class for Mips.
329bf2b567SAkira Hatanaka class MipsDisassemblerBase : public MCDisassembler {
3371928e68SAkira Hatanaka public:
3471928e68SAkira Hatanaka   /// Constructor     - Initializes the disassembler.
3571928e68SAkira Hatanaka   ///
369bf2b567SAkira Hatanaka   MipsDisassemblerBase(const MCSubtargetInfo &STI, const MCRegisterInfo *Info,
379bf2b567SAkira Hatanaka                        bool bigEndian) :
389bf2b567SAkira Hatanaka     MCDisassembler(STI), RegInfo(Info), isBigEndian(bigEndian) {}
3971928e68SAkira Hatanaka 
409bf2b567SAkira Hatanaka   virtual ~MipsDisassemblerBase() {}
419bf2b567SAkira Hatanaka 
429bf2b567SAkira Hatanaka   const MCRegisterInfo *getRegInfo() const { return RegInfo; }
439bf2b567SAkira Hatanaka 
449bf2b567SAkira Hatanaka private:
459bf2b567SAkira Hatanaka   const MCRegisterInfo *RegInfo;
469bf2b567SAkira Hatanaka protected:
479bf2b567SAkira Hatanaka   bool isBigEndian;
489bf2b567SAkira Hatanaka };
499bf2b567SAkira Hatanaka 
509bf2b567SAkira Hatanaka /// MipsDisassembler - a disasembler class for Mips32.
519bf2b567SAkira Hatanaka class MipsDisassembler : public MipsDisassemblerBase {
529bf2b567SAkira Hatanaka public:
539bf2b567SAkira Hatanaka   /// Constructor     - Initializes the disassembler.
549bf2b567SAkira Hatanaka   ///
559bf2b567SAkira Hatanaka   MipsDisassembler(const MCSubtargetInfo &STI, const MCRegisterInfo *Info,
569bf2b567SAkira Hatanaka                    bool bigEndian) :
579bf2b567SAkira Hatanaka     MipsDisassemblerBase(STI, Info, bigEndian) {}
5871928e68SAkira Hatanaka 
5971928e68SAkira Hatanaka   /// getInstruction - See MCDisassembler.
609bf2b567SAkira Hatanaka   virtual DecodeStatus getInstruction(MCInst &instr,
6171928e68SAkira Hatanaka                                       uint64_t &size,
6271928e68SAkira Hatanaka                                       const MemoryObject &region,
6371928e68SAkira Hatanaka                                       uint64_t address,
6471928e68SAkira Hatanaka                                       raw_ostream &vStream,
6571928e68SAkira Hatanaka                                       raw_ostream &cStream) const;
6671928e68SAkira Hatanaka };
6771928e68SAkira Hatanaka 
6871928e68SAkira Hatanaka 
6971928e68SAkira Hatanaka /// Mips64Disassembler - a disasembler class for Mips64.
709bf2b567SAkira Hatanaka class Mips64Disassembler : public MipsDisassemblerBase {
7171928e68SAkira Hatanaka public:
7271928e68SAkira Hatanaka   /// Constructor     - Initializes the disassembler.
7371928e68SAkira Hatanaka   ///
749bf2b567SAkira Hatanaka   Mips64Disassembler(const MCSubtargetInfo &STI, const MCRegisterInfo *Info,
759bf2b567SAkira Hatanaka                      bool bigEndian) :
769bf2b567SAkira Hatanaka     MipsDisassemblerBase(STI, Info, bigEndian) {}
7771928e68SAkira Hatanaka 
7871928e68SAkira Hatanaka   /// getInstruction - See MCDisassembler.
799bf2b567SAkira Hatanaka   virtual DecodeStatus getInstruction(MCInst &instr,
8071928e68SAkira Hatanaka                                       uint64_t &size,
8171928e68SAkira Hatanaka                                       const MemoryObject &region,
8271928e68SAkira Hatanaka                                       uint64_t address,
8371928e68SAkira Hatanaka                                       raw_ostream &vStream,
8471928e68SAkira Hatanaka                                       raw_ostream &cStream) const;
8571928e68SAkira Hatanaka };
8671928e68SAkira Hatanaka 
87cb3e98cfSBenjamin Kramer } // end anonymous namespace
88cb3e98cfSBenjamin Kramer 
8971928e68SAkira Hatanaka // Forward declare these because the autogenerated code will reference them.
9071928e68SAkira Hatanaka // Definitions are further down.
9171928e68SAkira Hatanaka static DecodeStatus DecodeCPU64RegsRegisterClass(MCInst &Inst,
9271928e68SAkira Hatanaka                                                  unsigned RegNo,
9371928e68SAkira Hatanaka                                                  uint64_t Address,
9471928e68SAkira Hatanaka                                                  const void *Decoder);
9571928e68SAkira Hatanaka 
96*ec8a5490SReed Kotler static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst,
97*ec8a5490SReed Kotler                                                  unsigned RegNo,
98*ec8a5490SReed Kotler                                                  uint64_t Address,
99*ec8a5490SReed Kotler                                                  const void *Decoder);
100*ec8a5490SReed Kotler 
10171928e68SAkira Hatanaka static DecodeStatus DecodeCPURegsRegisterClass(MCInst &Inst,
10271928e68SAkira Hatanaka                                                unsigned RegNo,
10371928e68SAkira Hatanaka                                                uint64_t Address,
10471928e68SAkira Hatanaka                                                const void *Decoder);
10571928e68SAkira Hatanaka 
106ecabd1a5SAkira Hatanaka static DecodeStatus DecodeDSPRegsRegisterClass(MCInst &Inst,
107ecabd1a5SAkira Hatanaka                                                unsigned RegNo,
108ecabd1a5SAkira Hatanaka                                                uint64_t Address,
109ecabd1a5SAkira Hatanaka                                                const void *Decoder);
110ecabd1a5SAkira 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 
1362a74a87bSJack Carter static DecodeStatus DecodeHWRegs64RegisterClass(MCInst &Inst,
1372a74a87bSJack Carter                                                 unsigned Insn,
1382a74a87bSJack Carter                                                 uint64_t Address,
1392a74a87bSJack Carter                                                 const void *Decoder);
1402a74a87bSJack Carter 
141ecabd1a5SAkira Hatanaka static DecodeStatus DecodeACRegsRegisterClass(MCInst &Inst,
142ecabd1a5SAkira Hatanaka                                               unsigned RegNo,
143ecabd1a5SAkira Hatanaka                                               uint64_t Address,
144ecabd1a5SAkira Hatanaka                                               const void *Decoder);
145ecabd1a5SAkira Hatanaka 
14671928e68SAkira Hatanaka static DecodeStatus DecodeBranchTarget(MCInst &Inst,
14771928e68SAkira Hatanaka                                        unsigned Offset,
14871928e68SAkira Hatanaka                                        uint64_t Address,
14971928e68SAkira Hatanaka                                        const void *Decoder);
15071928e68SAkira Hatanaka 
15171928e68SAkira Hatanaka static DecodeStatus DecodeBC1(MCInst &Inst,
15271928e68SAkira Hatanaka                               unsigned Insn,
15371928e68SAkira Hatanaka                               uint64_t Address,
15471928e68SAkira Hatanaka                               const void *Decoder);
15571928e68SAkira Hatanaka 
15671928e68SAkira Hatanaka 
15771928e68SAkira Hatanaka static DecodeStatus DecodeJumpTarget(MCInst &Inst,
15871928e68SAkira Hatanaka                                      unsigned Insn,
15971928e68SAkira Hatanaka                                      uint64_t Address,
16071928e68SAkira Hatanaka                                      const void *Decoder);
16171928e68SAkira Hatanaka 
16271928e68SAkira Hatanaka static DecodeStatus DecodeMem(MCInst &Inst,
16371928e68SAkira Hatanaka                               unsigned Insn,
16471928e68SAkira Hatanaka                               uint64_t Address,
16571928e68SAkira Hatanaka                               const void *Decoder);
16671928e68SAkira Hatanaka 
16771928e68SAkira Hatanaka static DecodeStatus DecodeFMem(MCInst &Inst, unsigned Insn,
16871928e68SAkira Hatanaka                                uint64_t Address,
16971928e68SAkira Hatanaka                                const void *Decoder);
17071928e68SAkira Hatanaka 
17171928e68SAkira Hatanaka static DecodeStatus DecodeSimm16(MCInst &Inst,
17271928e68SAkira Hatanaka                                  unsigned Insn,
17371928e68SAkira Hatanaka                                  uint64_t Address,
17471928e68SAkira Hatanaka                                  const void *Decoder);
17571928e68SAkira Hatanaka 
17671928e68SAkira Hatanaka static DecodeStatus DecodeCondCode(MCInst &Inst,
17771928e68SAkira Hatanaka                                    unsigned Insn,
17871928e68SAkira Hatanaka                                    uint64_t Address,
17971928e68SAkira Hatanaka                                    const void *Decoder);
18071928e68SAkira Hatanaka 
18171928e68SAkira Hatanaka static DecodeStatus DecodeInsSize(MCInst &Inst,
18271928e68SAkira Hatanaka                                   unsigned Insn,
18371928e68SAkira Hatanaka                                   uint64_t Address,
18471928e68SAkira Hatanaka                                   const void *Decoder);
18571928e68SAkira Hatanaka 
18671928e68SAkira Hatanaka static DecodeStatus DecodeExtSize(MCInst &Inst,
18771928e68SAkira Hatanaka                                   unsigned Insn,
18871928e68SAkira Hatanaka                                   uint64_t Address,
18971928e68SAkira Hatanaka                                   const void *Decoder);
19071928e68SAkira Hatanaka 
19171928e68SAkira Hatanaka namespace llvm {
19271928e68SAkira Hatanaka extern Target TheMipselTarget, TheMipsTarget, TheMips64Target,
19371928e68SAkira Hatanaka               TheMips64elTarget;
19471928e68SAkira Hatanaka }
19571928e68SAkira Hatanaka 
19671928e68SAkira Hatanaka static MCDisassembler *createMipsDisassembler(
19771928e68SAkira Hatanaka                        const Target &T,
19871928e68SAkira Hatanaka                        const MCSubtargetInfo &STI) {
1999bf2b567SAkira Hatanaka   return new MipsDisassembler(STI, T.createMCRegInfo(""), true);
20071928e68SAkira Hatanaka }
20171928e68SAkira Hatanaka 
20271928e68SAkira Hatanaka static MCDisassembler *createMipselDisassembler(
20371928e68SAkira Hatanaka                        const Target &T,
20471928e68SAkira Hatanaka                        const MCSubtargetInfo &STI) {
2059bf2b567SAkira Hatanaka   return new MipsDisassembler(STI, T.createMCRegInfo(""), false);
20671928e68SAkira Hatanaka }
20771928e68SAkira Hatanaka 
20871928e68SAkira Hatanaka static MCDisassembler *createMips64Disassembler(
20971928e68SAkira Hatanaka                        const Target &T,
21071928e68SAkira Hatanaka                        const MCSubtargetInfo &STI) {
2119bf2b567SAkira Hatanaka   return new Mips64Disassembler(STI, T.createMCRegInfo(""), true);
21271928e68SAkira Hatanaka }
21371928e68SAkira Hatanaka 
21471928e68SAkira Hatanaka static MCDisassembler *createMips64elDisassembler(
21571928e68SAkira Hatanaka                        const Target &T,
21671928e68SAkira Hatanaka                        const MCSubtargetInfo &STI) {
2179bf2b567SAkira Hatanaka   return new Mips64Disassembler(STI, T.createMCRegInfo(""), false);
21871928e68SAkira Hatanaka }
21971928e68SAkira Hatanaka 
22071928e68SAkira Hatanaka extern "C" void LLVMInitializeMipsDisassembler() {
22171928e68SAkira Hatanaka   // Register the disassembler.
22271928e68SAkira Hatanaka   TargetRegistry::RegisterMCDisassembler(TheMipsTarget,
22371928e68SAkira Hatanaka                                          createMipsDisassembler);
22471928e68SAkira Hatanaka   TargetRegistry::RegisterMCDisassembler(TheMipselTarget,
22571928e68SAkira Hatanaka                                          createMipselDisassembler);
22671928e68SAkira Hatanaka   TargetRegistry::RegisterMCDisassembler(TheMips64Target,
22771928e68SAkira Hatanaka                                          createMips64Disassembler);
22871928e68SAkira Hatanaka   TargetRegistry::RegisterMCDisassembler(TheMips64elTarget,
22971928e68SAkira Hatanaka                                          createMips64elDisassembler);
23071928e68SAkira Hatanaka }
23171928e68SAkira Hatanaka 
23271928e68SAkira Hatanaka 
23371928e68SAkira Hatanaka #include "MipsGenDisassemblerTables.inc"
23471928e68SAkira Hatanaka 
23571928e68SAkira Hatanaka   /// readInstruction - read four bytes from the MemoryObject
23671928e68SAkira Hatanaka   /// and return 32 bit word sorted according to the given endianess
23771928e68SAkira Hatanaka static DecodeStatus readInstruction32(const MemoryObject &region,
23871928e68SAkira Hatanaka                                       uint64_t address,
23971928e68SAkira Hatanaka                                       uint64_t &size,
24071928e68SAkira Hatanaka                                       uint32_t &insn,
24171928e68SAkira Hatanaka                                       bool isBigEndian) {
24271928e68SAkira Hatanaka   uint8_t Bytes[4];
24371928e68SAkira Hatanaka 
24471928e68SAkira Hatanaka   // We want to read exactly 4 Bytes of data.
24571928e68SAkira Hatanaka   if (region.readBytes(address, 4, (uint8_t*)Bytes, NULL) == -1) {
24671928e68SAkira Hatanaka     size = 0;
24771928e68SAkira Hatanaka     return MCDisassembler::Fail;
24871928e68SAkira Hatanaka   }
24971928e68SAkira Hatanaka 
25071928e68SAkira Hatanaka   if (isBigEndian) {
25171928e68SAkira Hatanaka     // Encoded as a big-endian 32-bit word in the stream.
25271928e68SAkira Hatanaka     insn = (Bytes[3] <<  0) |
25371928e68SAkira Hatanaka            (Bytes[2] <<  8) |
25471928e68SAkira Hatanaka            (Bytes[1] << 16) |
25571928e68SAkira Hatanaka            (Bytes[0] << 24);
25671928e68SAkira Hatanaka   }
25771928e68SAkira Hatanaka   else {
25871928e68SAkira Hatanaka     // Encoded as a small-endian 32-bit word in the stream.
25971928e68SAkira Hatanaka     insn = (Bytes[0] <<  0) |
26071928e68SAkira Hatanaka            (Bytes[1] <<  8) |
26171928e68SAkira Hatanaka            (Bytes[2] << 16) |
26271928e68SAkira Hatanaka            (Bytes[3] << 24);
26371928e68SAkira Hatanaka   }
26471928e68SAkira Hatanaka 
26571928e68SAkira Hatanaka   return MCDisassembler::Success;
26671928e68SAkira Hatanaka }
26771928e68SAkira Hatanaka 
26871928e68SAkira Hatanaka DecodeStatus
26971928e68SAkira Hatanaka MipsDisassembler::getInstruction(MCInst &instr,
27071928e68SAkira Hatanaka                                  uint64_t &Size,
27171928e68SAkira Hatanaka                                  const MemoryObject &Region,
27271928e68SAkira Hatanaka                                  uint64_t Address,
27371928e68SAkira Hatanaka                                  raw_ostream &vStream,
27471928e68SAkira Hatanaka                                  raw_ostream &cStream) const {
27571928e68SAkira Hatanaka   uint32_t Insn;
27671928e68SAkira Hatanaka 
27771928e68SAkira Hatanaka   DecodeStatus Result = readInstruction32(Region, Address, Size,
27871928e68SAkira Hatanaka                                           Insn, isBigEndian);
27971928e68SAkira Hatanaka   if (Result == MCDisassembler::Fail)
28071928e68SAkira Hatanaka     return MCDisassembler::Fail;
28171928e68SAkira Hatanaka 
28271928e68SAkira Hatanaka   // Calling the auto-generated decoder function.
283ecaef49fSJim Grosbach   Result = decodeInstruction(DecoderTableMips32, instr, Insn, Address,
284ecaef49fSJim Grosbach                              this, STI);
28571928e68SAkira Hatanaka   if (Result != MCDisassembler::Fail) {
28671928e68SAkira Hatanaka     Size = 4;
28771928e68SAkira Hatanaka     return Result;
28871928e68SAkira Hatanaka   }
28971928e68SAkira Hatanaka 
29071928e68SAkira Hatanaka   return MCDisassembler::Fail;
29171928e68SAkira Hatanaka }
29271928e68SAkira Hatanaka 
29371928e68SAkira Hatanaka DecodeStatus
29471928e68SAkira Hatanaka Mips64Disassembler::getInstruction(MCInst &instr,
29571928e68SAkira Hatanaka                                    uint64_t &Size,
29671928e68SAkira Hatanaka                                    const MemoryObject &Region,
29771928e68SAkira Hatanaka                                    uint64_t Address,
29871928e68SAkira Hatanaka                                    raw_ostream &vStream,
29971928e68SAkira Hatanaka                                    raw_ostream &cStream) const {
30071928e68SAkira Hatanaka   uint32_t Insn;
30171928e68SAkira Hatanaka 
30271928e68SAkira Hatanaka   DecodeStatus Result = readInstruction32(Region, Address, Size,
30371928e68SAkira Hatanaka                                           Insn, isBigEndian);
30471928e68SAkira Hatanaka   if (Result == MCDisassembler::Fail)
30571928e68SAkira Hatanaka     return MCDisassembler::Fail;
30671928e68SAkira Hatanaka 
30771928e68SAkira Hatanaka   // Calling the auto-generated decoder function.
308ecaef49fSJim Grosbach   Result = decodeInstruction(DecoderTableMips6432, instr, Insn, Address,
309ecaef49fSJim Grosbach                              this, STI);
31071928e68SAkira Hatanaka   if (Result != MCDisassembler::Fail) {
31171928e68SAkira Hatanaka     Size = 4;
31271928e68SAkira Hatanaka     return Result;
31371928e68SAkira Hatanaka   }
31471928e68SAkira Hatanaka   // If we fail to decode in Mips64 decoder space we can try in Mips32
315ecaef49fSJim Grosbach   Result = decodeInstruction(DecoderTableMips32, instr, Insn, Address,
316ecaef49fSJim Grosbach                              this, STI);
31771928e68SAkira Hatanaka   if (Result != MCDisassembler::Fail) {
31871928e68SAkira Hatanaka     Size = 4;
31971928e68SAkira Hatanaka     return Result;
32071928e68SAkira Hatanaka   }
32171928e68SAkira Hatanaka 
32271928e68SAkira Hatanaka   return MCDisassembler::Fail;
32371928e68SAkira Hatanaka }
32471928e68SAkira Hatanaka 
3259bf2b567SAkira Hatanaka static unsigned getReg(const void *D, unsigned RC, unsigned RegNo) {
3269bf2b567SAkira Hatanaka   const MipsDisassemblerBase *Dis = static_cast<const MipsDisassemblerBase*>(D);
3279bf2b567SAkira Hatanaka   return *(Dis->getRegInfo()->getRegClass(RC).begin() + RegNo);
3289bf2b567SAkira Hatanaka }
3299bf2b567SAkira Hatanaka 
330*ec8a5490SReed Kotler static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst,
331*ec8a5490SReed Kotler                                                  unsigned RegNo,
332*ec8a5490SReed Kotler                                                  uint64_t Address,
333*ec8a5490SReed Kotler                                                  const void *Decoder) {
334*ec8a5490SReed Kotler 
335*ec8a5490SReed Kotler   return MCDisassembler::Fail;
336*ec8a5490SReed Kotler 
337*ec8a5490SReed Kotler }
338*ec8a5490SReed Kotler 
33971928e68SAkira Hatanaka static DecodeStatus DecodeCPU64RegsRegisterClass(MCInst &Inst,
34071928e68SAkira Hatanaka                                                  unsigned RegNo,
34171928e68SAkira Hatanaka                                                  uint64_t Address,
34271928e68SAkira Hatanaka                                                  const void *Decoder) {
34371928e68SAkira Hatanaka 
34471928e68SAkira Hatanaka   if (RegNo > 31)
34571928e68SAkira Hatanaka     return MCDisassembler::Fail;
34671928e68SAkira Hatanaka 
3479bf2b567SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::CPU64RegsRegClassID, RegNo);
3489bf2b567SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
34971928e68SAkira Hatanaka   return MCDisassembler::Success;
35071928e68SAkira Hatanaka }
35171928e68SAkira Hatanaka 
35271928e68SAkira Hatanaka static DecodeStatus DecodeCPURegsRegisterClass(MCInst &Inst,
35371928e68SAkira Hatanaka                                                unsigned RegNo,
35471928e68SAkira Hatanaka                                                uint64_t Address,
35571928e68SAkira Hatanaka                                                const void *Decoder) {
35671928e68SAkira Hatanaka   if (RegNo > 31)
35771928e68SAkira Hatanaka     return MCDisassembler::Fail;
3589bf2b567SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::CPURegsRegClassID, RegNo);
3599bf2b567SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
36071928e68SAkira Hatanaka   return MCDisassembler::Success;
36171928e68SAkira Hatanaka }
36271928e68SAkira Hatanaka 
363ecabd1a5SAkira Hatanaka static DecodeStatus DecodeDSPRegsRegisterClass(MCInst &Inst,
364ecabd1a5SAkira Hatanaka                                                unsigned RegNo,
365ecabd1a5SAkira Hatanaka                                                uint64_t Address,
366ecabd1a5SAkira Hatanaka                                                const void *Decoder) {
367ecabd1a5SAkira Hatanaka   return DecodeCPURegsRegisterClass(Inst, RegNo, Address, Decoder);
368ecabd1a5SAkira Hatanaka }
369ecabd1a5SAkira Hatanaka 
37071928e68SAkira Hatanaka static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
37171928e68SAkira Hatanaka                                              unsigned RegNo,
37271928e68SAkira Hatanaka                                              uint64_t Address,
37371928e68SAkira Hatanaka                                              const void *Decoder) {
37471928e68SAkira Hatanaka   if (RegNo > 31)
37571928e68SAkira Hatanaka     return MCDisassembler::Fail;
37671928e68SAkira Hatanaka 
3779bf2b567SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::FGR64RegClassID, RegNo);
3789bf2b567SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
37971928e68SAkira Hatanaka   return MCDisassembler::Success;
38071928e68SAkira Hatanaka }
38171928e68SAkira Hatanaka 
38271928e68SAkira Hatanaka static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
38371928e68SAkira Hatanaka                                              unsigned RegNo,
38471928e68SAkira Hatanaka                                              uint64_t Address,
38571928e68SAkira Hatanaka                                              const void *Decoder) {
38671928e68SAkira Hatanaka   if (RegNo > 31)
38771928e68SAkira Hatanaka     return MCDisassembler::Fail;
38871928e68SAkira Hatanaka 
3899bf2b567SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::FGR32RegClassID, RegNo);
3909bf2b567SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
39171928e68SAkira Hatanaka   return MCDisassembler::Success;
39271928e68SAkira Hatanaka }
39371928e68SAkira Hatanaka 
39471928e68SAkira Hatanaka static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
39571928e68SAkira Hatanaka                                            unsigned RegNo,
39671928e68SAkira Hatanaka                                            uint64_t Address,
39771928e68SAkira Hatanaka                                            const void *Decoder) {
39871928e68SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(RegNo));
39971928e68SAkira Hatanaka   return MCDisassembler::Success;
40071928e68SAkira Hatanaka }
40171928e68SAkira Hatanaka 
40271928e68SAkira Hatanaka static DecodeStatus DecodeMem(MCInst &Inst,
40371928e68SAkira Hatanaka                               unsigned Insn,
40471928e68SAkira Hatanaka                               uint64_t Address,
40571928e68SAkira Hatanaka                               const void *Decoder) {
40671928e68SAkira Hatanaka   int Offset = SignExtend32<16>(Insn & 0xffff);
407ecaef49fSJim Grosbach   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
408ecaef49fSJim Grosbach   unsigned Base = fieldFromInstruction(Insn, 21, 5);
4099bf2b567SAkira Hatanaka 
4109bf2b567SAkira Hatanaka   Reg = getReg(Decoder, Mips::CPURegsRegClassID, Reg);
4119bf2b567SAkira Hatanaka   Base = getReg(Decoder, Mips::CPURegsRegClassID, Base);
41271928e68SAkira Hatanaka 
41371928e68SAkira Hatanaka   if(Inst.getOpcode() == Mips::SC){
4149bf2b567SAkira Hatanaka     Inst.addOperand(MCOperand::CreateReg(Reg));
41571928e68SAkira Hatanaka   }
41671928e68SAkira Hatanaka 
4179bf2b567SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
4189bf2b567SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Base));
41971928e68SAkira Hatanaka   Inst.addOperand(MCOperand::CreateImm(Offset));
42071928e68SAkira Hatanaka 
42171928e68SAkira Hatanaka   return MCDisassembler::Success;
42271928e68SAkira Hatanaka }
42371928e68SAkira Hatanaka 
42471928e68SAkira Hatanaka static DecodeStatus DecodeFMem(MCInst &Inst,
42571928e68SAkira Hatanaka                                unsigned Insn,
42671928e68SAkira Hatanaka                                uint64_t Address,
42771928e68SAkira Hatanaka                                const void *Decoder) {
42871928e68SAkira Hatanaka   int Offset = SignExtend32<16>(Insn & 0xffff);
429ecaef49fSJim Grosbach   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
430ecaef49fSJim Grosbach   unsigned Base = fieldFromInstruction(Insn, 21, 5);
43171928e68SAkira Hatanaka 
4329bf2b567SAkira Hatanaka   Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg);
4339bf2b567SAkira Hatanaka   Base = getReg(Decoder, Mips::CPURegsRegClassID, Base);
4349bf2b567SAkira Hatanaka 
4359bf2b567SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
4369bf2b567SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Base));
43771928e68SAkira Hatanaka   Inst.addOperand(MCOperand::CreateImm(Offset));
43871928e68SAkira Hatanaka 
43971928e68SAkira Hatanaka   return MCDisassembler::Success;
44071928e68SAkira Hatanaka }
44171928e68SAkira Hatanaka 
44271928e68SAkira Hatanaka 
44371928e68SAkira Hatanaka static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
44471928e68SAkira Hatanaka                                               unsigned RegNo,
44571928e68SAkira Hatanaka                                               uint64_t Address,
44671928e68SAkira Hatanaka                                               const void *Decoder) {
44771928e68SAkira Hatanaka   // Currently only hardware register 29 is supported.
44871928e68SAkira Hatanaka   if (RegNo != 29)
44971928e68SAkira Hatanaka     return  MCDisassembler::Fail;
45071928e68SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Mips::HWR29));
45171928e68SAkira Hatanaka   return MCDisassembler::Success;
45271928e68SAkira Hatanaka }
45371928e68SAkira Hatanaka 
45471928e68SAkira Hatanaka static DecodeStatus DecodeCondCode(MCInst &Inst,
45571928e68SAkira Hatanaka                                    unsigned Insn,
45671928e68SAkira Hatanaka                                    uint64_t Address,
45771928e68SAkira Hatanaka                                    const void *Decoder) {
45871928e68SAkira Hatanaka   int CondCode = Insn & 0xf;
45971928e68SAkira Hatanaka   Inst.addOperand(MCOperand::CreateImm(CondCode));
46071928e68SAkira Hatanaka   return MCDisassembler::Success;
46171928e68SAkira Hatanaka }
46271928e68SAkira Hatanaka 
46371928e68SAkira Hatanaka static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
46471928e68SAkira Hatanaka                                               unsigned RegNo,
46571928e68SAkira Hatanaka                                               uint64_t Address,
46671928e68SAkira Hatanaka                                               const void *Decoder) {
4679bf2b567SAkira Hatanaka   if (RegNo > 30 || RegNo %2)
46871928e68SAkira Hatanaka     return MCDisassembler::Fail;
46971928e68SAkira Hatanaka 
4709bf2b567SAkira Hatanaka   ;
4719bf2b567SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::AFGR64RegClassID, RegNo /2);
4729bf2b567SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
47371928e68SAkira Hatanaka   return MCDisassembler::Success;
47471928e68SAkira Hatanaka }
47571928e68SAkira Hatanaka 
4762a74a87bSJack Carter static DecodeStatus DecodeHWRegs64RegisterClass(MCInst &Inst,
4772a74a87bSJack Carter                                                 unsigned RegNo,
4782a74a87bSJack Carter                                                 uint64_t Address,
4792a74a87bSJack Carter                                                 const void *Decoder) {
4802a74a87bSJack Carter   //Currently only hardware register 29 is supported
4812a74a87bSJack Carter   if (RegNo != 29)
4822a74a87bSJack Carter     return  MCDisassembler::Fail;
4832a74a87bSJack Carter   Inst.addOperand(MCOperand::CreateReg(Mips::HWR29_64));
4842a74a87bSJack Carter   return MCDisassembler::Success;
4852a74a87bSJack Carter }
4862a74a87bSJack Carter 
487ecabd1a5SAkira Hatanaka static DecodeStatus DecodeACRegsRegisterClass(MCInst &Inst,
488ecabd1a5SAkira Hatanaka                                               unsigned RegNo,
489ecabd1a5SAkira Hatanaka                                               uint64_t Address,
490ecabd1a5SAkira Hatanaka                                               const void *Decoder) {
491ecabd1a5SAkira Hatanaka   if (RegNo >= 4)
492ecabd1a5SAkira Hatanaka     return MCDisassembler::Fail;
493ecabd1a5SAkira Hatanaka 
494ecabd1a5SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::ACRegsRegClassID, RegNo);
495ecabd1a5SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
496ecabd1a5SAkira Hatanaka   return MCDisassembler::Success;
497ecabd1a5SAkira Hatanaka }
498ecabd1a5SAkira Hatanaka 
49971928e68SAkira Hatanaka static DecodeStatus DecodeBranchTarget(MCInst &Inst,
50071928e68SAkira Hatanaka                                        unsigned Offset,
50171928e68SAkira Hatanaka                                        uint64_t Address,
50271928e68SAkira Hatanaka                                        const void *Decoder) {
50371928e68SAkira Hatanaka   unsigned BranchOffset = Offset & 0xffff;
50471928e68SAkira Hatanaka   BranchOffset = SignExtend32<18>(BranchOffset << 2) + 4;
50571928e68SAkira Hatanaka   Inst.addOperand(MCOperand::CreateImm(BranchOffset));
50671928e68SAkira Hatanaka   return MCDisassembler::Success;
50771928e68SAkira Hatanaka }
50871928e68SAkira Hatanaka 
50971928e68SAkira Hatanaka static DecodeStatus DecodeBC1(MCInst &Inst,
51071928e68SAkira Hatanaka                               unsigned Insn,
51171928e68SAkira Hatanaka                               uint64_t Address,
51271928e68SAkira Hatanaka                               const void *Decoder) {
51371928e68SAkira Hatanaka   unsigned BranchOffset = Insn & 0xffff;
51471928e68SAkira Hatanaka   BranchOffset = SignExtend32<18>(BranchOffset << 2) + 4;
51571928e68SAkira Hatanaka   Inst.addOperand(MCOperand::CreateImm(BranchOffset));
51671928e68SAkira Hatanaka   return MCDisassembler::Success;
51771928e68SAkira Hatanaka }
51871928e68SAkira Hatanaka 
51971928e68SAkira Hatanaka static DecodeStatus DecodeJumpTarget(MCInst &Inst,
52071928e68SAkira Hatanaka                                      unsigned Insn,
52171928e68SAkira Hatanaka                                      uint64_t Address,
52271928e68SAkira Hatanaka                                      const void *Decoder) {
52371928e68SAkira Hatanaka 
524ecaef49fSJim Grosbach   unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 2;
52571928e68SAkira Hatanaka   Inst.addOperand(MCOperand::CreateImm(JumpOffset));
52671928e68SAkira Hatanaka   return MCDisassembler::Success;
52771928e68SAkira Hatanaka }
52871928e68SAkira Hatanaka 
52971928e68SAkira Hatanaka 
53071928e68SAkira Hatanaka static DecodeStatus DecodeSimm16(MCInst &Inst,
53171928e68SAkira Hatanaka                                  unsigned Insn,
53271928e68SAkira Hatanaka                                  uint64_t Address,
53371928e68SAkira Hatanaka                                  const void *Decoder) {
53471928e68SAkira Hatanaka   Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Insn)));
53571928e68SAkira Hatanaka   return MCDisassembler::Success;
53671928e68SAkira Hatanaka }
53771928e68SAkira Hatanaka 
53871928e68SAkira Hatanaka static DecodeStatus DecodeInsSize(MCInst &Inst,
53971928e68SAkira Hatanaka                                   unsigned Insn,
54071928e68SAkira Hatanaka                                   uint64_t Address,
54171928e68SAkira Hatanaka                                   const void *Decoder) {
54271928e68SAkira Hatanaka   // First we need to grab the pos(lsb) from MCInst.
54371928e68SAkira Hatanaka   int Pos = Inst.getOperand(2).getImm();
54471928e68SAkira Hatanaka   int Size = (int) Insn - Pos + 1;
54571928e68SAkira Hatanaka   Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size)));
54671928e68SAkira Hatanaka   return MCDisassembler::Success;
54771928e68SAkira Hatanaka }
54871928e68SAkira Hatanaka 
54971928e68SAkira Hatanaka static DecodeStatus DecodeExtSize(MCInst &Inst,
55071928e68SAkira Hatanaka                                   unsigned Insn,
55171928e68SAkira Hatanaka                                   uint64_t Address,
55271928e68SAkira Hatanaka                                   const void *Decoder) {
55371928e68SAkira Hatanaka   int Size = (int) Insn  + 1;
55471928e68SAkira Hatanaka   Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size)));
55571928e68SAkira Hatanaka   return MCDisassembler::Success;
55671928e68SAkira Hatanaka }
557