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) :
389bfa2e2eSAkira Hatanaka     MCDisassembler(STI), RegInfo(Info),
399bfa2e2eSAkira Hatanaka     IsN64(STI.getFeatureBits() & Mips::FeatureN64), isBigEndian(bigEndian) {}
4071928e68SAkira Hatanaka 
419bf2b567SAkira Hatanaka   virtual ~MipsDisassemblerBase() {}
429bf2b567SAkira Hatanaka 
43dcfd5b52SBenjamin Kramer   const MCRegisterInfo *getRegInfo() const { return RegInfo.get(); }
449bf2b567SAkira Hatanaka 
459bfa2e2eSAkira Hatanaka   bool isN64() const { return IsN64; }
469bfa2e2eSAkira Hatanaka 
479bf2b567SAkira Hatanaka private:
48dcfd5b52SBenjamin Kramer   OwningPtr<const MCRegisterInfo> RegInfo;
499bfa2e2eSAkira Hatanaka   bool IsN64;
509bf2b567SAkira Hatanaka protected:
519bf2b567SAkira Hatanaka   bool isBigEndian;
529bf2b567SAkira Hatanaka };
539bf2b567SAkira Hatanaka 
549bf2b567SAkira Hatanaka /// MipsDisassembler - a disasembler class for Mips32.
559bf2b567SAkira Hatanaka class MipsDisassembler : public MipsDisassemblerBase {
56dde3d582SVladimir Medic   bool IsMicroMips;
579bf2b567SAkira Hatanaka public:
589bf2b567SAkira Hatanaka   /// Constructor     - Initializes the disassembler.
599bf2b567SAkira Hatanaka   ///
609bf2b567SAkira Hatanaka   MipsDisassembler(const MCSubtargetInfo &STI, const MCRegisterInfo *Info,
619bf2b567SAkira Hatanaka                    bool bigEndian) :
62dde3d582SVladimir Medic     MipsDisassemblerBase(STI, Info, bigEndian) {
63dde3d582SVladimir Medic       IsMicroMips = STI.getFeatureBits() & Mips::FeatureMicroMips;
64dde3d582SVladimir Medic     }
6571928e68SAkira Hatanaka 
6671928e68SAkira Hatanaka   /// getInstruction - See MCDisassembler.
679bf2b567SAkira Hatanaka   virtual DecodeStatus getInstruction(MCInst &instr,
6871928e68SAkira Hatanaka                                       uint64_t &size,
6971928e68SAkira Hatanaka                                       const MemoryObject &region,
7071928e68SAkira Hatanaka                                       uint64_t address,
7171928e68SAkira Hatanaka                                       raw_ostream &vStream,
7271928e68SAkira Hatanaka                                       raw_ostream &cStream) const;
7371928e68SAkira Hatanaka };
7471928e68SAkira Hatanaka 
7571928e68SAkira Hatanaka 
7671928e68SAkira Hatanaka /// Mips64Disassembler - a disasembler class for Mips64.
779bf2b567SAkira Hatanaka class Mips64Disassembler : public MipsDisassemblerBase {
7871928e68SAkira Hatanaka public:
7971928e68SAkira Hatanaka   /// Constructor     - Initializes the disassembler.
8071928e68SAkira Hatanaka   ///
819bf2b567SAkira Hatanaka   Mips64Disassembler(const MCSubtargetInfo &STI, const MCRegisterInfo *Info,
829bf2b567SAkira Hatanaka                      bool bigEndian) :
839bf2b567SAkira Hatanaka     MipsDisassemblerBase(STI, Info, bigEndian) {}
8471928e68SAkira Hatanaka 
8571928e68SAkira Hatanaka   /// getInstruction - See MCDisassembler.
869bf2b567SAkira Hatanaka   virtual DecodeStatus getInstruction(MCInst &instr,
8771928e68SAkira Hatanaka                                       uint64_t &size,
8871928e68SAkira Hatanaka                                       const MemoryObject &region,
8971928e68SAkira Hatanaka                                       uint64_t address,
9071928e68SAkira Hatanaka                                       raw_ostream &vStream,
9171928e68SAkira Hatanaka                                       raw_ostream &cStream) const;
9271928e68SAkira Hatanaka };
9371928e68SAkira Hatanaka 
94cb3e98cfSBenjamin Kramer } // end anonymous namespace
95cb3e98cfSBenjamin Kramer 
9671928e68SAkira Hatanaka // Forward declare these because the autogenerated code will reference them.
9771928e68SAkira Hatanaka // Definitions are further down.
9813e6ccf3SAkira Hatanaka static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst,
9971928e68SAkira Hatanaka                                              unsigned RegNo,
10071928e68SAkira Hatanaka                                              uint64_t Address,
10171928e68SAkira Hatanaka                                              const void *Decoder);
10271928e68SAkira Hatanaka 
103ec8a5490SReed Kotler static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst,
104ec8a5490SReed Kotler                                                  unsigned RegNo,
105ec8a5490SReed Kotler                                                  uint64_t Address,
106ec8a5490SReed Kotler                                                  const void *Decoder);
107ec8a5490SReed Kotler 
10813e6ccf3SAkira Hatanaka static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst,
10971928e68SAkira Hatanaka                                              unsigned RegNo,
11071928e68SAkira Hatanaka                                              uint64_t Address,
11171928e68SAkira Hatanaka                                              const void *Decoder);
11271928e68SAkira Hatanaka 
1139bfa2e2eSAkira Hatanaka static DecodeStatus DecodePtrRegisterClass(MCInst &Inst,
1149bfa2e2eSAkira Hatanaka                                            unsigned Insn,
1159bfa2e2eSAkira Hatanaka                                            uint64_t Address,
1169bfa2e2eSAkira Hatanaka                                            const void *Decoder);
1179bfa2e2eSAkira Hatanaka 
118654655f1SAkira Hatanaka static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst,
119ecabd1a5SAkira Hatanaka                                             unsigned RegNo,
120ecabd1a5SAkira Hatanaka                                             uint64_t Address,
121ecabd1a5SAkira Hatanaka                                             const void *Decoder);
122ecabd1a5SAkira Hatanaka 
12371928e68SAkira Hatanaka static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
12471928e68SAkira Hatanaka                                              unsigned RegNo,
12571928e68SAkira Hatanaka                                              uint64_t Address,
12671928e68SAkira Hatanaka                                              const void *Decoder);
12771928e68SAkira Hatanaka 
12871928e68SAkira Hatanaka static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
12971928e68SAkira Hatanaka                                              unsigned RegNo,
13071928e68SAkira Hatanaka                                              uint64_t Address,
13171928e68SAkira Hatanaka                                              const void *Decoder);
13271928e68SAkira Hatanaka 
13314e31a2fSAkira Hatanaka static DecodeStatus DecodeFGRH32RegisterClass(MCInst &Inst,
13414e31a2fSAkira Hatanaka                                               unsigned RegNo,
13514e31a2fSAkira Hatanaka                                               uint64_t Address,
13614e31a2fSAkira Hatanaka                                               const void *Decoder);
13714e31a2fSAkira Hatanaka 
13871928e68SAkira Hatanaka static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
13971928e68SAkira Hatanaka                                            unsigned RegNo,
14071928e68SAkira Hatanaka                                            uint64_t Address,
14171928e68SAkira Hatanaka                                            const void *Decoder);
14271928e68SAkira Hatanaka 
1431fb1b8b8SAkira Hatanaka static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst,
1441fb1b8b8SAkira Hatanaka                                            unsigned RegNo,
1451fb1b8b8SAkira Hatanaka                                            uint64_t Address,
1461fb1b8b8SAkira Hatanaka                                            const void *Decoder);
1471fb1b8b8SAkira Hatanaka 
14871928e68SAkira Hatanaka static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
14971928e68SAkira Hatanaka                                               unsigned Insn,
15071928e68SAkira Hatanaka                                               uint64_t Address,
15171928e68SAkira Hatanaka                                               const void *Decoder);
15271928e68SAkira Hatanaka 
15371928e68SAkira Hatanaka static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
15471928e68SAkira Hatanaka                                               unsigned RegNo,
15571928e68SAkira Hatanaka                                               uint64_t Address,
15671928e68SAkira Hatanaka                                               const void *Decoder);
15771928e68SAkira Hatanaka 
15800fcf2e1SAkira Hatanaka static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst,
159ecabd1a5SAkira Hatanaka                                                 unsigned RegNo,
160ecabd1a5SAkira Hatanaka                                                 uint64_t Address,
161ecabd1a5SAkira Hatanaka                                                 const void *Decoder);
162ecabd1a5SAkira Hatanaka 
1638002a3f6SAkira Hatanaka static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst,
16459bfaf77SAkira Hatanaka                                                unsigned RegNo,
16559bfaf77SAkira Hatanaka                                                uint64_t Address,
16659bfaf77SAkira Hatanaka                                                const void *Decoder);
16759bfaf77SAkira Hatanaka 
1688002a3f6SAkira Hatanaka static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst,
16959bfaf77SAkira Hatanaka                                                unsigned RegNo,
17059bfaf77SAkira Hatanaka                                                uint64_t Address,
17159bfaf77SAkira Hatanaka                                                const void *Decoder);
17259bfaf77SAkira Hatanaka 
1733eb663b0SJack Carter static DecodeStatus DecodeMSA128BRegisterClass(MCInst &Inst,
1743eb663b0SJack Carter                                                unsigned RegNo,
1753eb663b0SJack Carter                                                uint64_t Address,
1763eb663b0SJack Carter                                                const void *Decoder);
1773eb663b0SJack Carter 
1785dc8ac92SJack Carter static DecodeStatus DecodeMSA128HRegisterClass(MCInst &Inst,
1795dc8ac92SJack Carter                                                unsigned RegNo,
1805dc8ac92SJack Carter                                                uint64_t Address,
1815dc8ac92SJack Carter                                                const void *Decoder);
1825dc8ac92SJack Carter 
1835dc8ac92SJack Carter static DecodeStatus DecodeMSA128WRegisterClass(MCInst &Inst,
1845dc8ac92SJack Carter                                                unsigned RegNo,
1855dc8ac92SJack Carter                                                uint64_t Address,
1865dc8ac92SJack Carter                                                const void *Decoder);
1875dc8ac92SJack Carter 
1885dc8ac92SJack Carter static DecodeStatus DecodeMSA128DRegisterClass(MCInst &Inst,
1895dc8ac92SJack Carter                                                unsigned RegNo,
1905dc8ac92SJack Carter                                                uint64_t Address,
1915dc8ac92SJack Carter                                                const void *Decoder);
1925dc8ac92SJack Carter 
193a591fdc6SMatheus Almeida static DecodeStatus DecodeMSACtrlRegisterClass(MCInst &Inst,
194a591fdc6SMatheus Almeida                                                unsigned RegNo,
195a591fdc6SMatheus Almeida                                                uint64_t Address,
196a591fdc6SMatheus Almeida                                                const void *Decoder);
197a591fdc6SMatheus Almeida 
19871928e68SAkira Hatanaka static DecodeStatus DecodeBranchTarget(MCInst &Inst,
19971928e68SAkira Hatanaka                                        unsigned Offset,
20071928e68SAkira Hatanaka                                        uint64_t Address,
20171928e68SAkira Hatanaka                                        const void *Decoder);
20271928e68SAkira Hatanaka 
20371928e68SAkira Hatanaka static DecodeStatus DecodeJumpTarget(MCInst &Inst,
20471928e68SAkira Hatanaka                                      unsigned Insn,
20571928e68SAkira Hatanaka                                      uint64_t Address,
20671928e68SAkira Hatanaka                                      const void *Decoder);
20771928e68SAkira Hatanaka 
208*8a80aa76SZoran Jovanovic // DecodeBranchTargetMM - Decode microMIPS branch offset, which is
209*8a80aa76SZoran Jovanovic // shifted left by 1 bit.
210*8a80aa76SZoran Jovanovic static DecodeStatus DecodeBranchTargetMM(MCInst &Inst,
211*8a80aa76SZoran Jovanovic                                          unsigned Offset,
212*8a80aa76SZoran Jovanovic                                          uint64_t Address,
213*8a80aa76SZoran Jovanovic                                          const void *Decoder);
214*8a80aa76SZoran Jovanovic 
215507e084aSZoran Jovanovic // DecodeJumpTargetMM - Decode microMIPS jump target, which is
216507e084aSZoran Jovanovic // shifted left by 1 bit.
217507e084aSZoran Jovanovic static DecodeStatus DecodeJumpTargetMM(MCInst &Inst,
218507e084aSZoran Jovanovic                                        unsigned Insn,
219507e084aSZoran Jovanovic                                        uint64_t Address,
220507e084aSZoran Jovanovic                                        const void *Decoder);
221507e084aSZoran Jovanovic 
22271928e68SAkira Hatanaka static DecodeStatus DecodeMem(MCInst &Inst,
22371928e68SAkira Hatanaka                               unsigned Insn,
22471928e68SAkira Hatanaka                               uint64_t Address,
22571928e68SAkira Hatanaka                               const void *Decoder);
22671928e68SAkira Hatanaka 
227fe0bf9f6SMatheus Almeida static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn,
228fe0bf9f6SMatheus Almeida                                     uint64_t Address, const void *Decoder);
229fe0bf9f6SMatheus Almeida 
230dde3d582SVladimir Medic static DecodeStatus DecodeMemMMImm12(MCInst &Inst,
231dde3d582SVladimir Medic                                      unsigned Insn,
232dde3d582SVladimir Medic                                      uint64_t Address,
233dde3d582SVladimir Medic                                      const void *Decoder);
234dde3d582SVladimir Medic 
235dde3d582SVladimir Medic static DecodeStatus DecodeMemMMImm16(MCInst &Inst,
236dde3d582SVladimir Medic                                      unsigned Insn,
237dde3d582SVladimir Medic                                      uint64_t Address,
238dde3d582SVladimir Medic                                      const void *Decoder);
239dde3d582SVladimir Medic 
24071928e68SAkira Hatanaka static DecodeStatus DecodeFMem(MCInst &Inst, unsigned Insn,
24171928e68SAkira Hatanaka                                uint64_t Address,
24271928e68SAkira Hatanaka                                const void *Decoder);
24371928e68SAkira Hatanaka 
24471928e68SAkira Hatanaka static DecodeStatus DecodeSimm16(MCInst &Inst,
24571928e68SAkira Hatanaka                                  unsigned Insn,
24671928e68SAkira Hatanaka                                  uint64_t Address,
24771928e68SAkira Hatanaka                                  const void *Decoder);
24871928e68SAkira Hatanaka 
24971928e68SAkira Hatanaka static DecodeStatus DecodeInsSize(MCInst &Inst,
25071928e68SAkira Hatanaka                                   unsigned Insn,
25171928e68SAkira Hatanaka                                   uint64_t Address,
25271928e68SAkira Hatanaka                                   const void *Decoder);
25371928e68SAkira Hatanaka 
25471928e68SAkira Hatanaka static DecodeStatus DecodeExtSize(MCInst &Inst,
25571928e68SAkira Hatanaka                                   unsigned Insn,
25671928e68SAkira Hatanaka                                   uint64_t Address,
25771928e68SAkira Hatanaka                                   const void *Decoder);
25871928e68SAkira Hatanaka 
25971928e68SAkira Hatanaka namespace llvm {
26071928e68SAkira Hatanaka extern Target TheMipselTarget, TheMipsTarget, TheMips64Target,
26171928e68SAkira Hatanaka               TheMips64elTarget;
26271928e68SAkira Hatanaka }
26371928e68SAkira Hatanaka 
26471928e68SAkira Hatanaka static MCDisassembler *createMipsDisassembler(
26571928e68SAkira Hatanaka                        const Target &T,
26671928e68SAkira Hatanaka                        const MCSubtargetInfo &STI) {
2679bf2b567SAkira Hatanaka   return new MipsDisassembler(STI, T.createMCRegInfo(""), true);
26871928e68SAkira Hatanaka }
26971928e68SAkira Hatanaka 
27071928e68SAkira Hatanaka static MCDisassembler *createMipselDisassembler(
27171928e68SAkira Hatanaka                        const Target &T,
27271928e68SAkira Hatanaka                        const MCSubtargetInfo &STI) {
2739bf2b567SAkira Hatanaka   return new MipsDisassembler(STI, T.createMCRegInfo(""), false);
27471928e68SAkira Hatanaka }
27571928e68SAkira Hatanaka 
27671928e68SAkira Hatanaka static MCDisassembler *createMips64Disassembler(
27771928e68SAkira Hatanaka                        const Target &T,
27871928e68SAkira Hatanaka                        const MCSubtargetInfo &STI) {
2799bf2b567SAkira Hatanaka   return new Mips64Disassembler(STI, T.createMCRegInfo(""), true);
28071928e68SAkira Hatanaka }
28171928e68SAkira Hatanaka 
28271928e68SAkira Hatanaka static MCDisassembler *createMips64elDisassembler(
28371928e68SAkira Hatanaka                        const Target &T,
28471928e68SAkira Hatanaka                        const MCSubtargetInfo &STI) {
2859bf2b567SAkira Hatanaka   return new Mips64Disassembler(STI, T.createMCRegInfo(""), false);
28671928e68SAkira Hatanaka }
28771928e68SAkira Hatanaka 
28871928e68SAkira Hatanaka extern "C" void LLVMInitializeMipsDisassembler() {
28971928e68SAkira Hatanaka   // Register the disassembler.
29071928e68SAkira Hatanaka   TargetRegistry::RegisterMCDisassembler(TheMipsTarget,
29171928e68SAkira Hatanaka                                          createMipsDisassembler);
29271928e68SAkira Hatanaka   TargetRegistry::RegisterMCDisassembler(TheMipselTarget,
29371928e68SAkira Hatanaka                                          createMipselDisassembler);
29471928e68SAkira Hatanaka   TargetRegistry::RegisterMCDisassembler(TheMips64Target,
29571928e68SAkira Hatanaka                                          createMips64Disassembler);
29671928e68SAkira Hatanaka   TargetRegistry::RegisterMCDisassembler(TheMips64elTarget,
29771928e68SAkira Hatanaka                                          createMips64elDisassembler);
29871928e68SAkira Hatanaka }
29971928e68SAkira Hatanaka 
30071928e68SAkira Hatanaka 
30171928e68SAkira Hatanaka #include "MipsGenDisassemblerTables.inc"
30271928e68SAkira Hatanaka 
30371928e68SAkira Hatanaka   /// readInstruction - read four bytes from the MemoryObject
30471928e68SAkira Hatanaka   /// and return 32 bit word sorted according to the given endianess
30571928e68SAkira Hatanaka static DecodeStatus readInstruction32(const MemoryObject &region,
30671928e68SAkira Hatanaka                                       uint64_t address,
30771928e68SAkira Hatanaka                                       uint64_t &size,
30871928e68SAkira Hatanaka                                       uint32_t &insn,
309dde3d582SVladimir Medic                                       bool isBigEndian,
310dde3d582SVladimir Medic                                       bool IsMicroMips) {
31171928e68SAkira Hatanaka   uint8_t Bytes[4];
31271928e68SAkira Hatanaka 
31371928e68SAkira Hatanaka   // We want to read exactly 4 Bytes of data.
314534d3a46SBenjamin Kramer   if (region.readBytes(address, 4, Bytes) == -1) {
31571928e68SAkira Hatanaka     size = 0;
31671928e68SAkira Hatanaka     return MCDisassembler::Fail;
31771928e68SAkira Hatanaka   }
31871928e68SAkira Hatanaka 
31971928e68SAkira Hatanaka   if (isBigEndian) {
32071928e68SAkira Hatanaka     // Encoded as a big-endian 32-bit word in the stream.
32171928e68SAkira Hatanaka     insn = (Bytes[3] <<  0) |
32271928e68SAkira Hatanaka            (Bytes[2] <<  8) |
32371928e68SAkira Hatanaka            (Bytes[1] << 16) |
32471928e68SAkira Hatanaka            (Bytes[0] << 24);
32571928e68SAkira Hatanaka   }
32671928e68SAkira Hatanaka   else {
32771928e68SAkira Hatanaka     // Encoded as a small-endian 32-bit word in the stream.
328dde3d582SVladimir Medic     // Little-endian byte ordering:
329dde3d582SVladimir Medic     //   mips32r2:   4 | 3 | 2 | 1
330dde3d582SVladimir Medic     //   microMIPS:  2 | 1 | 4 | 3
331dde3d582SVladimir Medic     if (IsMicroMips) {
332dde3d582SVladimir Medic       insn = (Bytes[2] <<  0) |
333dde3d582SVladimir Medic              (Bytes[3] <<  8) |
334dde3d582SVladimir Medic              (Bytes[0] << 16) |
335dde3d582SVladimir Medic              (Bytes[1] << 24);
336dde3d582SVladimir Medic     } else {
33771928e68SAkira Hatanaka       insn = (Bytes[0] <<  0) |
33871928e68SAkira Hatanaka              (Bytes[1] <<  8) |
33971928e68SAkira Hatanaka              (Bytes[2] << 16) |
34071928e68SAkira Hatanaka              (Bytes[3] << 24);
34171928e68SAkira Hatanaka     }
342dde3d582SVladimir Medic   }
34371928e68SAkira Hatanaka 
34471928e68SAkira Hatanaka   return MCDisassembler::Success;
34571928e68SAkira Hatanaka }
34671928e68SAkira Hatanaka 
34771928e68SAkira Hatanaka DecodeStatus
34871928e68SAkira Hatanaka MipsDisassembler::getInstruction(MCInst &instr,
34971928e68SAkira Hatanaka                                  uint64_t &Size,
35071928e68SAkira Hatanaka                                  const MemoryObject &Region,
35171928e68SAkira Hatanaka                                  uint64_t Address,
35271928e68SAkira Hatanaka                                  raw_ostream &vStream,
35371928e68SAkira Hatanaka                                  raw_ostream &cStream) const {
35471928e68SAkira Hatanaka   uint32_t Insn;
35571928e68SAkira Hatanaka 
35671928e68SAkira Hatanaka   DecodeStatus Result = readInstruction32(Region, Address, Size,
357dde3d582SVladimir Medic                                           Insn, isBigEndian, IsMicroMips);
35871928e68SAkira Hatanaka   if (Result == MCDisassembler::Fail)
35971928e68SAkira Hatanaka     return MCDisassembler::Fail;
36071928e68SAkira Hatanaka 
361dde3d582SVladimir Medic   if (IsMicroMips) {
362dde3d582SVladimir Medic     // Calling the auto-generated decoder function.
363dde3d582SVladimir Medic     Result = decodeInstruction(DecoderTableMicroMips32, instr, Insn, Address,
364dde3d582SVladimir Medic                                this, STI);
365dde3d582SVladimir Medic     if (Result != MCDisassembler::Fail) {
366dde3d582SVladimir Medic       Size = 4;
367dde3d582SVladimir Medic       return Result;
368dde3d582SVladimir Medic     }
369dde3d582SVladimir Medic     return MCDisassembler::Fail;
370dde3d582SVladimir Medic   }
371dde3d582SVladimir Medic 
37271928e68SAkira Hatanaka   // Calling the auto-generated decoder function.
373ecaef49fSJim Grosbach   Result = decodeInstruction(DecoderTableMips32, instr, Insn, Address,
374ecaef49fSJim Grosbach                              this, STI);
37571928e68SAkira Hatanaka   if (Result != MCDisassembler::Fail) {
37671928e68SAkira Hatanaka     Size = 4;
37771928e68SAkira Hatanaka     return Result;
37871928e68SAkira Hatanaka   }
37971928e68SAkira Hatanaka 
38071928e68SAkira Hatanaka   return MCDisassembler::Fail;
38171928e68SAkira Hatanaka }
38271928e68SAkira Hatanaka 
38371928e68SAkira Hatanaka DecodeStatus
38471928e68SAkira Hatanaka Mips64Disassembler::getInstruction(MCInst &instr,
38571928e68SAkira Hatanaka                                    uint64_t &Size,
38671928e68SAkira Hatanaka                                    const MemoryObject &Region,
38771928e68SAkira Hatanaka                                    uint64_t Address,
38871928e68SAkira Hatanaka                                    raw_ostream &vStream,
38971928e68SAkira Hatanaka                                    raw_ostream &cStream) const {
39071928e68SAkira Hatanaka   uint32_t Insn;
39171928e68SAkira Hatanaka 
39271928e68SAkira Hatanaka   DecodeStatus Result = readInstruction32(Region, Address, Size,
393dde3d582SVladimir Medic                                           Insn, isBigEndian, false);
39471928e68SAkira Hatanaka   if (Result == MCDisassembler::Fail)
39571928e68SAkira Hatanaka     return MCDisassembler::Fail;
39671928e68SAkira Hatanaka 
39771928e68SAkira Hatanaka   // Calling the auto-generated decoder function.
398ecaef49fSJim Grosbach   Result = decodeInstruction(DecoderTableMips6432, instr, Insn, Address,
399ecaef49fSJim Grosbach                              this, STI);
40071928e68SAkira Hatanaka   if (Result != MCDisassembler::Fail) {
40171928e68SAkira Hatanaka     Size = 4;
40271928e68SAkira Hatanaka     return Result;
40371928e68SAkira Hatanaka   }
40471928e68SAkira Hatanaka   // If we fail to decode in Mips64 decoder space we can try in Mips32
405ecaef49fSJim Grosbach   Result = decodeInstruction(DecoderTableMips32, instr, Insn, Address,
406ecaef49fSJim Grosbach                              this, STI);
40771928e68SAkira Hatanaka   if (Result != MCDisassembler::Fail) {
40871928e68SAkira Hatanaka     Size = 4;
40971928e68SAkira Hatanaka     return Result;
41071928e68SAkira Hatanaka   }
41171928e68SAkira Hatanaka 
41271928e68SAkira Hatanaka   return MCDisassembler::Fail;
41371928e68SAkira Hatanaka }
41471928e68SAkira Hatanaka 
4159bf2b567SAkira Hatanaka static unsigned getReg(const void *D, unsigned RC, unsigned RegNo) {
4169bf2b567SAkira Hatanaka   const MipsDisassemblerBase *Dis = static_cast<const MipsDisassemblerBase*>(D);
4179bf2b567SAkira Hatanaka   return *(Dis->getRegInfo()->getRegClass(RC).begin() + RegNo);
4189bf2b567SAkira Hatanaka }
4199bf2b567SAkira Hatanaka 
420ec8a5490SReed Kotler static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst,
421ec8a5490SReed Kotler                                                  unsigned RegNo,
422ec8a5490SReed Kotler                                                  uint64_t Address,
423ec8a5490SReed Kotler                                                  const void *Decoder) {
424ec8a5490SReed Kotler 
425ec8a5490SReed Kotler   return MCDisassembler::Fail;
426ec8a5490SReed Kotler 
427ec8a5490SReed Kotler }
428ec8a5490SReed Kotler 
42913e6ccf3SAkira Hatanaka static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst,
43071928e68SAkira Hatanaka                                              unsigned RegNo,
43171928e68SAkira Hatanaka                                              uint64_t Address,
43271928e68SAkira Hatanaka                                              const void *Decoder) {
43371928e68SAkira Hatanaka 
43471928e68SAkira Hatanaka   if (RegNo > 31)
43571928e68SAkira Hatanaka     return MCDisassembler::Fail;
43671928e68SAkira Hatanaka 
43713e6ccf3SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::GPR64RegClassID, RegNo);
4389bf2b567SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
43971928e68SAkira Hatanaka   return MCDisassembler::Success;
44071928e68SAkira Hatanaka }
44171928e68SAkira Hatanaka 
44213e6ccf3SAkira Hatanaka static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst,
44371928e68SAkira Hatanaka                                              unsigned RegNo,
44471928e68SAkira Hatanaka                                              uint64_t Address,
44571928e68SAkira Hatanaka                                              const void *Decoder) {
44671928e68SAkira Hatanaka   if (RegNo > 31)
44771928e68SAkira Hatanaka     return MCDisassembler::Fail;
44813e6ccf3SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::GPR32RegClassID, RegNo);
4499bf2b567SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
45071928e68SAkira Hatanaka   return MCDisassembler::Success;
45171928e68SAkira Hatanaka }
45271928e68SAkira Hatanaka 
4539bfa2e2eSAkira Hatanaka static DecodeStatus DecodePtrRegisterClass(MCInst &Inst,
4549bfa2e2eSAkira Hatanaka                                            unsigned RegNo,
4559bfa2e2eSAkira Hatanaka                                            uint64_t Address,
4569bfa2e2eSAkira Hatanaka                                            const void *Decoder) {
4579bfa2e2eSAkira Hatanaka   if (static_cast<const MipsDisassembler *>(Decoder)->isN64())
4589bfa2e2eSAkira Hatanaka     return DecodeGPR64RegisterClass(Inst, RegNo, Address, Decoder);
4599bfa2e2eSAkira Hatanaka 
4609bfa2e2eSAkira Hatanaka   return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
4619bfa2e2eSAkira Hatanaka }
4629bfa2e2eSAkira Hatanaka 
463654655f1SAkira Hatanaka static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst,
464ecabd1a5SAkira Hatanaka                                             unsigned RegNo,
465ecabd1a5SAkira Hatanaka                                             uint64_t Address,
466ecabd1a5SAkira Hatanaka                                             const void *Decoder) {
46713e6ccf3SAkira Hatanaka   return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
468ecabd1a5SAkira Hatanaka }
469ecabd1a5SAkira Hatanaka 
47071928e68SAkira Hatanaka static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
47171928e68SAkira Hatanaka                                              unsigned RegNo,
47271928e68SAkira Hatanaka                                              uint64_t Address,
47371928e68SAkira Hatanaka                                              const void *Decoder) {
47471928e68SAkira Hatanaka   if (RegNo > 31)
47571928e68SAkira Hatanaka     return MCDisassembler::Fail;
47671928e68SAkira Hatanaka 
4779bf2b567SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::FGR64RegClassID, RegNo);
4789bf2b567SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
47971928e68SAkira Hatanaka   return MCDisassembler::Success;
48071928e68SAkira Hatanaka }
48171928e68SAkira Hatanaka 
48271928e68SAkira Hatanaka static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
48371928e68SAkira Hatanaka                                              unsigned RegNo,
48471928e68SAkira Hatanaka                                              uint64_t Address,
48571928e68SAkira Hatanaka                                              const void *Decoder) {
48671928e68SAkira Hatanaka   if (RegNo > 31)
48771928e68SAkira Hatanaka     return MCDisassembler::Fail;
48871928e68SAkira Hatanaka 
4899bf2b567SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::FGR32RegClassID, RegNo);
4909bf2b567SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
49171928e68SAkira Hatanaka   return MCDisassembler::Success;
49271928e68SAkira Hatanaka }
49371928e68SAkira Hatanaka 
49414e31a2fSAkira Hatanaka static DecodeStatus DecodeFGRH32RegisterClass(MCInst &Inst,
49514e31a2fSAkira Hatanaka                                               unsigned RegNo,
49614e31a2fSAkira Hatanaka                                               uint64_t Address,
49714e31a2fSAkira Hatanaka                                               const void *Decoder) {
49814e31a2fSAkira Hatanaka   if (RegNo > 31)
49914e31a2fSAkira Hatanaka     return MCDisassembler::Fail;
50014e31a2fSAkira Hatanaka 
50114e31a2fSAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::FGRH32RegClassID, RegNo);
50214e31a2fSAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
50314e31a2fSAkira Hatanaka   return MCDisassembler::Success;
50414e31a2fSAkira Hatanaka }
50514e31a2fSAkira Hatanaka 
50671928e68SAkira Hatanaka static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
50771928e68SAkira Hatanaka                                            unsigned RegNo,
50871928e68SAkira Hatanaka                                            uint64_t Address,
50971928e68SAkira Hatanaka                                            const void *Decoder) {
510253777fdSChad Rosier   if (RegNo > 31)
511253777fdSChad Rosier     return MCDisassembler::Fail;
512253777fdSChad Rosier   unsigned Reg = getReg(Decoder, Mips::CCRRegClassID, RegNo);
513253777fdSChad Rosier   Inst.addOperand(MCOperand::CreateReg(Reg));
51471928e68SAkira Hatanaka   return MCDisassembler::Success;
51571928e68SAkira Hatanaka }
51671928e68SAkira Hatanaka 
5171fb1b8b8SAkira Hatanaka static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst,
5181fb1b8b8SAkira Hatanaka                                            unsigned RegNo,
5191fb1b8b8SAkira Hatanaka                                            uint64_t Address,
5201fb1b8b8SAkira Hatanaka                                            const void *Decoder) {
5211fb1b8b8SAkira Hatanaka   if (RegNo > 7)
5221fb1b8b8SAkira Hatanaka     return MCDisassembler::Fail;
5231fb1b8b8SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::FCCRegClassID, RegNo);
5241fb1b8b8SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
5251fb1b8b8SAkira Hatanaka   return MCDisassembler::Success;
5261fb1b8b8SAkira Hatanaka }
5271fb1b8b8SAkira Hatanaka 
52871928e68SAkira Hatanaka static DecodeStatus DecodeMem(MCInst &Inst,
52971928e68SAkira Hatanaka                               unsigned Insn,
53071928e68SAkira Hatanaka                               uint64_t Address,
53171928e68SAkira Hatanaka                               const void *Decoder) {
53271928e68SAkira Hatanaka   int Offset = SignExtend32<16>(Insn & 0xffff);
533ecaef49fSJim Grosbach   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
534ecaef49fSJim Grosbach   unsigned Base = fieldFromInstruction(Insn, 21, 5);
5359bf2b567SAkira Hatanaka 
53613e6ccf3SAkira Hatanaka   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
53713e6ccf3SAkira Hatanaka   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
53871928e68SAkira Hatanaka 
53971928e68SAkira Hatanaka   if(Inst.getOpcode() == Mips::SC){
5409bf2b567SAkira Hatanaka     Inst.addOperand(MCOperand::CreateReg(Reg));
54171928e68SAkira Hatanaka   }
54271928e68SAkira Hatanaka 
5439bf2b567SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
5449bf2b567SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Base));
54571928e68SAkira Hatanaka   Inst.addOperand(MCOperand::CreateImm(Offset));
54671928e68SAkira Hatanaka 
54771928e68SAkira Hatanaka   return MCDisassembler::Success;
54871928e68SAkira Hatanaka }
54971928e68SAkira Hatanaka 
550fe0bf9f6SMatheus Almeida static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn,
551fe0bf9f6SMatheus Almeida                                     uint64_t Address, const void *Decoder) {
552fe0bf9f6SMatheus Almeida   int Offset = SignExtend32<10>(fieldFromInstruction(Insn, 16, 10));
553fe0bf9f6SMatheus Almeida   unsigned Reg = fieldFromInstruction(Insn, 6, 5);
554fe0bf9f6SMatheus Almeida   unsigned Base = fieldFromInstruction(Insn, 11, 5);
555fe0bf9f6SMatheus Almeida 
556fe0bf9f6SMatheus Almeida   Reg = getReg(Decoder, Mips::MSA128BRegClassID, Reg);
557fe0bf9f6SMatheus Almeida   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
558fe0bf9f6SMatheus Almeida 
559fe0bf9f6SMatheus Almeida   Inst.addOperand(MCOperand::CreateReg(Reg));
560fe0bf9f6SMatheus Almeida   Inst.addOperand(MCOperand::CreateReg(Base));
561fe0bf9f6SMatheus Almeida   Inst.addOperand(MCOperand::CreateImm(Offset));
562fe0bf9f6SMatheus Almeida 
563fe0bf9f6SMatheus Almeida   return MCDisassembler::Success;
564fe0bf9f6SMatheus Almeida }
565fe0bf9f6SMatheus Almeida 
566dde3d582SVladimir Medic static DecodeStatus DecodeMemMMImm12(MCInst &Inst,
567dde3d582SVladimir Medic                                      unsigned Insn,
568dde3d582SVladimir Medic                                      uint64_t Address,
569dde3d582SVladimir Medic                                      const void *Decoder) {
570dde3d582SVladimir Medic   int Offset = SignExtend32<12>(Insn & 0x0fff);
571dde3d582SVladimir Medic   unsigned Reg = fieldFromInstruction(Insn, 21, 5);
572dde3d582SVladimir Medic   unsigned Base = fieldFromInstruction(Insn, 16, 5);
573dde3d582SVladimir Medic 
574dde3d582SVladimir Medic   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
575dde3d582SVladimir Medic   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
576dde3d582SVladimir Medic 
577dde3d582SVladimir Medic   Inst.addOperand(MCOperand::CreateReg(Reg));
578dde3d582SVladimir Medic   Inst.addOperand(MCOperand::CreateReg(Base));
579dde3d582SVladimir Medic   Inst.addOperand(MCOperand::CreateImm(Offset));
580dde3d582SVladimir Medic 
581dde3d582SVladimir Medic   return MCDisassembler::Success;
582dde3d582SVladimir Medic }
583dde3d582SVladimir Medic 
584dde3d582SVladimir Medic static DecodeStatus DecodeMemMMImm16(MCInst &Inst,
585dde3d582SVladimir Medic                                      unsigned Insn,
586dde3d582SVladimir Medic                                      uint64_t Address,
587dde3d582SVladimir Medic                                      const void *Decoder) {
588dde3d582SVladimir Medic   int Offset = SignExtend32<16>(Insn & 0xffff);
589dde3d582SVladimir Medic   unsigned Reg = fieldFromInstruction(Insn, 21, 5);
590dde3d582SVladimir Medic   unsigned Base = fieldFromInstruction(Insn, 16, 5);
591dde3d582SVladimir Medic 
592dde3d582SVladimir Medic   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
593dde3d582SVladimir Medic   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
594dde3d582SVladimir Medic 
595dde3d582SVladimir Medic   Inst.addOperand(MCOperand::CreateReg(Reg));
596dde3d582SVladimir Medic   Inst.addOperand(MCOperand::CreateReg(Base));
597dde3d582SVladimir Medic   Inst.addOperand(MCOperand::CreateImm(Offset));
598dde3d582SVladimir Medic 
599dde3d582SVladimir Medic   return MCDisassembler::Success;
600dde3d582SVladimir Medic }
601dde3d582SVladimir Medic 
60271928e68SAkira Hatanaka static DecodeStatus DecodeFMem(MCInst &Inst,
60371928e68SAkira Hatanaka                                unsigned Insn,
60471928e68SAkira Hatanaka                                uint64_t Address,
60571928e68SAkira Hatanaka                                const void *Decoder) {
60671928e68SAkira Hatanaka   int Offset = SignExtend32<16>(Insn & 0xffff);
607ecaef49fSJim Grosbach   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
608ecaef49fSJim Grosbach   unsigned Base = fieldFromInstruction(Insn, 21, 5);
60971928e68SAkira Hatanaka 
6109bf2b567SAkira Hatanaka   Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg);
61113e6ccf3SAkira Hatanaka   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
6129bf2b567SAkira Hatanaka 
6139bf2b567SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
6149bf2b567SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Base));
61571928e68SAkira Hatanaka   Inst.addOperand(MCOperand::CreateImm(Offset));
61671928e68SAkira Hatanaka 
61771928e68SAkira Hatanaka   return MCDisassembler::Success;
61871928e68SAkira Hatanaka }
61971928e68SAkira Hatanaka 
62071928e68SAkira Hatanaka 
62171928e68SAkira Hatanaka static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
62271928e68SAkira Hatanaka                                               unsigned RegNo,
62371928e68SAkira Hatanaka                                               uint64_t Address,
62471928e68SAkira Hatanaka                                               const void *Decoder) {
62571928e68SAkira Hatanaka   // Currently only hardware register 29 is supported.
62671928e68SAkira Hatanaka   if (RegNo != 29)
62771928e68SAkira Hatanaka     return  MCDisassembler::Fail;
62871928e68SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Mips::HWR29));
62971928e68SAkira Hatanaka   return MCDisassembler::Success;
63071928e68SAkira Hatanaka }
63171928e68SAkira Hatanaka 
63271928e68SAkira Hatanaka static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
63371928e68SAkira Hatanaka                                               unsigned RegNo,
63471928e68SAkira Hatanaka                                               uint64_t Address,
63571928e68SAkira Hatanaka                                               const void *Decoder) {
6369bf2b567SAkira Hatanaka   if (RegNo > 30 || RegNo %2)
63771928e68SAkira Hatanaka     return MCDisassembler::Fail;
63871928e68SAkira Hatanaka 
6399bf2b567SAkira Hatanaka   ;
6409bf2b567SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::AFGR64RegClassID, RegNo /2);
6419bf2b567SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
64271928e68SAkira Hatanaka   return MCDisassembler::Success;
64371928e68SAkira Hatanaka }
64471928e68SAkira Hatanaka 
64500fcf2e1SAkira Hatanaka static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst,
646ecabd1a5SAkira Hatanaka                                                 unsigned RegNo,
647ecabd1a5SAkira Hatanaka                                                 uint64_t Address,
648ecabd1a5SAkira Hatanaka                                                 const void *Decoder) {
649ecabd1a5SAkira Hatanaka   if (RegNo >= 4)
650ecabd1a5SAkira Hatanaka     return MCDisassembler::Fail;
651ecabd1a5SAkira Hatanaka 
65200fcf2e1SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::ACC64DSPRegClassID, RegNo);
653ecabd1a5SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
654ecabd1a5SAkira Hatanaka   return MCDisassembler::Success;
655ecabd1a5SAkira Hatanaka }
656ecabd1a5SAkira Hatanaka 
6578002a3f6SAkira Hatanaka static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst,
65859bfaf77SAkira Hatanaka                                                unsigned RegNo,
65959bfaf77SAkira Hatanaka                                                uint64_t Address,
66059bfaf77SAkira Hatanaka                                                const void *Decoder) {
66159bfaf77SAkira Hatanaka   if (RegNo >= 4)
66259bfaf77SAkira Hatanaka     return MCDisassembler::Fail;
66359bfaf77SAkira Hatanaka 
6648002a3f6SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::HI32DSPRegClassID, RegNo);
66559bfaf77SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
66659bfaf77SAkira Hatanaka   return MCDisassembler::Success;
66759bfaf77SAkira Hatanaka }
66859bfaf77SAkira Hatanaka 
6698002a3f6SAkira Hatanaka static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst,
67059bfaf77SAkira Hatanaka                                                unsigned RegNo,
67159bfaf77SAkira Hatanaka                                                uint64_t Address,
67259bfaf77SAkira Hatanaka                                                const void *Decoder) {
67359bfaf77SAkira Hatanaka   if (RegNo >= 4)
67459bfaf77SAkira Hatanaka     return MCDisassembler::Fail;
67559bfaf77SAkira Hatanaka 
6768002a3f6SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::LO32DSPRegClassID, RegNo);
67759bfaf77SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
67859bfaf77SAkira Hatanaka   return MCDisassembler::Success;
67959bfaf77SAkira Hatanaka }
68059bfaf77SAkira Hatanaka 
6813eb663b0SJack Carter static DecodeStatus DecodeMSA128BRegisterClass(MCInst &Inst,
6823eb663b0SJack Carter                                                unsigned RegNo,
6833eb663b0SJack Carter                                                uint64_t Address,
6843eb663b0SJack Carter                                                const void *Decoder) {
6853eb663b0SJack Carter   if (RegNo > 31)
6863eb663b0SJack Carter     return MCDisassembler::Fail;
6873eb663b0SJack Carter 
6883eb663b0SJack Carter   unsigned Reg = getReg(Decoder, Mips::MSA128BRegClassID, RegNo);
6893eb663b0SJack Carter   Inst.addOperand(MCOperand::CreateReg(Reg));
6903eb663b0SJack Carter   return MCDisassembler::Success;
6913eb663b0SJack Carter }
6923eb663b0SJack Carter 
6935dc8ac92SJack Carter static DecodeStatus DecodeMSA128HRegisterClass(MCInst &Inst,
6945dc8ac92SJack Carter                                                unsigned RegNo,
6955dc8ac92SJack Carter                                                uint64_t Address,
6965dc8ac92SJack Carter                                                const void *Decoder) {
6975dc8ac92SJack Carter   if (RegNo > 31)
6985dc8ac92SJack Carter     return MCDisassembler::Fail;
6995dc8ac92SJack Carter 
7005dc8ac92SJack Carter   unsigned Reg = getReg(Decoder, Mips::MSA128HRegClassID, RegNo);
7015dc8ac92SJack Carter   Inst.addOperand(MCOperand::CreateReg(Reg));
7025dc8ac92SJack Carter   return MCDisassembler::Success;
7035dc8ac92SJack Carter }
7045dc8ac92SJack Carter 
7055dc8ac92SJack Carter static DecodeStatus DecodeMSA128WRegisterClass(MCInst &Inst,
7065dc8ac92SJack Carter                                                unsigned RegNo,
7075dc8ac92SJack Carter                                                uint64_t Address,
7085dc8ac92SJack Carter                                                const void *Decoder) {
7095dc8ac92SJack Carter   if (RegNo > 31)
7105dc8ac92SJack Carter     return MCDisassembler::Fail;
7115dc8ac92SJack Carter 
7125dc8ac92SJack Carter   unsigned Reg = getReg(Decoder, Mips::MSA128WRegClassID, RegNo);
7135dc8ac92SJack Carter   Inst.addOperand(MCOperand::CreateReg(Reg));
7145dc8ac92SJack Carter   return MCDisassembler::Success;
7155dc8ac92SJack Carter }
7165dc8ac92SJack Carter 
7175dc8ac92SJack Carter static DecodeStatus DecodeMSA128DRegisterClass(MCInst &Inst,
7185dc8ac92SJack Carter                                                unsigned RegNo,
7195dc8ac92SJack Carter                                                uint64_t Address,
7205dc8ac92SJack Carter                                                const void *Decoder) {
7215dc8ac92SJack Carter   if (RegNo > 31)
7225dc8ac92SJack Carter     return MCDisassembler::Fail;
7235dc8ac92SJack Carter 
7245dc8ac92SJack Carter   unsigned Reg = getReg(Decoder, Mips::MSA128DRegClassID, RegNo);
7255dc8ac92SJack Carter   Inst.addOperand(MCOperand::CreateReg(Reg));
7265dc8ac92SJack Carter   return MCDisassembler::Success;
7275dc8ac92SJack Carter }
7285dc8ac92SJack Carter 
729a591fdc6SMatheus Almeida static DecodeStatus DecodeMSACtrlRegisterClass(MCInst &Inst,
730a591fdc6SMatheus Almeida                                                unsigned RegNo,
731a591fdc6SMatheus Almeida                                                uint64_t Address,
732a591fdc6SMatheus Almeida                                                const void *Decoder) {
733a591fdc6SMatheus Almeida   if (RegNo > 7)
734a591fdc6SMatheus Almeida     return MCDisassembler::Fail;
735a591fdc6SMatheus Almeida 
736a591fdc6SMatheus Almeida   unsigned Reg = getReg(Decoder, Mips::MSACtrlRegClassID, RegNo);
737a591fdc6SMatheus Almeida   Inst.addOperand(MCOperand::CreateReg(Reg));
738a591fdc6SMatheus Almeida   return MCDisassembler::Success;
739a591fdc6SMatheus Almeida }
740a591fdc6SMatheus Almeida 
74171928e68SAkira Hatanaka static DecodeStatus DecodeBranchTarget(MCInst &Inst,
74271928e68SAkira Hatanaka                                        unsigned Offset,
74371928e68SAkira Hatanaka                                        uint64_t Address,
74471928e68SAkira Hatanaka                                        const void *Decoder) {
74571928e68SAkira Hatanaka   unsigned BranchOffset = Offset & 0xffff;
74671928e68SAkira Hatanaka   BranchOffset = SignExtend32<18>(BranchOffset << 2) + 4;
74771928e68SAkira Hatanaka   Inst.addOperand(MCOperand::CreateImm(BranchOffset));
74871928e68SAkira Hatanaka   return MCDisassembler::Success;
74971928e68SAkira Hatanaka }
75071928e68SAkira Hatanaka 
75171928e68SAkira Hatanaka static DecodeStatus DecodeJumpTarget(MCInst &Inst,
75271928e68SAkira Hatanaka                                      unsigned Insn,
75371928e68SAkira Hatanaka                                      uint64_t Address,
75471928e68SAkira Hatanaka                                      const void *Decoder) {
75571928e68SAkira Hatanaka 
756ecaef49fSJim Grosbach   unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 2;
75771928e68SAkira Hatanaka   Inst.addOperand(MCOperand::CreateImm(JumpOffset));
75871928e68SAkira Hatanaka   return MCDisassembler::Success;
75971928e68SAkira Hatanaka }
76071928e68SAkira Hatanaka 
761*8a80aa76SZoran Jovanovic static DecodeStatus DecodeBranchTargetMM(MCInst &Inst,
762*8a80aa76SZoran Jovanovic                                          unsigned Offset,
763*8a80aa76SZoran Jovanovic                                          uint64_t Address,
764*8a80aa76SZoran Jovanovic                                          const void *Decoder) {
765*8a80aa76SZoran Jovanovic   unsigned BranchOffset = Offset & 0xffff;
766*8a80aa76SZoran Jovanovic   BranchOffset = SignExtend32<18>(BranchOffset << 1);
767*8a80aa76SZoran Jovanovic   Inst.addOperand(MCOperand::CreateImm(BranchOffset));
768*8a80aa76SZoran Jovanovic   return MCDisassembler::Success;
769*8a80aa76SZoran Jovanovic }
770*8a80aa76SZoran Jovanovic 
771507e084aSZoran Jovanovic static DecodeStatus DecodeJumpTargetMM(MCInst &Inst,
772507e084aSZoran Jovanovic                                        unsigned Insn,
773507e084aSZoran Jovanovic                                        uint64_t Address,
774507e084aSZoran Jovanovic                                        const void *Decoder) {
775507e084aSZoran Jovanovic   unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 1;
776507e084aSZoran Jovanovic   Inst.addOperand(MCOperand::CreateImm(JumpOffset));
777507e084aSZoran Jovanovic   return MCDisassembler::Success;
778507e084aSZoran Jovanovic }
77971928e68SAkira Hatanaka 
78071928e68SAkira Hatanaka static DecodeStatus DecodeSimm16(MCInst &Inst,
78171928e68SAkira Hatanaka                                  unsigned Insn,
78271928e68SAkira Hatanaka                                  uint64_t Address,
78371928e68SAkira Hatanaka                                  const void *Decoder) {
78471928e68SAkira Hatanaka   Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Insn)));
78571928e68SAkira Hatanaka   return MCDisassembler::Success;
78671928e68SAkira Hatanaka }
78771928e68SAkira Hatanaka 
78871928e68SAkira Hatanaka static DecodeStatus DecodeInsSize(MCInst &Inst,
78971928e68SAkira Hatanaka                                   unsigned Insn,
79071928e68SAkira Hatanaka                                   uint64_t Address,
79171928e68SAkira Hatanaka                                   const void *Decoder) {
79271928e68SAkira Hatanaka   // First we need to grab the pos(lsb) from MCInst.
79371928e68SAkira Hatanaka   int Pos = Inst.getOperand(2).getImm();
79471928e68SAkira Hatanaka   int Size = (int) Insn - Pos + 1;
79571928e68SAkira Hatanaka   Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size)));
79671928e68SAkira Hatanaka   return MCDisassembler::Success;
79771928e68SAkira Hatanaka }
79871928e68SAkira Hatanaka 
79971928e68SAkira Hatanaka static DecodeStatus DecodeExtSize(MCInst &Inst,
80071928e68SAkira Hatanaka                                   unsigned Insn,
80171928e68SAkira Hatanaka                                   uint64_t Address,
80271928e68SAkira Hatanaka                                   const void *Decoder) {
80371928e68SAkira Hatanaka   int Size = (int) Insn  + 1;
80471928e68SAkira Hatanaka   Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size)));
80571928e68SAkira Hatanaka   return MCDisassembler::Success;
80671928e68SAkira Hatanaka }
807