171928e68SAkira Hatanaka //===- MipsDisassembler.cpp - Disassembler for Mips -------------*- C++ -*-===//
271928e68SAkira Hatanaka //
371928e68SAkira Hatanaka //                     The LLVM Compiler Infrastructure
471928e68SAkira Hatanaka //
571928e68SAkira Hatanaka // This file is distributed under the University of Illinois Open Source
671928e68SAkira Hatanaka // License. See LICENSE.TXT for details.
771928e68SAkira Hatanaka //
871928e68SAkira Hatanaka //===----------------------------------------------------------------------===//
971928e68SAkira Hatanaka //
1071928e68SAkira Hatanaka // This file is part of the Mips Disassembler.
1171928e68SAkira Hatanaka //
1271928e68SAkira Hatanaka //===----------------------------------------------------------------------===//
1371928e68SAkira Hatanaka 
1471928e68SAkira Hatanaka #include "Mips.h"
159bf2b567SAkira Hatanaka #include "MipsRegisterInfo.h"
16ed0881b2SChandler Carruth #include "MipsSubtarget.h"
17a1bc0f56SLang Hames #include "llvm/MC/MCContext.h"
1871928e68SAkira Hatanaka #include "llvm/MC/MCDisassembler.h"
19ecaef49fSJim Grosbach #include "llvm/MC/MCFixedLenDisassembler.h"
20ed0881b2SChandler Carruth #include "llvm/MC/MCInst.h"
21ed0881b2SChandler Carruth #include "llvm/MC/MCSubtargetInfo.h"
22ed0881b2SChandler Carruth #include "llvm/Support/MathExtras.h"
2371928e68SAkira Hatanaka #include "llvm/Support/TargetRegistry.h"
2471928e68SAkira Hatanaka 
2571928e68SAkira Hatanaka using namespace llvm;
2671928e68SAkira Hatanaka 
27e96dd897SChandler Carruth #define DEBUG_TYPE "mips-disassembler"
28e96dd897SChandler Carruth 
2971928e68SAkira Hatanaka typedef MCDisassembler::DecodeStatus DecodeStatus;
3071928e68SAkira Hatanaka 
31cb3e98cfSBenjamin Kramer namespace {
32cb3e98cfSBenjamin Kramer 
334aa6bea7SRafael Espindola /// A disasembler class for Mips.
349bf2b567SAkira Hatanaka class MipsDisassemblerBase : public MCDisassembler {
3571928e68SAkira Hatanaka public:
36a1bc0f56SLang Hames   MipsDisassemblerBase(const MCSubtargetInfo &STI, MCContext &Ctx,
374aa6bea7SRafael Espindola                        bool IsBigEndian)
384aa6bea7SRafael Espindola       : MCDisassembler(STI, Ctx),
39e8860938SVladimir Medic         IsGP64Bit(STI.getFeatureBits() & Mips::FeatureGP64Bit),
404aa6bea7SRafael Espindola         IsBigEndian(IsBigEndian) {}
4171928e68SAkira Hatanaka 
429bf2b567SAkira Hatanaka   virtual ~MipsDisassemblerBase() {}
439bf2b567SAkira Hatanaka 
44e8860938SVladimir Medic   bool isGP64Bit() const { return IsGP64Bit; }
459bfa2e2eSAkira Hatanaka 
469bf2b567SAkira Hatanaka private:
47e8860938SVladimir Medic   bool IsGP64Bit;
489bf2b567SAkira Hatanaka protected:
494aa6bea7SRafael Espindola   bool IsBigEndian;
509bf2b567SAkira Hatanaka };
519bf2b567SAkira Hatanaka 
524aa6bea7SRafael Espindola /// A disasembler class for Mips32.
539bf2b567SAkira Hatanaka class MipsDisassembler : public MipsDisassemblerBase {
54dde3d582SVladimir Medic   bool IsMicroMips;
559bf2b567SAkira Hatanaka public:
56c171f65aSDaniel Sanders   MipsDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx, bool bigEndian)
57c171f65aSDaniel Sanders       : MipsDisassemblerBase(STI, Ctx, bigEndian) {
58dde3d582SVladimir Medic     IsMicroMips = STI.getFeatureBits() & Mips::FeatureMicroMips;
59dde3d582SVladimir Medic   }
6071928e68SAkira Hatanaka 
61c171f65aSDaniel Sanders   bool hasMips3() const { return STI.getFeatureBits() & Mips::FeatureMips3; }
62c171f65aSDaniel Sanders   bool hasMips32() const { return STI.getFeatureBits() & Mips::FeatureMips32; }
63c171f65aSDaniel Sanders   bool hasMips32r6() const {
645c582b2fSDaniel Sanders     return STI.getFeatureBits() & Mips::FeatureMips32r6;
655c582b2fSDaniel Sanders   }
665c582b2fSDaniel Sanders 
670fa60416SDaniel Sanders   bool isGP64() const { return STI.getFeatureBits() & Mips::FeatureGP64Bit; }
680fa60416SDaniel Sanders 
69c171f65aSDaniel Sanders   bool hasCOP3() const {
70c171f65aSDaniel Sanders     // Only present in MIPS-I and MIPS-II
71c171f65aSDaniel Sanders     return !hasMips32() && !hasMips3();
72c171f65aSDaniel Sanders   }
73c171f65aSDaniel Sanders 
744aa6bea7SRafael Espindola   DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
757fc5b874SRafael Espindola                               ArrayRef<uint8_t> Bytes, uint64_t Address,
764aa6bea7SRafael Espindola                               raw_ostream &VStream,
774aa6bea7SRafael Espindola                               raw_ostream &CStream) const override;
7871928e68SAkira Hatanaka };
7971928e68SAkira Hatanaka 
804aa6bea7SRafael Espindola /// A disasembler class for Mips64.
819bf2b567SAkira Hatanaka class Mips64Disassembler : public MipsDisassemblerBase {
8271928e68SAkira Hatanaka public:
83a1bc0f56SLang Hames   Mips64Disassembler(const MCSubtargetInfo &STI, MCContext &Ctx,
849bf2b567SAkira Hatanaka                      bool bigEndian) :
85a1bc0f56SLang Hames     MipsDisassemblerBase(STI, Ctx, bigEndian) {}
8671928e68SAkira Hatanaka 
874aa6bea7SRafael Espindola   DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
887fc5b874SRafael Espindola                               ArrayRef<uint8_t> Bytes, uint64_t Address,
894aa6bea7SRafael Espindola                               raw_ostream &VStream,
904aa6bea7SRafael Espindola                               raw_ostream &CStream) const override;
9171928e68SAkira Hatanaka };
9271928e68SAkira Hatanaka 
93cb3e98cfSBenjamin Kramer } // end anonymous namespace
94cb3e98cfSBenjamin Kramer 
9571928e68SAkira Hatanaka // Forward declare these because the autogenerated code will reference them.
9671928e68SAkira Hatanaka // Definitions are further down.
9713e6ccf3SAkira Hatanaka static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst,
9871928e68SAkira Hatanaka                                              unsigned RegNo,
9971928e68SAkira Hatanaka                                              uint64_t Address,
10071928e68SAkira Hatanaka                                              const void *Decoder);
10171928e68SAkira Hatanaka 
102ec8a5490SReed Kotler static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst,
103ec8a5490SReed Kotler                                                  unsigned RegNo,
104ec8a5490SReed Kotler                                                  uint64_t Address,
105ec8a5490SReed Kotler                                                  const void *Decoder);
106ec8a5490SReed Kotler 
107b0852e54SZoran Jovanovic static DecodeStatus DecodeGPRMM16RegisterClass(MCInst &Inst,
108b0852e54SZoran Jovanovic                                                unsigned RegNo,
109b0852e54SZoran Jovanovic                                                uint64_t Address,
110b0852e54SZoran Jovanovic                                                const void *Decoder);
111b0852e54SZoran Jovanovic 
1121904fa21SJozef Kolek static DecodeStatus DecodeGPRMM16ZeroRegisterClass(MCInst &Inst,
1131904fa21SJozef Kolek                                                    unsigned RegNo,
1141904fa21SJozef Kolek                                                    uint64_t Address,
1151904fa21SJozef Kolek                                                    const void *Decoder);
1161904fa21SJozef Kolek 
11713e6ccf3SAkira Hatanaka static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst,
11871928e68SAkira Hatanaka                                              unsigned RegNo,
11971928e68SAkira Hatanaka                                              uint64_t Address,
12071928e68SAkira Hatanaka                                              const void *Decoder);
12171928e68SAkira Hatanaka 
1229bfa2e2eSAkira Hatanaka static DecodeStatus DecodePtrRegisterClass(MCInst &Inst,
1239bfa2e2eSAkira Hatanaka                                            unsigned Insn,
1249bfa2e2eSAkira Hatanaka                                            uint64_t Address,
1259bfa2e2eSAkira Hatanaka                                            const void *Decoder);
1269bfa2e2eSAkira Hatanaka 
127654655f1SAkira Hatanaka static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst,
128ecabd1a5SAkira Hatanaka                                             unsigned RegNo,
129ecabd1a5SAkira Hatanaka                                             uint64_t Address,
130ecabd1a5SAkira Hatanaka                                             const void *Decoder);
131ecabd1a5SAkira Hatanaka 
13271928e68SAkira Hatanaka static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
13371928e68SAkira Hatanaka                                              unsigned RegNo,
13471928e68SAkira Hatanaka                                              uint64_t Address,
13571928e68SAkira Hatanaka                                              const void *Decoder);
13671928e68SAkira Hatanaka 
13771928e68SAkira Hatanaka static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
13871928e68SAkira Hatanaka                                              unsigned RegNo,
13971928e68SAkira Hatanaka                                              uint64_t Address,
14071928e68SAkira Hatanaka                                              const void *Decoder);
14171928e68SAkira Hatanaka 
14271928e68SAkira Hatanaka static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
14371928e68SAkira Hatanaka                                            unsigned RegNo,
14471928e68SAkira Hatanaka                                            uint64_t Address,
14571928e68SAkira Hatanaka                                            const void *Decoder);
14671928e68SAkira Hatanaka 
1471fb1b8b8SAkira Hatanaka static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst,
1481fb1b8b8SAkira Hatanaka                                            unsigned RegNo,
1491fb1b8b8SAkira Hatanaka                                            uint64_t Address,
1501fb1b8b8SAkira Hatanaka                                            const void *Decoder);
1511fb1b8b8SAkira Hatanaka 
1520fa60416SDaniel Sanders static DecodeStatus DecodeFGRCCRegisterClass(MCInst &Inst, unsigned RegNo,
1530fa60416SDaniel Sanders                                              uint64_t Address,
1540fa60416SDaniel Sanders                                              const void *Decoder);
1550fa60416SDaniel Sanders 
15671928e68SAkira Hatanaka static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
15771928e68SAkira Hatanaka                                               unsigned Insn,
15871928e68SAkira Hatanaka                                               uint64_t Address,
15971928e68SAkira Hatanaka                                               const void *Decoder);
16071928e68SAkira Hatanaka 
16171928e68SAkira Hatanaka static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
16271928e68SAkira Hatanaka                                               unsigned RegNo,
16371928e68SAkira Hatanaka                                               uint64_t Address,
16471928e68SAkira Hatanaka                                               const void *Decoder);
16571928e68SAkira Hatanaka 
16600fcf2e1SAkira Hatanaka static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst,
167ecabd1a5SAkira Hatanaka                                                 unsigned RegNo,
168ecabd1a5SAkira Hatanaka                                                 uint64_t Address,
169ecabd1a5SAkira Hatanaka                                                 const void *Decoder);
170ecabd1a5SAkira Hatanaka 
1718002a3f6SAkira Hatanaka static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst,
17259bfaf77SAkira Hatanaka                                                unsigned RegNo,
17359bfaf77SAkira Hatanaka                                                uint64_t Address,
17459bfaf77SAkira Hatanaka                                                const void *Decoder);
17559bfaf77SAkira Hatanaka 
1768002a3f6SAkira Hatanaka static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst,
17759bfaf77SAkira Hatanaka                                                unsigned RegNo,
17859bfaf77SAkira Hatanaka                                                uint64_t Address,
17959bfaf77SAkira Hatanaka                                                const void *Decoder);
18059bfaf77SAkira Hatanaka 
1813eb663b0SJack Carter static DecodeStatus DecodeMSA128BRegisterClass(MCInst &Inst,
1823eb663b0SJack Carter                                                unsigned RegNo,
1833eb663b0SJack Carter                                                uint64_t Address,
1843eb663b0SJack Carter                                                const void *Decoder);
1853eb663b0SJack Carter 
1865dc8ac92SJack Carter static DecodeStatus DecodeMSA128HRegisterClass(MCInst &Inst,
1875dc8ac92SJack Carter                                                unsigned RegNo,
1885dc8ac92SJack Carter                                                uint64_t Address,
1895dc8ac92SJack Carter                                                const void *Decoder);
1905dc8ac92SJack Carter 
1915dc8ac92SJack Carter static DecodeStatus DecodeMSA128WRegisterClass(MCInst &Inst,
1925dc8ac92SJack Carter                                                unsigned RegNo,
1935dc8ac92SJack Carter                                                uint64_t Address,
1945dc8ac92SJack Carter                                                const void *Decoder);
1955dc8ac92SJack Carter 
1965dc8ac92SJack Carter static DecodeStatus DecodeMSA128DRegisterClass(MCInst &Inst,
1975dc8ac92SJack Carter                                                unsigned RegNo,
1985dc8ac92SJack Carter                                                uint64_t Address,
1995dc8ac92SJack Carter                                                const void *Decoder);
2005dc8ac92SJack Carter 
201a591fdc6SMatheus Almeida static DecodeStatus DecodeMSACtrlRegisterClass(MCInst &Inst,
202a591fdc6SMatheus Almeida                                                unsigned RegNo,
203a591fdc6SMatheus Almeida                                                uint64_t Address,
204a591fdc6SMatheus Almeida                                                const void *Decoder);
205a591fdc6SMatheus Almeida 
2062a83d680SDaniel Sanders static DecodeStatus DecodeCOP2RegisterClass(MCInst &Inst,
2072a83d680SDaniel Sanders                                             unsigned RegNo,
2082a83d680SDaniel Sanders                                             uint64_t Address,
2092a83d680SDaniel Sanders                                             const void *Decoder);
2102a83d680SDaniel Sanders 
21171928e68SAkira Hatanaka static DecodeStatus DecodeBranchTarget(MCInst &Inst,
21271928e68SAkira Hatanaka                                        unsigned Offset,
21371928e68SAkira Hatanaka                                        uint64_t Address,
21471928e68SAkira Hatanaka                                        const void *Decoder);
21571928e68SAkira Hatanaka 
21671928e68SAkira Hatanaka static DecodeStatus DecodeJumpTarget(MCInst &Inst,
21771928e68SAkira Hatanaka                                      unsigned Insn,
21871928e68SAkira Hatanaka                                      uint64_t Address,
21971928e68SAkira Hatanaka                                      const void *Decoder);
22071928e68SAkira Hatanaka 
2213c8869dcSZoran Jovanovic static DecodeStatus DecodeBranchTarget21(MCInst &Inst,
2223c8869dcSZoran Jovanovic                                          unsigned Offset,
2233c8869dcSZoran Jovanovic                                          uint64_t Address,
2243c8869dcSZoran Jovanovic                                          const void *Decoder);
2253c8869dcSZoran Jovanovic 
2263c8869dcSZoran Jovanovic static DecodeStatus DecodeBranchTarget26(MCInst &Inst,
2273c8869dcSZoran Jovanovic                                          unsigned Offset,
2283c8869dcSZoran Jovanovic                                          uint64_t Address,
2293c8869dcSZoran Jovanovic                                          const void *Decoder);
2303c8869dcSZoran Jovanovic 
2319761e96bSJozef Kolek // DecodeBranchTarget7MM - Decode microMIPS branch offset, which is
2329761e96bSJozef Kolek // shifted left by 1 bit.
2339761e96bSJozef Kolek static DecodeStatus DecodeBranchTarget7MM(MCInst &Inst,
2349761e96bSJozef Kolek                                           unsigned Offset,
2359761e96bSJozef Kolek                                           uint64_t Address,
2369761e96bSJozef Kolek                                           const void *Decoder);
2379761e96bSJozef Kolek 
238*5cfebddeSJozef Kolek // DecodeBranchTarget10MM - Decode microMIPS branch offset, which is
239*5cfebddeSJozef Kolek // shifted left by 1 bit.
240*5cfebddeSJozef Kolek static DecodeStatus DecodeBranchTarget10MM(MCInst &Inst,
241*5cfebddeSJozef Kolek                                            unsigned Offset,
242*5cfebddeSJozef Kolek                                            uint64_t Address,
243*5cfebddeSJozef Kolek                                            const void *Decoder);
244*5cfebddeSJozef Kolek 
2458a80aa76SZoran Jovanovic // DecodeBranchTargetMM - Decode microMIPS branch offset, which is
2468a80aa76SZoran Jovanovic // shifted left by 1 bit.
2478a80aa76SZoran Jovanovic static DecodeStatus DecodeBranchTargetMM(MCInst &Inst,
2488a80aa76SZoran Jovanovic                                          unsigned Offset,
2498a80aa76SZoran Jovanovic                                          uint64_t Address,
2508a80aa76SZoran Jovanovic                                          const void *Decoder);
2518a80aa76SZoran Jovanovic 
252507e084aSZoran Jovanovic // DecodeJumpTargetMM - Decode microMIPS jump target, which is
253507e084aSZoran Jovanovic // shifted left by 1 bit.
254507e084aSZoran Jovanovic static DecodeStatus DecodeJumpTargetMM(MCInst &Inst,
255507e084aSZoran Jovanovic                                        unsigned Insn,
256507e084aSZoran Jovanovic                                        uint64_t Address,
257507e084aSZoran Jovanovic                                        const void *Decoder);
258507e084aSZoran Jovanovic 
25971928e68SAkira Hatanaka static DecodeStatus DecodeMem(MCInst &Inst,
26071928e68SAkira Hatanaka                               unsigned Insn,
26171928e68SAkira Hatanaka                               uint64_t Address,
26271928e68SAkira Hatanaka                               const void *Decoder);
26371928e68SAkira Hatanaka 
26492db6b78SDaniel Sanders static DecodeStatus DecodeCacheOp(MCInst &Inst,
26592db6b78SDaniel Sanders                               unsigned Insn,
26692db6b78SDaniel Sanders                               uint64_t Address,
26792db6b78SDaniel Sanders                               const void *Decoder);
26892db6b78SDaniel Sanders 
269ab6d1cceSJozef Kolek static DecodeStatus DecodeCacheOpMM(MCInst &Inst,
270ab6d1cceSJozef Kolek                                     unsigned Insn,
271ab6d1cceSJozef Kolek                                     uint64_t Address,
272ab6d1cceSJozef Kolek                                     const void *Decoder);
273ab6d1cceSJozef Kolek 
274b4484d62SDaniel Sanders static DecodeStatus DecodeSyncI(MCInst &Inst,
275b4484d62SDaniel Sanders                                 unsigned Insn,
276b4484d62SDaniel Sanders                                 uint64_t Address,
277b4484d62SDaniel Sanders                                 const void *Decoder);
278b4484d62SDaniel Sanders 
279fe0bf9f6SMatheus Almeida static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn,
280fe0bf9f6SMatheus Almeida                                     uint64_t Address, const void *Decoder);
281fe0bf9f6SMatheus Almeida 
282315e7ecaSJozef Kolek static DecodeStatus DecodeMemMMImm4(MCInst &Inst,
283315e7ecaSJozef Kolek                                     unsigned Insn,
284315e7ecaSJozef Kolek                                     uint64_t Address,
285315e7ecaSJozef Kolek                                     const void *Decoder);
286315e7ecaSJozef Kolek 
28712c6982bSJozef Kolek static DecodeStatus DecodeMemMMSPImm5Lsl2(MCInst &Inst,
28812c6982bSJozef Kolek                                           unsigned Insn,
28912c6982bSJozef Kolek                                           uint64_t Address,
29012c6982bSJozef Kolek                                           const void *Decoder);
29112c6982bSJozef Kolek 
292dde3d582SVladimir Medic static DecodeStatus DecodeMemMMImm12(MCInst &Inst,
293dde3d582SVladimir Medic                                      unsigned Insn,
294dde3d582SVladimir Medic                                      uint64_t Address,
295dde3d582SVladimir Medic                                      const void *Decoder);
296dde3d582SVladimir Medic 
297dde3d582SVladimir Medic static DecodeStatus DecodeMemMMImm16(MCInst &Inst,
298dde3d582SVladimir Medic                                      unsigned Insn,
299dde3d582SVladimir Medic                                      uint64_t Address,
300dde3d582SVladimir Medic                                      const void *Decoder);
301dde3d582SVladimir Medic 
30271928e68SAkira Hatanaka static DecodeStatus DecodeFMem(MCInst &Inst, unsigned Insn,
30371928e68SAkira Hatanaka                                uint64_t Address,
30471928e68SAkira Hatanaka                                const void *Decoder);
30571928e68SAkira Hatanaka 
30692db6b78SDaniel Sanders static DecodeStatus DecodeFMem2(MCInst &Inst, unsigned Insn,
30792db6b78SDaniel Sanders                                uint64_t Address,
30892db6b78SDaniel Sanders                                const void *Decoder);
30992db6b78SDaniel Sanders 
31092db6b78SDaniel Sanders static DecodeStatus DecodeFMem3(MCInst &Inst, unsigned Insn,
31192db6b78SDaniel Sanders                                uint64_t Address,
31292db6b78SDaniel Sanders                                const void *Decoder);
31392db6b78SDaniel Sanders 
314435cf8a4SVladimir Medic static DecodeStatus DecodeFMemCop2R6(MCInst &Inst, unsigned Insn,
315435cf8a4SVladimir Medic                                uint64_t Address,
316435cf8a4SVladimir Medic                                const void *Decoder);
317435cf8a4SVladimir Medic 
3186a803f61SDaniel Sanders static DecodeStatus DecodeSpecial3LlSc(MCInst &Inst,
3196a803f61SDaniel Sanders                                        unsigned Insn,
3206a803f61SDaniel Sanders                                        uint64_t Address,
3216a803f61SDaniel Sanders                                        const void *Decoder);
3226a803f61SDaniel Sanders 
323aa2b9278SJozef Kolek static DecodeStatus DecodeAddiur2Simm7(MCInst &Inst,
324aa2b9278SJozef Kolek                                        unsigned Value,
325aa2b9278SJozef Kolek                                        uint64_t Address,
326aa2b9278SJozef Kolek                                        const void *Decoder);
327aa2b9278SJozef Kolek 
328aa2b9278SJozef Kolek static DecodeStatus DecodeUImm6Lsl2(MCInst &Inst,
329aa2b9278SJozef Kolek                                     unsigned Value,
330aa2b9278SJozef Kolek                                     uint64_t Address,
331aa2b9278SJozef Kolek                                     const void *Decoder);
332aa2b9278SJozef Kolek 
333aa2b9278SJozef Kolek static DecodeStatus DecodeLiSimm7(MCInst &Inst,
334aa2b9278SJozef Kolek                                   unsigned Value,
335aa2b9278SJozef Kolek                                   uint64_t Address,
336aa2b9278SJozef Kolek                                   const void *Decoder);
337aa2b9278SJozef Kolek 
338aa2b9278SJozef Kolek static DecodeStatus DecodeSimm4(MCInst &Inst,
339aa2b9278SJozef Kolek                                 unsigned Value,
340aa2b9278SJozef Kolek                                 uint64_t Address,
341aa2b9278SJozef Kolek                                 const void *Decoder);
342aa2b9278SJozef Kolek 
34371928e68SAkira Hatanaka static DecodeStatus DecodeSimm16(MCInst &Inst,
34471928e68SAkira Hatanaka                                  unsigned Insn,
34571928e68SAkira Hatanaka                                  uint64_t Address,
34671928e68SAkira Hatanaka                                  const void *Decoder);
34771928e68SAkira Hatanaka 
348779c5937SMatheus Almeida // Decode the immediate field of an LSA instruction which
349779c5937SMatheus Almeida // is off by one.
350779c5937SMatheus Almeida static DecodeStatus DecodeLSAImm(MCInst &Inst,
351779c5937SMatheus Almeida                                  unsigned Insn,
352779c5937SMatheus Almeida                                  uint64_t Address,
353779c5937SMatheus Almeida                                  const void *Decoder);
354779c5937SMatheus Almeida 
35571928e68SAkira Hatanaka static DecodeStatus DecodeInsSize(MCInst &Inst,
35671928e68SAkira Hatanaka                                   unsigned Insn,
35771928e68SAkira Hatanaka                                   uint64_t Address,
35871928e68SAkira Hatanaka                                   const void *Decoder);
35971928e68SAkira Hatanaka 
36071928e68SAkira Hatanaka static DecodeStatus DecodeExtSize(MCInst &Inst,
36171928e68SAkira Hatanaka                                   unsigned Insn,
36271928e68SAkira Hatanaka                                   uint64_t Address,
36371928e68SAkira Hatanaka                                   const void *Decoder);
36471928e68SAkira Hatanaka 
365b59e1a41SDaniel Sanders static DecodeStatus DecodeSimm19Lsl2(MCInst &Inst, unsigned Insn,
366b59e1a41SDaniel Sanders                                      uint64_t Address, const void *Decoder);
367b59e1a41SDaniel Sanders 
3682855142aSZoran Jovanovic static DecodeStatus DecodeSimm18Lsl3(MCInst &Inst, unsigned Insn,
3692855142aSZoran Jovanovic                                      uint64_t Address, const void *Decoder);
3702855142aSZoran Jovanovic 
371b682ddf3SVladimir Medic static DecodeStatus DecodeSimm9SP(MCInst &Inst, unsigned Insn,
372b682ddf3SVladimir Medic                                   uint64_t Address, const void *Decoder);
373b682ddf3SVladimir Medic 
374b682ddf3SVladimir Medic static DecodeStatus DecodeANDI16Imm(MCInst &Inst, unsigned Insn,
375b682ddf3SVladimir Medic                                     uint64_t Address, const void *Decoder);
376b682ddf3SVladimir Medic 
377b682ddf3SVladimir Medic static DecodeStatus DecodeUImm5lsl2(MCInst &Inst, unsigned Insn,
378b682ddf3SVladimir Medic                                    uint64_t Address, const void *Decoder);
379b682ddf3SVladimir Medic 
3802c6d7320SJozef Kolek static DecodeStatus DecodeSimm23Lsl2(MCInst &Inst, unsigned Insn,
3812c6d7320SJozef Kolek                                      uint64_t Address, const void *Decoder);
3822c6d7320SJozef Kolek 
383b50ccf8eSDaniel Sanders /// INSVE_[BHWD] have an implicit operand that the generated decoder doesn't
384b50ccf8eSDaniel Sanders /// handle.
385b50ccf8eSDaniel Sanders template <typename InsnType>
386b50ccf8eSDaniel Sanders static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address,
387b50ccf8eSDaniel Sanders                                    const void *Decoder);
3885c582b2fSDaniel Sanders 
3895c582b2fSDaniel Sanders template <typename InsnType>
3905c582b2fSDaniel Sanders static DecodeStatus
3915c582b2fSDaniel Sanders DecodeAddiGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
3925c582b2fSDaniel Sanders                       const void *Decoder);
3935c582b2fSDaniel Sanders 
3945c582b2fSDaniel Sanders template <typename InsnType>
3955c582b2fSDaniel Sanders static DecodeStatus
3965c582b2fSDaniel Sanders DecodeDaddiGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
3975c582b2fSDaniel Sanders                        const void *Decoder);
3985c582b2fSDaniel Sanders 
3995c582b2fSDaniel Sanders template <typename InsnType>
4005c582b2fSDaniel Sanders static DecodeStatus
4015c582b2fSDaniel Sanders DecodeBlezlGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
4025c582b2fSDaniel Sanders                        const void *Decoder);
4035c582b2fSDaniel Sanders 
4045c582b2fSDaniel Sanders template <typename InsnType>
4055c582b2fSDaniel Sanders static DecodeStatus
4065c582b2fSDaniel Sanders DecodeBgtzlGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
4075c582b2fSDaniel Sanders                        const void *Decoder);
4085c582b2fSDaniel Sanders 
4095c582b2fSDaniel Sanders template <typename InsnType>
4105c582b2fSDaniel Sanders static DecodeStatus
4115c582b2fSDaniel Sanders DecodeBgtzGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
4125c582b2fSDaniel Sanders                       const void *Decoder);
4135c582b2fSDaniel Sanders 
41428a0ca07SZoran Jovanovic template <typename InsnType>
41528a0ca07SZoran Jovanovic static DecodeStatus
41628a0ca07SZoran Jovanovic DecodeBlezGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
41728a0ca07SZoran Jovanovic                        const void *Decoder);
41828a0ca07SZoran Jovanovic 
419a4c4b5fcSZoran Jovanovic static DecodeStatus DecodeRegListOperand(MCInst &Inst, unsigned Insn,
420a4c4b5fcSZoran Jovanovic                                          uint64_t Address,
421a4c4b5fcSZoran Jovanovic                                          const void *Decoder);
422a4c4b5fcSZoran Jovanovic 
423f9a02500SZoran Jovanovic static DecodeStatus DecodeRegListOperand16(MCInst &Inst, unsigned Insn,
424f9a02500SZoran Jovanovic                                            uint64_t Address,
425f9a02500SZoran Jovanovic                                            const void *Decoder);
426f9a02500SZoran Jovanovic 
42771928e68SAkira Hatanaka namespace llvm {
42871928e68SAkira Hatanaka extern Target TheMipselTarget, TheMipsTarget, TheMips64Target,
42971928e68SAkira Hatanaka               TheMips64elTarget;
43071928e68SAkira Hatanaka }
43171928e68SAkira Hatanaka 
43271928e68SAkira Hatanaka static MCDisassembler *createMipsDisassembler(
43371928e68SAkira Hatanaka                        const Target &T,
434a1bc0f56SLang Hames                        const MCSubtargetInfo &STI,
435a1bc0f56SLang Hames                        MCContext &Ctx) {
436a1bc0f56SLang Hames   return new MipsDisassembler(STI, Ctx, true);
43771928e68SAkira Hatanaka }
43871928e68SAkira Hatanaka 
43971928e68SAkira Hatanaka static MCDisassembler *createMipselDisassembler(
44071928e68SAkira Hatanaka                        const Target &T,
441a1bc0f56SLang Hames                        const MCSubtargetInfo &STI,
442a1bc0f56SLang Hames                        MCContext &Ctx) {
443a1bc0f56SLang Hames   return new MipsDisassembler(STI, Ctx, false);
44471928e68SAkira Hatanaka }
44571928e68SAkira Hatanaka 
44671928e68SAkira Hatanaka static MCDisassembler *createMips64Disassembler(
44771928e68SAkira Hatanaka                        const Target &T,
448a1bc0f56SLang Hames                        const MCSubtargetInfo &STI,
449a1bc0f56SLang Hames                        MCContext &Ctx) {
450a1bc0f56SLang Hames   return new Mips64Disassembler(STI, Ctx, true);
45171928e68SAkira Hatanaka }
45271928e68SAkira Hatanaka 
45371928e68SAkira Hatanaka static MCDisassembler *createMips64elDisassembler(
45471928e68SAkira Hatanaka                        const Target &T,
455a1bc0f56SLang Hames                        const MCSubtargetInfo &STI,
456a1bc0f56SLang Hames                        MCContext &Ctx) {
457a1bc0f56SLang Hames   return new Mips64Disassembler(STI, Ctx, false);
45871928e68SAkira Hatanaka }
45971928e68SAkira Hatanaka 
46071928e68SAkira Hatanaka extern "C" void LLVMInitializeMipsDisassembler() {
46171928e68SAkira Hatanaka   // Register the disassembler.
46271928e68SAkira Hatanaka   TargetRegistry::RegisterMCDisassembler(TheMipsTarget,
46371928e68SAkira Hatanaka                                          createMipsDisassembler);
46471928e68SAkira Hatanaka   TargetRegistry::RegisterMCDisassembler(TheMipselTarget,
46571928e68SAkira Hatanaka                                          createMipselDisassembler);
46671928e68SAkira Hatanaka   TargetRegistry::RegisterMCDisassembler(TheMips64Target,
46771928e68SAkira Hatanaka                                          createMips64Disassembler);
46871928e68SAkira Hatanaka   TargetRegistry::RegisterMCDisassembler(TheMips64elTarget,
46971928e68SAkira Hatanaka                                          createMips64elDisassembler);
47071928e68SAkira Hatanaka }
47171928e68SAkira Hatanaka 
47271928e68SAkira Hatanaka #include "MipsGenDisassemblerTables.inc"
47371928e68SAkira Hatanaka 
4745c582b2fSDaniel Sanders static unsigned getReg(const void *D, unsigned RC, unsigned RegNo) {
4755c582b2fSDaniel Sanders   const MipsDisassemblerBase *Dis = static_cast<const MipsDisassemblerBase*>(D);
4765c582b2fSDaniel Sanders   const MCRegisterInfo *RegInfo = Dis->getContext().getRegisterInfo();
4775c582b2fSDaniel Sanders   return *(RegInfo->getRegClass(RC).begin() + RegNo);
4785c582b2fSDaniel Sanders }
4795c582b2fSDaniel Sanders 
480b50ccf8eSDaniel Sanders template <typename InsnType>
481b50ccf8eSDaniel Sanders static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address,
482b50ccf8eSDaniel Sanders                                    const void *Decoder) {
483b50ccf8eSDaniel Sanders   typedef DecodeStatus (*DecodeFN)(MCInst &, unsigned, uint64_t, const void *);
484b50ccf8eSDaniel Sanders   // The size of the n field depends on the element size
485b50ccf8eSDaniel Sanders   // The register class also depends on this.
486b50ccf8eSDaniel Sanders   InsnType tmp = fieldFromInstruction(insn, 17, 5);
487b50ccf8eSDaniel Sanders   unsigned NSize = 0;
488b50ccf8eSDaniel Sanders   DecodeFN RegDecoder = nullptr;
489b50ccf8eSDaniel Sanders   if ((tmp & 0x18) == 0x00) { // INSVE_B
490b50ccf8eSDaniel Sanders     NSize = 4;
491b50ccf8eSDaniel Sanders     RegDecoder = DecodeMSA128BRegisterClass;
492b50ccf8eSDaniel Sanders   } else if ((tmp & 0x1c) == 0x10) { // INSVE_H
493b50ccf8eSDaniel Sanders     NSize = 3;
494b50ccf8eSDaniel Sanders     RegDecoder = DecodeMSA128HRegisterClass;
495b50ccf8eSDaniel Sanders   } else if ((tmp & 0x1e) == 0x18) { // INSVE_W
496b50ccf8eSDaniel Sanders     NSize = 2;
497b50ccf8eSDaniel Sanders     RegDecoder = DecodeMSA128WRegisterClass;
498b50ccf8eSDaniel Sanders   } else if ((tmp & 0x1f) == 0x1c) { // INSVE_D
499b50ccf8eSDaniel Sanders     NSize = 1;
500b50ccf8eSDaniel Sanders     RegDecoder = DecodeMSA128DRegisterClass;
501b50ccf8eSDaniel Sanders   } else
502b50ccf8eSDaniel Sanders     llvm_unreachable("Invalid encoding");
503b50ccf8eSDaniel Sanders 
504b50ccf8eSDaniel Sanders   assert(NSize != 0 && RegDecoder != nullptr);
505b50ccf8eSDaniel Sanders 
506b50ccf8eSDaniel Sanders   // $wd
507b50ccf8eSDaniel Sanders   tmp = fieldFromInstruction(insn, 6, 5);
508b50ccf8eSDaniel Sanders   if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
509b50ccf8eSDaniel Sanders     return MCDisassembler::Fail;
510b50ccf8eSDaniel Sanders   // $wd_in
511b50ccf8eSDaniel Sanders   if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
512b50ccf8eSDaniel Sanders     return MCDisassembler::Fail;
513b50ccf8eSDaniel Sanders   // $n
514b50ccf8eSDaniel Sanders   tmp = fieldFromInstruction(insn, 16, NSize);
515b50ccf8eSDaniel Sanders   MI.addOperand(MCOperand::CreateImm(tmp));
516b50ccf8eSDaniel Sanders   // $ws
517b50ccf8eSDaniel Sanders   tmp = fieldFromInstruction(insn, 11, 5);
518b50ccf8eSDaniel Sanders   if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
519b50ccf8eSDaniel Sanders     return MCDisassembler::Fail;
520b50ccf8eSDaniel Sanders   // $n2
521b50ccf8eSDaniel Sanders   MI.addOperand(MCOperand::CreateImm(0));
522b50ccf8eSDaniel Sanders 
523b50ccf8eSDaniel Sanders   return MCDisassembler::Success;
524b50ccf8eSDaniel Sanders }
525b50ccf8eSDaniel Sanders 
5265c582b2fSDaniel Sanders template <typename InsnType>
5275c582b2fSDaniel Sanders static DecodeStatus DecodeAddiGroupBranch(MCInst &MI, InsnType insn,
5285c582b2fSDaniel Sanders                                           uint64_t Address,
5295c582b2fSDaniel Sanders                                           const void *Decoder) {
5305c582b2fSDaniel Sanders   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
5315c582b2fSDaniel Sanders   // (otherwise we would have matched the ADDI instruction from the earlier
5325c582b2fSDaniel Sanders   // ISA's instead).
5335c582b2fSDaniel Sanders   //
5345c582b2fSDaniel Sanders   // We have:
5355c582b2fSDaniel Sanders   //    0b001000 sssss ttttt iiiiiiiiiiiiiiii
5365c582b2fSDaniel Sanders   //      BOVC if rs >= rt
5375c582b2fSDaniel Sanders   //      BEQZALC if rs == 0 && rt != 0
5385c582b2fSDaniel Sanders   //      BEQC if rs < rt && rs != 0
5395c582b2fSDaniel Sanders 
5405c582b2fSDaniel Sanders   InsnType Rs = fieldFromInstruction(insn, 21, 5);
5415c582b2fSDaniel Sanders   InsnType Rt = fieldFromInstruction(insn, 16, 5);
542d37bab61SAlexey Samsonov   InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4;
5435c582b2fSDaniel Sanders   bool HasRs = false;
5445c582b2fSDaniel Sanders 
5455c582b2fSDaniel Sanders   if (Rs >= Rt) {
5465c582b2fSDaniel Sanders     MI.setOpcode(Mips::BOVC);
5475c582b2fSDaniel Sanders     HasRs = true;
5485c582b2fSDaniel Sanders   } else if (Rs != 0 && Rs < Rt) {
5495c582b2fSDaniel Sanders     MI.setOpcode(Mips::BEQC);
5505c582b2fSDaniel Sanders     HasRs = true;
5515c582b2fSDaniel Sanders   } else
5525c582b2fSDaniel Sanders     MI.setOpcode(Mips::BEQZALC);
5535c582b2fSDaniel Sanders 
5545c582b2fSDaniel Sanders   if (HasRs)
5555c582b2fSDaniel Sanders     MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
5565c582b2fSDaniel Sanders                                        Rs)));
5575c582b2fSDaniel Sanders 
5585c582b2fSDaniel Sanders   MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
5595c582b2fSDaniel Sanders                                      Rt)));
5605c582b2fSDaniel Sanders   MI.addOperand(MCOperand::CreateImm(Imm));
5615c582b2fSDaniel Sanders 
5625c582b2fSDaniel Sanders   return MCDisassembler::Success;
5635c582b2fSDaniel Sanders }
5645c582b2fSDaniel Sanders 
5655c582b2fSDaniel Sanders template <typename InsnType>
5665c582b2fSDaniel Sanders static DecodeStatus DecodeDaddiGroupBranch(MCInst &MI, InsnType insn,
5675c582b2fSDaniel Sanders                                            uint64_t Address,
5685c582b2fSDaniel Sanders                                            const void *Decoder) {
5695c582b2fSDaniel Sanders   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
5705c582b2fSDaniel Sanders   // (otherwise we would have matched the ADDI instruction from the earlier
5715c582b2fSDaniel Sanders   // ISA's instead).
5725c582b2fSDaniel Sanders   //
5735c582b2fSDaniel Sanders   // We have:
5745c582b2fSDaniel Sanders   //    0b011000 sssss ttttt iiiiiiiiiiiiiiii
5755c582b2fSDaniel Sanders   //      BNVC if rs >= rt
5765c582b2fSDaniel Sanders   //      BNEZALC if rs == 0 && rt != 0
5775c582b2fSDaniel Sanders   //      BNEC if rs < rt && rs != 0
5785c582b2fSDaniel Sanders 
5795c582b2fSDaniel Sanders   InsnType Rs = fieldFromInstruction(insn, 21, 5);
5805c582b2fSDaniel Sanders   InsnType Rt = fieldFromInstruction(insn, 16, 5);
581d37bab61SAlexey Samsonov   InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4;
5825c582b2fSDaniel Sanders   bool HasRs = false;
5835c582b2fSDaniel Sanders 
5845c582b2fSDaniel Sanders   if (Rs >= Rt) {
5855c582b2fSDaniel Sanders     MI.setOpcode(Mips::BNVC);
5865c582b2fSDaniel Sanders     HasRs = true;
5875c582b2fSDaniel Sanders   } else if (Rs != 0 && Rs < Rt) {
5885c582b2fSDaniel Sanders     MI.setOpcode(Mips::BNEC);
5895c582b2fSDaniel Sanders     HasRs = true;
5905c582b2fSDaniel Sanders   } else
5915c582b2fSDaniel Sanders     MI.setOpcode(Mips::BNEZALC);
5925c582b2fSDaniel Sanders 
5935c582b2fSDaniel Sanders   if (HasRs)
5945c582b2fSDaniel Sanders     MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
5955c582b2fSDaniel Sanders                                        Rs)));
5965c582b2fSDaniel Sanders 
5975c582b2fSDaniel Sanders   MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
5985c582b2fSDaniel Sanders                                      Rt)));
5995c582b2fSDaniel Sanders   MI.addOperand(MCOperand::CreateImm(Imm));
6005c582b2fSDaniel Sanders 
6015c582b2fSDaniel Sanders   return MCDisassembler::Success;
6025c582b2fSDaniel Sanders }
6035c582b2fSDaniel Sanders 
6045c582b2fSDaniel Sanders template <typename InsnType>
6055c582b2fSDaniel Sanders static DecodeStatus DecodeBlezlGroupBranch(MCInst &MI, InsnType insn,
6065c582b2fSDaniel Sanders                                            uint64_t Address,
6075c582b2fSDaniel Sanders                                            const void *Decoder) {
6085c582b2fSDaniel Sanders   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
6095c582b2fSDaniel Sanders   // (otherwise we would have matched the BLEZL instruction from the earlier
6105c582b2fSDaniel Sanders   // ISA's instead).
6115c582b2fSDaniel Sanders   //
6125c582b2fSDaniel Sanders   // We have:
6135c582b2fSDaniel Sanders   //    0b010110 sssss ttttt iiiiiiiiiiiiiiii
6145c582b2fSDaniel Sanders   //      Invalid if rs == 0
6155c582b2fSDaniel Sanders   //      BLEZC   if rs == 0  && rt != 0
6165c582b2fSDaniel Sanders   //      BGEZC   if rs == rt && rt != 0
6175c582b2fSDaniel Sanders   //      BGEC    if rs != rt && rs != 0  && rt != 0
6185c582b2fSDaniel Sanders 
6195c582b2fSDaniel Sanders   InsnType Rs = fieldFromInstruction(insn, 21, 5);
6205c582b2fSDaniel Sanders   InsnType Rt = fieldFromInstruction(insn, 16, 5);
621d37bab61SAlexey Samsonov   InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4;
62228a0ca07SZoran Jovanovic   bool HasRs = false;
6235c582b2fSDaniel Sanders 
6245c582b2fSDaniel Sanders   if (Rt == 0)
6255c582b2fSDaniel Sanders     return MCDisassembler::Fail;
6265c582b2fSDaniel Sanders   else if (Rs == 0)
6275c582b2fSDaniel Sanders     MI.setOpcode(Mips::BLEZC);
6285c582b2fSDaniel Sanders   else if (Rs == Rt)
6295c582b2fSDaniel Sanders     MI.setOpcode(Mips::BGEZC);
63028a0ca07SZoran Jovanovic   else {
63128a0ca07SZoran Jovanovic     HasRs = true;
63228a0ca07SZoran Jovanovic     MI.setOpcode(Mips::BGEC);
63328a0ca07SZoran Jovanovic   }
63428a0ca07SZoran Jovanovic 
63528a0ca07SZoran Jovanovic   if (HasRs)
63628a0ca07SZoran Jovanovic     MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
63728a0ca07SZoran Jovanovic                                        Rs)));
6385c582b2fSDaniel Sanders 
6395c582b2fSDaniel Sanders   MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
6405c582b2fSDaniel Sanders                                      Rt)));
6415c582b2fSDaniel Sanders 
6425c582b2fSDaniel Sanders   MI.addOperand(MCOperand::CreateImm(Imm));
6435c582b2fSDaniel Sanders 
6445c582b2fSDaniel Sanders   return MCDisassembler::Success;
6455c582b2fSDaniel Sanders }
6465c582b2fSDaniel Sanders 
6475c582b2fSDaniel Sanders template <typename InsnType>
6485c582b2fSDaniel Sanders static DecodeStatus DecodeBgtzlGroupBranch(MCInst &MI, InsnType insn,
6495c582b2fSDaniel Sanders                                            uint64_t Address,
6505c582b2fSDaniel Sanders                                            const void *Decoder) {
6515c582b2fSDaniel Sanders   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
6525c582b2fSDaniel Sanders   // (otherwise we would have matched the BGTZL instruction from the earlier
6535c582b2fSDaniel Sanders   // ISA's instead).
6545c582b2fSDaniel Sanders   //
6555c582b2fSDaniel Sanders   // We have:
6565c582b2fSDaniel Sanders   //    0b010111 sssss ttttt iiiiiiiiiiiiiiii
6575c582b2fSDaniel Sanders   //      Invalid if rs == 0
6585c582b2fSDaniel Sanders   //      BGTZC   if rs == 0  && rt != 0
6595c582b2fSDaniel Sanders   //      BLTZC   if rs == rt && rt != 0
6605c582b2fSDaniel Sanders   //      BLTC    if rs != rt && rs != 0  && rt != 0
6615c582b2fSDaniel Sanders 
6625c14b069SZoran Jovanovic   bool HasRs = false;
6635c14b069SZoran Jovanovic 
6645c582b2fSDaniel Sanders   InsnType Rs = fieldFromInstruction(insn, 21, 5);
6655c582b2fSDaniel Sanders   InsnType Rt = fieldFromInstruction(insn, 16, 5);
666d37bab61SAlexey Samsonov   InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4;
6675c582b2fSDaniel Sanders 
6685c582b2fSDaniel Sanders   if (Rt == 0)
6695c582b2fSDaniel Sanders     return MCDisassembler::Fail;
6705c582b2fSDaniel Sanders   else if (Rs == 0)
6715c582b2fSDaniel Sanders     MI.setOpcode(Mips::BGTZC);
6725c582b2fSDaniel Sanders   else if (Rs == Rt)
6735c582b2fSDaniel Sanders     MI.setOpcode(Mips::BLTZC);
6745c14b069SZoran Jovanovic   else {
6755c14b069SZoran Jovanovic     MI.setOpcode(Mips::BLTC);
6765c14b069SZoran Jovanovic     HasRs = true;
6775c14b069SZoran Jovanovic   }
6785c14b069SZoran Jovanovic 
6795c14b069SZoran Jovanovic   if (HasRs)
6805c14b069SZoran Jovanovic     MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
6815c14b069SZoran Jovanovic                                               Rs)));
6825c582b2fSDaniel Sanders 
6835c582b2fSDaniel Sanders   MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
6845c582b2fSDaniel Sanders                                      Rt)));
6855c582b2fSDaniel Sanders 
6865c582b2fSDaniel Sanders   MI.addOperand(MCOperand::CreateImm(Imm));
6875c582b2fSDaniel Sanders 
6885c582b2fSDaniel Sanders   return MCDisassembler::Success;
6895c582b2fSDaniel Sanders }
6905c582b2fSDaniel Sanders 
6915c582b2fSDaniel Sanders template <typename InsnType>
6925c582b2fSDaniel Sanders static DecodeStatus DecodeBgtzGroupBranch(MCInst &MI, InsnType insn,
6935c582b2fSDaniel Sanders                                           uint64_t Address,
6945c582b2fSDaniel Sanders                                           const void *Decoder) {
6955c582b2fSDaniel Sanders   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
6965c582b2fSDaniel Sanders   // (otherwise we would have matched the BGTZ instruction from the earlier
6975c582b2fSDaniel Sanders   // ISA's instead).
6985c582b2fSDaniel Sanders   //
6995c582b2fSDaniel Sanders   // We have:
7005c582b2fSDaniel Sanders   //    0b000111 sssss ttttt iiiiiiiiiiiiiiii
7015c582b2fSDaniel Sanders   //      BGTZ    if rt == 0
7025c582b2fSDaniel Sanders   //      BGTZALC if rs == 0 && rt != 0
7035c582b2fSDaniel Sanders   //      BLTZALC if rs != 0 && rs == rt
7045c582b2fSDaniel Sanders   //      BLTUC   if rs != 0 && rs != rt
7055c582b2fSDaniel Sanders 
7065c582b2fSDaniel Sanders   InsnType Rs = fieldFromInstruction(insn, 21, 5);
7075c582b2fSDaniel Sanders   InsnType Rt = fieldFromInstruction(insn, 16, 5);
708d37bab61SAlexey Samsonov   InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4;
7095c582b2fSDaniel Sanders   bool HasRs = false;
7105c582b2fSDaniel Sanders   bool HasRt = false;
7115c582b2fSDaniel Sanders 
7125c582b2fSDaniel Sanders   if (Rt == 0) {
7135c582b2fSDaniel Sanders     MI.setOpcode(Mips::BGTZ);
7145c582b2fSDaniel Sanders     HasRs = true;
7155c582b2fSDaniel Sanders   } else if (Rs == 0) {
7165c582b2fSDaniel Sanders     MI.setOpcode(Mips::BGTZALC);
7175c582b2fSDaniel Sanders     HasRt = true;
7185c582b2fSDaniel Sanders   } else if (Rs == Rt) {
7195c582b2fSDaniel Sanders     MI.setOpcode(Mips::BLTZALC);
7205c582b2fSDaniel Sanders     HasRs = true;
7215c14b069SZoran Jovanovic   } else {
7225c14b069SZoran Jovanovic     MI.setOpcode(Mips::BLTUC);
7235c14b069SZoran Jovanovic     HasRs = true;
7245c14b069SZoran Jovanovic     HasRt = true;
7255c14b069SZoran Jovanovic   }
7265c582b2fSDaniel Sanders 
7275c582b2fSDaniel Sanders   if (HasRs)
7285c582b2fSDaniel Sanders     MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
7295c582b2fSDaniel Sanders                                        Rs)));
7305c582b2fSDaniel Sanders 
7315c582b2fSDaniel Sanders   if (HasRt)
7325c582b2fSDaniel Sanders     MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
7335c582b2fSDaniel Sanders                                        Rt)));
7345c582b2fSDaniel Sanders 
7355c582b2fSDaniel Sanders   MI.addOperand(MCOperand::CreateImm(Imm));
7365c582b2fSDaniel Sanders 
7375c582b2fSDaniel Sanders   return MCDisassembler::Success;
7385c582b2fSDaniel Sanders }
7395c582b2fSDaniel Sanders 
74028a0ca07SZoran Jovanovic template <typename InsnType>
74128a0ca07SZoran Jovanovic static DecodeStatus DecodeBlezGroupBranch(MCInst &MI, InsnType insn,
74228a0ca07SZoran Jovanovic                                            uint64_t Address,
74328a0ca07SZoran Jovanovic                                            const void *Decoder) {
74428a0ca07SZoran Jovanovic   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
74528a0ca07SZoran Jovanovic   // (otherwise we would have matched the BLEZL instruction from the earlier
74628a0ca07SZoran Jovanovic   // ISA's instead).
74728a0ca07SZoran Jovanovic   //
74828a0ca07SZoran Jovanovic   // We have:
74928a0ca07SZoran Jovanovic   //    0b000110 sssss ttttt iiiiiiiiiiiiiiii
75028a0ca07SZoran Jovanovic   //      Invalid   if rs == 0
75128a0ca07SZoran Jovanovic   //      BLEZALC   if rs == 0  && rt != 0
75228a0ca07SZoran Jovanovic   //      BGEZALC   if rs == rt && rt != 0
75328a0ca07SZoran Jovanovic   //      BGEUC     if rs != rt && rs != 0  && rt != 0
75428a0ca07SZoran Jovanovic 
75528a0ca07SZoran Jovanovic   InsnType Rs = fieldFromInstruction(insn, 21, 5);
75628a0ca07SZoran Jovanovic   InsnType Rt = fieldFromInstruction(insn, 16, 5);
757d37bab61SAlexey Samsonov   InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4;
75828a0ca07SZoran Jovanovic   bool HasRs = false;
75928a0ca07SZoran Jovanovic 
76028a0ca07SZoran Jovanovic   if (Rt == 0)
76128a0ca07SZoran Jovanovic     return MCDisassembler::Fail;
76228a0ca07SZoran Jovanovic   else if (Rs == 0)
76328a0ca07SZoran Jovanovic     MI.setOpcode(Mips::BLEZALC);
76428a0ca07SZoran Jovanovic   else if (Rs == Rt)
76528a0ca07SZoran Jovanovic     MI.setOpcode(Mips::BGEZALC);
76628a0ca07SZoran Jovanovic   else {
76728a0ca07SZoran Jovanovic     HasRs = true;
76828a0ca07SZoran Jovanovic     MI.setOpcode(Mips::BGEUC);
76928a0ca07SZoran Jovanovic   }
77028a0ca07SZoran Jovanovic 
77128a0ca07SZoran Jovanovic   if (HasRs)
77228a0ca07SZoran Jovanovic     MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
77328a0ca07SZoran Jovanovic                                        Rs)));
77428a0ca07SZoran Jovanovic   MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
77528a0ca07SZoran Jovanovic                                      Rt)));
77628a0ca07SZoran Jovanovic 
77728a0ca07SZoran Jovanovic   MI.addOperand(MCOperand::CreateImm(Imm));
77828a0ca07SZoran Jovanovic 
77928a0ca07SZoran Jovanovic   return MCDisassembler::Success;
78028a0ca07SZoran Jovanovic }
78128a0ca07SZoran Jovanovic 
782ea22c4cfSJozef Kolek /// Read two bytes from the ArrayRef and return 16 bit halfword sorted
783ea22c4cfSJozef Kolek /// according to the given endianess.
784ea22c4cfSJozef Kolek static DecodeStatus readInstruction16(ArrayRef<uint8_t> Bytes, uint64_t Address,
785ea22c4cfSJozef Kolek                                       uint64_t &Size, uint32_t &Insn,
786ea22c4cfSJozef Kolek                                       bool IsBigEndian) {
787ea22c4cfSJozef Kolek   // We want to read exactly 2 Bytes of data.
788ea22c4cfSJozef Kolek   if (Bytes.size() < 2) {
789ea22c4cfSJozef Kolek     Size = 0;
790ea22c4cfSJozef Kolek     return MCDisassembler::Fail;
791ea22c4cfSJozef Kolek   }
792ea22c4cfSJozef Kolek 
793ea22c4cfSJozef Kolek   if (IsBigEndian) {
794ea22c4cfSJozef Kolek     Insn = (Bytes[0] << 8) | Bytes[1];
795ea22c4cfSJozef Kolek   } else {
796ea22c4cfSJozef Kolek     Insn = (Bytes[1] << 8) | Bytes[0];
797ea22c4cfSJozef Kolek   }
798ea22c4cfSJozef Kolek 
799ea22c4cfSJozef Kolek   return MCDisassembler::Success;
800ea22c4cfSJozef Kolek }
801ea22c4cfSJozef Kolek 
8027fc5b874SRafael Espindola /// Read four bytes from the ArrayRef and return 32 bit word sorted
8034aa6bea7SRafael Espindola /// according to the given endianess
8047fc5b874SRafael Espindola static DecodeStatus readInstruction32(ArrayRef<uint8_t> Bytes, uint64_t Address,
8057fc5b874SRafael Espindola                                       uint64_t &Size, uint32_t &Insn,
8067fc5b874SRafael Espindola                                       bool IsBigEndian, bool IsMicroMips) {
80771928e68SAkira Hatanaka   // We want to read exactly 4 Bytes of data.
8087fc5b874SRafael Espindola   if (Bytes.size() < 4) {
8094aa6bea7SRafael Espindola     Size = 0;
81071928e68SAkira Hatanaka     return MCDisassembler::Fail;
81171928e68SAkira Hatanaka   }
81271928e68SAkira Hatanaka 
813ea22c4cfSJozef Kolek   // High 16 bits of a 32-bit microMIPS instruction (where the opcode is)
814ea22c4cfSJozef Kolek   // always precede the low 16 bits in the instruction stream (that is, they
815ea22c4cfSJozef Kolek   // are placed at lower addresses in the instruction stream).
816ea22c4cfSJozef Kolek   //
817ea22c4cfSJozef Kolek   // microMIPS byte ordering:
818ea22c4cfSJozef Kolek   //   Big-endian:    0 | 1 | 2 | 3
819ea22c4cfSJozef Kolek   //   Little-endian: 1 | 0 | 3 | 2
820ea22c4cfSJozef Kolek 
8214aa6bea7SRafael Espindola   if (IsBigEndian) {
82271928e68SAkira Hatanaka     // Encoded as a big-endian 32-bit word in the stream.
8234aa6bea7SRafael Espindola     Insn =
8244aa6bea7SRafael Espindola         (Bytes[3] << 0) | (Bytes[2] << 8) | (Bytes[1] << 16) | (Bytes[0] << 24);
8254aa6bea7SRafael Espindola   } else {
826dde3d582SVladimir Medic     if (IsMicroMips) {
8274aa6bea7SRafael Espindola       Insn = (Bytes[2] << 0) | (Bytes[3] << 8) | (Bytes[0] << 16) |
828dde3d582SVladimir Medic              (Bytes[1] << 24);
829dde3d582SVladimir Medic     } else {
8304aa6bea7SRafael Espindola       Insn = (Bytes[0] << 0) | (Bytes[1] << 8) | (Bytes[2] << 16) |
83171928e68SAkira Hatanaka              (Bytes[3] << 24);
83271928e68SAkira Hatanaka     }
833dde3d582SVladimir Medic   }
83471928e68SAkira Hatanaka 
83571928e68SAkira Hatanaka   return MCDisassembler::Success;
83671928e68SAkira Hatanaka }
83771928e68SAkira Hatanaka 
8384aa6bea7SRafael Espindola DecodeStatus MipsDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,
8397fc5b874SRafael Espindola                                               ArrayRef<uint8_t> Bytes,
84071928e68SAkira Hatanaka                                               uint64_t Address,
8414aa6bea7SRafael Espindola                                               raw_ostream &VStream,
8424aa6bea7SRafael Espindola                                               raw_ostream &CStream) const {
84371928e68SAkira Hatanaka   uint32_t Insn;
844ea22c4cfSJozef Kolek   DecodeStatus Result;
84571928e68SAkira Hatanaka 
846ea22c4cfSJozef Kolek   if (IsMicroMips) {
847ea22c4cfSJozef Kolek     Result = readInstruction16(Bytes, Address, Size, Insn, IsBigEndian);
848ea22c4cfSJozef Kolek 
849ea22c4cfSJozef Kolek     DEBUG(dbgs() << "Trying MicroMips16 table (16-bit instructions):\n");
850ea22c4cfSJozef Kolek     // Calling the auto-generated decoder function.
851ea22c4cfSJozef Kolek     Result = decodeInstruction(DecoderTableMicroMips16, Instr, Insn, Address,
852ea22c4cfSJozef Kolek                                this, STI);
853ea22c4cfSJozef Kolek     if (Result != MCDisassembler::Fail) {
854ea22c4cfSJozef Kolek       Size = 2;
855ea22c4cfSJozef Kolek       return Result;
856ea22c4cfSJozef Kolek     }
857ea22c4cfSJozef Kolek 
858ea22c4cfSJozef Kolek     Result = readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, true);
85971928e68SAkira Hatanaka     if (Result == MCDisassembler::Fail)
86071928e68SAkira Hatanaka       return MCDisassembler::Fail;
86171928e68SAkira Hatanaka 
862ea22c4cfSJozef Kolek     DEBUG(dbgs() << "Trying MicroMips32 table (32-bit instructions):\n");
863dde3d582SVladimir Medic     // Calling the auto-generated decoder function.
8644aa6bea7SRafael Espindola     Result = decodeInstruction(DecoderTableMicroMips32, Instr, Insn, Address,
865dde3d582SVladimir Medic                                this, STI);
866dde3d582SVladimir Medic     if (Result != MCDisassembler::Fail) {
867dde3d582SVladimir Medic       Size = 4;
868dde3d582SVladimir Medic       return Result;
869dde3d582SVladimir Medic     }
870dde3d582SVladimir Medic     return MCDisassembler::Fail;
871dde3d582SVladimir Medic   }
872dde3d582SVladimir Medic 
873ea22c4cfSJozef Kolek   Result = readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, false);
874ea22c4cfSJozef Kolek   if (Result == MCDisassembler::Fail)
875ea22c4cfSJozef Kolek     return MCDisassembler::Fail;
876ea22c4cfSJozef Kolek 
877c171f65aSDaniel Sanders   if (hasCOP3()) {
878c171f65aSDaniel Sanders     DEBUG(dbgs() << "Trying COP3_ table (32-bit opcodes):\n");
879c171f65aSDaniel Sanders     Result =
8804aa6bea7SRafael Espindola         decodeInstruction(DecoderTableCOP3_32, Instr, Insn, Address, this, STI);
881c171f65aSDaniel Sanders     if (Result != MCDisassembler::Fail) {
882c171f65aSDaniel Sanders       Size = 4;
883c171f65aSDaniel Sanders       return Result;
884c171f65aSDaniel Sanders     }
885c171f65aSDaniel Sanders   }
886c171f65aSDaniel Sanders 
887c171f65aSDaniel Sanders   if (hasMips32r6() && isGP64()) {
8880fa60416SDaniel Sanders     DEBUG(dbgs() << "Trying Mips32r6_64r6 (GPR64) table (32-bit opcodes):\n");
8894aa6bea7SRafael Espindola     Result = decodeInstruction(DecoderTableMips32r6_64r6_GP6432, Instr, Insn,
8900fa60416SDaniel Sanders                                Address, this, STI);
8910fa60416SDaniel Sanders     if (Result != MCDisassembler::Fail) {
8920fa60416SDaniel Sanders       Size = 4;
8930fa60416SDaniel Sanders       return Result;
8940fa60416SDaniel Sanders     }
8950fa60416SDaniel Sanders   }
8960fa60416SDaniel Sanders 
897c171f65aSDaniel Sanders   if (hasMips32r6()) {
8980fa60416SDaniel Sanders     DEBUG(dbgs() << "Trying Mips32r6_64r6 table (32-bit opcodes):\n");
8994aa6bea7SRafael Espindola     Result = decodeInstruction(DecoderTableMips32r6_64r632, Instr, Insn,
9005c582b2fSDaniel Sanders                                Address, this, STI);
9015c582b2fSDaniel Sanders     if (Result != MCDisassembler::Fail) {
9025c582b2fSDaniel Sanders       Size = 4;
9035c582b2fSDaniel Sanders       return Result;
9045c582b2fSDaniel Sanders     }
9055c582b2fSDaniel Sanders   }
9065c582b2fSDaniel Sanders 
9070fa60416SDaniel Sanders   DEBUG(dbgs() << "Trying Mips table (32-bit opcodes):\n");
90871928e68SAkira Hatanaka   // Calling the auto-generated decoder function.
9094aa6bea7SRafael Espindola   Result =
9104aa6bea7SRafael Espindola       decodeInstruction(DecoderTableMips32, Instr, Insn, Address, this, STI);
91171928e68SAkira Hatanaka   if (Result != MCDisassembler::Fail) {
91271928e68SAkira Hatanaka     Size = 4;
91371928e68SAkira Hatanaka     return Result;
91471928e68SAkira Hatanaka   }
91571928e68SAkira Hatanaka 
91671928e68SAkira Hatanaka   return MCDisassembler::Fail;
91771928e68SAkira Hatanaka }
91871928e68SAkira Hatanaka 
9194aa6bea7SRafael Espindola DecodeStatus Mips64Disassembler::getInstruction(MCInst &Instr, uint64_t &Size,
9207fc5b874SRafael Espindola                                                 ArrayRef<uint8_t> Bytes,
92171928e68SAkira Hatanaka                                                 uint64_t Address,
9224aa6bea7SRafael Espindola                                                 raw_ostream &VStream,
9234aa6bea7SRafael Espindola                                                 raw_ostream &CStream) const {
92471928e68SAkira Hatanaka   uint32_t Insn;
92571928e68SAkira Hatanaka 
9264aa6bea7SRafael Espindola   DecodeStatus Result =
9277fc5b874SRafael Espindola       readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, false);
92871928e68SAkira Hatanaka   if (Result == MCDisassembler::Fail)
92971928e68SAkira Hatanaka     return MCDisassembler::Fail;
93071928e68SAkira Hatanaka 
93171928e68SAkira Hatanaka   // Calling the auto-generated decoder function.
9324aa6bea7SRafael Espindola   Result =
9334aa6bea7SRafael Espindola       decodeInstruction(DecoderTableMips6432, Instr, Insn, Address, this, STI);
93471928e68SAkira Hatanaka   if (Result != MCDisassembler::Fail) {
93571928e68SAkira Hatanaka     Size = 4;
93671928e68SAkira Hatanaka     return Result;
93771928e68SAkira Hatanaka   }
93871928e68SAkira Hatanaka   // If we fail to decode in Mips64 decoder space we can try in Mips32
9394aa6bea7SRafael Espindola   Result =
9404aa6bea7SRafael Espindola       decodeInstruction(DecoderTableMips32, Instr, Insn, Address, this, STI);
94171928e68SAkira Hatanaka   if (Result != MCDisassembler::Fail) {
94271928e68SAkira Hatanaka     Size = 4;
94371928e68SAkira Hatanaka     return Result;
94471928e68SAkira Hatanaka   }
94571928e68SAkira Hatanaka 
94671928e68SAkira Hatanaka   return MCDisassembler::Fail;
94771928e68SAkira Hatanaka }
94871928e68SAkira Hatanaka 
949ec8a5490SReed Kotler static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst,
950ec8a5490SReed Kotler                                                  unsigned RegNo,
951ec8a5490SReed Kotler                                                  uint64_t Address,
952ec8a5490SReed Kotler                                                  const void *Decoder) {
953ec8a5490SReed Kotler 
954ec8a5490SReed Kotler   return MCDisassembler::Fail;
955ec8a5490SReed Kotler 
956ec8a5490SReed Kotler }
957ec8a5490SReed Kotler 
95813e6ccf3SAkira Hatanaka static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst,
95971928e68SAkira Hatanaka                                              unsigned RegNo,
96071928e68SAkira Hatanaka                                              uint64_t Address,
96171928e68SAkira Hatanaka                                              const void *Decoder) {
96271928e68SAkira Hatanaka 
96371928e68SAkira Hatanaka   if (RegNo > 31)
96471928e68SAkira Hatanaka     return MCDisassembler::Fail;
96571928e68SAkira Hatanaka 
96613e6ccf3SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::GPR64RegClassID, RegNo);
9679bf2b567SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
96871928e68SAkira Hatanaka   return MCDisassembler::Success;
96971928e68SAkira Hatanaka }
97071928e68SAkira Hatanaka 
971b0852e54SZoran Jovanovic static DecodeStatus DecodeGPRMM16RegisterClass(MCInst &Inst,
972b0852e54SZoran Jovanovic                                                unsigned RegNo,
973b0852e54SZoran Jovanovic                                                uint64_t Address,
974b0852e54SZoran Jovanovic                                                const void *Decoder) {
975ea22c4cfSJozef Kolek   if (RegNo > 7)
976b0852e54SZoran Jovanovic     return MCDisassembler::Fail;
977ea22c4cfSJozef Kolek   unsigned Reg = getReg(Decoder, Mips::GPRMM16RegClassID, RegNo);
978ea22c4cfSJozef Kolek   Inst.addOperand(MCOperand::CreateReg(Reg));
979ea22c4cfSJozef Kolek   return MCDisassembler::Success;
980b0852e54SZoran Jovanovic }
981b0852e54SZoran Jovanovic 
9821904fa21SJozef Kolek static DecodeStatus DecodeGPRMM16ZeroRegisterClass(MCInst &Inst,
9831904fa21SJozef Kolek                                                    unsigned RegNo,
9841904fa21SJozef Kolek                                                    uint64_t Address,
9851904fa21SJozef Kolek                                                    const void *Decoder) {
986315e7ecaSJozef Kolek   if (RegNo > 7)
9871904fa21SJozef Kolek     return MCDisassembler::Fail;
988315e7ecaSJozef Kolek   unsigned Reg = getReg(Decoder, Mips::GPRMM16ZeroRegClassID, RegNo);
989315e7ecaSJozef Kolek   Inst.addOperand(MCOperand::CreateReg(Reg));
990315e7ecaSJozef Kolek   return MCDisassembler::Success;
9911904fa21SJozef Kolek }
9921904fa21SJozef Kolek 
99313e6ccf3SAkira Hatanaka static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst,
99471928e68SAkira Hatanaka                                              unsigned RegNo,
99571928e68SAkira Hatanaka                                              uint64_t Address,
99671928e68SAkira Hatanaka                                              const void *Decoder) {
99771928e68SAkira Hatanaka   if (RegNo > 31)
99871928e68SAkira Hatanaka     return MCDisassembler::Fail;
99913e6ccf3SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::GPR32RegClassID, RegNo);
10009bf2b567SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
100171928e68SAkira Hatanaka   return MCDisassembler::Success;
100271928e68SAkira Hatanaka }
100371928e68SAkira Hatanaka 
10049bfa2e2eSAkira Hatanaka static DecodeStatus DecodePtrRegisterClass(MCInst &Inst,
10059bfa2e2eSAkira Hatanaka                                            unsigned RegNo,
10069bfa2e2eSAkira Hatanaka                                            uint64_t Address,
10079bfa2e2eSAkira Hatanaka                                            const void *Decoder) {
1008e8860938SVladimir Medic   if (static_cast<const MipsDisassembler *>(Decoder)->isGP64Bit())
10099bfa2e2eSAkira Hatanaka     return DecodeGPR64RegisterClass(Inst, RegNo, Address, Decoder);
10109bfa2e2eSAkira Hatanaka 
10119bfa2e2eSAkira Hatanaka   return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
10129bfa2e2eSAkira Hatanaka }
10139bfa2e2eSAkira Hatanaka 
1014654655f1SAkira Hatanaka static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst,
1015ecabd1a5SAkira Hatanaka                                             unsigned RegNo,
1016ecabd1a5SAkira Hatanaka                                             uint64_t Address,
1017ecabd1a5SAkira Hatanaka                                             const void *Decoder) {
101813e6ccf3SAkira Hatanaka   return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
1019ecabd1a5SAkira Hatanaka }
1020ecabd1a5SAkira Hatanaka 
102171928e68SAkira Hatanaka static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
102271928e68SAkira Hatanaka                                              unsigned RegNo,
102371928e68SAkira Hatanaka                                              uint64_t Address,
102471928e68SAkira Hatanaka                                              const void *Decoder) {
102571928e68SAkira Hatanaka   if (RegNo > 31)
102671928e68SAkira Hatanaka     return MCDisassembler::Fail;
102771928e68SAkira Hatanaka 
10289bf2b567SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::FGR64RegClassID, RegNo);
10299bf2b567SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
103071928e68SAkira Hatanaka   return MCDisassembler::Success;
103171928e68SAkira Hatanaka }
103271928e68SAkira Hatanaka 
103371928e68SAkira Hatanaka static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
103471928e68SAkira Hatanaka                                              unsigned RegNo,
103571928e68SAkira Hatanaka                                              uint64_t Address,
103671928e68SAkira Hatanaka                                              const void *Decoder) {
103771928e68SAkira Hatanaka   if (RegNo > 31)
103871928e68SAkira Hatanaka     return MCDisassembler::Fail;
103971928e68SAkira Hatanaka 
10409bf2b567SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::FGR32RegClassID, RegNo);
10419bf2b567SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
104271928e68SAkira Hatanaka   return MCDisassembler::Success;
104371928e68SAkira Hatanaka }
104471928e68SAkira Hatanaka 
104571928e68SAkira Hatanaka static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
104671928e68SAkira Hatanaka                                            unsigned RegNo,
104771928e68SAkira Hatanaka                                            uint64_t Address,
104871928e68SAkira Hatanaka                                            const void *Decoder) {
1049253777fdSChad Rosier   if (RegNo > 31)
1050253777fdSChad Rosier     return MCDisassembler::Fail;
1051253777fdSChad Rosier   unsigned Reg = getReg(Decoder, Mips::CCRRegClassID, RegNo);
1052253777fdSChad Rosier   Inst.addOperand(MCOperand::CreateReg(Reg));
105371928e68SAkira Hatanaka   return MCDisassembler::Success;
105471928e68SAkira Hatanaka }
105571928e68SAkira Hatanaka 
10561fb1b8b8SAkira Hatanaka static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst,
10571fb1b8b8SAkira Hatanaka                                            unsigned RegNo,
10581fb1b8b8SAkira Hatanaka                                            uint64_t Address,
10591fb1b8b8SAkira Hatanaka                                            const void *Decoder) {
10601fb1b8b8SAkira Hatanaka   if (RegNo > 7)
10611fb1b8b8SAkira Hatanaka     return MCDisassembler::Fail;
10621fb1b8b8SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::FCCRegClassID, RegNo);
10631fb1b8b8SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
10641fb1b8b8SAkira Hatanaka   return MCDisassembler::Success;
10651fb1b8b8SAkira Hatanaka }
10661fb1b8b8SAkira Hatanaka 
10670fa60416SDaniel Sanders static DecodeStatus DecodeFGRCCRegisterClass(MCInst &Inst, unsigned RegNo,
10680fa60416SDaniel Sanders                                              uint64_t Address,
10690fa60416SDaniel Sanders                                              const void *Decoder) {
10700fa60416SDaniel Sanders   if (RegNo > 31)
10710fa60416SDaniel Sanders     return MCDisassembler::Fail;
10720fa60416SDaniel Sanders 
10730fa60416SDaniel Sanders   unsigned Reg = getReg(Decoder, Mips::FGRCCRegClassID, RegNo);
10740fa60416SDaniel Sanders   Inst.addOperand(MCOperand::CreateReg(Reg));
10750fa60416SDaniel Sanders   return MCDisassembler::Success;
10760fa60416SDaniel Sanders }
10770fa60416SDaniel Sanders 
107871928e68SAkira Hatanaka static DecodeStatus DecodeMem(MCInst &Inst,
107971928e68SAkira Hatanaka                               unsigned Insn,
108071928e68SAkira Hatanaka                               uint64_t Address,
108171928e68SAkira Hatanaka                               const void *Decoder) {
108271928e68SAkira Hatanaka   int Offset = SignExtend32<16>(Insn & 0xffff);
1083ecaef49fSJim Grosbach   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1084ecaef49fSJim Grosbach   unsigned Base = fieldFromInstruction(Insn, 21, 5);
10859bf2b567SAkira Hatanaka 
108613e6ccf3SAkira Hatanaka   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
108713e6ccf3SAkira Hatanaka   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
108871928e68SAkira Hatanaka 
1089d7ecf49eSVladimir Medic   if(Inst.getOpcode() == Mips::SC ||
1090d7ecf49eSVladimir Medic      Inst.getOpcode() == Mips::SCD){
10919bf2b567SAkira Hatanaka     Inst.addOperand(MCOperand::CreateReg(Reg));
109271928e68SAkira Hatanaka   }
109371928e68SAkira Hatanaka 
10949bf2b567SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
10959bf2b567SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Base));
109671928e68SAkira Hatanaka   Inst.addOperand(MCOperand::CreateImm(Offset));
109771928e68SAkira Hatanaka 
109871928e68SAkira Hatanaka   return MCDisassembler::Success;
109971928e68SAkira Hatanaka }
110071928e68SAkira Hatanaka 
110192db6b78SDaniel Sanders static DecodeStatus DecodeCacheOp(MCInst &Inst,
110292db6b78SDaniel Sanders                               unsigned Insn,
110392db6b78SDaniel Sanders                               uint64_t Address,
110492db6b78SDaniel Sanders                               const void *Decoder) {
110592db6b78SDaniel Sanders   int Offset = SignExtend32<16>(Insn & 0xffff);
110692db6b78SDaniel Sanders   unsigned Hint = fieldFromInstruction(Insn, 16, 5);
110792db6b78SDaniel Sanders   unsigned Base = fieldFromInstruction(Insn, 21, 5);
110892db6b78SDaniel Sanders 
110992db6b78SDaniel Sanders   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
111092db6b78SDaniel Sanders 
111192db6b78SDaniel Sanders   Inst.addOperand(MCOperand::CreateReg(Base));
111292db6b78SDaniel Sanders   Inst.addOperand(MCOperand::CreateImm(Offset));
111392db6b78SDaniel Sanders   Inst.addOperand(MCOperand::CreateImm(Hint));
111492db6b78SDaniel Sanders 
111592db6b78SDaniel Sanders   return MCDisassembler::Success;
111692db6b78SDaniel Sanders }
111792db6b78SDaniel Sanders 
1118ab6d1cceSJozef Kolek static DecodeStatus DecodeCacheOpMM(MCInst &Inst,
1119ab6d1cceSJozef Kolek                                     unsigned Insn,
1120ab6d1cceSJozef Kolek                                     uint64_t Address,
1121ab6d1cceSJozef Kolek                                     const void *Decoder) {
1122ab6d1cceSJozef Kolek   int Offset = SignExtend32<12>(Insn & 0xfff);
1123ab6d1cceSJozef Kolek   unsigned Base = fieldFromInstruction(Insn, 16, 5);
1124ab6d1cceSJozef Kolek   unsigned Hint = fieldFromInstruction(Insn, 21, 5);
1125ab6d1cceSJozef Kolek 
1126ab6d1cceSJozef Kolek   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1127ab6d1cceSJozef Kolek 
1128ab6d1cceSJozef Kolek   Inst.addOperand(MCOperand::CreateReg(Base));
1129ab6d1cceSJozef Kolek   Inst.addOperand(MCOperand::CreateImm(Offset));
1130ab6d1cceSJozef Kolek   Inst.addOperand(MCOperand::CreateImm(Hint));
1131ab6d1cceSJozef Kolek 
1132ab6d1cceSJozef Kolek   return MCDisassembler::Success;
1133ab6d1cceSJozef Kolek }
1134ab6d1cceSJozef Kolek 
1135b4484d62SDaniel Sanders static DecodeStatus DecodeSyncI(MCInst &Inst,
1136b4484d62SDaniel Sanders                               unsigned Insn,
1137b4484d62SDaniel Sanders                               uint64_t Address,
1138b4484d62SDaniel Sanders                               const void *Decoder) {
1139b4484d62SDaniel Sanders   int Offset = SignExtend32<16>(Insn & 0xffff);
1140b4484d62SDaniel Sanders   unsigned Base = fieldFromInstruction(Insn, 21, 5);
1141b4484d62SDaniel Sanders 
1142b4484d62SDaniel Sanders   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1143b4484d62SDaniel Sanders 
1144b4484d62SDaniel Sanders   Inst.addOperand(MCOperand::CreateReg(Base));
1145b4484d62SDaniel Sanders   Inst.addOperand(MCOperand::CreateImm(Offset));
1146b4484d62SDaniel Sanders 
1147b4484d62SDaniel Sanders   return MCDisassembler::Success;
1148b4484d62SDaniel Sanders }
1149b4484d62SDaniel Sanders 
1150fe0bf9f6SMatheus Almeida static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn,
1151fe0bf9f6SMatheus Almeida                                     uint64_t Address, const void *Decoder) {
1152fe0bf9f6SMatheus Almeida   int Offset = SignExtend32<10>(fieldFromInstruction(Insn, 16, 10));
1153fe0bf9f6SMatheus Almeida   unsigned Reg = fieldFromInstruction(Insn, 6, 5);
1154fe0bf9f6SMatheus Almeida   unsigned Base = fieldFromInstruction(Insn, 11, 5);
1155fe0bf9f6SMatheus Almeida 
1156fe0bf9f6SMatheus Almeida   Reg = getReg(Decoder, Mips::MSA128BRegClassID, Reg);
1157fe0bf9f6SMatheus Almeida   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1158fe0bf9f6SMatheus Almeida 
1159fe0bf9f6SMatheus Almeida   Inst.addOperand(MCOperand::CreateReg(Reg));
1160fe0bf9f6SMatheus Almeida   Inst.addOperand(MCOperand::CreateReg(Base));
11616b59c449SMatheus Almeida 
11626b59c449SMatheus Almeida   // The immediate field of an LD/ST instruction is scaled which means it must
11636b59c449SMatheus Almeida   // be multiplied (when decoding) by the size (in bytes) of the instructions'
11646b59c449SMatheus Almeida   // data format.
11656b59c449SMatheus Almeida   // .b - 1 byte
11666b59c449SMatheus Almeida   // .h - 2 bytes
11676b59c449SMatheus Almeida   // .w - 4 bytes
11686b59c449SMatheus Almeida   // .d - 8 bytes
11696b59c449SMatheus Almeida   switch(Inst.getOpcode())
11706b59c449SMatheus Almeida   {
11716b59c449SMatheus Almeida   default:
11726b59c449SMatheus Almeida     assert (0 && "Unexpected instruction");
11736b59c449SMatheus Almeida     return MCDisassembler::Fail;
11746b59c449SMatheus Almeida     break;
11756b59c449SMatheus Almeida   case Mips::LD_B:
11766b59c449SMatheus Almeida   case Mips::ST_B:
1177fe0bf9f6SMatheus Almeida     Inst.addOperand(MCOperand::CreateImm(Offset));
11786b59c449SMatheus Almeida     break;
11796b59c449SMatheus Almeida   case Mips::LD_H:
11806b59c449SMatheus Almeida   case Mips::ST_H:
1181d37bab61SAlexey Samsonov     Inst.addOperand(MCOperand::CreateImm(Offset * 2));
11826b59c449SMatheus Almeida     break;
11836b59c449SMatheus Almeida   case Mips::LD_W:
11846b59c449SMatheus Almeida   case Mips::ST_W:
1185d37bab61SAlexey Samsonov     Inst.addOperand(MCOperand::CreateImm(Offset * 4));
11866b59c449SMatheus Almeida     break;
11876b59c449SMatheus Almeida   case Mips::LD_D:
11886b59c449SMatheus Almeida   case Mips::ST_D:
1189d37bab61SAlexey Samsonov     Inst.addOperand(MCOperand::CreateImm(Offset * 8));
11906b59c449SMatheus Almeida     break;
11916b59c449SMatheus Almeida   }
1192fe0bf9f6SMatheus Almeida 
1193fe0bf9f6SMatheus Almeida   return MCDisassembler::Success;
1194fe0bf9f6SMatheus Almeida }
1195fe0bf9f6SMatheus Almeida 
1196315e7ecaSJozef Kolek static DecodeStatus DecodeMemMMImm4(MCInst &Inst,
1197315e7ecaSJozef Kolek                                     unsigned Insn,
1198315e7ecaSJozef Kolek                                     uint64_t Address,
1199315e7ecaSJozef Kolek                                     const void *Decoder) {
1200315e7ecaSJozef Kolek   unsigned Offset = Insn & 0xf;
1201315e7ecaSJozef Kolek   unsigned Reg = fieldFromInstruction(Insn, 7, 3);
1202315e7ecaSJozef Kolek   unsigned Base = fieldFromInstruction(Insn, 4, 3);
1203315e7ecaSJozef Kolek 
1204315e7ecaSJozef Kolek   switch (Inst.getOpcode()) {
1205315e7ecaSJozef Kolek     case Mips::LBU16_MM:
1206315e7ecaSJozef Kolek     case Mips::LHU16_MM:
1207315e7ecaSJozef Kolek     case Mips::LW16_MM:
1208315e7ecaSJozef Kolek       if (DecodeGPRMM16RegisterClass(Inst, Reg, Address, Decoder)
1209315e7ecaSJozef Kolek             == MCDisassembler::Fail)
1210315e7ecaSJozef Kolek         return MCDisassembler::Fail;
1211315e7ecaSJozef Kolek       break;
1212315e7ecaSJozef Kolek     case Mips::SB16_MM:
1213315e7ecaSJozef Kolek     case Mips::SH16_MM:
1214315e7ecaSJozef Kolek     case Mips::SW16_MM:
1215315e7ecaSJozef Kolek       if (DecodeGPRMM16ZeroRegisterClass(Inst, Reg, Address, Decoder)
1216315e7ecaSJozef Kolek             == MCDisassembler::Fail)
1217315e7ecaSJozef Kolek         return MCDisassembler::Fail;
1218315e7ecaSJozef Kolek       break;
1219315e7ecaSJozef Kolek   }
1220315e7ecaSJozef Kolek 
1221315e7ecaSJozef Kolek   if (DecodeGPRMM16RegisterClass(Inst, Base, Address, Decoder)
1222315e7ecaSJozef Kolek         == MCDisassembler::Fail)
1223315e7ecaSJozef Kolek     return MCDisassembler::Fail;
1224315e7ecaSJozef Kolek 
1225315e7ecaSJozef Kolek   switch (Inst.getOpcode()) {
1226315e7ecaSJozef Kolek     case Mips::LBU16_MM:
1227315e7ecaSJozef Kolek       if (Offset == 0xf)
1228315e7ecaSJozef Kolek         Inst.addOperand(MCOperand::CreateImm(-1));
1229315e7ecaSJozef Kolek       else
1230315e7ecaSJozef Kolek         Inst.addOperand(MCOperand::CreateImm(Offset));
1231315e7ecaSJozef Kolek       break;
1232315e7ecaSJozef Kolek     case Mips::SB16_MM:
1233315e7ecaSJozef Kolek       Inst.addOperand(MCOperand::CreateImm(Offset));
1234315e7ecaSJozef Kolek       break;
1235315e7ecaSJozef Kolek     case Mips::LHU16_MM:
1236315e7ecaSJozef Kolek     case Mips::SH16_MM:
1237315e7ecaSJozef Kolek       Inst.addOperand(MCOperand::CreateImm(Offset << 1));
1238315e7ecaSJozef Kolek       break;
1239315e7ecaSJozef Kolek     case Mips::LW16_MM:
1240315e7ecaSJozef Kolek     case Mips::SW16_MM:
1241315e7ecaSJozef Kolek       Inst.addOperand(MCOperand::CreateImm(Offset << 2));
1242315e7ecaSJozef Kolek       break;
1243315e7ecaSJozef Kolek   }
1244315e7ecaSJozef Kolek 
1245315e7ecaSJozef Kolek   return MCDisassembler::Success;
1246315e7ecaSJozef Kolek }
1247315e7ecaSJozef Kolek 
124812c6982bSJozef Kolek static DecodeStatus DecodeMemMMSPImm5Lsl2(MCInst &Inst,
124912c6982bSJozef Kolek                                           unsigned Insn,
125012c6982bSJozef Kolek                                           uint64_t Address,
125112c6982bSJozef Kolek                                           const void *Decoder) {
125212c6982bSJozef Kolek   unsigned Offset = Insn & 0x1F;
125312c6982bSJozef Kolek   unsigned Reg = fieldFromInstruction(Insn, 5, 5);
125412c6982bSJozef Kolek 
125512c6982bSJozef Kolek   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
125612c6982bSJozef Kolek 
125712c6982bSJozef Kolek   Inst.addOperand(MCOperand::CreateReg(Reg));
125812c6982bSJozef Kolek   Inst.addOperand(MCOperand::CreateReg(Mips::SP));
125912c6982bSJozef Kolek   Inst.addOperand(MCOperand::CreateImm(Offset << 2));
126012c6982bSJozef Kolek 
126112c6982bSJozef Kolek   return MCDisassembler::Success;
126212c6982bSJozef Kolek }
126312c6982bSJozef Kolek 
1264dde3d582SVladimir Medic static DecodeStatus DecodeMemMMImm12(MCInst &Inst,
1265dde3d582SVladimir Medic                                      unsigned Insn,
1266dde3d582SVladimir Medic                                      uint64_t Address,
1267dde3d582SVladimir Medic                                      const void *Decoder) {
1268dde3d582SVladimir Medic   int Offset = SignExtend32<12>(Insn & 0x0fff);
1269dde3d582SVladimir Medic   unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1270dde3d582SVladimir Medic   unsigned Base = fieldFromInstruction(Insn, 16, 5);
1271dde3d582SVladimir Medic 
1272dde3d582SVladimir Medic   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1273dde3d582SVladimir Medic   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1274dde3d582SVladimir Medic 
1275a4c4b5fcSZoran Jovanovic   switch (Inst.getOpcode()) {
1276a4c4b5fcSZoran Jovanovic   case Mips::SWM32_MM:
1277a4c4b5fcSZoran Jovanovic   case Mips::LWM32_MM:
1278a4c4b5fcSZoran Jovanovic     if (DecodeRegListOperand(Inst, Insn, Address, Decoder)
1279a4c4b5fcSZoran Jovanovic         == MCDisassembler::Fail)
1280a4c4b5fcSZoran Jovanovic       return MCDisassembler::Fail;
1281a4c4b5fcSZoran Jovanovic     Inst.addOperand(MCOperand::CreateReg(Base));
1282a4c4b5fcSZoran Jovanovic     Inst.addOperand(MCOperand::CreateImm(Offset));
1283a4c4b5fcSZoran Jovanovic     break;
1284a4c4b5fcSZoran Jovanovic   case Mips::SC_MM:
1285285cc289SZoran Jovanovic     Inst.addOperand(MCOperand::CreateReg(Reg));
1286a4c4b5fcSZoran Jovanovic     // fallthrough
1287a4c4b5fcSZoran Jovanovic   default:
1288dde3d582SVladimir Medic     Inst.addOperand(MCOperand::CreateReg(Reg));
12892deca348SZoran Jovanovic     if (Inst.getOpcode() == Mips::LWP_MM || Inst.getOpcode() == Mips::SWP_MM)
12902deca348SZoran Jovanovic       Inst.addOperand(MCOperand::CreateReg(Reg+1));
12912deca348SZoran Jovanovic 
1292dde3d582SVladimir Medic     Inst.addOperand(MCOperand::CreateReg(Base));
1293dde3d582SVladimir Medic     Inst.addOperand(MCOperand::CreateImm(Offset));
1294a4c4b5fcSZoran Jovanovic   }
1295dde3d582SVladimir Medic 
1296dde3d582SVladimir Medic   return MCDisassembler::Success;
1297dde3d582SVladimir Medic }
1298dde3d582SVladimir Medic 
1299dde3d582SVladimir Medic static DecodeStatus DecodeMemMMImm16(MCInst &Inst,
1300dde3d582SVladimir Medic                                      unsigned Insn,
1301dde3d582SVladimir Medic                                      uint64_t Address,
1302dde3d582SVladimir Medic                                      const void *Decoder) {
1303dde3d582SVladimir Medic   int Offset = SignExtend32<16>(Insn & 0xffff);
1304dde3d582SVladimir Medic   unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1305dde3d582SVladimir Medic   unsigned Base = fieldFromInstruction(Insn, 16, 5);
1306dde3d582SVladimir Medic 
1307dde3d582SVladimir Medic   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1308dde3d582SVladimir Medic   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1309dde3d582SVladimir Medic 
1310dde3d582SVladimir Medic   Inst.addOperand(MCOperand::CreateReg(Reg));
1311dde3d582SVladimir Medic   Inst.addOperand(MCOperand::CreateReg(Base));
1312dde3d582SVladimir Medic   Inst.addOperand(MCOperand::CreateImm(Offset));
1313dde3d582SVladimir Medic 
1314dde3d582SVladimir Medic   return MCDisassembler::Success;
1315dde3d582SVladimir Medic }
1316dde3d582SVladimir Medic 
131771928e68SAkira Hatanaka static DecodeStatus DecodeFMem(MCInst &Inst,
131871928e68SAkira Hatanaka                                unsigned Insn,
131971928e68SAkira Hatanaka                                uint64_t Address,
132071928e68SAkira Hatanaka                                const void *Decoder) {
132171928e68SAkira Hatanaka   int Offset = SignExtend32<16>(Insn & 0xffff);
1322ecaef49fSJim Grosbach   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1323ecaef49fSJim Grosbach   unsigned Base = fieldFromInstruction(Insn, 21, 5);
132471928e68SAkira Hatanaka 
13259bf2b567SAkira Hatanaka   Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg);
132613e6ccf3SAkira Hatanaka   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
13279bf2b567SAkira Hatanaka 
13289bf2b567SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
13299bf2b567SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Base));
133071928e68SAkira Hatanaka   Inst.addOperand(MCOperand::CreateImm(Offset));
133171928e68SAkira Hatanaka 
133271928e68SAkira Hatanaka   return MCDisassembler::Success;
133371928e68SAkira Hatanaka }
133471928e68SAkira Hatanaka 
133592db6b78SDaniel Sanders static DecodeStatus DecodeFMem2(MCInst &Inst,
133692db6b78SDaniel Sanders                                unsigned Insn,
133792db6b78SDaniel Sanders                                uint64_t Address,
133892db6b78SDaniel Sanders                                const void *Decoder) {
133992db6b78SDaniel Sanders   int Offset = SignExtend32<16>(Insn & 0xffff);
134092db6b78SDaniel Sanders   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
134192db6b78SDaniel Sanders   unsigned Base = fieldFromInstruction(Insn, 21, 5);
134292db6b78SDaniel Sanders 
134392db6b78SDaniel Sanders   Reg = getReg(Decoder, Mips::COP2RegClassID, Reg);
134492db6b78SDaniel Sanders   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
134592db6b78SDaniel Sanders 
134692db6b78SDaniel Sanders   Inst.addOperand(MCOperand::CreateReg(Reg));
134792db6b78SDaniel Sanders   Inst.addOperand(MCOperand::CreateReg(Base));
134892db6b78SDaniel Sanders   Inst.addOperand(MCOperand::CreateImm(Offset));
134992db6b78SDaniel Sanders 
135092db6b78SDaniel Sanders   return MCDisassembler::Success;
135192db6b78SDaniel Sanders }
135292db6b78SDaniel Sanders 
135392db6b78SDaniel Sanders static DecodeStatus DecodeFMem3(MCInst &Inst,
135492db6b78SDaniel Sanders                                unsigned Insn,
135592db6b78SDaniel Sanders                                uint64_t Address,
135692db6b78SDaniel Sanders                                const void *Decoder) {
135792db6b78SDaniel Sanders   int Offset = SignExtend32<16>(Insn & 0xffff);
135892db6b78SDaniel Sanders   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
135992db6b78SDaniel Sanders   unsigned Base = fieldFromInstruction(Insn, 21, 5);
136092db6b78SDaniel Sanders 
136192db6b78SDaniel Sanders   Reg = getReg(Decoder, Mips::COP3RegClassID, Reg);
136292db6b78SDaniel Sanders   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
136392db6b78SDaniel Sanders 
136492db6b78SDaniel Sanders   Inst.addOperand(MCOperand::CreateReg(Reg));
136592db6b78SDaniel Sanders   Inst.addOperand(MCOperand::CreateReg(Base));
136692db6b78SDaniel Sanders   Inst.addOperand(MCOperand::CreateImm(Offset));
136792db6b78SDaniel Sanders 
136892db6b78SDaniel Sanders   return MCDisassembler::Success;
136992db6b78SDaniel Sanders }
137092db6b78SDaniel Sanders 
1371435cf8a4SVladimir Medic static DecodeStatus DecodeFMemCop2R6(MCInst &Inst,
1372435cf8a4SVladimir Medic                                     unsigned Insn,
1373435cf8a4SVladimir Medic                                     uint64_t Address,
1374435cf8a4SVladimir Medic                                     const void *Decoder) {
1375435cf8a4SVladimir Medic   int Offset = SignExtend32<11>(Insn & 0x07ff);
1376435cf8a4SVladimir Medic   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1377435cf8a4SVladimir Medic   unsigned Base = fieldFromInstruction(Insn, 11, 5);
1378435cf8a4SVladimir Medic 
1379435cf8a4SVladimir Medic   Reg = getReg(Decoder, Mips::COP2RegClassID, Reg);
1380435cf8a4SVladimir Medic   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1381435cf8a4SVladimir Medic 
1382435cf8a4SVladimir Medic   Inst.addOperand(MCOperand::CreateReg(Reg));
1383435cf8a4SVladimir Medic   Inst.addOperand(MCOperand::CreateReg(Base));
1384435cf8a4SVladimir Medic   Inst.addOperand(MCOperand::CreateImm(Offset));
1385435cf8a4SVladimir Medic 
1386435cf8a4SVladimir Medic   return MCDisassembler::Success;
1387435cf8a4SVladimir Medic }
13886a803f61SDaniel Sanders static DecodeStatus DecodeSpecial3LlSc(MCInst &Inst,
13896a803f61SDaniel Sanders                                        unsigned Insn,
13906a803f61SDaniel Sanders                                        uint64_t Address,
13916a803f61SDaniel Sanders                                        const void *Decoder) {
13926a803f61SDaniel Sanders   int64_t Offset = SignExtend64<9>((Insn >> 7) & 0x1ff);
13936a803f61SDaniel Sanders   unsigned Rt = fieldFromInstruction(Insn, 16, 5);
13946a803f61SDaniel Sanders   unsigned Base = fieldFromInstruction(Insn, 21, 5);
13956a803f61SDaniel Sanders 
13966a803f61SDaniel Sanders   Rt = getReg(Decoder, Mips::GPR32RegClassID, Rt);
13976a803f61SDaniel Sanders   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
13986a803f61SDaniel Sanders 
13996a803f61SDaniel Sanders   if(Inst.getOpcode() == Mips::SC_R6 || Inst.getOpcode() == Mips::SCD_R6){
14006a803f61SDaniel Sanders     Inst.addOperand(MCOperand::CreateReg(Rt));
14016a803f61SDaniel Sanders   }
14026a803f61SDaniel Sanders 
14036a803f61SDaniel Sanders   Inst.addOperand(MCOperand::CreateReg(Rt));
14046a803f61SDaniel Sanders   Inst.addOperand(MCOperand::CreateReg(Base));
14056a803f61SDaniel Sanders   Inst.addOperand(MCOperand::CreateImm(Offset));
14066a803f61SDaniel Sanders 
14076a803f61SDaniel Sanders   return MCDisassembler::Success;
14086a803f61SDaniel Sanders }
140971928e68SAkira Hatanaka 
141071928e68SAkira Hatanaka static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
141171928e68SAkira Hatanaka                                               unsigned RegNo,
141271928e68SAkira Hatanaka                                               uint64_t Address,
141371928e68SAkira Hatanaka                                               const void *Decoder) {
141471928e68SAkira Hatanaka   // Currently only hardware register 29 is supported.
141571928e68SAkira Hatanaka   if (RegNo != 29)
141671928e68SAkira Hatanaka     return  MCDisassembler::Fail;
141771928e68SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Mips::HWR29));
141871928e68SAkira Hatanaka   return MCDisassembler::Success;
141971928e68SAkira Hatanaka }
142071928e68SAkira Hatanaka 
142171928e68SAkira Hatanaka static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
142271928e68SAkira Hatanaka                                               unsigned RegNo,
142371928e68SAkira Hatanaka                                               uint64_t Address,
142471928e68SAkira Hatanaka                                               const void *Decoder) {
14259bf2b567SAkira Hatanaka   if (RegNo > 30 || RegNo %2)
142671928e68SAkira Hatanaka     return MCDisassembler::Fail;
142771928e68SAkira Hatanaka 
14289bf2b567SAkira Hatanaka   ;
14299bf2b567SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::AFGR64RegClassID, RegNo /2);
14309bf2b567SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
143171928e68SAkira Hatanaka   return MCDisassembler::Success;
143271928e68SAkira Hatanaka }
143371928e68SAkira Hatanaka 
143400fcf2e1SAkira Hatanaka static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst,
1435ecabd1a5SAkira Hatanaka                                                 unsigned RegNo,
1436ecabd1a5SAkira Hatanaka                                                 uint64_t Address,
1437ecabd1a5SAkira Hatanaka                                                 const void *Decoder) {
1438ecabd1a5SAkira Hatanaka   if (RegNo >= 4)
1439ecabd1a5SAkira Hatanaka     return MCDisassembler::Fail;
1440ecabd1a5SAkira Hatanaka 
144100fcf2e1SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::ACC64DSPRegClassID, RegNo);
1442ecabd1a5SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
1443ecabd1a5SAkira Hatanaka   return MCDisassembler::Success;
1444ecabd1a5SAkira Hatanaka }
1445ecabd1a5SAkira Hatanaka 
14468002a3f6SAkira Hatanaka static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst,
144759bfaf77SAkira Hatanaka                                                unsigned RegNo,
144859bfaf77SAkira Hatanaka                                                uint64_t Address,
144959bfaf77SAkira Hatanaka                                                const void *Decoder) {
145059bfaf77SAkira Hatanaka   if (RegNo >= 4)
145159bfaf77SAkira Hatanaka     return MCDisassembler::Fail;
145259bfaf77SAkira Hatanaka 
14538002a3f6SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::HI32DSPRegClassID, RegNo);
145459bfaf77SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
145559bfaf77SAkira Hatanaka   return MCDisassembler::Success;
145659bfaf77SAkira Hatanaka }
145759bfaf77SAkira Hatanaka 
14588002a3f6SAkira Hatanaka static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst,
145959bfaf77SAkira Hatanaka                                                unsigned RegNo,
146059bfaf77SAkira Hatanaka                                                uint64_t Address,
146159bfaf77SAkira Hatanaka                                                const void *Decoder) {
146259bfaf77SAkira Hatanaka   if (RegNo >= 4)
146359bfaf77SAkira Hatanaka     return MCDisassembler::Fail;
146459bfaf77SAkira Hatanaka 
14658002a3f6SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::LO32DSPRegClassID, RegNo);
146659bfaf77SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
146759bfaf77SAkira Hatanaka   return MCDisassembler::Success;
146859bfaf77SAkira Hatanaka }
146959bfaf77SAkira Hatanaka 
14703eb663b0SJack Carter static DecodeStatus DecodeMSA128BRegisterClass(MCInst &Inst,
14713eb663b0SJack Carter                                                unsigned RegNo,
14723eb663b0SJack Carter                                                uint64_t Address,
14733eb663b0SJack Carter                                                const void *Decoder) {
14743eb663b0SJack Carter   if (RegNo > 31)
14753eb663b0SJack Carter     return MCDisassembler::Fail;
14763eb663b0SJack Carter 
14773eb663b0SJack Carter   unsigned Reg = getReg(Decoder, Mips::MSA128BRegClassID, RegNo);
14783eb663b0SJack Carter   Inst.addOperand(MCOperand::CreateReg(Reg));
14793eb663b0SJack Carter   return MCDisassembler::Success;
14803eb663b0SJack Carter }
14813eb663b0SJack Carter 
14825dc8ac92SJack Carter static DecodeStatus DecodeMSA128HRegisterClass(MCInst &Inst,
14835dc8ac92SJack Carter                                                unsigned RegNo,
14845dc8ac92SJack Carter                                                uint64_t Address,
14855dc8ac92SJack Carter                                                const void *Decoder) {
14865dc8ac92SJack Carter   if (RegNo > 31)
14875dc8ac92SJack Carter     return MCDisassembler::Fail;
14885dc8ac92SJack Carter 
14895dc8ac92SJack Carter   unsigned Reg = getReg(Decoder, Mips::MSA128HRegClassID, RegNo);
14905dc8ac92SJack Carter   Inst.addOperand(MCOperand::CreateReg(Reg));
14915dc8ac92SJack Carter   return MCDisassembler::Success;
14925dc8ac92SJack Carter }
14935dc8ac92SJack Carter 
14945dc8ac92SJack Carter static DecodeStatus DecodeMSA128WRegisterClass(MCInst &Inst,
14955dc8ac92SJack Carter                                                unsigned RegNo,
14965dc8ac92SJack Carter                                                uint64_t Address,
14975dc8ac92SJack Carter                                                const void *Decoder) {
14985dc8ac92SJack Carter   if (RegNo > 31)
14995dc8ac92SJack Carter     return MCDisassembler::Fail;
15005dc8ac92SJack Carter 
15015dc8ac92SJack Carter   unsigned Reg = getReg(Decoder, Mips::MSA128WRegClassID, RegNo);
15025dc8ac92SJack Carter   Inst.addOperand(MCOperand::CreateReg(Reg));
15035dc8ac92SJack Carter   return MCDisassembler::Success;
15045dc8ac92SJack Carter }
15055dc8ac92SJack Carter 
15065dc8ac92SJack Carter static DecodeStatus DecodeMSA128DRegisterClass(MCInst &Inst,
15075dc8ac92SJack Carter                                                unsigned RegNo,
15085dc8ac92SJack Carter                                                uint64_t Address,
15095dc8ac92SJack Carter                                                const void *Decoder) {
15105dc8ac92SJack Carter   if (RegNo > 31)
15115dc8ac92SJack Carter     return MCDisassembler::Fail;
15125dc8ac92SJack Carter 
15135dc8ac92SJack Carter   unsigned Reg = getReg(Decoder, Mips::MSA128DRegClassID, RegNo);
15145dc8ac92SJack Carter   Inst.addOperand(MCOperand::CreateReg(Reg));
15155dc8ac92SJack Carter   return MCDisassembler::Success;
15165dc8ac92SJack Carter }
15175dc8ac92SJack Carter 
1518a591fdc6SMatheus Almeida static DecodeStatus DecodeMSACtrlRegisterClass(MCInst &Inst,
1519a591fdc6SMatheus Almeida                                                unsigned RegNo,
1520a591fdc6SMatheus Almeida                                                uint64_t Address,
1521a591fdc6SMatheus Almeida                                                const void *Decoder) {
1522a591fdc6SMatheus Almeida   if (RegNo > 7)
1523a591fdc6SMatheus Almeida     return MCDisassembler::Fail;
1524a591fdc6SMatheus Almeida 
1525a591fdc6SMatheus Almeida   unsigned Reg = getReg(Decoder, Mips::MSACtrlRegClassID, RegNo);
1526a591fdc6SMatheus Almeida   Inst.addOperand(MCOperand::CreateReg(Reg));
1527a591fdc6SMatheus Almeida   return MCDisassembler::Success;
1528a591fdc6SMatheus Almeida }
1529a591fdc6SMatheus Almeida 
15302a83d680SDaniel Sanders static DecodeStatus DecodeCOP2RegisterClass(MCInst &Inst,
15312a83d680SDaniel Sanders                                             unsigned RegNo,
15322a83d680SDaniel Sanders                                             uint64_t Address,
15332a83d680SDaniel Sanders                                             const void *Decoder) {
15342a83d680SDaniel Sanders   if (RegNo > 31)
15352a83d680SDaniel Sanders     return MCDisassembler::Fail;
15362a83d680SDaniel Sanders 
15372a83d680SDaniel Sanders   unsigned Reg = getReg(Decoder, Mips::COP2RegClassID, RegNo);
15382a83d680SDaniel Sanders   Inst.addOperand(MCOperand::CreateReg(Reg));
15392a83d680SDaniel Sanders   return MCDisassembler::Success;
15402a83d680SDaniel Sanders }
15412a83d680SDaniel Sanders 
154271928e68SAkira Hatanaka static DecodeStatus DecodeBranchTarget(MCInst &Inst,
154371928e68SAkira Hatanaka                                        unsigned Offset,
154471928e68SAkira Hatanaka                                        uint64_t Address,
154571928e68SAkira Hatanaka                                        const void *Decoder) {
1546d37bab61SAlexey Samsonov   int32_t BranchOffset = (SignExtend32<16>(Offset) * 4) + 4;
154771928e68SAkira Hatanaka   Inst.addOperand(MCOperand::CreateImm(BranchOffset));
154871928e68SAkira Hatanaka   return MCDisassembler::Success;
154971928e68SAkira Hatanaka }
155071928e68SAkira Hatanaka 
155171928e68SAkira Hatanaka static DecodeStatus DecodeJumpTarget(MCInst &Inst,
155271928e68SAkira Hatanaka                                      unsigned Insn,
155371928e68SAkira Hatanaka                                      uint64_t Address,
155471928e68SAkira Hatanaka                                      const void *Decoder) {
155571928e68SAkira Hatanaka 
1556ecaef49fSJim Grosbach   unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 2;
155771928e68SAkira Hatanaka   Inst.addOperand(MCOperand::CreateImm(JumpOffset));
155871928e68SAkira Hatanaka   return MCDisassembler::Success;
155971928e68SAkira Hatanaka }
156071928e68SAkira Hatanaka 
15613c8869dcSZoran Jovanovic static DecodeStatus DecodeBranchTarget21(MCInst &Inst,
15623c8869dcSZoran Jovanovic                                          unsigned Offset,
15633c8869dcSZoran Jovanovic                                          uint64_t Address,
15643c8869dcSZoran Jovanovic                                          const void *Decoder) {
1565d37bab61SAlexey Samsonov   int32_t BranchOffset = SignExtend32<21>(Offset) * 4;
15663c8869dcSZoran Jovanovic 
15673c8869dcSZoran Jovanovic   Inst.addOperand(MCOperand::CreateImm(BranchOffset));
15683c8869dcSZoran Jovanovic   return MCDisassembler::Success;
15693c8869dcSZoran Jovanovic }
15703c8869dcSZoran Jovanovic 
15713c8869dcSZoran Jovanovic static DecodeStatus DecodeBranchTarget26(MCInst &Inst,
15723c8869dcSZoran Jovanovic                                          unsigned Offset,
15733c8869dcSZoran Jovanovic                                          uint64_t Address,
15743c8869dcSZoran Jovanovic                                          const void *Decoder) {
1575d37bab61SAlexey Samsonov   int32_t BranchOffset = SignExtend32<26>(Offset) * 4;
15763c8869dcSZoran Jovanovic 
15773c8869dcSZoran Jovanovic   Inst.addOperand(MCOperand::CreateImm(BranchOffset));
15783c8869dcSZoran Jovanovic   return MCDisassembler::Success;
15793c8869dcSZoran Jovanovic }
15803c8869dcSZoran Jovanovic 
15819761e96bSJozef Kolek static DecodeStatus DecodeBranchTarget7MM(MCInst &Inst,
15829761e96bSJozef Kolek                                           unsigned Offset,
15839761e96bSJozef Kolek                                           uint64_t Address,
15849761e96bSJozef Kolek                                           const void *Decoder) {
15859761e96bSJozef Kolek   int32_t BranchOffset = SignExtend32<7>(Offset) << 1;
15869761e96bSJozef Kolek   Inst.addOperand(MCOperand::CreateImm(BranchOffset));
15879761e96bSJozef Kolek   return MCDisassembler::Success;
15889761e96bSJozef Kolek }
15899761e96bSJozef Kolek 
1590*5cfebddeSJozef Kolek static DecodeStatus DecodeBranchTarget10MM(MCInst &Inst,
1591*5cfebddeSJozef Kolek                                            unsigned Offset,
1592*5cfebddeSJozef Kolek                                            uint64_t Address,
1593*5cfebddeSJozef Kolek                                            const void *Decoder) {
1594*5cfebddeSJozef Kolek   int32_t BranchOffset = SignExtend32<10>(Offset) << 1;
1595*5cfebddeSJozef Kolek   Inst.addOperand(MCOperand::CreateImm(BranchOffset));
1596*5cfebddeSJozef Kolek   return MCDisassembler::Success;
1597*5cfebddeSJozef Kolek }
1598*5cfebddeSJozef Kolek 
15998a80aa76SZoran Jovanovic static DecodeStatus DecodeBranchTargetMM(MCInst &Inst,
16008a80aa76SZoran Jovanovic                                          unsigned Offset,
16018a80aa76SZoran Jovanovic                                          uint64_t Address,
16028a80aa76SZoran Jovanovic                                          const void *Decoder) {
1603d37bab61SAlexey Samsonov   int32_t BranchOffset = SignExtend32<16>(Offset) * 2;
16048a80aa76SZoran Jovanovic   Inst.addOperand(MCOperand::CreateImm(BranchOffset));
16058a80aa76SZoran Jovanovic   return MCDisassembler::Success;
16068a80aa76SZoran Jovanovic }
16078a80aa76SZoran Jovanovic 
1608507e084aSZoran Jovanovic static DecodeStatus DecodeJumpTargetMM(MCInst &Inst,
1609507e084aSZoran Jovanovic                                        unsigned Insn,
1610507e084aSZoran Jovanovic                                        uint64_t Address,
1611507e084aSZoran Jovanovic                                        const void *Decoder) {
1612507e084aSZoran Jovanovic   unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 1;
1613507e084aSZoran Jovanovic   Inst.addOperand(MCOperand::CreateImm(JumpOffset));
1614507e084aSZoran Jovanovic   return MCDisassembler::Success;
1615507e084aSZoran Jovanovic }
161671928e68SAkira Hatanaka 
1617aa2b9278SJozef Kolek static DecodeStatus DecodeAddiur2Simm7(MCInst &Inst,
1618aa2b9278SJozef Kolek                                        unsigned Value,
1619aa2b9278SJozef Kolek                                        uint64_t Address,
1620aa2b9278SJozef Kolek                                        const void *Decoder) {
1621aa2b9278SJozef Kolek   if (Value == 0)
1622aa2b9278SJozef Kolek     Inst.addOperand(MCOperand::CreateImm(1));
1623aa2b9278SJozef Kolek   else if (Value == 0x7)
1624aa2b9278SJozef Kolek     Inst.addOperand(MCOperand::CreateImm(-1));
1625aa2b9278SJozef Kolek   else
1626aa2b9278SJozef Kolek     Inst.addOperand(MCOperand::CreateImm(Value << 2));
1627aa2b9278SJozef Kolek   return MCDisassembler::Success;
1628aa2b9278SJozef Kolek }
1629aa2b9278SJozef Kolek 
1630aa2b9278SJozef Kolek static DecodeStatus DecodeUImm6Lsl2(MCInst &Inst,
1631aa2b9278SJozef Kolek                                     unsigned Value,
1632aa2b9278SJozef Kolek                                     uint64_t Address,
1633aa2b9278SJozef Kolek                                     const void *Decoder) {
1634aa2b9278SJozef Kolek   Inst.addOperand(MCOperand::CreateImm(Value << 2));
1635aa2b9278SJozef Kolek   return MCDisassembler::Success;
1636aa2b9278SJozef Kolek }
1637aa2b9278SJozef Kolek 
1638aa2b9278SJozef Kolek static DecodeStatus DecodeLiSimm7(MCInst &Inst,
1639aa2b9278SJozef Kolek                                   unsigned Value,
1640aa2b9278SJozef Kolek                                   uint64_t Address,
1641aa2b9278SJozef Kolek                                   const void *Decoder) {
1642aa2b9278SJozef Kolek   if (Value == 0x7F)
1643aa2b9278SJozef Kolek     Inst.addOperand(MCOperand::CreateImm(-1));
1644aa2b9278SJozef Kolek   else
1645aa2b9278SJozef Kolek     Inst.addOperand(MCOperand::CreateImm(Value));
1646aa2b9278SJozef Kolek   return MCDisassembler::Success;
1647aa2b9278SJozef Kolek }
1648aa2b9278SJozef Kolek 
1649aa2b9278SJozef Kolek static DecodeStatus DecodeSimm4(MCInst &Inst,
1650aa2b9278SJozef Kolek                                 unsigned Value,
1651aa2b9278SJozef Kolek                                 uint64_t Address,
1652aa2b9278SJozef Kolek                                 const void *Decoder) {
1653aa2b9278SJozef Kolek   Inst.addOperand(MCOperand::CreateImm(SignExtend32<4>(Value)));
1654aa2b9278SJozef Kolek   return MCDisassembler::Success;
1655aa2b9278SJozef Kolek }
1656aa2b9278SJozef Kolek 
165771928e68SAkira Hatanaka static DecodeStatus DecodeSimm16(MCInst &Inst,
165871928e68SAkira Hatanaka                                  unsigned Insn,
165971928e68SAkira Hatanaka                                  uint64_t Address,
166071928e68SAkira Hatanaka                                  const void *Decoder) {
166171928e68SAkira Hatanaka   Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Insn)));
166271928e68SAkira Hatanaka   return MCDisassembler::Success;
166371928e68SAkira Hatanaka }
166471928e68SAkira Hatanaka 
1665779c5937SMatheus Almeida static DecodeStatus DecodeLSAImm(MCInst &Inst,
1666779c5937SMatheus Almeida                                  unsigned Insn,
1667779c5937SMatheus Almeida                                  uint64_t Address,
1668779c5937SMatheus Almeida                                  const void *Decoder) {
1669779c5937SMatheus Almeida   // We add one to the immediate field as it was encoded as 'imm - 1'.
1670779c5937SMatheus Almeida   Inst.addOperand(MCOperand::CreateImm(Insn + 1));
1671779c5937SMatheus Almeida   return MCDisassembler::Success;
1672779c5937SMatheus Almeida }
1673779c5937SMatheus Almeida 
167471928e68SAkira Hatanaka static DecodeStatus DecodeInsSize(MCInst &Inst,
167571928e68SAkira Hatanaka                                   unsigned Insn,
167671928e68SAkira Hatanaka                                   uint64_t Address,
167771928e68SAkira Hatanaka                                   const void *Decoder) {
167871928e68SAkira Hatanaka   // First we need to grab the pos(lsb) from MCInst.
167971928e68SAkira Hatanaka   int Pos = Inst.getOperand(2).getImm();
168071928e68SAkira Hatanaka   int Size = (int) Insn - Pos + 1;
168171928e68SAkira Hatanaka   Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size)));
168271928e68SAkira Hatanaka   return MCDisassembler::Success;
168371928e68SAkira Hatanaka }
168471928e68SAkira Hatanaka 
168571928e68SAkira Hatanaka static DecodeStatus DecodeExtSize(MCInst &Inst,
168671928e68SAkira Hatanaka                                   unsigned Insn,
168771928e68SAkira Hatanaka                                   uint64_t Address,
168871928e68SAkira Hatanaka                                   const void *Decoder) {
168971928e68SAkira Hatanaka   int Size = (int) Insn  + 1;
169071928e68SAkira Hatanaka   Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size)));
169171928e68SAkira Hatanaka   return MCDisassembler::Success;
169271928e68SAkira Hatanaka }
1693b59e1a41SDaniel Sanders 
1694b59e1a41SDaniel Sanders static DecodeStatus DecodeSimm19Lsl2(MCInst &Inst, unsigned Insn,
1695b59e1a41SDaniel Sanders                                      uint64_t Address, const void *Decoder) {
1696d37bab61SAlexey Samsonov   Inst.addOperand(MCOperand::CreateImm(SignExtend32<19>(Insn) * 4));
1697b59e1a41SDaniel Sanders   return MCDisassembler::Success;
1698b59e1a41SDaniel Sanders }
16992855142aSZoran Jovanovic 
17002855142aSZoran Jovanovic static DecodeStatus DecodeSimm18Lsl3(MCInst &Inst, unsigned Insn,
17012855142aSZoran Jovanovic                                      uint64_t Address, const void *Decoder) {
1702d37bab61SAlexey Samsonov   Inst.addOperand(MCOperand::CreateImm(SignExtend32<18>(Insn) * 8));
17032855142aSZoran Jovanovic   return MCDisassembler::Success;
17042855142aSZoran Jovanovic }
1705a4c4b5fcSZoran Jovanovic 
1706b682ddf3SVladimir Medic static DecodeStatus DecodeSimm9SP(MCInst &Inst, unsigned Insn,
1707b682ddf3SVladimir Medic                                   uint64_t Address, const void *Decoder) {
1708b682ddf3SVladimir Medic   int32_t DecodedValue;
1709b682ddf3SVladimir Medic   switch (Insn) {
1710b682ddf3SVladimir Medic   case 0: DecodedValue = 256; break;
1711b682ddf3SVladimir Medic   case 1: DecodedValue = 257; break;
1712b682ddf3SVladimir Medic   case 510: DecodedValue = -258; break;
1713b682ddf3SVladimir Medic   case 511: DecodedValue = -257; break;
1714b682ddf3SVladimir Medic   default: DecodedValue = SignExtend32<9>(Insn); break;
1715b682ddf3SVladimir Medic   }
17162c55974dSAlexey Samsonov   Inst.addOperand(MCOperand::CreateImm(DecodedValue * 4));
1717b682ddf3SVladimir Medic   return MCDisassembler::Success;
1718b682ddf3SVladimir Medic }
1719b682ddf3SVladimir Medic 
1720b682ddf3SVladimir Medic static DecodeStatus DecodeANDI16Imm(MCInst &Inst, unsigned Insn,
1721b682ddf3SVladimir Medic                                     uint64_t Address, const void *Decoder) {
1722b682ddf3SVladimir Medic   // Insn must be >= 0, since it is unsigned that condition is always true.
1723b682ddf3SVladimir Medic   assert(Insn < 16);
1724b682ddf3SVladimir Medic   int32_t DecodedValues[] = {128, 1, 2, 3, 4, 7, 8, 15, 16, 31, 32, 63, 64,
1725b682ddf3SVladimir Medic                              255, 32768, 65535};
1726b682ddf3SVladimir Medic   Inst.addOperand(MCOperand::CreateImm(DecodedValues[Insn]));
1727b682ddf3SVladimir Medic   return MCDisassembler::Success;
1728b682ddf3SVladimir Medic }
1729b682ddf3SVladimir Medic 
1730b682ddf3SVladimir Medic static DecodeStatus DecodeUImm5lsl2(MCInst &Inst, unsigned Insn,
1731b682ddf3SVladimir Medic                                     uint64_t Address, const void *Decoder) {
1732b682ddf3SVladimir Medic   Inst.addOperand(MCOperand::CreateImm(Insn << 2));
1733b682ddf3SVladimir Medic   return MCDisassembler::Success;
1734b682ddf3SVladimir Medic }
1735b682ddf3SVladimir Medic 
1736a4c4b5fcSZoran Jovanovic static DecodeStatus DecodeRegListOperand(MCInst &Inst,
1737a4c4b5fcSZoran Jovanovic                                          unsigned Insn,
1738a4c4b5fcSZoran Jovanovic                                          uint64_t Address,
1739a4c4b5fcSZoran Jovanovic                                          const void *Decoder) {
1740a4c4b5fcSZoran Jovanovic   unsigned Regs[] = {Mips::S0, Mips::S1, Mips::S2, Mips::S3, Mips::S4, Mips::S5,
1741a4c4b5fcSZoran Jovanovic                      Mips::S6, Mips::FP};
1742a4c4b5fcSZoran Jovanovic   unsigned RegNum;
1743a4c4b5fcSZoran Jovanovic 
1744a4c4b5fcSZoran Jovanovic   unsigned RegLst = fieldFromInstruction(Insn, 21, 5);
1745a4c4b5fcSZoran Jovanovic   // Empty register lists are not allowed.
1746a4c4b5fcSZoran Jovanovic   if (RegLst == 0)
1747a4c4b5fcSZoran Jovanovic     return MCDisassembler::Fail;
1748a4c4b5fcSZoran Jovanovic 
1749a4c4b5fcSZoran Jovanovic   RegNum = RegLst & 0xf;
1750a4c4b5fcSZoran Jovanovic   for (unsigned i = 0; i < RegNum; i++)
1751a4c4b5fcSZoran Jovanovic     Inst.addOperand(MCOperand::CreateReg(Regs[i]));
1752a4c4b5fcSZoran Jovanovic 
1753a4c4b5fcSZoran Jovanovic   if (RegLst & 0x10)
1754a4c4b5fcSZoran Jovanovic     Inst.addOperand(MCOperand::CreateReg(Mips::RA));
1755a4c4b5fcSZoran Jovanovic 
1756a4c4b5fcSZoran Jovanovic   return MCDisassembler::Success;
1757a4c4b5fcSZoran Jovanovic }
1758f9a02500SZoran Jovanovic 
1759f9a02500SZoran Jovanovic static DecodeStatus DecodeRegListOperand16(MCInst &Inst, unsigned Insn,
1760f9a02500SZoran Jovanovic                                            uint64_t Address,
1761f9a02500SZoran Jovanovic                                            const void *Decoder) {
1762f9a02500SZoran Jovanovic   unsigned Regs[] = {Mips::S0, Mips::S1, Mips::S2, Mips::S3};
1763f9a02500SZoran Jovanovic   unsigned RegNum;
1764f9a02500SZoran Jovanovic 
1765f9a02500SZoran Jovanovic   unsigned RegLst = fieldFromInstruction(Insn, 4, 2);
1766f9a02500SZoran Jovanovic   // Empty register lists are not allowed.
1767f9a02500SZoran Jovanovic   if (RegLst == 0)
1768f9a02500SZoran Jovanovic     return MCDisassembler::Fail;
1769f9a02500SZoran Jovanovic 
1770f9a02500SZoran Jovanovic   RegNum = RegLst & 0x3;
1771f9a02500SZoran Jovanovic   for (unsigned i = 0; i < RegNum - 1; i++)
1772f9a02500SZoran Jovanovic     Inst.addOperand(MCOperand::CreateReg(Regs[i]));
1773f9a02500SZoran Jovanovic 
1774f9a02500SZoran Jovanovic   Inst.addOperand(MCOperand::CreateReg(Mips::RA));
1775f9a02500SZoran Jovanovic 
1776f9a02500SZoran Jovanovic   return MCDisassembler::Success;
1777f9a02500SZoran Jovanovic }
17782c6d7320SJozef Kolek 
17792c6d7320SJozef Kolek static DecodeStatus DecodeSimm23Lsl2(MCInst &Inst, unsigned Insn,
17802c6d7320SJozef Kolek                                      uint64_t Address, const void *Decoder) {
17812c6d7320SJozef Kolek   Inst.addOperand(MCOperand::CreateImm(SignExtend32<23>(Insn) << 2));
17822c6d7320SJozef Kolek   return MCDisassembler::Success;
17832c6d7320SJozef Kolek }
1784