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 
334ea2f606SAlexei Starovoitov /// A disassembler 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 
524ea2f606SAlexei Starovoitov /// A disassembler 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 
804ea2f606SAlexei Starovoitov /// A disassembler 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 
2385cfebddeSJozef Kolek // DecodeBranchTarget10MM - Decode microMIPS branch offset, which is
2395cfebddeSJozef Kolek // shifted left by 1 bit.
2405cfebddeSJozef Kolek static DecodeStatus DecodeBranchTarget10MM(MCInst &Inst,
2415cfebddeSJozef Kolek                                            unsigned Offset,
2425cfebddeSJozef Kolek                                            uint64_t Address,
2435cfebddeSJozef Kolek                                            const void *Decoder);
2445cfebddeSJozef 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 
269*df464ae2SVladimir Medic static DecodeStatus DecodeCacheOpR6(MCInst &Inst,
270*df464ae2SVladimir Medic                                     unsigned Insn,
271*df464ae2SVladimir Medic                                     uint64_t Address,
272*df464ae2SVladimir Medic                                     const void *Decoder);
273*df464ae2SVladimir Medic 
274ab6d1cceSJozef Kolek static DecodeStatus DecodeCacheOpMM(MCInst &Inst,
275ab6d1cceSJozef Kolek                                     unsigned Insn,
276ab6d1cceSJozef Kolek                                     uint64_t Address,
277ab6d1cceSJozef Kolek                                     const void *Decoder);
278ab6d1cceSJozef Kolek 
279b4484d62SDaniel Sanders static DecodeStatus DecodeSyncI(MCInst &Inst,
280b4484d62SDaniel Sanders                                 unsigned Insn,
281b4484d62SDaniel Sanders                                 uint64_t Address,
282b4484d62SDaniel Sanders                                 const void *Decoder);
283b4484d62SDaniel Sanders 
284fe0bf9f6SMatheus Almeida static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn,
285fe0bf9f6SMatheus Almeida                                     uint64_t Address, const void *Decoder);
286fe0bf9f6SMatheus Almeida 
287315e7ecaSJozef Kolek static DecodeStatus DecodeMemMMImm4(MCInst &Inst,
288315e7ecaSJozef Kolek                                     unsigned Insn,
289315e7ecaSJozef Kolek                                     uint64_t Address,
290315e7ecaSJozef Kolek                                     const void *Decoder);
291315e7ecaSJozef Kolek 
29212c6982bSJozef Kolek static DecodeStatus DecodeMemMMSPImm5Lsl2(MCInst &Inst,
29312c6982bSJozef Kolek                                           unsigned Insn,
29412c6982bSJozef Kolek                                           uint64_t Address,
29512c6982bSJozef Kolek                                           const void *Decoder);
29612c6982bSJozef Kolek 
297e10a02ecSJozef Kolek static DecodeStatus DecodeMemMMGPImm7Lsl2(MCInst &Inst,
298e10a02ecSJozef Kolek                                           unsigned Insn,
299e10a02ecSJozef Kolek                                           uint64_t Address,
300e10a02ecSJozef Kolek                                           const void *Decoder);
301e10a02ecSJozef Kolek 
302dde3d582SVladimir Medic static DecodeStatus DecodeMemMMImm12(MCInst &Inst,
303dde3d582SVladimir Medic                                      unsigned Insn,
304dde3d582SVladimir Medic                                      uint64_t Address,
305dde3d582SVladimir Medic                                      const void *Decoder);
306dde3d582SVladimir Medic 
307dde3d582SVladimir Medic static DecodeStatus DecodeMemMMImm16(MCInst &Inst,
308dde3d582SVladimir Medic                                      unsigned Insn,
309dde3d582SVladimir Medic                                      uint64_t Address,
310dde3d582SVladimir Medic                                      const void *Decoder);
311dde3d582SVladimir Medic 
31271928e68SAkira Hatanaka static DecodeStatus DecodeFMem(MCInst &Inst, unsigned Insn,
31371928e68SAkira Hatanaka                                uint64_t Address,
31471928e68SAkira Hatanaka                                const void *Decoder);
31571928e68SAkira Hatanaka 
31692db6b78SDaniel Sanders static DecodeStatus DecodeFMem2(MCInst &Inst, unsigned Insn,
31792db6b78SDaniel Sanders                                uint64_t Address,
31892db6b78SDaniel Sanders                                const void *Decoder);
31992db6b78SDaniel Sanders 
32092db6b78SDaniel Sanders static DecodeStatus DecodeFMem3(MCInst &Inst, unsigned Insn,
32192db6b78SDaniel Sanders                                uint64_t Address,
32292db6b78SDaniel Sanders                                const void *Decoder);
32392db6b78SDaniel Sanders 
324435cf8a4SVladimir Medic static DecodeStatus DecodeFMemCop2R6(MCInst &Inst, unsigned Insn,
325435cf8a4SVladimir Medic                                uint64_t Address,
326435cf8a4SVladimir Medic                                const void *Decoder);
327435cf8a4SVladimir Medic 
3286a803f61SDaniel Sanders static DecodeStatus DecodeSpecial3LlSc(MCInst &Inst,
3296a803f61SDaniel Sanders                                        unsigned Insn,
3306a803f61SDaniel Sanders                                        uint64_t Address,
3316a803f61SDaniel Sanders                                        const void *Decoder);
3326a803f61SDaniel Sanders 
333aa2b9278SJozef Kolek static DecodeStatus DecodeAddiur2Simm7(MCInst &Inst,
334aa2b9278SJozef Kolek                                        unsigned Value,
335aa2b9278SJozef Kolek                                        uint64_t Address,
336aa2b9278SJozef Kolek                                        const void *Decoder);
337aa2b9278SJozef Kolek 
338aa2b9278SJozef Kolek static DecodeStatus DecodeUImm6Lsl2(MCInst &Inst,
339aa2b9278SJozef Kolek                                     unsigned Value,
340aa2b9278SJozef Kolek                                     uint64_t Address,
341aa2b9278SJozef Kolek                                     const void *Decoder);
342aa2b9278SJozef Kolek 
343aa2b9278SJozef Kolek static DecodeStatus DecodeLiSimm7(MCInst &Inst,
344aa2b9278SJozef Kolek                                   unsigned Value,
345aa2b9278SJozef Kolek                                   uint64_t Address,
346aa2b9278SJozef Kolek                                   const void *Decoder);
347aa2b9278SJozef Kolek 
348aa2b9278SJozef Kolek static DecodeStatus DecodeSimm4(MCInst &Inst,
349aa2b9278SJozef Kolek                                 unsigned Value,
350aa2b9278SJozef Kolek                                 uint64_t Address,
351aa2b9278SJozef Kolek                                 const void *Decoder);
352aa2b9278SJozef Kolek 
35371928e68SAkira Hatanaka static DecodeStatus DecodeSimm16(MCInst &Inst,
35471928e68SAkira Hatanaka                                  unsigned Insn,
35571928e68SAkira Hatanaka                                  uint64_t Address,
35671928e68SAkira Hatanaka                                  const void *Decoder);
35771928e68SAkira Hatanaka 
358779c5937SMatheus Almeida // Decode the immediate field of an LSA instruction which
359779c5937SMatheus Almeida // is off by one.
360779c5937SMatheus Almeida static DecodeStatus DecodeLSAImm(MCInst &Inst,
361779c5937SMatheus Almeida                                  unsigned Insn,
362779c5937SMatheus Almeida                                  uint64_t Address,
363779c5937SMatheus Almeida                                  const void *Decoder);
364779c5937SMatheus Almeida 
36571928e68SAkira Hatanaka static DecodeStatus DecodeInsSize(MCInst &Inst,
36671928e68SAkira Hatanaka                                   unsigned Insn,
36771928e68SAkira Hatanaka                                   uint64_t Address,
36871928e68SAkira Hatanaka                                   const void *Decoder);
36971928e68SAkira Hatanaka 
37071928e68SAkira Hatanaka static DecodeStatus DecodeExtSize(MCInst &Inst,
37171928e68SAkira Hatanaka                                   unsigned Insn,
37271928e68SAkira Hatanaka                                   uint64_t Address,
37371928e68SAkira Hatanaka                                   const void *Decoder);
37471928e68SAkira Hatanaka 
375b59e1a41SDaniel Sanders static DecodeStatus DecodeSimm19Lsl2(MCInst &Inst, unsigned Insn,
376b59e1a41SDaniel Sanders                                      uint64_t Address, const void *Decoder);
377b59e1a41SDaniel Sanders 
3782855142aSZoran Jovanovic static DecodeStatus DecodeSimm18Lsl3(MCInst &Inst, unsigned Insn,
3792855142aSZoran Jovanovic                                      uint64_t Address, const void *Decoder);
3802855142aSZoran Jovanovic 
381b682ddf3SVladimir Medic static DecodeStatus DecodeSimm9SP(MCInst &Inst, unsigned Insn,
382b682ddf3SVladimir Medic                                   uint64_t Address, const void *Decoder);
383b682ddf3SVladimir Medic 
384b682ddf3SVladimir Medic static DecodeStatus DecodeANDI16Imm(MCInst &Inst, unsigned Insn,
385b682ddf3SVladimir Medic                                     uint64_t Address, const void *Decoder);
386b682ddf3SVladimir Medic 
387b682ddf3SVladimir Medic static DecodeStatus DecodeUImm5lsl2(MCInst &Inst, unsigned Insn,
388b682ddf3SVladimir Medic                                    uint64_t Address, const void *Decoder);
389b682ddf3SVladimir Medic 
3902c6d7320SJozef Kolek static DecodeStatus DecodeSimm23Lsl2(MCInst &Inst, unsigned Insn,
3912c6d7320SJozef Kolek                                      uint64_t Address, const void *Decoder);
3922c6d7320SJozef Kolek 
393b50ccf8eSDaniel Sanders /// INSVE_[BHWD] have an implicit operand that the generated decoder doesn't
394b50ccf8eSDaniel Sanders /// handle.
395b50ccf8eSDaniel Sanders template <typename InsnType>
396b50ccf8eSDaniel Sanders static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address,
397b50ccf8eSDaniel Sanders                                    const void *Decoder);
3985c582b2fSDaniel Sanders 
3995c582b2fSDaniel Sanders template <typename InsnType>
4005c582b2fSDaniel Sanders static DecodeStatus
4015c582b2fSDaniel Sanders DecodeAddiGroupBranch(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 DecodeDaddiGroupBranch(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 DecodeBlezlGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
4125c582b2fSDaniel Sanders                        const void *Decoder);
4135c582b2fSDaniel Sanders 
4145c582b2fSDaniel Sanders template <typename InsnType>
4155c582b2fSDaniel Sanders static DecodeStatus
4165c582b2fSDaniel Sanders DecodeBgtzlGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
4175c582b2fSDaniel Sanders                        const void *Decoder);
4185c582b2fSDaniel Sanders 
4195c582b2fSDaniel Sanders template <typename InsnType>
4205c582b2fSDaniel Sanders static DecodeStatus
4215c582b2fSDaniel Sanders DecodeBgtzGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
4225c582b2fSDaniel Sanders                       const void *Decoder);
4235c582b2fSDaniel Sanders 
42428a0ca07SZoran Jovanovic template <typename InsnType>
42528a0ca07SZoran Jovanovic static DecodeStatus
42628a0ca07SZoran Jovanovic DecodeBlezGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
42728a0ca07SZoran Jovanovic                        const void *Decoder);
42828a0ca07SZoran Jovanovic 
429a4c4b5fcSZoran Jovanovic static DecodeStatus DecodeRegListOperand(MCInst &Inst, unsigned Insn,
430a4c4b5fcSZoran Jovanovic                                          uint64_t Address,
431a4c4b5fcSZoran Jovanovic                                          const void *Decoder);
432a4c4b5fcSZoran Jovanovic 
433f9a02500SZoran Jovanovic static DecodeStatus DecodeRegListOperand16(MCInst &Inst, unsigned Insn,
434f9a02500SZoran Jovanovic                                            uint64_t Address,
435f9a02500SZoran Jovanovic                                            const void *Decoder);
436f9a02500SZoran Jovanovic 
43771928e68SAkira Hatanaka namespace llvm {
43871928e68SAkira Hatanaka extern Target TheMipselTarget, TheMipsTarget, TheMips64Target,
43971928e68SAkira Hatanaka               TheMips64elTarget;
44071928e68SAkira Hatanaka }
44171928e68SAkira Hatanaka 
44271928e68SAkira Hatanaka static MCDisassembler *createMipsDisassembler(
44371928e68SAkira Hatanaka                        const Target &T,
444a1bc0f56SLang Hames                        const MCSubtargetInfo &STI,
445a1bc0f56SLang Hames                        MCContext &Ctx) {
446a1bc0f56SLang Hames   return new MipsDisassembler(STI, Ctx, true);
44771928e68SAkira Hatanaka }
44871928e68SAkira Hatanaka 
44971928e68SAkira Hatanaka static MCDisassembler *createMipselDisassembler(
45071928e68SAkira Hatanaka                        const Target &T,
451a1bc0f56SLang Hames                        const MCSubtargetInfo &STI,
452a1bc0f56SLang Hames                        MCContext &Ctx) {
453a1bc0f56SLang Hames   return new MipsDisassembler(STI, Ctx, false);
45471928e68SAkira Hatanaka }
45571928e68SAkira Hatanaka 
45671928e68SAkira Hatanaka static MCDisassembler *createMips64Disassembler(
45771928e68SAkira Hatanaka                        const Target &T,
458a1bc0f56SLang Hames                        const MCSubtargetInfo &STI,
459a1bc0f56SLang Hames                        MCContext &Ctx) {
460a1bc0f56SLang Hames   return new Mips64Disassembler(STI, Ctx, true);
46171928e68SAkira Hatanaka }
46271928e68SAkira Hatanaka 
46371928e68SAkira Hatanaka static MCDisassembler *createMips64elDisassembler(
46471928e68SAkira Hatanaka                        const Target &T,
465a1bc0f56SLang Hames                        const MCSubtargetInfo &STI,
466a1bc0f56SLang Hames                        MCContext &Ctx) {
467a1bc0f56SLang Hames   return new Mips64Disassembler(STI, Ctx, false);
46871928e68SAkira Hatanaka }
46971928e68SAkira Hatanaka 
47071928e68SAkira Hatanaka extern "C" void LLVMInitializeMipsDisassembler() {
47171928e68SAkira Hatanaka   // Register the disassembler.
47271928e68SAkira Hatanaka   TargetRegistry::RegisterMCDisassembler(TheMipsTarget,
47371928e68SAkira Hatanaka                                          createMipsDisassembler);
47471928e68SAkira Hatanaka   TargetRegistry::RegisterMCDisassembler(TheMipselTarget,
47571928e68SAkira Hatanaka                                          createMipselDisassembler);
47671928e68SAkira Hatanaka   TargetRegistry::RegisterMCDisassembler(TheMips64Target,
47771928e68SAkira Hatanaka                                          createMips64Disassembler);
47871928e68SAkira Hatanaka   TargetRegistry::RegisterMCDisassembler(TheMips64elTarget,
47971928e68SAkira Hatanaka                                          createMips64elDisassembler);
48071928e68SAkira Hatanaka }
48171928e68SAkira Hatanaka 
48271928e68SAkira Hatanaka #include "MipsGenDisassemblerTables.inc"
48371928e68SAkira Hatanaka 
4845c582b2fSDaniel Sanders static unsigned getReg(const void *D, unsigned RC, unsigned RegNo) {
4855c582b2fSDaniel Sanders   const MipsDisassemblerBase *Dis = static_cast<const MipsDisassemblerBase*>(D);
4865c582b2fSDaniel Sanders   const MCRegisterInfo *RegInfo = Dis->getContext().getRegisterInfo();
4875c582b2fSDaniel Sanders   return *(RegInfo->getRegClass(RC).begin() + RegNo);
4885c582b2fSDaniel Sanders }
4895c582b2fSDaniel Sanders 
490b50ccf8eSDaniel Sanders template <typename InsnType>
491b50ccf8eSDaniel Sanders static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address,
492b50ccf8eSDaniel Sanders                                    const void *Decoder) {
493b50ccf8eSDaniel Sanders   typedef DecodeStatus (*DecodeFN)(MCInst &, unsigned, uint64_t, const void *);
494b50ccf8eSDaniel Sanders   // The size of the n field depends on the element size
495b50ccf8eSDaniel Sanders   // The register class also depends on this.
496b50ccf8eSDaniel Sanders   InsnType tmp = fieldFromInstruction(insn, 17, 5);
497b50ccf8eSDaniel Sanders   unsigned NSize = 0;
498b50ccf8eSDaniel Sanders   DecodeFN RegDecoder = nullptr;
499b50ccf8eSDaniel Sanders   if ((tmp & 0x18) == 0x00) { // INSVE_B
500b50ccf8eSDaniel Sanders     NSize = 4;
501b50ccf8eSDaniel Sanders     RegDecoder = DecodeMSA128BRegisterClass;
502b50ccf8eSDaniel Sanders   } else if ((tmp & 0x1c) == 0x10) { // INSVE_H
503b50ccf8eSDaniel Sanders     NSize = 3;
504b50ccf8eSDaniel Sanders     RegDecoder = DecodeMSA128HRegisterClass;
505b50ccf8eSDaniel Sanders   } else if ((tmp & 0x1e) == 0x18) { // INSVE_W
506b50ccf8eSDaniel Sanders     NSize = 2;
507b50ccf8eSDaniel Sanders     RegDecoder = DecodeMSA128WRegisterClass;
508b50ccf8eSDaniel Sanders   } else if ((tmp & 0x1f) == 0x1c) { // INSVE_D
509b50ccf8eSDaniel Sanders     NSize = 1;
510b50ccf8eSDaniel Sanders     RegDecoder = DecodeMSA128DRegisterClass;
511b50ccf8eSDaniel Sanders   } else
512b50ccf8eSDaniel Sanders     llvm_unreachable("Invalid encoding");
513b50ccf8eSDaniel Sanders 
514b50ccf8eSDaniel Sanders   assert(NSize != 0 && RegDecoder != nullptr);
515b50ccf8eSDaniel Sanders 
516b50ccf8eSDaniel Sanders   // $wd
517b50ccf8eSDaniel Sanders   tmp = fieldFromInstruction(insn, 6, 5);
518b50ccf8eSDaniel Sanders   if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
519b50ccf8eSDaniel Sanders     return MCDisassembler::Fail;
520b50ccf8eSDaniel Sanders   // $wd_in
521b50ccf8eSDaniel Sanders   if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
522b50ccf8eSDaniel Sanders     return MCDisassembler::Fail;
523b50ccf8eSDaniel Sanders   // $n
524b50ccf8eSDaniel Sanders   tmp = fieldFromInstruction(insn, 16, NSize);
525b50ccf8eSDaniel Sanders   MI.addOperand(MCOperand::CreateImm(tmp));
526b50ccf8eSDaniel Sanders   // $ws
527b50ccf8eSDaniel Sanders   tmp = fieldFromInstruction(insn, 11, 5);
528b50ccf8eSDaniel Sanders   if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
529b50ccf8eSDaniel Sanders     return MCDisassembler::Fail;
530b50ccf8eSDaniel Sanders   // $n2
531b50ccf8eSDaniel Sanders   MI.addOperand(MCOperand::CreateImm(0));
532b50ccf8eSDaniel Sanders 
533b50ccf8eSDaniel Sanders   return MCDisassembler::Success;
534b50ccf8eSDaniel Sanders }
535b50ccf8eSDaniel Sanders 
5365c582b2fSDaniel Sanders template <typename InsnType>
5375c582b2fSDaniel Sanders static DecodeStatus DecodeAddiGroupBranch(MCInst &MI, InsnType insn,
5385c582b2fSDaniel Sanders                                           uint64_t Address,
5395c582b2fSDaniel Sanders                                           const void *Decoder) {
5405c582b2fSDaniel Sanders   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
5415c582b2fSDaniel Sanders   // (otherwise we would have matched the ADDI instruction from the earlier
5425c582b2fSDaniel Sanders   // ISA's instead).
5435c582b2fSDaniel Sanders   //
5445c582b2fSDaniel Sanders   // We have:
5455c582b2fSDaniel Sanders   //    0b001000 sssss ttttt iiiiiiiiiiiiiiii
5465c582b2fSDaniel Sanders   //      BOVC if rs >= rt
5475c582b2fSDaniel Sanders   //      BEQZALC if rs == 0 && rt != 0
5485c582b2fSDaniel Sanders   //      BEQC if rs < rt && rs != 0
5495c582b2fSDaniel Sanders 
5505c582b2fSDaniel Sanders   InsnType Rs = fieldFromInstruction(insn, 21, 5);
5515c582b2fSDaniel Sanders   InsnType Rt = fieldFromInstruction(insn, 16, 5);
552d37bab61SAlexey Samsonov   InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4;
5535c582b2fSDaniel Sanders   bool HasRs = false;
5545c582b2fSDaniel Sanders 
5555c582b2fSDaniel Sanders   if (Rs >= Rt) {
5565c582b2fSDaniel Sanders     MI.setOpcode(Mips::BOVC);
5575c582b2fSDaniel Sanders     HasRs = true;
5585c582b2fSDaniel Sanders   } else if (Rs != 0 && Rs < Rt) {
5595c582b2fSDaniel Sanders     MI.setOpcode(Mips::BEQC);
5605c582b2fSDaniel Sanders     HasRs = true;
5615c582b2fSDaniel Sanders   } else
5625c582b2fSDaniel Sanders     MI.setOpcode(Mips::BEQZALC);
5635c582b2fSDaniel Sanders 
5645c582b2fSDaniel Sanders   if (HasRs)
5655c582b2fSDaniel Sanders     MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
5665c582b2fSDaniel Sanders                                        Rs)));
5675c582b2fSDaniel Sanders 
5685c582b2fSDaniel Sanders   MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
5695c582b2fSDaniel Sanders                                      Rt)));
5705c582b2fSDaniel Sanders   MI.addOperand(MCOperand::CreateImm(Imm));
5715c582b2fSDaniel Sanders 
5725c582b2fSDaniel Sanders   return MCDisassembler::Success;
5735c582b2fSDaniel Sanders }
5745c582b2fSDaniel Sanders 
5755c582b2fSDaniel Sanders template <typename InsnType>
5765c582b2fSDaniel Sanders static DecodeStatus DecodeDaddiGroupBranch(MCInst &MI, InsnType insn,
5775c582b2fSDaniel Sanders                                            uint64_t Address,
5785c582b2fSDaniel Sanders                                            const void *Decoder) {
5795c582b2fSDaniel Sanders   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
5805c582b2fSDaniel Sanders   // (otherwise we would have matched the ADDI instruction from the earlier
5815c582b2fSDaniel Sanders   // ISA's instead).
5825c582b2fSDaniel Sanders   //
5835c582b2fSDaniel Sanders   // We have:
5845c582b2fSDaniel Sanders   //    0b011000 sssss ttttt iiiiiiiiiiiiiiii
5855c582b2fSDaniel Sanders   //      BNVC if rs >= rt
5865c582b2fSDaniel Sanders   //      BNEZALC if rs == 0 && rt != 0
5875c582b2fSDaniel Sanders   //      BNEC if rs < rt && rs != 0
5885c582b2fSDaniel Sanders 
5895c582b2fSDaniel Sanders   InsnType Rs = fieldFromInstruction(insn, 21, 5);
5905c582b2fSDaniel Sanders   InsnType Rt = fieldFromInstruction(insn, 16, 5);
591d37bab61SAlexey Samsonov   InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4;
5925c582b2fSDaniel Sanders   bool HasRs = false;
5935c582b2fSDaniel Sanders 
5945c582b2fSDaniel Sanders   if (Rs >= Rt) {
5955c582b2fSDaniel Sanders     MI.setOpcode(Mips::BNVC);
5965c582b2fSDaniel Sanders     HasRs = true;
5975c582b2fSDaniel Sanders   } else if (Rs != 0 && Rs < Rt) {
5985c582b2fSDaniel Sanders     MI.setOpcode(Mips::BNEC);
5995c582b2fSDaniel Sanders     HasRs = true;
6005c582b2fSDaniel Sanders   } else
6015c582b2fSDaniel Sanders     MI.setOpcode(Mips::BNEZALC);
6025c582b2fSDaniel Sanders 
6035c582b2fSDaniel Sanders   if (HasRs)
6045c582b2fSDaniel Sanders     MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
6055c582b2fSDaniel Sanders                                        Rs)));
6065c582b2fSDaniel Sanders 
6075c582b2fSDaniel Sanders   MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
6085c582b2fSDaniel Sanders                                      Rt)));
6095c582b2fSDaniel Sanders   MI.addOperand(MCOperand::CreateImm(Imm));
6105c582b2fSDaniel Sanders 
6115c582b2fSDaniel Sanders   return MCDisassembler::Success;
6125c582b2fSDaniel Sanders }
6135c582b2fSDaniel Sanders 
6145c582b2fSDaniel Sanders template <typename InsnType>
6155c582b2fSDaniel Sanders static DecodeStatus DecodeBlezlGroupBranch(MCInst &MI, InsnType insn,
6165c582b2fSDaniel Sanders                                            uint64_t Address,
6175c582b2fSDaniel Sanders                                            const void *Decoder) {
6185c582b2fSDaniel Sanders   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
6195c582b2fSDaniel Sanders   // (otherwise we would have matched the BLEZL instruction from the earlier
6205c582b2fSDaniel Sanders   // ISA's instead).
6215c582b2fSDaniel Sanders   //
6225c582b2fSDaniel Sanders   // We have:
6235c582b2fSDaniel Sanders   //    0b010110 sssss ttttt iiiiiiiiiiiiiiii
6245c582b2fSDaniel Sanders   //      Invalid if rs == 0
6255c582b2fSDaniel Sanders   //      BLEZC   if rs == 0  && rt != 0
6265c582b2fSDaniel Sanders   //      BGEZC   if rs == rt && rt != 0
6275c582b2fSDaniel Sanders   //      BGEC    if rs != rt && rs != 0  && rt != 0
6285c582b2fSDaniel Sanders 
6295c582b2fSDaniel Sanders   InsnType Rs = fieldFromInstruction(insn, 21, 5);
6305c582b2fSDaniel Sanders   InsnType Rt = fieldFromInstruction(insn, 16, 5);
631d37bab61SAlexey Samsonov   InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4;
63228a0ca07SZoran Jovanovic   bool HasRs = false;
6335c582b2fSDaniel Sanders 
6345c582b2fSDaniel Sanders   if (Rt == 0)
6355c582b2fSDaniel Sanders     return MCDisassembler::Fail;
6365c582b2fSDaniel Sanders   else if (Rs == 0)
6375c582b2fSDaniel Sanders     MI.setOpcode(Mips::BLEZC);
6385c582b2fSDaniel Sanders   else if (Rs == Rt)
6395c582b2fSDaniel Sanders     MI.setOpcode(Mips::BGEZC);
64028a0ca07SZoran Jovanovic   else {
64128a0ca07SZoran Jovanovic     HasRs = true;
64228a0ca07SZoran Jovanovic     MI.setOpcode(Mips::BGEC);
64328a0ca07SZoran Jovanovic   }
64428a0ca07SZoran Jovanovic 
64528a0ca07SZoran Jovanovic   if (HasRs)
64628a0ca07SZoran Jovanovic     MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
64728a0ca07SZoran Jovanovic                                        Rs)));
6485c582b2fSDaniel Sanders 
6495c582b2fSDaniel Sanders   MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
6505c582b2fSDaniel Sanders                                      Rt)));
6515c582b2fSDaniel Sanders 
6525c582b2fSDaniel Sanders   MI.addOperand(MCOperand::CreateImm(Imm));
6535c582b2fSDaniel Sanders 
6545c582b2fSDaniel Sanders   return MCDisassembler::Success;
6555c582b2fSDaniel Sanders }
6565c582b2fSDaniel Sanders 
6575c582b2fSDaniel Sanders template <typename InsnType>
6585c582b2fSDaniel Sanders static DecodeStatus DecodeBgtzlGroupBranch(MCInst &MI, InsnType insn,
6595c582b2fSDaniel Sanders                                            uint64_t Address,
6605c582b2fSDaniel Sanders                                            const void *Decoder) {
6615c582b2fSDaniel Sanders   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
6625c582b2fSDaniel Sanders   // (otherwise we would have matched the BGTZL instruction from the earlier
6635c582b2fSDaniel Sanders   // ISA's instead).
6645c582b2fSDaniel Sanders   //
6655c582b2fSDaniel Sanders   // We have:
6665c582b2fSDaniel Sanders   //    0b010111 sssss ttttt iiiiiiiiiiiiiiii
6675c582b2fSDaniel Sanders   //      Invalid if rs == 0
6685c582b2fSDaniel Sanders   //      BGTZC   if rs == 0  && rt != 0
6695c582b2fSDaniel Sanders   //      BLTZC   if rs == rt && rt != 0
6705c582b2fSDaniel Sanders   //      BLTC    if rs != rt && rs != 0  && rt != 0
6715c582b2fSDaniel Sanders 
6725c14b069SZoran Jovanovic   bool HasRs = false;
6735c14b069SZoran Jovanovic 
6745c582b2fSDaniel Sanders   InsnType Rs = fieldFromInstruction(insn, 21, 5);
6755c582b2fSDaniel Sanders   InsnType Rt = fieldFromInstruction(insn, 16, 5);
676d37bab61SAlexey Samsonov   InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4;
6775c582b2fSDaniel Sanders 
6785c582b2fSDaniel Sanders   if (Rt == 0)
6795c582b2fSDaniel Sanders     return MCDisassembler::Fail;
6805c582b2fSDaniel Sanders   else if (Rs == 0)
6815c582b2fSDaniel Sanders     MI.setOpcode(Mips::BGTZC);
6825c582b2fSDaniel Sanders   else if (Rs == Rt)
6835c582b2fSDaniel Sanders     MI.setOpcode(Mips::BLTZC);
6845c14b069SZoran Jovanovic   else {
6855c14b069SZoran Jovanovic     MI.setOpcode(Mips::BLTC);
6865c14b069SZoran Jovanovic     HasRs = true;
6875c14b069SZoran Jovanovic   }
6885c14b069SZoran Jovanovic 
6895c14b069SZoran Jovanovic   if (HasRs)
6905c14b069SZoran Jovanovic     MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
6915c14b069SZoran Jovanovic                                               Rs)));
6925c582b2fSDaniel Sanders 
6935c582b2fSDaniel Sanders   MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
6945c582b2fSDaniel Sanders                                      Rt)));
6955c582b2fSDaniel Sanders 
6965c582b2fSDaniel Sanders   MI.addOperand(MCOperand::CreateImm(Imm));
6975c582b2fSDaniel Sanders 
6985c582b2fSDaniel Sanders   return MCDisassembler::Success;
6995c582b2fSDaniel Sanders }
7005c582b2fSDaniel Sanders 
7015c582b2fSDaniel Sanders template <typename InsnType>
7025c582b2fSDaniel Sanders static DecodeStatus DecodeBgtzGroupBranch(MCInst &MI, InsnType insn,
7035c582b2fSDaniel Sanders                                           uint64_t Address,
7045c582b2fSDaniel Sanders                                           const void *Decoder) {
7055c582b2fSDaniel Sanders   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
7065c582b2fSDaniel Sanders   // (otherwise we would have matched the BGTZ instruction from the earlier
7075c582b2fSDaniel Sanders   // ISA's instead).
7085c582b2fSDaniel Sanders   //
7095c582b2fSDaniel Sanders   // We have:
7105c582b2fSDaniel Sanders   //    0b000111 sssss ttttt iiiiiiiiiiiiiiii
7115c582b2fSDaniel Sanders   //      BGTZ    if rt == 0
7125c582b2fSDaniel Sanders   //      BGTZALC if rs == 0 && rt != 0
7135c582b2fSDaniel Sanders   //      BLTZALC if rs != 0 && rs == rt
7145c582b2fSDaniel Sanders   //      BLTUC   if rs != 0 && rs != rt
7155c582b2fSDaniel Sanders 
7165c582b2fSDaniel Sanders   InsnType Rs = fieldFromInstruction(insn, 21, 5);
7175c582b2fSDaniel Sanders   InsnType Rt = fieldFromInstruction(insn, 16, 5);
718d37bab61SAlexey Samsonov   InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4;
7195c582b2fSDaniel Sanders   bool HasRs = false;
7205c582b2fSDaniel Sanders   bool HasRt = false;
7215c582b2fSDaniel Sanders 
7225c582b2fSDaniel Sanders   if (Rt == 0) {
7235c582b2fSDaniel Sanders     MI.setOpcode(Mips::BGTZ);
7245c582b2fSDaniel Sanders     HasRs = true;
7255c582b2fSDaniel Sanders   } else if (Rs == 0) {
7265c582b2fSDaniel Sanders     MI.setOpcode(Mips::BGTZALC);
7275c582b2fSDaniel Sanders     HasRt = true;
7285c582b2fSDaniel Sanders   } else if (Rs == Rt) {
7295c582b2fSDaniel Sanders     MI.setOpcode(Mips::BLTZALC);
7305c582b2fSDaniel Sanders     HasRs = true;
7315c14b069SZoran Jovanovic   } else {
7325c14b069SZoran Jovanovic     MI.setOpcode(Mips::BLTUC);
7335c14b069SZoran Jovanovic     HasRs = true;
7345c14b069SZoran Jovanovic     HasRt = true;
7355c14b069SZoran Jovanovic   }
7365c582b2fSDaniel Sanders 
7375c582b2fSDaniel Sanders   if (HasRs)
7385c582b2fSDaniel Sanders     MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
7395c582b2fSDaniel Sanders                                        Rs)));
7405c582b2fSDaniel Sanders 
7415c582b2fSDaniel Sanders   if (HasRt)
7425c582b2fSDaniel Sanders     MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
7435c582b2fSDaniel Sanders                                        Rt)));
7445c582b2fSDaniel Sanders 
7455c582b2fSDaniel Sanders   MI.addOperand(MCOperand::CreateImm(Imm));
7465c582b2fSDaniel Sanders 
7475c582b2fSDaniel Sanders   return MCDisassembler::Success;
7485c582b2fSDaniel Sanders }
7495c582b2fSDaniel Sanders 
75028a0ca07SZoran Jovanovic template <typename InsnType>
75128a0ca07SZoran Jovanovic static DecodeStatus DecodeBlezGroupBranch(MCInst &MI, InsnType insn,
75228a0ca07SZoran Jovanovic                                            uint64_t Address,
75328a0ca07SZoran Jovanovic                                            const void *Decoder) {
75428a0ca07SZoran Jovanovic   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
75528a0ca07SZoran Jovanovic   // (otherwise we would have matched the BLEZL instruction from the earlier
75628a0ca07SZoran Jovanovic   // ISA's instead).
75728a0ca07SZoran Jovanovic   //
75828a0ca07SZoran Jovanovic   // We have:
75928a0ca07SZoran Jovanovic   //    0b000110 sssss ttttt iiiiiiiiiiiiiiii
76028a0ca07SZoran Jovanovic   //      Invalid   if rs == 0
76128a0ca07SZoran Jovanovic   //      BLEZALC   if rs == 0  && rt != 0
76228a0ca07SZoran Jovanovic   //      BGEZALC   if rs == rt && rt != 0
76328a0ca07SZoran Jovanovic   //      BGEUC     if rs != rt && rs != 0  && rt != 0
76428a0ca07SZoran Jovanovic 
76528a0ca07SZoran Jovanovic   InsnType Rs = fieldFromInstruction(insn, 21, 5);
76628a0ca07SZoran Jovanovic   InsnType Rt = fieldFromInstruction(insn, 16, 5);
767d37bab61SAlexey Samsonov   InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4;
76828a0ca07SZoran Jovanovic   bool HasRs = false;
76928a0ca07SZoran Jovanovic 
77028a0ca07SZoran Jovanovic   if (Rt == 0)
77128a0ca07SZoran Jovanovic     return MCDisassembler::Fail;
77228a0ca07SZoran Jovanovic   else if (Rs == 0)
77328a0ca07SZoran Jovanovic     MI.setOpcode(Mips::BLEZALC);
77428a0ca07SZoran Jovanovic   else if (Rs == Rt)
77528a0ca07SZoran Jovanovic     MI.setOpcode(Mips::BGEZALC);
77628a0ca07SZoran Jovanovic   else {
77728a0ca07SZoran Jovanovic     HasRs = true;
77828a0ca07SZoran Jovanovic     MI.setOpcode(Mips::BGEUC);
77928a0ca07SZoran Jovanovic   }
78028a0ca07SZoran Jovanovic 
78128a0ca07SZoran Jovanovic   if (HasRs)
78228a0ca07SZoran Jovanovic     MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
78328a0ca07SZoran Jovanovic                                        Rs)));
78428a0ca07SZoran Jovanovic   MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
78528a0ca07SZoran Jovanovic                                      Rt)));
78628a0ca07SZoran Jovanovic 
78728a0ca07SZoran Jovanovic   MI.addOperand(MCOperand::CreateImm(Imm));
78828a0ca07SZoran Jovanovic 
78928a0ca07SZoran Jovanovic   return MCDisassembler::Success;
79028a0ca07SZoran Jovanovic }
79128a0ca07SZoran Jovanovic 
792ea22c4cfSJozef Kolek /// Read two bytes from the ArrayRef and return 16 bit halfword sorted
793ea22c4cfSJozef Kolek /// according to the given endianess.
794ea22c4cfSJozef Kolek static DecodeStatus readInstruction16(ArrayRef<uint8_t> Bytes, uint64_t Address,
795ea22c4cfSJozef Kolek                                       uint64_t &Size, uint32_t &Insn,
796ea22c4cfSJozef Kolek                                       bool IsBigEndian) {
797ea22c4cfSJozef Kolek   // We want to read exactly 2 Bytes of data.
798ea22c4cfSJozef Kolek   if (Bytes.size() < 2) {
799ea22c4cfSJozef Kolek     Size = 0;
800ea22c4cfSJozef Kolek     return MCDisassembler::Fail;
801ea22c4cfSJozef Kolek   }
802ea22c4cfSJozef Kolek 
803ea22c4cfSJozef Kolek   if (IsBigEndian) {
804ea22c4cfSJozef Kolek     Insn = (Bytes[0] << 8) | Bytes[1];
805ea22c4cfSJozef Kolek   } else {
806ea22c4cfSJozef Kolek     Insn = (Bytes[1] << 8) | Bytes[0];
807ea22c4cfSJozef Kolek   }
808ea22c4cfSJozef Kolek 
809ea22c4cfSJozef Kolek   return MCDisassembler::Success;
810ea22c4cfSJozef Kolek }
811ea22c4cfSJozef Kolek 
8127fc5b874SRafael Espindola /// Read four bytes from the ArrayRef and return 32 bit word sorted
8134aa6bea7SRafael Espindola /// according to the given endianess
8147fc5b874SRafael Espindola static DecodeStatus readInstruction32(ArrayRef<uint8_t> Bytes, uint64_t Address,
8157fc5b874SRafael Espindola                                       uint64_t &Size, uint32_t &Insn,
8167fc5b874SRafael Espindola                                       bool IsBigEndian, bool IsMicroMips) {
81771928e68SAkira Hatanaka   // We want to read exactly 4 Bytes of data.
8187fc5b874SRafael Espindola   if (Bytes.size() < 4) {
8194aa6bea7SRafael Espindola     Size = 0;
82071928e68SAkira Hatanaka     return MCDisassembler::Fail;
82171928e68SAkira Hatanaka   }
82271928e68SAkira Hatanaka 
823ea22c4cfSJozef Kolek   // High 16 bits of a 32-bit microMIPS instruction (where the opcode is)
824ea22c4cfSJozef Kolek   // always precede the low 16 bits in the instruction stream (that is, they
825ea22c4cfSJozef Kolek   // are placed at lower addresses in the instruction stream).
826ea22c4cfSJozef Kolek   //
827ea22c4cfSJozef Kolek   // microMIPS byte ordering:
828ea22c4cfSJozef Kolek   //   Big-endian:    0 | 1 | 2 | 3
829ea22c4cfSJozef Kolek   //   Little-endian: 1 | 0 | 3 | 2
830ea22c4cfSJozef Kolek 
8314aa6bea7SRafael Espindola   if (IsBigEndian) {
83271928e68SAkira Hatanaka     // Encoded as a big-endian 32-bit word in the stream.
8334aa6bea7SRafael Espindola     Insn =
8344aa6bea7SRafael Espindola         (Bytes[3] << 0) | (Bytes[2] << 8) | (Bytes[1] << 16) | (Bytes[0] << 24);
8354aa6bea7SRafael Espindola   } else {
836dde3d582SVladimir Medic     if (IsMicroMips) {
8374aa6bea7SRafael Espindola       Insn = (Bytes[2] << 0) | (Bytes[3] << 8) | (Bytes[0] << 16) |
838dde3d582SVladimir Medic              (Bytes[1] << 24);
839dde3d582SVladimir Medic     } else {
8404aa6bea7SRafael Espindola       Insn = (Bytes[0] << 0) | (Bytes[1] << 8) | (Bytes[2] << 16) |
84171928e68SAkira Hatanaka              (Bytes[3] << 24);
84271928e68SAkira Hatanaka     }
843dde3d582SVladimir Medic   }
84471928e68SAkira Hatanaka 
84571928e68SAkira Hatanaka   return MCDisassembler::Success;
84671928e68SAkira Hatanaka }
84771928e68SAkira Hatanaka 
8484aa6bea7SRafael Espindola DecodeStatus MipsDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,
8497fc5b874SRafael Espindola                                               ArrayRef<uint8_t> Bytes,
85071928e68SAkira Hatanaka                                               uint64_t Address,
8514aa6bea7SRafael Espindola                                               raw_ostream &VStream,
8524aa6bea7SRafael Espindola                                               raw_ostream &CStream) const {
85371928e68SAkira Hatanaka   uint32_t Insn;
854ea22c4cfSJozef Kolek   DecodeStatus Result;
85571928e68SAkira Hatanaka 
856ea22c4cfSJozef Kolek   if (IsMicroMips) {
857ea22c4cfSJozef Kolek     Result = readInstruction16(Bytes, Address, Size, Insn, IsBigEndian);
858ea22c4cfSJozef Kolek 
859ea22c4cfSJozef Kolek     DEBUG(dbgs() << "Trying MicroMips16 table (16-bit instructions):\n");
860ea22c4cfSJozef Kolek     // Calling the auto-generated decoder function.
861ea22c4cfSJozef Kolek     Result = decodeInstruction(DecoderTableMicroMips16, Instr, Insn, Address,
862ea22c4cfSJozef Kolek                                this, STI);
863ea22c4cfSJozef Kolek     if (Result != MCDisassembler::Fail) {
864ea22c4cfSJozef Kolek       Size = 2;
865ea22c4cfSJozef Kolek       return Result;
866ea22c4cfSJozef Kolek     }
867ea22c4cfSJozef Kolek 
868ea22c4cfSJozef Kolek     Result = readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, true);
86971928e68SAkira Hatanaka     if (Result == MCDisassembler::Fail)
87071928e68SAkira Hatanaka       return MCDisassembler::Fail;
87171928e68SAkira Hatanaka 
872ea22c4cfSJozef Kolek     DEBUG(dbgs() << "Trying MicroMips32 table (32-bit instructions):\n");
873dde3d582SVladimir Medic     // Calling the auto-generated decoder function.
8744aa6bea7SRafael Espindola     Result = decodeInstruction(DecoderTableMicroMips32, Instr, Insn, Address,
875dde3d582SVladimir Medic                                this, STI);
876dde3d582SVladimir Medic     if (Result != MCDisassembler::Fail) {
877dde3d582SVladimir Medic       Size = 4;
878dde3d582SVladimir Medic       return Result;
879dde3d582SVladimir Medic     }
880dde3d582SVladimir Medic     return MCDisassembler::Fail;
881dde3d582SVladimir Medic   }
882dde3d582SVladimir Medic 
883ea22c4cfSJozef Kolek   Result = readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, false);
884ea22c4cfSJozef Kolek   if (Result == MCDisassembler::Fail)
885ea22c4cfSJozef Kolek     return MCDisassembler::Fail;
886ea22c4cfSJozef Kolek 
887c171f65aSDaniel Sanders   if (hasCOP3()) {
888c171f65aSDaniel Sanders     DEBUG(dbgs() << "Trying COP3_ table (32-bit opcodes):\n");
889c171f65aSDaniel Sanders     Result =
8904aa6bea7SRafael Espindola         decodeInstruction(DecoderTableCOP3_32, Instr, Insn, Address, this, STI);
891c171f65aSDaniel Sanders     if (Result != MCDisassembler::Fail) {
892c171f65aSDaniel Sanders       Size = 4;
893c171f65aSDaniel Sanders       return Result;
894c171f65aSDaniel Sanders     }
895c171f65aSDaniel Sanders   }
896c171f65aSDaniel Sanders 
897c171f65aSDaniel Sanders   if (hasMips32r6() && isGP64()) {
8980fa60416SDaniel Sanders     DEBUG(dbgs() << "Trying Mips32r6_64r6 (GPR64) table (32-bit opcodes):\n");
8994aa6bea7SRafael Espindola     Result = decodeInstruction(DecoderTableMips32r6_64r6_GP6432, Instr, Insn,
9000fa60416SDaniel Sanders                                Address, this, STI);
9010fa60416SDaniel Sanders     if (Result != MCDisassembler::Fail) {
9020fa60416SDaniel Sanders       Size = 4;
9030fa60416SDaniel Sanders       return Result;
9040fa60416SDaniel Sanders     }
9050fa60416SDaniel Sanders   }
9060fa60416SDaniel Sanders 
907c171f65aSDaniel Sanders   if (hasMips32r6()) {
9080fa60416SDaniel Sanders     DEBUG(dbgs() << "Trying Mips32r6_64r6 table (32-bit opcodes):\n");
9094aa6bea7SRafael Espindola     Result = decodeInstruction(DecoderTableMips32r6_64r632, Instr, Insn,
9105c582b2fSDaniel Sanders                                Address, this, STI);
9115c582b2fSDaniel Sanders     if (Result != MCDisassembler::Fail) {
9125c582b2fSDaniel Sanders       Size = 4;
9135c582b2fSDaniel Sanders       return Result;
9145c582b2fSDaniel Sanders     }
9155c582b2fSDaniel Sanders   }
9165c582b2fSDaniel Sanders 
9170fa60416SDaniel Sanders   DEBUG(dbgs() << "Trying Mips table (32-bit opcodes):\n");
91871928e68SAkira Hatanaka   // Calling the auto-generated decoder function.
9194aa6bea7SRafael Espindola   Result =
9204aa6bea7SRafael Espindola       decodeInstruction(DecoderTableMips32, Instr, Insn, Address, this, STI);
92171928e68SAkira Hatanaka   if (Result != MCDisassembler::Fail) {
92271928e68SAkira Hatanaka     Size = 4;
92371928e68SAkira Hatanaka     return Result;
92471928e68SAkira Hatanaka   }
92571928e68SAkira Hatanaka 
92671928e68SAkira Hatanaka   return MCDisassembler::Fail;
92771928e68SAkira Hatanaka }
92871928e68SAkira Hatanaka 
9294aa6bea7SRafael Espindola DecodeStatus Mips64Disassembler::getInstruction(MCInst &Instr, uint64_t &Size,
9307fc5b874SRafael Espindola                                                 ArrayRef<uint8_t> Bytes,
93171928e68SAkira Hatanaka                                                 uint64_t Address,
9324aa6bea7SRafael Espindola                                                 raw_ostream &VStream,
9334aa6bea7SRafael Espindola                                                 raw_ostream &CStream) const {
93471928e68SAkira Hatanaka   uint32_t Insn;
93571928e68SAkira Hatanaka 
9364aa6bea7SRafael Espindola   DecodeStatus Result =
9377fc5b874SRafael Espindola       readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, false);
93871928e68SAkira Hatanaka   if (Result == MCDisassembler::Fail)
93971928e68SAkira Hatanaka     return MCDisassembler::Fail;
94071928e68SAkira Hatanaka 
94171928e68SAkira Hatanaka   // Calling the auto-generated decoder function.
9424aa6bea7SRafael Espindola   Result =
9434aa6bea7SRafael Espindola       decodeInstruction(DecoderTableMips6432, Instr, Insn, Address, this, STI);
94471928e68SAkira Hatanaka   if (Result != MCDisassembler::Fail) {
94571928e68SAkira Hatanaka     Size = 4;
94671928e68SAkira Hatanaka     return Result;
94771928e68SAkira Hatanaka   }
94871928e68SAkira Hatanaka   // If we fail to decode in Mips64 decoder space we can try in Mips32
9494aa6bea7SRafael Espindola   Result =
9504aa6bea7SRafael Espindola       decodeInstruction(DecoderTableMips32, Instr, Insn, Address, this, STI);
95171928e68SAkira Hatanaka   if (Result != MCDisassembler::Fail) {
95271928e68SAkira Hatanaka     Size = 4;
95371928e68SAkira Hatanaka     return Result;
95471928e68SAkira Hatanaka   }
95571928e68SAkira Hatanaka 
95671928e68SAkira Hatanaka   return MCDisassembler::Fail;
95771928e68SAkira Hatanaka }
95871928e68SAkira Hatanaka 
959ec8a5490SReed Kotler static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst,
960ec8a5490SReed Kotler                                                  unsigned RegNo,
961ec8a5490SReed Kotler                                                  uint64_t Address,
962ec8a5490SReed Kotler                                                  const void *Decoder) {
963ec8a5490SReed Kotler 
964ec8a5490SReed Kotler   return MCDisassembler::Fail;
965ec8a5490SReed Kotler 
966ec8a5490SReed Kotler }
967ec8a5490SReed Kotler 
96813e6ccf3SAkira Hatanaka static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst,
96971928e68SAkira Hatanaka                                              unsigned RegNo,
97071928e68SAkira Hatanaka                                              uint64_t Address,
97171928e68SAkira Hatanaka                                              const void *Decoder) {
97271928e68SAkira Hatanaka 
97371928e68SAkira Hatanaka   if (RegNo > 31)
97471928e68SAkira Hatanaka     return MCDisassembler::Fail;
97571928e68SAkira Hatanaka 
97613e6ccf3SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::GPR64RegClassID, RegNo);
9779bf2b567SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
97871928e68SAkira Hatanaka   return MCDisassembler::Success;
97971928e68SAkira Hatanaka }
98071928e68SAkira Hatanaka 
981b0852e54SZoran Jovanovic static DecodeStatus DecodeGPRMM16RegisterClass(MCInst &Inst,
982b0852e54SZoran Jovanovic                                                unsigned RegNo,
983b0852e54SZoran Jovanovic                                                uint64_t Address,
984b0852e54SZoran Jovanovic                                                const void *Decoder) {
985ea22c4cfSJozef Kolek   if (RegNo > 7)
986b0852e54SZoran Jovanovic     return MCDisassembler::Fail;
987ea22c4cfSJozef Kolek   unsigned Reg = getReg(Decoder, Mips::GPRMM16RegClassID, RegNo);
988ea22c4cfSJozef Kolek   Inst.addOperand(MCOperand::CreateReg(Reg));
989ea22c4cfSJozef Kolek   return MCDisassembler::Success;
990b0852e54SZoran Jovanovic }
991b0852e54SZoran Jovanovic 
9921904fa21SJozef Kolek static DecodeStatus DecodeGPRMM16ZeroRegisterClass(MCInst &Inst,
9931904fa21SJozef Kolek                                                    unsigned RegNo,
9941904fa21SJozef Kolek                                                    uint64_t Address,
9951904fa21SJozef Kolek                                                    const void *Decoder) {
996315e7ecaSJozef Kolek   if (RegNo > 7)
9971904fa21SJozef Kolek     return MCDisassembler::Fail;
998315e7ecaSJozef Kolek   unsigned Reg = getReg(Decoder, Mips::GPRMM16ZeroRegClassID, RegNo);
999315e7ecaSJozef Kolek   Inst.addOperand(MCOperand::CreateReg(Reg));
1000315e7ecaSJozef Kolek   return MCDisassembler::Success;
10011904fa21SJozef Kolek }
10021904fa21SJozef Kolek 
100313e6ccf3SAkira Hatanaka static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst,
100471928e68SAkira Hatanaka                                              unsigned RegNo,
100571928e68SAkira Hatanaka                                              uint64_t Address,
100671928e68SAkira Hatanaka                                              const void *Decoder) {
100771928e68SAkira Hatanaka   if (RegNo > 31)
100871928e68SAkira Hatanaka     return MCDisassembler::Fail;
100913e6ccf3SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::GPR32RegClassID, RegNo);
10109bf2b567SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
101171928e68SAkira Hatanaka   return MCDisassembler::Success;
101271928e68SAkira Hatanaka }
101371928e68SAkira Hatanaka 
10149bfa2e2eSAkira Hatanaka static DecodeStatus DecodePtrRegisterClass(MCInst &Inst,
10159bfa2e2eSAkira Hatanaka                                            unsigned RegNo,
10169bfa2e2eSAkira Hatanaka                                            uint64_t Address,
10179bfa2e2eSAkira Hatanaka                                            const void *Decoder) {
1018e8860938SVladimir Medic   if (static_cast<const MipsDisassembler *>(Decoder)->isGP64Bit())
10199bfa2e2eSAkira Hatanaka     return DecodeGPR64RegisterClass(Inst, RegNo, Address, Decoder);
10209bfa2e2eSAkira Hatanaka 
10219bfa2e2eSAkira Hatanaka   return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
10229bfa2e2eSAkira Hatanaka }
10239bfa2e2eSAkira Hatanaka 
1024654655f1SAkira Hatanaka static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst,
1025ecabd1a5SAkira Hatanaka                                             unsigned RegNo,
1026ecabd1a5SAkira Hatanaka                                             uint64_t Address,
1027ecabd1a5SAkira Hatanaka                                             const void *Decoder) {
102813e6ccf3SAkira Hatanaka   return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
1029ecabd1a5SAkira Hatanaka }
1030ecabd1a5SAkira Hatanaka 
103171928e68SAkira Hatanaka static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
103271928e68SAkira Hatanaka                                              unsigned RegNo,
103371928e68SAkira Hatanaka                                              uint64_t Address,
103471928e68SAkira Hatanaka                                              const void *Decoder) {
103571928e68SAkira Hatanaka   if (RegNo > 31)
103671928e68SAkira Hatanaka     return MCDisassembler::Fail;
103771928e68SAkira Hatanaka 
10389bf2b567SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::FGR64RegClassID, RegNo);
10399bf2b567SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
104071928e68SAkira Hatanaka   return MCDisassembler::Success;
104171928e68SAkira Hatanaka }
104271928e68SAkira Hatanaka 
104371928e68SAkira Hatanaka static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
104471928e68SAkira Hatanaka                                              unsigned RegNo,
104571928e68SAkira Hatanaka                                              uint64_t Address,
104671928e68SAkira Hatanaka                                              const void *Decoder) {
104771928e68SAkira Hatanaka   if (RegNo > 31)
104871928e68SAkira Hatanaka     return MCDisassembler::Fail;
104971928e68SAkira Hatanaka 
10509bf2b567SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::FGR32RegClassID, RegNo);
10519bf2b567SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
105271928e68SAkira Hatanaka   return MCDisassembler::Success;
105371928e68SAkira Hatanaka }
105471928e68SAkira Hatanaka 
105571928e68SAkira Hatanaka static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
105671928e68SAkira Hatanaka                                            unsigned RegNo,
105771928e68SAkira Hatanaka                                            uint64_t Address,
105871928e68SAkira Hatanaka                                            const void *Decoder) {
1059253777fdSChad Rosier   if (RegNo > 31)
1060253777fdSChad Rosier     return MCDisassembler::Fail;
1061253777fdSChad Rosier   unsigned Reg = getReg(Decoder, Mips::CCRRegClassID, RegNo);
1062253777fdSChad Rosier   Inst.addOperand(MCOperand::CreateReg(Reg));
106371928e68SAkira Hatanaka   return MCDisassembler::Success;
106471928e68SAkira Hatanaka }
106571928e68SAkira Hatanaka 
10661fb1b8b8SAkira Hatanaka static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst,
10671fb1b8b8SAkira Hatanaka                                            unsigned RegNo,
10681fb1b8b8SAkira Hatanaka                                            uint64_t Address,
10691fb1b8b8SAkira Hatanaka                                            const void *Decoder) {
10701fb1b8b8SAkira Hatanaka   if (RegNo > 7)
10711fb1b8b8SAkira Hatanaka     return MCDisassembler::Fail;
10721fb1b8b8SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::FCCRegClassID, RegNo);
10731fb1b8b8SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
10741fb1b8b8SAkira Hatanaka   return MCDisassembler::Success;
10751fb1b8b8SAkira Hatanaka }
10761fb1b8b8SAkira Hatanaka 
10770fa60416SDaniel Sanders static DecodeStatus DecodeFGRCCRegisterClass(MCInst &Inst, unsigned RegNo,
10780fa60416SDaniel Sanders                                              uint64_t Address,
10790fa60416SDaniel Sanders                                              const void *Decoder) {
10800fa60416SDaniel Sanders   if (RegNo > 31)
10810fa60416SDaniel Sanders     return MCDisassembler::Fail;
10820fa60416SDaniel Sanders 
10830fa60416SDaniel Sanders   unsigned Reg = getReg(Decoder, Mips::FGRCCRegClassID, RegNo);
10840fa60416SDaniel Sanders   Inst.addOperand(MCOperand::CreateReg(Reg));
10850fa60416SDaniel Sanders   return MCDisassembler::Success;
10860fa60416SDaniel Sanders }
10870fa60416SDaniel Sanders 
108871928e68SAkira Hatanaka static DecodeStatus DecodeMem(MCInst &Inst,
108971928e68SAkira Hatanaka                               unsigned Insn,
109071928e68SAkira Hatanaka                               uint64_t Address,
109171928e68SAkira Hatanaka                               const void *Decoder) {
109271928e68SAkira Hatanaka   int Offset = SignExtend32<16>(Insn & 0xffff);
1093ecaef49fSJim Grosbach   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1094ecaef49fSJim Grosbach   unsigned Base = fieldFromInstruction(Insn, 21, 5);
10959bf2b567SAkira Hatanaka 
109613e6ccf3SAkira Hatanaka   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
109713e6ccf3SAkira Hatanaka   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
109871928e68SAkira Hatanaka 
1099d7ecf49eSVladimir Medic   if(Inst.getOpcode() == Mips::SC ||
1100d7ecf49eSVladimir Medic      Inst.getOpcode() == Mips::SCD){
11019bf2b567SAkira Hatanaka     Inst.addOperand(MCOperand::CreateReg(Reg));
110271928e68SAkira Hatanaka   }
110371928e68SAkira Hatanaka 
11049bf2b567SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
11059bf2b567SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Base));
110671928e68SAkira Hatanaka   Inst.addOperand(MCOperand::CreateImm(Offset));
110771928e68SAkira Hatanaka 
110871928e68SAkira Hatanaka   return MCDisassembler::Success;
110971928e68SAkira Hatanaka }
111071928e68SAkira Hatanaka 
111192db6b78SDaniel Sanders static DecodeStatus DecodeCacheOp(MCInst &Inst,
111292db6b78SDaniel Sanders                               unsigned Insn,
111392db6b78SDaniel Sanders                               uint64_t Address,
111492db6b78SDaniel Sanders                               const void *Decoder) {
111592db6b78SDaniel Sanders   int Offset = SignExtend32<16>(Insn & 0xffff);
111692db6b78SDaniel Sanders   unsigned Hint = fieldFromInstruction(Insn, 16, 5);
111792db6b78SDaniel Sanders   unsigned Base = fieldFromInstruction(Insn, 21, 5);
111892db6b78SDaniel Sanders 
111992db6b78SDaniel Sanders   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
112092db6b78SDaniel Sanders 
112192db6b78SDaniel Sanders   Inst.addOperand(MCOperand::CreateReg(Base));
112292db6b78SDaniel Sanders   Inst.addOperand(MCOperand::CreateImm(Offset));
112392db6b78SDaniel Sanders   Inst.addOperand(MCOperand::CreateImm(Hint));
112492db6b78SDaniel Sanders 
112592db6b78SDaniel Sanders   return MCDisassembler::Success;
112692db6b78SDaniel Sanders }
112792db6b78SDaniel Sanders 
1128ab6d1cceSJozef Kolek static DecodeStatus DecodeCacheOpMM(MCInst &Inst,
1129ab6d1cceSJozef Kolek                                     unsigned Insn,
1130ab6d1cceSJozef Kolek                                     uint64_t Address,
1131ab6d1cceSJozef Kolek                                     const void *Decoder) {
1132ab6d1cceSJozef Kolek   int Offset = SignExtend32<12>(Insn & 0xfff);
1133ab6d1cceSJozef Kolek   unsigned Base = fieldFromInstruction(Insn, 16, 5);
1134ab6d1cceSJozef Kolek   unsigned Hint = fieldFromInstruction(Insn, 21, 5);
1135ab6d1cceSJozef Kolek 
1136ab6d1cceSJozef Kolek   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1137ab6d1cceSJozef Kolek 
1138ab6d1cceSJozef Kolek   Inst.addOperand(MCOperand::CreateReg(Base));
1139ab6d1cceSJozef Kolek   Inst.addOperand(MCOperand::CreateImm(Offset));
1140ab6d1cceSJozef Kolek   Inst.addOperand(MCOperand::CreateImm(Hint));
1141ab6d1cceSJozef Kolek 
1142ab6d1cceSJozef Kolek   return MCDisassembler::Success;
1143ab6d1cceSJozef Kolek }
1144ab6d1cceSJozef Kolek 
1145*df464ae2SVladimir Medic static DecodeStatus DecodeCacheOpR6(MCInst &Inst,
1146*df464ae2SVladimir Medic                                     unsigned Insn,
1147*df464ae2SVladimir Medic                                     uint64_t Address,
1148*df464ae2SVladimir Medic                                     const void *Decoder) {
1149*df464ae2SVladimir Medic   int Offset = fieldFromInstruction(Insn, 7, 9);
1150*df464ae2SVladimir Medic   unsigned Hint = fieldFromInstruction(Insn, 16, 5);
1151*df464ae2SVladimir Medic   unsigned Base = fieldFromInstruction(Insn, 21, 5);
1152*df464ae2SVladimir Medic 
1153*df464ae2SVladimir Medic   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1154*df464ae2SVladimir Medic 
1155*df464ae2SVladimir Medic   Inst.addOperand(MCOperand::CreateReg(Base));
1156*df464ae2SVladimir Medic   Inst.addOperand(MCOperand::CreateImm(Offset));
1157*df464ae2SVladimir Medic   Inst.addOperand(MCOperand::CreateImm(Hint));
1158*df464ae2SVladimir Medic 
1159*df464ae2SVladimir Medic   return MCDisassembler::Success;
1160*df464ae2SVladimir Medic }
1161*df464ae2SVladimir Medic 
1162b4484d62SDaniel Sanders static DecodeStatus DecodeSyncI(MCInst &Inst,
1163b4484d62SDaniel Sanders                               unsigned Insn,
1164b4484d62SDaniel Sanders                               uint64_t Address,
1165b4484d62SDaniel Sanders                               const void *Decoder) {
1166b4484d62SDaniel Sanders   int Offset = SignExtend32<16>(Insn & 0xffff);
1167b4484d62SDaniel Sanders   unsigned Base = fieldFromInstruction(Insn, 21, 5);
1168b4484d62SDaniel Sanders 
1169b4484d62SDaniel Sanders   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1170b4484d62SDaniel Sanders 
1171b4484d62SDaniel Sanders   Inst.addOperand(MCOperand::CreateReg(Base));
1172b4484d62SDaniel Sanders   Inst.addOperand(MCOperand::CreateImm(Offset));
1173b4484d62SDaniel Sanders 
1174b4484d62SDaniel Sanders   return MCDisassembler::Success;
1175b4484d62SDaniel Sanders }
1176b4484d62SDaniel Sanders 
1177fe0bf9f6SMatheus Almeida static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn,
1178fe0bf9f6SMatheus Almeida                                     uint64_t Address, const void *Decoder) {
1179fe0bf9f6SMatheus Almeida   int Offset = SignExtend32<10>(fieldFromInstruction(Insn, 16, 10));
1180fe0bf9f6SMatheus Almeida   unsigned Reg = fieldFromInstruction(Insn, 6, 5);
1181fe0bf9f6SMatheus Almeida   unsigned Base = fieldFromInstruction(Insn, 11, 5);
1182fe0bf9f6SMatheus Almeida 
1183fe0bf9f6SMatheus Almeida   Reg = getReg(Decoder, Mips::MSA128BRegClassID, Reg);
1184fe0bf9f6SMatheus Almeida   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1185fe0bf9f6SMatheus Almeida 
1186fe0bf9f6SMatheus Almeida   Inst.addOperand(MCOperand::CreateReg(Reg));
1187fe0bf9f6SMatheus Almeida   Inst.addOperand(MCOperand::CreateReg(Base));
11886b59c449SMatheus Almeida 
11896b59c449SMatheus Almeida   // The immediate field of an LD/ST instruction is scaled which means it must
11906b59c449SMatheus Almeida   // be multiplied (when decoding) by the size (in bytes) of the instructions'
11916b59c449SMatheus Almeida   // data format.
11926b59c449SMatheus Almeida   // .b - 1 byte
11936b59c449SMatheus Almeida   // .h - 2 bytes
11946b59c449SMatheus Almeida   // .w - 4 bytes
11956b59c449SMatheus Almeida   // .d - 8 bytes
11966b59c449SMatheus Almeida   switch(Inst.getOpcode())
11976b59c449SMatheus Almeida   {
11986b59c449SMatheus Almeida   default:
11996b59c449SMatheus Almeida     assert (0 && "Unexpected instruction");
12006b59c449SMatheus Almeida     return MCDisassembler::Fail;
12016b59c449SMatheus Almeida     break;
12026b59c449SMatheus Almeida   case Mips::LD_B:
12036b59c449SMatheus Almeida   case Mips::ST_B:
1204fe0bf9f6SMatheus Almeida     Inst.addOperand(MCOperand::CreateImm(Offset));
12056b59c449SMatheus Almeida     break;
12066b59c449SMatheus Almeida   case Mips::LD_H:
12076b59c449SMatheus Almeida   case Mips::ST_H:
1208d37bab61SAlexey Samsonov     Inst.addOperand(MCOperand::CreateImm(Offset * 2));
12096b59c449SMatheus Almeida     break;
12106b59c449SMatheus Almeida   case Mips::LD_W:
12116b59c449SMatheus Almeida   case Mips::ST_W:
1212d37bab61SAlexey Samsonov     Inst.addOperand(MCOperand::CreateImm(Offset * 4));
12136b59c449SMatheus Almeida     break;
12146b59c449SMatheus Almeida   case Mips::LD_D:
12156b59c449SMatheus Almeida   case Mips::ST_D:
1216d37bab61SAlexey Samsonov     Inst.addOperand(MCOperand::CreateImm(Offset * 8));
12176b59c449SMatheus Almeida     break;
12186b59c449SMatheus Almeida   }
1219fe0bf9f6SMatheus Almeida 
1220fe0bf9f6SMatheus Almeida   return MCDisassembler::Success;
1221fe0bf9f6SMatheus Almeida }
1222fe0bf9f6SMatheus Almeida 
1223315e7ecaSJozef Kolek static DecodeStatus DecodeMemMMImm4(MCInst &Inst,
1224315e7ecaSJozef Kolek                                     unsigned Insn,
1225315e7ecaSJozef Kolek                                     uint64_t Address,
1226315e7ecaSJozef Kolek                                     const void *Decoder) {
1227315e7ecaSJozef Kolek   unsigned Offset = Insn & 0xf;
1228315e7ecaSJozef Kolek   unsigned Reg = fieldFromInstruction(Insn, 7, 3);
1229315e7ecaSJozef Kolek   unsigned Base = fieldFromInstruction(Insn, 4, 3);
1230315e7ecaSJozef Kolek 
1231315e7ecaSJozef Kolek   switch (Inst.getOpcode()) {
1232315e7ecaSJozef Kolek     case Mips::LBU16_MM:
1233315e7ecaSJozef Kolek     case Mips::LHU16_MM:
1234315e7ecaSJozef Kolek     case Mips::LW16_MM:
1235315e7ecaSJozef Kolek       if (DecodeGPRMM16RegisterClass(Inst, Reg, Address, Decoder)
1236315e7ecaSJozef Kolek             == MCDisassembler::Fail)
1237315e7ecaSJozef Kolek         return MCDisassembler::Fail;
1238315e7ecaSJozef Kolek       break;
1239315e7ecaSJozef Kolek     case Mips::SB16_MM:
1240315e7ecaSJozef Kolek     case Mips::SH16_MM:
1241315e7ecaSJozef Kolek     case Mips::SW16_MM:
1242315e7ecaSJozef Kolek       if (DecodeGPRMM16ZeroRegisterClass(Inst, Reg, Address, Decoder)
1243315e7ecaSJozef Kolek             == MCDisassembler::Fail)
1244315e7ecaSJozef Kolek         return MCDisassembler::Fail;
1245315e7ecaSJozef Kolek       break;
1246315e7ecaSJozef Kolek   }
1247315e7ecaSJozef Kolek 
1248315e7ecaSJozef Kolek   if (DecodeGPRMM16RegisterClass(Inst, Base, Address, Decoder)
1249315e7ecaSJozef Kolek         == MCDisassembler::Fail)
1250315e7ecaSJozef Kolek     return MCDisassembler::Fail;
1251315e7ecaSJozef Kolek 
1252315e7ecaSJozef Kolek   switch (Inst.getOpcode()) {
1253315e7ecaSJozef Kolek     case Mips::LBU16_MM:
1254315e7ecaSJozef Kolek       if (Offset == 0xf)
1255315e7ecaSJozef Kolek         Inst.addOperand(MCOperand::CreateImm(-1));
1256315e7ecaSJozef Kolek       else
1257315e7ecaSJozef Kolek         Inst.addOperand(MCOperand::CreateImm(Offset));
1258315e7ecaSJozef Kolek       break;
1259315e7ecaSJozef Kolek     case Mips::SB16_MM:
1260315e7ecaSJozef Kolek       Inst.addOperand(MCOperand::CreateImm(Offset));
1261315e7ecaSJozef Kolek       break;
1262315e7ecaSJozef Kolek     case Mips::LHU16_MM:
1263315e7ecaSJozef Kolek     case Mips::SH16_MM:
1264315e7ecaSJozef Kolek       Inst.addOperand(MCOperand::CreateImm(Offset << 1));
1265315e7ecaSJozef Kolek       break;
1266315e7ecaSJozef Kolek     case Mips::LW16_MM:
1267315e7ecaSJozef Kolek     case Mips::SW16_MM:
1268315e7ecaSJozef Kolek       Inst.addOperand(MCOperand::CreateImm(Offset << 2));
1269315e7ecaSJozef Kolek       break;
1270315e7ecaSJozef Kolek   }
1271315e7ecaSJozef Kolek 
1272315e7ecaSJozef Kolek   return MCDisassembler::Success;
1273315e7ecaSJozef Kolek }
1274315e7ecaSJozef Kolek 
127512c6982bSJozef Kolek static DecodeStatus DecodeMemMMSPImm5Lsl2(MCInst &Inst,
127612c6982bSJozef Kolek                                           unsigned Insn,
127712c6982bSJozef Kolek                                           uint64_t Address,
127812c6982bSJozef Kolek                                           const void *Decoder) {
127912c6982bSJozef Kolek   unsigned Offset = Insn & 0x1F;
128012c6982bSJozef Kolek   unsigned Reg = fieldFromInstruction(Insn, 5, 5);
128112c6982bSJozef Kolek 
128212c6982bSJozef Kolek   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
128312c6982bSJozef Kolek 
128412c6982bSJozef Kolek   Inst.addOperand(MCOperand::CreateReg(Reg));
128512c6982bSJozef Kolek   Inst.addOperand(MCOperand::CreateReg(Mips::SP));
128612c6982bSJozef Kolek   Inst.addOperand(MCOperand::CreateImm(Offset << 2));
128712c6982bSJozef Kolek 
128812c6982bSJozef Kolek   return MCDisassembler::Success;
128912c6982bSJozef Kolek }
129012c6982bSJozef Kolek 
1291e10a02ecSJozef Kolek static DecodeStatus DecodeMemMMGPImm7Lsl2(MCInst &Inst,
1292e10a02ecSJozef Kolek                                           unsigned Insn,
1293e10a02ecSJozef Kolek                                           uint64_t Address,
1294e10a02ecSJozef Kolek                                           const void *Decoder) {
1295e10a02ecSJozef Kolek   unsigned Offset = Insn & 0x7F;
1296e10a02ecSJozef Kolek   unsigned Reg = fieldFromInstruction(Insn, 7, 3);
1297e10a02ecSJozef Kolek 
1298e10a02ecSJozef Kolek   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1299e10a02ecSJozef Kolek 
1300e10a02ecSJozef Kolek   Inst.addOperand(MCOperand::CreateReg(Reg));
1301e10a02ecSJozef Kolek   Inst.addOperand(MCOperand::CreateReg(Mips::GP));
1302e10a02ecSJozef Kolek   Inst.addOperand(MCOperand::CreateImm(Offset << 2));
1303e10a02ecSJozef Kolek 
1304e10a02ecSJozef Kolek   return MCDisassembler::Success;
1305e10a02ecSJozef Kolek }
1306e10a02ecSJozef Kolek 
1307dde3d582SVladimir Medic static DecodeStatus DecodeMemMMImm12(MCInst &Inst,
1308dde3d582SVladimir Medic                                      unsigned Insn,
1309dde3d582SVladimir Medic                                      uint64_t Address,
1310dde3d582SVladimir Medic                                      const void *Decoder) {
1311dde3d582SVladimir Medic   int Offset = SignExtend32<12>(Insn & 0x0fff);
1312dde3d582SVladimir Medic   unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1313dde3d582SVladimir Medic   unsigned Base = fieldFromInstruction(Insn, 16, 5);
1314dde3d582SVladimir Medic 
1315dde3d582SVladimir Medic   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1316dde3d582SVladimir Medic   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1317dde3d582SVladimir Medic 
1318a4c4b5fcSZoran Jovanovic   switch (Inst.getOpcode()) {
1319a4c4b5fcSZoran Jovanovic   case Mips::SWM32_MM:
1320a4c4b5fcSZoran Jovanovic   case Mips::LWM32_MM:
1321a4c4b5fcSZoran Jovanovic     if (DecodeRegListOperand(Inst, Insn, Address, Decoder)
1322a4c4b5fcSZoran Jovanovic         == MCDisassembler::Fail)
1323a4c4b5fcSZoran Jovanovic       return MCDisassembler::Fail;
1324a4c4b5fcSZoran Jovanovic     Inst.addOperand(MCOperand::CreateReg(Base));
1325a4c4b5fcSZoran Jovanovic     Inst.addOperand(MCOperand::CreateImm(Offset));
1326a4c4b5fcSZoran Jovanovic     break;
1327a4c4b5fcSZoran Jovanovic   case Mips::SC_MM:
1328285cc289SZoran Jovanovic     Inst.addOperand(MCOperand::CreateReg(Reg));
1329a4c4b5fcSZoran Jovanovic     // fallthrough
1330a4c4b5fcSZoran Jovanovic   default:
1331dde3d582SVladimir Medic     Inst.addOperand(MCOperand::CreateReg(Reg));
13322deca348SZoran Jovanovic     if (Inst.getOpcode() == Mips::LWP_MM || Inst.getOpcode() == Mips::SWP_MM)
13332deca348SZoran Jovanovic       Inst.addOperand(MCOperand::CreateReg(Reg+1));
13342deca348SZoran Jovanovic 
1335dde3d582SVladimir Medic     Inst.addOperand(MCOperand::CreateReg(Base));
1336dde3d582SVladimir Medic     Inst.addOperand(MCOperand::CreateImm(Offset));
1337a4c4b5fcSZoran Jovanovic   }
1338dde3d582SVladimir Medic 
1339dde3d582SVladimir Medic   return MCDisassembler::Success;
1340dde3d582SVladimir Medic }
1341dde3d582SVladimir Medic 
1342dde3d582SVladimir Medic static DecodeStatus DecodeMemMMImm16(MCInst &Inst,
1343dde3d582SVladimir Medic                                      unsigned Insn,
1344dde3d582SVladimir Medic                                      uint64_t Address,
1345dde3d582SVladimir Medic                                      const void *Decoder) {
1346dde3d582SVladimir Medic   int Offset = SignExtend32<16>(Insn & 0xffff);
1347dde3d582SVladimir Medic   unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1348dde3d582SVladimir Medic   unsigned Base = fieldFromInstruction(Insn, 16, 5);
1349dde3d582SVladimir Medic 
1350dde3d582SVladimir Medic   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1351dde3d582SVladimir Medic   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1352dde3d582SVladimir Medic 
1353dde3d582SVladimir Medic   Inst.addOperand(MCOperand::CreateReg(Reg));
1354dde3d582SVladimir Medic   Inst.addOperand(MCOperand::CreateReg(Base));
1355dde3d582SVladimir Medic   Inst.addOperand(MCOperand::CreateImm(Offset));
1356dde3d582SVladimir Medic 
1357dde3d582SVladimir Medic   return MCDisassembler::Success;
1358dde3d582SVladimir Medic }
1359dde3d582SVladimir Medic 
136071928e68SAkira Hatanaka static DecodeStatus DecodeFMem(MCInst &Inst,
136171928e68SAkira Hatanaka                                unsigned Insn,
136271928e68SAkira Hatanaka                                uint64_t Address,
136371928e68SAkira Hatanaka                                const void *Decoder) {
136471928e68SAkira Hatanaka   int Offset = SignExtend32<16>(Insn & 0xffff);
1365ecaef49fSJim Grosbach   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1366ecaef49fSJim Grosbach   unsigned Base = fieldFromInstruction(Insn, 21, 5);
136771928e68SAkira Hatanaka 
13689bf2b567SAkira Hatanaka   Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg);
136913e6ccf3SAkira Hatanaka   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
13709bf2b567SAkira Hatanaka 
13719bf2b567SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
13729bf2b567SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Base));
137371928e68SAkira Hatanaka   Inst.addOperand(MCOperand::CreateImm(Offset));
137471928e68SAkira Hatanaka 
137571928e68SAkira Hatanaka   return MCDisassembler::Success;
137671928e68SAkira Hatanaka }
137771928e68SAkira Hatanaka 
137892db6b78SDaniel Sanders static DecodeStatus DecodeFMem2(MCInst &Inst,
137992db6b78SDaniel Sanders                                unsigned Insn,
138092db6b78SDaniel Sanders                                uint64_t Address,
138192db6b78SDaniel Sanders                                const void *Decoder) {
138292db6b78SDaniel Sanders   int Offset = SignExtend32<16>(Insn & 0xffff);
138392db6b78SDaniel Sanders   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
138492db6b78SDaniel Sanders   unsigned Base = fieldFromInstruction(Insn, 21, 5);
138592db6b78SDaniel Sanders 
138692db6b78SDaniel Sanders   Reg = getReg(Decoder, Mips::COP2RegClassID, Reg);
138792db6b78SDaniel Sanders   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
138892db6b78SDaniel Sanders 
138992db6b78SDaniel Sanders   Inst.addOperand(MCOperand::CreateReg(Reg));
139092db6b78SDaniel Sanders   Inst.addOperand(MCOperand::CreateReg(Base));
139192db6b78SDaniel Sanders   Inst.addOperand(MCOperand::CreateImm(Offset));
139292db6b78SDaniel Sanders 
139392db6b78SDaniel Sanders   return MCDisassembler::Success;
139492db6b78SDaniel Sanders }
139592db6b78SDaniel Sanders 
139692db6b78SDaniel Sanders static DecodeStatus DecodeFMem3(MCInst &Inst,
139792db6b78SDaniel Sanders                                unsigned Insn,
139892db6b78SDaniel Sanders                                uint64_t Address,
139992db6b78SDaniel Sanders                                const void *Decoder) {
140092db6b78SDaniel Sanders   int Offset = SignExtend32<16>(Insn & 0xffff);
140192db6b78SDaniel Sanders   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
140292db6b78SDaniel Sanders   unsigned Base = fieldFromInstruction(Insn, 21, 5);
140392db6b78SDaniel Sanders 
140492db6b78SDaniel Sanders   Reg = getReg(Decoder, Mips::COP3RegClassID, Reg);
140592db6b78SDaniel Sanders   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
140692db6b78SDaniel Sanders 
140792db6b78SDaniel Sanders   Inst.addOperand(MCOperand::CreateReg(Reg));
140892db6b78SDaniel Sanders   Inst.addOperand(MCOperand::CreateReg(Base));
140992db6b78SDaniel Sanders   Inst.addOperand(MCOperand::CreateImm(Offset));
141092db6b78SDaniel Sanders 
141192db6b78SDaniel Sanders   return MCDisassembler::Success;
141292db6b78SDaniel Sanders }
141392db6b78SDaniel Sanders 
1414435cf8a4SVladimir Medic static DecodeStatus DecodeFMemCop2R6(MCInst &Inst,
1415435cf8a4SVladimir Medic                                     unsigned Insn,
1416435cf8a4SVladimir Medic                                     uint64_t Address,
1417435cf8a4SVladimir Medic                                     const void *Decoder) {
1418435cf8a4SVladimir Medic   int Offset = SignExtend32<11>(Insn & 0x07ff);
1419435cf8a4SVladimir Medic   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1420435cf8a4SVladimir Medic   unsigned Base = fieldFromInstruction(Insn, 11, 5);
1421435cf8a4SVladimir Medic 
1422435cf8a4SVladimir Medic   Reg = getReg(Decoder, Mips::COP2RegClassID, Reg);
1423435cf8a4SVladimir Medic   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1424435cf8a4SVladimir Medic 
1425435cf8a4SVladimir Medic   Inst.addOperand(MCOperand::CreateReg(Reg));
1426435cf8a4SVladimir Medic   Inst.addOperand(MCOperand::CreateReg(Base));
1427435cf8a4SVladimir Medic   Inst.addOperand(MCOperand::CreateImm(Offset));
1428435cf8a4SVladimir Medic 
1429435cf8a4SVladimir Medic   return MCDisassembler::Success;
1430435cf8a4SVladimir Medic }
14316a803f61SDaniel Sanders static DecodeStatus DecodeSpecial3LlSc(MCInst &Inst,
14326a803f61SDaniel Sanders                                        unsigned Insn,
14336a803f61SDaniel Sanders                                        uint64_t Address,
14346a803f61SDaniel Sanders                                        const void *Decoder) {
14356a803f61SDaniel Sanders   int64_t Offset = SignExtend64<9>((Insn >> 7) & 0x1ff);
14366a803f61SDaniel Sanders   unsigned Rt = fieldFromInstruction(Insn, 16, 5);
14376a803f61SDaniel Sanders   unsigned Base = fieldFromInstruction(Insn, 21, 5);
14386a803f61SDaniel Sanders 
14396a803f61SDaniel Sanders   Rt = getReg(Decoder, Mips::GPR32RegClassID, Rt);
14406a803f61SDaniel Sanders   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
14416a803f61SDaniel Sanders 
14426a803f61SDaniel Sanders   if(Inst.getOpcode() == Mips::SC_R6 || Inst.getOpcode() == Mips::SCD_R6){
14436a803f61SDaniel Sanders     Inst.addOperand(MCOperand::CreateReg(Rt));
14446a803f61SDaniel Sanders   }
14456a803f61SDaniel Sanders 
14466a803f61SDaniel Sanders   Inst.addOperand(MCOperand::CreateReg(Rt));
14476a803f61SDaniel Sanders   Inst.addOperand(MCOperand::CreateReg(Base));
14486a803f61SDaniel Sanders   Inst.addOperand(MCOperand::CreateImm(Offset));
14496a803f61SDaniel Sanders 
14506a803f61SDaniel Sanders   return MCDisassembler::Success;
14516a803f61SDaniel Sanders }
145271928e68SAkira Hatanaka 
145371928e68SAkira Hatanaka static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
145471928e68SAkira Hatanaka                                               unsigned RegNo,
145571928e68SAkira Hatanaka                                               uint64_t Address,
145671928e68SAkira Hatanaka                                               const void *Decoder) {
145771928e68SAkira Hatanaka   // Currently only hardware register 29 is supported.
145871928e68SAkira Hatanaka   if (RegNo != 29)
145971928e68SAkira Hatanaka     return  MCDisassembler::Fail;
146071928e68SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Mips::HWR29));
146171928e68SAkira Hatanaka   return MCDisassembler::Success;
146271928e68SAkira Hatanaka }
146371928e68SAkira Hatanaka 
146471928e68SAkira Hatanaka static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
146571928e68SAkira Hatanaka                                               unsigned RegNo,
146671928e68SAkira Hatanaka                                               uint64_t Address,
146771928e68SAkira Hatanaka                                               const void *Decoder) {
14689bf2b567SAkira Hatanaka   if (RegNo > 30 || RegNo %2)
146971928e68SAkira Hatanaka     return MCDisassembler::Fail;
147071928e68SAkira Hatanaka 
14719bf2b567SAkira Hatanaka   ;
14729bf2b567SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::AFGR64RegClassID, RegNo /2);
14739bf2b567SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
147471928e68SAkira Hatanaka   return MCDisassembler::Success;
147571928e68SAkira Hatanaka }
147671928e68SAkira Hatanaka 
147700fcf2e1SAkira Hatanaka static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst,
1478ecabd1a5SAkira Hatanaka                                                 unsigned RegNo,
1479ecabd1a5SAkira Hatanaka                                                 uint64_t Address,
1480ecabd1a5SAkira Hatanaka                                                 const void *Decoder) {
1481ecabd1a5SAkira Hatanaka   if (RegNo >= 4)
1482ecabd1a5SAkira Hatanaka     return MCDisassembler::Fail;
1483ecabd1a5SAkira Hatanaka 
148400fcf2e1SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::ACC64DSPRegClassID, RegNo);
1485ecabd1a5SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
1486ecabd1a5SAkira Hatanaka   return MCDisassembler::Success;
1487ecabd1a5SAkira Hatanaka }
1488ecabd1a5SAkira Hatanaka 
14898002a3f6SAkira Hatanaka static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst,
149059bfaf77SAkira Hatanaka                                                unsigned RegNo,
149159bfaf77SAkira Hatanaka                                                uint64_t Address,
149259bfaf77SAkira Hatanaka                                                const void *Decoder) {
149359bfaf77SAkira Hatanaka   if (RegNo >= 4)
149459bfaf77SAkira Hatanaka     return MCDisassembler::Fail;
149559bfaf77SAkira Hatanaka 
14968002a3f6SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::HI32DSPRegClassID, RegNo);
149759bfaf77SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
149859bfaf77SAkira Hatanaka   return MCDisassembler::Success;
149959bfaf77SAkira Hatanaka }
150059bfaf77SAkira Hatanaka 
15018002a3f6SAkira Hatanaka static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst,
150259bfaf77SAkira Hatanaka                                                unsigned RegNo,
150359bfaf77SAkira Hatanaka                                                uint64_t Address,
150459bfaf77SAkira Hatanaka                                                const void *Decoder) {
150559bfaf77SAkira Hatanaka   if (RegNo >= 4)
150659bfaf77SAkira Hatanaka     return MCDisassembler::Fail;
150759bfaf77SAkira Hatanaka 
15088002a3f6SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::LO32DSPRegClassID, RegNo);
150959bfaf77SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
151059bfaf77SAkira Hatanaka   return MCDisassembler::Success;
151159bfaf77SAkira Hatanaka }
151259bfaf77SAkira Hatanaka 
15133eb663b0SJack Carter static DecodeStatus DecodeMSA128BRegisterClass(MCInst &Inst,
15143eb663b0SJack Carter                                                unsigned RegNo,
15153eb663b0SJack Carter                                                uint64_t Address,
15163eb663b0SJack Carter                                                const void *Decoder) {
15173eb663b0SJack Carter   if (RegNo > 31)
15183eb663b0SJack Carter     return MCDisassembler::Fail;
15193eb663b0SJack Carter 
15203eb663b0SJack Carter   unsigned Reg = getReg(Decoder, Mips::MSA128BRegClassID, RegNo);
15213eb663b0SJack Carter   Inst.addOperand(MCOperand::CreateReg(Reg));
15223eb663b0SJack Carter   return MCDisassembler::Success;
15233eb663b0SJack Carter }
15243eb663b0SJack Carter 
15255dc8ac92SJack Carter static DecodeStatus DecodeMSA128HRegisterClass(MCInst &Inst,
15265dc8ac92SJack Carter                                                unsigned RegNo,
15275dc8ac92SJack Carter                                                uint64_t Address,
15285dc8ac92SJack Carter                                                const void *Decoder) {
15295dc8ac92SJack Carter   if (RegNo > 31)
15305dc8ac92SJack Carter     return MCDisassembler::Fail;
15315dc8ac92SJack Carter 
15325dc8ac92SJack Carter   unsigned Reg = getReg(Decoder, Mips::MSA128HRegClassID, RegNo);
15335dc8ac92SJack Carter   Inst.addOperand(MCOperand::CreateReg(Reg));
15345dc8ac92SJack Carter   return MCDisassembler::Success;
15355dc8ac92SJack Carter }
15365dc8ac92SJack Carter 
15375dc8ac92SJack Carter static DecodeStatus DecodeMSA128WRegisterClass(MCInst &Inst,
15385dc8ac92SJack Carter                                                unsigned RegNo,
15395dc8ac92SJack Carter                                                uint64_t Address,
15405dc8ac92SJack Carter                                                const void *Decoder) {
15415dc8ac92SJack Carter   if (RegNo > 31)
15425dc8ac92SJack Carter     return MCDisassembler::Fail;
15435dc8ac92SJack Carter 
15445dc8ac92SJack Carter   unsigned Reg = getReg(Decoder, Mips::MSA128WRegClassID, RegNo);
15455dc8ac92SJack Carter   Inst.addOperand(MCOperand::CreateReg(Reg));
15465dc8ac92SJack Carter   return MCDisassembler::Success;
15475dc8ac92SJack Carter }
15485dc8ac92SJack Carter 
15495dc8ac92SJack Carter static DecodeStatus DecodeMSA128DRegisterClass(MCInst &Inst,
15505dc8ac92SJack Carter                                                unsigned RegNo,
15515dc8ac92SJack Carter                                                uint64_t Address,
15525dc8ac92SJack Carter                                                const void *Decoder) {
15535dc8ac92SJack Carter   if (RegNo > 31)
15545dc8ac92SJack Carter     return MCDisassembler::Fail;
15555dc8ac92SJack Carter 
15565dc8ac92SJack Carter   unsigned Reg = getReg(Decoder, Mips::MSA128DRegClassID, RegNo);
15575dc8ac92SJack Carter   Inst.addOperand(MCOperand::CreateReg(Reg));
15585dc8ac92SJack Carter   return MCDisassembler::Success;
15595dc8ac92SJack Carter }
15605dc8ac92SJack Carter 
1561a591fdc6SMatheus Almeida static DecodeStatus DecodeMSACtrlRegisterClass(MCInst &Inst,
1562a591fdc6SMatheus Almeida                                                unsigned RegNo,
1563a591fdc6SMatheus Almeida                                                uint64_t Address,
1564a591fdc6SMatheus Almeida                                                const void *Decoder) {
1565a591fdc6SMatheus Almeida   if (RegNo > 7)
1566a591fdc6SMatheus Almeida     return MCDisassembler::Fail;
1567a591fdc6SMatheus Almeida 
1568a591fdc6SMatheus Almeida   unsigned Reg = getReg(Decoder, Mips::MSACtrlRegClassID, RegNo);
1569a591fdc6SMatheus Almeida   Inst.addOperand(MCOperand::CreateReg(Reg));
1570a591fdc6SMatheus Almeida   return MCDisassembler::Success;
1571a591fdc6SMatheus Almeida }
1572a591fdc6SMatheus Almeida 
15732a83d680SDaniel Sanders static DecodeStatus DecodeCOP2RegisterClass(MCInst &Inst,
15742a83d680SDaniel Sanders                                             unsigned RegNo,
15752a83d680SDaniel Sanders                                             uint64_t Address,
15762a83d680SDaniel Sanders                                             const void *Decoder) {
15772a83d680SDaniel Sanders   if (RegNo > 31)
15782a83d680SDaniel Sanders     return MCDisassembler::Fail;
15792a83d680SDaniel Sanders 
15802a83d680SDaniel Sanders   unsigned Reg = getReg(Decoder, Mips::COP2RegClassID, RegNo);
15812a83d680SDaniel Sanders   Inst.addOperand(MCOperand::CreateReg(Reg));
15822a83d680SDaniel Sanders   return MCDisassembler::Success;
15832a83d680SDaniel Sanders }
15842a83d680SDaniel Sanders 
158571928e68SAkira Hatanaka static DecodeStatus DecodeBranchTarget(MCInst &Inst,
158671928e68SAkira Hatanaka                                        unsigned Offset,
158771928e68SAkira Hatanaka                                        uint64_t Address,
158871928e68SAkira Hatanaka                                        const void *Decoder) {
1589d37bab61SAlexey Samsonov   int32_t BranchOffset = (SignExtend32<16>(Offset) * 4) + 4;
159071928e68SAkira Hatanaka   Inst.addOperand(MCOperand::CreateImm(BranchOffset));
159171928e68SAkira Hatanaka   return MCDisassembler::Success;
159271928e68SAkira Hatanaka }
159371928e68SAkira Hatanaka 
159471928e68SAkira Hatanaka static DecodeStatus DecodeJumpTarget(MCInst &Inst,
159571928e68SAkira Hatanaka                                      unsigned Insn,
159671928e68SAkira Hatanaka                                      uint64_t Address,
159771928e68SAkira Hatanaka                                      const void *Decoder) {
159871928e68SAkira Hatanaka 
1599ecaef49fSJim Grosbach   unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 2;
160071928e68SAkira Hatanaka   Inst.addOperand(MCOperand::CreateImm(JumpOffset));
160171928e68SAkira Hatanaka   return MCDisassembler::Success;
160271928e68SAkira Hatanaka }
160371928e68SAkira Hatanaka 
16043c8869dcSZoran Jovanovic static DecodeStatus DecodeBranchTarget21(MCInst &Inst,
16053c8869dcSZoran Jovanovic                                          unsigned Offset,
16063c8869dcSZoran Jovanovic                                          uint64_t Address,
16073c8869dcSZoran Jovanovic                                          const void *Decoder) {
1608d37bab61SAlexey Samsonov   int32_t BranchOffset = SignExtend32<21>(Offset) * 4;
16093c8869dcSZoran Jovanovic 
16103c8869dcSZoran Jovanovic   Inst.addOperand(MCOperand::CreateImm(BranchOffset));
16113c8869dcSZoran Jovanovic   return MCDisassembler::Success;
16123c8869dcSZoran Jovanovic }
16133c8869dcSZoran Jovanovic 
16143c8869dcSZoran Jovanovic static DecodeStatus DecodeBranchTarget26(MCInst &Inst,
16153c8869dcSZoran Jovanovic                                          unsigned Offset,
16163c8869dcSZoran Jovanovic                                          uint64_t Address,
16173c8869dcSZoran Jovanovic                                          const void *Decoder) {
1618d37bab61SAlexey Samsonov   int32_t BranchOffset = SignExtend32<26>(Offset) * 4;
16193c8869dcSZoran Jovanovic 
16203c8869dcSZoran Jovanovic   Inst.addOperand(MCOperand::CreateImm(BranchOffset));
16213c8869dcSZoran Jovanovic   return MCDisassembler::Success;
16223c8869dcSZoran Jovanovic }
16233c8869dcSZoran Jovanovic 
16249761e96bSJozef Kolek static DecodeStatus DecodeBranchTarget7MM(MCInst &Inst,
16259761e96bSJozef Kolek                                           unsigned Offset,
16269761e96bSJozef Kolek                                           uint64_t Address,
16279761e96bSJozef Kolek                                           const void *Decoder) {
16289761e96bSJozef Kolek   int32_t BranchOffset = SignExtend32<7>(Offset) << 1;
16299761e96bSJozef Kolek   Inst.addOperand(MCOperand::CreateImm(BranchOffset));
16309761e96bSJozef Kolek   return MCDisassembler::Success;
16319761e96bSJozef Kolek }
16329761e96bSJozef Kolek 
16335cfebddeSJozef Kolek static DecodeStatus DecodeBranchTarget10MM(MCInst &Inst,
16345cfebddeSJozef Kolek                                            unsigned Offset,
16355cfebddeSJozef Kolek                                            uint64_t Address,
16365cfebddeSJozef Kolek                                            const void *Decoder) {
16375cfebddeSJozef Kolek   int32_t BranchOffset = SignExtend32<10>(Offset) << 1;
16385cfebddeSJozef Kolek   Inst.addOperand(MCOperand::CreateImm(BranchOffset));
16395cfebddeSJozef Kolek   return MCDisassembler::Success;
16405cfebddeSJozef Kolek }
16415cfebddeSJozef Kolek 
16428a80aa76SZoran Jovanovic static DecodeStatus DecodeBranchTargetMM(MCInst &Inst,
16438a80aa76SZoran Jovanovic                                          unsigned Offset,
16448a80aa76SZoran Jovanovic                                          uint64_t Address,
16458a80aa76SZoran Jovanovic                                          const void *Decoder) {
1646d37bab61SAlexey Samsonov   int32_t BranchOffset = SignExtend32<16>(Offset) * 2;
16478a80aa76SZoran Jovanovic   Inst.addOperand(MCOperand::CreateImm(BranchOffset));
16488a80aa76SZoran Jovanovic   return MCDisassembler::Success;
16498a80aa76SZoran Jovanovic }
16508a80aa76SZoran Jovanovic 
1651507e084aSZoran Jovanovic static DecodeStatus DecodeJumpTargetMM(MCInst &Inst,
1652507e084aSZoran Jovanovic                                        unsigned Insn,
1653507e084aSZoran Jovanovic                                        uint64_t Address,
1654507e084aSZoran Jovanovic                                        const void *Decoder) {
1655507e084aSZoran Jovanovic   unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 1;
1656507e084aSZoran Jovanovic   Inst.addOperand(MCOperand::CreateImm(JumpOffset));
1657507e084aSZoran Jovanovic   return MCDisassembler::Success;
1658507e084aSZoran Jovanovic }
165971928e68SAkira Hatanaka 
1660aa2b9278SJozef Kolek static DecodeStatus DecodeAddiur2Simm7(MCInst &Inst,
1661aa2b9278SJozef Kolek                                        unsigned Value,
1662aa2b9278SJozef Kolek                                        uint64_t Address,
1663aa2b9278SJozef Kolek                                        const void *Decoder) {
1664aa2b9278SJozef Kolek   if (Value == 0)
1665aa2b9278SJozef Kolek     Inst.addOperand(MCOperand::CreateImm(1));
1666aa2b9278SJozef Kolek   else if (Value == 0x7)
1667aa2b9278SJozef Kolek     Inst.addOperand(MCOperand::CreateImm(-1));
1668aa2b9278SJozef Kolek   else
1669aa2b9278SJozef Kolek     Inst.addOperand(MCOperand::CreateImm(Value << 2));
1670aa2b9278SJozef Kolek   return MCDisassembler::Success;
1671aa2b9278SJozef Kolek }
1672aa2b9278SJozef Kolek 
1673aa2b9278SJozef Kolek static DecodeStatus DecodeUImm6Lsl2(MCInst &Inst,
1674aa2b9278SJozef Kolek                                     unsigned Value,
1675aa2b9278SJozef Kolek                                     uint64_t Address,
1676aa2b9278SJozef Kolek                                     const void *Decoder) {
1677aa2b9278SJozef Kolek   Inst.addOperand(MCOperand::CreateImm(Value << 2));
1678aa2b9278SJozef Kolek   return MCDisassembler::Success;
1679aa2b9278SJozef Kolek }
1680aa2b9278SJozef Kolek 
1681aa2b9278SJozef Kolek static DecodeStatus DecodeLiSimm7(MCInst &Inst,
1682aa2b9278SJozef Kolek                                   unsigned Value,
1683aa2b9278SJozef Kolek                                   uint64_t Address,
1684aa2b9278SJozef Kolek                                   const void *Decoder) {
1685aa2b9278SJozef Kolek   if (Value == 0x7F)
1686aa2b9278SJozef Kolek     Inst.addOperand(MCOperand::CreateImm(-1));
1687aa2b9278SJozef Kolek   else
1688aa2b9278SJozef Kolek     Inst.addOperand(MCOperand::CreateImm(Value));
1689aa2b9278SJozef Kolek   return MCDisassembler::Success;
1690aa2b9278SJozef Kolek }
1691aa2b9278SJozef Kolek 
1692aa2b9278SJozef Kolek static DecodeStatus DecodeSimm4(MCInst &Inst,
1693aa2b9278SJozef Kolek                                 unsigned Value,
1694aa2b9278SJozef Kolek                                 uint64_t Address,
1695aa2b9278SJozef Kolek                                 const void *Decoder) {
1696aa2b9278SJozef Kolek   Inst.addOperand(MCOperand::CreateImm(SignExtend32<4>(Value)));
1697aa2b9278SJozef Kolek   return MCDisassembler::Success;
1698aa2b9278SJozef Kolek }
1699aa2b9278SJozef Kolek 
170071928e68SAkira Hatanaka static DecodeStatus DecodeSimm16(MCInst &Inst,
170171928e68SAkira Hatanaka                                  unsigned Insn,
170271928e68SAkira Hatanaka                                  uint64_t Address,
170371928e68SAkira Hatanaka                                  const void *Decoder) {
170471928e68SAkira Hatanaka   Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Insn)));
170571928e68SAkira Hatanaka   return MCDisassembler::Success;
170671928e68SAkira Hatanaka }
170771928e68SAkira Hatanaka 
1708779c5937SMatheus Almeida static DecodeStatus DecodeLSAImm(MCInst &Inst,
1709779c5937SMatheus Almeida                                  unsigned Insn,
1710779c5937SMatheus Almeida                                  uint64_t Address,
1711779c5937SMatheus Almeida                                  const void *Decoder) {
1712779c5937SMatheus Almeida   // We add one to the immediate field as it was encoded as 'imm - 1'.
1713779c5937SMatheus Almeida   Inst.addOperand(MCOperand::CreateImm(Insn + 1));
1714779c5937SMatheus Almeida   return MCDisassembler::Success;
1715779c5937SMatheus Almeida }
1716779c5937SMatheus Almeida 
171771928e68SAkira Hatanaka static DecodeStatus DecodeInsSize(MCInst &Inst,
171871928e68SAkira Hatanaka                                   unsigned Insn,
171971928e68SAkira Hatanaka                                   uint64_t Address,
172071928e68SAkira Hatanaka                                   const void *Decoder) {
172171928e68SAkira Hatanaka   // First we need to grab the pos(lsb) from MCInst.
172271928e68SAkira Hatanaka   int Pos = Inst.getOperand(2).getImm();
172371928e68SAkira Hatanaka   int Size = (int) Insn - Pos + 1;
172471928e68SAkira Hatanaka   Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size)));
172571928e68SAkira Hatanaka   return MCDisassembler::Success;
172671928e68SAkira Hatanaka }
172771928e68SAkira Hatanaka 
172871928e68SAkira Hatanaka static DecodeStatus DecodeExtSize(MCInst &Inst,
172971928e68SAkira Hatanaka                                   unsigned Insn,
173071928e68SAkira Hatanaka                                   uint64_t Address,
173171928e68SAkira Hatanaka                                   const void *Decoder) {
173271928e68SAkira Hatanaka   int Size = (int) Insn  + 1;
173371928e68SAkira Hatanaka   Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size)));
173471928e68SAkira Hatanaka   return MCDisassembler::Success;
173571928e68SAkira Hatanaka }
1736b59e1a41SDaniel Sanders 
1737b59e1a41SDaniel Sanders static DecodeStatus DecodeSimm19Lsl2(MCInst &Inst, unsigned Insn,
1738b59e1a41SDaniel Sanders                                      uint64_t Address, const void *Decoder) {
1739d37bab61SAlexey Samsonov   Inst.addOperand(MCOperand::CreateImm(SignExtend32<19>(Insn) * 4));
1740b59e1a41SDaniel Sanders   return MCDisassembler::Success;
1741b59e1a41SDaniel Sanders }
17422855142aSZoran Jovanovic 
17432855142aSZoran Jovanovic static DecodeStatus DecodeSimm18Lsl3(MCInst &Inst, unsigned Insn,
17442855142aSZoran Jovanovic                                      uint64_t Address, const void *Decoder) {
1745d37bab61SAlexey Samsonov   Inst.addOperand(MCOperand::CreateImm(SignExtend32<18>(Insn) * 8));
17462855142aSZoran Jovanovic   return MCDisassembler::Success;
17472855142aSZoran Jovanovic }
1748a4c4b5fcSZoran Jovanovic 
1749b682ddf3SVladimir Medic static DecodeStatus DecodeSimm9SP(MCInst &Inst, unsigned Insn,
1750b682ddf3SVladimir Medic                                   uint64_t Address, const void *Decoder) {
1751b682ddf3SVladimir Medic   int32_t DecodedValue;
1752b682ddf3SVladimir Medic   switch (Insn) {
1753b682ddf3SVladimir Medic   case 0: DecodedValue = 256; break;
1754b682ddf3SVladimir Medic   case 1: DecodedValue = 257; break;
1755b682ddf3SVladimir Medic   case 510: DecodedValue = -258; break;
1756b682ddf3SVladimir Medic   case 511: DecodedValue = -257; break;
1757b682ddf3SVladimir Medic   default: DecodedValue = SignExtend32<9>(Insn); break;
1758b682ddf3SVladimir Medic   }
17592c55974dSAlexey Samsonov   Inst.addOperand(MCOperand::CreateImm(DecodedValue * 4));
1760b682ddf3SVladimir Medic   return MCDisassembler::Success;
1761b682ddf3SVladimir Medic }
1762b682ddf3SVladimir Medic 
1763b682ddf3SVladimir Medic static DecodeStatus DecodeANDI16Imm(MCInst &Inst, unsigned Insn,
1764b682ddf3SVladimir Medic                                     uint64_t Address, const void *Decoder) {
1765b682ddf3SVladimir Medic   // Insn must be >= 0, since it is unsigned that condition is always true.
1766b682ddf3SVladimir Medic   assert(Insn < 16);
1767b682ddf3SVladimir Medic   int32_t DecodedValues[] = {128, 1, 2, 3, 4, 7, 8, 15, 16, 31, 32, 63, 64,
1768b682ddf3SVladimir Medic                              255, 32768, 65535};
1769b682ddf3SVladimir Medic   Inst.addOperand(MCOperand::CreateImm(DecodedValues[Insn]));
1770b682ddf3SVladimir Medic   return MCDisassembler::Success;
1771b682ddf3SVladimir Medic }
1772b682ddf3SVladimir Medic 
1773b682ddf3SVladimir Medic static DecodeStatus DecodeUImm5lsl2(MCInst &Inst, unsigned Insn,
1774b682ddf3SVladimir Medic                                     uint64_t Address, const void *Decoder) {
1775b682ddf3SVladimir Medic   Inst.addOperand(MCOperand::CreateImm(Insn << 2));
1776b682ddf3SVladimir Medic   return MCDisassembler::Success;
1777b682ddf3SVladimir Medic }
1778b682ddf3SVladimir Medic 
1779a4c4b5fcSZoran Jovanovic static DecodeStatus DecodeRegListOperand(MCInst &Inst,
1780a4c4b5fcSZoran Jovanovic                                          unsigned Insn,
1781a4c4b5fcSZoran Jovanovic                                          uint64_t Address,
1782a4c4b5fcSZoran Jovanovic                                          const void *Decoder) {
1783a4c4b5fcSZoran Jovanovic   unsigned Regs[] = {Mips::S0, Mips::S1, Mips::S2, Mips::S3, Mips::S4, Mips::S5,
1784a4c4b5fcSZoran Jovanovic                      Mips::S6, Mips::FP};
1785a4c4b5fcSZoran Jovanovic   unsigned RegNum;
1786a4c4b5fcSZoran Jovanovic 
1787a4c4b5fcSZoran Jovanovic   unsigned RegLst = fieldFromInstruction(Insn, 21, 5);
1788a4c4b5fcSZoran Jovanovic   // Empty register lists are not allowed.
1789a4c4b5fcSZoran Jovanovic   if (RegLst == 0)
1790a4c4b5fcSZoran Jovanovic     return MCDisassembler::Fail;
1791a4c4b5fcSZoran Jovanovic 
1792a4c4b5fcSZoran Jovanovic   RegNum = RegLst & 0xf;
1793a4c4b5fcSZoran Jovanovic   for (unsigned i = 0; i < RegNum; i++)
1794a4c4b5fcSZoran Jovanovic     Inst.addOperand(MCOperand::CreateReg(Regs[i]));
1795a4c4b5fcSZoran Jovanovic 
1796a4c4b5fcSZoran Jovanovic   if (RegLst & 0x10)
1797a4c4b5fcSZoran Jovanovic     Inst.addOperand(MCOperand::CreateReg(Mips::RA));
1798a4c4b5fcSZoran Jovanovic 
1799a4c4b5fcSZoran Jovanovic   return MCDisassembler::Success;
1800a4c4b5fcSZoran Jovanovic }
1801f9a02500SZoran Jovanovic 
1802f9a02500SZoran Jovanovic static DecodeStatus DecodeRegListOperand16(MCInst &Inst, unsigned Insn,
1803f9a02500SZoran Jovanovic                                            uint64_t Address,
1804f9a02500SZoran Jovanovic                                            const void *Decoder) {
1805f9a02500SZoran Jovanovic   unsigned Regs[] = {Mips::S0, Mips::S1, Mips::S2, Mips::S3};
1806f9a02500SZoran Jovanovic   unsigned RegNum;
1807f9a02500SZoran Jovanovic 
1808f9a02500SZoran Jovanovic   unsigned RegLst = fieldFromInstruction(Insn, 4, 2);
1809f9a02500SZoran Jovanovic   // Empty register lists are not allowed.
1810f9a02500SZoran Jovanovic   if (RegLst == 0)
1811f9a02500SZoran Jovanovic     return MCDisassembler::Fail;
1812f9a02500SZoran Jovanovic 
1813f9a02500SZoran Jovanovic   RegNum = RegLst & 0x3;
1814f9a02500SZoran Jovanovic   for (unsigned i = 0; i < RegNum - 1; i++)
1815f9a02500SZoran Jovanovic     Inst.addOperand(MCOperand::CreateReg(Regs[i]));
1816f9a02500SZoran Jovanovic 
1817f9a02500SZoran Jovanovic   Inst.addOperand(MCOperand::CreateReg(Mips::RA));
1818f9a02500SZoran Jovanovic 
1819f9a02500SZoran Jovanovic   return MCDisassembler::Success;
1820f9a02500SZoran Jovanovic }
18212c6d7320SJozef Kolek 
18222c6d7320SJozef Kolek static DecodeStatus DecodeSimm23Lsl2(MCInst &Inst, unsigned Insn,
18232c6d7320SJozef Kolek                                      uint64_t Address, const void *Decoder) {
18242c6d7320SJozef Kolek   Inst.addOperand(MCOperand::CreateImm(SignExtend32<23>(Insn) << 2));
18252c6d7320SJozef Kolek   return MCDisassembler::Success;
18262c6d7320SJozef Kolek }
1827