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 
2088a80aa76SZoran Jovanovic // DecodeBranchTargetMM - Decode microMIPS branch offset, which is
2098a80aa76SZoran Jovanovic // shifted left by 1 bit.
2108a80aa76SZoran Jovanovic static DecodeStatus DecodeBranchTargetMM(MCInst &Inst,
2118a80aa76SZoran Jovanovic                                          unsigned Offset,
2128a80aa76SZoran Jovanovic                                          uint64_t Address,
2138a80aa76SZoran Jovanovic                                          const void *Decoder);
2148a80aa76SZoran 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 
249779c5937SMatheus Almeida // Decode the immediate field of an LSA instruction which
250779c5937SMatheus Almeida // is off by one.
251779c5937SMatheus Almeida static DecodeStatus DecodeLSAImm(MCInst &Inst,
252779c5937SMatheus Almeida                                  unsigned Insn,
253779c5937SMatheus Almeida                                  uint64_t Address,
254779c5937SMatheus Almeida                                  const void *Decoder);
255779c5937SMatheus Almeida 
25671928e68SAkira Hatanaka static DecodeStatus DecodeInsSize(MCInst &Inst,
25771928e68SAkira Hatanaka                                   unsigned Insn,
25871928e68SAkira Hatanaka                                   uint64_t Address,
25971928e68SAkira Hatanaka                                   const void *Decoder);
26071928e68SAkira Hatanaka 
26171928e68SAkira Hatanaka static DecodeStatus DecodeExtSize(MCInst &Inst,
26271928e68SAkira Hatanaka                                   unsigned Insn,
26371928e68SAkira Hatanaka                                   uint64_t Address,
26471928e68SAkira Hatanaka                                   const void *Decoder);
26571928e68SAkira Hatanaka 
26671928e68SAkira Hatanaka namespace llvm {
26771928e68SAkira Hatanaka extern Target TheMipselTarget, TheMipsTarget, TheMips64Target,
26871928e68SAkira Hatanaka               TheMips64elTarget;
26971928e68SAkira Hatanaka }
27071928e68SAkira Hatanaka 
27171928e68SAkira Hatanaka static MCDisassembler *createMipsDisassembler(
27271928e68SAkira Hatanaka                        const Target &T,
27371928e68SAkira Hatanaka                        const MCSubtargetInfo &STI) {
2749bf2b567SAkira Hatanaka   return new MipsDisassembler(STI, T.createMCRegInfo(""), true);
27571928e68SAkira Hatanaka }
27671928e68SAkira Hatanaka 
27771928e68SAkira Hatanaka static MCDisassembler *createMipselDisassembler(
27871928e68SAkira Hatanaka                        const Target &T,
27971928e68SAkira Hatanaka                        const MCSubtargetInfo &STI) {
2809bf2b567SAkira Hatanaka   return new MipsDisassembler(STI, T.createMCRegInfo(""), false);
28171928e68SAkira Hatanaka }
28271928e68SAkira Hatanaka 
28371928e68SAkira Hatanaka static MCDisassembler *createMips64Disassembler(
28471928e68SAkira Hatanaka                        const Target &T,
28571928e68SAkira Hatanaka                        const MCSubtargetInfo &STI) {
2869bf2b567SAkira Hatanaka   return new Mips64Disassembler(STI, T.createMCRegInfo(""), true);
28771928e68SAkira Hatanaka }
28871928e68SAkira Hatanaka 
28971928e68SAkira Hatanaka static MCDisassembler *createMips64elDisassembler(
29071928e68SAkira Hatanaka                        const Target &T,
29171928e68SAkira Hatanaka                        const MCSubtargetInfo &STI) {
2929bf2b567SAkira Hatanaka   return new Mips64Disassembler(STI, T.createMCRegInfo(""), false);
29371928e68SAkira Hatanaka }
29471928e68SAkira Hatanaka 
29571928e68SAkira Hatanaka extern "C" void LLVMInitializeMipsDisassembler() {
29671928e68SAkira Hatanaka   // Register the disassembler.
29771928e68SAkira Hatanaka   TargetRegistry::RegisterMCDisassembler(TheMipsTarget,
29871928e68SAkira Hatanaka                                          createMipsDisassembler);
29971928e68SAkira Hatanaka   TargetRegistry::RegisterMCDisassembler(TheMipselTarget,
30071928e68SAkira Hatanaka                                          createMipselDisassembler);
30171928e68SAkira Hatanaka   TargetRegistry::RegisterMCDisassembler(TheMips64Target,
30271928e68SAkira Hatanaka                                          createMips64Disassembler);
30371928e68SAkira Hatanaka   TargetRegistry::RegisterMCDisassembler(TheMips64elTarget,
30471928e68SAkira Hatanaka                                          createMips64elDisassembler);
30571928e68SAkira Hatanaka }
30671928e68SAkira Hatanaka 
30771928e68SAkira Hatanaka 
30871928e68SAkira Hatanaka #include "MipsGenDisassemblerTables.inc"
30971928e68SAkira Hatanaka 
31071928e68SAkira Hatanaka   /// readInstruction - read four bytes from the MemoryObject
31171928e68SAkira Hatanaka   /// and return 32 bit word sorted according to the given endianess
31271928e68SAkira Hatanaka static DecodeStatus readInstruction32(const MemoryObject &region,
31371928e68SAkira Hatanaka                                       uint64_t address,
31471928e68SAkira Hatanaka                                       uint64_t &size,
31571928e68SAkira Hatanaka                                       uint32_t &insn,
316dde3d582SVladimir Medic                                       bool isBigEndian,
317dde3d582SVladimir Medic                                       bool IsMicroMips) {
31871928e68SAkira Hatanaka   uint8_t Bytes[4];
31971928e68SAkira Hatanaka 
32071928e68SAkira Hatanaka   // We want to read exactly 4 Bytes of data.
321534d3a46SBenjamin Kramer   if (region.readBytes(address, 4, Bytes) == -1) {
32271928e68SAkira Hatanaka     size = 0;
32371928e68SAkira Hatanaka     return MCDisassembler::Fail;
32471928e68SAkira Hatanaka   }
32571928e68SAkira Hatanaka 
32671928e68SAkira Hatanaka   if (isBigEndian) {
32771928e68SAkira Hatanaka     // Encoded as a big-endian 32-bit word in the stream.
32871928e68SAkira Hatanaka     insn = (Bytes[3] <<  0) |
32971928e68SAkira Hatanaka            (Bytes[2] <<  8) |
33071928e68SAkira Hatanaka            (Bytes[1] << 16) |
33171928e68SAkira Hatanaka            (Bytes[0] << 24);
33271928e68SAkira Hatanaka   }
33371928e68SAkira Hatanaka   else {
33471928e68SAkira Hatanaka     // Encoded as a small-endian 32-bit word in the stream.
335dde3d582SVladimir Medic     // Little-endian byte ordering:
336dde3d582SVladimir Medic     //   mips32r2:   4 | 3 | 2 | 1
337dde3d582SVladimir Medic     //   microMIPS:  2 | 1 | 4 | 3
338dde3d582SVladimir Medic     if (IsMicroMips) {
339dde3d582SVladimir Medic       insn = (Bytes[2] <<  0) |
340dde3d582SVladimir Medic              (Bytes[3] <<  8) |
341dde3d582SVladimir Medic              (Bytes[0] << 16) |
342dde3d582SVladimir Medic              (Bytes[1] << 24);
343dde3d582SVladimir Medic     } else {
34471928e68SAkira Hatanaka       insn = (Bytes[0] <<  0) |
34571928e68SAkira Hatanaka              (Bytes[1] <<  8) |
34671928e68SAkira Hatanaka              (Bytes[2] << 16) |
34771928e68SAkira Hatanaka              (Bytes[3] << 24);
34871928e68SAkira Hatanaka     }
349dde3d582SVladimir Medic   }
35071928e68SAkira Hatanaka 
35171928e68SAkira Hatanaka   return MCDisassembler::Success;
35271928e68SAkira Hatanaka }
35371928e68SAkira Hatanaka 
35471928e68SAkira Hatanaka DecodeStatus
35571928e68SAkira Hatanaka MipsDisassembler::getInstruction(MCInst &instr,
35671928e68SAkira Hatanaka                                  uint64_t &Size,
35771928e68SAkira Hatanaka                                  const MemoryObject &Region,
35871928e68SAkira Hatanaka                                  uint64_t Address,
35971928e68SAkira Hatanaka                                  raw_ostream &vStream,
36071928e68SAkira Hatanaka                                  raw_ostream &cStream) const {
36171928e68SAkira Hatanaka   uint32_t Insn;
36271928e68SAkira Hatanaka 
36371928e68SAkira Hatanaka   DecodeStatus Result = readInstruction32(Region, Address, Size,
364dde3d582SVladimir Medic                                           Insn, isBigEndian, IsMicroMips);
36571928e68SAkira Hatanaka   if (Result == MCDisassembler::Fail)
36671928e68SAkira Hatanaka     return MCDisassembler::Fail;
36771928e68SAkira Hatanaka 
368dde3d582SVladimir Medic   if (IsMicroMips) {
369dde3d582SVladimir Medic     // Calling the auto-generated decoder function.
370dde3d582SVladimir Medic     Result = decodeInstruction(DecoderTableMicroMips32, instr, Insn, Address,
371dde3d582SVladimir Medic                                this, STI);
372dde3d582SVladimir Medic     if (Result != MCDisassembler::Fail) {
373dde3d582SVladimir Medic       Size = 4;
374dde3d582SVladimir Medic       return Result;
375dde3d582SVladimir Medic     }
376dde3d582SVladimir Medic     return MCDisassembler::Fail;
377dde3d582SVladimir Medic   }
378dde3d582SVladimir Medic 
37971928e68SAkira Hatanaka   // Calling the auto-generated decoder function.
380ecaef49fSJim Grosbach   Result = decodeInstruction(DecoderTableMips32, instr, Insn, Address,
381ecaef49fSJim Grosbach                              this, STI);
38271928e68SAkira Hatanaka   if (Result != MCDisassembler::Fail) {
38371928e68SAkira Hatanaka     Size = 4;
38471928e68SAkira Hatanaka     return Result;
38571928e68SAkira Hatanaka   }
38671928e68SAkira Hatanaka 
38771928e68SAkira Hatanaka   return MCDisassembler::Fail;
38871928e68SAkira Hatanaka }
38971928e68SAkira Hatanaka 
39071928e68SAkira Hatanaka DecodeStatus
39171928e68SAkira Hatanaka Mips64Disassembler::getInstruction(MCInst &instr,
39271928e68SAkira Hatanaka                                    uint64_t &Size,
39371928e68SAkira Hatanaka                                    const MemoryObject &Region,
39471928e68SAkira Hatanaka                                    uint64_t Address,
39571928e68SAkira Hatanaka                                    raw_ostream &vStream,
39671928e68SAkira Hatanaka                                    raw_ostream &cStream) const {
39771928e68SAkira Hatanaka   uint32_t Insn;
39871928e68SAkira Hatanaka 
39971928e68SAkira Hatanaka   DecodeStatus Result = readInstruction32(Region, Address, Size,
400dde3d582SVladimir Medic                                           Insn, isBigEndian, false);
40171928e68SAkira Hatanaka   if (Result == MCDisassembler::Fail)
40271928e68SAkira Hatanaka     return MCDisassembler::Fail;
40371928e68SAkira Hatanaka 
40471928e68SAkira Hatanaka   // Calling the auto-generated decoder function.
405ecaef49fSJim Grosbach   Result = decodeInstruction(DecoderTableMips6432, 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   // If we fail to decode in Mips64 decoder space we can try in Mips32
412ecaef49fSJim Grosbach   Result = decodeInstruction(DecoderTableMips32, instr, Insn, Address,
413ecaef49fSJim Grosbach                              this, STI);
41471928e68SAkira Hatanaka   if (Result != MCDisassembler::Fail) {
41571928e68SAkira Hatanaka     Size = 4;
41671928e68SAkira Hatanaka     return Result;
41771928e68SAkira Hatanaka   }
41871928e68SAkira Hatanaka 
41971928e68SAkira Hatanaka   return MCDisassembler::Fail;
42071928e68SAkira Hatanaka }
42171928e68SAkira Hatanaka 
4229bf2b567SAkira Hatanaka static unsigned getReg(const void *D, unsigned RC, unsigned RegNo) {
4239bf2b567SAkira Hatanaka   const MipsDisassemblerBase *Dis = static_cast<const MipsDisassemblerBase*>(D);
4249bf2b567SAkira Hatanaka   return *(Dis->getRegInfo()->getRegClass(RC).begin() + RegNo);
4259bf2b567SAkira Hatanaka }
4269bf2b567SAkira Hatanaka 
427ec8a5490SReed Kotler static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst,
428ec8a5490SReed Kotler                                                  unsigned RegNo,
429ec8a5490SReed Kotler                                                  uint64_t Address,
430ec8a5490SReed Kotler                                                  const void *Decoder) {
431ec8a5490SReed Kotler 
432ec8a5490SReed Kotler   return MCDisassembler::Fail;
433ec8a5490SReed Kotler 
434ec8a5490SReed Kotler }
435ec8a5490SReed Kotler 
43613e6ccf3SAkira Hatanaka static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst,
43771928e68SAkira Hatanaka                                              unsigned RegNo,
43871928e68SAkira Hatanaka                                              uint64_t Address,
43971928e68SAkira Hatanaka                                              const void *Decoder) {
44071928e68SAkira Hatanaka 
44171928e68SAkira Hatanaka   if (RegNo > 31)
44271928e68SAkira Hatanaka     return MCDisassembler::Fail;
44371928e68SAkira Hatanaka 
44413e6ccf3SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::GPR64RegClassID, RegNo);
4459bf2b567SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
44671928e68SAkira Hatanaka   return MCDisassembler::Success;
44771928e68SAkira Hatanaka }
44871928e68SAkira Hatanaka 
44913e6ccf3SAkira Hatanaka static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst,
45071928e68SAkira Hatanaka                                              unsigned RegNo,
45171928e68SAkira Hatanaka                                              uint64_t Address,
45271928e68SAkira Hatanaka                                              const void *Decoder) {
45371928e68SAkira Hatanaka   if (RegNo > 31)
45471928e68SAkira Hatanaka     return MCDisassembler::Fail;
45513e6ccf3SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::GPR32RegClassID, RegNo);
4569bf2b567SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
45771928e68SAkira Hatanaka   return MCDisassembler::Success;
45871928e68SAkira Hatanaka }
45971928e68SAkira Hatanaka 
4609bfa2e2eSAkira Hatanaka static DecodeStatus DecodePtrRegisterClass(MCInst &Inst,
4619bfa2e2eSAkira Hatanaka                                            unsigned RegNo,
4629bfa2e2eSAkira Hatanaka                                            uint64_t Address,
4639bfa2e2eSAkira Hatanaka                                            const void *Decoder) {
4649bfa2e2eSAkira Hatanaka   if (static_cast<const MipsDisassembler *>(Decoder)->isN64())
4659bfa2e2eSAkira Hatanaka     return DecodeGPR64RegisterClass(Inst, RegNo, Address, Decoder);
4669bfa2e2eSAkira Hatanaka 
4679bfa2e2eSAkira Hatanaka   return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
4689bfa2e2eSAkira Hatanaka }
4699bfa2e2eSAkira Hatanaka 
470654655f1SAkira Hatanaka static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst,
471ecabd1a5SAkira Hatanaka                                             unsigned RegNo,
472ecabd1a5SAkira Hatanaka                                             uint64_t Address,
473ecabd1a5SAkira Hatanaka                                             const void *Decoder) {
47413e6ccf3SAkira Hatanaka   return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
475ecabd1a5SAkira Hatanaka }
476ecabd1a5SAkira Hatanaka 
47771928e68SAkira Hatanaka static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
47871928e68SAkira Hatanaka                                              unsigned RegNo,
47971928e68SAkira Hatanaka                                              uint64_t Address,
48071928e68SAkira Hatanaka                                              const void *Decoder) {
48171928e68SAkira Hatanaka   if (RegNo > 31)
48271928e68SAkira Hatanaka     return MCDisassembler::Fail;
48371928e68SAkira Hatanaka 
4849bf2b567SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::FGR64RegClassID, RegNo);
4859bf2b567SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
48671928e68SAkira Hatanaka   return MCDisassembler::Success;
48771928e68SAkira Hatanaka }
48871928e68SAkira Hatanaka 
48971928e68SAkira Hatanaka static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
49071928e68SAkira Hatanaka                                              unsigned RegNo,
49171928e68SAkira Hatanaka                                              uint64_t Address,
49271928e68SAkira Hatanaka                                              const void *Decoder) {
49371928e68SAkira Hatanaka   if (RegNo > 31)
49471928e68SAkira Hatanaka     return MCDisassembler::Fail;
49571928e68SAkira Hatanaka 
4969bf2b567SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::FGR32RegClassID, RegNo);
4979bf2b567SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
49871928e68SAkira Hatanaka   return MCDisassembler::Success;
49971928e68SAkira Hatanaka }
50071928e68SAkira Hatanaka 
50114e31a2fSAkira Hatanaka static DecodeStatus DecodeFGRH32RegisterClass(MCInst &Inst,
50214e31a2fSAkira Hatanaka                                               unsigned RegNo,
50314e31a2fSAkira Hatanaka                                               uint64_t Address,
50414e31a2fSAkira Hatanaka                                               const void *Decoder) {
50514e31a2fSAkira Hatanaka   if (RegNo > 31)
50614e31a2fSAkira Hatanaka     return MCDisassembler::Fail;
50714e31a2fSAkira Hatanaka 
50814e31a2fSAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::FGRH32RegClassID, RegNo);
50914e31a2fSAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
51014e31a2fSAkira Hatanaka   return MCDisassembler::Success;
51114e31a2fSAkira Hatanaka }
51214e31a2fSAkira Hatanaka 
51371928e68SAkira Hatanaka static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
51471928e68SAkira Hatanaka                                            unsigned RegNo,
51571928e68SAkira Hatanaka                                            uint64_t Address,
51671928e68SAkira Hatanaka                                            const void *Decoder) {
517253777fdSChad Rosier   if (RegNo > 31)
518253777fdSChad Rosier     return MCDisassembler::Fail;
519253777fdSChad Rosier   unsigned Reg = getReg(Decoder, Mips::CCRRegClassID, RegNo);
520253777fdSChad Rosier   Inst.addOperand(MCOperand::CreateReg(Reg));
52171928e68SAkira Hatanaka   return MCDisassembler::Success;
52271928e68SAkira Hatanaka }
52371928e68SAkira Hatanaka 
5241fb1b8b8SAkira Hatanaka static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst,
5251fb1b8b8SAkira Hatanaka                                            unsigned RegNo,
5261fb1b8b8SAkira Hatanaka                                            uint64_t Address,
5271fb1b8b8SAkira Hatanaka                                            const void *Decoder) {
5281fb1b8b8SAkira Hatanaka   if (RegNo > 7)
5291fb1b8b8SAkira Hatanaka     return MCDisassembler::Fail;
5301fb1b8b8SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::FCCRegClassID, RegNo);
5311fb1b8b8SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
5321fb1b8b8SAkira Hatanaka   return MCDisassembler::Success;
5331fb1b8b8SAkira Hatanaka }
5341fb1b8b8SAkira Hatanaka 
53571928e68SAkira Hatanaka static DecodeStatus DecodeMem(MCInst &Inst,
53671928e68SAkira Hatanaka                               unsigned Insn,
53771928e68SAkira Hatanaka                               uint64_t Address,
53871928e68SAkira Hatanaka                               const void *Decoder) {
53971928e68SAkira Hatanaka   int Offset = SignExtend32<16>(Insn & 0xffff);
540ecaef49fSJim Grosbach   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
541ecaef49fSJim Grosbach   unsigned Base = fieldFromInstruction(Insn, 21, 5);
5429bf2b567SAkira Hatanaka 
54313e6ccf3SAkira Hatanaka   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
54413e6ccf3SAkira Hatanaka   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
54571928e68SAkira Hatanaka 
54671928e68SAkira Hatanaka   if(Inst.getOpcode() == Mips::SC){
5479bf2b567SAkira Hatanaka     Inst.addOperand(MCOperand::CreateReg(Reg));
54871928e68SAkira Hatanaka   }
54971928e68SAkira Hatanaka 
5509bf2b567SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
5519bf2b567SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Base));
55271928e68SAkira Hatanaka   Inst.addOperand(MCOperand::CreateImm(Offset));
55371928e68SAkira Hatanaka 
55471928e68SAkira Hatanaka   return MCDisassembler::Success;
55571928e68SAkira Hatanaka }
55671928e68SAkira Hatanaka 
557fe0bf9f6SMatheus Almeida static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn,
558fe0bf9f6SMatheus Almeida                                     uint64_t Address, const void *Decoder) {
559fe0bf9f6SMatheus Almeida   int Offset = SignExtend32<10>(fieldFromInstruction(Insn, 16, 10));
560fe0bf9f6SMatheus Almeida   unsigned Reg = fieldFromInstruction(Insn, 6, 5);
561fe0bf9f6SMatheus Almeida   unsigned Base = fieldFromInstruction(Insn, 11, 5);
562fe0bf9f6SMatheus Almeida 
563fe0bf9f6SMatheus Almeida   Reg = getReg(Decoder, Mips::MSA128BRegClassID, Reg);
564fe0bf9f6SMatheus Almeida   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
565fe0bf9f6SMatheus Almeida 
566fe0bf9f6SMatheus Almeida   Inst.addOperand(MCOperand::CreateReg(Reg));
567fe0bf9f6SMatheus Almeida   Inst.addOperand(MCOperand::CreateReg(Base));
5686b59c449SMatheus Almeida 
5696b59c449SMatheus Almeida   // The immediate field of an LD/ST instruction is scaled which means it must
5706b59c449SMatheus Almeida   // be multiplied (when decoding) by the size (in bytes) of the instructions'
5716b59c449SMatheus Almeida   // data format.
5726b59c449SMatheus Almeida   // .b - 1 byte
5736b59c449SMatheus Almeida   // .h - 2 bytes
5746b59c449SMatheus Almeida   // .w - 4 bytes
5756b59c449SMatheus Almeida   // .d - 8 bytes
5766b59c449SMatheus Almeida   switch(Inst.getOpcode())
5776b59c449SMatheus Almeida   {
5786b59c449SMatheus Almeida   default:
5796b59c449SMatheus Almeida     assert (0 && "Unexpected instruction");
5806b59c449SMatheus Almeida     return MCDisassembler::Fail;
5816b59c449SMatheus Almeida     break;
5826b59c449SMatheus Almeida   case Mips::LD_B:
5836b59c449SMatheus Almeida   case Mips::ST_B:
584fe0bf9f6SMatheus Almeida     Inst.addOperand(MCOperand::CreateImm(Offset));
5856b59c449SMatheus Almeida     break;
5866b59c449SMatheus Almeida   case Mips::LD_H:
5876b59c449SMatheus Almeida   case Mips::ST_H:
5886b59c449SMatheus Almeida     Inst.addOperand(MCOperand::CreateImm(Offset << 1));
5896b59c449SMatheus Almeida     break;
5906b59c449SMatheus Almeida   case Mips::LD_W:
5916b59c449SMatheus Almeida   case Mips::ST_W:
5926b59c449SMatheus Almeida     Inst.addOperand(MCOperand::CreateImm(Offset << 2));
5936b59c449SMatheus Almeida     break;
5946b59c449SMatheus Almeida   case Mips::LD_D:
5956b59c449SMatheus Almeida   case Mips::ST_D:
5966b59c449SMatheus Almeida     Inst.addOperand(MCOperand::CreateImm(Offset << 3));
5976b59c449SMatheus Almeida     break;
5986b59c449SMatheus Almeida   }
599fe0bf9f6SMatheus Almeida 
600fe0bf9f6SMatheus Almeida   return MCDisassembler::Success;
601fe0bf9f6SMatheus Almeida }
602fe0bf9f6SMatheus Almeida 
603dde3d582SVladimir Medic static DecodeStatus DecodeMemMMImm12(MCInst &Inst,
604dde3d582SVladimir Medic                                      unsigned Insn,
605dde3d582SVladimir Medic                                      uint64_t Address,
606dde3d582SVladimir Medic                                      const void *Decoder) {
607dde3d582SVladimir Medic   int Offset = SignExtend32<12>(Insn & 0x0fff);
608dde3d582SVladimir Medic   unsigned Reg = fieldFromInstruction(Insn, 21, 5);
609dde3d582SVladimir Medic   unsigned Base = fieldFromInstruction(Insn, 16, 5);
610dde3d582SVladimir Medic 
611dde3d582SVladimir Medic   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
612dde3d582SVladimir Medic   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
613dde3d582SVladimir Medic 
614*285cc289SZoran Jovanovic   if (Inst.getOpcode() == Mips::SC_MM)
615*285cc289SZoran Jovanovic     Inst.addOperand(MCOperand::CreateReg(Reg));
616*285cc289SZoran Jovanovic 
617dde3d582SVladimir Medic   Inst.addOperand(MCOperand::CreateReg(Reg));
618dde3d582SVladimir Medic   Inst.addOperand(MCOperand::CreateReg(Base));
619dde3d582SVladimir Medic   Inst.addOperand(MCOperand::CreateImm(Offset));
620dde3d582SVladimir Medic 
621dde3d582SVladimir Medic   return MCDisassembler::Success;
622dde3d582SVladimir Medic }
623dde3d582SVladimir Medic 
624dde3d582SVladimir Medic static DecodeStatus DecodeMemMMImm16(MCInst &Inst,
625dde3d582SVladimir Medic                                      unsigned Insn,
626dde3d582SVladimir Medic                                      uint64_t Address,
627dde3d582SVladimir Medic                                      const void *Decoder) {
628dde3d582SVladimir Medic   int Offset = SignExtend32<16>(Insn & 0xffff);
629dde3d582SVladimir Medic   unsigned Reg = fieldFromInstruction(Insn, 21, 5);
630dde3d582SVladimir Medic   unsigned Base = fieldFromInstruction(Insn, 16, 5);
631dde3d582SVladimir Medic 
632dde3d582SVladimir Medic   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
633dde3d582SVladimir Medic   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
634dde3d582SVladimir Medic 
635dde3d582SVladimir Medic   Inst.addOperand(MCOperand::CreateReg(Reg));
636dde3d582SVladimir Medic   Inst.addOperand(MCOperand::CreateReg(Base));
637dde3d582SVladimir Medic   Inst.addOperand(MCOperand::CreateImm(Offset));
638dde3d582SVladimir Medic 
639dde3d582SVladimir Medic   return MCDisassembler::Success;
640dde3d582SVladimir Medic }
641dde3d582SVladimir Medic 
64271928e68SAkira Hatanaka static DecodeStatus DecodeFMem(MCInst &Inst,
64371928e68SAkira Hatanaka                                unsigned Insn,
64471928e68SAkira Hatanaka                                uint64_t Address,
64571928e68SAkira Hatanaka                                const void *Decoder) {
64671928e68SAkira Hatanaka   int Offset = SignExtend32<16>(Insn & 0xffff);
647ecaef49fSJim Grosbach   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
648ecaef49fSJim Grosbach   unsigned Base = fieldFromInstruction(Insn, 21, 5);
64971928e68SAkira Hatanaka 
6509bf2b567SAkira Hatanaka   Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg);
65113e6ccf3SAkira Hatanaka   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
6529bf2b567SAkira Hatanaka 
6539bf2b567SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
6549bf2b567SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Base));
65571928e68SAkira Hatanaka   Inst.addOperand(MCOperand::CreateImm(Offset));
65671928e68SAkira Hatanaka 
65771928e68SAkira Hatanaka   return MCDisassembler::Success;
65871928e68SAkira Hatanaka }
65971928e68SAkira Hatanaka 
66071928e68SAkira Hatanaka 
66171928e68SAkira Hatanaka static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
66271928e68SAkira Hatanaka                                               unsigned RegNo,
66371928e68SAkira Hatanaka                                               uint64_t Address,
66471928e68SAkira Hatanaka                                               const void *Decoder) {
66571928e68SAkira Hatanaka   // Currently only hardware register 29 is supported.
66671928e68SAkira Hatanaka   if (RegNo != 29)
66771928e68SAkira Hatanaka     return  MCDisassembler::Fail;
66871928e68SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Mips::HWR29));
66971928e68SAkira Hatanaka   return MCDisassembler::Success;
67071928e68SAkira Hatanaka }
67171928e68SAkira Hatanaka 
67271928e68SAkira Hatanaka static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
67371928e68SAkira Hatanaka                                               unsigned RegNo,
67471928e68SAkira Hatanaka                                               uint64_t Address,
67571928e68SAkira Hatanaka                                               const void *Decoder) {
6769bf2b567SAkira Hatanaka   if (RegNo > 30 || RegNo %2)
67771928e68SAkira Hatanaka     return MCDisassembler::Fail;
67871928e68SAkira Hatanaka 
6799bf2b567SAkira Hatanaka   ;
6809bf2b567SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::AFGR64RegClassID, RegNo /2);
6819bf2b567SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
68271928e68SAkira Hatanaka   return MCDisassembler::Success;
68371928e68SAkira Hatanaka }
68471928e68SAkira Hatanaka 
68500fcf2e1SAkira Hatanaka static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst,
686ecabd1a5SAkira Hatanaka                                                 unsigned RegNo,
687ecabd1a5SAkira Hatanaka                                                 uint64_t Address,
688ecabd1a5SAkira Hatanaka                                                 const void *Decoder) {
689ecabd1a5SAkira Hatanaka   if (RegNo >= 4)
690ecabd1a5SAkira Hatanaka     return MCDisassembler::Fail;
691ecabd1a5SAkira Hatanaka 
69200fcf2e1SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::ACC64DSPRegClassID, RegNo);
693ecabd1a5SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
694ecabd1a5SAkira Hatanaka   return MCDisassembler::Success;
695ecabd1a5SAkira Hatanaka }
696ecabd1a5SAkira Hatanaka 
6978002a3f6SAkira Hatanaka static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst,
69859bfaf77SAkira Hatanaka                                                unsigned RegNo,
69959bfaf77SAkira Hatanaka                                                uint64_t Address,
70059bfaf77SAkira Hatanaka                                                const void *Decoder) {
70159bfaf77SAkira Hatanaka   if (RegNo >= 4)
70259bfaf77SAkira Hatanaka     return MCDisassembler::Fail;
70359bfaf77SAkira Hatanaka 
7048002a3f6SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::HI32DSPRegClassID, RegNo);
70559bfaf77SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
70659bfaf77SAkira Hatanaka   return MCDisassembler::Success;
70759bfaf77SAkira Hatanaka }
70859bfaf77SAkira Hatanaka 
7098002a3f6SAkira Hatanaka static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst,
71059bfaf77SAkira Hatanaka                                                unsigned RegNo,
71159bfaf77SAkira Hatanaka                                                uint64_t Address,
71259bfaf77SAkira Hatanaka                                                const void *Decoder) {
71359bfaf77SAkira Hatanaka   if (RegNo >= 4)
71459bfaf77SAkira Hatanaka     return MCDisassembler::Fail;
71559bfaf77SAkira Hatanaka 
7168002a3f6SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::LO32DSPRegClassID, RegNo);
71759bfaf77SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
71859bfaf77SAkira Hatanaka   return MCDisassembler::Success;
71959bfaf77SAkira Hatanaka }
72059bfaf77SAkira Hatanaka 
7213eb663b0SJack Carter static DecodeStatus DecodeMSA128BRegisterClass(MCInst &Inst,
7223eb663b0SJack Carter                                                unsigned RegNo,
7233eb663b0SJack Carter                                                uint64_t Address,
7243eb663b0SJack Carter                                                const void *Decoder) {
7253eb663b0SJack Carter   if (RegNo > 31)
7263eb663b0SJack Carter     return MCDisassembler::Fail;
7273eb663b0SJack Carter 
7283eb663b0SJack Carter   unsigned Reg = getReg(Decoder, Mips::MSA128BRegClassID, RegNo);
7293eb663b0SJack Carter   Inst.addOperand(MCOperand::CreateReg(Reg));
7303eb663b0SJack Carter   return MCDisassembler::Success;
7313eb663b0SJack Carter }
7323eb663b0SJack Carter 
7335dc8ac92SJack Carter static DecodeStatus DecodeMSA128HRegisterClass(MCInst &Inst,
7345dc8ac92SJack Carter                                                unsigned RegNo,
7355dc8ac92SJack Carter                                                uint64_t Address,
7365dc8ac92SJack Carter                                                const void *Decoder) {
7375dc8ac92SJack Carter   if (RegNo > 31)
7385dc8ac92SJack Carter     return MCDisassembler::Fail;
7395dc8ac92SJack Carter 
7405dc8ac92SJack Carter   unsigned Reg = getReg(Decoder, Mips::MSA128HRegClassID, RegNo);
7415dc8ac92SJack Carter   Inst.addOperand(MCOperand::CreateReg(Reg));
7425dc8ac92SJack Carter   return MCDisassembler::Success;
7435dc8ac92SJack Carter }
7445dc8ac92SJack Carter 
7455dc8ac92SJack Carter static DecodeStatus DecodeMSA128WRegisterClass(MCInst &Inst,
7465dc8ac92SJack Carter                                                unsigned RegNo,
7475dc8ac92SJack Carter                                                uint64_t Address,
7485dc8ac92SJack Carter                                                const void *Decoder) {
7495dc8ac92SJack Carter   if (RegNo > 31)
7505dc8ac92SJack Carter     return MCDisassembler::Fail;
7515dc8ac92SJack Carter 
7525dc8ac92SJack Carter   unsigned Reg = getReg(Decoder, Mips::MSA128WRegClassID, RegNo);
7535dc8ac92SJack Carter   Inst.addOperand(MCOperand::CreateReg(Reg));
7545dc8ac92SJack Carter   return MCDisassembler::Success;
7555dc8ac92SJack Carter }
7565dc8ac92SJack Carter 
7575dc8ac92SJack Carter static DecodeStatus DecodeMSA128DRegisterClass(MCInst &Inst,
7585dc8ac92SJack Carter                                                unsigned RegNo,
7595dc8ac92SJack Carter                                                uint64_t Address,
7605dc8ac92SJack Carter                                                const void *Decoder) {
7615dc8ac92SJack Carter   if (RegNo > 31)
7625dc8ac92SJack Carter     return MCDisassembler::Fail;
7635dc8ac92SJack Carter 
7645dc8ac92SJack Carter   unsigned Reg = getReg(Decoder, Mips::MSA128DRegClassID, RegNo);
7655dc8ac92SJack Carter   Inst.addOperand(MCOperand::CreateReg(Reg));
7665dc8ac92SJack Carter   return MCDisassembler::Success;
7675dc8ac92SJack Carter }
7685dc8ac92SJack Carter 
769a591fdc6SMatheus Almeida static DecodeStatus DecodeMSACtrlRegisterClass(MCInst &Inst,
770a591fdc6SMatheus Almeida                                                unsigned RegNo,
771a591fdc6SMatheus Almeida                                                uint64_t Address,
772a591fdc6SMatheus Almeida                                                const void *Decoder) {
773a591fdc6SMatheus Almeida   if (RegNo > 7)
774a591fdc6SMatheus Almeida     return MCDisassembler::Fail;
775a591fdc6SMatheus Almeida 
776a591fdc6SMatheus Almeida   unsigned Reg = getReg(Decoder, Mips::MSACtrlRegClassID, RegNo);
777a591fdc6SMatheus Almeida   Inst.addOperand(MCOperand::CreateReg(Reg));
778a591fdc6SMatheus Almeida   return MCDisassembler::Success;
779a591fdc6SMatheus Almeida }
780a591fdc6SMatheus Almeida 
78171928e68SAkira Hatanaka static DecodeStatus DecodeBranchTarget(MCInst &Inst,
78271928e68SAkira Hatanaka                                        unsigned Offset,
78371928e68SAkira Hatanaka                                        uint64_t Address,
78471928e68SAkira Hatanaka                                        const void *Decoder) {
78571928e68SAkira Hatanaka   unsigned BranchOffset = Offset & 0xffff;
78671928e68SAkira Hatanaka   BranchOffset = SignExtend32<18>(BranchOffset << 2) + 4;
78771928e68SAkira Hatanaka   Inst.addOperand(MCOperand::CreateImm(BranchOffset));
78871928e68SAkira Hatanaka   return MCDisassembler::Success;
78971928e68SAkira Hatanaka }
79071928e68SAkira Hatanaka 
79171928e68SAkira Hatanaka static DecodeStatus DecodeJumpTarget(MCInst &Inst,
79271928e68SAkira Hatanaka                                      unsigned Insn,
79371928e68SAkira Hatanaka                                      uint64_t Address,
79471928e68SAkira Hatanaka                                      const void *Decoder) {
79571928e68SAkira Hatanaka 
796ecaef49fSJim Grosbach   unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 2;
79771928e68SAkira Hatanaka   Inst.addOperand(MCOperand::CreateImm(JumpOffset));
79871928e68SAkira Hatanaka   return MCDisassembler::Success;
79971928e68SAkira Hatanaka }
80071928e68SAkira Hatanaka 
8018a80aa76SZoran Jovanovic static DecodeStatus DecodeBranchTargetMM(MCInst &Inst,
8028a80aa76SZoran Jovanovic                                          unsigned Offset,
8038a80aa76SZoran Jovanovic                                          uint64_t Address,
8048a80aa76SZoran Jovanovic                                          const void *Decoder) {
8058a80aa76SZoran Jovanovic   unsigned BranchOffset = Offset & 0xffff;
8068a80aa76SZoran Jovanovic   BranchOffset = SignExtend32<18>(BranchOffset << 1);
8078a80aa76SZoran Jovanovic   Inst.addOperand(MCOperand::CreateImm(BranchOffset));
8088a80aa76SZoran Jovanovic   return MCDisassembler::Success;
8098a80aa76SZoran Jovanovic }
8108a80aa76SZoran Jovanovic 
811507e084aSZoran Jovanovic static DecodeStatus DecodeJumpTargetMM(MCInst &Inst,
812507e084aSZoran Jovanovic                                        unsigned Insn,
813507e084aSZoran Jovanovic                                        uint64_t Address,
814507e084aSZoran Jovanovic                                        const void *Decoder) {
815507e084aSZoran Jovanovic   unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 1;
816507e084aSZoran Jovanovic   Inst.addOperand(MCOperand::CreateImm(JumpOffset));
817507e084aSZoran Jovanovic   return MCDisassembler::Success;
818507e084aSZoran Jovanovic }
81971928e68SAkira Hatanaka 
82071928e68SAkira Hatanaka static DecodeStatus DecodeSimm16(MCInst &Inst,
82171928e68SAkira Hatanaka                                  unsigned Insn,
82271928e68SAkira Hatanaka                                  uint64_t Address,
82371928e68SAkira Hatanaka                                  const void *Decoder) {
82471928e68SAkira Hatanaka   Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Insn)));
82571928e68SAkira Hatanaka   return MCDisassembler::Success;
82671928e68SAkira Hatanaka }
82771928e68SAkira Hatanaka 
828779c5937SMatheus Almeida static DecodeStatus DecodeLSAImm(MCInst &Inst,
829779c5937SMatheus Almeida                                  unsigned Insn,
830779c5937SMatheus Almeida                                  uint64_t Address,
831779c5937SMatheus Almeida                                  const void *Decoder) {
832779c5937SMatheus Almeida   // We add one to the immediate field as it was encoded as 'imm - 1'.
833779c5937SMatheus Almeida   Inst.addOperand(MCOperand::CreateImm(Insn + 1));
834779c5937SMatheus Almeida   return MCDisassembler::Success;
835779c5937SMatheus Almeida }
836779c5937SMatheus Almeida 
83771928e68SAkira Hatanaka static DecodeStatus DecodeInsSize(MCInst &Inst,
83871928e68SAkira Hatanaka                                   unsigned Insn,
83971928e68SAkira Hatanaka                                   uint64_t Address,
84071928e68SAkira Hatanaka                                   const void *Decoder) {
84171928e68SAkira Hatanaka   // First we need to grab the pos(lsb) from MCInst.
84271928e68SAkira Hatanaka   int Pos = Inst.getOperand(2).getImm();
84371928e68SAkira Hatanaka   int Size = (int) Insn - Pos + 1;
84471928e68SAkira Hatanaka   Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size)));
84571928e68SAkira Hatanaka   return MCDisassembler::Success;
84671928e68SAkira Hatanaka }
84771928e68SAkira Hatanaka 
84871928e68SAkira Hatanaka static DecodeStatus DecodeExtSize(MCInst &Inst,
84971928e68SAkira Hatanaka                                   unsigned Insn,
85071928e68SAkira Hatanaka                                   uint64_t Address,
85171928e68SAkira Hatanaka                                   const void *Decoder) {
85271928e68SAkira Hatanaka   int Size = (int) Insn  + 1;
85371928e68SAkira Hatanaka   Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size)));
85471928e68SAkira Hatanaka   return MCDisassembler::Success;
85571928e68SAkira Hatanaka }
856