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"
17a1bc0f56SLang Hames #include "llvm/MC/MCContext.h"
1871928e68SAkira Hatanaka #include "llvm/MC/MCDisassembler.h"
19ecaef49fSJim Grosbach #include "llvm/MC/MCFixedLenDisassembler.h"
20ed0881b2SChandler Carruth #include "llvm/MC/MCInst.h"
21ed0881b2SChandler Carruth #include "llvm/MC/MCSubtargetInfo.h"
22ed0881b2SChandler Carruth #include "llvm/Support/MathExtras.h"
2371928e68SAkira Hatanaka #include "llvm/Support/TargetRegistry.h"
2471928e68SAkira Hatanaka 
2571928e68SAkira Hatanaka using namespace llvm;
2671928e68SAkira Hatanaka 
27e96dd897SChandler Carruth #define DEBUG_TYPE "mips-disassembler"
28e96dd897SChandler Carruth 
2971928e68SAkira Hatanaka typedef MCDisassembler::DecodeStatus DecodeStatus;
3071928e68SAkira Hatanaka 
31cb3e98cfSBenjamin Kramer namespace {
32cb3e98cfSBenjamin Kramer 
334aa6bea7SRafael Espindola /// A disasembler class for Mips.
349bf2b567SAkira Hatanaka class MipsDisassemblerBase : public MCDisassembler {
3571928e68SAkira Hatanaka public:
36a1bc0f56SLang Hames   MipsDisassemblerBase(const MCSubtargetInfo &STI, MCContext &Ctx,
374aa6bea7SRafael Espindola                        bool IsBigEndian)
384aa6bea7SRafael Espindola       : MCDisassembler(STI, Ctx),
394aa6bea7SRafael Espindola         IsN64(STI.getFeatureBits() & Mips::FeatureN64),
404aa6bea7SRafael Espindola         IsBigEndian(IsBigEndian) {}
4171928e68SAkira Hatanaka 
429bf2b567SAkira Hatanaka   virtual ~MipsDisassemblerBase() {}
439bf2b567SAkira Hatanaka 
449bfa2e2eSAkira Hatanaka   bool isN64() const { return IsN64; }
459bfa2e2eSAkira Hatanaka 
469bf2b567SAkira Hatanaka private:
479bfa2e2eSAkira Hatanaka   bool IsN64;
489bf2b567SAkira Hatanaka protected:
494aa6bea7SRafael Espindola   bool IsBigEndian;
509bf2b567SAkira Hatanaka };
519bf2b567SAkira Hatanaka 
524aa6bea7SRafael Espindola /// A disasembler class for Mips32.
539bf2b567SAkira Hatanaka class MipsDisassembler : public MipsDisassemblerBase {
54dde3d582SVladimir Medic   bool IsMicroMips;
559bf2b567SAkira Hatanaka public:
56c171f65aSDaniel Sanders   MipsDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx, bool bigEndian)
57c171f65aSDaniel Sanders       : MipsDisassemblerBase(STI, Ctx, bigEndian) {
58dde3d582SVladimir Medic     IsMicroMips = STI.getFeatureBits() & Mips::FeatureMicroMips;
59dde3d582SVladimir Medic   }
6071928e68SAkira Hatanaka 
61c171f65aSDaniel Sanders   bool hasMips3() const { return STI.getFeatureBits() & Mips::FeatureMips3; }
62c171f65aSDaniel Sanders   bool hasMips32() const { return STI.getFeatureBits() & Mips::FeatureMips32; }
63c171f65aSDaniel Sanders   bool hasMips32r6() const {
645c582b2fSDaniel Sanders     return STI.getFeatureBits() & Mips::FeatureMips32r6;
655c582b2fSDaniel Sanders   }
665c582b2fSDaniel Sanders 
670fa60416SDaniel Sanders   bool isGP64() const { return STI.getFeatureBits() & Mips::FeatureGP64Bit; }
680fa60416SDaniel Sanders 
69c171f65aSDaniel Sanders   bool hasCOP3() const {
70c171f65aSDaniel Sanders     // Only present in MIPS-I and MIPS-II
71c171f65aSDaniel Sanders     return !hasMips32() && !hasMips3();
72c171f65aSDaniel Sanders   }
73c171f65aSDaniel Sanders 
744aa6bea7SRafael Espindola   DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
757fc5b874SRafael Espindola                               ArrayRef<uint8_t> Bytes, uint64_t Address,
764aa6bea7SRafael Espindola                               raw_ostream &VStream,
774aa6bea7SRafael Espindola                               raw_ostream &CStream) const override;
7871928e68SAkira Hatanaka };
7971928e68SAkira Hatanaka 
804aa6bea7SRafael Espindola /// A disasembler class for Mips64.
819bf2b567SAkira Hatanaka class Mips64Disassembler : public MipsDisassemblerBase {
8271928e68SAkira Hatanaka public:
83a1bc0f56SLang Hames   Mips64Disassembler(const MCSubtargetInfo &STI, MCContext &Ctx,
849bf2b567SAkira Hatanaka                      bool bigEndian) :
85a1bc0f56SLang Hames     MipsDisassemblerBase(STI, Ctx, bigEndian) {}
8671928e68SAkira Hatanaka 
874aa6bea7SRafael Espindola   DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
887fc5b874SRafael Espindola                               ArrayRef<uint8_t> Bytes, uint64_t Address,
894aa6bea7SRafael Espindola                               raw_ostream &VStream,
904aa6bea7SRafael Espindola                               raw_ostream &CStream) const override;
9171928e68SAkira Hatanaka };
9271928e68SAkira Hatanaka 
93cb3e98cfSBenjamin Kramer } // end anonymous namespace
94cb3e98cfSBenjamin Kramer 
9571928e68SAkira Hatanaka // Forward declare these because the autogenerated code will reference them.
9671928e68SAkira Hatanaka // Definitions are further down.
9713e6ccf3SAkira Hatanaka static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst,
9871928e68SAkira Hatanaka                                              unsigned RegNo,
9971928e68SAkira Hatanaka                                              uint64_t Address,
10071928e68SAkira Hatanaka                                              const void *Decoder);
10171928e68SAkira Hatanaka 
102ec8a5490SReed Kotler static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst,
103ec8a5490SReed Kotler                                                  unsigned RegNo,
104ec8a5490SReed Kotler                                                  uint64_t Address,
105ec8a5490SReed Kotler                                                  const void *Decoder);
106ec8a5490SReed Kotler 
107b0852e54SZoran Jovanovic static DecodeStatus DecodeGPRMM16RegisterClass(MCInst &Inst,
108b0852e54SZoran Jovanovic                                                unsigned RegNo,
109b0852e54SZoran Jovanovic                                                uint64_t Address,
110b0852e54SZoran Jovanovic                                                const void *Decoder);
111b0852e54SZoran Jovanovic 
11213e6ccf3SAkira Hatanaka static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst,
11371928e68SAkira Hatanaka                                              unsigned RegNo,
11471928e68SAkira Hatanaka                                              uint64_t Address,
11571928e68SAkira Hatanaka                                              const void *Decoder);
11671928e68SAkira Hatanaka 
1179bfa2e2eSAkira Hatanaka static DecodeStatus DecodePtrRegisterClass(MCInst &Inst,
1189bfa2e2eSAkira Hatanaka                                            unsigned Insn,
1199bfa2e2eSAkira Hatanaka                                            uint64_t Address,
1209bfa2e2eSAkira Hatanaka                                            const void *Decoder);
1219bfa2e2eSAkira Hatanaka 
122654655f1SAkira Hatanaka static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst,
123ecabd1a5SAkira Hatanaka                                             unsigned RegNo,
124ecabd1a5SAkira Hatanaka                                             uint64_t Address,
125ecabd1a5SAkira Hatanaka                                             const void *Decoder);
126ecabd1a5SAkira Hatanaka 
12771928e68SAkira Hatanaka static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
12871928e68SAkira Hatanaka                                              unsigned RegNo,
12971928e68SAkira Hatanaka                                              uint64_t Address,
13071928e68SAkira Hatanaka                                              const void *Decoder);
13171928e68SAkira Hatanaka 
13271928e68SAkira Hatanaka static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
13371928e68SAkira Hatanaka                                              unsigned RegNo,
13471928e68SAkira Hatanaka                                              uint64_t Address,
13571928e68SAkira Hatanaka                                              const void *Decoder);
13671928e68SAkira Hatanaka 
13771928e68SAkira Hatanaka static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
13871928e68SAkira Hatanaka                                            unsigned RegNo,
13971928e68SAkira Hatanaka                                            uint64_t Address,
14071928e68SAkira Hatanaka                                            const void *Decoder);
14171928e68SAkira Hatanaka 
1421fb1b8b8SAkira Hatanaka static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst,
1431fb1b8b8SAkira Hatanaka                                            unsigned RegNo,
1441fb1b8b8SAkira Hatanaka                                            uint64_t Address,
1451fb1b8b8SAkira Hatanaka                                            const void *Decoder);
1461fb1b8b8SAkira Hatanaka 
1470fa60416SDaniel Sanders static DecodeStatus DecodeFGRCCRegisterClass(MCInst &Inst, unsigned RegNo,
1480fa60416SDaniel Sanders                                              uint64_t Address,
1490fa60416SDaniel Sanders                                              const void *Decoder);
1500fa60416SDaniel Sanders 
15171928e68SAkira Hatanaka static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
15271928e68SAkira Hatanaka                                               unsigned Insn,
15371928e68SAkira Hatanaka                                               uint64_t Address,
15471928e68SAkira Hatanaka                                               const void *Decoder);
15571928e68SAkira Hatanaka 
15671928e68SAkira Hatanaka static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
15771928e68SAkira Hatanaka                                               unsigned RegNo,
15871928e68SAkira Hatanaka                                               uint64_t Address,
15971928e68SAkira Hatanaka                                               const void *Decoder);
16071928e68SAkira Hatanaka 
16100fcf2e1SAkira Hatanaka static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst,
162ecabd1a5SAkira Hatanaka                                                 unsigned RegNo,
163ecabd1a5SAkira Hatanaka                                                 uint64_t Address,
164ecabd1a5SAkira Hatanaka                                                 const void *Decoder);
165ecabd1a5SAkira Hatanaka 
1668002a3f6SAkira Hatanaka static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst,
16759bfaf77SAkira Hatanaka                                                unsigned RegNo,
16859bfaf77SAkira Hatanaka                                                uint64_t Address,
16959bfaf77SAkira Hatanaka                                                const void *Decoder);
17059bfaf77SAkira Hatanaka 
1718002a3f6SAkira Hatanaka static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst,
17259bfaf77SAkira Hatanaka                                                unsigned RegNo,
17359bfaf77SAkira Hatanaka                                                uint64_t Address,
17459bfaf77SAkira Hatanaka                                                const void *Decoder);
17559bfaf77SAkira Hatanaka 
1763eb663b0SJack Carter static DecodeStatus DecodeMSA128BRegisterClass(MCInst &Inst,
1773eb663b0SJack Carter                                                unsigned RegNo,
1783eb663b0SJack Carter                                                uint64_t Address,
1793eb663b0SJack Carter                                                const void *Decoder);
1803eb663b0SJack Carter 
1815dc8ac92SJack Carter static DecodeStatus DecodeMSA128HRegisterClass(MCInst &Inst,
1825dc8ac92SJack Carter                                                unsigned RegNo,
1835dc8ac92SJack Carter                                                uint64_t Address,
1845dc8ac92SJack Carter                                                const void *Decoder);
1855dc8ac92SJack Carter 
1865dc8ac92SJack Carter static DecodeStatus DecodeMSA128WRegisterClass(MCInst &Inst,
1875dc8ac92SJack Carter                                                unsigned RegNo,
1885dc8ac92SJack Carter                                                uint64_t Address,
1895dc8ac92SJack Carter                                                const void *Decoder);
1905dc8ac92SJack Carter 
1915dc8ac92SJack Carter static DecodeStatus DecodeMSA128DRegisterClass(MCInst &Inst,
1925dc8ac92SJack Carter                                                unsigned RegNo,
1935dc8ac92SJack Carter                                                uint64_t Address,
1945dc8ac92SJack Carter                                                const void *Decoder);
1955dc8ac92SJack Carter 
196a591fdc6SMatheus Almeida static DecodeStatus DecodeMSACtrlRegisterClass(MCInst &Inst,
197a591fdc6SMatheus Almeida                                                unsigned RegNo,
198a591fdc6SMatheus Almeida                                                uint64_t Address,
199a591fdc6SMatheus Almeida                                                const void *Decoder);
200a591fdc6SMatheus Almeida 
2012a83d680SDaniel Sanders static DecodeStatus DecodeCOP2RegisterClass(MCInst &Inst,
2022a83d680SDaniel Sanders                                             unsigned RegNo,
2032a83d680SDaniel Sanders                                             uint64_t Address,
2042a83d680SDaniel Sanders                                             const void *Decoder);
2052a83d680SDaniel Sanders 
20671928e68SAkira Hatanaka static DecodeStatus DecodeBranchTarget(MCInst &Inst,
20771928e68SAkira Hatanaka                                        unsigned Offset,
20871928e68SAkira Hatanaka                                        uint64_t Address,
20971928e68SAkira Hatanaka                                        const void *Decoder);
21071928e68SAkira Hatanaka 
21171928e68SAkira Hatanaka static DecodeStatus DecodeJumpTarget(MCInst &Inst,
21271928e68SAkira Hatanaka                                      unsigned Insn,
21371928e68SAkira Hatanaka                                      uint64_t Address,
21471928e68SAkira Hatanaka                                      const void *Decoder);
21571928e68SAkira Hatanaka 
2163c8869dcSZoran Jovanovic static DecodeStatus DecodeBranchTarget21(MCInst &Inst,
2173c8869dcSZoran Jovanovic                                          unsigned Offset,
2183c8869dcSZoran Jovanovic                                          uint64_t Address,
2193c8869dcSZoran Jovanovic                                          const void *Decoder);
2203c8869dcSZoran Jovanovic 
2213c8869dcSZoran Jovanovic static DecodeStatus DecodeBranchTarget26(MCInst &Inst,
2223c8869dcSZoran Jovanovic                                          unsigned Offset,
2233c8869dcSZoran Jovanovic                                          uint64_t Address,
2243c8869dcSZoran Jovanovic                                          const void *Decoder);
2253c8869dcSZoran Jovanovic 
2268a80aa76SZoran Jovanovic // DecodeBranchTargetMM - Decode microMIPS branch offset, which is
2278a80aa76SZoran Jovanovic // shifted left by 1 bit.
2288a80aa76SZoran Jovanovic static DecodeStatus DecodeBranchTargetMM(MCInst &Inst,
2298a80aa76SZoran Jovanovic                                          unsigned Offset,
2308a80aa76SZoran Jovanovic                                          uint64_t Address,
2318a80aa76SZoran Jovanovic                                          const void *Decoder);
2328a80aa76SZoran Jovanovic 
233507e084aSZoran Jovanovic // DecodeJumpTargetMM - Decode microMIPS jump target, which is
234507e084aSZoran Jovanovic // shifted left by 1 bit.
235507e084aSZoran Jovanovic static DecodeStatus DecodeJumpTargetMM(MCInst &Inst,
236507e084aSZoran Jovanovic                                        unsigned Insn,
237507e084aSZoran Jovanovic                                        uint64_t Address,
238507e084aSZoran Jovanovic                                        const void *Decoder);
239507e084aSZoran Jovanovic 
24071928e68SAkira Hatanaka static DecodeStatus DecodeMem(MCInst &Inst,
24171928e68SAkira Hatanaka                               unsigned Insn,
24271928e68SAkira Hatanaka                               uint64_t Address,
24371928e68SAkira Hatanaka                               const void *Decoder);
24471928e68SAkira Hatanaka 
24592db6b78SDaniel Sanders static DecodeStatus DecodeCacheOp(MCInst &Inst,
24692db6b78SDaniel Sanders                               unsigned Insn,
24792db6b78SDaniel Sanders                               uint64_t Address,
24892db6b78SDaniel Sanders                               const void *Decoder);
24992db6b78SDaniel Sanders 
250fe0bf9f6SMatheus Almeida static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn,
251fe0bf9f6SMatheus Almeida                                     uint64_t Address, const void *Decoder);
252fe0bf9f6SMatheus Almeida 
253dde3d582SVladimir Medic static DecodeStatus DecodeMemMMImm12(MCInst &Inst,
254dde3d582SVladimir Medic                                      unsigned Insn,
255dde3d582SVladimir Medic                                      uint64_t Address,
256dde3d582SVladimir Medic                                      const void *Decoder);
257dde3d582SVladimir Medic 
258dde3d582SVladimir Medic static DecodeStatus DecodeMemMMImm16(MCInst &Inst,
259dde3d582SVladimir Medic                                      unsigned Insn,
260dde3d582SVladimir Medic                                      uint64_t Address,
261dde3d582SVladimir Medic                                      const void *Decoder);
262dde3d582SVladimir Medic 
26371928e68SAkira Hatanaka static DecodeStatus DecodeFMem(MCInst &Inst, unsigned Insn,
26471928e68SAkira Hatanaka                                uint64_t Address,
26571928e68SAkira Hatanaka                                const void *Decoder);
26671928e68SAkira Hatanaka 
26792db6b78SDaniel Sanders static DecodeStatus DecodeFMem2(MCInst &Inst, unsigned Insn,
26892db6b78SDaniel Sanders                                uint64_t Address,
26992db6b78SDaniel Sanders                                const void *Decoder);
27092db6b78SDaniel Sanders 
27192db6b78SDaniel Sanders static DecodeStatus DecodeFMem3(MCInst &Inst, unsigned Insn,
27292db6b78SDaniel Sanders                                uint64_t Address,
27392db6b78SDaniel Sanders                                const void *Decoder);
27492db6b78SDaniel Sanders 
2756a803f61SDaniel Sanders static DecodeStatus DecodeSpecial3LlSc(MCInst &Inst,
2766a803f61SDaniel Sanders                                        unsigned Insn,
2776a803f61SDaniel Sanders                                        uint64_t Address,
2786a803f61SDaniel Sanders                                        const void *Decoder);
2796a803f61SDaniel Sanders 
28071928e68SAkira Hatanaka static DecodeStatus DecodeSimm16(MCInst &Inst,
28171928e68SAkira Hatanaka                                  unsigned Insn,
28271928e68SAkira Hatanaka                                  uint64_t Address,
28371928e68SAkira Hatanaka                                  const void *Decoder);
28471928e68SAkira Hatanaka 
285779c5937SMatheus Almeida // Decode the immediate field of an LSA instruction which
286779c5937SMatheus Almeida // is off by one.
287779c5937SMatheus Almeida static DecodeStatus DecodeLSAImm(MCInst &Inst,
288779c5937SMatheus Almeida                                  unsigned Insn,
289779c5937SMatheus Almeida                                  uint64_t Address,
290779c5937SMatheus Almeida                                  const void *Decoder);
291779c5937SMatheus Almeida 
29271928e68SAkira Hatanaka static DecodeStatus DecodeInsSize(MCInst &Inst,
29371928e68SAkira Hatanaka                                   unsigned Insn,
29471928e68SAkira Hatanaka                                   uint64_t Address,
29571928e68SAkira Hatanaka                                   const void *Decoder);
29671928e68SAkira Hatanaka 
29771928e68SAkira Hatanaka static DecodeStatus DecodeExtSize(MCInst &Inst,
29871928e68SAkira Hatanaka                                   unsigned Insn,
29971928e68SAkira Hatanaka                                   uint64_t Address,
30071928e68SAkira Hatanaka                                   const void *Decoder);
30171928e68SAkira Hatanaka 
302b59e1a41SDaniel Sanders static DecodeStatus DecodeSimm19Lsl2(MCInst &Inst, unsigned Insn,
303b59e1a41SDaniel Sanders                                      uint64_t Address, const void *Decoder);
304b59e1a41SDaniel Sanders 
3052855142aSZoran Jovanovic static DecodeStatus DecodeSimm18Lsl3(MCInst &Inst, unsigned Insn,
3062855142aSZoran Jovanovic                                      uint64_t Address, const void *Decoder);
3072855142aSZoran Jovanovic 
308b50ccf8eSDaniel Sanders /// INSVE_[BHWD] have an implicit operand that the generated decoder doesn't
309b50ccf8eSDaniel Sanders /// handle.
310b50ccf8eSDaniel Sanders template <typename InsnType>
311b50ccf8eSDaniel Sanders static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address,
312b50ccf8eSDaniel Sanders                                    const void *Decoder);
3135c582b2fSDaniel Sanders 
3145c582b2fSDaniel Sanders template <typename InsnType>
3155c582b2fSDaniel Sanders static DecodeStatus
3165c582b2fSDaniel Sanders DecodeAddiGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
3175c582b2fSDaniel Sanders                       const void *Decoder);
3185c582b2fSDaniel Sanders 
3195c582b2fSDaniel Sanders template <typename InsnType>
3205c582b2fSDaniel Sanders static DecodeStatus
3215c582b2fSDaniel Sanders DecodeDaddiGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
3225c582b2fSDaniel Sanders                        const void *Decoder);
3235c582b2fSDaniel Sanders 
3245c582b2fSDaniel Sanders template <typename InsnType>
3255c582b2fSDaniel Sanders static DecodeStatus
3265c582b2fSDaniel Sanders DecodeBlezlGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
3275c582b2fSDaniel Sanders                        const void *Decoder);
3285c582b2fSDaniel Sanders 
3295c582b2fSDaniel Sanders template <typename InsnType>
3305c582b2fSDaniel Sanders static DecodeStatus
3315c582b2fSDaniel Sanders DecodeBgtzlGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
3325c582b2fSDaniel Sanders                        const void *Decoder);
3335c582b2fSDaniel Sanders 
3345c582b2fSDaniel Sanders template <typename InsnType>
3355c582b2fSDaniel Sanders static DecodeStatus
3365c582b2fSDaniel Sanders DecodeBgtzGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
3375c582b2fSDaniel Sanders                       const void *Decoder);
3385c582b2fSDaniel Sanders 
33928a0ca07SZoran Jovanovic template <typename InsnType>
34028a0ca07SZoran Jovanovic static DecodeStatus
34128a0ca07SZoran Jovanovic DecodeBlezGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
34228a0ca07SZoran Jovanovic                        const void *Decoder);
34328a0ca07SZoran Jovanovic 
344a4c4b5fcSZoran Jovanovic static DecodeStatus DecodeRegListOperand(MCInst &Inst, unsigned Insn,
345a4c4b5fcSZoran Jovanovic                                          uint64_t Address,
346a4c4b5fcSZoran Jovanovic                                          const void *Decoder);
347a4c4b5fcSZoran Jovanovic 
34871928e68SAkira Hatanaka namespace llvm {
34971928e68SAkira Hatanaka extern Target TheMipselTarget, TheMipsTarget, TheMips64Target,
35071928e68SAkira Hatanaka               TheMips64elTarget;
35171928e68SAkira Hatanaka }
35271928e68SAkira Hatanaka 
35371928e68SAkira Hatanaka static MCDisassembler *createMipsDisassembler(
35471928e68SAkira Hatanaka                        const Target &T,
355a1bc0f56SLang Hames                        const MCSubtargetInfo &STI,
356a1bc0f56SLang Hames                        MCContext &Ctx) {
357a1bc0f56SLang Hames   return new MipsDisassembler(STI, Ctx, true);
35871928e68SAkira Hatanaka }
35971928e68SAkira Hatanaka 
36071928e68SAkira Hatanaka static MCDisassembler *createMipselDisassembler(
36171928e68SAkira Hatanaka                        const Target &T,
362a1bc0f56SLang Hames                        const MCSubtargetInfo &STI,
363a1bc0f56SLang Hames                        MCContext &Ctx) {
364a1bc0f56SLang Hames   return new MipsDisassembler(STI, Ctx, false);
36571928e68SAkira Hatanaka }
36671928e68SAkira Hatanaka 
36771928e68SAkira Hatanaka static MCDisassembler *createMips64Disassembler(
36871928e68SAkira Hatanaka                        const Target &T,
369a1bc0f56SLang Hames                        const MCSubtargetInfo &STI,
370a1bc0f56SLang Hames                        MCContext &Ctx) {
371a1bc0f56SLang Hames   return new Mips64Disassembler(STI, Ctx, true);
37271928e68SAkira Hatanaka }
37371928e68SAkira Hatanaka 
37471928e68SAkira Hatanaka static MCDisassembler *createMips64elDisassembler(
37571928e68SAkira Hatanaka                        const Target &T,
376a1bc0f56SLang Hames                        const MCSubtargetInfo &STI,
377a1bc0f56SLang Hames                        MCContext &Ctx) {
378a1bc0f56SLang Hames   return new Mips64Disassembler(STI, Ctx, false);
37971928e68SAkira Hatanaka }
38071928e68SAkira Hatanaka 
38171928e68SAkira Hatanaka extern "C" void LLVMInitializeMipsDisassembler() {
38271928e68SAkira Hatanaka   // Register the disassembler.
38371928e68SAkira Hatanaka   TargetRegistry::RegisterMCDisassembler(TheMipsTarget,
38471928e68SAkira Hatanaka                                          createMipsDisassembler);
38571928e68SAkira Hatanaka   TargetRegistry::RegisterMCDisassembler(TheMipselTarget,
38671928e68SAkira Hatanaka                                          createMipselDisassembler);
38771928e68SAkira Hatanaka   TargetRegistry::RegisterMCDisassembler(TheMips64Target,
38871928e68SAkira Hatanaka                                          createMips64Disassembler);
38971928e68SAkira Hatanaka   TargetRegistry::RegisterMCDisassembler(TheMips64elTarget,
39071928e68SAkira Hatanaka                                          createMips64elDisassembler);
39171928e68SAkira Hatanaka }
39271928e68SAkira Hatanaka 
39371928e68SAkira Hatanaka #include "MipsGenDisassemblerTables.inc"
39471928e68SAkira Hatanaka 
3955c582b2fSDaniel Sanders static unsigned getReg(const void *D, unsigned RC, unsigned RegNo) {
3965c582b2fSDaniel Sanders   const MipsDisassemblerBase *Dis = static_cast<const MipsDisassemblerBase*>(D);
3975c582b2fSDaniel Sanders   const MCRegisterInfo *RegInfo = Dis->getContext().getRegisterInfo();
3985c582b2fSDaniel Sanders   return *(RegInfo->getRegClass(RC).begin() + RegNo);
3995c582b2fSDaniel Sanders }
4005c582b2fSDaniel Sanders 
401b50ccf8eSDaniel Sanders template <typename InsnType>
402b50ccf8eSDaniel Sanders static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address,
403b50ccf8eSDaniel Sanders                                    const void *Decoder) {
404b50ccf8eSDaniel Sanders   typedef DecodeStatus (*DecodeFN)(MCInst &, unsigned, uint64_t, const void *);
405b50ccf8eSDaniel Sanders   // The size of the n field depends on the element size
406b50ccf8eSDaniel Sanders   // The register class also depends on this.
407b50ccf8eSDaniel Sanders   InsnType tmp = fieldFromInstruction(insn, 17, 5);
408b50ccf8eSDaniel Sanders   unsigned NSize = 0;
409b50ccf8eSDaniel Sanders   DecodeFN RegDecoder = nullptr;
410b50ccf8eSDaniel Sanders   if ((tmp & 0x18) == 0x00) { // INSVE_B
411b50ccf8eSDaniel Sanders     NSize = 4;
412b50ccf8eSDaniel Sanders     RegDecoder = DecodeMSA128BRegisterClass;
413b50ccf8eSDaniel Sanders   } else if ((tmp & 0x1c) == 0x10) { // INSVE_H
414b50ccf8eSDaniel Sanders     NSize = 3;
415b50ccf8eSDaniel Sanders     RegDecoder = DecodeMSA128HRegisterClass;
416b50ccf8eSDaniel Sanders   } else if ((tmp & 0x1e) == 0x18) { // INSVE_W
417b50ccf8eSDaniel Sanders     NSize = 2;
418b50ccf8eSDaniel Sanders     RegDecoder = DecodeMSA128WRegisterClass;
419b50ccf8eSDaniel Sanders   } else if ((tmp & 0x1f) == 0x1c) { // INSVE_D
420b50ccf8eSDaniel Sanders     NSize = 1;
421b50ccf8eSDaniel Sanders     RegDecoder = DecodeMSA128DRegisterClass;
422b50ccf8eSDaniel Sanders   } else
423b50ccf8eSDaniel Sanders     llvm_unreachable("Invalid encoding");
424b50ccf8eSDaniel Sanders 
425b50ccf8eSDaniel Sanders   assert(NSize != 0 && RegDecoder != nullptr);
426b50ccf8eSDaniel Sanders 
427b50ccf8eSDaniel Sanders   // $wd
428b50ccf8eSDaniel Sanders   tmp = fieldFromInstruction(insn, 6, 5);
429b50ccf8eSDaniel Sanders   if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
430b50ccf8eSDaniel Sanders     return MCDisassembler::Fail;
431b50ccf8eSDaniel Sanders   // $wd_in
432b50ccf8eSDaniel Sanders   if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
433b50ccf8eSDaniel Sanders     return MCDisassembler::Fail;
434b50ccf8eSDaniel Sanders   // $n
435b50ccf8eSDaniel Sanders   tmp = fieldFromInstruction(insn, 16, NSize);
436b50ccf8eSDaniel Sanders   MI.addOperand(MCOperand::CreateImm(tmp));
437b50ccf8eSDaniel Sanders   // $ws
438b50ccf8eSDaniel Sanders   tmp = fieldFromInstruction(insn, 11, 5);
439b50ccf8eSDaniel Sanders   if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
440b50ccf8eSDaniel Sanders     return MCDisassembler::Fail;
441b50ccf8eSDaniel Sanders   // $n2
442b50ccf8eSDaniel Sanders   MI.addOperand(MCOperand::CreateImm(0));
443b50ccf8eSDaniel Sanders 
444b50ccf8eSDaniel Sanders   return MCDisassembler::Success;
445b50ccf8eSDaniel Sanders }
446b50ccf8eSDaniel Sanders 
4475c582b2fSDaniel Sanders template <typename InsnType>
4485c582b2fSDaniel Sanders static DecodeStatus DecodeAddiGroupBranch(MCInst &MI, InsnType insn,
4495c582b2fSDaniel Sanders                                           uint64_t Address,
4505c582b2fSDaniel Sanders                                           const void *Decoder) {
4515c582b2fSDaniel Sanders   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
4525c582b2fSDaniel Sanders   // (otherwise we would have matched the ADDI instruction from the earlier
4535c582b2fSDaniel Sanders   // ISA's instead).
4545c582b2fSDaniel Sanders   //
4555c582b2fSDaniel Sanders   // We have:
4565c582b2fSDaniel Sanders   //    0b001000 sssss ttttt iiiiiiiiiiiiiiii
4575c582b2fSDaniel Sanders   //      BOVC if rs >= rt
4585c582b2fSDaniel Sanders   //      BEQZALC if rs == 0 && rt != 0
4595c582b2fSDaniel Sanders   //      BEQC if rs < rt && rs != 0
4605c582b2fSDaniel Sanders 
4615c582b2fSDaniel Sanders   InsnType Rs = fieldFromInstruction(insn, 21, 5);
4625c582b2fSDaniel Sanders   InsnType Rt = fieldFromInstruction(insn, 16, 5);
463d37bab61SAlexey Samsonov   InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4;
4645c582b2fSDaniel Sanders   bool HasRs = false;
4655c582b2fSDaniel Sanders 
4665c582b2fSDaniel Sanders   if (Rs >= Rt) {
4675c582b2fSDaniel Sanders     MI.setOpcode(Mips::BOVC);
4685c582b2fSDaniel Sanders     HasRs = true;
4695c582b2fSDaniel Sanders   } else if (Rs != 0 && Rs < Rt) {
4705c582b2fSDaniel Sanders     MI.setOpcode(Mips::BEQC);
4715c582b2fSDaniel Sanders     HasRs = true;
4725c582b2fSDaniel Sanders   } else
4735c582b2fSDaniel Sanders     MI.setOpcode(Mips::BEQZALC);
4745c582b2fSDaniel Sanders 
4755c582b2fSDaniel Sanders   if (HasRs)
4765c582b2fSDaniel Sanders     MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
4775c582b2fSDaniel Sanders                                        Rs)));
4785c582b2fSDaniel Sanders 
4795c582b2fSDaniel Sanders   MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
4805c582b2fSDaniel Sanders                                      Rt)));
4815c582b2fSDaniel Sanders   MI.addOperand(MCOperand::CreateImm(Imm));
4825c582b2fSDaniel Sanders 
4835c582b2fSDaniel Sanders   return MCDisassembler::Success;
4845c582b2fSDaniel Sanders }
4855c582b2fSDaniel Sanders 
4865c582b2fSDaniel Sanders template <typename InsnType>
4875c582b2fSDaniel Sanders static DecodeStatus DecodeDaddiGroupBranch(MCInst &MI, InsnType insn,
4885c582b2fSDaniel Sanders                                            uint64_t Address,
4895c582b2fSDaniel Sanders                                            const void *Decoder) {
4905c582b2fSDaniel Sanders   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
4915c582b2fSDaniel Sanders   // (otherwise we would have matched the ADDI instruction from the earlier
4925c582b2fSDaniel Sanders   // ISA's instead).
4935c582b2fSDaniel Sanders   //
4945c582b2fSDaniel Sanders   // We have:
4955c582b2fSDaniel Sanders   //    0b011000 sssss ttttt iiiiiiiiiiiiiiii
4965c582b2fSDaniel Sanders   //      BNVC if rs >= rt
4975c582b2fSDaniel Sanders   //      BNEZALC if rs == 0 && rt != 0
4985c582b2fSDaniel Sanders   //      BNEC if rs < rt && rs != 0
4995c582b2fSDaniel Sanders 
5005c582b2fSDaniel Sanders   InsnType Rs = fieldFromInstruction(insn, 21, 5);
5015c582b2fSDaniel Sanders   InsnType Rt = fieldFromInstruction(insn, 16, 5);
502d37bab61SAlexey Samsonov   InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4;
5035c582b2fSDaniel Sanders   bool HasRs = false;
5045c582b2fSDaniel Sanders 
5055c582b2fSDaniel Sanders   if (Rs >= Rt) {
5065c582b2fSDaniel Sanders     MI.setOpcode(Mips::BNVC);
5075c582b2fSDaniel Sanders     HasRs = true;
5085c582b2fSDaniel Sanders   } else if (Rs != 0 && Rs < Rt) {
5095c582b2fSDaniel Sanders     MI.setOpcode(Mips::BNEC);
5105c582b2fSDaniel Sanders     HasRs = true;
5115c582b2fSDaniel Sanders   } else
5125c582b2fSDaniel Sanders     MI.setOpcode(Mips::BNEZALC);
5135c582b2fSDaniel Sanders 
5145c582b2fSDaniel Sanders   if (HasRs)
5155c582b2fSDaniel Sanders     MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
5165c582b2fSDaniel Sanders                                        Rs)));
5175c582b2fSDaniel Sanders 
5185c582b2fSDaniel Sanders   MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
5195c582b2fSDaniel Sanders                                      Rt)));
5205c582b2fSDaniel Sanders   MI.addOperand(MCOperand::CreateImm(Imm));
5215c582b2fSDaniel Sanders 
5225c582b2fSDaniel Sanders   return MCDisassembler::Success;
5235c582b2fSDaniel Sanders }
5245c582b2fSDaniel Sanders 
5255c582b2fSDaniel Sanders template <typename InsnType>
5265c582b2fSDaniel Sanders static DecodeStatus DecodeBlezlGroupBranch(MCInst &MI, InsnType insn,
5275c582b2fSDaniel Sanders                                            uint64_t Address,
5285c582b2fSDaniel Sanders                                            const void *Decoder) {
5295c582b2fSDaniel Sanders   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
5305c582b2fSDaniel Sanders   // (otherwise we would have matched the BLEZL instruction from the earlier
5315c582b2fSDaniel Sanders   // ISA's instead).
5325c582b2fSDaniel Sanders   //
5335c582b2fSDaniel Sanders   // We have:
5345c582b2fSDaniel Sanders   //    0b010110 sssss ttttt iiiiiiiiiiiiiiii
5355c582b2fSDaniel Sanders   //      Invalid if rs == 0
5365c582b2fSDaniel Sanders   //      BLEZC   if rs == 0  && rt != 0
5375c582b2fSDaniel Sanders   //      BGEZC   if rs == rt && rt != 0
5385c582b2fSDaniel Sanders   //      BGEC    if rs != rt && rs != 0  && rt != 0
5395c582b2fSDaniel Sanders 
5405c582b2fSDaniel Sanders   InsnType Rs = fieldFromInstruction(insn, 21, 5);
5415c582b2fSDaniel Sanders   InsnType Rt = fieldFromInstruction(insn, 16, 5);
542d37bab61SAlexey Samsonov   InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4;
54328a0ca07SZoran Jovanovic   bool HasRs = false;
5445c582b2fSDaniel Sanders 
5455c582b2fSDaniel Sanders   if (Rt == 0)
5465c582b2fSDaniel Sanders     return MCDisassembler::Fail;
5475c582b2fSDaniel Sanders   else if (Rs == 0)
5485c582b2fSDaniel Sanders     MI.setOpcode(Mips::BLEZC);
5495c582b2fSDaniel Sanders   else if (Rs == Rt)
5505c582b2fSDaniel Sanders     MI.setOpcode(Mips::BGEZC);
55128a0ca07SZoran Jovanovic   else {
55228a0ca07SZoran Jovanovic     HasRs = true;
55328a0ca07SZoran Jovanovic     MI.setOpcode(Mips::BGEC);
55428a0ca07SZoran Jovanovic   }
55528a0ca07SZoran Jovanovic 
55628a0ca07SZoran Jovanovic   if (HasRs)
55728a0ca07SZoran Jovanovic     MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
55828a0ca07SZoran Jovanovic                                        Rs)));
5595c582b2fSDaniel Sanders 
5605c582b2fSDaniel Sanders   MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
5615c582b2fSDaniel Sanders                                      Rt)));
5625c582b2fSDaniel Sanders 
5635c582b2fSDaniel Sanders   MI.addOperand(MCOperand::CreateImm(Imm));
5645c582b2fSDaniel Sanders 
5655c582b2fSDaniel Sanders   return MCDisassembler::Success;
5665c582b2fSDaniel Sanders }
5675c582b2fSDaniel Sanders 
5685c582b2fSDaniel Sanders template <typename InsnType>
5695c582b2fSDaniel Sanders static DecodeStatus DecodeBgtzlGroupBranch(MCInst &MI, InsnType insn,
5705c582b2fSDaniel Sanders                                            uint64_t Address,
5715c582b2fSDaniel Sanders                                            const void *Decoder) {
5725c582b2fSDaniel Sanders   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
5735c582b2fSDaniel Sanders   // (otherwise we would have matched the BGTZL instruction from the earlier
5745c582b2fSDaniel Sanders   // ISA's instead).
5755c582b2fSDaniel Sanders   //
5765c582b2fSDaniel Sanders   // We have:
5775c582b2fSDaniel Sanders   //    0b010111 sssss ttttt iiiiiiiiiiiiiiii
5785c582b2fSDaniel Sanders   //      Invalid if rs == 0
5795c582b2fSDaniel Sanders   //      BGTZC   if rs == 0  && rt != 0
5805c582b2fSDaniel Sanders   //      BLTZC   if rs == rt && rt != 0
5815c582b2fSDaniel Sanders   //      BLTC    if rs != rt && rs != 0  && rt != 0
5825c582b2fSDaniel Sanders 
5835c14b069SZoran Jovanovic   bool HasRs = false;
5845c14b069SZoran Jovanovic 
5855c582b2fSDaniel Sanders   InsnType Rs = fieldFromInstruction(insn, 21, 5);
5865c582b2fSDaniel Sanders   InsnType Rt = fieldFromInstruction(insn, 16, 5);
587d37bab61SAlexey Samsonov   InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4;
5885c582b2fSDaniel Sanders 
5895c582b2fSDaniel Sanders   if (Rt == 0)
5905c582b2fSDaniel Sanders     return MCDisassembler::Fail;
5915c582b2fSDaniel Sanders   else if (Rs == 0)
5925c582b2fSDaniel Sanders     MI.setOpcode(Mips::BGTZC);
5935c582b2fSDaniel Sanders   else if (Rs == Rt)
5945c582b2fSDaniel Sanders     MI.setOpcode(Mips::BLTZC);
5955c14b069SZoran Jovanovic   else {
5965c14b069SZoran Jovanovic     MI.setOpcode(Mips::BLTC);
5975c14b069SZoran Jovanovic     HasRs = true;
5985c14b069SZoran Jovanovic   }
5995c14b069SZoran Jovanovic 
6005c14b069SZoran Jovanovic   if (HasRs)
6015c14b069SZoran Jovanovic     MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
6025c14b069SZoran Jovanovic                                               Rs)));
6035c582b2fSDaniel Sanders 
6045c582b2fSDaniel Sanders   MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
6055c582b2fSDaniel Sanders                                      Rt)));
6065c582b2fSDaniel Sanders 
6075c582b2fSDaniel Sanders   MI.addOperand(MCOperand::CreateImm(Imm));
6085c582b2fSDaniel Sanders 
6095c582b2fSDaniel Sanders   return MCDisassembler::Success;
6105c582b2fSDaniel Sanders }
6115c582b2fSDaniel Sanders 
6125c582b2fSDaniel Sanders template <typename InsnType>
6135c582b2fSDaniel Sanders static DecodeStatus DecodeBgtzGroupBranch(MCInst &MI, InsnType insn,
6145c582b2fSDaniel Sanders                                           uint64_t Address,
6155c582b2fSDaniel Sanders                                           const void *Decoder) {
6165c582b2fSDaniel Sanders   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
6175c582b2fSDaniel Sanders   // (otherwise we would have matched the BGTZ instruction from the earlier
6185c582b2fSDaniel Sanders   // ISA's instead).
6195c582b2fSDaniel Sanders   //
6205c582b2fSDaniel Sanders   // We have:
6215c582b2fSDaniel Sanders   //    0b000111 sssss ttttt iiiiiiiiiiiiiiii
6225c582b2fSDaniel Sanders   //      BGTZ    if rt == 0
6235c582b2fSDaniel Sanders   //      BGTZALC if rs == 0 && rt != 0
6245c582b2fSDaniel Sanders   //      BLTZALC if rs != 0 && rs == rt
6255c582b2fSDaniel Sanders   //      BLTUC   if rs != 0 && rs != rt
6265c582b2fSDaniel Sanders 
6275c582b2fSDaniel Sanders   InsnType Rs = fieldFromInstruction(insn, 21, 5);
6285c582b2fSDaniel Sanders   InsnType Rt = fieldFromInstruction(insn, 16, 5);
629d37bab61SAlexey Samsonov   InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4;
6305c582b2fSDaniel Sanders   bool HasRs = false;
6315c582b2fSDaniel Sanders   bool HasRt = false;
6325c582b2fSDaniel Sanders 
6335c582b2fSDaniel Sanders   if (Rt == 0) {
6345c582b2fSDaniel Sanders     MI.setOpcode(Mips::BGTZ);
6355c582b2fSDaniel Sanders     HasRs = true;
6365c582b2fSDaniel Sanders   } else if (Rs == 0) {
6375c582b2fSDaniel Sanders     MI.setOpcode(Mips::BGTZALC);
6385c582b2fSDaniel Sanders     HasRt = true;
6395c582b2fSDaniel Sanders   } else if (Rs == Rt) {
6405c582b2fSDaniel Sanders     MI.setOpcode(Mips::BLTZALC);
6415c582b2fSDaniel Sanders     HasRs = true;
6425c14b069SZoran Jovanovic   } else {
6435c14b069SZoran Jovanovic     MI.setOpcode(Mips::BLTUC);
6445c14b069SZoran Jovanovic     HasRs = true;
6455c14b069SZoran Jovanovic     HasRt = true;
6465c14b069SZoran Jovanovic   }
6475c582b2fSDaniel Sanders 
6485c582b2fSDaniel Sanders   if (HasRs)
6495c582b2fSDaniel Sanders     MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
6505c582b2fSDaniel Sanders                                        Rs)));
6515c582b2fSDaniel Sanders 
6525c582b2fSDaniel Sanders   if (HasRt)
6535c582b2fSDaniel Sanders     MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
6545c582b2fSDaniel Sanders                                        Rt)));
6555c582b2fSDaniel Sanders 
6565c582b2fSDaniel Sanders   MI.addOperand(MCOperand::CreateImm(Imm));
6575c582b2fSDaniel Sanders 
6585c582b2fSDaniel Sanders   return MCDisassembler::Success;
6595c582b2fSDaniel Sanders }
6605c582b2fSDaniel Sanders 
66128a0ca07SZoran Jovanovic template <typename InsnType>
66228a0ca07SZoran Jovanovic static DecodeStatus DecodeBlezGroupBranch(MCInst &MI, InsnType insn,
66328a0ca07SZoran Jovanovic                                            uint64_t Address,
66428a0ca07SZoran Jovanovic                                            const void *Decoder) {
66528a0ca07SZoran Jovanovic   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
66628a0ca07SZoran Jovanovic   // (otherwise we would have matched the BLEZL instruction from the earlier
66728a0ca07SZoran Jovanovic   // ISA's instead).
66828a0ca07SZoran Jovanovic   //
66928a0ca07SZoran Jovanovic   // We have:
67028a0ca07SZoran Jovanovic   //    0b000110 sssss ttttt iiiiiiiiiiiiiiii
67128a0ca07SZoran Jovanovic   //      Invalid   if rs == 0
67228a0ca07SZoran Jovanovic   //      BLEZALC   if rs == 0  && rt != 0
67328a0ca07SZoran Jovanovic   //      BGEZALC   if rs == rt && rt != 0
67428a0ca07SZoran Jovanovic   //      BGEUC     if rs != rt && rs != 0  && rt != 0
67528a0ca07SZoran Jovanovic 
67628a0ca07SZoran Jovanovic   InsnType Rs = fieldFromInstruction(insn, 21, 5);
67728a0ca07SZoran Jovanovic   InsnType Rt = fieldFromInstruction(insn, 16, 5);
678d37bab61SAlexey Samsonov   InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4;
67928a0ca07SZoran Jovanovic   bool HasRs = false;
68028a0ca07SZoran Jovanovic 
68128a0ca07SZoran Jovanovic   if (Rt == 0)
68228a0ca07SZoran Jovanovic     return MCDisassembler::Fail;
68328a0ca07SZoran Jovanovic   else if (Rs == 0)
68428a0ca07SZoran Jovanovic     MI.setOpcode(Mips::BLEZALC);
68528a0ca07SZoran Jovanovic   else if (Rs == Rt)
68628a0ca07SZoran Jovanovic     MI.setOpcode(Mips::BGEZALC);
68728a0ca07SZoran Jovanovic   else {
68828a0ca07SZoran Jovanovic     HasRs = true;
68928a0ca07SZoran Jovanovic     MI.setOpcode(Mips::BGEUC);
69028a0ca07SZoran Jovanovic   }
69128a0ca07SZoran Jovanovic 
69228a0ca07SZoran Jovanovic   if (HasRs)
69328a0ca07SZoran Jovanovic     MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
69428a0ca07SZoran Jovanovic                                        Rs)));
69528a0ca07SZoran Jovanovic   MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
69628a0ca07SZoran Jovanovic                                      Rt)));
69728a0ca07SZoran Jovanovic 
69828a0ca07SZoran Jovanovic   MI.addOperand(MCOperand::CreateImm(Imm));
69928a0ca07SZoran Jovanovic 
70028a0ca07SZoran Jovanovic   return MCDisassembler::Success;
70128a0ca07SZoran Jovanovic }
70228a0ca07SZoran Jovanovic 
703*ea22c4cfSJozef Kolek /// Read two bytes from the ArrayRef and return 16 bit halfword sorted
704*ea22c4cfSJozef Kolek /// according to the given endianess.
705*ea22c4cfSJozef Kolek static DecodeStatus readInstruction16(ArrayRef<uint8_t> Bytes, uint64_t Address,
706*ea22c4cfSJozef Kolek                                       uint64_t &Size, uint32_t &Insn,
707*ea22c4cfSJozef Kolek                                       bool IsBigEndian) {
708*ea22c4cfSJozef Kolek   // We want to read exactly 2 Bytes of data.
709*ea22c4cfSJozef Kolek   if (Bytes.size() < 2) {
710*ea22c4cfSJozef Kolek     Size = 0;
711*ea22c4cfSJozef Kolek     return MCDisassembler::Fail;
712*ea22c4cfSJozef Kolek   }
713*ea22c4cfSJozef Kolek 
714*ea22c4cfSJozef Kolek   if (IsBigEndian) {
715*ea22c4cfSJozef Kolek     Insn = (Bytes[0] << 8) | Bytes[1];
716*ea22c4cfSJozef Kolek   } else {
717*ea22c4cfSJozef Kolek     Insn = (Bytes[1] << 8) | Bytes[0];
718*ea22c4cfSJozef Kolek   }
719*ea22c4cfSJozef Kolek 
720*ea22c4cfSJozef Kolek   return MCDisassembler::Success;
721*ea22c4cfSJozef Kolek }
722*ea22c4cfSJozef Kolek 
7237fc5b874SRafael Espindola /// Read four bytes from the ArrayRef and return 32 bit word sorted
7244aa6bea7SRafael Espindola /// according to the given endianess
7257fc5b874SRafael Espindola static DecodeStatus readInstruction32(ArrayRef<uint8_t> Bytes, uint64_t Address,
7267fc5b874SRafael Espindola                                       uint64_t &Size, uint32_t &Insn,
7277fc5b874SRafael Espindola                                       bool IsBigEndian, bool IsMicroMips) {
72871928e68SAkira Hatanaka   // We want to read exactly 4 Bytes of data.
7297fc5b874SRafael Espindola   if (Bytes.size() < 4) {
7304aa6bea7SRafael Espindola     Size = 0;
73171928e68SAkira Hatanaka     return MCDisassembler::Fail;
73271928e68SAkira Hatanaka   }
73371928e68SAkira Hatanaka 
734*ea22c4cfSJozef Kolek   // High 16 bits of a 32-bit microMIPS instruction (where the opcode is)
735*ea22c4cfSJozef Kolek   // always precede the low 16 bits in the instruction stream (that is, they
736*ea22c4cfSJozef Kolek   // are placed at lower addresses in the instruction stream).
737*ea22c4cfSJozef Kolek   //
738*ea22c4cfSJozef Kolek   // microMIPS byte ordering:
739*ea22c4cfSJozef Kolek   //   Big-endian:    0 | 1 | 2 | 3
740*ea22c4cfSJozef Kolek   //   Little-endian: 1 | 0 | 3 | 2
741*ea22c4cfSJozef Kolek 
7424aa6bea7SRafael Espindola   if (IsBigEndian) {
74371928e68SAkira Hatanaka     // Encoded as a big-endian 32-bit word in the stream.
7444aa6bea7SRafael Espindola     Insn =
7454aa6bea7SRafael Espindola         (Bytes[3] << 0) | (Bytes[2] << 8) | (Bytes[1] << 16) | (Bytes[0] << 24);
7464aa6bea7SRafael Espindola   } else {
747dde3d582SVladimir Medic     if (IsMicroMips) {
7484aa6bea7SRafael Espindola       Insn = (Bytes[2] << 0) | (Bytes[3] << 8) | (Bytes[0] << 16) |
749dde3d582SVladimir Medic              (Bytes[1] << 24);
750dde3d582SVladimir Medic     } else {
7514aa6bea7SRafael Espindola       Insn = (Bytes[0] << 0) | (Bytes[1] << 8) | (Bytes[2] << 16) |
75271928e68SAkira Hatanaka              (Bytes[3] << 24);
75371928e68SAkira Hatanaka     }
754dde3d582SVladimir Medic   }
75571928e68SAkira Hatanaka 
75671928e68SAkira Hatanaka   return MCDisassembler::Success;
75771928e68SAkira Hatanaka }
75871928e68SAkira Hatanaka 
7594aa6bea7SRafael Espindola DecodeStatus MipsDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,
7607fc5b874SRafael Espindola                                               ArrayRef<uint8_t> Bytes,
76171928e68SAkira Hatanaka                                               uint64_t Address,
7624aa6bea7SRafael Espindola                                               raw_ostream &VStream,
7634aa6bea7SRafael Espindola                                               raw_ostream &CStream) const {
76471928e68SAkira Hatanaka   uint32_t Insn;
765*ea22c4cfSJozef Kolek   DecodeStatus Result;
76671928e68SAkira Hatanaka 
767*ea22c4cfSJozef Kolek   if (IsMicroMips) {
768*ea22c4cfSJozef Kolek     Result = readInstruction16(Bytes, Address, Size, Insn, IsBigEndian);
769*ea22c4cfSJozef Kolek 
770*ea22c4cfSJozef Kolek     DEBUG(dbgs() << "Trying MicroMips16 table (16-bit instructions):\n");
771*ea22c4cfSJozef Kolek     // Calling the auto-generated decoder function.
772*ea22c4cfSJozef Kolek     Result = decodeInstruction(DecoderTableMicroMips16, Instr, Insn, Address,
773*ea22c4cfSJozef Kolek                                this, STI);
774*ea22c4cfSJozef Kolek     if (Result != MCDisassembler::Fail) {
775*ea22c4cfSJozef Kolek       Size = 2;
776*ea22c4cfSJozef Kolek       return Result;
777*ea22c4cfSJozef Kolek     }
778*ea22c4cfSJozef Kolek 
779*ea22c4cfSJozef Kolek     Result = readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, true);
78071928e68SAkira Hatanaka     if (Result == MCDisassembler::Fail)
78171928e68SAkira Hatanaka       return MCDisassembler::Fail;
78271928e68SAkira Hatanaka 
783*ea22c4cfSJozef Kolek     DEBUG(dbgs() << "Trying MicroMips32 table (32-bit instructions):\n");
784dde3d582SVladimir Medic     // Calling the auto-generated decoder function.
7854aa6bea7SRafael Espindola     Result = decodeInstruction(DecoderTableMicroMips32, Instr, Insn, Address,
786dde3d582SVladimir Medic                                this, STI);
787dde3d582SVladimir Medic     if (Result != MCDisassembler::Fail) {
788dde3d582SVladimir Medic       Size = 4;
789dde3d582SVladimir Medic       return Result;
790dde3d582SVladimir Medic     }
791dde3d582SVladimir Medic     return MCDisassembler::Fail;
792dde3d582SVladimir Medic   }
793dde3d582SVladimir Medic 
794*ea22c4cfSJozef Kolek   Result = readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, false);
795*ea22c4cfSJozef Kolek   if (Result == MCDisassembler::Fail)
796*ea22c4cfSJozef Kolek     return MCDisassembler::Fail;
797*ea22c4cfSJozef Kolek 
798c171f65aSDaniel Sanders   if (hasCOP3()) {
799c171f65aSDaniel Sanders     DEBUG(dbgs() << "Trying COP3_ table (32-bit opcodes):\n");
800c171f65aSDaniel Sanders     Result =
8014aa6bea7SRafael Espindola         decodeInstruction(DecoderTableCOP3_32, Instr, Insn, Address, this, STI);
802c171f65aSDaniel Sanders     if (Result != MCDisassembler::Fail) {
803c171f65aSDaniel Sanders       Size = 4;
804c171f65aSDaniel Sanders       return Result;
805c171f65aSDaniel Sanders     }
806c171f65aSDaniel Sanders   }
807c171f65aSDaniel Sanders 
808c171f65aSDaniel Sanders   if (hasMips32r6() && isGP64()) {
8090fa60416SDaniel Sanders     DEBUG(dbgs() << "Trying Mips32r6_64r6 (GPR64) table (32-bit opcodes):\n");
8104aa6bea7SRafael Espindola     Result = decodeInstruction(DecoderTableMips32r6_64r6_GP6432, Instr, Insn,
8110fa60416SDaniel Sanders                                Address, this, STI);
8120fa60416SDaniel Sanders     if (Result != MCDisassembler::Fail) {
8130fa60416SDaniel Sanders       Size = 4;
8140fa60416SDaniel Sanders       return Result;
8150fa60416SDaniel Sanders     }
8160fa60416SDaniel Sanders   }
8170fa60416SDaniel Sanders 
818c171f65aSDaniel Sanders   if (hasMips32r6()) {
8190fa60416SDaniel Sanders     DEBUG(dbgs() << "Trying Mips32r6_64r6 table (32-bit opcodes):\n");
8204aa6bea7SRafael Espindola     Result = decodeInstruction(DecoderTableMips32r6_64r632, Instr, Insn,
8215c582b2fSDaniel Sanders                                Address, this, STI);
8225c582b2fSDaniel Sanders     if (Result != MCDisassembler::Fail) {
8235c582b2fSDaniel Sanders       Size = 4;
8245c582b2fSDaniel Sanders       return Result;
8255c582b2fSDaniel Sanders     }
8265c582b2fSDaniel Sanders   }
8275c582b2fSDaniel Sanders 
8280fa60416SDaniel Sanders   DEBUG(dbgs() << "Trying Mips table (32-bit opcodes):\n");
82971928e68SAkira Hatanaka   // Calling the auto-generated decoder function.
8304aa6bea7SRafael Espindola   Result =
8314aa6bea7SRafael Espindola       decodeInstruction(DecoderTableMips32, Instr, Insn, Address, this, STI);
83271928e68SAkira Hatanaka   if (Result != MCDisassembler::Fail) {
83371928e68SAkira Hatanaka     Size = 4;
83471928e68SAkira Hatanaka     return Result;
83571928e68SAkira Hatanaka   }
83671928e68SAkira Hatanaka 
83771928e68SAkira Hatanaka   return MCDisassembler::Fail;
83871928e68SAkira Hatanaka }
83971928e68SAkira Hatanaka 
8404aa6bea7SRafael Espindola DecodeStatus Mips64Disassembler::getInstruction(MCInst &Instr, uint64_t &Size,
8417fc5b874SRafael Espindola                                                 ArrayRef<uint8_t> Bytes,
84271928e68SAkira Hatanaka                                                 uint64_t Address,
8434aa6bea7SRafael Espindola                                                 raw_ostream &VStream,
8444aa6bea7SRafael Espindola                                                 raw_ostream &CStream) const {
84571928e68SAkira Hatanaka   uint32_t Insn;
84671928e68SAkira Hatanaka 
8474aa6bea7SRafael Espindola   DecodeStatus Result =
8487fc5b874SRafael Espindola       readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, false);
84971928e68SAkira Hatanaka   if (Result == MCDisassembler::Fail)
85071928e68SAkira Hatanaka     return MCDisassembler::Fail;
85171928e68SAkira Hatanaka 
85271928e68SAkira Hatanaka   // Calling the auto-generated decoder function.
8534aa6bea7SRafael Espindola   Result =
8544aa6bea7SRafael Espindola       decodeInstruction(DecoderTableMips6432, Instr, Insn, Address, this, STI);
85571928e68SAkira Hatanaka   if (Result != MCDisassembler::Fail) {
85671928e68SAkira Hatanaka     Size = 4;
85771928e68SAkira Hatanaka     return Result;
85871928e68SAkira Hatanaka   }
85971928e68SAkira Hatanaka   // If we fail to decode in Mips64 decoder space we can try in Mips32
8604aa6bea7SRafael Espindola   Result =
8614aa6bea7SRafael Espindola       decodeInstruction(DecoderTableMips32, Instr, Insn, Address, this, STI);
86271928e68SAkira Hatanaka   if (Result != MCDisassembler::Fail) {
86371928e68SAkira Hatanaka     Size = 4;
86471928e68SAkira Hatanaka     return Result;
86571928e68SAkira Hatanaka   }
86671928e68SAkira Hatanaka 
86771928e68SAkira Hatanaka   return MCDisassembler::Fail;
86871928e68SAkira Hatanaka }
86971928e68SAkira Hatanaka 
870ec8a5490SReed Kotler static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst,
871ec8a5490SReed Kotler                                                  unsigned RegNo,
872ec8a5490SReed Kotler                                                  uint64_t Address,
873ec8a5490SReed Kotler                                                  const void *Decoder) {
874ec8a5490SReed Kotler 
875ec8a5490SReed Kotler   return MCDisassembler::Fail;
876ec8a5490SReed Kotler 
877ec8a5490SReed Kotler }
878ec8a5490SReed Kotler 
87913e6ccf3SAkira Hatanaka static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst,
88071928e68SAkira Hatanaka                                              unsigned RegNo,
88171928e68SAkira Hatanaka                                              uint64_t Address,
88271928e68SAkira Hatanaka                                              const void *Decoder) {
88371928e68SAkira Hatanaka 
88471928e68SAkira Hatanaka   if (RegNo > 31)
88571928e68SAkira Hatanaka     return MCDisassembler::Fail;
88671928e68SAkira Hatanaka 
88713e6ccf3SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::GPR64RegClassID, RegNo);
8889bf2b567SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
88971928e68SAkira Hatanaka   return MCDisassembler::Success;
89071928e68SAkira Hatanaka }
89171928e68SAkira Hatanaka 
892b0852e54SZoran Jovanovic static DecodeStatus DecodeGPRMM16RegisterClass(MCInst &Inst,
893b0852e54SZoran Jovanovic                                                unsigned RegNo,
894b0852e54SZoran Jovanovic                                                uint64_t Address,
895b0852e54SZoran Jovanovic                                                const void *Decoder) {
896*ea22c4cfSJozef Kolek   if (RegNo > 7)
897b0852e54SZoran Jovanovic     return MCDisassembler::Fail;
898*ea22c4cfSJozef Kolek   unsigned Reg = getReg(Decoder, Mips::GPRMM16RegClassID, RegNo);
899*ea22c4cfSJozef Kolek   Inst.addOperand(MCOperand::CreateReg(Reg));
900*ea22c4cfSJozef Kolek   return MCDisassembler::Success;
901b0852e54SZoran Jovanovic }
902b0852e54SZoran Jovanovic 
90313e6ccf3SAkira Hatanaka static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst,
90471928e68SAkira Hatanaka                                              unsigned RegNo,
90571928e68SAkira Hatanaka                                              uint64_t Address,
90671928e68SAkira Hatanaka                                              const void *Decoder) {
90771928e68SAkira Hatanaka   if (RegNo > 31)
90871928e68SAkira Hatanaka     return MCDisassembler::Fail;
90913e6ccf3SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::GPR32RegClassID, RegNo);
9109bf2b567SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
91171928e68SAkira Hatanaka   return MCDisassembler::Success;
91271928e68SAkira Hatanaka }
91371928e68SAkira Hatanaka 
9149bfa2e2eSAkira Hatanaka static DecodeStatus DecodePtrRegisterClass(MCInst &Inst,
9159bfa2e2eSAkira Hatanaka                                            unsigned RegNo,
9169bfa2e2eSAkira Hatanaka                                            uint64_t Address,
9179bfa2e2eSAkira Hatanaka                                            const void *Decoder) {
9189bfa2e2eSAkira Hatanaka   if (static_cast<const MipsDisassembler *>(Decoder)->isN64())
9199bfa2e2eSAkira Hatanaka     return DecodeGPR64RegisterClass(Inst, RegNo, Address, Decoder);
9209bfa2e2eSAkira Hatanaka 
9219bfa2e2eSAkira Hatanaka   return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
9229bfa2e2eSAkira Hatanaka }
9239bfa2e2eSAkira Hatanaka 
924654655f1SAkira Hatanaka static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst,
925ecabd1a5SAkira Hatanaka                                             unsigned RegNo,
926ecabd1a5SAkira Hatanaka                                             uint64_t Address,
927ecabd1a5SAkira Hatanaka                                             const void *Decoder) {
92813e6ccf3SAkira Hatanaka   return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
929ecabd1a5SAkira Hatanaka }
930ecabd1a5SAkira Hatanaka 
93171928e68SAkira Hatanaka static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
93271928e68SAkira Hatanaka                                              unsigned RegNo,
93371928e68SAkira Hatanaka                                              uint64_t Address,
93471928e68SAkira Hatanaka                                              const void *Decoder) {
93571928e68SAkira Hatanaka   if (RegNo > 31)
93671928e68SAkira Hatanaka     return MCDisassembler::Fail;
93771928e68SAkira Hatanaka 
9389bf2b567SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::FGR64RegClassID, RegNo);
9399bf2b567SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
94071928e68SAkira Hatanaka   return MCDisassembler::Success;
94171928e68SAkira Hatanaka }
94271928e68SAkira Hatanaka 
94371928e68SAkira Hatanaka static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
94471928e68SAkira Hatanaka                                              unsigned RegNo,
94571928e68SAkira Hatanaka                                              uint64_t Address,
94671928e68SAkira Hatanaka                                              const void *Decoder) {
94771928e68SAkira Hatanaka   if (RegNo > 31)
94871928e68SAkira Hatanaka     return MCDisassembler::Fail;
94971928e68SAkira Hatanaka 
9509bf2b567SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::FGR32RegClassID, RegNo);
9519bf2b567SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
95271928e68SAkira Hatanaka   return MCDisassembler::Success;
95371928e68SAkira Hatanaka }
95471928e68SAkira Hatanaka 
95571928e68SAkira Hatanaka static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
95671928e68SAkira Hatanaka                                            unsigned RegNo,
95771928e68SAkira Hatanaka                                            uint64_t Address,
95871928e68SAkira Hatanaka                                            const void *Decoder) {
959253777fdSChad Rosier   if (RegNo > 31)
960253777fdSChad Rosier     return MCDisassembler::Fail;
961253777fdSChad Rosier   unsigned Reg = getReg(Decoder, Mips::CCRRegClassID, RegNo);
962253777fdSChad Rosier   Inst.addOperand(MCOperand::CreateReg(Reg));
96371928e68SAkira Hatanaka   return MCDisassembler::Success;
96471928e68SAkira Hatanaka }
96571928e68SAkira Hatanaka 
9661fb1b8b8SAkira Hatanaka static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst,
9671fb1b8b8SAkira Hatanaka                                            unsigned RegNo,
9681fb1b8b8SAkira Hatanaka                                            uint64_t Address,
9691fb1b8b8SAkira Hatanaka                                            const void *Decoder) {
9701fb1b8b8SAkira Hatanaka   if (RegNo > 7)
9711fb1b8b8SAkira Hatanaka     return MCDisassembler::Fail;
9721fb1b8b8SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::FCCRegClassID, RegNo);
9731fb1b8b8SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
9741fb1b8b8SAkira Hatanaka   return MCDisassembler::Success;
9751fb1b8b8SAkira Hatanaka }
9761fb1b8b8SAkira Hatanaka 
9770fa60416SDaniel Sanders static DecodeStatus DecodeFGRCCRegisterClass(MCInst &Inst, unsigned RegNo,
9780fa60416SDaniel Sanders                                              uint64_t Address,
9790fa60416SDaniel Sanders                                              const void *Decoder) {
9800fa60416SDaniel Sanders   if (RegNo > 31)
9810fa60416SDaniel Sanders     return MCDisassembler::Fail;
9820fa60416SDaniel Sanders 
9830fa60416SDaniel Sanders   unsigned Reg = getReg(Decoder, Mips::FGRCCRegClassID, RegNo);
9840fa60416SDaniel Sanders   Inst.addOperand(MCOperand::CreateReg(Reg));
9850fa60416SDaniel Sanders   return MCDisassembler::Success;
9860fa60416SDaniel Sanders }
9870fa60416SDaniel Sanders 
98871928e68SAkira Hatanaka static DecodeStatus DecodeMem(MCInst &Inst,
98971928e68SAkira Hatanaka                               unsigned Insn,
99071928e68SAkira Hatanaka                               uint64_t Address,
99171928e68SAkira Hatanaka                               const void *Decoder) {
99271928e68SAkira Hatanaka   int Offset = SignExtend32<16>(Insn & 0xffff);
993ecaef49fSJim Grosbach   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
994ecaef49fSJim Grosbach   unsigned Base = fieldFromInstruction(Insn, 21, 5);
9959bf2b567SAkira Hatanaka 
99613e6ccf3SAkira Hatanaka   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
99713e6ccf3SAkira Hatanaka   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
99871928e68SAkira Hatanaka 
99971928e68SAkira Hatanaka   if(Inst.getOpcode() == Mips::SC){
10009bf2b567SAkira Hatanaka     Inst.addOperand(MCOperand::CreateReg(Reg));
100171928e68SAkira Hatanaka   }
100271928e68SAkira Hatanaka 
10039bf2b567SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
10049bf2b567SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Base));
100571928e68SAkira Hatanaka   Inst.addOperand(MCOperand::CreateImm(Offset));
100671928e68SAkira Hatanaka 
100771928e68SAkira Hatanaka   return MCDisassembler::Success;
100871928e68SAkira Hatanaka }
100971928e68SAkira Hatanaka 
101092db6b78SDaniel Sanders static DecodeStatus DecodeCacheOp(MCInst &Inst,
101192db6b78SDaniel Sanders                               unsigned Insn,
101292db6b78SDaniel Sanders                               uint64_t Address,
101392db6b78SDaniel Sanders                               const void *Decoder) {
101492db6b78SDaniel Sanders   int Offset = SignExtend32<16>(Insn & 0xffff);
101592db6b78SDaniel Sanders   unsigned Hint = fieldFromInstruction(Insn, 16, 5);
101692db6b78SDaniel Sanders   unsigned Base = fieldFromInstruction(Insn, 21, 5);
101792db6b78SDaniel Sanders 
101892db6b78SDaniel Sanders   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
101992db6b78SDaniel Sanders 
102092db6b78SDaniel Sanders   Inst.addOperand(MCOperand::CreateReg(Base));
102192db6b78SDaniel Sanders   Inst.addOperand(MCOperand::CreateImm(Offset));
102292db6b78SDaniel Sanders   Inst.addOperand(MCOperand::CreateImm(Hint));
102392db6b78SDaniel Sanders 
102492db6b78SDaniel Sanders   return MCDisassembler::Success;
102592db6b78SDaniel Sanders }
102692db6b78SDaniel Sanders 
1027fe0bf9f6SMatheus Almeida static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn,
1028fe0bf9f6SMatheus Almeida                                     uint64_t Address, const void *Decoder) {
1029fe0bf9f6SMatheus Almeida   int Offset = SignExtend32<10>(fieldFromInstruction(Insn, 16, 10));
1030fe0bf9f6SMatheus Almeida   unsigned Reg = fieldFromInstruction(Insn, 6, 5);
1031fe0bf9f6SMatheus Almeida   unsigned Base = fieldFromInstruction(Insn, 11, 5);
1032fe0bf9f6SMatheus Almeida 
1033fe0bf9f6SMatheus Almeida   Reg = getReg(Decoder, Mips::MSA128BRegClassID, Reg);
1034fe0bf9f6SMatheus Almeida   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1035fe0bf9f6SMatheus Almeida 
1036fe0bf9f6SMatheus Almeida   Inst.addOperand(MCOperand::CreateReg(Reg));
1037fe0bf9f6SMatheus Almeida   Inst.addOperand(MCOperand::CreateReg(Base));
10386b59c449SMatheus Almeida 
10396b59c449SMatheus Almeida   // The immediate field of an LD/ST instruction is scaled which means it must
10406b59c449SMatheus Almeida   // be multiplied (when decoding) by the size (in bytes) of the instructions'
10416b59c449SMatheus Almeida   // data format.
10426b59c449SMatheus Almeida   // .b - 1 byte
10436b59c449SMatheus Almeida   // .h - 2 bytes
10446b59c449SMatheus Almeida   // .w - 4 bytes
10456b59c449SMatheus Almeida   // .d - 8 bytes
10466b59c449SMatheus Almeida   switch(Inst.getOpcode())
10476b59c449SMatheus Almeida   {
10486b59c449SMatheus Almeida   default:
10496b59c449SMatheus Almeida     assert (0 && "Unexpected instruction");
10506b59c449SMatheus Almeida     return MCDisassembler::Fail;
10516b59c449SMatheus Almeida     break;
10526b59c449SMatheus Almeida   case Mips::LD_B:
10536b59c449SMatheus Almeida   case Mips::ST_B:
1054fe0bf9f6SMatheus Almeida     Inst.addOperand(MCOperand::CreateImm(Offset));
10556b59c449SMatheus Almeida     break;
10566b59c449SMatheus Almeida   case Mips::LD_H:
10576b59c449SMatheus Almeida   case Mips::ST_H:
1058d37bab61SAlexey Samsonov     Inst.addOperand(MCOperand::CreateImm(Offset * 2));
10596b59c449SMatheus Almeida     break;
10606b59c449SMatheus Almeida   case Mips::LD_W:
10616b59c449SMatheus Almeida   case Mips::ST_W:
1062d37bab61SAlexey Samsonov     Inst.addOperand(MCOperand::CreateImm(Offset * 4));
10636b59c449SMatheus Almeida     break;
10646b59c449SMatheus Almeida   case Mips::LD_D:
10656b59c449SMatheus Almeida   case Mips::ST_D:
1066d37bab61SAlexey Samsonov     Inst.addOperand(MCOperand::CreateImm(Offset * 8));
10676b59c449SMatheus Almeida     break;
10686b59c449SMatheus Almeida   }
1069fe0bf9f6SMatheus Almeida 
1070fe0bf9f6SMatheus Almeida   return MCDisassembler::Success;
1071fe0bf9f6SMatheus Almeida }
1072fe0bf9f6SMatheus Almeida 
1073dde3d582SVladimir Medic static DecodeStatus DecodeMemMMImm12(MCInst &Inst,
1074dde3d582SVladimir Medic                                      unsigned Insn,
1075dde3d582SVladimir Medic                                      uint64_t Address,
1076dde3d582SVladimir Medic                                      const void *Decoder) {
1077dde3d582SVladimir Medic   int Offset = SignExtend32<12>(Insn & 0x0fff);
1078dde3d582SVladimir Medic   unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1079dde3d582SVladimir Medic   unsigned Base = fieldFromInstruction(Insn, 16, 5);
1080dde3d582SVladimir Medic 
1081dde3d582SVladimir Medic   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1082dde3d582SVladimir Medic   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1083dde3d582SVladimir Medic 
1084a4c4b5fcSZoran Jovanovic   switch (Inst.getOpcode()) {
1085a4c4b5fcSZoran Jovanovic   case Mips::SWM32_MM:
1086a4c4b5fcSZoran Jovanovic   case Mips::LWM32_MM:
1087a4c4b5fcSZoran Jovanovic     if (DecodeRegListOperand(Inst, Insn, Address, Decoder)
1088a4c4b5fcSZoran Jovanovic         == MCDisassembler::Fail)
1089a4c4b5fcSZoran Jovanovic       return MCDisassembler::Fail;
1090a4c4b5fcSZoran Jovanovic     Inst.addOperand(MCOperand::CreateReg(Base));
1091a4c4b5fcSZoran Jovanovic     Inst.addOperand(MCOperand::CreateImm(Offset));
1092a4c4b5fcSZoran Jovanovic     break;
1093a4c4b5fcSZoran Jovanovic   case Mips::SC_MM:
1094285cc289SZoran Jovanovic     Inst.addOperand(MCOperand::CreateReg(Reg));
1095a4c4b5fcSZoran Jovanovic     // fallthrough
1096a4c4b5fcSZoran Jovanovic   default:
1097dde3d582SVladimir Medic     Inst.addOperand(MCOperand::CreateReg(Reg));
1098dde3d582SVladimir Medic     Inst.addOperand(MCOperand::CreateReg(Base));
1099dde3d582SVladimir Medic     Inst.addOperand(MCOperand::CreateImm(Offset));
1100a4c4b5fcSZoran Jovanovic   }
1101dde3d582SVladimir Medic 
1102dde3d582SVladimir Medic   return MCDisassembler::Success;
1103dde3d582SVladimir Medic }
1104dde3d582SVladimir Medic 
1105dde3d582SVladimir Medic static DecodeStatus DecodeMemMMImm16(MCInst &Inst,
1106dde3d582SVladimir Medic                                      unsigned Insn,
1107dde3d582SVladimir Medic                                      uint64_t Address,
1108dde3d582SVladimir Medic                                      const void *Decoder) {
1109dde3d582SVladimir Medic   int Offset = SignExtend32<16>(Insn & 0xffff);
1110dde3d582SVladimir Medic   unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1111dde3d582SVladimir Medic   unsigned Base = fieldFromInstruction(Insn, 16, 5);
1112dde3d582SVladimir Medic 
1113dde3d582SVladimir Medic   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1114dde3d582SVladimir Medic   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1115dde3d582SVladimir Medic 
1116dde3d582SVladimir Medic   Inst.addOperand(MCOperand::CreateReg(Reg));
1117dde3d582SVladimir Medic   Inst.addOperand(MCOperand::CreateReg(Base));
1118dde3d582SVladimir Medic   Inst.addOperand(MCOperand::CreateImm(Offset));
1119dde3d582SVladimir Medic 
1120dde3d582SVladimir Medic   return MCDisassembler::Success;
1121dde3d582SVladimir Medic }
1122dde3d582SVladimir Medic 
112371928e68SAkira Hatanaka static DecodeStatus DecodeFMem(MCInst &Inst,
112471928e68SAkira Hatanaka                                unsigned Insn,
112571928e68SAkira Hatanaka                                uint64_t Address,
112671928e68SAkira Hatanaka                                const void *Decoder) {
112771928e68SAkira Hatanaka   int Offset = SignExtend32<16>(Insn & 0xffff);
1128ecaef49fSJim Grosbach   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1129ecaef49fSJim Grosbach   unsigned Base = fieldFromInstruction(Insn, 21, 5);
113071928e68SAkira Hatanaka 
11319bf2b567SAkira Hatanaka   Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg);
113213e6ccf3SAkira Hatanaka   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
11339bf2b567SAkira Hatanaka 
11349bf2b567SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
11359bf2b567SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Base));
113671928e68SAkira Hatanaka   Inst.addOperand(MCOperand::CreateImm(Offset));
113771928e68SAkira Hatanaka 
113871928e68SAkira Hatanaka   return MCDisassembler::Success;
113971928e68SAkira Hatanaka }
114071928e68SAkira Hatanaka 
114192db6b78SDaniel Sanders static DecodeStatus DecodeFMem2(MCInst &Inst,
114292db6b78SDaniel Sanders                                unsigned Insn,
114392db6b78SDaniel Sanders                                uint64_t Address,
114492db6b78SDaniel Sanders                                const void *Decoder) {
114592db6b78SDaniel Sanders   int Offset = SignExtend32<16>(Insn & 0xffff);
114692db6b78SDaniel Sanders   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
114792db6b78SDaniel Sanders   unsigned Base = fieldFromInstruction(Insn, 21, 5);
114892db6b78SDaniel Sanders 
114992db6b78SDaniel Sanders   Reg = getReg(Decoder, Mips::COP2RegClassID, Reg);
115092db6b78SDaniel Sanders   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
115192db6b78SDaniel Sanders 
115292db6b78SDaniel Sanders   Inst.addOperand(MCOperand::CreateReg(Reg));
115392db6b78SDaniel Sanders   Inst.addOperand(MCOperand::CreateReg(Base));
115492db6b78SDaniel Sanders   Inst.addOperand(MCOperand::CreateImm(Offset));
115592db6b78SDaniel Sanders 
115692db6b78SDaniel Sanders   return MCDisassembler::Success;
115792db6b78SDaniel Sanders }
115892db6b78SDaniel Sanders 
115992db6b78SDaniel Sanders static DecodeStatus DecodeFMem3(MCInst &Inst,
116092db6b78SDaniel Sanders                                unsigned Insn,
116192db6b78SDaniel Sanders                                uint64_t Address,
116292db6b78SDaniel Sanders                                const void *Decoder) {
116392db6b78SDaniel Sanders   int Offset = SignExtend32<16>(Insn & 0xffff);
116492db6b78SDaniel Sanders   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
116592db6b78SDaniel Sanders   unsigned Base = fieldFromInstruction(Insn, 21, 5);
116692db6b78SDaniel Sanders 
116792db6b78SDaniel Sanders   Reg = getReg(Decoder, Mips::COP3RegClassID, Reg);
116892db6b78SDaniel Sanders   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
116992db6b78SDaniel Sanders 
117092db6b78SDaniel Sanders   Inst.addOperand(MCOperand::CreateReg(Reg));
117192db6b78SDaniel Sanders   Inst.addOperand(MCOperand::CreateReg(Base));
117292db6b78SDaniel Sanders   Inst.addOperand(MCOperand::CreateImm(Offset));
117392db6b78SDaniel Sanders 
117492db6b78SDaniel Sanders   return MCDisassembler::Success;
117592db6b78SDaniel Sanders }
117692db6b78SDaniel Sanders 
11776a803f61SDaniel Sanders static DecodeStatus DecodeSpecial3LlSc(MCInst &Inst,
11786a803f61SDaniel Sanders                                        unsigned Insn,
11796a803f61SDaniel Sanders                                        uint64_t Address,
11806a803f61SDaniel Sanders                                        const void *Decoder) {
11816a803f61SDaniel Sanders   int64_t Offset = SignExtend64<9>((Insn >> 7) & 0x1ff);
11826a803f61SDaniel Sanders   unsigned Rt = fieldFromInstruction(Insn, 16, 5);
11836a803f61SDaniel Sanders   unsigned Base = fieldFromInstruction(Insn, 21, 5);
11846a803f61SDaniel Sanders 
11856a803f61SDaniel Sanders   Rt = getReg(Decoder, Mips::GPR32RegClassID, Rt);
11866a803f61SDaniel Sanders   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
11876a803f61SDaniel Sanders 
11886a803f61SDaniel Sanders   if(Inst.getOpcode() == Mips::SC_R6 || Inst.getOpcode() == Mips::SCD_R6){
11896a803f61SDaniel Sanders     Inst.addOperand(MCOperand::CreateReg(Rt));
11906a803f61SDaniel Sanders   }
11916a803f61SDaniel Sanders 
11926a803f61SDaniel Sanders   Inst.addOperand(MCOperand::CreateReg(Rt));
11936a803f61SDaniel Sanders   Inst.addOperand(MCOperand::CreateReg(Base));
11946a803f61SDaniel Sanders   Inst.addOperand(MCOperand::CreateImm(Offset));
11956a803f61SDaniel Sanders 
11966a803f61SDaniel Sanders   return MCDisassembler::Success;
11976a803f61SDaniel Sanders }
119871928e68SAkira Hatanaka 
119971928e68SAkira Hatanaka static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
120071928e68SAkira Hatanaka                                               unsigned RegNo,
120171928e68SAkira Hatanaka                                               uint64_t Address,
120271928e68SAkira Hatanaka                                               const void *Decoder) {
120371928e68SAkira Hatanaka   // Currently only hardware register 29 is supported.
120471928e68SAkira Hatanaka   if (RegNo != 29)
120571928e68SAkira Hatanaka     return  MCDisassembler::Fail;
120671928e68SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Mips::HWR29));
120771928e68SAkira Hatanaka   return MCDisassembler::Success;
120871928e68SAkira Hatanaka }
120971928e68SAkira Hatanaka 
121071928e68SAkira Hatanaka static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
121171928e68SAkira Hatanaka                                               unsigned RegNo,
121271928e68SAkira Hatanaka                                               uint64_t Address,
121371928e68SAkira Hatanaka                                               const void *Decoder) {
12149bf2b567SAkira Hatanaka   if (RegNo > 30 || RegNo %2)
121571928e68SAkira Hatanaka     return MCDisassembler::Fail;
121671928e68SAkira Hatanaka 
12179bf2b567SAkira Hatanaka   ;
12189bf2b567SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::AFGR64RegClassID, RegNo /2);
12199bf2b567SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
122071928e68SAkira Hatanaka   return MCDisassembler::Success;
122171928e68SAkira Hatanaka }
122271928e68SAkira Hatanaka 
122300fcf2e1SAkira Hatanaka static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst,
1224ecabd1a5SAkira Hatanaka                                                 unsigned RegNo,
1225ecabd1a5SAkira Hatanaka                                                 uint64_t Address,
1226ecabd1a5SAkira Hatanaka                                                 const void *Decoder) {
1227ecabd1a5SAkira Hatanaka   if (RegNo >= 4)
1228ecabd1a5SAkira Hatanaka     return MCDisassembler::Fail;
1229ecabd1a5SAkira Hatanaka 
123000fcf2e1SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::ACC64DSPRegClassID, RegNo);
1231ecabd1a5SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
1232ecabd1a5SAkira Hatanaka   return MCDisassembler::Success;
1233ecabd1a5SAkira Hatanaka }
1234ecabd1a5SAkira Hatanaka 
12358002a3f6SAkira Hatanaka static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst,
123659bfaf77SAkira Hatanaka                                                unsigned RegNo,
123759bfaf77SAkira Hatanaka                                                uint64_t Address,
123859bfaf77SAkira Hatanaka                                                const void *Decoder) {
123959bfaf77SAkira Hatanaka   if (RegNo >= 4)
124059bfaf77SAkira Hatanaka     return MCDisassembler::Fail;
124159bfaf77SAkira Hatanaka 
12428002a3f6SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::HI32DSPRegClassID, RegNo);
124359bfaf77SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
124459bfaf77SAkira Hatanaka   return MCDisassembler::Success;
124559bfaf77SAkira Hatanaka }
124659bfaf77SAkira Hatanaka 
12478002a3f6SAkira Hatanaka static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst,
124859bfaf77SAkira Hatanaka                                                unsigned RegNo,
124959bfaf77SAkira Hatanaka                                                uint64_t Address,
125059bfaf77SAkira Hatanaka                                                const void *Decoder) {
125159bfaf77SAkira Hatanaka   if (RegNo >= 4)
125259bfaf77SAkira Hatanaka     return MCDisassembler::Fail;
125359bfaf77SAkira Hatanaka 
12548002a3f6SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::LO32DSPRegClassID, RegNo);
125559bfaf77SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
125659bfaf77SAkira Hatanaka   return MCDisassembler::Success;
125759bfaf77SAkira Hatanaka }
125859bfaf77SAkira Hatanaka 
12593eb663b0SJack Carter static DecodeStatus DecodeMSA128BRegisterClass(MCInst &Inst,
12603eb663b0SJack Carter                                                unsigned RegNo,
12613eb663b0SJack Carter                                                uint64_t Address,
12623eb663b0SJack Carter                                                const void *Decoder) {
12633eb663b0SJack Carter   if (RegNo > 31)
12643eb663b0SJack Carter     return MCDisassembler::Fail;
12653eb663b0SJack Carter 
12663eb663b0SJack Carter   unsigned Reg = getReg(Decoder, Mips::MSA128BRegClassID, RegNo);
12673eb663b0SJack Carter   Inst.addOperand(MCOperand::CreateReg(Reg));
12683eb663b0SJack Carter   return MCDisassembler::Success;
12693eb663b0SJack Carter }
12703eb663b0SJack Carter 
12715dc8ac92SJack Carter static DecodeStatus DecodeMSA128HRegisterClass(MCInst &Inst,
12725dc8ac92SJack Carter                                                unsigned RegNo,
12735dc8ac92SJack Carter                                                uint64_t Address,
12745dc8ac92SJack Carter                                                const void *Decoder) {
12755dc8ac92SJack Carter   if (RegNo > 31)
12765dc8ac92SJack Carter     return MCDisassembler::Fail;
12775dc8ac92SJack Carter 
12785dc8ac92SJack Carter   unsigned Reg = getReg(Decoder, Mips::MSA128HRegClassID, RegNo);
12795dc8ac92SJack Carter   Inst.addOperand(MCOperand::CreateReg(Reg));
12805dc8ac92SJack Carter   return MCDisassembler::Success;
12815dc8ac92SJack Carter }
12825dc8ac92SJack Carter 
12835dc8ac92SJack Carter static DecodeStatus DecodeMSA128WRegisterClass(MCInst &Inst,
12845dc8ac92SJack Carter                                                unsigned RegNo,
12855dc8ac92SJack Carter                                                uint64_t Address,
12865dc8ac92SJack Carter                                                const void *Decoder) {
12875dc8ac92SJack Carter   if (RegNo > 31)
12885dc8ac92SJack Carter     return MCDisassembler::Fail;
12895dc8ac92SJack Carter 
12905dc8ac92SJack Carter   unsigned Reg = getReg(Decoder, Mips::MSA128WRegClassID, RegNo);
12915dc8ac92SJack Carter   Inst.addOperand(MCOperand::CreateReg(Reg));
12925dc8ac92SJack Carter   return MCDisassembler::Success;
12935dc8ac92SJack Carter }
12945dc8ac92SJack Carter 
12955dc8ac92SJack Carter static DecodeStatus DecodeMSA128DRegisterClass(MCInst &Inst,
12965dc8ac92SJack Carter                                                unsigned RegNo,
12975dc8ac92SJack Carter                                                uint64_t Address,
12985dc8ac92SJack Carter                                                const void *Decoder) {
12995dc8ac92SJack Carter   if (RegNo > 31)
13005dc8ac92SJack Carter     return MCDisassembler::Fail;
13015dc8ac92SJack Carter 
13025dc8ac92SJack Carter   unsigned Reg = getReg(Decoder, Mips::MSA128DRegClassID, RegNo);
13035dc8ac92SJack Carter   Inst.addOperand(MCOperand::CreateReg(Reg));
13045dc8ac92SJack Carter   return MCDisassembler::Success;
13055dc8ac92SJack Carter }
13065dc8ac92SJack Carter 
1307a591fdc6SMatheus Almeida static DecodeStatus DecodeMSACtrlRegisterClass(MCInst &Inst,
1308a591fdc6SMatheus Almeida                                                unsigned RegNo,
1309a591fdc6SMatheus Almeida                                                uint64_t Address,
1310a591fdc6SMatheus Almeida                                                const void *Decoder) {
1311a591fdc6SMatheus Almeida   if (RegNo > 7)
1312a591fdc6SMatheus Almeida     return MCDisassembler::Fail;
1313a591fdc6SMatheus Almeida 
1314a591fdc6SMatheus Almeida   unsigned Reg = getReg(Decoder, Mips::MSACtrlRegClassID, RegNo);
1315a591fdc6SMatheus Almeida   Inst.addOperand(MCOperand::CreateReg(Reg));
1316a591fdc6SMatheus Almeida   return MCDisassembler::Success;
1317a591fdc6SMatheus Almeida }
1318a591fdc6SMatheus Almeida 
13192a83d680SDaniel Sanders static DecodeStatus DecodeCOP2RegisterClass(MCInst &Inst,
13202a83d680SDaniel Sanders                                             unsigned RegNo,
13212a83d680SDaniel Sanders                                             uint64_t Address,
13222a83d680SDaniel Sanders                                             const void *Decoder) {
13232a83d680SDaniel Sanders   if (RegNo > 31)
13242a83d680SDaniel Sanders     return MCDisassembler::Fail;
13252a83d680SDaniel Sanders 
13262a83d680SDaniel Sanders   unsigned Reg = getReg(Decoder, Mips::COP2RegClassID, RegNo);
13272a83d680SDaniel Sanders   Inst.addOperand(MCOperand::CreateReg(Reg));
13282a83d680SDaniel Sanders   return MCDisassembler::Success;
13292a83d680SDaniel Sanders }
13302a83d680SDaniel Sanders 
133171928e68SAkira Hatanaka static DecodeStatus DecodeBranchTarget(MCInst &Inst,
133271928e68SAkira Hatanaka                                        unsigned Offset,
133371928e68SAkira Hatanaka                                        uint64_t Address,
133471928e68SAkira Hatanaka                                        const void *Decoder) {
1335d37bab61SAlexey Samsonov   int32_t BranchOffset = (SignExtend32<16>(Offset) * 4) + 4;
133671928e68SAkira Hatanaka   Inst.addOperand(MCOperand::CreateImm(BranchOffset));
133771928e68SAkira Hatanaka   return MCDisassembler::Success;
133871928e68SAkira Hatanaka }
133971928e68SAkira Hatanaka 
134071928e68SAkira Hatanaka static DecodeStatus DecodeJumpTarget(MCInst &Inst,
134171928e68SAkira Hatanaka                                      unsigned Insn,
134271928e68SAkira Hatanaka                                      uint64_t Address,
134371928e68SAkira Hatanaka                                      const void *Decoder) {
134471928e68SAkira Hatanaka 
1345ecaef49fSJim Grosbach   unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 2;
134671928e68SAkira Hatanaka   Inst.addOperand(MCOperand::CreateImm(JumpOffset));
134771928e68SAkira Hatanaka   return MCDisassembler::Success;
134871928e68SAkira Hatanaka }
134971928e68SAkira Hatanaka 
13503c8869dcSZoran Jovanovic static DecodeStatus DecodeBranchTarget21(MCInst &Inst,
13513c8869dcSZoran Jovanovic                                          unsigned Offset,
13523c8869dcSZoran Jovanovic                                          uint64_t Address,
13533c8869dcSZoran Jovanovic                                          const void *Decoder) {
1354d37bab61SAlexey Samsonov   int32_t BranchOffset = SignExtend32<21>(Offset) * 4;
13553c8869dcSZoran Jovanovic 
13563c8869dcSZoran Jovanovic   Inst.addOperand(MCOperand::CreateImm(BranchOffset));
13573c8869dcSZoran Jovanovic   return MCDisassembler::Success;
13583c8869dcSZoran Jovanovic }
13593c8869dcSZoran Jovanovic 
13603c8869dcSZoran Jovanovic static DecodeStatus DecodeBranchTarget26(MCInst &Inst,
13613c8869dcSZoran Jovanovic                                          unsigned Offset,
13623c8869dcSZoran Jovanovic                                          uint64_t Address,
13633c8869dcSZoran Jovanovic                                          const void *Decoder) {
1364d37bab61SAlexey Samsonov   int32_t BranchOffset = SignExtend32<26>(Offset) * 4;
13653c8869dcSZoran Jovanovic 
13663c8869dcSZoran Jovanovic   Inst.addOperand(MCOperand::CreateImm(BranchOffset));
13673c8869dcSZoran Jovanovic   return MCDisassembler::Success;
13683c8869dcSZoran Jovanovic }
13693c8869dcSZoran Jovanovic 
13708a80aa76SZoran Jovanovic static DecodeStatus DecodeBranchTargetMM(MCInst &Inst,
13718a80aa76SZoran Jovanovic                                          unsigned Offset,
13728a80aa76SZoran Jovanovic                                          uint64_t Address,
13738a80aa76SZoran Jovanovic                                          const void *Decoder) {
1374d37bab61SAlexey Samsonov   int32_t BranchOffset = SignExtend32<16>(Offset) * 2;
13758a80aa76SZoran Jovanovic   Inst.addOperand(MCOperand::CreateImm(BranchOffset));
13768a80aa76SZoran Jovanovic   return MCDisassembler::Success;
13778a80aa76SZoran Jovanovic }
13788a80aa76SZoran Jovanovic 
1379507e084aSZoran Jovanovic static DecodeStatus DecodeJumpTargetMM(MCInst &Inst,
1380507e084aSZoran Jovanovic                                        unsigned Insn,
1381507e084aSZoran Jovanovic                                        uint64_t Address,
1382507e084aSZoran Jovanovic                                        const void *Decoder) {
1383507e084aSZoran Jovanovic   unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 1;
1384507e084aSZoran Jovanovic   Inst.addOperand(MCOperand::CreateImm(JumpOffset));
1385507e084aSZoran Jovanovic   return MCDisassembler::Success;
1386507e084aSZoran Jovanovic }
138771928e68SAkira Hatanaka 
138871928e68SAkira Hatanaka static DecodeStatus DecodeSimm16(MCInst &Inst,
138971928e68SAkira Hatanaka                                  unsigned Insn,
139071928e68SAkira Hatanaka                                  uint64_t Address,
139171928e68SAkira Hatanaka                                  const void *Decoder) {
139271928e68SAkira Hatanaka   Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Insn)));
139371928e68SAkira Hatanaka   return MCDisassembler::Success;
139471928e68SAkira Hatanaka }
139571928e68SAkira Hatanaka 
1396779c5937SMatheus Almeida static DecodeStatus DecodeLSAImm(MCInst &Inst,
1397779c5937SMatheus Almeida                                  unsigned Insn,
1398779c5937SMatheus Almeida                                  uint64_t Address,
1399779c5937SMatheus Almeida                                  const void *Decoder) {
1400779c5937SMatheus Almeida   // We add one to the immediate field as it was encoded as 'imm - 1'.
1401779c5937SMatheus Almeida   Inst.addOperand(MCOperand::CreateImm(Insn + 1));
1402779c5937SMatheus Almeida   return MCDisassembler::Success;
1403779c5937SMatheus Almeida }
1404779c5937SMatheus Almeida 
140571928e68SAkira Hatanaka static DecodeStatus DecodeInsSize(MCInst &Inst,
140671928e68SAkira Hatanaka                                   unsigned Insn,
140771928e68SAkira Hatanaka                                   uint64_t Address,
140871928e68SAkira Hatanaka                                   const void *Decoder) {
140971928e68SAkira Hatanaka   // First we need to grab the pos(lsb) from MCInst.
141071928e68SAkira Hatanaka   int Pos = Inst.getOperand(2).getImm();
141171928e68SAkira Hatanaka   int Size = (int) Insn - Pos + 1;
141271928e68SAkira Hatanaka   Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size)));
141371928e68SAkira Hatanaka   return MCDisassembler::Success;
141471928e68SAkira Hatanaka }
141571928e68SAkira Hatanaka 
141671928e68SAkira Hatanaka static DecodeStatus DecodeExtSize(MCInst &Inst,
141771928e68SAkira Hatanaka                                   unsigned Insn,
141871928e68SAkira Hatanaka                                   uint64_t Address,
141971928e68SAkira Hatanaka                                   const void *Decoder) {
142071928e68SAkira Hatanaka   int Size = (int) Insn  + 1;
142171928e68SAkira Hatanaka   Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size)));
142271928e68SAkira Hatanaka   return MCDisassembler::Success;
142371928e68SAkira Hatanaka }
1424b59e1a41SDaniel Sanders 
1425b59e1a41SDaniel Sanders static DecodeStatus DecodeSimm19Lsl2(MCInst &Inst, unsigned Insn,
1426b59e1a41SDaniel Sanders                                      uint64_t Address, const void *Decoder) {
1427d37bab61SAlexey Samsonov   Inst.addOperand(MCOperand::CreateImm(SignExtend32<19>(Insn) * 4));
1428b59e1a41SDaniel Sanders   return MCDisassembler::Success;
1429b59e1a41SDaniel Sanders }
14302855142aSZoran Jovanovic 
14312855142aSZoran Jovanovic static DecodeStatus DecodeSimm18Lsl3(MCInst &Inst, unsigned Insn,
14322855142aSZoran Jovanovic                                      uint64_t Address, const void *Decoder) {
1433d37bab61SAlexey Samsonov   Inst.addOperand(MCOperand::CreateImm(SignExtend32<18>(Insn) * 8));
14342855142aSZoran Jovanovic   return MCDisassembler::Success;
14352855142aSZoran Jovanovic }
1436a4c4b5fcSZoran Jovanovic 
1437a4c4b5fcSZoran Jovanovic static DecodeStatus DecodeRegListOperand(MCInst &Inst,
1438a4c4b5fcSZoran Jovanovic                                          unsigned Insn,
1439a4c4b5fcSZoran Jovanovic                                          uint64_t Address,
1440a4c4b5fcSZoran Jovanovic                                          const void *Decoder) {
1441a4c4b5fcSZoran Jovanovic   unsigned Regs[] = {Mips::S0, Mips::S1, Mips::S2, Mips::S3, Mips::S4, Mips::S5,
1442a4c4b5fcSZoran Jovanovic                      Mips::S6, Mips::FP};
1443a4c4b5fcSZoran Jovanovic   unsigned RegNum;
1444a4c4b5fcSZoran Jovanovic 
1445a4c4b5fcSZoran Jovanovic   unsigned RegLst = fieldFromInstruction(Insn, 21, 5);
1446a4c4b5fcSZoran Jovanovic   // Empty register lists are not allowed.
1447a4c4b5fcSZoran Jovanovic   if (RegLst == 0)
1448a4c4b5fcSZoran Jovanovic     return MCDisassembler::Fail;
1449a4c4b5fcSZoran Jovanovic 
1450a4c4b5fcSZoran Jovanovic   RegNum = RegLst & 0xf;
1451a4c4b5fcSZoran Jovanovic   for (unsigned i = 0; i < RegNum; i++)
1452a4c4b5fcSZoran Jovanovic     Inst.addOperand(MCOperand::CreateReg(Regs[i]));
1453a4c4b5fcSZoran Jovanovic 
1454a4c4b5fcSZoran Jovanovic   if (RegLst & 0x10)
1455a4c4b5fcSZoran Jovanovic     Inst.addOperand(MCOperand::CreateReg(Mips::RA));
1456a4c4b5fcSZoran Jovanovic 
1457a4c4b5fcSZoran Jovanovic   return MCDisassembler::Success;
1458a4c4b5fcSZoran Jovanovic }
1459