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),
39e8860938SVladimir Medic         IsGP64Bit(STI.getFeatureBits() & Mips::FeatureGP64Bit),
404aa6bea7SRafael Espindola         IsBigEndian(IsBigEndian) {}
4171928e68SAkira Hatanaka 
429bf2b567SAkira Hatanaka   virtual ~MipsDisassemblerBase() {}
439bf2b567SAkira Hatanaka 
44e8860938SVladimir Medic   bool isGP64Bit() const { return IsGP64Bit; }
459bfa2e2eSAkira Hatanaka 
469bf2b567SAkira Hatanaka private:
47e8860938SVladimir Medic   bool IsGP64Bit;
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 
1121904fa21SJozef Kolek static DecodeStatus DecodeGPRMM16ZeroRegisterClass(MCInst &Inst,
1131904fa21SJozef Kolek                                                    unsigned RegNo,
1141904fa21SJozef Kolek                                                    uint64_t Address,
1151904fa21SJozef Kolek                                                    const void *Decoder);
1161904fa21SJozef Kolek 
11713e6ccf3SAkira Hatanaka static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst,
11871928e68SAkira Hatanaka                                              unsigned RegNo,
11971928e68SAkira Hatanaka                                              uint64_t Address,
12071928e68SAkira Hatanaka                                              const void *Decoder);
12171928e68SAkira Hatanaka 
1229bfa2e2eSAkira Hatanaka static DecodeStatus DecodePtrRegisterClass(MCInst &Inst,
1239bfa2e2eSAkira Hatanaka                                            unsigned Insn,
1249bfa2e2eSAkira Hatanaka                                            uint64_t Address,
1259bfa2e2eSAkira Hatanaka                                            const void *Decoder);
1269bfa2e2eSAkira Hatanaka 
127654655f1SAkira Hatanaka static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst,
128ecabd1a5SAkira Hatanaka                                             unsigned RegNo,
129ecabd1a5SAkira Hatanaka                                             uint64_t Address,
130ecabd1a5SAkira Hatanaka                                             const void *Decoder);
131ecabd1a5SAkira Hatanaka 
13271928e68SAkira Hatanaka static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
13371928e68SAkira Hatanaka                                              unsigned RegNo,
13471928e68SAkira Hatanaka                                              uint64_t Address,
13571928e68SAkira Hatanaka                                              const void *Decoder);
13671928e68SAkira Hatanaka 
13771928e68SAkira Hatanaka static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
13871928e68SAkira Hatanaka                                              unsigned RegNo,
13971928e68SAkira Hatanaka                                              uint64_t Address,
14071928e68SAkira Hatanaka                                              const void *Decoder);
14171928e68SAkira Hatanaka 
14271928e68SAkira Hatanaka static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
14371928e68SAkira Hatanaka                                            unsigned RegNo,
14471928e68SAkira Hatanaka                                            uint64_t Address,
14571928e68SAkira Hatanaka                                            const void *Decoder);
14671928e68SAkira Hatanaka 
1471fb1b8b8SAkira Hatanaka static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst,
1481fb1b8b8SAkira Hatanaka                                            unsigned RegNo,
1491fb1b8b8SAkira Hatanaka                                            uint64_t Address,
1501fb1b8b8SAkira Hatanaka                                            const void *Decoder);
1511fb1b8b8SAkira Hatanaka 
1520fa60416SDaniel Sanders static DecodeStatus DecodeFGRCCRegisterClass(MCInst &Inst, unsigned RegNo,
1530fa60416SDaniel Sanders                                              uint64_t Address,
1540fa60416SDaniel Sanders                                              const void *Decoder);
1550fa60416SDaniel Sanders 
15671928e68SAkira Hatanaka static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
15771928e68SAkira Hatanaka                                               unsigned Insn,
15871928e68SAkira Hatanaka                                               uint64_t Address,
15971928e68SAkira Hatanaka                                               const void *Decoder);
16071928e68SAkira Hatanaka 
16171928e68SAkira Hatanaka static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
16271928e68SAkira Hatanaka                                               unsigned RegNo,
16371928e68SAkira Hatanaka                                               uint64_t Address,
16471928e68SAkira Hatanaka                                               const void *Decoder);
16571928e68SAkira Hatanaka 
16600fcf2e1SAkira Hatanaka static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst,
167ecabd1a5SAkira Hatanaka                                                 unsigned RegNo,
168ecabd1a5SAkira Hatanaka                                                 uint64_t Address,
169ecabd1a5SAkira Hatanaka                                                 const void *Decoder);
170ecabd1a5SAkira Hatanaka 
1718002a3f6SAkira Hatanaka static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst,
17259bfaf77SAkira Hatanaka                                                unsigned RegNo,
17359bfaf77SAkira Hatanaka                                                uint64_t Address,
17459bfaf77SAkira Hatanaka                                                const void *Decoder);
17559bfaf77SAkira Hatanaka 
1768002a3f6SAkira Hatanaka static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst,
17759bfaf77SAkira Hatanaka                                                unsigned RegNo,
17859bfaf77SAkira Hatanaka                                                uint64_t Address,
17959bfaf77SAkira Hatanaka                                                const void *Decoder);
18059bfaf77SAkira Hatanaka 
1813eb663b0SJack Carter static DecodeStatus DecodeMSA128BRegisterClass(MCInst &Inst,
1823eb663b0SJack Carter                                                unsigned RegNo,
1833eb663b0SJack Carter                                                uint64_t Address,
1843eb663b0SJack Carter                                                const void *Decoder);
1853eb663b0SJack Carter 
1865dc8ac92SJack Carter static DecodeStatus DecodeMSA128HRegisterClass(MCInst &Inst,
1875dc8ac92SJack Carter                                                unsigned RegNo,
1885dc8ac92SJack Carter                                                uint64_t Address,
1895dc8ac92SJack Carter                                                const void *Decoder);
1905dc8ac92SJack Carter 
1915dc8ac92SJack Carter static DecodeStatus DecodeMSA128WRegisterClass(MCInst &Inst,
1925dc8ac92SJack Carter                                                unsigned RegNo,
1935dc8ac92SJack Carter                                                uint64_t Address,
1945dc8ac92SJack Carter                                                const void *Decoder);
1955dc8ac92SJack Carter 
1965dc8ac92SJack Carter static DecodeStatus DecodeMSA128DRegisterClass(MCInst &Inst,
1975dc8ac92SJack Carter                                                unsigned RegNo,
1985dc8ac92SJack Carter                                                uint64_t Address,
1995dc8ac92SJack Carter                                                const void *Decoder);
2005dc8ac92SJack Carter 
201a591fdc6SMatheus Almeida static DecodeStatus DecodeMSACtrlRegisterClass(MCInst &Inst,
202a591fdc6SMatheus Almeida                                                unsigned RegNo,
203a591fdc6SMatheus Almeida                                                uint64_t Address,
204a591fdc6SMatheus Almeida                                                const void *Decoder);
205a591fdc6SMatheus Almeida 
2062a83d680SDaniel Sanders static DecodeStatus DecodeCOP2RegisterClass(MCInst &Inst,
2072a83d680SDaniel Sanders                                             unsigned RegNo,
2082a83d680SDaniel Sanders                                             uint64_t Address,
2092a83d680SDaniel Sanders                                             const void *Decoder);
2102a83d680SDaniel Sanders 
21171928e68SAkira Hatanaka static DecodeStatus DecodeBranchTarget(MCInst &Inst,
21271928e68SAkira Hatanaka                                        unsigned Offset,
21371928e68SAkira Hatanaka                                        uint64_t Address,
21471928e68SAkira Hatanaka                                        const void *Decoder);
21571928e68SAkira Hatanaka 
21671928e68SAkira Hatanaka static DecodeStatus DecodeJumpTarget(MCInst &Inst,
21771928e68SAkira Hatanaka                                      unsigned Insn,
21871928e68SAkira Hatanaka                                      uint64_t Address,
21971928e68SAkira Hatanaka                                      const void *Decoder);
22071928e68SAkira Hatanaka 
2213c8869dcSZoran Jovanovic static DecodeStatus DecodeBranchTarget21(MCInst &Inst,
2223c8869dcSZoran Jovanovic                                          unsigned Offset,
2233c8869dcSZoran Jovanovic                                          uint64_t Address,
2243c8869dcSZoran Jovanovic                                          const void *Decoder);
2253c8869dcSZoran Jovanovic 
2263c8869dcSZoran Jovanovic static DecodeStatus DecodeBranchTarget26(MCInst &Inst,
2273c8869dcSZoran Jovanovic                                          unsigned Offset,
2283c8869dcSZoran Jovanovic                                          uint64_t Address,
2293c8869dcSZoran Jovanovic                                          const void *Decoder);
2303c8869dcSZoran Jovanovic 
2319761e96bSJozef Kolek // DecodeBranchTarget7MM - Decode microMIPS branch offset, which is
2329761e96bSJozef Kolek // shifted left by 1 bit.
2339761e96bSJozef Kolek static DecodeStatus DecodeBranchTarget7MM(MCInst &Inst,
2349761e96bSJozef Kolek                                           unsigned Offset,
2359761e96bSJozef Kolek                                           uint64_t Address,
2369761e96bSJozef Kolek                                           const void *Decoder);
2379761e96bSJozef Kolek 
2388a80aa76SZoran Jovanovic // DecodeBranchTargetMM - Decode microMIPS branch offset, which is
2398a80aa76SZoran Jovanovic // shifted left by 1 bit.
2408a80aa76SZoran Jovanovic static DecodeStatus DecodeBranchTargetMM(MCInst &Inst,
2418a80aa76SZoran Jovanovic                                          unsigned Offset,
2428a80aa76SZoran Jovanovic                                          uint64_t Address,
2438a80aa76SZoran Jovanovic                                          const void *Decoder);
2448a80aa76SZoran Jovanovic 
245507e084aSZoran Jovanovic // DecodeJumpTargetMM - Decode microMIPS jump target, which is
246507e084aSZoran Jovanovic // shifted left by 1 bit.
247507e084aSZoran Jovanovic static DecodeStatus DecodeJumpTargetMM(MCInst &Inst,
248507e084aSZoran Jovanovic                                        unsigned Insn,
249507e084aSZoran Jovanovic                                        uint64_t Address,
250507e084aSZoran Jovanovic                                        const void *Decoder);
251507e084aSZoran Jovanovic 
25271928e68SAkira Hatanaka static DecodeStatus DecodeMem(MCInst &Inst,
25371928e68SAkira Hatanaka                               unsigned Insn,
25471928e68SAkira Hatanaka                               uint64_t Address,
25571928e68SAkira Hatanaka                               const void *Decoder);
25671928e68SAkira Hatanaka 
25792db6b78SDaniel Sanders static DecodeStatus DecodeCacheOp(MCInst &Inst,
25892db6b78SDaniel Sanders                               unsigned Insn,
25992db6b78SDaniel Sanders                               uint64_t Address,
26092db6b78SDaniel Sanders                               const void *Decoder);
26192db6b78SDaniel Sanders 
262ab6d1cceSJozef Kolek static DecodeStatus DecodeCacheOpMM(MCInst &Inst,
263ab6d1cceSJozef Kolek                                     unsigned Insn,
264ab6d1cceSJozef Kolek                                     uint64_t Address,
265ab6d1cceSJozef Kolek                                     const void *Decoder);
266ab6d1cceSJozef Kolek 
267b4484d62SDaniel Sanders static DecodeStatus DecodeSyncI(MCInst &Inst,
268b4484d62SDaniel Sanders                                 unsigned Insn,
269b4484d62SDaniel Sanders                                 uint64_t Address,
270b4484d62SDaniel Sanders                                 const void *Decoder);
271b4484d62SDaniel Sanders 
272fe0bf9f6SMatheus Almeida static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn,
273fe0bf9f6SMatheus Almeida                                     uint64_t Address, const void *Decoder);
274fe0bf9f6SMatheus Almeida 
275315e7ecaSJozef Kolek static DecodeStatus DecodeMemMMImm4(MCInst &Inst,
276315e7ecaSJozef Kolek                                     unsigned Insn,
277315e7ecaSJozef Kolek                                     uint64_t Address,
278315e7ecaSJozef Kolek                                     const void *Decoder);
279315e7ecaSJozef Kolek 
28012c6982bSJozef Kolek static DecodeStatus DecodeMemMMSPImm5Lsl2(MCInst &Inst,
28112c6982bSJozef Kolek                                           unsigned Insn,
28212c6982bSJozef Kolek                                           uint64_t Address,
28312c6982bSJozef Kolek                                           const void *Decoder);
28412c6982bSJozef Kolek 
285dde3d582SVladimir Medic static DecodeStatus DecodeMemMMImm12(MCInst &Inst,
286dde3d582SVladimir Medic                                      unsigned Insn,
287dde3d582SVladimir Medic                                      uint64_t Address,
288dde3d582SVladimir Medic                                      const void *Decoder);
289dde3d582SVladimir Medic 
290dde3d582SVladimir Medic static DecodeStatus DecodeMemMMImm16(MCInst &Inst,
291dde3d582SVladimir Medic                                      unsigned Insn,
292dde3d582SVladimir Medic                                      uint64_t Address,
293dde3d582SVladimir Medic                                      const void *Decoder);
294dde3d582SVladimir Medic 
29571928e68SAkira Hatanaka static DecodeStatus DecodeFMem(MCInst &Inst, unsigned Insn,
29671928e68SAkira Hatanaka                                uint64_t Address,
29771928e68SAkira Hatanaka                                const void *Decoder);
29871928e68SAkira Hatanaka 
29992db6b78SDaniel Sanders static DecodeStatus DecodeFMem2(MCInst &Inst, unsigned Insn,
30092db6b78SDaniel Sanders                                uint64_t Address,
30192db6b78SDaniel Sanders                                const void *Decoder);
30292db6b78SDaniel Sanders 
30392db6b78SDaniel Sanders static DecodeStatus DecodeFMem3(MCInst &Inst, unsigned Insn,
30492db6b78SDaniel Sanders                                uint64_t Address,
30592db6b78SDaniel Sanders                                const void *Decoder);
30692db6b78SDaniel Sanders 
307*435cf8a4SVladimir Medic static DecodeStatus DecodeFMemCop2R6(MCInst &Inst, unsigned Insn,
308*435cf8a4SVladimir Medic                                uint64_t Address,
309*435cf8a4SVladimir Medic                                const void *Decoder);
310*435cf8a4SVladimir Medic 
3116a803f61SDaniel Sanders static DecodeStatus DecodeSpecial3LlSc(MCInst &Inst,
3126a803f61SDaniel Sanders                                        unsigned Insn,
3136a803f61SDaniel Sanders                                        uint64_t Address,
3146a803f61SDaniel Sanders                                        const void *Decoder);
3156a803f61SDaniel Sanders 
316aa2b9278SJozef Kolek static DecodeStatus DecodeAddiur2Simm7(MCInst &Inst,
317aa2b9278SJozef Kolek                                        unsigned Value,
318aa2b9278SJozef Kolek                                        uint64_t Address,
319aa2b9278SJozef Kolek                                        const void *Decoder);
320aa2b9278SJozef Kolek 
321aa2b9278SJozef Kolek static DecodeStatus DecodeUImm6Lsl2(MCInst &Inst,
322aa2b9278SJozef Kolek                                     unsigned Value,
323aa2b9278SJozef Kolek                                     uint64_t Address,
324aa2b9278SJozef Kolek                                     const void *Decoder);
325aa2b9278SJozef Kolek 
326aa2b9278SJozef Kolek static DecodeStatus DecodeLiSimm7(MCInst &Inst,
327aa2b9278SJozef Kolek                                   unsigned Value,
328aa2b9278SJozef Kolek                                   uint64_t Address,
329aa2b9278SJozef Kolek                                   const void *Decoder);
330aa2b9278SJozef Kolek 
331aa2b9278SJozef Kolek static DecodeStatus DecodeSimm4(MCInst &Inst,
332aa2b9278SJozef Kolek                                 unsigned Value,
333aa2b9278SJozef Kolek                                 uint64_t Address,
334aa2b9278SJozef Kolek                                 const void *Decoder);
335aa2b9278SJozef Kolek 
33671928e68SAkira Hatanaka static DecodeStatus DecodeSimm16(MCInst &Inst,
33771928e68SAkira Hatanaka                                  unsigned Insn,
33871928e68SAkira Hatanaka                                  uint64_t Address,
33971928e68SAkira Hatanaka                                  const void *Decoder);
34071928e68SAkira Hatanaka 
341779c5937SMatheus Almeida // Decode the immediate field of an LSA instruction which
342779c5937SMatheus Almeida // is off by one.
343779c5937SMatheus Almeida static DecodeStatus DecodeLSAImm(MCInst &Inst,
344779c5937SMatheus Almeida                                  unsigned Insn,
345779c5937SMatheus Almeida                                  uint64_t Address,
346779c5937SMatheus Almeida                                  const void *Decoder);
347779c5937SMatheus Almeida 
34871928e68SAkira Hatanaka static DecodeStatus DecodeInsSize(MCInst &Inst,
34971928e68SAkira Hatanaka                                   unsigned Insn,
35071928e68SAkira Hatanaka                                   uint64_t Address,
35171928e68SAkira Hatanaka                                   const void *Decoder);
35271928e68SAkira Hatanaka 
35371928e68SAkira Hatanaka static DecodeStatus DecodeExtSize(MCInst &Inst,
35471928e68SAkira Hatanaka                                   unsigned Insn,
35571928e68SAkira Hatanaka                                   uint64_t Address,
35671928e68SAkira Hatanaka                                   const void *Decoder);
35771928e68SAkira Hatanaka 
358b59e1a41SDaniel Sanders static DecodeStatus DecodeSimm19Lsl2(MCInst &Inst, unsigned Insn,
359b59e1a41SDaniel Sanders                                      uint64_t Address, const void *Decoder);
360b59e1a41SDaniel Sanders 
3612855142aSZoran Jovanovic static DecodeStatus DecodeSimm18Lsl3(MCInst &Inst, unsigned Insn,
3622855142aSZoran Jovanovic                                      uint64_t Address, const void *Decoder);
3632855142aSZoran Jovanovic 
364b682ddf3SVladimir Medic static DecodeStatus DecodeSimm9SP(MCInst &Inst, unsigned Insn,
365b682ddf3SVladimir Medic                                   uint64_t Address, const void *Decoder);
366b682ddf3SVladimir Medic 
367b682ddf3SVladimir Medic static DecodeStatus DecodeANDI16Imm(MCInst &Inst, unsigned Insn,
368b682ddf3SVladimir Medic                                     uint64_t Address, const void *Decoder);
369b682ddf3SVladimir Medic 
370b682ddf3SVladimir Medic static DecodeStatus DecodeUImm5lsl2(MCInst &Inst, unsigned Insn,
371b682ddf3SVladimir Medic                                    uint64_t Address, const void *Decoder);
372b682ddf3SVladimir Medic 
373b50ccf8eSDaniel Sanders /// INSVE_[BHWD] have an implicit operand that the generated decoder doesn't
374b50ccf8eSDaniel Sanders /// handle.
375b50ccf8eSDaniel Sanders template <typename InsnType>
376b50ccf8eSDaniel Sanders static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address,
377b50ccf8eSDaniel Sanders                                    const void *Decoder);
3785c582b2fSDaniel Sanders 
3795c582b2fSDaniel Sanders template <typename InsnType>
3805c582b2fSDaniel Sanders static DecodeStatus
3815c582b2fSDaniel Sanders DecodeAddiGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
3825c582b2fSDaniel Sanders                       const void *Decoder);
3835c582b2fSDaniel Sanders 
3845c582b2fSDaniel Sanders template <typename InsnType>
3855c582b2fSDaniel Sanders static DecodeStatus
3865c582b2fSDaniel Sanders DecodeDaddiGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
3875c582b2fSDaniel Sanders                        const void *Decoder);
3885c582b2fSDaniel Sanders 
3895c582b2fSDaniel Sanders template <typename InsnType>
3905c582b2fSDaniel Sanders static DecodeStatus
3915c582b2fSDaniel Sanders DecodeBlezlGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
3925c582b2fSDaniel Sanders                        const void *Decoder);
3935c582b2fSDaniel Sanders 
3945c582b2fSDaniel Sanders template <typename InsnType>
3955c582b2fSDaniel Sanders static DecodeStatus
3965c582b2fSDaniel Sanders DecodeBgtzlGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
3975c582b2fSDaniel Sanders                        const void *Decoder);
3985c582b2fSDaniel Sanders 
3995c582b2fSDaniel Sanders template <typename InsnType>
4005c582b2fSDaniel Sanders static DecodeStatus
4015c582b2fSDaniel Sanders DecodeBgtzGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
4025c582b2fSDaniel Sanders                       const void *Decoder);
4035c582b2fSDaniel Sanders 
40428a0ca07SZoran Jovanovic template <typename InsnType>
40528a0ca07SZoran Jovanovic static DecodeStatus
40628a0ca07SZoran Jovanovic DecodeBlezGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
40728a0ca07SZoran Jovanovic                        const void *Decoder);
40828a0ca07SZoran Jovanovic 
409a4c4b5fcSZoran Jovanovic static DecodeStatus DecodeRegListOperand(MCInst &Inst, unsigned Insn,
410a4c4b5fcSZoran Jovanovic                                          uint64_t Address,
411a4c4b5fcSZoran Jovanovic                                          const void *Decoder);
412a4c4b5fcSZoran Jovanovic 
413f9a02500SZoran Jovanovic static DecodeStatus DecodeRegListOperand16(MCInst &Inst, unsigned Insn,
414f9a02500SZoran Jovanovic                                            uint64_t Address,
415f9a02500SZoran Jovanovic                                            const void *Decoder);
416f9a02500SZoran Jovanovic 
41771928e68SAkira Hatanaka namespace llvm {
41871928e68SAkira Hatanaka extern Target TheMipselTarget, TheMipsTarget, TheMips64Target,
41971928e68SAkira Hatanaka               TheMips64elTarget;
42071928e68SAkira Hatanaka }
42171928e68SAkira Hatanaka 
42271928e68SAkira Hatanaka static MCDisassembler *createMipsDisassembler(
42371928e68SAkira Hatanaka                        const Target &T,
424a1bc0f56SLang Hames                        const MCSubtargetInfo &STI,
425a1bc0f56SLang Hames                        MCContext &Ctx) {
426a1bc0f56SLang Hames   return new MipsDisassembler(STI, Ctx, true);
42771928e68SAkira Hatanaka }
42871928e68SAkira Hatanaka 
42971928e68SAkira Hatanaka static MCDisassembler *createMipselDisassembler(
43071928e68SAkira Hatanaka                        const Target &T,
431a1bc0f56SLang Hames                        const MCSubtargetInfo &STI,
432a1bc0f56SLang Hames                        MCContext &Ctx) {
433a1bc0f56SLang Hames   return new MipsDisassembler(STI, Ctx, false);
43471928e68SAkira Hatanaka }
43571928e68SAkira Hatanaka 
43671928e68SAkira Hatanaka static MCDisassembler *createMips64Disassembler(
43771928e68SAkira Hatanaka                        const Target &T,
438a1bc0f56SLang Hames                        const MCSubtargetInfo &STI,
439a1bc0f56SLang Hames                        MCContext &Ctx) {
440a1bc0f56SLang Hames   return new Mips64Disassembler(STI, Ctx, true);
44171928e68SAkira Hatanaka }
44271928e68SAkira Hatanaka 
44371928e68SAkira Hatanaka static MCDisassembler *createMips64elDisassembler(
44471928e68SAkira Hatanaka                        const Target &T,
445a1bc0f56SLang Hames                        const MCSubtargetInfo &STI,
446a1bc0f56SLang Hames                        MCContext &Ctx) {
447a1bc0f56SLang Hames   return new Mips64Disassembler(STI, Ctx, false);
44871928e68SAkira Hatanaka }
44971928e68SAkira Hatanaka 
45071928e68SAkira Hatanaka extern "C" void LLVMInitializeMipsDisassembler() {
45171928e68SAkira Hatanaka   // Register the disassembler.
45271928e68SAkira Hatanaka   TargetRegistry::RegisterMCDisassembler(TheMipsTarget,
45371928e68SAkira Hatanaka                                          createMipsDisassembler);
45471928e68SAkira Hatanaka   TargetRegistry::RegisterMCDisassembler(TheMipselTarget,
45571928e68SAkira Hatanaka                                          createMipselDisassembler);
45671928e68SAkira Hatanaka   TargetRegistry::RegisterMCDisassembler(TheMips64Target,
45771928e68SAkira Hatanaka                                          createMips64Disassembler);
45871928e68SAkira Hatanaka   TargetRegistry::RegisterMCDisassembler(TheMips64elTarget,
45971928e68SAkira Hatanaka                                          createMips64elDisassembler);
46071928e68SAkira Hatanaka }
46171928e68SAkira Hatanaka 
46271928e68SAkira Hatanaka #include "MipsGenDisassemblerTables.inc"
46371928e68SAkira Hatanaka 
4645c582b2fSDaniel Sanders static unsigned getReg(const void *D, unsigned RC, unsigned RegNo) {
4655c582b2fSDaniel Sanders   const MipsDisassemblerBase *Dis = static_cast<const MipsDisassemblerBase*>(D);
4665c582b2fSDaniel Sanders   const MCRegisterInfo *RegInfo = Dis->getContext().getRegisterInfo();
4675c582b2fSDaniel Sanders   return *(RegInfo->getRegClass(RC).begin() + RegNo);
4685c582b2fSDaniel Sanders }
4695c582b2fSDaniel Sanders 
470b50ccf8eSDaniel Sanders template <typename InsnType>
471b50ccf8eSDaniel Sanders static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address,
472b50ccf8eSDaniel Sanders                                    const void *Decoder) {
473b50ccf8eSDaniel Sanders   typedef DecodeStatus (*DecodeFN)(MCInst &, unsigned, uint64_t, const void *);
474b50ccf8eSDaniel Sanders   // The size of the n field depends on the element size
475b50ccf8eSDaniel Sanders   // The register class also depends on this.
476b50ccf8eSDaniel Sanders   InsnType tmp = fieldFromInstruction(insn, 17, 5);
477b50ccf8eSDaniel Sanders   unsigned NSize = 0;
478b50ccf8eSDaniel Sanders   DecodeFN RegDecoder = nullptr;
479b50ccf8eSDaniel Sanders   if ((tmp & 0x18) == 0x00) { // INSVE_B
480b50ccf8eSDaniel Sanders     NSize = 4;
481b50ccf8eSDaniel Sanders     RegDecoder = DecodeMSA128BRegisterClass;
482b50ccf8eSDaniel Sanders   } else if ((tmp & 0x1c) == 0x10) { // INSVE_H
483b50ccf8eSDaniel Sanders     NSize = 3;
484b50ccf8eSDaniel Sanders     RegDecoder = DecodeMSA128HRegisterClass;
485b50ccf8eSDaniel Sanders   } else if ((tmp & 0x1e) == 0x18) { // INSVE_W
486b50ccf8eSDaniel Sanders     NSize = 2;
487b50ccf8eSDaniel Sanders     RegDecoder = DecodeMSA128WRegisterClass;
488b50ccf8eSDaniel Sanders   } else if ((tmp & 0x1f) == 0x1c) { // INSVE_D
489b50ccf8eSDaniel Sanders     NSize = 1;
490b50ccf8eSDaniel Sanders     RegDecoder = DecodeMSA128DRegisterClass;
491b50ccf8eSDaniel Sanders   } else
492b50ccf8eSDaniel Sanders     llvm_unreachable("Invalid encoding");
493b50ccf8eSDaniel Sanders 
494b50ccf8eSDaniel Sanders   assert(NSize != 0 && RegDecoder != nullptr);
495b50ccf8eSDaniel Sanders 
496b50ccf8eSDaniel Sanders   // $wd
497b50ccf8eSDaniel Sanders   tmp = fieldFromInstruction(insn, 6, 5);
498b50ccf8eSDaniel Sanders   if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
499b50ccf8eSDaniel Sanders     return MCDisassembler::Fail;
500b50ccf8eSDaniel Sanders   // $wd_in
501b50ccf8eSDaniel Sanders   if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
502b50ccf8eSDaniel Sanders     return MCDisassembler::Fail;
503b50ccf8eSDaniel Sanders   // $n
504b50ccf8eSDaniel Sanders   tmp = fieldFromInstruction(insn, 16, NSize);
505b50ccf8eSDaniel Sanders   MI.addOperand(MCOperand::CreateImm(tmp));
506b50ccf8eSDaniel Sanders   // $ws
507b50ccf8eSDaniel Sanders   tmp = fieldFromInstruction(insn, 11, 5);
508b50ccf8eSDaniel Sanders   if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
509b50ccf8eSDaniel Sanders     return MCDisassembler::Fail;
510b50ccf8eSDaniel Sanders   // $n2
511b50ccf8eSDaniel Sanders   MI.addOperand(MCOperand::CreateImm(0));
512b50ccf8eSDaniel Sanders 
513b50ccf8eSDaniel Sanders   return MCDisassembler::Success;
514b50ccf8eSDaniel Sanders }
515b50ccf8eSDaniel Sanders 
5165c582b2fSDaniel Sanders template <typename InsnType>
5175c582b2fSDaniel Sanders static DecodeStatus DecodeAddiGroupBranch(MCInst &MI, InsnType insn,
5185c582b2fSDaniel Sanders                                           uint64_t Address,
5195c582b2fSDaniel Sanders                                           const void *Decoder) {
5205c582b2fSDaniel Sanders   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
5215c582b2fSDaniel Sanders   // (otherwise we would have matched the ADDI instruction from the earlier
5225c582b2fSDaniel Sanders   // ISA's instead).
5235c582b2fSDaniel Sanders   //
5245c582b2fSDaniel Sanders   // We have:
5255c582b2fSDaniel Sanders   //    0b001000 sssss ttttt iiiiiiiiiiiiiiii
5265c582b2fSDaniel Sanders   //      BOVC if rs >= rt
5275c582b2fSDaniel Sanders   //      BEQZALC if rs == 0 && rt != 0
5285c582b2fSDaniel Sanders   //      BEQC if rs < rt && rs != 0
5295c582b2fSDaniel Sanders 
5305c582b2fSDaniel Sanders   InsnType Rs = fieldFromInstruction(insn, 21, 5);
5315c582b2fSDaniel Sanders   InsnType Rt = fieldFromInstruction(insn, 16, 5);
532d37bab61SAlexey Samsonov   InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4;
5335c582b2fSDaniel Sanders   bool HasRs = false;
5345c582b2fSDaniel Sanders 
5355c582b2fSDaniel Sanders   if (Rs >= Rt) {
5365c582b2fSDaniel Sanders     MI.setOpcode(Mips::BOVC);
5375c582b2fSDaniel Sanders     HasRs = true;
5385c582b2fSDaniel Sanders   } else if (Rs != 0 && Rs < Rt) {
5395c582b2fSDaniel Sanders     MI.setOpcode(Mips::BEQC);
5405c582b2fSDaniel Sanders     HasRs = true;
5415c582b2fSDaniel Sanders   } else
5425c582b2fSDaniel Sanders     MI.setOpcode(Mips::BEQZALC);
5435c582b2fSDaniel Sanders 
5445c582b2fSDaniel Sanders   if (HasRs)
5455c582b2fSDaniel Sanders     MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
5465c582b2fSDaniel Sanders                                        Rs)));
5475c582b2fSDaniel Sanders 
5485c582b2fSDaniel Sanders   MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
5495c582b2fSDaniel Sanders                                      Rt)));
5505c582b2fSDaniel Sanders   MI.addOperand(MCOperand::CreateImm(Imm));
5515c582b2fSDaniel Sanders 
5525c582b2fSDaniel Sanders   return MCDisassembler::Success;
5535c582b2fSDaniel Sanders }
5545c582b2fSDaniel Sanders 
5555c582b2fSDaniel Sanders template <typename InsnType>
5565c582b2fSDaniel Sanders static DecodeStatus DecodeDaddiGroupBranch(MCInst &MI, InsnType insn,
5575c582b2fSDaniel Sanders                                            uint64_t Address,
5585c582b2fSDaniel Sanders                                            const void *Decoder) {
5595c582b2fSDaniel Sanders   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
5605c582b2fSDaniel Sanders   // (otherwise we would have matched the ADDI instruction from the earlier
5615c582b2fSDaniel Sanders   // ISA's instead).
5625c582b2fSDaniel Sanders   //
5635c582b2fSDaniel Sanders   // We have:
5645c582b2fSDaniel Sanders   //    0b011000 sssss ttttt iiiiiiiiiiiiiiii
5655c582b2fSDaniel Sanders   //      BNVC if rs >= rt
5665c582b2fSDaniel Sanders   //      BNEZALC if rs == 0 && rt != 0
5675c582b2fSDaniel Sanders   //      BNEC if rs < rt && rs != 0
5685c582b2fSDaniel Sanders 
5695c582b2fSDaniel Sanders   InsnType Rs = fieldFromInstruction(insn, 21, 5);
5705c582b2fSDaniel Sanders   InsnType Rt = fieldFromInstruction(insn, 16, 5);
571d37bab61SAlexey Samsonov   InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4;
5725c582b2fSDaniel Sanders   bool HasRs = false;
5735c582b2fSDaniel Sanders 
5745c582b2fSDaniel Sanders   if (Rs >= Rt) {
5755c582b2fSDaniel Sanders     MI.setOpcode(Mips::BNVC);
5765c582b2fSDaniel Sanders     HasRs = true;
5775c582b2fSDaniel Sanders   } else if (Rs != 0 && Rs < Rt) {
5785c582b2fSDaniel Sanders     MI.setOpcode(Mips::BNEC);
5795c582b2fSDaniel Sanders     HasRs = true;
5805c582b2fSDaniel Sanders   } else
5815c582b2fSDaniel Sanders     MI.setOpcode(Mips::BNEZALC);
5825c582b2fSDaniel Sanders 
5835c582b2fSDaniel Sanders   if (HasRs)
5845c582b2fSDaniel Sanders     MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
5855c582b2fSDaniel Sanders                                        Rs)));
5865c582b2fSDaniel Sanders 
5875c582b2fSDaniel Sanders   MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
5885c582b2fSDaniel Sanders                                      Rt)));
5895c582b2fSDaniel Sanders   MI.addOperand(MCOperand::CreateImm(Imm));
5905c582b2fSDaniel Sanders 
5915c582b2fSDaniel Sanders   return MCDisassembler::Success;
5925c582b2fSDaniel Sanders }
5935c582b2fSDaniel Sanders 
5945c582b2fSDaniel Sanders template <typename InsnType>
5955c582b2fSDaniel Sanders static DecodeStatus DecodeBlezlGroupBranch(MCInst &MI, InsnType insn,
5965c582b2fSDaniel Sanders                                            uint64_t Address,
5975c582b2fSDaniel Sanders                                            const void *Decoder) {
5985c582b2fSDaniel Sanders   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
5995c582b2fSDaniel Sanders   // (otherwise we would have matched the BLEZL instruction from the earlier
6005c582b2fSDaniel Sanders   // ISA's instead).
6015c582b2fSDaniel Sanders   //
6025c582b2fSDaniel Sanders   // We have:
6035c582b2fSDaniel Sanders   //    0b010110 sssss ttttt iiiiiiiiiiiiiiii
6045c582b2fSDaniel Sanders   //      Invalid if rs == 0
6055c582b2fSDaniel Sanders   //      BLEZC   if rs == 0  && rt != 0
6065c582b2fSDaniel Sanders   //      BGEZC   if rs == rt && rt != 0
6075c582b2fSDaniel Sanders   //      BGEC    if rs != rt && rs != 0  && rt != 0
6085c582b2fSDaniel Sanders 
6095c582b2fSDaniel Sanders   InsnType Rs = fieldFromInstruction(insn, 21, 5);
6105c582b2fSDaniel Sanders   InsnType Rt = fieldFromInstruction(insn, 16, 5);
611d37bab61SAlexey Samsonov   InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4;
61228a0ca07SZoran Jovanovic   bool HasRs = false;
6135c582b2fSDaniel Sanders 
6145c582b2fSDaniel Sanders   if (Rt == 0)
6155c582b2fSDaniel Sanders     return MCDisassembler::Fail;
6165c582b2fSDaniel Sanders   else if (Rs == 0)
6175c582b2fSDaniel Sanders     MI.setOpcode(Mips::BLEZC);
6185c582b2fSDaniel Sanders   else if (Rs == Rt)
6195c582b2fSDaniel Sanders     MI.setOpcode(Mips::BGEZC);
62028a0ca07SZoran Jovanovic   else {
62128a0ca07SZoran Jovanovic     HasRs = true;
62228a0ca07SZoran Jovanovic     MI.setOpcode(Mips::BGEC);
62328a0ca07SZoran Jovanovic   }
62428a0ca07SZoran Jovanovic 
62528a0ca07SZoran Jovanovic   if (HasRs)
62628a0ca07SZoran Jovanovic     MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
62728a0ca07SZoran Jovanovic                                        Rs)));
6285c582b2fSDaniel Sanders 
6295c582b2fSDaniel Sanders   MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
6305c582b2fSDaniel Sanders                                      Rt)));
6315c582b2fSDaniel Sanders 
6325c582b2fSDaniel Sanders   MI.addOperand(MCOperand::CreateImm(Imm));
6335c582b2fSDaniel Sanders 
6345c582b2fSDaniel Sanders   return MCDisassembler::Success;
6355c582b2fSDaniel Sanders }
6365c582b2fSDaniel Sanders 
6375c582b2fSDaniel Sanders template <typename InsnType>
6385c582b2fSDaniel Sanders static DecodeStatus DecodeBgtzlGroupBranch(MCInst &MI, InsnType insn,
6395c582b2fSDaniel Sanders                                            uint64_t Address,
6405c582b2fSDaniel Sanders                                            const void *Decoder) {
6415c582b2fSDaniel Sanders   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
6425c582b2fSDaniel Sanders   // (otherwise we would have matched the BGTZL instruction from the earlier
6435c582b2fSDaniel Sanders   // ISA's instead).
6445c582b2fSDaniel Sanders   //
6455c582b2fSDaniel Sanders   // We have:
6465c582b2fSDaniel Sanders   //    0b010111 sssss ttttt iiiiiiiiiiiiiiii
6475c582b2fSDaniel Sanders   //      Invalid if rs == 0
6485c582b2fSDaniel Sanders   //      BGTZC   if rs == 0  && rt != 0
6495c582b2fSDaniel Sanders   //      BLTZC   if rs == rt && rt != 0
6505c582b2fSDaniel Sanders   //      BLTC    if rs != rt && rs != 0  && rt != 0
6515c582b2fSDaniel Sanders 
6525c14b069SZoran Jovanovic   bool HasRs = false;
6535c14b069SZoran Jovanovic 
6545c582b2fSDaniel Sanders   InsnType Rs = fieldFromInstruction(insn, 21, 5);
6555c582b2fSDaniel Sanders   InsnType Rt = fieldFromInstruction(insn, 16, 5);
656d37bab61SAlexey Samsonov   InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4;
6575c582b2fSDaniel Sanders 
6585c582b2fSDaniel Sanders   if (Rt == 0)
6595c582b2fSDaniel Sanders     return MCDisassembler::Fail;
6605c582b2fSDaniel Sanders   else if (Rs == 0)
6615c582b2fSDaniel Sanders     MI.setOpcode(Mips::BGTZC);
6625c582b2fSDaniel Sanders   else if (Rs == Rt)
6635c582b2fSDaniel Sanders     MI.setOpcode(Mips::BLTZC);
6645c14b069SZoran Jovanovic   else {
6655c14b069SZoran Jovanovic     MI.setOpcode(Mips::BLTC);
6665c14b069SZoran Jovanovic     HasRs = true;
6675c14b069SZoran Jovanovic   }
6685c14b069SZoran Jovanovic 
6695c14b069SZoran Jovanovic   if (HasRs)
6705c14b069SZoran Jovanovic     MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
6715c14b069SZoran Jovanovic                                               Rs)));
6725c582b2fSDaniel Sanders 
6735c582b2fSDaniel Sanders   MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
6745c582b2fSDaniel Sanders                                      Rt)));
6755c582b2fSDaniel Sanders 
6765c582b2fSDaniel Sanders   MI.addOperand(MCOperand::CreateImm(Imm));
6775c582b2fSDaniel Sanders 
6785c582b2fSDaniel Sanders   return MCDisassembler::Success;
6795c582b2fSDaniel Sanders }
6805c582b2fSDaniel Sanders 
6815c582b2fSDaniel Sanders template <typename InsnType>
6825c582b2fSDaniel Sanders static DecodeStatus DecodeBgtzGroupBranch(MCInst &MI, InsnType insn,
6835c582b2fSDaniel Sanders                                           uint64_t Address,
6845c582b2fSDaniel Sanders                                           const void *Decoder) {
6855c582b2fSDaniel Sanders   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
6865c582b2fSDaniel Sanders   // (otherwise we would have matched the BGTZ instruction from the earlier
6875c582b2fSDaniel Sanders   // ISA's instead).
6885c582b2fSDaniel Sanders   //
6895c582b2fSDaniel Sanders   // We have:
6905c582b2fSDaniel Sanders   //    0b000111 sssss ttttt iiiiiiiiiiiiiiii
6915c582b2fSDaniel Sanders   //      BGTZ    if rt == 0
6925c582b2fSDaniel Sanders   //      BGTZALC if rs == 0 && rt != 0
6935c582b2fSDaniel Sanders   //      BLTZALC if rs != 0 && rs == rt
6945c582b2fSDaniel Sanders   //      BLTUC   if rs != 0 && rs != rt
6955c582b2fSDaniel Sanders 
6965c582b2fSDaniel Sanders   InsnType Rs = fieldFromInstruction(insn, 21, 5);
6975c582b2fSDaniel Sanders   InsnType Rt = fieldFromInstruction(insn, 16, 5);
698d37bab61SAlexey Samsonov   InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4;
6995c582b2fSDaniel Sanders   bool HasRs = false;
7005c582b2fSDaniel Sanders   bool HasRt = false;
7015c582b2fSDaniel Sanders 
7025c582b2fSDaniel Sanders   if (Rt == 0) {
7035c582b2fSDaniel Sanders     MI.setOpcode(Mips::BGTZ);
7045c582b2fSDaniel Sanders     HasRs = true;
7055c582b2fSDaniel Sanders   } else if (Rs == 0) {
7065c582b2fSDaniel Sanders     MI.setOpcode(Mips::BGTZALC);
7075c582b2fSDaniel Sanders     HasRt = true;
7085c582b2fSDaniel Sanders   } else if (Rs == Rt) {
7095c582b2fSDaniel Sanders     MI.setOpcode(Mips::BLTZALC);
7105c582b2fSDaniel Sanders     HasRs = true;
7115c14b069SZoran Jovanovic   } else {
7125c14b069SZoran Jovanovic     MI.setOpcode(Mips::BLTUC);
7135c14b069SZoran Jovanovic     HasRs = true;
7145c14b069SZoran Jovanovic     HasRt = true;
7155c14b069SZoran Jovanovic   }
7165c582b2fSDaniel Sanders 
7175c582b2fSDaniel Sanders   if (HasRs)
7185c582b2fSDaniel Sanders     MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
7195c582b2fSDaniel Sanders                                        Rs)));
7205c582b2fSDaniel Sanders 
7215c582b2fSDaniel Sanders   if (HasRt)
7225c582b2fSDaniel Sanders     MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
7235c582b2fSDaniel Sanders                                        Rt)));
7245c582b2fSDaniel Sanders 
7255c582b2fSDaniel Sanders   MI.addOperand(MCOperand::CreateImm(Imm));
7265c582b2fSDaniel Sanders 
7275c582b2fSDaniel Sanders   return MCDisassembler::Success;
7285c582b2fSDaniel Sanders }
7295c582b2fSDaniel Sanders 
73028a0ca07SZoran Jovanovic template <typename InsnType>
73128a0ca07SZoran Jovanovic static DecodeStatus DecodeBlezGroupBranch(MCInst &MI, InsnType insn,
73228a0ca07SZoran Jovanovic                                            uint64_t Address,
73328a0ca07SZoran Jovanovic                                            const void *Decoder) {
73428a0ca07SZoran Jovanovic   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
73528a0ca07SZoran Jovanovic   // (otherwise we would have matched the BLEZL instruction from the earlier
73628a0ca07SZoran Jovanovic   // ISA's instead).
73728a0ca07SZoran Jovanovic   //
73828a0ca07SZoran Jovanovic   // We have:
73928a0ca07SZoran Jovanovic   //    0b000110 sssss ttttt iiiiiiiiiiiiiiii
74028a0ca07SZoran Jovanovic   //      Invalid   if rs == 0
74128a0ca07SZoran Jovanovic   //      BLEZALC   if rs == 0  && rt != 0
74228a0ca07SZoran Jovanovic   //      BGEZALC   if rs == rt && rt != 0
74328a0ca07SZoran Jovanovic   //      BGEUC     if rs != rt && rs != 0  && rt != 0
74428a0ca07SZoran Jovanovic 
74528a0ca07SZoran Jovanovic   InsnType Rs = fieldFromInstruction(insn, 21, 5);
74628a0ca07SZoran Jovanovic   InsnType Rt = fieldFromInstruction(insn, 16, 5);
747d37bab61SAlexey Samsonov   InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4;
74828a0ca07SZoran Jovanovic   bool HasRs = false;
74928a0ca07SZoran Jovanovic 
75028a0ca07SZoran Jovanovic   if (Rt == 0)
75128a0ca07SZoran Jovanovic     return MCDisassembler::Fail;
75228a0ca07SZoran Jovanovic   else if (Rs == 0)
75328a0ca07SZoran Jovanovic     MI.setOpcode(Mips::BLEZALC);
75428a0ca07SZoran Jovanovic   else if (Rs == Rt)
75528a0ca07SZoran Jovanovic     MI.setOpcode(Mips::BGEZALC);
75628a0ca07SZoran Jovanovic   else {
75728a0ca07SZoran Jovanovic     HasRs = true;
75828a0ca07SZoran Jovanovic     MI.setOpcode(Mips::BGEUC);
75928a0ca07SZoran Jovanovic   }
76028a0ca07SZoran Jovanovic 
76128a0ca07SZoran Jovanovic   if (HasRs)
76228a0ca07SZoran Jovanovic     MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
76328a0ca07SZoran Jovanovic                                        Rs)));
76428a0ca07SZoran Jovanovic   MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
76528a0ca07SZoran Jovanovic                                      Rt)));
76628a0ca07SZoran Jovanovic 
76728a0ca07SZoran Jovanovic   MI.addOperand(MCOperand::CreateImm(Imm));
76828a0ca07SZoran Jovanovic 
76928a0ca07SZoran Jovanovic   return MCDisassembler::Success;
77028a0ca07SZoran Jovanovic }
77128a0ca07SZoran Jovanovic 
772ea22c4cfSJozef Kolek /// Read two bytes from the ArrayRef and return 16 bit halfword sorted
773ea22c4cfSJozef Kolek /// according to the given endianess.
774ea22c4cfSJozef Kolek static DecodeStatus readInstruction16(ArrayRef<uint8_t> Bytes, uint64_t Address,
775ea22c4cfSJozef Kolek                                       uint64_t &Size, uint32_t &Insn,
776ea22c4cfSJozef Kolek                                       bool IsBigEndian) {
777ea22c4cfSJozef Kolek   // We want to read exactly 2 Bytes of data.
778ea22c4cfSJozef Kolek   if (Bytes.size() < 2) {
779ea22c4cfSJozef Kolek     Size = 0;
780ea22c4cfSJozef Kolek     return MCDisassembler::Fail;
781ea22c4cfSJozef Kolek   }
782ea22c4cfSJozef Kolek 
783ea22c4cfSJozef Kolek   if (IsBigEndian) {
784ea22c4cfSJozef Kolek     Insn = (Bytes[0] << 8) | Bytes[1];
785ea22c4cfSJozef Kolek   } else {
786ea22c4cfSJozef Kolek     Insn = (Bytes[1] << 8) | Bytes[0];
787ea22c4cfSJozef Kolek   }
788ea22c4cfSJozef Kolek 
789ea22c4cfSJozef Kolek   return MCDisassembler::Success;
790ea22c4cfSJozef Kolek }
791ea22c4cfSJozef Kolek 
7927fc5b874SRafael Espindola /// Read four bytes from the ArrayRef and return 32 bit word sorted
7934aa6bea7SRafael Espindola /// according to the given endianess
7947fc5b874SRafael Espindola static DecodeStatus readInstruction32(ArrayRef<uint8_t> Bytes, uint64_t Address,
7957fc5b874SRafael Espindola                                       uint64_t &Size, uint32_t &Insn,
7967fc5b874SRafael Espindola                                       bool IsBigEndian, bool IsMicroMips) {
79771928e68SAkira Hatanaka   // We want to read exactly 4 Bytes of data.
7987fc5b874SRafael Espindola   if (Bytes.size() < 4) {
7994aa6bea7SRafael Espindola     Size = 0;
80071928e68SAkira Hatanaka     return MCDisassembler::Fail;
80171928e68SAkira Hatanaka   }
80271928e68SAkira Hatanaka 
803ea22c4cfSJozef Kolek   // High 16 bits of a 32-bit microMIPS instruction (where the opcode is)
804ea22c4cfSJozef Kolek   // always precede the low 16 bits in the instruction stream (that is, they
805ea22c4cfSJozef Kolek   // are placed at lower addresses in the instruction stream).
806ea22c4cfSJozef Kolek   //
807ea22c4cfSJozef Kolek   // microMIPS byte ordering:
808ea22c4cfSJozef Kolek   //   Big-endian:    0 | 1 | 2 | 3
809ea22c4cfSJozef Kolek   //   Little-endian: 1 | 0 | 3 | 2
810ea22c4cfSJozef Kolek 
8114aa6bea7SRafael Espindola   if (IsBigEndian) {
81271928e68SAkira Hatanaka     // Encoded as a big-endian 32-bit word in the stream.
8134aa6bea7SRafael Espindola     Insn =
8144aa6bea7SRafael Espindola         (Bytes[3] << 0) | (Bytes[2] << 8) | (Bytes[1] << 16) | (Bytes[0] << 24);
8154aa6bea7SRafael Espindola   } else {
816dde3d582SVladimir Medic     if (IsMicroMips) {
8174aa6bea7SRafael Espindola       Insn = (Bytes[2] << 0) | (Bytes[3] << 8) | (Bytes[0] << 16) |
818dde3d582SVladimir Medic              (Bytes[1] << 24);
819dde3d582SVladimir Medic     } else {
8204aa6bea7SRafael Espindola       Insn = (Bytes[0] << 0) | (Bytes[1] << 8) | (Bytes[2] << 16) |
82171928e68SAkira Hatanaka              (Bytes[3] << 24);
82271928e68SAkira Hatanaka     }
823dde3d582SVladimir Medic   }
82471928e68SAkira Hatanaka 
82571928e68SAkira Hatanaka   return MCDisassembler::Success;
82671928e68SAkira Hatanaka }
82771928e68SAkira Hatanaka 
8284aa6bea7SRafael Espindola DecodeStatus MipsDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,
8297fc5b874SRafael Espindola                                               ArrayRef<uint8_t> Bytes,
83071928e68SAkira Hatanaka                                               uint64_t Address,
8314aa6bea7SRafael Espindola                                               raw_ostream &VStream,
8324aa6bea7SRafael Espindola                                               raw_ostream &CStream) const {
83371928e68SAkira Hatanaka   uint32_t Insn;
834ea22c4cfSJozef Kolek   DecodeStatus Result;
83571928e68SAkira Hatanaka 
836ea22c4cfSJozef Kolek   if (IsMicroMips) {
837ea22c4cfSJozef Kolek     Result = readInstruction16(Bytes, Address, Size, Insn, IsBigEndian);
838ea22c4cfSJozef Kolek 
839ea22c4cfSJozef Kolek     DEBUG(dbgs() << "Trying MicroMips16 table (16-bit instructions):\n");
840ea22c4cfSJozef Kolek     // Calling the auto-generated decoder function.
841ea22c4cfSJozef Kolek     Result = decodeInstruction(DecoderTableMicroMips16, Instr, Insn, Address,
842ea22c4cfSJozef Kolek                                this, STI);
843ea22c4cfSJozef Kolek     if (Result != MCDisassembler::Fail) {
844ea22c4cfSJozef Kolek       Size = 2;
845ea22c4cfSJozef Kolek       return Result;
846ea22c4cfSJozef Kolek     }
847ea22c4cfSJozef Kolek 
848ea22c4cfSJozef Kolek     Result = readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, true);
84971928e68SAkira Hatanaka     if (Result == MCDisassembler::Fail)
85071928e68SAkira Hatanaka       return MCDisassembler::Fail;
85171928e68SAkira Hatanaka 
852ea22c4cfSJozef Kolek     DEBUG(dbgs() << "Trying MicroMips32 table (32-bit instructions):\n");
853dde3d582SVladimir Medic     // Calling the auto-generated decoder function.
8544aa6bea7SRafael Espindola     Result = decodeInstruction(DecoderTableMicroMips32, Instr, Insn, Address,
855dde3d582SVladimir Medic                                this, STI);
856dde3d582SVladimir Medic     if (Result != MCDisassembler::Fail) {
857dde3d582SVladimir Medic       Size = 4;
858dde3d582SVladimir Medic       return Result;
859dde3d582SVladimir Medic     }
860dde3d582SVladimir Medic     return MCDisassembler::Fail;
861dde3d582SVladimir Medic   }
862dde3d582SVladimir Medic 
863ea22c4cfSJozef Kolek   Result = readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, false);
864ea22c4cfSJozef Kolek   if (Result == MCDisassembler::Fail)
865ea22c4cfSJozef Kolek     return MCDisassembler::Fail;
866ea22c4cfSJozef Kolek 
867c171f65aSDaniel Sanders   if (hasCOP3()) {
868c171f65aSDaniel Sanders     DEBUG(dbgs() << "Trying COP3_ table (32-bit opcodes):\n");
869c171f65aSDaniel Sanders     Result =
8704aa6bea7SRafael Espindola         decodeInstruction(DecoderTableCOP3_32, Instr, Insn, Address, this, STI);
871c171f65aSDaniel Sanders     if (Result != MCDisassembler::Fail) {
872c171f65aSDaniel Sanders       Size = 4;
873c171f65aSDaniel Sanders       return Result;
874c171f65aSDaniel Sanders     }
875c171f65aSDaniel Sanders   }
876c171f65aSDaniel Sanders 
877c171f65aSDaniel Sanders   if (hasMips32r6() && isGP64()) {
8780fa60416SDaniel Sanders     DEBUG(dbgs() << "Trying Mips32r6_64r6 (GPR64) table (32-bit opcodes):\n");
8794aa6bea7SRafael Espindola     Result = decodeInstruction(DecoderTableMips32r6_64r6_GP6432, Instr, Insn,
8800fa60416SDaniel Sanders                                Address, this, STI);
8810fa60416SDaniel Sanders     if (Result != MCDisassembler::Fail) {
8820fa60416SDaniel Sanders       Size = 4;
8830fa60416SDaniel Sanders       return Result;
8840fa60416SDaniel Sanders     }
8850fa60416SDaniel Sanders   }
8860fa60416SDaniel Sanders 
887c171f65aSDaniel Sanders   if (hasMips32r6()) {
8880fa60416SDaniel Sanders     DEBUG(dbgs() << "Trying Mips32r6_64r6 table (32-bit opcodes):\n");
8894aa6bea7SRafael Espindola     Result = decodeInstruction(DecoderTableMips32r6_64r632, Instr, Insn,
8905c582b2fSDaniel Sanders                                Address, this, STI);
8915c582b2fSDaniel Sanders     if (Result != MCDisassembler::Fail) {
8925c582b2fSDaniel Sanders       Size = 4;
8935c582b2fSDaniel Sanders       return Result;
8945c582b2fSDaniel Sanders     }
8955c582b2fSDaniel Sanders   }
8965c582b2fSDaniel Sanders 
8970fa60416SDaniel Sanders   DEBUG(dbgs() << "Trying Mips table (32-bit opcodes):\n");
89871928e68SAkira Hatanaka   // Calling the auto-generated decoder function.
8994aa6bea7SRafael Espindola   Result =
9004aa6bea7SRafael Espindola       decodeInstruction(DecoderTableMips32, Instr, Insn, Address, this, STI);
90171928e68SAkira Hatanaka   if (Result != MCDisassembler::Fail) {
90271928e68SAkira Hatanaka     Size = 4;
90371928e68SAkira Hatanaka     return Result;
90471928e68SAkira Hatanaka   }
90571928e68SAkira Hatanaka 
90671928e68SAkira Hatanaka   return MCDisassembler::Fail;
90771928e68SAkira Hatanaka }
90871928e68SAkira Hatanaka 
9094aa6bea7SRafael Espindola DecodeStatus Mips64Disassembler::getInstruction(MCInst &Instr, uint64_t &Size,
9107fc5b874SRafael Espindola                                                 ArrayRef<uint8_t> Bytes,
91171928e68SAkira Hatanaka                                                 uint64_t Address,
9124aa6bea7SRafael Espindola                                                 raw_ostream &VStream,
9134aa6bea7SRafael Espindola                                                 raw_ostream &CStream) const {
91471928e68SAkira Hatanaka   uint32_t Insn;
91571928e68SAkira Hatanaka 
9164aa6bea7SRafael Espindola   DecodeStatus Result =
9177fc5b874SRafael Espindola       readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, false);
91871928e68SAkira Hatanaka   if (Result == MCDisassembler::Fail)
91971928e68SAkira Hatanaka     return MCDisassembler::Fail;
92071928e68SAkira Hatanaka 
92171928e68SAkira Hatanaka   // Calling the auto-generated decoder function.
9224aa6bea7SRafael Espindola   Result =
9234aa6bea7SRafael Espindola       decodeInstruction(DecoderTableMips6432, Instr, Insn, Address, this, STI);
92471928e68SAkira Hatanaka   if (Result != MCDisassembler::Fail) {
92571928e68SAkira Hatanaka     Size = 4;
92671928e68SAkira Hatanaka     return Result;
92771928e68SAkira Hatanaka   }
92871928e68SAkira Hatanaka   // If we fail to decode in Mips64 decoder space we can try in Mips32
9294aa6bea7SRafael Espindola   Result =
9304aa6bea7SRafael Espindola       decodeInstruction(DecoderTableMips32, Instr, Insn, Address, this, STI);
93171928e68SAkira Hatanaka   if (Result != MCDisassembler::Fail) {
93271928e68SAkira Hatanaka     Size = 4;
93371928e68SAkira Hatanaka     return Result;
93471928e68SAkira Hatanaka   }
93571928e68SAkira Hatanaka 
93671928e68SAkira Hatanaka   return MCDisassembler::Fail;
93771928e68SAkira Hatanaka }
93871928e68SAkira Hatanaka 
939ec8a5490SReed Kotler static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst,
940ec8a5490SReed Kotler                                                  unsigned RegNo,
941ec8a5490SReed Kotler                                                  uint64_t Address,
942ec8a5490SReed Kotler                                                  const void *Decoder) {
943ec8a5490SReed Kotler 
944ec8a5490SReed Kotler   return MCDisassembler::Fail;
945ec8a5490SReed Kotler 
946ec8a5490SReed Kotler }
947ec8a5490SReed Kotler 
94813e6ccf3SAkira Hatanaka static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst,
94971928e68SAkira Hatanaka                                              unsigned RegNo,
95071928e68SAkira Hatanaka                                              uint64_t Address,
95171928e68SAkira Hatanaka                                              const void *Decoder) {
95271928e68SAkira Hatanaka 
95371928e68SAkira Hatanaka   if (RegNo > 31)
95471928e68SAkira Hatanaka     return MCDisassembler::Fail;
95571928e68SAkira Hatanaka 
95613e6ccf3SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::GPR64RegClassID, RegNo);
9579bf2b567SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
95871928e68SAkira Hatanaka   return MCDisassembler::Success;
95971928e68SAkira Hatanaka }
96071928e68SAkira Hatanaka 
961b0852e54SZoran Jovanovic static DecodeStatus DecodeGPRMM16RegisterClass(MCInst &Inst,
962b0852e54SZoran Jovanovic                                                unsigned RegNo,
963b0852e54SZoran Jovanovic                                                uint64_t Address,
964b0852e54SZoran Jovanovic                                                const void *Decoder) {
965ea22c4cfSJozef Kolek   if (RegNo > 7)
966b0852e54SZoran Jovanovic     return MCDisassembler::Fail;
967ea22c4cfSJozef Kolek   unsigned Reg = getReg(Decoder, Mips::GPRMM16RegClassID, RegNo);
968ea22c4cfSJozef Kolek   Inst.addOperand(MCOperand::CreateReg(Reg));
969ea22c4cfSJozef Kolek   return MCDisassembler::Success;
970b0852e54SZoran Jovanovic }
971b0852e54SZoran Jovanovic 
9721904fa21SJozef Kolek static DecodeStatus DecodeGPRMM16ZeroRegisterClass(MCInst &Inst,
9731904fa21SJozef Kolek                                                    unsigned RegNo,
9741904fa21SJozef Kolek                                                    uint64_t Address,
9751904fa21SJozef Kolek                                                    const void *Decoder) {
976315e7ecaSJozef Kolek   if (RegNo > 7)
9771904fa21SJozef Kolek     return MCDisassembler::Fail;
978315e7ecaSJozef Kolek   unsigned Reg = getReg(Decoder, Mips::GPRMM16ZeroRegClassID, RegNo);
979315e7ecaSJozef Kolek   Inst.addOperand(MCOperand::CreateReg(Reg));
980315e7ecaSJozef Kolek   return MCDisassembler::Success;
9811904fa21SJozef Kolek }
9821904fa21SJozef Kolek 
98313e6ccf3SAkira Hatanaka static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst,
98471928e68SAkira Hatanaka                                              unsigned RegNo,
98571928e68SAkira Hatanaka                                              uint64_t Address,
98671928e68SAkira Hatanaka                                              const void *Decoder) {
98771928e68SAkira Hatanaka   if (RegNo > 31)
98871928e68SAkira Hatanaka     return MCDisassembler::Fail;
98913e6ccf3SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::GPR32RegClassID, RegNo);
9909bf2b567SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
99171928e68SAkira Hatanaka   return MCDisassembler::Success;
99271928e68SAkira Hatanaka }
99371928e68SAkira Hatanaka 
9949bfa2e2eSAkira Hatanaka static DecodeStatus DecodePtrRegisterClass(MCInst &Inst,
9959bfa2e2eSAkira Hatanaka                                            unsigned RegNo,
9969bfa2e2eSAkira Hatanaka                                            uint64_t Address,
9979bfa2e2eSAkira Hatanaka                                            const void *Decoder) {
998e8860938SVladimir Medic   if (static_cast<const MipsDisassembler *>(Decoder)->isGP64Bit())
9999bfa2e2eSAkira Hatanaka     return DecodeGPR64RegisterClass(Inst, RegNo, Address, Decoder);
10009bfa2e2eSAkira Hatanaka 
10019bfa2e2eSAkira Hatanaka   return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
10029bfa2e2eSAkira Hatanaka }
10039bfa2e2eSAkira Hatanaka 
1004654655f1SAkira Hatanaka static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst,
1005ecabd1a5SAkira Hatanaka                                             unsigned RegNo,
1006ecabd1a5SAkira Hatanaka                                             uint64_t Address,
1007ecabd1a5SAkira Hatanaka                                             const void *Decoder) {
100813e6ccf3SAkira Hatanaka   return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
1009ecabd1a5SAkira Hatanaka }
1010ecabd1a5SAkira Hatanaka 
101171928e68SAkira Hatanaka static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
101271928e68SAkira Hatanaka                                              unsigned RegNo,
101371928e68SAkira Hatanaka                                              uint64_t Address,
101471928e68SAkira Hatanaka                                              const void *Decoder) {
101571928e68SAkira Hatanaka   if (RegNo > 31)
101671928e68SAkira Hatanaka     return MCDisassembler::Fail;
101771928e68SAkira Hatanaka 
10189bf2b567SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::FGR64RegClassID, RegNo);
10199bf2b567SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
102071928e68SAkira Hatanaka   return MCDisassembler::Success;
102171928e68SAkira Hatanaka }
102271928e68SAkira Hatanaka 
102371928e68SAkira Hatanaka static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
102471928e68SAkira Hatanaka                                              unsigned RegNo,
102571928e68SAkira Hatanaka                                              uint64_t Address,
102671928e68SAkira Hatanaka                                              const void *Decoder) {
102771928e68SAkira Hatanaka   if (RegNo > 31)
102871928e68SAkira Hatanaka     return MCDisassembler::Fail;
102971928e68SAkira Hatanaka 
10309bf2b567SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::FGR32RegClassID, RegNo);
10319bf2b567SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
103271928e68SAkira Hatanaka   return MCDisassembler::Success;
103371928e68SAkira Hatanaka }
103471928e68SAkira Hatanaka 
103571928e68SAkira Hatanaka static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
103671928e68SAkira Hatanaka                                            unsigned RegNo,
103771928e68SAkira Hatanaka                                            uint64_t Address,
103871928e68SAkira Hatanaka                                            const void *Decoder) {
1039253777fdSChad Rosier   if (RegNo > 31)
1040253777fdSChad Rosier     return MCDisassembler::Fail;
1041253777fdSChad Rosier   unsigned Reg = getReg(Decoder, Mips::CCRRegClassID, RegNo);
1042253777fdSChad Rosier   Inst.addOperand(MCOperand::CreateReg(Reg));
104371928e68SAkira Hatanaka   return MCDisassembler::Success;
104471928e68SAkira Hatanaka }
104571928e68SAkira Hatanaka 
10461fb1b8b8SAkira Hatanaka static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst,
10471fb1b8b8SAkira Hatanaka                                            unsigned RegNo,
10481fb1b8b8SAkira Hatanaka                                            uint64_t Address,
10491fb1b8b8SAkira Hatanaka                                            const void *Decoder) {
10501fb1b8b8SAkira Hatanaka   if (RegNo > 7)
10511fb1b8b8SAkira Hatanaka     return MCDisassembler::Fail;
10521fb1b8b8SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::FCCRegClassID, RegNo);
10531fb1b8b8SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
10541fb1b8b8SAkira Hatanaka   return MCDisassembler::Success;
10551fb1b8b8SAkira Hatanaka }
10561fb1b8b8SAkira Hatanaka 
10570fa60416SDaniel Sanders static DecodeStatus DecodeFGRCCRegisterClass(MCInst &Inst, unsigned RegNo,
10580fa60416SDaniel Sanders                                              uint64_t Address,
10590fa60416SDaniel Sanders                                              const void *Decoder) {
10600fa60416SDaniel Sanders   if (RegNo > 31)
10610fa60416SDaniel Sanders     return MCDisassembler::Fail;
10620fa60416SDaniel Sanders 
10630fa60416SDaniel Sanders   unsigned Reg = getReg(Decoder, Mips::FGRCCRegClassID, RegNo);
10640fa60416SDaniel Sanders   Inst.addOperand(MCOperand::CreateReg(Reg));
10650fa60416SDaniel Sanders   return MCDisassembler::Success;
10660fa60416SDaniel Sanders }
10670fa60416SDaniel Sanders 
106871928e68SAkira Hatanaka static DecodeStatus DecodeMem(MCInst &Inst,
106971928e68SAkira Hatanaka                               unsigned Insn,
107071928e68SAkira Hatanaka                               uint64_t Address,
107171928e68SAkira Hatanaka                               const void *Decoder) {
107271928e68SAkira Hatanaka   int Offset = SignExtend32<16>(Insn & 0xffff);
1073ecaef49fSJim Grosbach   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1074ecaef49fSJim Grosbach   unsigned Base = fieldFromInstruction(Insn, 21, 5);
10759bf2b567SAkira Hatanaka 
107613e6ccf3SAkira Hatanaka   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
107713e6ccf3SAkira Hatanaka   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
107871928e68SAkira Hatanaka 
1079d7ecf49eSVladimir Medic   if(Inst.getOpcode() == Mips::SC ||
1080d7ecf49eSVladimir Medic      Inst.getOpcode() == Mips::SCD){
10819bf2b567SAkira Hatanaka     Inst.addOperand(MCOperand::CreateReg(Reg));
108271928e68SAkira Hatanaka   }
108371928e68SAkira Hatanaka 
10849bf2b567SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
10859bf2b567SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Base));
108671928e68SAkira Hatanaka   Inst.addOperand(MCOperand::CreateImm(Offset));
108771928e68SAkira Hatanaka 
108871928e68SAkira Hatanaka   return MCDisassembler::Success;
108971928e68SAkira Hatanaka }
109071928e68SAkira Hatanaka 
109192db6b78SDaniel Sanders static DecodeStatus DecodeCacheOp(MCInst &Inst,
109292db6b78SDaniel Sanders                               unsigned Insn,
109392db6b78SDaniel Sanders                               uint64_t Address,
109492db6b78SDaniel Sanders                               const void *Decoder) {
109592db6b78SDaniel Sanders   int Offset = SignExtend32<16>(Insn & 0xffff);
109692db6b78SDaniel Sanders   unsigned Hint = fieldFromInstruction(Insn, 16, 5);
109792db6b78SDaniel Sanders   unsigned Base = fieldFromInstruction(Insn, 21, 5);
109892db6b78SDaniel Sanders 
109992db6b78SDaniel Sanders   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
110092db6b78SDaniel Sanders 
110192db6b78SDaniel Sanders   Inst.addOperand(MCOperand::CreateReg(Base));
110292db6b78SDaniel Sanders   Inst.addOperand(MCOperand::CreateImm(Offset));
110392db6b78SDaniel Sanders   Inst.addOperand(MCOperand::CreateImm(Hint));
110492db6b78SDaniel Sanders 
110592db6b78SDaniel Sanders   return MCDisassembler::Success;
110692db6b78SDaniel Sanders }
110792db6b78SDaniel Sanders 
1108ab6d1cceSJozef Kolek static DecodeStatus DecodeCacheOpMM(MCInst &Inst,
1109ab6d1cceSJozef Kolek                                     unsigned Insn,
1110ab6d1cceSJozef Kolek                                     uint64_t Address,
1111ab6d1cceSJozef Kolek                                     const void *Decoder) {
1112ab6d1cceSJozef Kolek   int Offset = SignExtend32<12>(Insn & 0xfff);
1113ab6d1cceSJozef Kolek   unsigned Base = fieldFromInstruction(Insn, 16, 5);
1114ab6d1cceSJozef Kolek   unsigned Hint = fieldFromInstruction(Insn, 21, 5);
1115ab6d1cceSJozef Kolek 
1116ab6d1cceSJozef Kolek   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1117ab6d1cceSJozef Kolek 
1118ab6d1cceSJozef Kolek   Inst.addOperand(MCOperand::CreateReg(Base));
1119ab6d1cceSJozef Kolek   Inst.addOperand(MCOperand::CreateImm(Offset));
1120ab6d1cceSJozef Kolek   Inst.addOperand(MCOperand::CreateImm(Hint));
1121ab6d1cceSJozef Kolek 
1122ab6d1cceSJozef Kolek   return MCDisassembler::Success;
1123ab6d1cceSJozef Kolek }
1124ab6d1cceSJozef Kolek 
1125b4484d62SDaniel Sanders static DecodeStatus DecodeSyncI(MCInst &Inst,
1126b4484d62SDaniel Sanders                               unsigned Insn,
1127b4484d62SDaniel Sanders                               uint64_t Address,
1128b4484d62SDaniel Sanders                               const void *Decoder) {
1129b4484d62SDaniel Sanders   int Offset = SignExtend32<16>(Insn & 0xffff);
1130b4484d62SDaniel Sanders   unsigned Base = fieldFromInstruction(Insn, 21, 5);
1131b4484d62SDaniel Sanders 
1132b4484d62SDaniel Sanders   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1133b4484d62SDaniel Sanders 
1134b4484d62SDaniel Sanders   Inst.addOperand(MCOperand::CreateReg(Base));
1135b4484d62SDaniel Sanders   Inst.addOperand(MCOperand::CreateImm(Offset));
1136b4484d62SDaniel Sanders 
1137b4484d62SDaniel Sanders   return MCDisassembler::Success;
1138b4484d62SDaniel Sanders }
1139b4484d62SDaniel Sanders 
1140fe0bf9f6SMatheus Almeida static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn,
1141fe0bf9f6SMatheus Almeida                                     uint64_t Address, const void *Decoder) {
1142fe0bf9f6SMatheus Almeida   int Offset = SignExtend32<10>(fieldFromInstruction(Insn, 16, 10));
1143fe0bf9f6SMatheus Almeida   unsigned Reg = fieldFromInstruction(Insn, 6, 5);
1144fe0bf9f6SMatheus Almeida   unsigned Base = fieldFromInstruction(Insn, 11, 5);
1145fe0bf9f6SMatheus Almeida 
1146fe0bf9f6SMatheus Almeida   Reg = getReg(Decoder, Mips::MSA128BRegClassID, Reg);
1147fe0bf9f6SMatheus Almeida   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1148fe0bf9f6SMatheus Almeida 
1149fe0bf9f6SMatheus Almeida   Inst.addOperand(MCOperand::CreateReg(Reg));
1150fe0bf9f6SMatheus Almeida   Inst.addOperand(MCOperand::CreateReg(Base));
11516b59c449SMatheus Almeida 
11526b59c449SMatheus Almeida   // The immediate field of an LD/ST instruction is scaled which means it must
11536b59c449SMatheus Almeida   // be multiplied (when decoding) by the size (in bytes) of the instructions'
11546b59c449SMatheus Almeida   // data format.
11556b59c449SMatheus Almeida   // .b - 1 byte
11566b59c449SMatheus Almeida   // .h - 2 bytes
11576b59c449SMatheus Almeida   // .w - 4 bytes
11586b59c449SMatheus Almeida   // .d - 8 bytes
11596b59c449SMatheus Almeida   switch(Inst.getOpcode())
11606b59c449SMatheus Almeida   {
11616b59c449SMatheus Almeida   default:
11626b59c449SMatheus Almeida     assert (0 && "Unexpected instruction");
11636b59c449SMatheus Almeida     return MCDisassembler::Fail;
11646b59c449SMatheus Almeida     break;
11656b59c449SMatheus Almeida   case Mips::LD_B:
11666b59c449SMatheus Almeida   case Mips::ST_B:
1167fe0bf9f6SMatheus Almeida     Inst.addOperand(MCOperand::CreateImm(Offset));
11686b59c449SMatheus Almeida     break;
11696b59c449SMatheus Almeida   case Mips::LD_H:
11706b59c449SMatheus Almeida   case Mips::ST_H:
1171d37bab61SAlexey Samsonov     Inst.addOperand(MCOperand::CreateImm(Offset * 2));
11726b59c449SMatheus Almeida     break;
11736b59c449SMatheus Almeida   case Mips::LD_W:
11746b59c449SMatheus Almeida   case Mips::ST_W:
1175d37bab61SAlexey Samsonov     Inst.addOperand(MCOperand::CreateImm(Offset * 4));
11766b59c449SMatheus Almeida     break;
11776b59c449SMatheus Almeida   case Mips::LD_D:
11786b59c449SMatheus Almeida   case Mips::ST_D:
1179d37bab61SAlexey Samsonov     Inst.addOperand(MCOperand::CreateImm(Offset * 8));
11806b59c449SMatheus Almeida     break;
11816b59c449SMatheus Almeida   }
1182fe0bf9f6SMatheus Almeida 
1183fe0bf9f6SMatheus Almeida   return MCDisassembler::Success;
1184fe0bf9f6SMatheus Almeida }
1185fe0bf9f6SMatheus Almeida 
1186315e7ecaSJozef Kolek static DecodeStatus DecodeMemMMImm4(MCInst &Inst,
1187315e7ecaSJozef Kolek                                     unsigned Insn,
1188315e7ecaSJozef Kolek                                     uint64_t Address,
1189315e7ecaSJozef Kolek                                     const void *Decoder) {
1190315e7ecaSJozef Kolek   unsigned Offset = Insn & 0xf;
1191315e7ecaSJozef Kolek   unsigned Reg = fieldFromInstruction(Insn, 7, 3);
1192315e7ecaSJozef Kolek   unsigned Base = fieldFromInstruction(Insn, 4, 3);
1193315e7ecaSJozef Kolek 
1194315e7ecaSJozef Kolek   switch (Inst.getOpcode()) {
1195315e7ecaSJozef Kolek     case Mips::LBU16_MM:
1196315e7ecaSJozef Kolek     case Mips::LHU16_MM:
1197315e7ecaSJozef Kolek     case Mips::LW16_MM:
1198315e7ecaSJozef Kolek       if (DecodeGPRMM16RegisterClass(Inst, Reg, Address, Decoder)
1199315e7ecaSJozef Kolek             == MCDisassembler::Fail)
1200315e7ecaSJozef Kolek         return MCDisassembler::Fail;
1201315e7ecaSJozef Kolek       break;
1202315e7ecaSJozef Kolek     case Mips::SB16_MM:
1203315e7ecaSJozef Kolek     case Mips::SH16_MM:
1204315e7ecaSJozef Kolek     case Mips::SW16_MM:
1205315e7ecaSJozef Kolek       if (DecodeGPRMM16ZeroRegisterClass(Inst, Reg, Address, Decoder)
1206315e7ecaSJozef Kolek             == MCDisassembler::Fail)
1207315e7ecaSJozef Kolek         return MCDisassembler::Fail;
1208315e7ecaSJozef Kolek       break;
1209315e7ecaSJozef Kolek   }
1210315e7ecaSJozef Kolek 
1211315e7ecaSJozef Kolek   if (DecodeGPRMM16RegisterClass(Inst, Base, Address, Decoder)
1212315e7ecaSJozef Kolek         == MCDisassembler::Fail)
1213315e7ecaSJozef Kolek     return MCDisassembler::Fail;
1214315e7ecaSJozef Kolek 
1215315e7ecaSJozef Kolek   switch (Inst.getOpcode()) {
1216315e7ecaSJozef Kolek     case Mips::LBU16_MM:
1217315e7ecaSJozef Kolek       if (Offset == 0xf)
1218315e7ecaSJozef Kolek         Inst.addOperand(MCOperand::CreateImm(-1));
1219315e7ecaSJozef Kolek       else
1220315e7ecaSJozef Kolek         Inst.addOperand(MCOperand::CreateImm(Offset));
1221315e7ecaSJozef Kolek       break;
1222315e7ecaSJozef Kolek     case Mips::SB16_MM:
1223315e7ecaSJozef Kolek       Inst.addOperand(MCOperand::CreateImm(Offset));
1224315e7ecaSJozef Kolek       break;
1225315e7ecaSJozef Kolek     case Mips::LHU16_MM:
1226315e7ecaSJozef Kolek     case Mips::SH16_MM:
1227315e7ecaSJozef Kolek       Inst.addOperand(MCOperand::CreateImm(Offset << 1));
1228315e7ecaSJozef Kolek       break;
1229315e7ecaSJozef Kolek     case Mips::LW16_MM:
1230315e7ecaSJozef Kolek     case Mips::SW16_MM:
1231315e7ecaSJozef Kolek       Inst.addOperand(MCOperand::CreateImm(Offset << 2));
1232315e7ecaSJozef Kolek       break;
1233315e7ecaSJozef Kolek   }
1234315e7ecaSJozef Kolek 
1235315e7ecaSJozef Kolek   return MCDisassembler::Success;
1236315e7ecaSJozef Kolek }
1237315e7ecaSJozef Kolek 
123812c6982bSJozef Kolek static DecodeStatus DecodeMemMMSPImm5Lsl2(MCInst &Inst,
123912c6982bSJozef Kolek                                           unsigned Insn,
124012c6982bSJozef Kolek                                           uint64_t Address,
124112c6982bSJozef Kolek                                           const void *Decoder) {
124212c6982bSJozef Kolek   unsigned Offset = Insn & 0x1F;
124312c6982bSJozef Kolek   unsigned Reg = fieldFromInstruction(Insn, 5, 5);
124412c6982bSJozef Kolek 
124512c6982bSJozef Kolek   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
124612c6982bSJozef Kolek 
124712c6982bSJozef Kolek   Inst.addOperand(MCOperand::CreateReg(Reg));
124812c6982bSJozef Kolek   Inst.addOperand(MCOperand::CreateReg(Mips::SP));
124912c6982bSJozef Kolek   Inst.addOperand(MCOperand::CreateImm(Offset << 2));
125012c6982bSJozef Kolek 
125112c6982bSJozef Kolek   return MCDisassembler::Success;
125212c6982bSJozef Kolek }
125312c6982bSJozef Kolek 
1254dde3d582SVladimir Medic static DecodeStatus DecodeMemMMImm12(MCInst &Inst,
1255dde3d582SVladimir Medic                                      unsigned Insn,
1256dde3d582SVladimir Medic                                      uint64_t Address,
1257dde3d582SVladimir Medic                                      const void *Decoder) {
1258dde3d582SVladimir Medic   int Offset = SignExtend32<12>(Insn & 0x0fff);
1259dde3d582SVladimir Medic   unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1260dde3d582SVladimir Medic   unsigned Base = fieldFromInstruction(Insn, 16, 5);
1261dde3d582SVladimir Medic 
1262dde3d582SVladimir Medic   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1263dde3d582SVladimir Medic   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1264dde3d582SVladimir Medic 
1265a4c4b5fcSZoran Jovanovic   switch (Inst.getOpcode()) {
1266a4c4b5fcSZoran Jovanovic   case Mips::SWM32_MM:
1267a4c4b5fcSZoran Jovanovic   case Mips::LWM32_MM:
1268a4c4b5fcSZoran Jovanovic     if (DecodeRegListOperand(Inst, Insn, Address, Decoder)
1269a4c4b5fcSZoran Jovanovic         == MCDisassembler::Fail)
1270a4c4b5fcSZoran Jovanovic       return MCDisassembler::Fail;
1271a4c4b5fcSZoran Jovanovic     Inst.addOperand(MCOperand::CreateReg(Base));
1272a4c4b5fcSZoran Jovanovic     Inst.addOperand(MCOperand::CreateImm(Offset));
1273a4c4b5fcSZoran Jovanovic     break;
1274a4c4b5fcSZoran Jovanovic   case Mips::SC_MM:
1275285cc289SZoran Jovanovic     Inst.addOperand(MCOperand::CreateReg(Reg));
1276a4c4b5fcSZoran Jovanovic     // fallthrough
1277a4c4b5fcSZoran Jovanovic   default:
1278dde3d582SVladimir Medic     Inst.addOperand(MCOperand::CreateReg(Reg));
12792deca348SZoran Jovanovic     if (Inst.getOpcode() == Mips::LWP_MM || Inst.getOpcode() == Mips::SWP_MM)
12802deca348SZoran Jovanovic       Inst.addOperand(MCOperand::CreateReg(Reg+1));
12812deca348SZoran Jovanovic 
1282dde3d582SVladimir Medic     Inst.addOperand(MCOperand::CreateReg(Base));
1283dde3d582SVladimir Medic     Inst.addOperand(MCOperand::CreateImm(Offset));
1284a4c4b5fcSZoran Jovanovic   }
1285dde3d582SVladimir Medic 
1286dde3d582SVladimir Medic   return MCDisassembler::Success;
1287dde3d582SVladimir Medic }
1288dde3d582SVladimir Medic 
1289dde3d582SVladimir Medic static DecodeStatus DecodeMemMMImm16(MCInst &Inst,
1290dde3d582SVladimir Medic                                      unsigned Insn,
1291dde3d582SVladimir Medic                                      uint64_t Address,
1292dde3d582SVladimir Medic                                      const void *Decoder) {
1293dde3d582SVladimir Medic   int Offset = SignExtend32<16>(Insn & 0xffff);
1294dde3d582SVladimir Medic   unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1295dde3d582SVladimir Medic   unsigned Base = fieldFromInstruction(Insn, 16, 5);
1296dde3d582SVladimir Medic 
1297dde3d582SVladimir Medic   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1298dde3d582SVladimir Medic   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1299dde3d582SVladimir Medic 
1300dde3d582SVladimir Medic   Inst.addOperand(MCOperand::CreateReg(Reg));
1301dde3d582SVladimir Medic   Inst.addOperand(MCOperand::CreateReg(Base));
1302dde3d582SVladimir Medic   Inst.addOperand(MCOperand::CreateImm(Offset));
1303dde3d582SVladimir Medic 
1304dde3d582SVladimir Medic   return MCDisassembler::Success;
1305dde3d582SVladimir Medic }
1306dde3d582SVladimir Medic 
130771928e68SAkira Hatanaka static DecodeStatus DecodeFMem(MCInst &Inst,
130871928e68SAkira Hatanaka                                unsigned Insn,
130971928e68SAkira Hatanaka                                uint64_t Address,
131071928e68SAkira Hatanaka                                const void *Decoder) {
131171928e68SAkira Hatanaka   int Offset = SignExtend32<16>(Insn & 0xffff);
1312ecaef49fSJim Grosbach   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1313ecaef49fSJim Grosbach   unsigned Base = fieldFromInstruction(Insn, 21, 5);
131471928e68SAkira Hatanaka 
13159bf2b567SAkira Hatanaka   Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg);
131613e6ccf3SAkira Hatanaka   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
13179bf2b567SAkira Hatanaka 
13189bf2b567SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
13199bf2b567SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Base));
132071928e68SAkira Hatanaka   Inst.addOperand(MCOperand::CreateImm(Offset));
132171928e68SAkira Hatanaka 
132271928e68SAkira Hatanaka   return MCDisassembler::Success;
132371928e68SAkira Hatanaka }
132471928e68SAkira Hatanaka 
132592db6b78SDaniel Sanders static DecodeStatus DecodeFMem2(MCInst &Inst,
132692db6b78SDaniel Sanders                                unsigned Insn,
132792db6b78SDaniel Sanders                                uint64_t Address,
132892db6b78SDaniel Sanders                                const void *Decoder) {
132992db6b78SDaniel Sanders   int Offset = SignExtend32<16>(Insn & 0xffff);
133092db6b78SDaniel Sanders   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
133192db6b78SDaniel Sanders   unsigned Base = fieldFromInstruction(Insn, 21, 5);
133292db6b78SDaniel Sanders 
133392db6b78SDaniel Sanders   Reg = getReg(Decoder, Mips::COP2RegClassID, Reg);
133492db6b78SDaniel Sanders   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
133592db6b78SDaniel Sanders 
133692db6b78SDaniel Sanders   Inst.addOperand(MCOperand::CreateReg(Reg));
133792db6b78SDaniel Sanders   Inst.addOperand(MCOperand::CreateReg(Base));
133892db6b78SDaniel Sanders   Inst.addOperand(MCOperand::CreateImm(Offset));
133992db6b78SDaniel Sanders 
134092db6b78SDaniel Sanders   return MCDisassembler::Success;
134192db6b78SDaniel Sanders }
134292db6b78SDaniel Sanders 
134392db6b78SDaniel Sanders static DecodeStatus DecodeFMem3(MCInst &Inst,
134492db6b78SDaniel Sanders                                unsigned Insn,
134592db6b78SDaniel Sanders                                uint64_t Address,
134692db6b78SDaniel Sanders                                const void *Decoder) {
134792db6b78SDaniel Sanders   int Offset = SignExtend32<16>(Insn & 0xffff);
134892db6b78SDaniel Sanders   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
134992db6b78SDaniel Sanders   unsigned Base = fieldFromInstruction(Insn, 21, 5);
135092db6b78SDaniel Sanders 
135192db6b78SDaniel Sanders   Reg = getReg(Decoder, Mips::COP3RegClassID, Reg);
135292db6b78SDaniel Sanders   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
135392db6b78SDaniel Sanders 
135492db6b78SDaniel Sanders   Inst.addOperand(MCOperand::CreateReg(Reg));
135592db6b78SDaniel Sanders   Inst.addOperand(MCOperand::CreateReg(Base));
135692db6b78SDaniel Sanders   Inst.addOperand(MCOperand::CreateImm(Offset));
135792db6b78SDaniel Sanders 
135892db6b78SDaniel Sanders   return MCDisassembler::Success;
135992db6b78SDaniel Sanders }
136092db6b78SDaniel Sanders 
1361*435cf8a4SVladimir Medic static DecodeStatus DecodeFMemCop2R6(MCInst &Inst,
1362*435cf8a4SVladimir Medic                                     unsigned Insn,
1363*435cf8a4SVladimir Medic                                     uint64_t Address,
1364*435cf8a4SVladimir Medic                                     const void *Decoder) {
1365*435cf8a4SVladimir Medic   int Offset = SignExtend32<11>(Insn & 0x07ff);
1366*435cf8a4SVladimir Medic   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1367*435cf8a4SVladimir Medic   unsigned Base = fieldFromInstruction(Insn, 11, 5);
1368*435cf8a4SVladimir Medic 
1369*435cf8a4SVladimir Medic   Reg = getReg(Decoder, Mips::COP2RegClassID, Reg);
1370*435cf8a4SVladimir Medic   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1371*435cf8a4SVladimir Medic 
1372*435cf8a4SVladimir Medic   Inst.addOperand(MCOperand::CreateReg(Reg));
1373*435cf8a4SVladimir Medic   Inst.addOperand(MCOperand::CreateReg(Base));
1374*435cf8a4SVladimir Medic   Inst.addOperand(MCOperand::CreateImm(Offset));
1375*435cf8a4SVladimir Medic 
1376*435cf8a4SVladimir Medic   return MCDisassembler::Success;
1377*435cf8a4SVladimir Medic }
13786a803f61SDaniel Sanders static DecodeStatus DecodeSpecial3LlSc(MCInst &Inst,
13796a803f61SDaniel Sanders                                        unsigned Insn,
13806a803f61SDaniel Sanders                                        uint64_t Address,
13816a803f61SDaniel Sanders                                        const void *Decoder) {
13826a803f61SDaniel Sanders   int64_t Offset = SignExtend64<9>((Insn >> 7) & 0x1ff);
13836a803f61SDaniel Sanders   unsigned Rt = fieldFromInstruction(Insn, 16, 5);
13846a803f61SDaniel Sanders   unsigned Base = fieldFromInstruction(Insn, 21, 5);
13856a803f61SDaniel Sanders 
13866a803f61SDaniel Sanders   Rt = getReg(Decoder, Mips::GPR32RegClassID, Rt);
13876a803f61SDaniel Sanders   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
13886a803f61SDaniel Sanders 
13896a803f61SDaniel Sanders   if(Inst.getOpcode() == Mips::SC_R6 || Inst.getOpcode() == Mips::SCD_R6){
13906a803f61SDaniel Sanders     Inst.addOperand(MCOperand::CreateReg(Rt));
13916a803f61SDaniel Sanders   }
13926a803f61SDaniel Sanders 
13936a803f61SDaniel Sanders   Inst.addOperand(MCOperand::CreateReg(Rt));
13946a803f61SDaniel Sanders   Inst.addOperand(MCOperand::CreateReg(Base));
13956a803f61SDaniel Sanders   Inst.addOperand(MCOperand::CreateImm(Offset));
13966a803f61SDaniel Sanders 
13976a803f61SDaniel Sanders   return MCDisassembler::Success;
13986a803f61SDaniel Sanders }
139971928e68SAkira Hatanaka 
140071928e68SAkira Hatanaka static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
140171928e68SAkira Hatanaka                                               unsigned RegNo,
140271928e68SAkira Hatanaka                                               uint64_t Address,
140371928e68SAkira Hatanaka                                               const void *Decoder) {
140471928e68SAkira Hatanaka   // Currently only hardware register 29 is supported.
140571928e68SAkira Hatanaka   if (RegNo != 29)
140671928e68SAkira Hatanaka     return  MCDisassembler::Fail;
140771928e68SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Mips::HWR29));
140871928e68SAkira Hatanaka   return MCDisassembler::Success;
140971928e68SAkira Hatanaka }
141071928e68SAkira Hatanaka 
141171928e68SAkira Hatanaka static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
141271928e68SAkira Hatanaka                                               unsigned RegNo,
141371928e68SAkira Hatanaka                                               uint64_t Address,
141471928e68SAkira Hatanaka                                               const void *Decoder) {
14159bf2b567SAkira Hatanaka   if (RegNo > 30 || RegNo %2)
141671928e68SAkira Hatanaka     return MCDisassembler::Fail;
141771928e68SAkira Hatanaka 
14189bf2b567SAkira Hatanaka   ;
14199bf2b567SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::AFGR64RegClassID, RegNo /2);
14209bf2b567SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
142171928e68SAkira Hatanaka   return MCDisassembler::Success;
142271928e68SAkira Hatanaka }
142371928e68SAkira Hatanaka 
142400fcf2e1SAkira Hatanaka static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst,
1425ecabd1a5SAkira Hatanaka                                                 unsigned RegNo,
1426ecabd1a5SAkira Hatanaka                                                 uint64_t Address,
1427ecabd1a5SAkira Hatanaka                                                 const void *Decoder) {
1428ecabd1a5SAkira Hatanaka   if (RegNo >= 4)
1429ecabd1a5SAkira Hatanaka     return MCDisassembler::Fail;
1430ecabd1a5SAkira Hatanaka 
143100fcf2e1SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::ACC64DSPRegClassID, RegNo);
1432ecabd1a5SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
1433ecabd1a5SAkira Hatanaka   return MCDisassembler::Success;
1434ecabd1a5SAkira Hatanaka }
1435ecabd1a5SAkira Hatanaka 
14368002a3f6SAkira Hatanaka static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst,
143759bfaf77SAkira Hatanaka                                                unsigned RegNo,
143859bfaf77SAkira Hatanaka                                                uint64_t Address,
143959bfaf77SAkira Hatanaka                                                const void *Decoder) {
144059bfaf77SAkira Hatanaka   if (RegNo >= 4)
144159bfaf77SAkira Hatanaka     return MCDisassembler::Fail;
144259bfaf77SAkira Hatanaka 
14438002a3f6SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::HI32DSPRegClassID, RegNo);
144459bfaf77SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
144559bfaf77SAkira Hatanaka   return MCDisassembler::Success;
144659bfaf77SAkira Hatanaka }
144759bfaf77SAkira Hatanaka 
14488002a3f6SAkira Hatanaka static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst,
144959bfaf77SAkira Hatanaka                                                unsigned RegNo,
145059bfaf77SAkira Hatanaka                                                uint64_t Address,
145159bfaf77SAkira Hatanaka                                                const void *Decoder) {
145259bfaf77SAkira Hatanaka   if (RegNo >= 4)
145359bfaf77SAkira Hatanaka     return MCDisassembler::Fail;
145459bfaf77SAkira Hatanaka 
14558002a3f6SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::LO32DSPRegClassID, RegNo);
145659bfaf77SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
145759bfaf77SAkira Hatanaka   return MCDisassembler::Success;
145859bfaf77SAkira Hatanaka }
145959bfaf77SAkira Hatanaka 
14603eb663b0SJack Carter static DecodeStatus DecodeMSA128BRegisterClass(MCInst &Inst,
14613eb663b0SJack Carter                                                unsigned RegNo,
14623eb663b0SJack Carter                                                uint64_t Address,
14633eb663b0SJack Carter                                                const void *Decoder) {
14643eb663b0SJack Carter   if (RegNo > 31)
14653eb663b0SJack Carter     return MCDisassembler::Fail;
14663eb663b0SJack Carter 
14673eb663b0SJack Carter   unsigned Reg = getReg(Decoder, Mips::MSA128BRegClassID, RegNo);
14683eb663b0SJack Carter   Inst.addOperand(MCOperand::CreateReg(Reg));
14693eb663b0SJack Carter   return MCDisassembler::Success;
14703eb663b0SJack Carter }
14713eb663b0SJack Carter 
14725dc8ac92SJack Carter static DecodeStatus DecodeMSA128HRegisterClass(MCInst &Inst,
14735dc8ac92SJack Carter                                                unsigned RegNo,
14745dc8ac92SJack Carter                                                uint64_t Address,
14755dc8ac92SJack Carter                                                const void *Decoder) {
14765dc8ac92SJack Carter   if (RegNo > 31)
14775dc8ac92SJack Carter     return MCDisassembler::Fail;
14785dc8ac92SJack Carter 
14795dc8ac92SJack Carter   unsigned Reg = getReg(Decoder, Mips::MSA128HRegClassID, RegNo);
14805dc8ac92SJack Carter   Inst.addOperand(MCOperand::CreateReg(Reg));
14815dc8ac92SJack Carter   return MCDisassembler::Success;
14825dc8ac92SJack Carter }
14835dc8ac92SJack Carter 
14845dc8ac92SJack Carter static DecodeStatus DecodeMSA128WRegisterClass(MCInst &Inst,
14855dc8ac92SJack Carter                                                unsigned RegNo,
14865dc8ac92SJack Carter                                                uint64_t Address,
14875dc8ac92SJack Carter                                                const void *Decoder) {
14885dc8ac92SJack Carter   if (RegNo > 31)
14895dc8ac92SJack Carter     return MCDisassembler::Fail;
14905dc8ac92SJack Carter 
14915dc8ac92SJack Carter   unsigned Reg = getReg(Decoder, Mips::MSA128WRegClassID, RegNo);
14925dc8ac92SJack Carter   Inst.addOperand(MCOperand::CreateReg(Reg));
14935dc8ac92SJack Carter   return MCDisassembler::Success;
14945dc8ac92SJack Carter }
14955dc8ac92SJack Carter 
14965dc8ac92SJack Carter static DecodeStatus DecodeMSA128DRegisterClass(MCInst &Inst,
14975dc8ac92SJack Carter                                                unsigned RegNo,
14985dc8ac92SJack Carter                                                uint64_t Address,
14995dc8ac92SJack Carter                                                const void *Decoder) {
15005dc8ac92SJack Carter   if (RegNo > 31)
15015dc8ac92SJack Carter     return MCDisassembler::Fail;
15025dc8ac92SJack Carter 
15035dc8ac92SJack Carter   unsigned Reg = getReg(Decoder, Mips::MSA128DRegClassID, RegNo);
15045dc8ac92SJack Carter   Inst.addOperand(MCOperand::CreateReg(Reg));
15055dc8ac92SJack Carter   return MCDisassembler::Success;
15065dc8ac92SJack Carter }
15075dc8ac92SJack Carter 
1508a591fdc6SMatheus Almeida static DecodeStatus DecodeMSACtrlRegisterClass(MCInst &Inst,
1509a591fdc6SMatheus Almeida                                                unsigned RegNo,
1510a591fdc6SMatheus Almeida                                                uint64_t Address,
1511a591fdc6SMatheus Almeida                                                const void *Decoder) {
1512a591fdc6SMatheus Almeida   if (RegNo > 7)
1513a591fdc6SMatheus Almeida     return MCDisassembler::Fail;
1514a591fdc6SMatheus Almeida 
1515a591fdc6SMatheus Almeida   unsigned Reg = getReg(Decoder, Mips::MSACtrlRegClassID, RegNo);
1516a591fdc6SMatheus Almeida   Inst.addOperand(MCOperand::CreateReg(Reg));
1517a591fdc6SMatheus Almeida   return MCDisassembler::Success;
1518a591fdc6SMatheus Almeida }
1519a591fdc6SMatheus Almeida 
15202a83d680SDaniel Sanders static DecodeStatus DecodeCOP2RegisterClass(MCInst &Inst,
15212a83d680SDaniel Sanders                                             unsigned RegNo,
15222a83d680SDaniel Sanders                                             uint64_t Address,
15232a83d680SDaniel Sanders                                             const void *Decoder) {
15242a83d680SDaniel Sanders   if (RegNo > 31)
15252a83d680SDaniel Sanders     return MCDisassembler::Fail;
15262a83d680SDaniel Sanders 
15272a83d680SDaniel Sanders   unsigned Reg = getReg(Decoder, Mips::COP2RegClassID, RegNo);
15282a83d680SDaniel Sanders   Inst.addOperand(MCOperand::CreateReg(Reg));
15292a83d680SDaniel Sanders   return MCDisassembler::Success;
15302a83d680SDaniel Sanders }
15312a83d680SDaniel Sanders 
153271928e68SAkira Hatanaka static DecodeStatus DecodeBranchTarget(MCInst &Inst,
153371928e68SAkira Hatanaka                                        unsigned Offset,
153471928e68SAkira Hatanaka                                        uint64_t Address,
153571928e68SAkira Hatanaka                                        const void *Decoder) {
1536d37bab61SAlexey Samsonov   int32_t BranchOffset = (SignExtend32<16>(Offset) * 4) + 4;
153771928e68SAkira Hatanaka   Inst.addOperand(MCOperand::CreateImm(BranchOffset));
153871928e68SAkira Hatanaka   return MCDisassembler::Success;
153971928e68SAkira Hatanaka }
154071928e68SAkira Hatanaka 
154171928e68SAkira Hatanaka static DecodeStatus DecodeJumpTarget(MCInst &Inst,
154271928e68SAkira Hatanaka                                      unsigned Insn,
154371928e68SAkira Hatanaka                                      uint64_t Address,
154471928e68SAkira Hatanaka                                      const void *Decoder) {
154571928e68SAkira Hatanaka 
1546ecaef49fSJim Grosbach   unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 2;
154771928e68SAkira Hatanaka   Inst.addOperand(MCOperand::CreateImm(JumpOffset));
154871928e68SAkira Hatanaka   return MCDisassembler::Success;
154971928e68SAkira Hatanaka }
155071928e68SAkira Hatanaka 
15513c8869dcSZoran Jovanovic static DecodeStatus DecodeBranchTarget21(MCInst &Inst,
15523c8869dcSZoran Jovanovic                                          unsigned Offset,
15533c8869dcSZoran Jovanovic                                          uint64_t Address,
15543c8869dcSZoran Jovanovic                                          const void *Decoder) {
1555d37bab61SAlexey Samsonov   int32_t BranchOffset = SignExtend32<21>(Offset) * 4;
15563c8869dcSZoran Jovanovic 
15573c8869dcSZoran Jovanovic   Inst.addOperand(MCOperand::CreateImm(BranchOffset));
15583c8869dcSZoran Jovanovic   return MCDisassembler::Success;
15593c8869dcSZoran Jovanovic }
15603c8869dcSZoran Jovanovic 
15613c8869dcSZoran Jovanovic static DecodeStatus DecodeBranchTarget26(MCInst &Inst,
15623c8869dcSZoran Jovanovic                                          unsigned Offset,
15633c8869dcSZoran Jovanovic                                          uint64_t Address,
15643c8869dcSZoran Jovanovic                                          const void *Decoder) {
1565d37bab61SAlexey Samsonov   int32_t BranchOffset = SignExtend32<26>(Offset) * 4;
15663c8869dcSZoran Jovanovic 
15673c8869dcSZoran Jovanovic   Inst.addOperand(MCOperand::CreateImm(BranchOffset));
15683c8869dcSZoran Jovanovic   return MCDisassembler::Success;
15693c8869dcSZoran Jovanovic }
15703c8869dcSZoran Jovanovic 
15719761e96bSJozef Kolek static DecodeStatus DecodeBranchTarget7MM(MCInst &Inst,
15729761e96bSJozef Kolek                                           unsigned Offset,
15739761e96bSJozef Kolek                                           uint64_t Address,
15749761e96bSJozef Kolek                                           const void *Decoder) {
15759761e96bSJozef Kolek   int32_t BranchOffset = SignExtend32<7>(Offset) << 1;
15769761e96bSJozef Kolek   Inst.addOperand(MCOperand::CreateImm(BranchOffset));
15779761e96bSJozef Kolek   return MCDisassembler::Success;
15789761e96bSJozef Kolek }
15799761e96bSJozef Kolek 
15808a80aa76SZoran Jovanovic static DecodeStatus DecodeBranchTargetMM(MCInst &Inst,
15818a80aa76SZoran Jovanovic                                          unsigned Offset,
15828a80aa76SZoran Jovanovic                                          uint64_t Address,
15838a80aa76SZoran Jovanovic                                          const void *Decoder) {
1584d37bab61SAlexey Samsonov   int32_t BranchOffset = SignExtend32<16>(Offset) * 2;
15858a80aa76SZoran Jovanovic   Inst.addOperand(MCOperand::CreateImm(BranchOffset));
15868a80aa76SZoran Jovanovic   return MCDisassembler::Success;
15878a80aa76SZoran Jovanovic }
15888a80aa76SZoran Jovanovic 
1589507e084aSZoran Jovanovic static DecodeStatus DecodeJumpTargetMM(MCInst &Inst,
1590507e084aSZoran Jovanovic                                        unsigned Insn,
1591507e084aSZoran Jovanovic                                        uint64_t Address,
1592507e084aSZoran Jovanovic                                        const void *Decoder) {
1593507e084aSZoran Jovanovic   unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 1;
1594507e084aSZoran Jovanovic   Inst.addOperand(MCOperand::CreateImm(JumpOffset));
1595507e084aSZoran Jovanovic   return MCDisassembler::Success;
1596507e084aSZoran Jovanovic }
159771928e68SAkira Hatanaka 
1598aa2b9278SJozef Kolek static DecodeStatus DecodeAddiur2Simm7(MCInst &Inst,
1599aa2b9278SJozef Kolek                                        unsigned Value,
1600aa2b9278SJozef Kolek                                        uint64_t Address,
1601aa2b9278SJozef Kolek                                        const void *Decoder) {
1602aa2b9278SJozef Kolek   if (Value == 0)
1603aa2b9278SJozef Kolek     Inst.addOperand(MCOperand::CreateImm(1));
1604aa2b9278SJozef Kolek   else if (Value == 0x7)
1605aa2b9278SJozef Kolek     Inst.addOperand(MCOperand::CreateImm(-1));
1606aa2b9278SJozef Kolek   else
1607aa2b9278SJozef Kolek     Inst.addOperand(MCOperand::CreateImm(Value << 2));
1608aa2b9278SJozef Kolek   return MCDisassembler::Success;
1609aa2b9278SJozef Kolek }
1610aa2b9278SJozef Kolek 
1611aa2b9278SJozef Kolek static DecodeStatus DecodeUImm6Lsl2(MCInst &Inst,
1612aa2b9278SJozef Kolek                                     unsigned Value,
1613aa2b9278SJozef Kolek                                     uint64_t Address,
1614aa2b9278SJozef Kolek                                     const void *Decoder) {
1615aa2b9278SJozef Kolek   Inst.addOperand(MCOperand::CreateImm(Value << 2));
1616aa2b9278SJozef Kolek   return MCDisassembler::Success;
1617aa2b9278SJozef Kolek }
1618aa2b9278SJozef Kolek 
1619aa2b9278SJozef Kolek static DecodeStatus DecodeLiSimm7(MCInst &Inst,
1620aa2b9278SJozef Kolek                                   unsigned Value,
1621aa2b9278SJozef Kolek                                   uint64_t Address,
1622aa2b9278SJozef Kolek                                   const void *Decoder) {
1623aa2b9278SJozef Kolek   if (Value == 0x7F)
1624aa2b9278SJozef Kolek     Inst.addOperand(MCOperand::CreateImm(-1));
1625aa2b9278SJozef Kolek   else
1626aa2b9278SJozef Kolek     Inst.addOperand(MCOperand::CreateImm(Value));
1627aa2b9278SJozef Kolek   return MCDisassembler::Success;
1628aa2b9278SJozef Kolek }
1629aa2b9278SJozef Kolek 
1630aa2b9278SJozef Kolek static DecodeStatus DecodeSimm4(MCInst &Inst,
1631aa2b9278SJozef Kolek                                 unsigned Value,
1632aa2b9278SJozef Kolek                                 uint64_t Address,
1633aa2b9278SJozef Kolek                                 const void *Decoder) {
1634aa2b9278SJozef Kolek   Inst.addOperand(MCOperand::CreateImm(SignExtend32<4>(Value)));
1635aa2b9278SJozef Kolek   return MCDisassembler::Success;
1636aa2b9278SJozef Kolek }
1637aa2b9278SJozef Kolek 
163871928e68SAkira Hatanaka static DecodeStatus DecodeSimm16(MCInst &Inst,
163971928e68SAkira Hatanaka                                  unsigned Insn,
164071928e68SAkira Hatanaka                                  uint64_t Address,
164171928e68SAkira Hatanaka                                  const void *Decoder) {
164271928e68SAkira Hatanaka   Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Insn)));
164371928e68SAkira Hatanaka   return MCDisassembler::Success;
164471928e68SAkira Hatanaka }
164571928e68SAkira Hatanaka 
1646779c5937SMatheus Almeida static DecodeStatus DecodeLSAImm(MCInst &Inst,
1647779c5937SMatheus Almeida                                  unsigned Insn,
1648779c5937SMatheus Almeida                                  uint64_t Address,
1649779c5937SMatheus Almeida                                  const void *Decoder) {
1650779c5937SMatheus Almeida   // We add one to the immediate field as it was encoded as 'imm - 1'.
1651779c5937SMatheus Almeida   Inst.addOperand(MCOperand::CreateImm(Insn + 1));
1652779c5937SMatheus Almeida   return MCDisassembler::Success;
1653779c5937SMatheus Almeida }
1654779c5937SMatheus Almeida 
165571928e68SAkira Hatanaka static DecodeStatus DecodeInsSize(MCInst &Inst,
165671928e68SAkira Hatanaka                                   unsigned Insn,
165771928e68SAkira Hatanaka                                   uint64_t Address,
165871928e68SAkira Hatanaka                                   const void *Decoder) {
165971928e68SAkira Hatanaka   // First we need to grab the pos(lsb) from MCInst.
166071928e68SAkira Hatanaka   int Pos = Inst.getOperand(2).getImm();
166171928e68SAkira Hatanaka   int Size = (int) Insn - Pos + 1;
166271928e68SAkira Hatanaka   Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size)));
166371928e68SAkira Hatanaka   return MCDisassembler::Success;
166471928e68SAkira Hatanaka }
166571928e68SAkira Hatanaka 
166671928e68SAkira Hatanaka static DecodeStatus DecodeExtSize(MCInst &Inst,
166771928e68SAkira Hatanaka                                   unsigned Insn,
166871928e68SAkira Hatanaka                                   uint64_t Address,
166971928e68SAkira Hatanaka                                   const void *Decoder) {
167071928e68SAkira Hatanaka   int Size = (int) Insn  + 1;
167171928e68SAkira Hatanaka   Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size)));
167271928e68SAkira Hatanaka   return MCDisassembler::Success;
167371928e68SAkira Hatanaka }
1674b59e1a41SDaniel Sanders 
1675b59e1a41SDaniel Sanders static DecodeStatus DecodeSimm19Lsl2(MCInst &Inst, unsigned Insn,
1676b59e1a41SDaniel Sanders                                      uint64_t Address, const void *Decoder) {
1677d37bab61SAlexey Samsonov   Inst.addOperand(MCOperand::CreateImm(SignExtend32<19>(Insn) * 4));
1678b59e1a41SDaniel Sanders   return MCDisassembler::Success;
1679b59e1a41SDaniel Sanders }
16802855142aSZoran Jovanovic 
16812855142aSZoran Jovanovic static DecodeStatus DecodeSimm18Lsl3(MCInst &Inst, unsigned Insn,
16822855142aSZoran Jovanovic                                      uint64_t Address, const void *Decoder) {
1683d37bab61SAlexey Samsonov   Inst.addOperand(MCOperand::CreateImm(SignExtend32<18>(Insn) * 8));
16842855142aSZoran Jovanovic   return MCDisassembler::Success;
16852855142aSZoran Jovanovic }
1686a4c4b5fcSZoran Jovanovic 
1687b682ddf3SVladimir Medic static DecodeStatus DecodeSimm9SP(MCInst &Inst, unsigned Insn,
1688b682ddf3SVladimir Medic                                   uint64_t Address, const void *Decoder) {
1689b682ddf3SVladimir Medic   int32_t DecodedValue;
1690b682ddf3SVladimir Medic   switch (Insn) {
1691b682ddf3SVladimir Medic   case 0: DecodedValue = 256; break;
1692b682ddf3SVladimir Medic   case 1: DecodedValue = 257; break;
1693b682ddf3SVladimir Medic   case 510: DecodedValue = -258; break;
1694b682ddf3SVladimir Medic   case 511: DecodedValue = -257; break;
1695b682ddf3SVladimir Medic   default: DecodedValue = SignExtend32<9>(Insn); break;
1696b682ddf3SVladimir Medic   }
16972c55974dSAlexey Samsonov   Inst.addOperand(MCOperand::CreateImm(DecodedValue * 4));
1698b682ddf3SVladimir Medic   return MCDisassembler::Success;
1699b682ddf3SVladimir Medic }
1700b682ddf3SVladimir Medic 
1701b682ddf3SVladimir Medic static DecodeStatus DecodeANDI16Imm(MCInst &Inst, unsigned Insn,
1702b682ddf3SVladimir Medic                                     uint64_t Address, const void *Decoder) {
1703b682ddf3SVladimir Medic   // Insn must be >= 0, since it is unsigned that condition is always true.
1704b682ddf3SVladimir Medic   assert(Insn < 16);
1705b682ddf3SVladimir Medic   int32_t DecodedValues[] = {128, 1, 2, 3, 4, 7, 8, 15, 16, 31, 32, 63, 64,
1706b682ddf3SVladimir Medic                              255, 32768, 65535};
1707b682ddf3SVladimir Medic   Inst.addOperand(MCOperand::CreateImm(DecodedValues[Insn]));
1708b682ddf3SVladimir Medic   return MCDisassembler::Success;
1709b682ddf3SVladimir Medic }
1710b682ddf3SVladimir Medic 
1711b682ddf3SVladimir Medic static DecodeStatus DecodeUImm5lsl2(MCInst &Inst, unsigned Insn,
1712b682ddf3SVladimir Medic                                     uint64_t Address, const void *Decoder) {
1713b682ddf3SVladimir Medic   Inst.addOperand(MCOperand::CreateImm(Insn << 2));
1714b682ddf3SVladimir Medic   return MCDisassembler::Success;
1715b682ddf3SVladimir Medic }
1716b682ddf3SVladimir Medic 
1717a4c4b5fcSZoran Jovanovic static DecodeStatus DecodeRegListOperand(MCInst &Inst,
1718a4c4b5fcSZoran Jovanovic                                          unsigned Insn,
1719a4c4b5fcSZoran Jovanovic                                          uint64_t Address,
1720a4c4b5fcSZoran Jovanovic                                          const void *Decoder) {
1721a4c4b5fcSZoran Jovanovic   unsigned Regs[] = {Mips::S0, Mips::S1, Mips::S2, Mips::S3, Mips::S4, Mips::S5,
1722a4c4b5fcSZoran Jovanovic                      Mips::S6, Mips::FP};
1723a4c4b5fcSZoran Jovanovic   unsigned RegNum;
1724a4c4b5fcSZoran Jovanovic 
1725a4c4b5fcSZoran Jovanovic   unsigned RegLst = fieldFromInstruction(Insn, 21, 5);
1726a4c4b5fcSZoran Jovanovic   // Empty register lists are not allowed.
1727a4c4b5fcSZoran Jovanovic   if (RegLst == 0)
1728a4c4b5fcSZoran Jovanovic     return MCDisassembler::Fail;
1729a4c4b5fcSZoran Jovanovic 
1730a4c4b5fcSZoran Jovanovic   RegNum = RegLst & 0xf;
1731a4c4b5fcSZoran Jovanovic   for (unsigned i = 0; i < RegNum; i++)
1732a4c4b5fcSZoran Jovanovic     Inst.addOperand(MCOperand::CreateReg(Regs[i]));
1733a4c4b5fcSZoran Jovanovic 
1734a4c4b5fcSZoran Jovanovic   if (RegLst & 0x10)
1735a4c4b5fcSZoran Jovanovic     Inst.addOperand(MCOperand::CreateReg(Mips::RA));
1736a4c4b5fcSZoran Jovanovic 
1737a4c4b5fcSZoran Jovanovic   return MCDisassembler::Success;
1738a4c4b5fcSZoran Jovanovic }
1739f9a02500SZoran Jovanovic 
1740f9a02500SZoran Jovanovic static DecodeStatus DecodeRegListOperand16(MCInst &Inst, unsigned Insn,
1741f9a02500SZoran Jovanovic                                            uint64_t Address,
1742f9a02500SZoran Jovanovic                                            const void *Decoder) {
1743f9a02500SZoran Jovanovic   unsigned Regs[] = {Mips::S0, Mips::S1, Mips::S2, Mips::S3};
1744f9a02500SZoran Jovanovic   unsigned RegNum;
1745f9a02500SZoran Jovanovic 
1746f9a02500SZoran Jovanovic   unsigned RegLst = fieldFromInstruction(Insn, 4, 2);
1747f9a02500SZoran Jovanovic   // Empty register lists are not allowed.
1748f9a02500SZoran Jovanovic   if (RegLst == 0)
1749f9a02500SZoran Jovanovic     return MCDisassembler::Fail;
1750f9a02500SZoran Jovanovic 
1751f9a02500SZoran Jovanovic   RegNum = RegLst & 0x3;
1752f9a02500SZoran Jovanovic   for (unsigned i = 0; i < RegNum - 1; i++)
1753f9a02500SZoran Jovanovic     Inst.addOperand(MCOperand::CreateReg(Regs[i]));
1754f9a02500SZoran Jovanovic 
1755f9a02500SZoran Jovanovic   Inst.addOperand(MCOperand::CreateReg(Mips::RA));
1756f9a02500SZoran Jovanovic 
1757f9a02500SZoran Jovanovic   return MCDisassembler::Success;
1758f9a02500SZoran Jovanovic }
1759