171928e68SAkira Hatanaka //===- MipsDisassembler.cpp - Disassembler for Mips -------------*- C++ -*-===//
271928e68SAkira Hatanaka //
371928e68SAkira Hatanaka //                     The LLVM Compiler Infrastructure
471928e68SAkira Hatanaka //
571928e68SAkira Hatanaka // This file is distributed under the University of Illinois Open Source
671928e68SAkira Hatanaka // License. See LICENSE.TXT for details.
771928e68SAkira Hatanaka //
871928e68SAkira Hatanaka //===----------------------------------------------------------------------===//
971928e68SAkira Hatanaka //
1071928e68SAkira Hatanaka // This file is part of the Mips Disassembler.
1171928e68SAkira Hatanaka //
1271928e68SAkira Hatanaka //===----------------------------------------------------------------------===//
1371928e68SAkira Hatanaka 
1471928e68SAkira Hatanaka #include "Mips.h"
159bf2b567SAkira Hatanaka #include "MipsRegisterInfo.h"
16ed0881b2SChandler Carruth #include "MipsSubtarget.h"
17a1bc0f56SLang Hames #include "llvm/MC/MCContext.h"
1871928e68SAkira Hatanaka #include "llvm/MC/MCDisassembler.h"
19ecaef49fSJim Grosbach #include "llvm/MC/MCFixedLenDisassembler.h"
20ed0881b2SChandler Carruth #include "llvm/MC/MCInst.h"
21ed0881b2SChandler Carruth #include "llvm/MC/MCSubtargetInfo.h"
22ed0881b2SChandler Carruth #include "llvm/Support/MathExtras.h"
2371928e68SAkira Hatanaka #include "llvm/Support/TargetRegistry.h"
2471928e68SAkira Hatanaka 
2571928e68SAkira Hatanaka using namespace llvm;
2671928e68SAkira Hatanaka 
27e96dd897SChandler Carruth #define DEBUG_TYPE "mips-disassembler"
28e96dd897SChandler Carruth 
2971928e68SAkira Hatanaka typedef MCDisassembler::DecodeStatus DecodeStatus;
3071928e68SAkira Hatanaka 
31cb3e98cfSBenjamin Kramer namespace {
32cb3e98cfSBenjamin Kramer 
334aa6bea7SRafael Espindola /// A disasembler class for Mips.
349bf2b567SAkira Hatanaka class MipsDisassemblerBase : public MCDisassembler {
3571928e68SAkira Hatanaka public:
36a1bc0f56SLang Hames   MipsDisassemblerBase(const MCSubtargetInfo &STI, MCContext &Ctx,
374aa6bea7SRafael Espindola                        bool IsBigEndian)
384aa6bea7SRafael Espindola       : MCDisassembler(STI, Ctx),
394aa6bea7SRafael Espindola         IsN64(STI.getFeatureBits() & Mips::FeatureN64),
404aa6bea7SRafael Espindola         IsBigEndian(IsBigEndian) {}
4171928e68SAkira Hatanaka 
429bf2b567SAkira Hatanaka   virtual ~MipsDisassemblerBase() {}
439bf2b567SAkira Hatanaka 
449bfa2e2eSAkira Hatanaka   bool isN64() const { return IsN64; }
459bfa2e2eSAkira Hatanaka 
469bf2b567SAkira Hatanaka private:
479bfa2e2eSAkira Hatanaka   bool IsN64;
489bf2b567SAkira Hatanaka protected:
494aa6bea7SRafael Espindola   bool IsBigEndian;
509bf2b567SAkira Hatanaka };
519bf2b567SAkira Hatanaka 
524aa6bea7SRafael Espindola /// A disasembler class for Mips32.
539bf2b567SAkira Hatanaka class MipsDisassembler : public MipsDisassemblerBase {
54dde3d582SVladimir Medic   bool IsMicroMips;
559bf2b567SAkira Hatanaka public:
56c171f65aSDaniel Sanders   MipsDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx, bool bigEndian)
57c171f65aSDaniel Sanders       : MipsDisassemblerBase(STI, Ctx, bigEndian) {
58dde3d582SVladimir Medic     IsMicroMips = STI.getFeatureBits() & Mips::FeatureMicroMips;
59dde3d582SVladimir Medic   }
6071928e68SAkira Hatanaka 
61c171f65aSDaniel Sanders   bool hasMips3() const { return STI.getFeatureBits() & Mips::FeatureMips3; }
62c171f65aSDaniel Sanders   bool hasMips32() const { return STI.getFeatureBits() & Mips::FeatureMips32; }
63c171f65aSDaniel Sanders   bool hasMips32r6() const {
645c582b2fSDaniel Sanders     return STI.getFeatureBits() & Mips::FeatureMips32r6;
655c582b2fSDaniel Sanders   }
665c582b2fSDaniel Sanders 
670fa60416SDaniel Sanders   bool isGP64() const { return STI.getFeatureBits() & Mips::FeatureGP64Bit; }
680fa60416SDaniel Sanders 
69c171f65aSDaniel Sanders   bool hasCOP3() const {
70c171f65aSDaniel Sanders     // Only present in MIPS-I and MIPS-II
71c171f65aSDaniel Sanders     return !hasMips32() && !hasMips3();
72c171f65aSDaniel Sanders   }
73c171f65aSDaniel Sanders 
744aa6bea7SRafael Espindola   DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
757fc5b874SRafael Espindola                               ArrayRef<uint8_t> Bytes, uint64_t Address,
764aa6bea7SRafael Espindola                               raw_ostream &VStream,
774aa6bea7SRafael Espindola                               raw_ostream &CStream) const override;
7871928e68SAkira Hatanaka };
7971928e68SAkira Hatanaka 
804aa6bea7SRafael Espindola /// A disasembler class for Mips64.
819bf2b567SAkira Hatanaka class Mips64Disassembler : public MipsDisassemblerBase {
8271928e68SAkira Hatanaka public:
83a1bc0f56SLang Hames   Mips64Disassembler(const MCSubtargetInfo &STI, MCContext &Ctx,
849bf2b567SAkira Hatanaka                      bool bigEndian) :
85a1bc0f56SLang Hames     MipsDisassemblerBase(STI, Ctx, bigEndian) {}
8671928e68SAkira Hatanaka 
874aa6bea7SRafael Espindola   DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
887fc5b874SRafael Espindola                               ArrayRef<uint8_t> Bytes, uint64_t Address,
894aa6bea7SRafael Espindola                               raw_ostream &VStream,
904aa6bea7SRafael Espindola                               raw_ostream &CStream) const override;
9171928e68SAkira Hatanaka };
9271928e68SAkira Hatanaka 
93cb3e98cfSBenjamin Kramer } // end anonymous namespace
94cb3e98cfSBenjamin Kramer 
9571928e68SAkira Hatanaka // Forward declare these because the autogenerated code will reference them.
9671928e68SAkira Hatanaka // Definitions are further down.
9713e6ccf3SAkira Hatanaka static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst,
9871928e68SAkira Hatanaka                                              unsigned RegNo,
9971928e68SAkira Hatanaka                                              uint64_t Address,
10071928e68SAkira Hatanaka                                              const void *Decoder);
10171928e68SAkira Hatanaka 
102ec8a5490SReed Kotler static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst,
103ec8a5490SReed Kotler                                                  unsigned RegNo,
104ec8a5490SReed Kotler                                                  uint64_t Address,
105ec8a5490SReed Kotler                                                  const void *Decoder);
106ec8a5490SReed Kotler 
107b0852e54SZoran Jovanovic static DecodeStatus DecodeGPRMM16RegisterClass(MCInst &Inst,
108b0852e54SZoran Jovanovic                                                unsigned RegNo,
109b0852e54SZoran Jovanovic                                                uint64_t Address,
110b0852e54SZoran Jovanovic                                                const void *Decoder);
111b0852e54SZoran Jovanovic 
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 
2318a80aa76SZoran Jovanovic // DecodeBranchTargetMM - Decode microMIPS branch offset, which is
2328a80aa76SZoran Jovanovic // shifted left by 1 bit.
2338a80aa76SZoran Jovanovic static DecodeStatus DecodeBranchTargetMM(MCInst &Inst,
2348a80aa76SZoran Jovanovic                                          unsigned Offset,
2358a80aa76SZoran Jovanovic                                          uint64_t Address,
2368a80aa76SZoran Jovanovic                                          const void *Decoder);
2378a80aa76SZoran Jovanovic 
238507e084aSZoran Jovanovic // DecodeJumpTargetMM - Decode microMIPS jump target, which is
239507e084aSZoran Jovanovic // shifted left by 1 bit.
240507e084aSZoran Jovanovic static DecodeStatus DecodeJumpTargetMM(MCInst &Inst,
241507e084aSZoran Jovanovic                                        unsigned Insn,
242507e084aSZoran Jovanovic                                        uint64_t Address,
243507e084aSZoran Jovanovic                                        const void *Decoder);
244507e084aSZoran Jovanovic 
24571928e68SAkira Hatanaka static DecodeStatus DecodeMem(MCInst &Inst,
24671928e68SAkira Hatanaka                               unsigned Insn,
24771928e68SAkira Hatanaka                               uint64_t Address,
24871928e68SAkira Hatanaka                               const void *Decoder);
24971928e68SAkira Hatanaka 
25092db6b78SDaniel Sanders static DecodeStatus DecodeCacheOp(MCInst &Inst,
25192db6b78SDaniel Sanders                               unsigned Insn,
25292db6b78SDaniel Sanders                               uint64_t Address,
25392db6b78SDaniel Sanders                               const void *Decoder);
25492db6b78SDaniel Sanders 
255b4484d62SDaniel Sanders static DecodeStatus DecodeSyncI(MCInst &Inst,
256b4484d62SDaniel Sanders                                 unsigned Insn,
257b4484d62SDaniel Sanders                                 uint64_t Address,
258b4484d62SDaniel Sanders                                 const void *Decoder);
259b4484d62SDaniel Sanders 
260fe0bf9f6SMatheus Almeida static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn,
261fe0bf9f6SMatheus Almeida                                     uint64_t Address, const void *Decoder);
262fe0bf9f6SMatheus Almeida 
263315e7ecaSJozef Kolek static DecodeStatus DecodeMemMMImm4(MCInst &Inst,
264315e7ecaSJozef Kolek                                     unsigned Insn,
265315e7ecaSJozef Kolek                                     uint64_t Address,
266315e7ecaSJozef Kolek                                     const void *Decoder);
267315e7ecaSJozef Kolek 
268dde3d582SVladimir Medic static DecodeStatus DecodeMemMMImm12(MCInst &Inst,
269dde3d582SVladimir Medic                                      unsigned Insn,
270dde3d582SVladimir Medic                                      uint64_t Address,
271dde3d582SVladimir Medic                                      const void *Decoder);
272dde3d582SVladimir Medic 
273dde3d582SVladimir Medic static DecodeStatus DecodeMemMMImm16(MCInst &Inst,
274dde3d582SVladimir Medic                                      unsigned Insn,
275dde3d582SVladimir Medic                                      uint64_t Address,
276dde3d582SVladimir Medic                                      const void *Decoder);
277dde3d582SVladimir Medic 
27871928e68SAkira Hatanaka static DecodeStatus DecodeFMem(MCInst &Inst, unsigned Insn,
27971928e68SAkira Hatanaka                                uint64_t Address,
28071928e68SAkira Hatanaka                                const void *Decoder);
28171928e68SAkira Hatanaka 
28292db6b78SDaniel Sanders static DecodeStatus DecodeFMem2(MCInst &Inst, unsigned Insn,
28392db6b78SDaniel Sanders                                uint64_t Address,
28492db6b78SDaniel Sanders                                const void *Decoder);
28592db6b78SDaniel Sanders 
28692db6b78SDaniel Sanders static DecodeStatus DecodeFMem3(MCInst &Inst, unsigned Insn,
28792db6b78SDaniel Sanders                                uint64_t Address,
28892db6b78SDaniel Sanders                                const void *Decoder);
28992db6b78SDaniel Sanders 
2906a803f61SDaniel Sanders static DecodeStatus DecodeSpecial3LlSc(MCInst &Inst,
2916a803f61SDaniel Sanders                                        unsigned Insn,
2926a803f61SDaniel Sanders                                        uint64_t Address,
2936a803f61SDaniel Sanders                                        const void *Decoder);
2946a803f61SDaniel Sanders 
295aa2b9278SJozef Kolek static DecodeStatus DecodeAddiur2Simm7(MCInst &Inst,
296aa2b9278SJozef Kolek                                        unsigned Value,
297aa2b9278SJozef Kolek                                        uint64_t Address,
298aa2b9278SJozef Kolek                                        const void *Decoder);
299aa2b9278SJozef Kolek 
300aa2b9278SJozef Kolek static DecodeStatus DecodeUImm6Lsl2(MCInst &Inst,
301aa2b9278SJozef Kolek                                     unsigned Value,
302aa2b9278SJozef Kolek                                     uint64_t Address,
303aa2b9278SJozef Kolek                                     const void *Decoder);
304aa2b9278SJozef Kolek 
305aa2b9278SJozef Kolek static DecodeStatus DecodeLiSimm7(MCInst &Inst,
306aa2b9278SJozef Kolek                                   unsigned Value,
307aa2b9278SJozef Kolek                                   uint64_t Address,
308aa2b9278SJozef Kolek                                   const void *Decoder);
309aa2b9278SJozef Kolek 
310aa2b9278SJozef Kolek static DecodeStatus DecodeSimm4(MCInst &Inst,
311aa2b9278SJozef Kolek                                 unsigned Value,
312aa2b9278SJozef Kolek                                 uint64_t Address,
313aa2b9278SJozef Kolek                                 const void *Decoder);
314aa2b9278SJozef Kolek 
31571928e68SAkira Hatanaka static DecodeStatus DecodeSimm16(MCInst &Inst,
31671928e68SAkira Hatanaka                                  unsigned Insn,
31771928e68SAkira Hatanaka                                  uint64_t Address,
31871928e68SAkira Hatanaka                                  const void *Decoder);
31971928e68SAkira Hatanaka 
320779c5937SMatheus Almeida // Decode the immediate field of an LSA instruction which
321779c5937SMatheus Almeida // is off by one.
322779c5937SMatheus Almeida static DecodeStatus DecodeLSAImm(MCInst &Inst,
323779c5937SMatheus Almeida                                  unsigned Insn,
324779c5937SMatheus Almeida                                  uint64_t Address,
325779c5937SMatheus Almeida                                  const void *Decoder);
326779c5937SMatheus Almeida 
32771928e68SAkira Hatanaka static DecodeStatus DecodeInsSize(MCInst &Inst,
32871928e68SAkira Hatanaka                                   unsigned Insn,
32971928e68SAkira Hatanaka                                   uint64_t Address,
33071928e68SAkira Hatanaka                                   const void *Decoder);
33171928e68SAkira Hatanaka 
33271928e68SAkira Hatanaka static DecodeStatus DecodeExtSize(MCInst &Inst,
33371928e68SAkira Hatanaka                                   unsigned Insn,
33471928e68SAkira Hatanaka                                   uint64_t Address,
33571928e68SAkira Hatanaka                                   const void *Decoder);
33671928e68SAkira Hatanaka 
337b59e1a41SDaniel Sanders static DecodeStatus DecodeSimm19Lsl2(MCInst &Inst, unsigned Insn,
338b59e1a41SDaniel Sanders                                      uint64_t Address, const void *Decoder);
339b59e1a41SDaniel Sanders 
3402855142aSZoran Jovanovic static DecodeStatus DecodeSimm18Lsl3(MCInst &Inst, unsigned Insn,
3412855142aSZoran Jovanovic                                      uint64_t Address, const void *Decoder);
3422855142aSZoran Jovanovic 
343b682ddf3SVladimir Medic static DecodeStatus DecodeSimm9SP(MCInst &Inst, unsigned Insn,
344b682ddf3SVladimir Medic                                   uint64_t Address, const void *Decoder);
345b682ddf3SVladimir Medic 
346b682ddf3SVladimir Medic static DecodeStatus DecodeANDI16Imm(MCInst &Inst, unsigned Insn,
347b682ddf3SVladimir Medic                                     uint64_t Address, const void *Decoder);
348b682ddf3SVladimir Medic 
349b682ddf3SVladimir Medic static DecodeStatus DecodeUImm5lsl2(MCInst &Inst, unsigned Insn,
350b682ddf3SVladimir Medic                                    uint64_t Address, const void *Decoder);
351b682ddf3SVladimir Medic 
352b50ccf8eSDaniel Sanders /// INSVE_[BHWD] have an implicit operand that the generated decoder doesn't
353b50ccf8eSDaniel Sanders /// handle.
354b50ccf8eSDaniel Sanders template <typename InsnType>
355b50ccf8eSDaniel Sanders static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address,
356b50ccf8eSDaniel Sanders                                    const void *Decoder);
3575c582b2fSDaniel Sanders 
3585c582b2fSDaniel Sanders template <typename InsnType>
3595c582b2fSDaniel Sanders static DecodeStatus
3605c582b2fSDaniel Sanders DecodeAddiGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
3615c582b2fSDaniel Sanders                       const void *Decoder);
3625c582b2fSDaniel Sanders 
3635c582b2fSDaniel Sanders template <typename InsnType>
3645c582b2fSDaniel Sanders static DecodeStatus
3655c582b2fSDaniel Sanders DecodeDaddiGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
3665c582b2fSDaniel Sanders                        const void *Decoder);
3675c582b2fSDaniel Sanders 
3685c582b2fSDaniel Sanders template <typename InsnType>
3695c582b2fSDaniel Sanders static DecodeStatus
3705c582b2fSDaniel Sanders DecodeBlezlGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
3715c582b2fSDaniel Sanders                        const void *Decoder);
3725c582b2fSDaniel Sanders 
3735c582b2fSDaniel Sanders template <typename InsnType>
3745c582b2fSDaniel Sanders static DecodeStatus
3755c582b2fSDaniel Sanders DecodeBgtzlGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
3765c582b2fSDaniel Sanders                        const void *Decoder);
3775c582b2fSDaniel Sanders 
3785c582b2fSDaniel Sanders template <typename InsnType>
3795c582b2fSDaniel Sanders static DecodeStatus
3805c582b2fSDaniel Sanders DecodeBgtzGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
3815c582b2fSDaniel Sanders                       const void *Decoder);
3825c582b2fSDaniel Sanders 
38328a0ca07SZoran Jovanovic template <typename InsnType>
38428a0ca07SZoran Jovanovic static DecodeStatus
38528a0ca07SZoran Jovanovic DecodeBlezGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
38628a0ca07SZoran Jovanovic                        const void *Decoder);
38728a0ca07SZoran Jovanovic 
388a4c4b5fcSZoran Jovanovic static DecodeStatus DecodeRegListOperand(MCInst &Inst, unsigned Insn,
389a4c4b5fcSZoran Jovanovic                                          uint64_t Address,
390a4c4b5fcSZoran Jovanovic                                          const void *Decoder);
391a4c4b5fcSZoran Jovanovic 
392f9a02500SZoran Jovanovic static DecodeStatus DecodeRegListOperand16(MCInst &Inst, unsigned Insn,
393f9a02500SZoran Jovanovic                                            uint64_t Address,
394f9a02500SZoran Jovanovic                                            const void *Decoder);
395f9a02500SZoran Jovanovic 
39671928e68SAkira Hatanaka namespace llvm {
39771928e68SAkira Hatanaka extern Target TheMipselTarget, TheMipsTarget, TheMips64Target,
39871928e68SAkira Hatanaka               TheMips64elTarget;
39971928e68SAkira Hatanaka }
40071928e68SAkira Hatanaka 
40171928e68SAkira Hatanaka static MCDisassembler *createMipsDisassembler(
40271928e68SAkira Hatanaka                        const Target &T,
403a1bc0f56SLang Hames                        const MCSubtargetInfo &STI,
404a1bc0f56SLang Hames                        MCContext &Ctx) {
405a1bc0f56SLang Hames   return new MipsDisassembler(STI, Ctx, true);
40671928e68SAkira Hatanaka }
40771928e68SAkira Hatanaka 
40871928e68SAkira Hatanaka static MCDisassembler *createMipselDisassembler(
40971928e68SAkira Hatanaka                        const Target &T,
410a1bc0f56SLang Hames                        const MCSubtargetInfo &STI,
411a1bc0f56SLang Hames                        MCContext &Ctx) {
412a1bc0f56SLang Hames   return new MipsDisassembler(STI, Ctx, false);
41371928e68SAkira Hatanaka }
41471928e68SAkira Hatanaka 
41571928e68SAkira Hatanaka static MCDisassembler *createMips64Disassembler(
41671928e68SAkira Hatanaka                        const Target &T,
417a1bc0f56SLang Hames                        const MCSubtargetInfo &STI,
418a1bc0f56SLang Hames                        MCContext &Ctx) {
419a1bc0f56SLang Hames   return new Mips64Disassembler(STI, Ctx, true);
42071928e68SAkira Hatanaka }
42171928e68SAkira Hatanaka 
42271928e68SAkira Hatanaka static MCDisassembler *createMips64elDisassembler(
42371928e68SAkira Hatanaka                        const Target &T,
424a1bc0f56SLang Hames                        const MCSubtargetInfo &STI,
425a1bc0f56SLang Hames                        MCContext &Ctx) {
426a1bc0f56SLang Hames   return new Mips64Disassembler(STI, Ctx, false);
42771928e68SAkira Hatanaka }
42871928e68SAkira Hatanaka 
42971928e68SAkira Hatanaka extern "C" void LLVMInitializeMipsDisassembler() {
43071928e68SAkira Hatanaka   // Register the disassembler.
43171928e68SAkira Hatanaka   TargetRegistry::RegisterMCDisassembler(TheMipsTarget,
43271928e68SAkira Hatanaka                                          createMipsDisassembler);
43371928e68SAkira Hatanaka   TargetRegistry::RegisterMCDisassembler(TheMipselTarget,
43471928e68SAkira Hatanaka                                          createMipselDisassembler);
43571928e68SAkira Hatanaka   TargetRegistry::RegisterMCDisassembler(TheMips64Target,
43671928e68SAkira Hatanaka                                          createMips64Disassembler);
43771928e68SAkira Hatanaka   TargetRegistry::RegisterMCDisassembler(TheMips64elTarget,
43871928e68SAkira Hatanaka                                          createMips64elDisassembler);
43971928e68SAkira Hatanaka }
44071928e68SAkira Hatanaka 
44171928e68SAkira Hatanaka #include "MipsGenDisassemblerTables.inc"
44271928e68SAkira Hatanaka 
4435c582b2fSDaniel Sanders static unsigned getReg(const void *D, unsigned RC, unsigned RegNo) {
4445c582b2fSDaniel Sanders   const MipsDisassemblerBase *Dis = static_cast<const MipsDisassemblerBase*>(D);
4455c582b2fSDaniel Sanders   const MCRegisterInfo *RegInfo = Dis->getContext().getRegisterInfo();
4465c582b2fSDaniel Sanders   return *(RegInfo->getRegClass(RC).begin() + RegNo);
4475c582b2fSDaniel Sanders }
4485c582b2fSDaniel Sanders 
449b50ccf8eSDaniel Sanders template <typename InsnType>
450b50ccf8eSDaniel Sanders static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address,
451b50ccf8eSDaniel Sanders                                    const void *Decoder) {
452b50ccf8eSDaniel Sanders   typedef DecodeStatus (*DecodeFN)(MCInst &, unsigned, uint64_t, const void *);
453b50ccf8eSDaniel Sanders   // The size of the n field depends on the element size
454b50ccf8eSDaniel Sanders   // The register class also depends on this.
455b50ccf8eSDaniel Sanders   InsnType tmp = fieldFromInstruction(insn, 17, 5);
456b50ccf8eSDaniel Sanders   unsigned NSize = 0;
457b50ccf8eSDaniel Sanders   DecodeFN RegDecoder = nullptr;
458b50ccf8eSDaniel Sanders   if ((tmp & 0x18) == 0x00) { // INSVE_B
459b50ccf8eSDaniel Sanders     NSize = 4;
460b50ccf8eSDaniel Sanders     RegDecoder = DecodeMSA128BRegisterClass;
461b50ccf8eSDaniel Sanders   } else if ((tmp & 0x1c) == 0x10) { // INSVE_H
462b50ccf8eSDaniel Sanders     NSize = 3;
463b50ccf8eSDaniel Sanders     RegDecoder = DecodeMSA128HRegisterClass;
464b50ccf8eSDaniel Sanders   } else if ((tmp & 0x1e) == 0x18) { // INSVE_W
465b50ccf8eSDaniel Sanders     NSize = 2;
466b50ccf8eSDaniel Sanders     RegDecoder = DecodeMSA128WRegisterClass;
467b50ccf8eSDaniel Sanders   } else if ((tmp & 0x1f) == 0x1c) { // INSVE_D
468b50ccf8eSDaniel Sanders     NSize = 1;
469b50ccf8eSDaniel Sanders     RegDecoder = DecodeMSA128DRegisterClass;
470b50ccf8eSDaniel Sanders   } else
471b50ccf8eSDaniel Sanders     llvm_unreachable("Invalid encoding");
472b50ccf8eSDaniel Sanders 
473b50ccf8eSDaniel Sanders   assert(NSize != 0 && RegDecoder != nullptr);
474b50ccf8eSDaniel Sanders 
475b50ccf8eSDaniel Sanders   // $wd
476b50ccf8eSDaniel Sanders   tmp = fieldFromInstruction(insn, 6, 5);
477b50ccf8eSDaniel Sanders   if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
478b50ccf8eSDaniel Sanders     return MCDisassembler::Fail;
479b50ccf8eSDaniel Sanders   // $wd_in
480b50ccf8eSDaniel Sanders   if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
481b50ccf8eSDaniel Sanders     return MCDisassembler::Fail;
482b50ccf8eSDaniel Sanders   // $n
483b50ccf8eSDaniel Sanders   tmp = fieldFromInstruction(insn, 16, NSize);
484b50ccf8eSDaniel Sanders   MI.addOperand(MCOperand::CreateImm(tmp));
485b50ccf8eSDaniel Sanders   // $ws
486b50ccf8eSDaniel Sanders   tmp = fieldFromInstruction(insn, 11, 5);
487b50ccf8eSDaniel Sanders   if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
488b50ccf8eSDaniel Sanders     return MCDisassembler::Fail;
489b50ccf8eSDaniel Sanders   // $n2
490b50ccf8eSDaniel Sanders   MI.addOperand(MCOperand::CreateImm(0));
491b50ccf8eSDaniel Sanders 
492b50ccf8eSDaniel Sanders   return MCDisassembler::Success;
493b50ccf8eSDaniel Sanders }
494b50ccf8eSDaniel Sanders 
4955c582b2fSDaniel Sanders template <typename InsnType>
4965c582b2fSDaniel Sanders static DecodeStatus DecodeAddiGroupBranch(MCInst &MI, InsnType insn,
4975c582b2fSDaniel Sanders                                           uint64_t Address,
4985c582b2fSDaniel Sanders                                           const void *Decoder) {
4995c582b2fSDaniel Sanders   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
5005c582b2fSDaniel Sanders   // (otherwise we would have matched the ADDI instruction from the earlier
5015c582b2fSDaniel Sanders   // ISA's instead).
5025c582b2fSDaniel Sanders   //
5035c582b2fSDaniel Sanders   // We have:
5045c582b2fSDaniel Sanders   //    0b001000 sssss ttttt iiiiiiiiiiiiiiii
5055c582b2fSDaniel Sanders   //      BOVC if rs >= rt
5065c582b2fSDaniel Sanders   //      BEQZALC if rs == 0 && rt != 0
5075c582b2fSDaniel Sanders   //      BEQC if rs < rt && rs != 0
5085c582b2fSDaniel Sanders 
5095c582b2fSDaniel Sanders   InsnType Rs = fieldFromInstruction(insn, 21, 5);
5105c582b2fSDaniel Sanders   InsnType Rt = fieldFromInstruction(insn, 16, 5);
511d37bab61SAlexey Samsonov   InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4;
5125c582b2fSDaniel Sanders   bool HasRs = false;
5135c582b2fSDaniel Sanders 
5145c582b2fSDaniel Sanders   if (Rs >= Rt) {
5155c582b2fSDaniel Sanders     MI.setOpcode(Mips::BOVC);
5165c582b2fSDaniel Sanders     HasRs = true;
5175c582b2fSDaniel Sanders   } else if (Rs != 0 && Rs < Rt) {
5185c582b2fSDaniel Sanders     MI.setOpcode(Mips::BEQC);
5195c582b2fSDaniel Sanders     HasRs = true;
5205c582b2fSDaniel Sanders   } else
5215c582b2fSDaniel Sanders     MI.setOpcode(Mips::BEQZALC);
5225c582b2fSDaniel Sanders 
5235c582b2fSDaniel Sanders   if (HasRs)
5245c582b2fSDaniel Sanders     MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
5255c582b2fSDaniel Sanders                                        Rs)));
5265c582b2fSDaniel Sanders 
5275c582b2fSDaniel Sanders   MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
5285c582b2fSDaniel Sanders                                      Rt)));
5295c582b2fSDaniel Sanders   MI.addOperand(MCOperand::CreateImm(Imm));
5305c582b2fSDaniel Sanders 
5315c582b2fSDaniel Sanders   return MCDisassembler::Success;
5325c582b2fSDaniel Sanders }
5335c582b2fSDaniel Sanders 
5345c582b2fSDaniel Sanders template <typename InsnType>
5355c582b2fSDaniel Sanders static DecodeStatus DecodeDaddiGroupBranch(MCInst &MI, InsnType insn,
5365c582b2fSDaniel Sanders                                            uint64_t Address,
5375c582b2fSDaniel Sanders                                            const void *Decoder) {
5385c582b2fSDaniel Sanders   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
5395c582b2fSDaniel Sanders   // (otherwise we would have matched the ADDI instruction from the earlier
5405c582b2fSDaniel Sanders   // ISA's instead).
5415c582b2fSDaniel Sanders   //
5425c582b2fSDaniel Sanders   // We have:
5435c582b2fSDaniel Sanders   //    0b011000 sssss ttttt iiiiiiiiiiiiiiii
5445c582b2fSDaniel Sanders   //      BNVC if rs >= rt
5455c582b2fSDaniel Sanders   //      BNEZALC if rs == 0 && rt != 0
5465c582b2fSDaniel Sanders   //      BNEC if rs < rt && rs != 0
5475c582b2fSDaniel Sanders 
5485c582b2fSDaniel Sanders   InsnType Rs = fieldFromInstruction(insn, 21, 5);
5495c582b2fSDaniel Sanders   InsnType Rt = fieldFromInstruction(insn, 16, 5);
550d37bab61SAlexey Samsonov   InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4;
5515c582b2fSDaniel Sanders   bool HasRs = false;
5525c582b2fSDaniel Sanders 
5535c582b2fSDaniel Sanders   if (Rs >= Rt) {
5545c582b2fSDaniel Sanders     MI.setOpcode(Mips::BNVC);
5555c582b2fSDaniel Sanders     HasRs = true;
5565c582b2fSDaniel Sanders   } else if (Rs != 0 && Rs < Rt) {
5575c582b2fSDaniel Sanders     MI.setOpcode(Mips::BNEC);
5585c582b2fSDaniel Sanders     HasRs = true;
5595c582b2fSDaniel Sanders   } else
5605c582b2fSDaniel Sanders     MI.setOpcode(Mips::BNEZALC);
5615c582b2fSDaniel Sanders 
5625c582b2fSDaniel Sanders   if (HasRs)
5635c582b2fSDaniel Sanders     MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
5645c582b2fSDaniel Sanders                                        Rs)));
5655c582b2fSDaniel Sanders 
5665c582b2fSDaniel Sanders   MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
5675c582b2fSDaniel Sanders                                      Rt)));
5685c582b2fSDaniel Sanders   MI.addOperand(MCOperand::CreateImm(Imm));
5695c582b2fSDaniel Sanders 
5705c582b2fSDaniel Sanders   return MCDisassembler::Success;
5715c582b2fSDaniel Sanders }
5725c582b2fSDaniel Sanders 
5735c582b2fSDaniel Sanders template <typename InsnType>
5745c582b2fSDaniel Sanders static DecodeStatus DecodeBlezlGroupBranch(MCInst &MI, InsnType insn,
5755c582b2fSDaniel Sanders                                            uint64_t Address,
5765c582b2fSDaniel Sanders                                            const void *Decoder) {
5775c582b2fSDaniel Sanders   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
5785c582b2fSDaniel Sanders   // (otherwise we would have matched the BLEZL instruction from the earlier
5795c582b2fSDaniel Sanders   // ISA's instead).
5805c582b2fSDaniel Sanders   //
5815c582b2fSDaniel Sanders   // We have:
5825c582b2fSDaniel Sanders   //    0b010110 sssss ttttt iiiiiiiiiiiiiiii
5835c582b2fSDaniel Sanders   //      Invalid if rs == 0
5845c582b2fSDaniel Sanders   //      BLEZC   if rs == 0  && rt != 0
5855c582b2fSDaniel Sanders   //      BGEZC   if rs == rt && rt != 0
5865c582b2fSDaniel Sanders   //      BGEC    if rs != rt && rs != 0  && rt != 0
5875c582b2fSDaniel Sanders 
5885c582b2fSDaniel Sanders   InsnType Rs = fieldFromInstruction(insn, 21, 5);
5895c582b2fSDaniel Sanders   InsnType Rt = fieldFromInstruction(insn, 16, 5);
590d37bab61SAlexey Samsonov   InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4;
59128a0ca07SZoran Jovanovic   bool HasRs = false;
5925c582b2fSDaniel Sanders 
5935c582b2fSDaniel Sanders   if (Rt == 0)
5945c582b2fSDaniel Sanders     return MCDisassembler::Fail;
5955c582b2fSDaniel Sanders   else if (Rs == 0)
5965c582b2fSDaniel Sanders     MI.setOpcode(Mips::BLEZC);
5975c582b2fSDaniel Sanders   else if (Rs == Rt)
5985c582b2fSDaniel Sanders     MI.setOpcode(Mips::BGEZC);
59928a0ca07SZoran Jovanovic   else {
60028a0ca07SZoran Jovanovic     HasRs = true;
60128a0ca07SZoran Jovanovic     MI.setOpcode(Mips::BGEC);
60228a0ca07SZoran Jovanovic   }
60328a0ca07SZoran Jovanovic 
60428a0ca07SZoran Jovanovic   if (HasRs)
60528a0ca07SZoran Jovanovic     MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
60628a0ca07SZoran Jovanovic                                        Rs)));
6075c582b2fSDaniel Sanders 
6085c582b2fSDaniel Sanders   MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
6095c582b2fSDaniel Sanders                                      Rt)));
6105c582b2fSDaniel Sanders 
6115c582b2fSDaniel Sanders   MI.addOperand(MCOperand::CreateImm(Imm));
6125c582b2fSDaniel Sanders 
6135c582b2fSDaniel Sanders   return MCDisassembler::Success;
6145c582b2fSDaniel Sanders }
6155c582b2fSDaniel Sanders 
6165c582b2fSDaniel Sanders template <typename InsnType>
6175c582b2fSDaniel Sanders static DecodeStatus DecodeBgtzlGroupBranch(MCInst &MI, InsnType insn,
6185c582b2fSDaniel Sanders                                            uint64_t Address,
6195c582b2fSDaniel Sanders                                            const void *Decoder) {
6205c582b2fSDaniel Sanders   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
6215c582b2fSDaniel Sanders   // (otherwise we would have matched the BGTZL instruction from the earlier
6225c582b2fSDaniel Sanders   // ISA's instead).
6235c582b2fSDaniel Sanders   //
6245c582b2fSDaniel Sanders   // We have:
6255c582b2fSDaniel Sanders   //    0b010111 sssss ttttt iiiiiiiiiiiiiiii
6265c582b2fSDaniel Sanders   //      Invalid if rs == 0
6275c582b2fSDaniel Sanders   //      BGTZC   if rs == 0  && rt != 0
6285c582b2fSDaniel Sanders   //      BLTZC   if rs == rt && rt != 0
6295c582b2fSDaniel Sanders   //      BLTC    if rs != rt && rs != 0  && rt != 0
6305c582b2fSDaniel Sanders 
6315c14b069SZoran Jovanovic   bool HasRs = false;
6325c14b069SZoran Jovanovic 
6335c582b2fSDaniel Sanders   InsnType Rs = fieldFromInstruction(insn, 21, 5);
6345c582b2fSDaniel Sanders   InsnType Rt = fieldFromInstruction(insn, 16, 5);
635d37bab61SAlexey Samsonov   InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4;
6365c582b2fSDaniel Sanders 
6375c582b2fSDaniel Sanders   if (Rt == 0)
6385c582b2fSDaniel Sanders     return MCDisassembler::Fail;
6395c582b2fSDaniel Sanders   else if (Rs == 0)
6405c582b2fSDaniel Sanders     MI.setOpcode(Mips::BGTZC);
6415c582b2fSDaniel Sanders   else if (Rs == Rt)
6425c582b2fSDaniel Sanders     MI.setOpcode(Mips::BLTZC);
6435c14b069SZoran Jovanovic   else {
6445c14b069SZoran Jovanovic     MI.setOpcode(Mips::BLTC);
6455c14b069SZoran Jovanovic     HasRs = true;
6465c14b069SZoran Jovanovic   }
6475c14b069SZoran Jovanovic 
6485c14b069SZoran Jovanovic   if (HasRs)
6495c14b069SZoran Jovanovic     MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
6505c14b069SZoran Jovanovic                                               Rs)));
6515c582b2fSDaniel Sanders 
6525c582b2fSDaniel Sanders   MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
6535c582b2fSDaniel Sanders                                      Rt)));
6545c582b2fSDaniel Sanders 
6555c582b2fSDaniel Sanders   MI.addOperand(MCOperand::CreateImm(Imm));
6565c582b2fSDaniel Sanders 
6575c582b2fSDaniel Sanders   return MCDisassembler::Success;
6585c582b2fSDaniel Sanders }
6595c582b2fSDaniel Sanders 
6605c582b2fSDaniel Sanders template <typename InsnType>
6615c582b2fSDaniel Sanders static DecodeStatus DecodeBgtzGroupBranch(MCInst &MI, InsnType insn,
6625c582b2fSDaniel Sanders                                           uint64_t Address,
6635c582b2fSDaniel Sanders                                           const void *Decoder) {
6645c582b2fSDaniel Sanders   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
6655c582b2fSDaniel Sanders   // (otherwise we would have matched the BGTZ instruction from the earlier
6665c582b2fSDaniel Sanders   // ISA's instead).
6675c582b2fSDaniel Sanders   //
6685c582b2fSDaniel Sanders   // We have:
6695c582b2fSDaniel Sanders   //    0b000111 sssss ttttt iiiiiiiiiiiiiiii
6705c582b2fSDaniel Sanders   //      BGTZ    if rt == 0
6715c582b2fSDaniel Sanders   //      BGTZALC if rs == 0 && rt != 0
6725c582b2fSDaniel Sanders   //      BLTZALC if rs != 0 && rs == rt
6735c582b2fSDaniel Sanders   //      BLTUC   if rs != 0 && rs != rt
6745c582b2fSDaniel Sanders 
6755c582b2fSDaniel Sanders   InsnType Rs = fieldFromInstruction(insn, 21, 5);
6765c582b2fSDaniel Sanders   InsnType Rt = fieldFromInstruction(insn, 16, 5);
677d37bab61SAlexey Samsonov   InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4;
6785c582b2fSDaniel Sanders   bool HasRs = false;
6795c582b2fSDaniel Sanders   bool HasRt = false;
6805c582b2fSDaniel Sanders 
6815c582b2fSDaniel Sanders   if (Rt == 0) {
6825c582b2fSDaniel Sanders     MI.setOpcode(Mips::BGTZ);
6835c582b2fSDaniel Sanders     HasRs = true;
6845c582b2fSDaniel Sanders   } else if (Rs == 0) {
6855c582b2fSDaniel Sanders     MI.setOpcode(Mips::BGTZALC);
6865c582b2fSDaniel Sanders     HasRt = true;
6875c582b2fSDaniel Sanders   } else if (Rs == Rt) {
6885c582b2fSDaniel Sanders     MI.setOpcode(Mips::BLTZALC);
6895c582b2fSDaniel Sanders     HasRs = true;
6905c14b069SZoran Jovanovic   } else {
6915c14b069SZoran Jovanovic     MI.setOpcode(Mips::BLTUC);
6925c14b069SZoran Jovanovic     HasRs = true;
6935c14b069SZoran Jovanovic     HasRt = true;
6945c14b069SZoran Jovanovic   }
6955c582b2fSDaniel Sanders 
6965c582b2fSDaniel Sanders   if (HasRs)
6975c582b2fSDaniel Sanders     MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
6985c582b2fSDaniel Sanders                                        Rs)));
6995c582b2fSDaniel Sanders 
7005c582b2fSDaniel Sanders   if (HasRt)
7015c582b2fSDaniel Sanders     MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
7025c582b2fSDaniel Sanders                                        Rt)));
7035c582b2fSDaniel Sanders 
7045c582b2fSDaniel Sanders   MI.addOperand(MCOperand::CreateImm(Imm));
7055c582b2fSDaniel Sanders 
7065c582b2fSDaniel Sanders   return MCDisassembler::Success;
7075c582b2fSDaniel Sanders }
7085c582b2fSDaniel Sanders 
70928a0ca07SZoran Jovanovic template <typename InsnType>
71028a0ca07SZoran Jovanovic static DecodeStatus DecodeBlezGroupBranch(MCInst &MI, InsnType insn,
71128a0ca07SZoran Jovanovic                                            uint64_t Address,
71228a0ca07SZoran Jovanovic                                            const void *Decoder) {
71328a0ca07SZoran Jovanovic   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
71428a0ca07SZoran Jovanovic   // (otherwise we would have matched the BLEZL instruction from the earlier
71528a0ca07SZoran Jovanovic   // ISA's instead).
71628a0ca07SZoran Jovanovic   //
71728a0ca07SZoran Jovanovic   // We have:
71828a0ca07SZoran Jovanovic   //    0b000110 sssss ttttt iiiiiiiiiiiiiiii
71928a0ca07SZoran Jovanovic   //      Invalid   if rs == 0
72028a0ca07SZoran Jovanovic   //      BLEZALC   if rs == 0  && rt != 0
72128a0ca07SZoran Jovanovic   //      BGEZALC   if rs == rt && rt != 0
72228a0ca07SZoran Jovanovic   //      BGEUC     if rs != rt && rs != 0  && rt != 0
72328a0ca07SZoran Jovanovic 
72428a0ca07SZoran Jovanovic   InsnType Rs = fieldFromInstruction(insn, 21, 5);
72528a0ca07SZoran Jovanovic   InsnType Rt = fieldFromInstruction(insn, 16, 5);
726d37bab61SAlexey Samsonov   InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4;
72728a0ca07SZoran Jovanovic   bool HasRs = false;
72828a0ca07SZoran Jovanovic 
72928a0ca07SZoran Jovanovic   if (Rt == 0)
73028a0ca07SZoran Jovanovic     return MCDisassembler::Fail;
73128a0ca07SZoran Jovanovic   else if (Rs == 0)
73228a0ca07SZoran Jovanovic     MI.setOpcode(Mips::BLEZALC);
73328a0ca07SZoran Jovanovic   else if (Rs == Rt)
73428a0ca07SZoran Jovanovic     MI.setOpcode(Mips::BGEZALC);
73528a0ca07SZoran Jovanovic   else {
73628a0ca07SZoran Jovanovic     HasRs = true;
73728a0ca07SZoran Jovanovic     MI.setOpcode(Mips::BGEUC);
73828a0ca07SZoran Jovanovic   }
73928a0ca07SZoran Jovanovic 
74028a0ca07SZoran Jovanovic   if (HasRs)
74128a0ca07SZoran Jovanovic     MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
74228a0ca07SZoran Jovanovic                                        Rs)));
74328a0ca07SZoran Jovanovic   MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
74428a0ca07SZoran Jovanovic                                      Rt)));
74528a0ca07SZoran Jovanovic 
74628a0ca07SZoran Jovanovic   MI.addOperand(MCOperand::CreateImm(Imm));
74728a0ca07SZoran Jovanovic 
74828a0ca07SZoran Jovanovic   return MCDisassembler::Success;
74928a0ca07SZoran Jovanovic }
75028a0ca07SZoran Jovanovic 
751ea22c4cfSJozef Kolek /// Read two bytes from the ArrayRef and return 16 bit halfword sorted
752ea22c4cfSJozef Kolek /// according to the given endianess.
753ea22c4cfSJozef Kolek static DecodeStatus readInstruction16(ArrayRef<uint8_t> Bytes, uint64_t Address,
754ea22c4cfSJozef Kolek                                       uint64_t &Size, uint32_t &Insn,
755ea22c4cfSJozef Kolek                                       bool IsBigEndian) {
756ea22c4cfSJozef Kolek   // We want to read exactly 2 Bytes of data.
757ea22c4cfSJozef Kolek   if (Bytes.size() < 2) {
758ea22c4cfSJozef Kolek     Size = 0;
759ea22c4cfSJozef Kolek     return MCDisassembler::Fail;
760ea22c4cfSJozef Kolek   }
761ea22c4cfSJozef Kolek 
762ea22c4cfSJozef Kolek   if (IsBigEndian) {
763ea22c4cfSJozef Kolek     Insn = (Bytes[0] << 8) | Bytes[1];
764ea22c4cfSJozef Kolek   } else {
765ea22c4cfSJozef Kolek     Insn = (Bytes[1] << 8) | Bytes[0];
766ea22c4cfSJozef Kolek   }
767ea22c4cfSJozef Kolek 
768ea22c4cfSJozef Kolek   return MCDisassembler::Success;
769ea22c4cfSJozef Kolek }
770ea22c4cfSJozef Kolek 
7717fc5b874SRafael Espindola /// Read four bytes from the ArrayRef and return 32 bit word sorted
7724aa6bea7SRafael Espindola /// according to the given endianess
7737fc5b874SRafael Espindola static DecodeStatus readInstruction32(ArrayRef<uint8_t> Bytes, uint64_t Address,
7747fc5b874SRafael Espindola                                       uint64_t &Size, uint32_t &Insn,
7757fc5b874SRafael Espindola                                       bool IsBigEndian, bool IsMicroMips) {
77671928e68SAkira Hatanaka   // We want to read exactly 4 Bytes of data.
7777fc5b874SRafael Espindola   if (Bytes.size() < 4) {
7784aa6bea7SRafael Espindola     Size = 0;
77971928e68SAkira Hatanaka     return MCDisassembler::Fail;
78071928e68SAkira Hatanaka   }
78171928e68SAkira Hatanaka 
782ea22c4cfSJozef Kolek   // High 16 bits of a 32-bit microMIPS instruction (where the opcode is)
783ea22c4cfSJozef Kolek   // always precede the low 16 bits in the instruction stream (that is, they
784ea22c4cfSJozef Kolek   // are placed at lower addresses in the instruction stream).
785ea22c4cfSJozef Kolek   //
786ea22c4cfSJozef Kolek   // microMIPS byte ordering:
787ea22c4cfSJozef Kolek   //   Big-endian:    0 | 1 | 2 | 3
788ea22c4cfSJozef Kolek   //   Little-endian: 1 | 0 | 3 | 2
789ea22c4cfSJozef Kolek 
7904aa6bea7SRafael Espindola   if (IsBigEndian) {
79171928e68SAkira Hatanaka     // Encoded as a big-endian 32-bit word in the stream.
7924aa6bea7SRafael Espindola     Insn =
7934aa6bea7SRafael Espindola         (Bytes[3] << 0) | (Bytes[2] << 8) | (Bytes[1] << 16) | (Bytes[0] << 24);
7944aa6bea7SRafael Espindola   } else {
795dde3d582SVladimir Medic     if (IsMicroMips) {
7964aa6bea7SRafael Espindola       Insn = (Bytes[2] << 0) | (Bytes[3] << 8) | (Bytes[0] << 16) |
797dde3d582SVladimir Medic              (Bytes[1] << 24);
798dde3d582SVladimir Medic     } else {
7994aa6bea7SRafael Espindola       Insn = (Bytes[0] << 0) | (Bytes[1] << 8) | (Bytes[2] << 16) |
80071928e68SAkira Hatanaka              (Bytes[3] << 24);
80171928e68SAkira Hatanaka     }
802dde3d582SVladimir Medic   }
80371928e68SAkira Hatanaka 
80471928e68SAkira Hatanaka   return MCDisassembler::Success;
80571928e68SAkira Hatanaka }
80671928e68SAkira Hatanaka 
8074aa6bea7SRafael Espindola DecodeStatus MipsDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,
8087fc5b874SRafael Espindola                                               ArrayRef<uint8_t> Bytes,
80971928e68SAkira Hatanaka                                               uint64_t Address,
8104aa6bea7SRafael Espindola                                               raw_ostream &VStream,
8114aa6bea7SRafael Espindola                                               raw_ostream &CStream) const {
81271928e68SAkira Hatanaka   uint32_t Insn;
813ea22c4cfSJozef Kolek   DecodeStatus Result;
81471928e68SAkira Hatanaka 
815ea22c4cfSJozef Kolek   if (IsMicroMips) {
816ea22c4cfSJozef Kolek     Result = readInstruction16(Bytes, Address, Size, Insn, IsBigEndian);
817ea22c4cfSJozef Kolek 
818ea22c4cfSJozef Kolek     DEBUG(dbgs() << "Trying MicroMips16 table (16-bit instructions):\n");
819ea22c4cfSJozef Kolek     // Calling the auto-generated decoder function.
820ea22c4cfSJozef Kolek     Result = decodeInstruction(DecoderTableMicroMips16, Instr, Insn, Address,
821ea22c4cfSJozef Kolek                                this, STI);
822ea22c4cfSJozef Kolek     if (Result != MCDisassembler::Fail) {
823ea22c4cfSJozef Kolek       Size = 2;
824ea22c4cfSJozef Kolek       return Result;
825ea22c4cfSJozef Kolek     }
826ea22c4cfSJozef Kolek 
827ea22c4cfSJozef Kolek     Result = readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, true);
82871928e68SAkira Hatanaka     if (Result == MCDisassembler::Fail)
82971928e68SAkira Hatanaka       return MCDisassembler::Fail;
83071928e68SAkira Hatanaka 
831ea22c4cfSJozef Kolek     DEBUG(dbgs() << "Trying MicroMips32 table (32-bit instructions):\n");
832dde3d582SVladimir Medic     // Calling the auto-generated decoder function.
8334aa6bea7SRafael Espindola     Result = decodeInstruction(DecoderTableMicroMips32, Instr, Insn, Address,
834dde3d582SVladimir Medic                                this, STI);
835dde3d582SVladimir Medic     if (Result != MCDisassembler::Fail) {
836dde3d582SVladimir Medic       Size = 4;
837dde3d582SVladimir Medic       return Result;
838dde3d582SVladimir Medic     }
839dde3d582SVladimir Medic     return MCDisassembler::Fail;
840dde3d582SVladimir Medic   }
841dde3d582SVladimir Medic 
842ea22c4cfSJozef Kolek   Result = readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, false);
843ea22c4cfSJozef Kolek   if (Result == MCDisassembler::Fail)
844ea22c4cfSJozef Kolek     return MCDisassembler::Fail;
845ea22c4cfSJozef Kolek 
846c171f65aSDaniel Sanders   if (hasCOP3()) {
847c171f65aSDaniel Sanders     DEBUG(dbgs() << "Trying COP3_ table (32-bit opcodes):\n");
848c171f65aSDaniel Sanders     Result =
8494aa6bea7SRafael Espindola         decodeInstruction(DecoderTableCOP3_32, Instr, Insn, Address, this, STI);
850c171f65aSDaniel Sanders     if (Result != MCDisassembler::Fail) {
851c171f65aSDaniel Sanders       Size = 4;
852c171f65aSDaniel Sanders       return Result;
853c171f65aSDaniel Sanders     }
854c171f65aSDaniel Sanders   }
855c171f65aSDaniel Sanders 
856c171f65aSDaniel Sanders   if (hasMips32r6() && isGP64()) {
8570fa60416SDaniel Sanders     DEBUG(dbgs() << "Trying Mips32r6_64r6 (GPR64) table (32-bit opcodes):\n");
8584aa6bea7SRafael Espindola     Result = decodeInstruction(DecoderTableMips32r6_64r6_GP6432, Instr, Insn,
8590fa60416SDaniel Sanders                                Address, this, STI);
8600fa60416SDaniel Sanders     if (Result != MCDisassembler::Fail) {
8610fa60416SDaniel Sanders       Size = 4;
8620fa60416SDaniel Sanders       return Result;
8630fa60416SDaniel Sanders     }
8640fa60416SDaniel Sanders   }
8650fa60416SDaniel Sanders 
866c171f65aSDaniel Sanders   if (hasMips32r6()) {
8670fa60416SDaniel Sanders     DEBUG(dbgs() << "Trying Mips32r6_64r6 table (32-bit opcodes):\n");
8684aa6bea7SRafael Espindola     Result = decodeInstruction(DecoderTableMips32r6_64r632, Instr, Insn,
8695c582b2fSDaniel Sanders                                Address, this, STI);
8705c582b2fSDaniel Sanders     if (Result != MCDisassembler::Fail) {
8715c582b2fSDaniel Sanders       Size = 4;
8725c582b2fSDaniel Sanders       return Result;
8735c582b2fSDaniel Sanders     }
8745c582b2fSDaniel Sanders   }
8755c582b2fSDaniel Sanders 
8760fa60416SDaniel Sanders   DEBUG(dbgs() << "Trying Mips table (32-bit opcodes):\n");
87771928e68SAkira Hatanaka   // Calling the auto-generated decoder function.
8784aa6bea7SRafael Espindola   Result =
8794aa6bea7SRafael Espindola       decodeInstruction(DecoderTableMips32, Instr, Insn, Address, this, STI);
88071928e68SAkira Hatanaka   if (Result != MCDisassembler::Fail) {
88171928e68SAkira Hatanaka     Size = 4;
88271928e68SAkira Hatanaka     return Result;
88371928e68SAkira Hatanaka   }
88471928e68SAkira Hatanaka 
88571928e68SAkira Hatanaka   return MCDisassembler::Fail;
88671928e68SAkira Hatanaka }
88771928e68SAkira Hatanaka 
8884aa6bea7SRafael Espindola DecodeStatus Mips64Disassembler::getInstruction(MCInst &Instr, uint64_t &Size,
8897fc5b874SRafael Espindola                                                 ArrayRef<uint8_t> Bytes,
89071928e68SAkira Hatanaka                                                 uint64_t Address,
8914aa6bea7SRafael Espindola                                                 raw_ostream &VStream,
8924aa6bea7SRafael Espindola                                                 raw_ostream &CStream) const {
89371928e68SAkira Hatanaka   uint32_t Insn;
89471928e68SAkira Hatanaka 
8954aa6bea7SRafael Espindola   DecodeStatus Result =
8967fc5b874SRafael Espindola       readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, false);
89771928e68SAkira Hatanaka   if (Result == MCDisassembler::Fail)
89871928e68SAkira Hatanaka     return MCDisassembler::Fail;
89971928e68SAkira Hatanaka 
90071928e68SAkira Hatanaka   // Calling the auto-generated decoder function.
9014aa6bea7SRafael Espindola   Result =
9024aa6bea7SRafael Espindola       decodeInstruction(DecoderTableMips6432, Instr, Insn, Address, this, STI);
90371928e68SAkira Hatanaka   if (Result != MCDisassembler::Fail) {
90471928e68SAkira Hatanaka     Size = 4;
90571928e68SAkira Hatanaka     return Result;
90671928e68SAkira Hatanaka   }
90771928e68SAkira Hatanaka   // If we fail to decode in Mips64 decoder space we can try in Mips32
9084aa6bea7SRafael Espindola   Result =
9094aa6bea7SRafael Espindola       decodeInstruction(DecoderTableMips32, Instr, Insn, Address, this, STI);
91071928e68SAkira Hatanaka   if (Result != MCDisassembler::Fail) {
91171928e68SAkira Hatanaka     Size = 4;
91271928e68SAkira Hatanaka     return Result;
91371928e68SAkira Hatanaka   }
91471928e68SAkira Hatanaka 
91571928e68SAkira Hatanaka   return MCDisassembler::Fail;
91671928e68SAkira Hatanaka }
91771928e68SAkira Hatanaka 
918ec8a5490SReed Kotler static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst,
919ec8a5490SReed Kotler                                                  unsigned RegNo,
920ec8a5490SReed Kotler                                                  uint64_t Address,
921ec8a5490SReed Kotler                                                  const void *Decoder) {
922ec8a5490SReed Kotler 
923ec8a5490SReed Kotler   return MCDisassembler::Fail;
924ec8a5490SReed Kotler 
925ec8a5490SReed Kotler }
926ec8a5490SReed Kotler 
92713e6ccf3SAkira Hatanaka static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst,
92871928e68SAkira Hatanaka                                              unsigned RegNo,
92971928e68SAkira Hatanaka                                              uint64_t Address,
93071928e68SAkira Hatanaka                                              const void *Decoder) {
93171928e68SAkira Hatanaka 
93271928e68SAkira Hatanaka   if (RegNo > 31)
93371928e68SAkira Hatanaka     return MCDisassembler::Fail;
93471928e68SAkira Hatanaka 
93513e6ccf3SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::GPR64RegClassID, RegNo);
9369bf2b567SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
93771928e68SAkira Hatanaka   return MCDisassembler::Success;
93871928e68SAkira Hatanaka }
93971928e68SAkira Hatanaka 
940b0852e54SZoran Jovanovic static DecodeStatus DecodeGPRMM16RegisterClass(MCInst &Inst,
941b0852e54SZoran Jovanovic                                                unsigned RegNo,
942b0852e54SZoran Jovanovic                                                uint64_t Address,
943b0852e54SZoran Jovanovic                                                const void *Decoder) {
944ea22c4cfSJozef Kolek   if (RegNo > 7)
945b0852e54SZoran Jovanovic     return MCDisassembler::Fail;
946ea22c4cfSJozef Kolek   unsigned Reg = getReg(Decoder, Mips::GPRMM16RegClassID, RegNo);
947ea22c4cfSJozef Kolek   Inst.addOperand(MCOperand::CreateReg(Reg));
948ea22c4cfSJozef Kolek   return MCDisassembler::Success;
949b0852e54SZoran Jovanovic }
950b0852e54SZoran Jovanovic 
9511904fa21SJozef Kolek static DecodeStatus DecodeGPRMM16ZeroRegisterClass(MCInst &Inst,
9521904fa21SJozef Kolek                                                    unsigned RegNo,
9531904fa21SJozef Kolek                                                    uint64_t Address,
9541904fa21SJozef Kolek                                                    const void *Decoder) {
955315e7ecaSJozef Kolek   if (RegNo > 7)
9561904fa21SJozef Kolek     return MCDisassembler::Fail;
957315e7ecaSJozef Kolek   unsigned Reg = getReg(Decoder, Mips::GPRMM16ZeroRegClassID, RegNo);
958315e7ecaSJozef Kolek   Inst.addOperand(MCOperand::CreateReg(Reg));
959315e7ecaSJozef Kolek   return MCDisassembler::Success;
9601904fa21SJozef Kolek }
9611904fa21SJozef Kolek 
96213e6ccf3SAkira Hatanaka static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst,
96371928e68SAkira Hatanaka                                              unsigned RegNo,
96471928e68SAkira Hatanaka                                              uint64_t Address,
96571928e68SAkira Hatanaka                                              const void *Decoder) {
96671928e68SAkira Hatanaka   if (RegNo > 31)
96771928e68SAkira Hatanaka     return MCDisassembler::Fail;
96813e6ccf3SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::GPR32RegClassID, RegNo);
9699bf2b567SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
97071928e68SAkira Hatanaka   return MCDisassembler::Success;
97171928e68SAkira Hatanaka }
97271928e68SAkira Hatanaka 
9739bfa2e2eSAkira Hatanaka static DecodeStatus DecodePtrRegisterClass(MCInst &Inst,
9749bfa2e2eSAkira Hatanaka                                            unsigned RegNo,
9759bfa2e2eSAkira Hatanaka                                            uint64_t Address,
9769bfa2e2eSAkira Hatanaka                                            const void *Decoder) {
9779bfa2e2eSAkira Hatanaka   if (static_cast<const MipsDisassembler *>(Decoder)->isN64())
9789bfa2e2eSAkira Hatanaka     return DecodeGPR64RegisterClass(Inst, RegNo, Address, Decoder);
9799bfa2e2eSAkira Hatanaka 
9809bfa2e2eSAkira Hatanaka   return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
9819bfa2e2eSAkira Hatanaka }
9829bfa2e2eSAkira Hatanaka 
983654655f1SAkira Hatanaka static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst,
984ecabd1a5SAkira Hatanaka                                             unsigned RegNo,
985ecabd1a5SAkira Hatanaka                                             uint64_t Address,
986ecabd1a5SAkira Hatanaka                                             const void *Decoder) {
98713e6ccf3SAkira Hatanaka   return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
988ecabd1a5SAkira Hatanaka }
989ecabd1a5SAkira Hatanaka 
99071928e68SAkira Hatanaka static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
99171928e68SAkira Hatanaka                                              unsigned RegNo,
99271928e68SAkira Hatanaka                                              uint64_t Address,
99371928e68SAkira Hatanaka                                              const void *Decoder) {
99471928e68SAkira Hatanaka   if (RegNo > 31)
99571928e68SAkira Hatanaka     return MCDisassembler::Fail;
99671928e68SAkira Hatanaka 
9979bf2b567SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::FGR64RegClassID, RegNo);
9989bf2b567SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
99971928e68SAkira Hatanaka   return MCDisassembler::Success;
100071928e68SAkira Hatanaka }
100171928e68SAkira Hatanaka 
100271928e68SAkira Hatanaka static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
100371928e68SAkira Hatanaka                                              unsigned RegNo,
100471928e68SAkira Hatanaka                                              uint64_t Address,
100571928e68SAkira Hatanaka                                              const void *Decoder) {
100671928e68SAkira Hatanaka   if (RegNo > 31)
100771928e68SAkira Hatanaka     return MCDisassembler::Fail;
100871928e68SAkira Hatanaka 
10099bf2b567SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::FGR32RegClassID, RegNo);
10109bf2b567SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
101171928e68SAkira Hatanaka   return MCDisassembler::Success;
101271928e68SAkira Hatanaka }
101371928e68SAkira Hatanaka 
101471928e68SAkira Hatanaka static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
101571928e68SAkira Hatanaka                                            unsigned RegNo,
101671928e68SAkira Hatanaka                                            uint64_t Address,
101771928e68SAkira Hatanaka                                            const void *Decoder) {
1018253777fdSChad Rosier   if (RegNo > 31)
1019253777fdSChad Rosier     return MCDisassembler::Fail;
1020253777fdSChad Rosier   unsigned Reg = getReg(Decoder, Mips::CCRRegClassID, RegNo);
1021253777fdSChad Rosier   Inst.addOperand(MCOperand::CreateReg(Reg));
102271928e68SAkira Hatanaka   return MCDisassembler::Success;
102371928e68SAkira Hatanaka }
102471928e68SAkira Hatanaka 
10251fb1b8b8SAkira Hatanaka static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst,
10261fb1b8b8SAkira Hatanaka                                            unsigned RegNo,
10271fb1b8b8SAkira Hatanaka                                            uint64_t Address,
10281fb1b8b8SAkira Hatanaka                                            const void *Decoder) {
10291fb1b8b8SAkira Hatanaka   if (RegNo > 7)
10301fb1b8b8SAkira Hatanaka     return MCDisassembler::Fail;
10311fb1b8b8SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::FCCRegClassID, RegNo);
10321fb1b8b8SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
10331fb1b8b8SAkira Hatanaka   return MCDisassembler::Success;
10341fb1b8b8SAkira Hatanaka }
10351fb1b8b8SAkira Hatanaka 
10360fa60416SDaniel Sanders static DecodeStatus DecodeFGRCCRegisterClass(MCInst &Inst, unsigned RegNo,
10370fa60416SDaniel Sanders                                              uint64_t Address,
10380fa60416SDaniel Sanders                                              const void *Decoder) {
10390fa60416SDaniel Sanders   if (RegNo > 31)
10400fa60416SDaniel Sanders     return MCDisassembler::Fail;
10410fa60416SDaniel Sanders 
10420fa60416SDaniel Sanders   unsigned Reg = getReg(Decoder, Mips::FGRCCRegClassID, RegNo);
10430fa60416SDaniel Sanders   Inst.addOperand(MCOperand::CreateReg(Reg));
10440fa60416SDaniel Sanders   return MCDisassembler::Success;
10450fa60416SDaniel Sanders }
10460fa60416SDaniel Sanders 
104771928e68SAkira Hatanaka static DecodeStatus DecodeMem(MCInst &Inst,
104871928e68SAkira Hatanaka                               unsigned Insn,
104971928e68SAkira Hatanaka                               uint64_t Address,
105071928e68SAkira Hatanaka                               const void *Decoder) {
105171928e68SAkira Hatanaka   int Offset = SignExtend32<16>(Insn & 0xffff);
1052ecaef49fSJim Grosbach   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1053ecaef49fSJim Grosbach   unsigned Base = fieldFromInstruction(Insn, 21, 5);
10549bf2b567SAkira Hatanaka 
105513e6ccf3SAkira Hatanaka   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
105613e6ccf3SAkira Hatanaka   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
105771928e68SAkira Hatanaka 
1058d7ecf49eSVladimir Medic   if(Inst.getOpcode() == Mips::SC ||
1059d7ecf49eSVladimir Medic      Inst.getOpcode() == Mips::SCD){
10609bf2b567SAkira Hatanaka     Inst.addOperand(MCOperand::CreateReg(Reg));
106171928e68SAkira Hatanaka   }
106271928e68SAkira Hatanaka 
10639bf2b567SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
10649bf2b567SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Base));
106571928e68SAkira Hatanaka   Inst.addOperand(MCOperand::CreateImm(Offset));
106671928e68SAkira Hatanaka 
106771928e68SAkira Hatanaka   return MCDisassembler::Success;
106871928e68SAkira Hatanaka }
106971928e68SAkira Hatanaka 
107092db6b78SDaniel Sanders static DecodeStatus DecodeCacheOp(MCInst &Inst,
107192db6b78SDaniel Sanders                               unsigned Insn,
107292db6b78SDaniel Sanders                               uint64_t Address,
107392db6b78SDaniel Sanders                               const void *Decoder) {
107492db6b78SDaniel Sanders   int Offset = SignExtend32<16>(Insn & 0xffff);
107592db6b78SDaniel Sanders   unsigned Hint = fieldFromInstruction(Insn, 16, 5);
107692db6b78SDaniel Sanders   unsigned Base = fieldFromInstruction(Insn, 21, 5);
107792db6b78SDaniel Sanders 
107892db6b78SDaniel Sanders   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
107992db6b78SDaniel Sanders 
108092db6b78SDaniel Sanders   Inst.addOperand(MCOperand::CreateReg(Base));
108192db6b78SDaniel Sanders   Inst.addOperand(MCOperand::CreateImm(Offset));
108292db6b78SDaniel Sanders   Inst.addOperand(MCOperand::CreateImm(Hint));
108392db6b78SDaniel Sanders 
108492db6b78SDaniel Sanders   return MCDisassembler::Success;
108592db6b78SDaniel Sanders }
108692db6b78SDaniel Sanders 
1087b4484d62SDaniel Sanders static DecodeStatus DecodeSyncI(MCInst &Inst,
1088b4484d62SDaniel Sanders                               unsigned Insn,
1089b4484d62SDaniel Sanders                               uint64_t Address,
1090b4484d62SDaniel Sanders                               const void *Decoder) {
1091b4484d62SDaniel Sanders   int Offset = SignExtend32<16>(Insn & 0xffff);
1092b4484d62SDaniel Sanders   unsigned Base = fieldFromInstruction(Insn, 21, 5);
1093b4484d62SDaniel Sanders 
1094b4484d62SDaniel Sanders   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1095b4484d62SDaniel Sanders 
1096b4484d62SDaniel Sanders   Inst.addOperand(MCOperand::CreateReg(Base));
1097b4484d62SDaniel Sanders   Inst.addOperand(MCOperand::CreateImm(Offset));
1098b4484d62SDaniel Sanders 
1099b4484d62SDaniel Sanders   return MCDisassembler::Success;
1100b4484d62SDaniel Sanders }
1101b4484d62SDaniel Sanders 
1102fe0bf9f6SMatheus Almeida static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn,
1103fe0bf9f6SMatheus Almeida                                     uint64_t Address, const void *Decoder) {
1104fe0bf9f6SMatheus Almeida   int Offset = SignExtend32<10>(fieldFromInstruction(Insn, 16, 10));
1105fe0bf9f6SMatheus Almeida   unsigned Reg = fieldFromInstruction(Insn, 6, 5);
1106fe0bf9f6SMatheus Almeida   unsigned Base = fieldFromInstruction(Insn, 11, 5);
1107fe0bf9f6SMatheus Almeida 
1108fe0bf9f6SMatheus Almeida   Reg = getReg(Decoder, Mips::MSA128BRegClassID, Reg);
1109fe0bf9f6SMatheus Almeida   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1110fe0bf9f6SMatheus Almeida 
1111fe0bf9f6SMatheus Almeida   Inst.addOperand(MCOperand::CreateReg(Reg));
1112fe0bf9f6SMatheus Almeida   Inst.addOperand(MCOperand::CreateReg(Base));
11136b59c449SMatheus Almeida 
11146b59c449SMatheus Almeida   // The immediate field of an LD/ST instruction is scaled which means it must
11156b59c449SMatheus Almeida   // be multiplied (when decoding) by the size (in bytes) of the instructions'
11166b59c449SMatheus Almeida   // data format.
11176b59c449SMatheus Almeida   // .b - 1 byte
11186b59c449SMatheus Almeida   // .h - 2 bytes
11196b59c449SMatheus Almeida   // .w - 4 bytes
11206b59c449SMatheus Almeida   // .d - 8 bytes
11216b59c449SMatheus Almeida   switch(Inst.getOpcode())
11226b59c449SMatheus Almeida   {
11236b59c449SMatheus Almeida   default:
11246b59c449SMatheus Almeida     assert (0 && "Unexpected instruction");
11256b59c449SMatheus Almeida     return MCDisassembler::Fail;
11266b59c449SMatheus Almeida     break;
11276b59c449SMatheus Almeida   case Mips::LD_B:
11286b59c449SMatheus Almeida   case Mips::ST_B:
1129fe0bf9f6SMatheus Almeida     Inst.addOperand(MCOperand::CreateImm(Offset));
11306b59c449SMatheus Almeida     break;
11316b59c449SMatheus Almeida   case Mips::LD_H:
11326b59c449SMatheus Almeida   case Mips::ST_H:
1133d37bab61SAlexey Samsonov     Inst.addOperand(MCOperand::CreateImm(Offset * 2));
11346b59c449SMatheus Almeida     break;
11356b59c449SMatheus Almeida   case Mips::LD_W:
11366b59c449SMatheus Almeida   case Mips::ST_W:
1137d37bab61SAlexey Samsonov     Inst.addOperand(MCOperand::CreateImm(Offset * 4));
11386b59c449SMatheus Almeida     break;
11396b59c449SMatheus Almeida   case Mips::LD_D:
11406b59c449SMatheus Almeida   case Mips::ST_D:
1141d37bab61SAlexey Samsonov     Inst.addOperand(MCOperand::CreateImm(Offset * 8));
11426b59c449SMatheus Almeida     break;
11436b59c449SMatheus Almeida   }
1144fe0bf9f6SMatheus Almeida 
1145fe0bf9f6SMatheus Almeida   return MCDisassembler::Success;
1146fe0bf9f6SMatheus Almeida }
1147fe0bf9f6SMatheus Almeida 
1148315e7ecaSJozef Kolek static DecodeStatus DecodeMemMMImm4(MCInst &Inst,
1149315e7ecaSJozef Kolek                                     unsigned Insn,
1150315e7ecaSJozef Kolek                                     uint64_t Address,
1151315e7ecaSJozef Kolek                                     const void *Decoder) {
1152315e7ecaSJozef Kolek   unsigned Offset = Insn & 0xf;
1153315e7ecaSJozef Kolek   unsigned Reg = fieldFromInstruction(Insn, 7, 3);
1154315e7ecaSJozef Kolek   unsigned Base = fieldFromInstruction(Insn, 4, 3);
1155315e7ecaSJozef Kolek 
1156315e7ecaSJozef Kolek   switch (Inst.getOpcode()) {
1157315e7ecaSJozef Kolek     case Mips::LBU16_MM:
1158315e7ecaSJozef Kolek     case Mips::LHU16_MM:
1159315e7ecaSJozef Kolek     case Mips::LW16_MM:
1160315e7ecaSJozef Kolek       if (DecodeGPRMM16RegisterClass(Inst, Reg, Address, Decoder)
1161315e7ecaSJozef Kolek             == MCDisassembler::Fail)
1162315e7ecaSJozef Kolek         return MCDisassembler::Fail;
1163315e7ecaSJozef Kolek       break;
1164315e7ecaSJozef Kolek     case Mips::SB16_MM:
1165315e7ecaSJozef Kolek     case Mips::SH16_MM:
1166315e7ecaSJozef Kolek     case Mips::SW16_MM:
1167315e7ecaSJozef Kolek       if (DecodeGPRMM16ZeroRegisterClass(Inst, Reg, Address, Decoder)
1168315e7ecaSJozef Kolek             == MCDisassembler::Fail)
1169315e7ecaSJozef Kolek         return MCDisassembler::Fail;
1170315e7ecaSJozef Kolek       break;
1171315e7ecaSJozef Kolek   }
1172315e7ecaSJozef Kolek 
1173315e7ecaSJozef Kolek   if (DecodeGPRMM16RegisterClass(Inst, Base, Address, Decoder)
1174315e7ecaSJozef Kolek         == MCDisassembler::Fail)
1175315e7ecaSJozef Kolek     return MCDisassembler::Fail;
1176315e7ecaSJozef Kolek 
1177315e7ecaSJozef Kolek   switch (Inst.getOpcode()) {
1178315e7ecaSJozef Kolek     case Mips::LBU16_MM:
1179315e7ecaSJozef Kolek       if (Offset == 0xf)
1180315e7ecaSJozef Kolek         Inst.addOperand(MCOperand::CreateImm(-1));
1181315e7ecaSJozef Kolek       else
1182315e7ecaSJozef Kolek         Inst.addOperand(MCOperand::CreateImm(Offset));
1183315e7ecaSJozef Kolek       break;
1184315e7ecaSJozef Kolek     case Mips::SB16_MM:
1185315e7ecaSJozef Kolek       Inst.addOperand(MCOperand::CreateImm(Offset));
1186315e7ecaSJozef Kolek       break;
1187315e7ecaSJozef Kolek     case Mips::LHU16_MM:
1188315e7ecaSJozef Kolek     case Mips::SH16_MM:
1189315e7ecaSJozef Kolek       Inst.addOperand(MCOperand::CreateImm(Offset << 1));
1190315e7ecaSJozef Kolek       break;
1191315e7ecaSJozef Kolek     case Mips::LW16_MM:
1192315e7ecaSJozef Kolek     case Mips::SW16_MM:
1193315e7ecaSJozef Kolek       Inst.addOperand(MCOperand::CreateImm(Offset << 2));
1194315e7ecaSJozef Kolek       break;
1195315e7ecaSJozef Kolek   }
1196315e7ecaSJozef Kolek 
1197315e7ecaSJozef Kolek   return MCDisassembler::Success;
1198315e7ecaSJozef Kolek }
1199315e7ecaSJozef Kolek 
1200dde3d582SVladimir Medic static DecodeStatus DecodeMemMMImm12(MCInst &Inst,
1201dde3d582SVladimir Medic                                      unsigned Insn,
1202dde3d582SVladimir Medic                                      uint64_t Address,
1203dde3d582SVladimir Medic                                      const void *Decoder) {
1204dde3d582SVladimir Medic   int Offset = SignExtend32<12>(Insn & 0x0fff);
1205dde3d582SVladimir Medic   unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1206dde3d582SVladimir Medic   unsigned Base = fieldFromInstruction(Insn, 16, 5);
1207dde3d582SVladimir Medic 
1208dde3d582SVladimir Medic   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1209dde3d582SVladimir Medic   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1210dde3d582SVladimir Medic 
1211a4c4b5fcSZoran Jovanovic   switch (Inst.getOpcode()) {
1212a4c4b5fcSZoran Jovanovic   case Mips::SWM32_MM:
1213a4c4b5fcSZoran Jovanovic   case Mips::LWM32_MM:
1214a4c4b5fcSZoran Jovanovic     if (DecodeRegListOperand(Inst, Insn, Address, Decoder)
1215a4c4b5fcSZoran Jovanovic         == MCDisassembler::Fail)
1216a4c4b5fcSZoran Jovanovic       return MCDisassembler::Fail;
1217a4c4b5fcSZoran Jovanovic     Inst.addOperand(MCOperand::CreateReg(Base));
1218a4c4b5fcSZoran Jovanovic     Inst.addOperand(MCOperand::CreateImm(Offset));
1219a4c4b5fcSZoran Jovanovic     break;
1220a4c4b5fcSZoran Jovanovic   case Mips::SC_MM:
1221285cc289SZoran Jovanovic     Inst.addOperand(MCOperand::CreateReg(Reg));
1222a4c4b5fcSZoran Jovanovic     // fallthrough
1223a4c4b5fcSZoran Jovanovic   default:
1224dde3d582SVladimir Medic     Inst.addOperand(MCOperand::CreateReg(Reg));
1225*2deca348SZoran Jovanovic     if (Inst.getOpcode() == Mips::LWP_MM || Inst.getOpcode() == Mips::SWP_MM)
1226*2deca348SZoran Jovanovic       Inst.addOperand(MCOperand::CreateReg(Reg+1));
1227*2deca348SZoran Jovanovic 
1228dde3d582SVladimir Medic     Inst.addOperand(MCOperand::CreateReg(Base));
1229dde3d582SVladimir Medic     Inst.addOperand(MCOperand::CreateImm(Offset));
1230a4c4b5fcSZoran Jovanovic   }
1231dde3d582SVladimir Medic 
1232dde3d582SVladimir Medic   return MCDisassembler::Success;
1233dde3d582SVladimir Medic }
1234dde3d582SVladimir Medic 
1235dde3d582SVladimir Medic static DecodeStatus DecodeMemMMImm16(MCInst &Inst,
1236dde3d582SVladimir Medic                                      unsigned Insn,
1237dde3d582SVladimir Medic                                      uint64_t Address,
1238dde3d582SVladimir Medic                                      const void *Decoder) {
1239dde3d582SVladimir Medic   int Offset = SignExtend32<16>(Insn & 0xffff);
1240dde3d582SVladimir Medic   unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1241dde3d582SVladimir Medic   unsigned Base = fieldFromInstruction(Insn, 16, 5);
1242dde3d582SVladimir Medic 
1243dde3d582SVladimir Medic   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1244dde3d582SVladimir Medic   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1245dde3d582SVladimir Medic 
1246dde3d582SVladimir Medic   Inst.addOperand(MCOperand::CreateReg(Reg));
1247dde3d582SVladimir Medic   Inst.addOperand(MCOperand::CreateReg(Base));
1248dde3d582SVladimir Medic   Inst.addOperand(MCOperand::CreateImm(Offset));
1249dde3d582SVladimir Medic 
1250dde3d582SVladimir Medic   return MCDisassembler::Success;
1251dde3d582SVladimir Medic }
1252dde3d582SVladimir Medic 
125371928e68SAkira Hatanaka static DecodeStatus DecodeFMem(MCInst &Inst,
125471928e68SAkira Hatanaka                                unsigned Insn,
125571928e68SAkira Hatanaka                                uint64_t Address,
125671928e68SAkira Hatanaka                                const void *Decoder) {
125771928e68SAkira Hatanaka   int Offset = SignExtend32<16>(Insn & 0xffff);
1258ecaef49fSJim Grosbach   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1259ecaef49fSJim Grosbach   unsigned Base = fieldFromInstruction(Insn, 21, 5);
126071928e68SAkira Hatanaka 
12619bf2b567SAkira Hatanaka   Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg);
126213e6ccf3SAkira Hatanaka   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
12639bf2b567SAkira Hatanaka 
12649bf2b567SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
12659bf2b567SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Base));
126671928e68SAkira Hatanaka   Inst.addOperand(MCOperand::CreateImm(Offset));
126771928e68SAkira Hatanaka 
126871928e68SAkira Hatanaka   return MCDisassembler::Success;
126971928e68SAkira Hatanaka }
127071928e68SAkira Hatanaka 
127192db6b78SDaniel Sanders static DecodeStatus DecodeFMem2(MCInst &Inst,
127292db6b78SDaniel Sanders                                unsigned Insn,
127392db6b78SDaniel Sanders                                uint64_t Address,
127492db6b78SDaniel Sanders                                const void *Decoder) {
127592db6b78SDaniel Sanders   int Offset = SignExtend32<16>(Insn & 0xffff);
127692db6b78SDaniel Sanders   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
127792db6b78SDaniel Sanders   unsigned Base = fieldFromInstruction(Insn, 21, 5);
127892db6b78SDaniel Sanders 
127992db6b78SDaniel Sanders   Reg = getReg(Decoder, Mips::COP2RegClassID, Reg);
128092db6b78SDaniel Sanders   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
128192db6b78SDaniel Sanders 
128292db6b78SDaniel Sanders   Inst.addOperand(MCOperand::CreateReg(Reg));
128392db6b78SDaniel Sanders   Inst.addOperand(MCOperand::CreateReg(Base));
128492db6b78SDaniel Sanders   Inst.addOperand(MCOperand::CreateImm(Offset));
128592db6b78SDaniel Sanders 
128692db6b78SDaniel Sanders   return MCDisassembler::Success;
128792db6b78SDaniel Sanders }
128892db6b78SDaniel Sanders 
128992db6b78SDaniel Sanders static DecodeStatus DecodeFMem3(MCInst &Inst,
129092db6b78SDaniel Sanders                                unsigned Insn,
129192db6b78SDaniel Sanders                                uint64_t Address,
129292db6b78SDaniel Sanders                                const void *Decoder) {
129392db6b78SDaniel Sanders   int Offset = SignExtend32<16>(Insn & 0xffff);
129492db6b78SDaniel Sanders   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
129592db6b78SDaniel Sanders   unsigned Base = fieldFromInstruction(Insn, 21, 5);
129692db6b78SDaniel Sanders 
129792db6b78SDaniel Sanders   Reg = getReg(Decoder, Mips::COP3RegClassID, Reg);
129892db6b78SDaniel Sanders   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
129992db6b78SDaniel Sanders 
130092db6b78SDaniel Sanders   Inst.addOperand(MCOperand::CreateReg(Reg));
130192db6b78SDaniel Sanders   Inst.addOperand(MCOperand::CreateReg(Base));
130292db6b78SDaniel Sanders   Inst.addOperand(MCOperand::CreateImm(Offset));
130392db6b78SDaniel Sanders 
130492db6b78SDaniel Sanders   return MCDisassembler::Success;
130592db6b78SDaniel Sanders }
130692db6b78SDaniel Sanders 
13076a803f61SDaniel Sanders static DecodeStatus DecodeSpecial3LlSc(MCInst &Inst,
13086a803f61SDaniel Sanders                                        unsigned Insn,
13096a803f61SDaniel Sanders                                        uint64_t Address,
13106a803f61SDaniel Sanders                                        const void *Decoder) {
13116a803f61SDaniel Sanders   int64_t Offset = SignExtend64<9>((Insn >> 7) & 0x1ff);
13126a803f61SDaniel Sanders   unsigned Rt = fieldFromInstruction(Insn, 16, 5);
13136a803f61SDaniel Sanders   unsigned Base = fieldFromInstruction(Insn, 21, 5);
13146a803f61SDaniel Sanders 
13156a803f61SDaniel Sanders   Rt = getReg(Decoder, Mips::GPR32RegClassID, Rt);
13166a803f61SDaniel Sanders   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
13176a803f61SDaniel Sanders 
13186a803f61SDaniel Sanders   if(Inst.getOpcode() == Mips::SC_R6 || Inst.getOpcode() == Mips::SCD_R6){
13196a803f61SDaniel Sanders     Inst.addOperand(MCOperand::CreateReg(Rt));
13206a803f61SDaniel Sanders   }
13216a803f61SDaniel Sanders 
13226a803f61SDaniel Sanders   Inst.addOperand(MCOperand::CreateReg(Rt));
13236a803f61SDaniel Sanders   Inst.addOperand(MCOperand::CreateReg(Base));
13246a803f61SDaniel Sanders   Inst.addOperand(MCOperand::CreateImm(Offset));
13256a803f61SDaniel Sanders 
13266a803f61SDaniel Sanders   return MCDisassembler::Success;
13276a803f61SDaniel Sanders }
132871928e68SAkira Hatanaka 
132971928e68SAkira Hatanaka static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
133071928e68SAkira Hatanaka                                               unsigned RegNo,
133171928e68SAkira Hatanaka                                               uint64_t Address,
133271928e68SAkira Hatanaka                                               const void *Decoder) {
133371928e68SAkira Hatanaka   // Currently only hardware register 29 is supported.
133471928e68SAkira Hatanaka   if (RegNo != 29)
133571928e68SAkira Hatanaka     return  MCDisassembler::Fail;
133671928e68SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Mips::HWR29));
133771928e68SAkira Hatanaka   return MCDisassembler::Success;
133871928e68SAkira Hatanaka }
133971928e68SAkira Hatanaka 
134071928e68SAkira Hatanaka static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
134171928e68SAkira Hatanaka                                               unsigned RegNo,
134271928e68SAkira Hatanaka                                               uint64_t Address,
134371928e68SAkira Hatanaka                                               const void *Decoder) {
13449bf2b567SAkira Hatanaka   if (RegNo > 30 || RegNo %2)
134571928e68SAkira Hatanaka     return MCDisassembler::Fail;
134671928e68SAkira Hatanaka 
13479bf2b567SAkira Hatanaka   ;
13489bf2b567SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::AFGR64RegClassID, RegNo /2);
13499bf2b567SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
135071928e68SAkira Hatanaka   return MCDisassembler::Success;
135171928e68SAkira Hatanaka }
135271928e68SAkira Hatanaka 
135300fcf2e1SAkira Hatanaka static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst,
1354ecabd1a5SAkira Hatanaka                                                 unsigned RegNo,
1355ecabd1a5SAkira Hatanaka                                                 uint64_t Address,
1356ecabd1a5SAkira Hatanaka                                                 const void *Decoder) {
1357ecabd1a5SAkira Hatanaka   if (RegNo >= 4)
1358ecabd1a5SAkira Hatanaka     return MCDisassembler::Fail;
1359ecabd1a5SAkira Hatanaka 
136000fcf2e1SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::ACC64DSPRegClassID, RegNo);
1361ecabd1a5SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
1362ecabd1a5SAkira Hatanaka   return MCDisassembler::Success;
1363ecabd1a5SAkira Hatanaka }
1364ecabd1a5SAkira Hatanaka 
13658002a3f6SAkira Hatanaka static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst,
136659bfaf77SAkira Hatanaka                                                unsigned RegNo,
136759bfaf77SAkira Hatanaka                                                uint64_t Address,
136859bfaf77SAkira Hatanaka                                                const void *Decoder) {
136959bfaf77SAkira Hatanaka   if (RegNo >= 4)
137059bfaf77SAkira Hatanaka     return MCDisassembler::Fail;
137159bfaf77SAkira Hatanaka 
13728002a3f6SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::HI32DSPRegClassID, RegNo);
137359bfaf77SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
137459bfaf77SAkira Hatanaka   return MCDisassembler::Success;
137559bfaf77SAkira Hatanaka }
137659bfaf77SAkira Hatanaka 
13778002a3f6SAkira Hatanaka static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst,
137859bfaf77SAkira Hatanaka                                                unsigned RegNo,
137959bfaf77SAkira Hatanaka                                                uint64_t Address,
138059bfaf77SAkira Hatanaka                                                const void *Decoder) {
138159bfaf77SAkira Hatanaka   if (RegNo >= 4)
138259bfaf77SAkira Hatanaka     return MCDisassembler::Fail;
138359bfaf77SAkira Hatanaka 
13848002a3f6SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::LO32DSPRegClassID, RegNo);
138559bfaf77SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
138659bfaf77SAkira Hatanaka   return MCDisassembler::Success;
138759bfaf77SAkira Hatanaka }
138859bfaf77SAkira Hatanaka 
13893eb663b0SJack Carter static DecodeStatus DecodeMSA128BRegisterClass(MCInst &Inst,
13903eb663b0SJack Carter                                                unsigned RegNo,
13913eb663b0SJack Carter                                                uint64_t Address,
13923eb663b0SJack Carter                                                const void *Decoder) {
13933eb663b0SJack Carter   if (RegNo > 31)
13943eb663b0SJack Carter     return MCDisassembler::Fail;
13953eb663b0SJack Carter 
13963eb663b0SJack Carter   unsigned Reg = getReg(Decoder, Mips::MSA128BRegClassID, RegNo);
13973eb663b0SJack Carter   Inst.addOperand(MCOperand::CreateReg(Reg));
13983eb663b0SJack Carter   return MCDisassembler::Success;
13993eb663b0SJack Carter }
14003eb663b0SJack Carter 
14015dc8ac92SJack Carter static DecodeStatus DecodeMSA128HRegisterClass(MCInst &Inst,
14025dc8ac92SJack Carter                                                unsigned RegNo,
14035dc8ac92SJack Carter                                                uint64_t Address,
14045dc8ac92SJack Carter                                                const void *Decoder) {
14055dc8ac92SJack Carter   if (RegNo > 31)
14065dc8ac92SJack Carter     return MCDisassembler::Fail;
14075dc8ac92SJack Carter 
14085dc8ac92SJack Carter   unsigned Reg = getReg(Decoder, Mips::MSA128HRegClassID, RegNo);
14095dc8ac92SJack Carter   Inst.addOperand(MCOperand::CreateReg(Reg));
14105dc8ac92SJack Carter   return MCDisassembler::Success;
14115dc8ac92SJack Carter }
14125dc8ac92SJack Carter 
14135dc8ac92SJack Carter static DecodeStatus DecodeMSA128WRegisterClass(MCInst &Inst,
14145dc8ac92SJack Carter                                                unsigned RegNo,
14155dc8ac92SJack Carter                                                uint64_t Address,
14165dc8ac92SJack Carter                                                const void *Decoder) {
14175dc8ac92SJack Carter   if (RegNo > 31)
14185dc8ac92SJack Carter     return MCDisassembler::Fail;
14195dc8ac92SJack Carter 
14205dc8ac92SJack Carter   unsigned Reg = getReg(Decoder, Mips::MSA128WRegClassID, RegNo);
14215dc8ac92SJack Carter   Inst.addOperand(MCOperand::CreateReg(Reg));
14225dc8ac92SJack Carter   return MCDisassembler::Success;
14235dc8ac92SJack Carter }
14245dc8ac92SJack Carter 
14255dc8ac92SJack Carter static DecodeStatus DecodeMSA128DRegisterClass(MCInst &Inst,
14265dc8ac92SJack Carter                                                unsigned RegNo,
14275dc8ac92SJack Carter                                                uint64_t Address,
14285dc8ac92SJack Carter                                                const void *Decoder) {
14295dc8ac92SJack Carter   if (RegNo > 31)
14305dc8ac92SJack Carter     return MCDisassembler::Fail;
14315dc8ac92SJack Carter 
14325dc8ac92SJack Carter   unsigned Reg = getReg(Decoder, Mips::MSA128DRegClassID, RegNo);
14335dc8ac92SJack Carter   Inst.addOperand(MCOperand::CreateReg(Reg));
14345dc8ac92SJack Carter   return MCDisassembler::Success;
14355dc8ac92SJack Carter }
14365dc8ac92SJack Carter 
1437a591fdc6SMatheus Almeida static DecodeStatus DecodeMSACtrlRegisterClass(MCInst &Inst,
1438a591fdc6SMatheus Almeida                                                unsigned RegNo,
1439a591fdc6SMatheus Almeida                                                uint64_t Address,
1440a591fdc6SMatheus Almeida                                                const void *Decoder) {
1441a591fdc6SMatheus Almeida   if (RegNo > 7)
1442a591fdc6SMatheus Almeida     return MCDisassembler::Fail;
1443a591fdc6SMatheus Almeida 
1444a591fdc6SMatheus Almeida   unsigned Reg = getReg(Decoder, Mips::MSACtrlRegClassID, RegNo);
1445a591fdc6SMatheus Almeida   Inst.addOperand(MCOperand::CreateReg(Reg));
1446a591fdc6SMatheus Almeida   return MCDisassembler::Success;
1447a591fdc6SMatheus Almeida }
1448a591fdc6SMatheus Almeida 
14492a83d680SDaniel Sanders static DecodeStatus DecodeCOP2RegisterClass(MCInst &Inst,
14502a83d680SDaniel Sanders                                             unsigned RegNo,
14512a83d680SDaniel Sanders                                             uint64_t Address,
14522a83d680SDaniel Sanders                                             const void *Decoder) {
14532a83d680SDaniel Sanders   if (RegNo > 31)
14542a83d680SDaniel Sanders     return MCDisassembler::Fail;
14552a83d680SDaniel Sanders 
14562a83d680SDaniel Sanders   unsigned Reg = getReg(Decoder, Mips::COP2RegClassID, RegNo);
14572a83d680SDaniel Sanders   Inst.addOperand(MCOperand::CreateReg(Reg));
14582a83d680SDaniel Sanders   return MCDisassembler::Success;
14592a83d680SDaniel Sanders }
14602a83d680SDaniel Sanders 
146171928e68SAkira Hatanaka static DecodeStatus DecodeBranchTarget(MCInst &Inst,
146271928e68SAkira Hatanaka                                        unsigned Offset,
146371928e68SAkira Hatanaka                                        uint64_t Address,
146471928e68SAkira Hatanaka                                        const void *Decoder) {
1465d37bab61SAlexey Samsonov   int32_t BranchOffset = (SignExtend32<16>(Offset) * 4) + 4;
146671928e68SAkira Hatanaka   Inst.addOperand(MCOperand::CreateImm(BranchOffset));
146771928e68SAkira Hatanaka   return MCDisassembler::Success;
146871928e68SAkira Hatanaka }
146971928e68SAkira Hatanaka 
147071928e68SAkira Hatanaka static DecodeStatus DecodeJumpTarget(MCInst &Inst,
147171928e68SAkira Hatanaka                                      unsigned Insn,
147271928e68SAkira Hatanaka                                      uint64_t Address,
147371928e68SAkira Hatanaka                                      const void *Decoder) {
147471928e68SAkira Hatanaka 
1475ecaef49fSJim Grosbach   unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 2;
147671928e68SAkira Hatanaka   Inst.addOperand(MCOperand::CreateImm(JumpOffset));
147771928e68SAkira Hatanaka   return MCDisassembler::Success;
147871928e68SAkira Hatanaka }
147971928e68SAkira Hatanaka 
14803c8869dcSZoran Jovanovic static DecodeStatus DecodeBranchTarget21(MCInst &Inst,
14813c8869dcSZoran Jovanovic                                          unsigned Offset,
14823c8869dcSZoran Jovanovic                                          uint64_t Address,
14833c8869dcSZoran Jovanovic                                          const void *Decoder) {
1484d37bab61SAlexey Samsonov   int32_t BranchOffset = SignExtend32<21>(Offset) * 4;
14853c8869dcSZoran Jovanovic 
14863c8869dcSZoran Jovanovic   Inst.addOperand(MCOperand::CreateImm(BranchOffset));
14873c8869dcSZoran Jovanovic   return MCDisassembler::Success;
14883c8869dcSZoran Jovanovic }
14893c8869dcSZoran Jovanovic 
14903c8869dcSZoran Jovanovic static DecodeStatus DecodeBranchTarget26(MCInst &Inst,
14913c8869dcSZoran Jovanovic                                          unsigned Offset,
14923c8869dcSZoran Jovanovic                                          uint64_t Address,
14933c8869dcSZoran Jovanovic                                          const void *Decoder) {
1494d37bab61SAlexey Samsonov   int32_t BranchOffset = SignExtend32<26>(Offset) * 4;
14953c8869dcSZoran Jovanovic 
14963c8869dcSZoran Jovanovic   Inst.addOperand(MCOperand::CreateImm(BranchOffset));
14973c8869dcSZoran Jovanovic   return MCDisassembler::Success;
14983c8869dcSZoran Jovanovic }
14993c8869dcSZoran Jovanovic 
15008a80aa76SZoran Jovanovic static DecodeStatus DecodeBranchTargetMM(MCInst &Inst,
15018a80aa76SZoran Jovanovic                                          unsigned Offset,
15028a80aa76SZoran Jovanovic                                          uint64_t Address,
15038a80aa76SZoran Jovanovic                                          const void *Decoder) {
1504d37bab61SAlexey Samsonov   int32_t BranchOffset = SignExtend32<16>(Offset) * 2;
15058a80aa76SZoran Jovanovic   Inst.addOperand(MCOperand::CreateImm(BranchOffset));
15068a80aa76SZoran Jovanovic   return MCDisassembler::Success;
15078a80aa76SZoran Jovanovic }
15088a80aa76SZoran Jovanovic 
1509507e084aSZoran Jovanovic static DecodeStatus DecodeJumpTargetMM(MCInst &Inst,
1510507e084aSZoran Jovanovic                                        unsigned Insn,
1511507e084aSZoran Jovanovic                                        uint64_t Address,
1512507e084aSZoran Jovanovic                                        const void *Decoder) {
1513507e084aSZoran Jovanovic   unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 1;
1514507e084aSZoran Jovanovic   Inst.addOperand(MCOperand::CreateImm(JumpOffset));
1515507e084aSZoran Jovanovic   return MCDisassembler::Success;
1516507e084aSZoran Jovanovic }
151771928e68SAkira Hatanaka 
1518aa2b9278SJozef Kolek static DecodeStatus DecodeAddiur2Simm7(MCInst &Inst,
1519aa2b9278SJozef Kolek                                        unsigned Value,
1520aa2b9278SJozef Kolek                                        uint64_t Address,
1521aa2b9278SJozef Kolek                                        const void *Decoder) {
1522aa2b9278SJozef Kolek   if (Value == 0)
1523aa2b9278SJozef Kolek     Inst.addOperand(MCOperand::CreateImm(1));
1524aa2b9278SJozef Kolek   else if (Value == 0x7)
1525aa2b9278SJozef Kolek     Inst.addOperand(MCOperand::CreateImm(-1));
1526aa2b9278SJozef Kolek   else
1527aa2b9278SJozef Kolek     Inst.addOperand(MCOperand::CreateImm(Value << 2));
1528aa2b9278SJozef Kolek   return MCDisassembler::Success;
1529aa2b9278SJozef Kolek }
1530aa2b9278SJozef Kolek 
1531aa2b9278SJozef Kolek static DecodeStatus DecodeUImm6Lsl2(MCInst &Inst,
1532aa2b9278SJozef Kolek                                     unsigned Value,
1533aa2b9278SJozef Kolek                                     uint64_t Address,
1534aa2b9278SJozef Kolek                                     const void *Decoder) {
1535aa2b9278SJozef Kolek   Inst.addOperand(MCOperand::CreateImm(Value << 2));
1536aa2b9278SJozef Kolek   return MCDisassembler::Success;
1537aa2b9278SJozef Kolek }
1538aa2b9278SJozef Kolek 
1539aa2b9278SJozef Kolek static DecodeStatus DecodeLiSimm7(MCInst &Inst,
1540aa2b9278SJozef Kolek                                   unsigned Value,
1541aa2b9278SJozef Kolek                                   uint64_t Address,
1542aa2b9278SJozef Kolek                                   const void *Decoder) {
1543aa2b9278SJozef Kolek   if (Value == 0x7F)
1544aa2b9278SJozef Kolek     Inst.addOperand(MCOperand::CreateImm(-1));
1545aa2b9278SJozef Kolek   else
1546aa2b9278SJozef Kolek     Inst.addOperand(MCOperand::CreateImm(Value));
1547aa2b9278SJozef Kolek   return MCDisassembler::Success;
1548aa2b9278SJozef Kolek }
1549aa2b9278SJozef Kolek 
1550aa2b9278SJozef Kolek static DecodeStatus DecodeSimm4(MCInst &Inst,
1551aa2b9278SJozef Kolek                                 unsigned Value,
1552aa2b9278SJozef Kolek                                 uint64_t Address,
1553aa2b9278SJozef Kolek                                 const void *Decoder) {
1554aa2b9278SJozef Kolek   Inst.addOperand(MCOperand::CreateImm(SignExtend32<4>(Value)));
1555aa2b9278SJozef Kolek   return MCDisassembler::Success;
1556aa2b9278SJozef Kolek }
1557aa2b9278SJozef Kolek 
155871928e68SAkira Hatanaka static DecodeStatus DecodeSimm16(MCInst &Inst,
155971928e68SAkira Hatanaka                                  unsigned Insn,
156071928e68SAkira Hatanaka                                  uint64_t Address,
156171928e68SAkira Hatanaka                                  const void *Decoder) {
156271928e68SAkira Hatanaka   Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Insn)));
156371928e68SAkira Hatanaka   return MCDisassembler::Success;
156471928e68SAkira Hatanaka }
156571928e68SAkira Hatanaka 
1566779c5937SMatheus Almeida static DecodeStatus DecodeLSAImm(MCInst &Inst,
1567779c5937SMatheus Almeida                                  unsigned Insn,
1568779c5937SMatheus Almeida                                  uint64_t Address,
1569779c5937SMatheus Almeida                                  const void *Decoder) {
1570779c5937SMatheus Almeida   // We add one to the immediate field as it was encoded as 'imm - 1'.
1571779c5937SMatheus Almeida   Inst.addOperand(MCOperand::CreateImm(Insn + 1));
1572779c5937SMatheus Almeida   return MCDisassembler::Success;
1573779c5937SMatheus Almeida }
1574779c5937SMatheus Almeida 
157571928e68SAkira Hatanaka static DecodeStatus DecodeInsSize(MCInst &Inst,
157671928e68SAkira Hatanaka                                   unsigned Insn,
157771928e68SAkira Hatanaka                                   uint64_t Address,
157871928e68SAkira Hatanaka                                   const void *Decoder) {
157971928e68SAkira Hatanaka   // First we need to grab the pos(lsb) from MCInst.
158071928e68SAkira Hatanaka   int Pos = Inst.getOperand(2).getImm();
158171928e68SAkira Hatanaka   int Size = (int) Insn - Pos + 1;
158271928e68SAkira Hatanaka   Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size)));
158371928e68SAkira Hatanaka   return MCDisassembler::Success;
158471928e68SAkira Hatanaka }
158571928e68SAkira Hatanaka 
158671928e68SAkira Hatanaka static DecodeStatus DecodeExtSize(MCInst &Inst,
158771928e68SAkira Hatanaka                                   unsigned Insn,
158871928e68SAkira Hatanaka                                   uint64_t Address,
158971928e68SAkira Hatanaka                                   const void *Decoder) {
159071928e68SAkira Hatanaka   int Size = (int) Insn  + 1;
159171928e68SAkira Hatanaka   Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size)));
159271928e68SAkira Hatanaka   return MCDisassembler::Success;
159371928e68SAkira Hatanaka }
1594b59e1a41SDaniel Sanders 
1595b59e1a41SDaniel Sanders static DecodeStatus DecodeSimm19Lsl2(MCInst &Inst, unsigned Insn,
1596b59e1a41SDaniel Sanders                                      uint64_t Address, const void *Decoder) {
1597d37bab61SAlexey Samsonov   Inst.addOperand(MCOperand::CreateImm(SignExtend32<19>(Insn) * 4));
1598b59e1a41SDaniel Sanders   return MCDisassembler::Success;
1599b59e1a41SDaniel Sanders }
16002855142aSZoran Jovanovic 
16012855142aSZoran Jovanovic static DecodeStatus DecodeSimm18Lsl3(MCInst &Inst, unsigned Insn,
16022855142aSZoran Jovanovic                                      uint64_t Address, const void *Decoder) {
1603d37bab61SAlexey Samsonov   Inst.addOperand(MCOperand::CreateImm(SignExtend32<18>(Insn) * 8));
16042855142aSZoran Jovanovic   return MCDisassembler::Success;
16052855142aSZoran Jovanovic }
1606a4c4b5fcSZoran Jovanovic 
1607b682ddf3SVladimir Medic static DecodeStatus DecodeSimm9SP(MCInst &Inst, unsigned Insn,
1608b682ddf3SVladimir Medic                                   uint64_t Address, const void *Decoder) {
1609b682ddf3SVladimir Medic   int32_t DecodedValue;
1610b682ddf3SVladimir Medic   switch (Insn) {
1611b682ddf3SVladimir Medic   case 0: DecodedValue = 256; break;
1612b682ddf3SVladimir Medic   case 1: DecodedValue = 257; break;
1613b682ddf3SVladimir Medic   case 510: DecodedValue = -258; break;
1614b682ddf3SVladimir Medic   case 511: DecodedValue = -257; break;
1615b682ddf3SVladimir Medic   default: DecodedValue = SignExtend32<9>(Insn); break;
1616b682ddf3SVladimir Medic   }
1617b682ddf3SVladimir Medic   Inst.addOperand(MCOperand::CreateImm(DecodedValue << 2));
1618b682ddf3SVladimir Medic   return MCDisassembler::Success;
1619b682ddf3SVladimir Medic }
1620b682ddf3SVladimir Medic 
1621b682ddf3SVladimir Medic static DecodeStatus DecodeANDI16Imm(MCInst &Inst, unsigned Insn,
1622b682ddf3SVladimir Medic                                     uint64_t Address, const void *Decoder) {
1623b682ddf3SVladimir Medic   // Insn must be >= 0, since it is unsigned that condition is always true.
1624b682ddf3SVladimir Medic   assert(Insn < 16);
1625b682ddf3SVladimir Medic   int32_t DecodedValues[] = {128, 1, 2, 3, 4, 7, 8, 15, 16, 31, 32, 63, 64,
1626b682ddf3SVladimir Medic                              255, 32768, 65535};
1627b682ddf3SVladimir Medic   Inst.addOperand(MCOperand::CreateImm(DecodedValues[Insn]));
1628b682ddf3SVladimir Medic   return MCDisassembler::Success;
1629b682ddf3SVladimir Medic }
1630b682ddf3SVladimir Medic 
1631b682ddf3SVladimir Medic static DecodeStatus DecodeUImm5lsl2(MCInst &Inst, unsigned Insn,
1632b682ddf3SVladimir Medic                                     uint64_t Address, const void *Decoder) {
1633b682ddf3SVladimir Medic   Inst.addOperand(MCOperand::CreateImm(Insn << 2));
1634b682ddf3SVladimir Medic   return MCDisassembler::Success;
1635b682ddf3SVladimir Medic }
1636b682ddf3SVladimir Medic 
1637a4c4b5fcSZoran Jovanovic static DecodeStatus DecodeRegListOperand(MCInst &Inst,
1638a4c4b5fcSZoran Jovanovic                                          unsigned Insn,
1639a4c4b5fcSZoran Jovanovic                                          uint64_t Address,
1640a4c4b5fcSZoran Jovanovic                                          const void *Decoder) {
1641a4c4b5fcSZoran Jovanovic   unsigned Regs[] = {Mips::S0, Mips::S1, Mips::S2, Mips::S3, Mips::S4, Mips::S5,
1642a4c4b5fcSZoran Jovanovic                      Mips::S6, Mips::FP};
1643a4c4b5fcSZoran Jovanovic   unsigned RegNum;
1644a4c4b5fcSZoran Jovanovic 
1645a4c4b5fcSZoran Jovanovic   unsigned RegLst = fieldFromInstruction(Insn, 21, 5);
1646a4c4b5fcSZoran Jovanovic   // Empty register lists are not allowed.
1647a4c4b5fcSZoran Jovanovic   if (RegLst == 0)
1648a4c4b5fcSZoran Jovanovic     return MCDisassembler::Fail;
1649a4c4b5fcSZoran Jovanovic 
1650a4c4b5fcSZoran Jovanovic   RegNum = RegLst & 0xf;
1651a4c4b5fcSZoran Jovanovic   for (unsigned i = 0; i < RegNum; i++)
1652a4c4b5fcSZoran Jovanovic     Inst.addOperand(MCOperand::CreateReg(Regs[i]));
1653a4c4b5fcSZoran Jovanovic 
1654a4c4b5fcSZoran Jovanovic   if (RegLst & 0x10)
1655a4c4b5fcSZoran Jovanovic     Inst.addOperand(MCOperand::CreateReg(Mips::RA));
1656a4c4b5fcSZoran Jovanovic 
1657a4c4b5fcSZoran Jovanovic   return MCDisassembler::Success;
1658a4c4b5fcSZoran Jovanovic }
1659f9a02500SZoran Jovanovic 
1660f9a02500SZoran Jovanovic static DecodeStatus DecodeRegListOperand16(MCInst &Inst, unsigned Insn,
1661f9a02500SZoran Jovanovic                                            uint64_t Address,
1662f9a02500SZoran Jovanovic                                            const void *Decoder) {
1663f9a02500SZoran Jovanovic   unsigned Regs[] = {Mips::S0, Mips::S1, Mips::S2, Mips::S3};
1664f9a02500SZoran Jovanovic   unsigned RegNum;
1665f9a02500SZoran Jovanovic 
1666f9a02500SZoran Jovanovic   unsigned RegLst = fieldFromInstruction(Insn, 4, 2);
1667f9a02500SZoran Jovanovic   // Empty register lists are not allowed.
1668f9a02500SZoran Jovanovic   if (RegLst == 0)
1669f9a02500SZoran Jovanovic     return MCDisassembler::Fail;
1670f9a02500SZoran Jovanovic 
1671f9a02500SZoran Jovanovic   RegNum = RegLst & 0x3;
1672f9a02500SZoran Jovanovic   for (unsigned i = 0; i < RegNum - 1; i++)
1673f9a02500SZoran Jovanovic     Inst.addOperand(MCOperand::CreateReg(Regs[i]));
1674f9a02500SZoran Jovanovic 
1675f9a02500SZoran Jovanovic   Inst.addOperand(MCOperand::CreateReg(Mips::RA));
1676f9a02500SZoran Jovanovic 
1677f9a02500SZoran Jovanovic   return MCDisassembler::Success;
1678f9a02500SZoran Jovanovic }
1679