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"
18f57c1977SBenjamin Kramer #include "llvm/MC/MCDisassembler/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 
33a19216c8SDaniel Sanders class MipsDisassembler : public MCDisassembler {
34dde3d582SVladimir Medic   bool IsMicroMips;
35a19216c8SDaniel Sanders   bool IsBigEndian;
369bf2b567SAkira Hatanaka public:
37a19216c8SDaniel Sanders   MipsDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx, bool IsBigEndian)
38a19216c8SDaniel Sanders       : MCDisassembler(STI, Ctx),
39db0712f9SMichael Kuperstein         IsMicroMips(STI.getFeatureBits()[Mips::FeatureMicroMips]),
40a19216c8SDaniel Sanders         IsBigEndian(IsBigEndian) {}
4171928e68SAkira Hatanaka 
424fbf76f7SSimon Dardis   bool hasMips2() const { return STI.getFeatureBits()[Mips::FeatureMips2]; }
43db0712f9SMichael Kuperstein   bool hasMips3() const { return STI.getFeatureBits()[Mips::FeatureMips3]; }
44db0712f9SMichael Kuperstein   bool hasMips32() const { return STI.getFeatureBits()[Mips::FeatureMips32]; }
45c171f65aSDaniel Sanders   bool hasMips32r6() const {
46db0712f9SMichael Kuperstein     return STI.getFeatureBits()[Mips::FeatureMips32r6];
475c582b2fSDaniel Sanders   }
486221be8eSZlatko Buljan   bool isFP64() const { return STI.getFeatureBits()[Mips::FeatureFP64Bit]; }
495c582b2fSDaniel Sanders 
50db0712f9SMichael Kuperstein   bool isGP64() const { return STI.getFeatureBits()[Mips::FeatureGP64Bit]; }
510fa60416SDaniel Sanders 
524fbf76f7SSimon Dardis   bool isPTR64() const { return STI.getFeatureBits()[Mips::FeaturePTR64Bit]; }
534fbf76f7SSimon Dardis 
543adf9b8dSKai Nacke   bool hasCnMips() const { return STI.getFeatureBits()[Mips::FeatureCnMips]; }
553adf9b8dSKai Nacke 
56c171f65aSDaniel Sanders   bool hasCOP3() const {
57c171f65aSDaniel Sanders     // Only present in MIPS-I and MIPS-II
58c171f65aSDaniel Sanders     return !hasMips32() && !hasMips3();
59c171f65aSDaniel Sanders   }
60c171f65aSDaniel Sanders 
614aa6bea7SRafael Espindola   DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
627fc5b874SRafael Espindola                               ArrayRef<uint8_t> Bytes, uint64_t Address,
634aa6bea7SRafael Espindola                               raw_ostream &VStream,
644aa6bea7SRafael Espindola                               raw_ostream &CStream) const override;
6571928e68SAkira Hatanaka };
6671928e68SAkira Hatanaka 
67cb3e98cfSBenjamin Kramer } // end anonymous namespace
68cb3e98cfSBenjamin Kramer 
6971928e68SAkira Hatanaka // Forward declare these because the autogenerated code will reference them.
7071928e68SAkira Hatanaka // Definitions are further down.
7113e6ccf3SAkira Hatanaka static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst,
7271928e68SAkira Hatanaka                                              unsigned RegNo,
7371928e68SAkira Hatanaka                                              uint64_t Address,
7471928e68SAkira Hatanaka                                              const void *Decoder);
7571928e68SAkira Hatanaka 
76ec8a5490SReed Kotler static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst,
77ec8a5490SReed Kotler                                                  unsigned RegNo,
78ec8a5490SReed Kotler                                                  uint64_t Address,
79ec8a5490SReed Kotler                                                  const void *Decoder);
80ec8a5490SReed Kotler 
81b0852e54SZoran Jovanovic static DecodeStatus DecodeGPRMM16RegisterClass(MCInst &Inst,
82b0852e54SZoran Jovanovic                                                unsigned RegNo,
83b0852e54SZoran Jovanovic                                                uint64_t Address,
84b0852e54SZoran Jovanovic                                                const void *Decoder);
85b0852e54SZoran Jovanovic 
861904fa21SJozef Kolek static DecodeStatus DecodeGPRMM16ZeroRegisterClass(MCInst &Inst,
871904fa21SJozef Kolek                                                    unsigned RegNo,
881904fa21SJozef Kolek                                                    uint64_t Address,
891904fa21SJozef Kolek                                                    const void *Decoder);
901904fa21SJozef Kolek 
9141688679SZoran Jovanovic static DecodeStatus DecodeGPRMM16MovePRegisterClass(MCInst &Inst,
9241688679SZoran Jovanovic                                                     unsigned RegNo,
9341688679SZoran Jovanovic                                                     uint64_t Address,
9441688679SZoran Jovanovic                                                     const void *Decoder);
9541688679SZoran Jovanovic 
9613e6ccf3SAkira Hatanaka static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst,
9771928e68SAkira Hatanaka                                              unsigned RegNo,
9871928e68SAkira Hatanaka                                              uint64_t Address,
9971928e68SAkira Hatanaka                                              const void *Decoder);
10071928e68SAkira Hatanaka 
1019bfa2e2eSAkira Hatanaka static DecodeStatus DecodePtrRegisterClass(MCInst &Inst,
1029bfa2e2eSAkira Hatanaka                                            unsigned Insn,
1039bfa2e2eSAkira Hatanaka                                            uint64_t Address,
1049bfa2e2eSAkira Hatanaka                                            const void *Decoder);
1059bfa2e2eSAkira Hatanaka 
106654655f1SAkira Hatanaka static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst,
107ecabd1a5SAkira Hatanaka                                             unsigned RegNo,
108ecabd1a5SAkira Hatanaka                                             uint64_t Address,
109ecabd1a5SAkira Hatanaka                                             const void *Decoder);
110ecabd1a5SAkira Hatanaka 
11171928e68SAkira Hatanaka static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
11271928e68SAkira Hatanaka                                              unsigned RegNo,
11371928e68SAkira Hatanaka                                              uint64_t Address,
11471928e68SAkira Hatanaka                                              const void *Decoder);
11571928e68SAkira Hatanaka 
11671928e68SAkira Hatanaka static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
11771928e68SAkira Hatanaka                                              unsigned RegNo,
11871928e68SAkira Hatanaka                                              uint64_t Address,
11971928e68SAkira Hatanaka                                              const void *Decoder);
12071928e68SAkira Hatanaka 
12171928e68SAkira Hatanaka static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
12271928e68SAkira Hatanaka                                            unsigned RegNo,
12371928e68SAkira Hatanaka                                            uint64_t Address,
12471928e68SAkira Hatanaka                                            const void *Decoder);
12571928e68SAkira Hatanaka 
1261fb1b8b8SAkira Hatanaka static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst,
1271fb1b8b8SAkira Hatanaka                                            unsigned RegNo,
1281fb1b8b8SAkira Hatanaka                                            uint64_t Address,
1291fb1b8b8SAkira Hatanaka                                            const void *Decoder);
1301fb1b8b8SAkira Hatanaka 
13136901dd1SVasileios Kalintiris static DecodeStatus DecodeFGRCCRegisterClass(MCInst &Inst, unsigned RegNo,
1320fa60416SDaniel Sanders                                              uint64_t Address,
1330fa60416SDaniel Sanders                                              const void *Decoder);
1340fa60416SDaniel Sanders 
13571928e68SAkira Hatanaka static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
13671928e68SAkira Hatanaka                                               unsigned Insn,
13771928e68SAkira Hatanaka                                               uint64_t Address,
13871928e68SAkira Hatanaka                                               const void *Decoder);
13971928e68SAkira Hatanaka 
14071928e68SAkira Hatanaka static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
14171928e68SAkira Hatanaka                                               unsigned RegNo,
14271928e68SAkira Hatanaka                                               uint64_t Address,
14371928e68SAkira Hatanaka                                               const void *Decoder);
14471928e68SAkira Hatanaka 
14500fcf2e1SAkira Hatanaka static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst,
146ecabd1a5SAkira Hatanaka                                                 unsigned RegNo,
147ecabd1a5SAkira Hatanaka                                                 uint64_t Address,
148ecabd1a5SAkira Hatanaka                                                 const void *Decoder);
149ecabd1a5SAkira Hatanaka 
1508002a3f6SAkira Hatanaka static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst,
15159bfaf77SAkira Hatanaka                                                unsigned RegNo,
15259bfaf77SAkira Hatanaka                                                uint64_t Address,
15359bfaf77SAkira Hatanaka                                                const void *Decoder);
15459bfaf77SAkira Hatanaka 
1558002a3f6SAkira Hatanaka static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst,
15659bfaf77SAkira Hatanaka                                                unsigned RegNo,
15759bfaf77SAkira Hatanaka                                                uint64_t Address,
15859bfaf77SAkira Hatanaka                                                const void *Decoder);
15959bfaf77SAkira Hatanaka 
1603eb663b0SJack Carter static DecodeStatus DecodeMSA128BRegisterClass(MCInst &Inst,
1613eb663b0SJack Carter                                                unsigned RegNo,
1623eb663b0SJack Carter                                                uint64_t Address,
1633eb663b0SJack Carter                                                const void *Decoder);
1643eb663b0SJack Carter 
1655dc8ac92SJack Carter static DecodeStatus DecodeMSA128HRegisterClass(MCInst &Inst,
1665dc8ac92SJack Carter                                                unsigned RegNo,
1675dc8ac92SJack Carter                                                uint64_t Address,
1685dc8ac92SJack Carter                                                const void *Decoder);
1695dc8ac92SJack Carter 
1705dc8ac92SJack Carter static DecodeStatus DecodeMSA128WRegisterClass(MCInst &Inst,
1715dc8ac92SJack Carter                                                unsigned RegNo,
1725dc8ac92SJack Carter                                                uint64_t Address,
1735dc8ac92SJack Carter                                                const void *Decoder);
1745dc8ac92SJack Carter 
1755dc8ac92SJack Carter static DecodeStatus DecodeMSA128DRegisterClass(MCInst &Inst,
1765dc8ac92SJack Carter                                                unsigned RegNo,
1775dc8ac92SJack Carter                                                uint64_t Address,
1785dc8ac92SJack Carter                                                const void *Decoder);
1795dc8ac92SJack Carter 
180a591fdc6SMatheus Almeida static DecodeStatus DecodeMSACtrlRegisterClass(MCInst &Inst,
181a591fdc6SMatheus Almeida                                                unsigned RegNo,
182a591fdc6SMatheus Almeida                                                uint64_t Address,
183a591fdc6SMatheus Almeida                                                const void *Decoder);
184a591fdc6SMatheus Almeida 
185a3134faeSDaniel Sanders static DecodeStatus DecodeCOP0RegisterClass(MCInst &Inst,
186a3134faeSDaniel Sanders                                             unsigned RegNo,
187a3134faeSDaniel Sanders                                             uint64_t Address,
188a3134faeSDaniel Sanders                                             const void *Decoder);
189a3134faeSDaniel Sanders 
1902a83d680SDaniel Sanders static DecodeStatus DecodeCOP2RegisterClass(MCInst &Inst,
1912a83d680SDaniel Sanders                                             unsigned RegNo,
1922a83d680SDaniel Sanders                                             uint64_t Address,
1932a83d680SDaniel Sanders                                             const void *Decoder);
1942a83d680SDaniel Sanders 
19571928e68SAkira Hatanaka static DecodeStatus DecodeBranchTarget(MCInst &Inst,
19671928e68SAkira Hatanaka                                        unsigned Offset,
19771928e68SAkira Hatanaka                                        uint64_t Address,
19871928e68SAkira Hatanaka                                        const void *Decoder);
19971928e68SAkira Hatanaka 
2006f09cdfdSHrvoje Varga static DecodeStatus DecodeBranchTarget1SImm16(MCInst &Inst,
2016f09cdfdSHrvoje Varga                                               unsigned Offset,
2026f09cdfdSHrvoje Varga                                               uint64_t Address,
2036f09cdfdSHrvoje Varga                                               const void *Decoder);
2046f09cdfdSHrvoje Varga 
20571928e68SAkira Hatanaka static DecodeStatus DecodeJumpTarget(MCInst &Inst,
20671928e68SAkira Hatanaka                                      unsigned Insn,
20771928e68SAkira Hatanaka                                      uint64_t Address,
20871928e68SAkira Hatanaka                                      const void *Decoder);
20971928e68SAkira Hatanaka 
2103c8869dcSZoran Jovanovic static DecodeStatus DecodeBranchTarget21(MCInst &Inst,
2113c8869dcSZoran Jovanovic                                          unsigned Offset,
2123c8869dcSZoran Jovanovic                                          uint64_t Address,
2133c8869dcSZoran Jovanovic                                          const void *Decoder);
2143c8869dcSZoran Jovanovic 
21584e4d59eSZoran Jovanovic static DecodeStatus DecodeBranchTarget21MM(MCInst &Inst,
21684e4d59eSZoran Jovanovic                                            unsigned Offset,
21784e4d59eSZoran Jovanovic                                            uint64_t Address,
21884e4d59eSZoran Jovanovic                                            const void *Decoder);
21984e4d59eSZoran Jovanovic 
2203c8869dcSZoran Jovanovic static DecodeStatus DecodeBranchTarget26(MCInst &Inst,
2213c8869dcSZoran Jovanovic                                          unsigned Offset,
2223c8869dcSZoran Jovanovic                                          uint64_t Address,
2233c8869dcSZoran Jovanovic                                          const void *Decoder);
2243c8869dcSZoran Jovanovic 
2259761e96bSJozef Kolek // DecodeBranchTarget7MM - Decode microMIPS branch offset, which is
2269761e96bSJozef Kolek // shifted left by 1 bit.
2279761e96bSJozef Kolek static DecodeStatus DecodeBranchTarget7MM(MCInst &Inst,
2289761e96bSJozef Kolek                                           unsigned Offset,
2299761e96bSJozef Kolek                                           uint64_t Address,
2309761e96bSJozef Kolek                                           const void *Decoder);
2319761e96bSJozef Kolek 
2325cfebddeSJozef Kolek // DecodeBranchTarget10MM - Decode microMIPS branch offset, which is
2335cfebddeSJozef Kolek // shifted left by 1 bit.
2345cfebddeSJozef Kolek static DecodeStatus DecodeBranchTarget10MM(MCInst &Inst,
2355cfebddeSJozef Kolek                                            unsigned Offset,
2365cfebddeSJozef Kolek                                            uint64_t Address,
2375cfebddeSJozef Kolek                                            const void *Decoder);
2385cfebddeSJozef Kolek 
2398a80aa76SZoran Jovanovic // DecodeBranchTargetMM - Decode microMIPS branch offset, which is
2408a80aa76SZoran Jovanovic // shifted left by 1 bit.
2418a80aa76SZoran Jovanovic static DecodeStatus DecodeBranchTargetMM(MCInst &Inst,
2428a80aa76SZoran Jovanovic                                          unsigned Offset,
2438a80aa76SZoran Jovanovic                                          uint64_t Address,
2448a80aa76SZoran Jovanovic                                          const void *Decoder);
2458a80aa76SZoran Jovanovic 
246a887b361SZoran Jovanovic // DecodeBranchTarget26MM - Decode microMIPS branch offset, which is
247a887b361SZoran Jovanovic // shifted left by 1 bit.
248a887b361SZoran Jovanovic static DecodeStatus DecodeBranchTarget26MM(MCInst &Inst,
249a887b361SZoran Jovanovic                                            unsigned Offset,
250a887b361SZoran Jovanovic                                            uint64_t Address,
251a887b361SZoran Jovanovic                                            const void *Decoder);
252a887b361SZoran Jovanovic 
253507e084aSZoran Jovanovic // DecodeJumpTargetMM - Decode microMIPS jump target, which is
254507e084aSZoran Jovanovic // shifted left by 1 bit.
255507e084aSZoran Jovanovic static DecodeStatus DecodeJumpTargetMM(MCInst &Inst,
256507e084aSZoran Jovanovic                                        unsigned Insn,
257507e084aSZoran Jovanovic                                        uint64_t Address,
258507e084aSZoran Jovanovic                                        const void *Decoder);
259507e084aSZoran Jovanovic 
26071928e68SAkira Hatanaka static DecodeStatus DecodeMem(MCInst &Inst,
26171928e68SAkira Hatanaka                               unsigned Insn,
26271928e68SAkira Hatanaka                               uint64_t Address,
26371928e68SAkira Hatanaka                               const void *Decoder);
26471928e68SAkira Hatanaka 
265e4e83a7bSDaniel Sanders static DecodeStatus DecodeMemEVA(MCInst &Inst,
266e4e83a7bSDaniel Sanders                                  unsigned Insn,
267e4e83a7bSDaniel Sanders                                  uint64_t Address,
268e4e83a7bSDaniel Sanders                                  const void *Decoder);
269e4e83a7bSDaniel Sanders 
2703c88fbd3SHrvoje Varga static DecodeStatus DecodeLoadByte9(MCInst &Inst,
2713c88fbd3SHrvoje Varga                                     unsigned Insn,
2723c88fbd3SHrvoje Varga                                     uint64_t Address,
2733c88fbd3SHrvoje Varga                                     const void *Decoder);
2743c88fbd3SHrvoje Varga 
2753c88fbd3SHrvoje Varga static DecodeStatus DecodeLoadByte15(MCInst &Inst,
2763c88fbd3SHrvoje Varga                                      unsigned Insn,
2773c88fbd3SHrvoje Varga                                      uint64_t Address,
2783c88fbd3SHrvoje Varga                                      const void *Decoder);
2793c88fbd3SHrvoje Varga 
28092db6b78SDaniel Sanders static DecodeStatus DecodeCacheOp(MCInst &Inst,
28192db6b78SDaniel Sanders                               unsigned Insn,
28292db6b78SDaniel Sanders                               uint64_t Address,
28392db6b78SDaniel Sanders                               const void *Decoder);
28492db6b78SDaniel Sanders 
285e4e83a7bSDaniel Sanders static DecodeStatus DecodeCacheeOp_CacheOpR6(MCInst &Inst,
286df464ae2SVladimir Medic                                              unsigned Insn,
287df464ae2SVladimir Medic                                              uint64_t Address,
288df464ae2SVladimir Medic                                              const void *Decoder);
289df464ae2SVladimir Medic 
290ab6d1cceSJozef Kolek static DecodeStatus DecodeCacheOpMM(MCInst &Inst,
291ab6d1cceSJozef Kolek                                     unsigned Insn,
292ab6d1cceSJozef Kolek                                     uint64_t Address,
293ab6d1cceSJozef Kolek                                     const void *Decoder);
294ab6d1cceSJozef Kolek 
2959eaa30d2SZoran Jovanovic static DecodeStatus DecodeStoreEvaOpMM(MCInst &Inst,
2969eaa30d2SZoran Jovanovic                                        unsigned Insn,
2979eaa30d2SZoran Jovanovic                                        uint64_t Address,
2989eaa30d2SZoran Jovanovic                                        const void *Decoder);
2999eaa30d2SZoran Jovanovic 
300d9790793SZoran Jovanovic static DecodeStatus DecodePrefeOpMM(MCInst &Inst,
301d9790793SZoran Jovanovic                                     unsigned Insn,
302d9790793SZoran Jovanovic                                     uint64_t Address,
303d9790793SZoran Jovanovic                                     const void *Decoder);
304d9790793SZoran Jovanovic 
305b4484d62SDaniel Sanders static DecodeStatus DecodeSyncI(MCInst &Inst,
306b4484d62SDaniel Sanders                                 unsigned Insn,
307b4484d62SDaniel Sanders                                 uint64_t Address,
308b4484d62SDaniel Sanders                                 const void *Decoder);
309b4484d62SDaniel Sanders 
31018148671SHrvoje Varga static DecodeStatus DecodeSynciR6(MCInst &Inst,
31118148671SHrvoje Varga                                   unsigned Insn,
31218148671SHrvoje Varga                                   uint64_t Address,
31318148671SHrvoje Varga                                   const void *Decoder);
31418148671SHrvoje Varga 
315fe0bf9f6SMatheus Almeida static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn,
316fe0bf9f6SMatheus Almeida                                     uint64_t Address, const void *Decoder);
317fe0bf9f6SMatheus Almeida 
318315e7ecaSJozef Kolek static DecodeStatus DecodeMemMMImm4(MCInst &Inst,
319315e7ecaSJozef Kolek                                     unsigned Insn,
320315e7ecaSJozef Kolek                                     uint64_t Address,
321315e7ecaSJozef Kolek                                     const void *Decoder);
322315e7ecaSJozef Kolek 
32312c6982bSJozef Kolek static DecodeStatus DecodeMemMMSPImm5Lsl2(MCInst &Inst,
32412c6982bSJozef Kolek                                           unsigned Insn,
32512c6982bSJozef Kolek                                           uint64_t Address,
32612c6982bSJozef Kolek                                           const void *Decoder);
32712c6982bSJozef Kolek 
328e10a02ecSJozef Kolek static DecodeStatus DecodeMemMMGPImm7Lsl2(MCInst &Inst,
329e10a02ecSJozef Kolek                                           unsigned Insn,
330e10a02ecSJozef Kolek                                           uint64_t Address,
331e10a02ecSJozef Kolek                                           const void *Decoder);
332e10a02ecSJozef Kolek 
333d68d424aSJozef Kolek static DecodeStatus DecodeMemMMReglistImm4Lsl2(MCInst &Inst,
334d68d424aSJozef Kolek                                                unsigned Insn,
335d68d424aSJozef Kolek                                                uint64_t Address,
336d68d424aSJozef Kolek                                                const void *Decoder);
337d68d424aSJozef Kolek 
338a6593ff6SZoran Jovanovic static DecodeStatus DecodeMemMMImm9(MCInst &Inst,
339a6593ff6SZoran Jovanovic                                     unsigned Insn,
340a6593ff6SZoran Jovanovic                                     uint64_t Address,
341a6593ff6SZoran Jovanovic                                     const void *Decoder);
342a6593ff6SZoran Jovanovic 
343dde3d582SVladimir Medic static DecodeStatus DecodeMemMMImm12(MCInst &Inst,
344dde3d582SVladimir Medic                                      unsigned Insn,
345dde3d582SVladimir Medic                                      uint64_t Address,
346dde3d582SVladimir Medic                                      const void *Decoder);
347dde3d582SVladimir Medic 
348dde3d582SVladimir Medic static DecodeStatus DecodeMemMMImm16(MCInst &Inst,
349dde3d582SVladimir Medic                                      unsigned Insn,
350dde3d582SVladimir Medic                                      uint64_t Address,
351dde3d582SVladimir Medic                                      const void *Decoder);
352dde3d582SVladimir Medic 
35371928e68SAkira Hatanaka static DecodeStatus DecodeFMem(MCInst &Inst, unsigned Insn,
35471928e68SAkira Hatanaka                                uint64_t Address,
35571928e68SAkira Hatanaka                                const void *Decoder);
35671928e68SAkira Hatanaka 
357cba9f80bSZlatko Buljan static DecodeStatus DecodeFMemMMR2(MCInst &Inst, unsigned Insn,
358cba9f80bSZlatko Buljan                                    uint64_t Address,
359cba9f80bSZlatko Buljan                                    const void *Decoder);
360cba9f80bSZlatko Buljan 
36192db6b78SDaniel Sanders static DecodeStatus DecodeFMem2(MCInst &Inst, unsigned Insn,
36292db6b78SDaniel Sanders                                uint64_t Address,
36392db6b78SDaniel Sanders                                const void *Decoder);
36492db6b78SDaniel Sanders 
36592db6b78SDaniel Sanders static DecodeStatus DecodeFMem3(MCInst &Inst, unsigned Insn,
36692db6b78SDaniel Sanders                                uint64_t Address,
36792db6b78SDaniel Sanders                                const void *Decoder);
36892db6b78SDaniel Sanders 
369435cf8a4SVladimir Medic static DecodeStatus DecodeFMemCop2R6(MCInst &Inst, unsigned Insn,
370435cf8a4SVladimir Medic                                uint64_t Address,
371435cf8a4SVladimir Medic                                const void *Decoder);
372435cf8a4SVladimir Medic 
373cba9f80bSZlatko Buljan static DecodeStatus DecodeFMemCop2MMR6(MCInst &Inst, unsigned Insn,
374cba9f80bSZlatko Buljan                                        uint64_t Address,
375cba9f80bSZlatko Buljan                                        const void *Decoder);
376cba9f80bSZlatko Buljan 
3776a803f61SDaniel Sanders static DecodeStatus DecodeSpecial3LlSc(MCInst &Inst,
3786a803f61SDaniel Sanders                                        unsigned Insn,
3796a803f61SDaniel Sanders                                        uint64_t Address,
3806a803f61SDaniel Sanders                                        const void *Decoder);
3816a803f61SDaniel Sanders 
382aa2b9278SJozef Kolek static DecodeStatus DecodeAddiur2Simm7(MCInst &Inst,
383aa2b9278SJozef Kolek                                        unsigned Value,
384aa2b9278SJozef Kolek                                        uint64_t Address,
385aa2b9278SJozef Kolek                                        const void *Decoder);
386aa2b9278SJozef Kolek 
38797297770SDaniel Sanders static DecodeStatus DecodeLi16Imm(MCInst &Inst,
388aa2b9278SJozef Kolek                                   unsigned Value,
389aa2b9278SJozef Kolek                                   uint64_t Address,
390aa2b9278SJozef Kolek                                   const void *Decoder);
391aa2b9278SJozef Kolek 
3926b28f09dSZoran Jovanovic static DecodeStatus DecodePOOL16BEncodedField(MCInst &Inst,
3936b28f09dSZoran Jovanovic                                               unsigned Value,
3946b28f09dSZoran Jovanovic                                               uint64_t Address,
3956b28f09dSZoran Jovanovic                                               const void *Decoder);
3966b28f09dSZoran Jovanovic 
39719b7f76aSDaniel Sanders template <unsigned Bits, int Offset, int Scale>
39819b7f76aSDaniel Sanders static DecodeStatus DecodeUImmWithOffsetAndScale(MCInst &Inst, unsigned Value,
39919b7f76aSDaniel Sanders                                                  uint64_t Address,
40019b7f76aSDaniel Sanders                                                  const void *Decoder);
40119b7f76aSDaniel Sanders 
402ea4f653dSDaniel Sanders template <unsigned Bits, int Offset>
403ea4f653dSDaniel Sanders static DecodeStatus DecodeUImmWithOffset(MCInst &Inst, unsigned Value,
40419b7f76aSDaniel Sanders                                          uint64_t Address,
40519b7f76aSDaniel Sanders                                          const void *Decoder) {
40619b7f76aSDaniel Sanders   return DecodeUImmWithOffsetAndScale<Bits, Offset, 1>(Inst, Value, Address,
40719b7f76aSDaniel Sanders                                                        Decoder);
40819b7f76aSDaniel Sanders }
409779c5937SMatheus Almeida 
41097297770SDaniel Sanders template <unsigned Bits, int Offset = 0, int ScaleBy = 1>
41197297770SDaniel Sanders static DecodeStatus DecodeSImmWithOffsetAndScale(MCInst &Inst, unsigned Value,
41297297770SDaniel Sanders                                                  uint64_t Address,
41397297770SDaniel Sanders                                                  const void *Decoder);
41478e89020SDaniel Sanders 
41571928e68SAkira Hatanaka static DecodeStatus DecodeInsSize(MCInst &Inst,
41671928e68SAkira Hatanaka                                   unsigned Insn,
41771928e68SAkira Hatanaka                                   uint64_t Address,
41871928e68SAkira Hatanaka                                   const void *Decoder);
41971928e68SAkira Hatanaka 
420b59e1a41SDaniel Sanders static DecodeStatus DecodeSimm19Lsl2(MCInst &Inst, unsigned Insn,
421b59e1a41SDaniel Sanders                                      uint64_t Address, const void *Decoder);
422b59e1a41SDaniel Sanders 
4232855142aSZoran Jovanovic static DecodeStatus DecodeSimm18Lsl3(MCInst &Inst, unsigned Insn,
4242855142aSZoran Jovanovic                                      uint64_t Address, const void *Decoder);
4252855142aSZoran Jovanovic 
426b682ddf3SVladimir Medic static DecodeStatus DecodeSimm9SP(MCInst &Inst, unsigned Insn,
427b682ddf3SVladimir Medic                                   uint64_t Address, const void *Decoder);
428b682ddf3SVladimir Medic 
429b682ddf3SVladimir Medic static DecodeStatus DecodeANDI16Imm(MCInst &Inst, unsigned Insn,
430b682ddf3SVladimir Medic                                     uint64_t Address, const void *Decoder);
431b682ddf3SVladimir Medic 
4322c6d7320SJozef Kolek static DecodeStatus DecodeSimm23Lsl2(MCInst &Inst, unsigned Insn,
4332c6d7320SJozef Kolek                                      uint64_t Address, const void *Decoder);
4342c6d7320SJozef Kolek 
435b50ccf8eSDaniel Sanders /// INSVE_[BHWD] have an implicit operand that the generated decoder doesn't
436b50ccf8eSDaniel Sanders /// handle.
437b50ccf8eSDaniel Sanders template <typename InsnType>
438b50ccf8eSDaniel Sanders static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address,
439b50ccf8eSDaniel Sanders                                    const void *Decoder);
4405c582b2fSDaniel Sanders 
4415c582b2fSDaniel Sanders template <typename InsnType>
442cf060794SSimon Dardis static DecodeStatus DecodeDAHIDATIMMR6(MCInst &MI, InsnType insn, uint64_t Address,
443cf060794SSimon Dardis                                    const void *Decoder);
444cf060794SSimon Dardis 
445cf060794SSimon Dardis template <typename InsnType>
446cf060794SSimon Dardis static DecodeStatus DecodeDAHIDATI(MCInst &MI, InsnType insn, uint64_t Address,
447cf060794SSimon Dardis                                    const void *Decoder);
448cf060794SSimon Dardis 
449cf060794SSimon Dardis template <typename InsnType>
450b3fd189cSSimon Dardis static DecodeStatus DecodeDAHIDATIMMR6(MCInst &MI, InsnType insn, uint64_t Address,
451b3fd189cSSimon Dardis                                    const void *Decoder);
452b3fd189cSSimon Dardis 
453b3fd189cSSimon Dardis template <typename InsnType>
454b3fd189cSSimon Dardis static DecodeStatus DecodeDAHIDATI(MCInst &MI, InsnType insn, uint64_t Address,
455b3fd189cSSimon Dardis                                    const void *Decoder);
456b3fd189cSSimon Dardis 
457b3fd189cSSimon Dardis template <typename InsnType>
4585c582b2fSDaniel Sanders static DecodeStatus
4595c582b2fSDaniel Sanders DecodeAddiGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
4605c582b2fSDaniel Sanders                       const void *Decoder);
4615c582b2fSDaniel Sanders 
4625c582b2fSDaniel Sanders template <typename InsnType>
4635c582b2fSDaniel Sanders static DecodeStatus
464c962c493SHrvoje Varga DecodePOP35GroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address,
465c962c493SHrvoje Varga                            const void *Decoder);
466c962c493SHrvoje Varga 
467c962c493SHrvoje Varga template <typename InsnType>
468c962c493SHrvoje Varga static DecodeStatus
4695c582b2fSDaniel Sanders DecodeDaddiGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
4705c582b2fSDaniel Sanders                        const void *Decoder);
4715c582b2fSDaniel Sanders 
4725c582b2fSDaniel Sanders template <typename InsnType>
4735c582b2fSDaniel Sanders static DecodeStatus
474c962c493SHrvoje Varga DecodePOP37GroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address,
475c962c493SHrvoje Varga                            const void *Decoder);
476c962c493SHrvoje Varga 
477c962c493SHrvoje Varga template <typename InsnType>
478c962c493SHrvoje Varga static DecodeStatus
479f0ed16eaSHrvoje Varga DecodePOP65GroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address,
480f0ed16eaSHrvoje Varga                            const void *Decoder);
481f0ed16eaSHrvoje Varga 
482f0ed16eaSHrvoje Varga template <typename InsnType>
483f0ed16eaSHrvoje Varga static DecodeStatus
484f0ed16eaSHrvoje Varga DecodePOP75GroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address,
485f0ed16eaSHrvoje Varga                            const void *Decoder);
486f0ed16eaSHrvoje Varga 
487f0ed16eaSHrvoje Varga template <typename InsnType>
488f0ed16eaSHrvoje Varga static DecodeStatus
4895c582b2fSDaniel Sanders DecodeBlezlGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
4905c582b2fSDaniel Sanders                        const void *Decoder);
4915c582b2fSDaniel Sanders 
4925c582b2fSDaniel Sanders template <typename InsnType>
4935c582b2fSDaniel Sanders static DecodeStatus
4945c582b2fSDaniel Sanders DecodeBgtzlGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
4955c582b2fSDaniel Sanders                        const void *Decoder);
4965c582b2fSDaniel Sanders 
4975c582b2fSDaniel Sanders template <typename InsnType>
4985c582b2fSDaniel Sanders static DecodeStatus
4995c582b2fSDaniel Sanders DecodeBgtzGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
5005c582b2fSDaniel Sanders                       const void *Decoder);
5015c582b2fSDaniel Sanders 
50228a0ca07SZoran Jovanovic template <typename InsnType>
50328a0ca07SZoran Jovanovic static DecodeStatus
50428a0ca07SZoran Jovanovic DecodeBlezGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
50528a0ca07SZoran Jovanovic                        const void *Decoder);
50628a0ca07SZoran Jovanovic 
507fdbd0a37SZoran Jovanovic template <typename InsnType>
508fdbd0a37SZoran Jovanovic static DecodeStatus
509fdbd0a37SZoran Jovanovic DecodeBgtzGroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address,
510fdbd0a37SZoran Jovanovic                           const void *Decoder);
511fdbd0a37SZoran Jovanovic 
512fdbd0a37SZoran Jovanovic template <typename InsnType>
513fdbd0a37SZoran Jovanovic static DecodeStatus
514fdbd0a37SZoran Jovanovic DecodeBlezGroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address,
515fdbd0a37SZoran Jovanovic                           const void *Decoder);
516fdbd0a37SZoran Jovanovic 
517a4c4b5fcSZoran Jovanovic static DecodeStatus DecodeRegListOperand(MCInst &Inst, unsigned Insn,
518a4c4b5fcSZoran Jovanovic                                          uint64_t Address,
519a4c4b5fcSZoran Jovanovic                                          const void *Decoder);
520a4c4b5fcSZoran Jovanovic 
521f9a02500SZoran Jovanovic static DecodeStatus DecodeRegListOperand16(MCInst &Inst, unsigned Insn,
522f9a02500SZoran Jovanovic                                            uint64_t Address,
523f9a02500SZoran Jovanovic                                            const void *Decoder);
524f9a02500SZoran Jovanovic 
52541688679SZoran Jovanovic static DecodeStatus DecodeMovePRegPair(MCInst &Inst, unsigned Insn,
52641688679SZoran Jovanovic                                        uint64_t Address,
52741688679SZoran Jovanovic                                        const void *Decoder);
52841688679SZoran Jovanovic 
52971928e68SAkira Hatanaka namespace llvm {
530f42454b9SMehdi Amini Target &getTheMipselTarget();
531f42454b9SMehdi Amini Target &getTheMipsTarget();
532f42454b9SMehdi Amini Target &getTheMips64Target();
533f42454b9SMehdi Amini Target &getTheMips64elTarget();
53471928e68SAkira Hatanaka }
53571928e68SAkira Hatanaka 
53671928e68SAkira Hatanaka static MCDisassembler *createMipsDisassembler(
53771928e68SAkira Hatanaka                        const Target &T,
538a1bc0f56SLang Hames                        const MCSubtargetInfo &STI,
539a1bc0f56SLang Hames                        MCContext &Ctx) {
540a1bc0f56SLang Hames   return new MipsDisassembler(STI, Ctx, true);
54171928e68SAkira Hatanaka }
54271928e68SAkira Hatanaka 
54371928e68SAkira Hatanaka static MCDisassembler *createMipselDisassembler(
54471928e68SAkira Hatanaka                        const Target &T,
545a1bc0f56SLang Hames                        const MCSubtargetInfo &STI,
546a1bc0f56SLang Hames                        MCContext &Ctx) {
547a1bc0f56SLang Hames   return new MipsDisassembler(STI, Ctx, false);
54871928e68SAkira Hatanaka }
54971928e68SAkira Hatanaka 
55071928e68SAkira Hatanaka extern "C" void LLVMInitializeMipsDisassembler() {
55171928e68SAkira Hatanaka   // Register the disassembler.
552f42454b9SMehdi Amini   TargetRegistry::RegisterMCDisassembler(getTheMipsTarget(),
55371928e68SAkira Hatanaka                                          createMipsDisassembler);
554f42454b9SMehdi Amini   TargetRegistry::RegisterMCDisassembler(getTheMipselTarget(),
55571928e68SAkira Hatanaka                                          createMipselDisassembler);
556f42454b9SMehdi Amini   TargetRegistry::RegisterMCDisassembler(getTheMips64Target(),
557a19216c8SDaniel Sanders                                          createMipsDisassembler);
558f42454b9SMehdi Amini   TargetRegistry::RegisterMCDisassembler(getTheMips64elTarget(),
559a19216c8SDaniel Sanders                                          createMipselDisassembler);
56071928e68SAkira Hatanaka }
56171928e68SAkira Hatanaka 
56271928e68SAkira Hatanaka #include "MipsGenDisassemblerTables.inc"
56371928e68SAkira Hatanaka 
5645c582b2fSDaniel Sanders static unsigned getReg(const void *D, unsigned RC, unsigned RegNo) {
565a19216c8SDaniel Sanders   const MipsDisassembler *Dis = static_cast<const MipsDisassembler*>(D);
5665c582b2fSDaniel Sanders   const MCRegisterInfo *RegInfo = Dis->getContext().getRegisterInfo();
5675c582b2fSDaniel Sanders   return *(RegInfo->getRegClass(RC).begin() + RegNo);
5685c582b2fSDaniel Sanders }
5695c582b2fSDaniel Sanders 
570b50ccf8eSDaniel Sanders template <typename InsnType>
571b50ccf8eSDaniel Sanders static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address,
572b50ccf8eSDaniel Sanders                                    const void *Decoder) {
573b50ccf8eSDaniel Sanders   typedef DecodeStatus (*DecodeFN)(MCInst &, unsigned, uint64_t, const void *);
574b50ccf8eSDaniel Sanders   // The size of the n field depends on the element size
575b50ccf8eSDaniel Sanders   // The register class also depends on this.
576b50ccf8eSDaniel Sanders   InsnType tmp = fieldFromInstruction(insn, 17, 5);
577b50ccf8eSDaniel Sanders   unsigned NSize = 0;
578b50ccf8eSDaniel Sanders   DecodeFN RegDecoder = nullptr;
579b50ccf8eSDaniel Sanders   if ((tmp & 0x18) == 0x00) { // INSVE_B
580b50ccf8eSDaniel Sanders     NSize = 4;
581b50ccf8eSDaniel Sanders     RegDecoder = DecodeMSA128BRegisterClass;
582b50ccf8eSDaniel Sanders   } else if ((tmp & 0x1c) == 0x10) { // INSVE_H
583b50ccf8eSDaniel Sanders     NSize = 3;
584b50ccf8eSDaniel Sanders     RegDecoder = DecodeMSA128HRegisterClass;
585b50ccf8eSDaniel Sanders   } else if ((tmp & 0x1e) == 0x18) { // INSVE_W
586b50ccf8eSDaniel Sanders     NSize = 2;
587b50ccf8eSDaniel Sanders     RegDecoder = DecodeMSA128WRegisterClass;
588b50ccf8eSDaniel Sanders   } else if ((tmp & 0x1f) == 0x1c) { // INSVE_D
589b50ccf8eSDaniel Sanders     NSize = 1;
590b50ccf8eSDaniel Sanders     RegDecoder = DecodeMSA128DRegisterClass;
591b50ccf8eSDaniel Sanders   } else
592b50ccf8eSDaniel Sanders     llvm_unreachable("Invalid encoding");
593b50ccf8eSDaniel Sanders 
594b50ccf8eSDaniel Sanders   assert(NSize != 0 && RegDecoder != nullptr);
595b50ccf8eSDaniel Sanders 
596b50ccf8eSDaniel Sanders   // $wd
597b50ccf8eSDaniel Sanders   tmp = fieldFromInstruction(insn, 6, 5);
598b50ccf8eSDaniel Sanders   if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
599b50ccf8eSDaniel Sanders     return MCDisassembler::Fail;
600b50ccf8eSDaniel Sanders   // $wd_in
601b50ccf8eSDaniel Sanders   if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
602b50ccf8eSDaniel Sanders     return MCDisassembler::Fail;
603b50ccf8eSDaniel Sanders   // $n
604b50ccf8eSDaniel Sanders   tmp = fieldFromInstruction(insn, 16, NSize);
605e9119e41SJim Grosbach   MI.addOperand(MCOperand::createImm(tmp));
606b50ccf8eSDaniel Sanders   // $ws
607b50ccf8eSDaniel Sanders   tmp = fieldFromInstruction(insn, 11, 5);
608b50ccf8eSDaniel Sanders   if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
609b50ccf8eSDaniel Sanders     return MCDisassembler::Fail;
610b50ccf8eSDaniel Sanders   // $n2
611e9119e41SJim Grosbach   MI.addOperand(MCOperand::createImm(0));
612b50ccf8eSDaniel Sanders 
613b50ccf8eSDaniel Sanders   return MCDisassembler::Success;
614b50ccf8eSDaniel Sanders }
615b50ccf8eSDaniel Sanders 
6165c582b2fSDaniel Sanders template <typename InsnType>
617cf060794SSimon Dardis static DecodeStatus DecodeDAHIDATIMMR6(MCInst &MI, InsnType insn, uint64_t Address,
618cf060794SSimon Dardis                                const void *Decoder) {
619b3fd189cSSimon Dardis   InsnType Rs = fieldFromInstruction(insn, 16, 5);
620cf060794SSimon Dardis   InsnType Imm = fieldFromInstruction(insn, 0, 16);
621cf060794SSimon Dardis   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID,
622b3fd189cSSimon Dardis                                        Rs)));
623cf060794SSimon Dardis   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID,
624b3fd189cSSimon Dardis                                        Rs)));
625cf060794SSimon Dardis   MI.addOperand(MCOperand::createImm(Imm));
626cf060794SSimon Dardis 
627cf060794SSimon Dardis   return MCDisassembler::Success;
628cf060794SSimon Dardis }
629cf060794SSimon Dardis 
630cf060794SSimon Dardis template <typename InsnType>
631cf060794SSimon Dardis static DecodeStatus DecodeDAHIDATI(MCInst &MI, InsnType insn, uint64_t Address,
632cf060794SSimon Dardis                                const void *Decoder) {
633b3fd189cSSimon Dardis   InsnType Rs = fieldFromInstruction(insn, 21, 5);
634cf060794SSimon Dardis   InsnType Imm = fieldFromInstruction(insn, 0, 16);
635cf060794SSimon Dardis   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID,
636b3fd189cSSimon Dardis                                        Rs)));
637cf060794SSimon Dardis   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID,
638b3fd189cSSimon Dardis                                        Rs)));
639cf060794SSimon Dardis   MI.addOperand(MCOperand::createImm(Imm));
640cf060794SSimon Dardis 
641cf060794SSimon Dardis   return MCDisassembler::Success;
642cf060794SSimon Dardis }
643cf060794SSimon Dardis 
644cf060794SSimon Dardis template <typename InsnType>
6455c582b2fSDaniel Sanders static DecodeStatus DecodeAddiGroupBranch(MCInst &MI, InsnType insn,
6465c582b2fSDaniel Sanders                                           uint64_t Address,
6475c582b2fSDaniel Sanders                                           const void *Decoder) {
6485c582b2fSDaniel Sanders   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
6495c582b2fSDaniel Sanders   // (otherwise we would have matched the ADDI instruction from the earlier
6505c582b2fSDaniel Sanders   // ISA's instead).
6515c582b2fSDaniel Sanders   //
6525c582b2fSDaniel Sanders   // We have:
6535c582b2fSDaniel Sanders   //    0b001000 sssss ttttt iiiiiiiiiiiiiiii
6545c582b2fSDaniel Sanders   //      BOVC if rs >= rt
6555c582b2fSDaniel Sanders   //      BEQZALC if rs == 0 && rt != 0
6565c582b2fSDaniel Sanders   //      BEQC if rs < rt && rs != 0
6575c582b2fSDaniel Sanders 
6585c582b2fSDaniel Sanders   InsnType Rs = fieldFromInstruction(insn, 21, 5);
6595c582b2fSDaniel Sanders   InsnType Rt = fieldFromInstruction(insn, 16, 5);
660672c710dSSagar Thakur   int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
6615c582b2fSDaniel Sanders   bool HasRs = false;
6625c582b2fSDaniel Sanders 
6635c582b2fSDaniel Sanders   if (Rs >= Rt) {
6645c582b2fSDaniel Sanders     MI.setOpcode(Mips::BOVC);
6655c582b2fSDaniel Sanders     HasRs = true;
6665c582b2fSDaniel Sanders   } else if (Rs != 0 && Rs < Rt) {
6675c582b2fSDaniel Sanders     MI.setOpcode(Mips::BEQC);
6685c582b2fSDaniel Sanders     HasRs = true;
6695c582b2fSDaniel Sanders   } else
6705c582b2fSDaniel Sanders     MI.setOpcode(Mips::BEQZALC);
6715c582b2fSDaniel Sanders 
6725c582b2fSDaniel Sanders   if (HasRs)
673e9119e41SJim Grosbach     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
6745c582b2fSDaniel Sanders                                        Rs)));
6755c582b2fSDaniel Sanders 
676e9119e41SJim Grosbach   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
6775c582b2fSDaniel Sanders                                      Rt)));
678e9119e41SJim Grosbach   MI.addOperand(MCOperand::createImm(Imm));
6795c582b2fSDaniel Sanders 
6805c582b2fSDaniel Sanders   return MCDisassembler::Success;
6815c582b2fSDaniel Sanders }
6825c582b2fSDaniel Sanders 
6835c582b2fSDaniel Sanders template <typename InsnType>
684c962c493SHrvoje Varga static DecodeStatus DecodePOP35GroupBranchMMR6(MCInst &MI, InsnType insn,
685c962c493SHrvoje Varga                                                uint64_t Address,
686c962c493SHrvoje Varga                                                const void *Decoder) {
687c962c493SHrvoje Varga   InsnType Rt = fieldFromInstruction(insn, 21, 5);
688c962c493SHrvoje Varga   InsnType Rs = fieldFromInstruction(insn, 16, 5);
689f0ed16eaSHrvoje Varga   int64_t Imm = 0;
690c962c493SHrvoje Varga 
691c962c493SHrvoje Varga   if (Rs >= Rt) {
692c962c493SHrvoje Varga     MI.setOpcode(Mips::BOVC_MMR6);
693c962c493SHrvoje Varga     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
694c962c493SHrvoje Varga                                        Rt)));
695c962c493SHrvoje Varga     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
696c962c493SHrvoje Varga                                        Rs)));
697f0ed16eaSHrvoje Varga     Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
698c962c493SHrvoje Varga   } else if (Rs != 0 && Rs < Rt) {
699c962c493SHrvoje Varga     MI.setOpcode(Mips::BEQC_MMR6);
700c962c493SHrvoje Varga     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
701c962c493SHrvoje Varga                                        Rs)));
702c962c493SHrvoje Varga     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
703c962c493SHrvoje Varga                                        Rt)));
704f0ed16eaSHrvoje Varga     Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
705c962c493SHrvoje Varga   } else {
706c962c493SHrvoje Varga     MI.setOpcode(Mips::BEQZALC_MMR6);
707c962c493SHrvoje Varga     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
708c962c493SHrvoje Varga                                        Rt)));
709f0ed16eaSHrvoje Varga     Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
710c962c493SHrvoje Varga   }
711c962c493SHrvoje Varga 
712c962c493SHrvoje Varga   MI.addOperand(MCOperand::createImm(Imm));
713c962c493SHrvoje Varga 
714c962c493SHrvoje Varga   return MCDisassembler::Success;
715c962c493SHrvoje Varga }
716c962c493SHrvoje Varga 
717c962c493SHrvoje Varga template <typename InsnType>
7185c582b2fSDaniel Sanders static DecodeStatus DecodeDaddiGroupBranch(MCInst &MI, InsnType insn,
7195c582b2fSDaniel Sanders                                            uint64_t Address,
7205c582b2fSDaniel Sanders                                            const void *Decoder) {
7215c582b2fSDaniel Sanders   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
7225c582b2fSDaniel Sanders   // (otherwise we would have matched the ADDI instruction from the earlier
7235c582b2fSDaniel Sanders   // ISA's instead).
7245c582b2fSDaniel Sanders   //
7255c582b2fSDaniel Sanders   // We have:
7265c582b2fSDaniel Sanders   //    0b011000 sssss ttttt iiiiiiiiiiiiiiii
7275c582b2fSDaniel Sanders   //      BNVC if rs >= rt
7285c582b2fSDaniel Sanders   //      BNEZALC if rs == 0 && rt != 0
7295c582b2fSDaniel Sanders   //      BNEC if rs < rt && rs != 0
7305c582b2fSDaniel Sanders 
7315c582b2fSDaniel Sanders   InsnType Rs = fieldFromInstruction(insn, 21, 5);
7325c582b2fSDaniel Sanders   InsnType Rt = fieldFromInstruction(insn, 16, 5);
733672c710dSSagar Thakur   int64_t  Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
7345c582b2fSDaniel Sanders   bool HasRs = false;
7355c582b2fSDaniel Sanders 
7365c582b2fSDaniel Sanders   if (Rs >= Rt) {
7375c582b2fSDaniel Sanders     MI.setOpcode(Mips::BNVC);
7385c582b2fSDaniel Sanders     HasRs = true;
7395c582b2fSDaniel Sanders   } else if (Rs != 0 && Rs < Rt) {
7405c582b2fSDaniel Sanders     MI.setOpcode(Mips::BNEC);
7415c582b2fSDaniel Sanders     HasRs = true;
7425c582b2fSDaniel Sanders   } else
7435c582b2fSDaniel Sanders     MI.setOpcode(Mips::BNEZALC);
7445c582b2fSDaniel Sanders 
7455c582b2fSDaniel Sanders   if (HasRs)
746e9119e41SJim Grosbach     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
7475c582b2fSDaniel Sanders                                        Rs)));
7485c582b2fSDaniel Sanders 
749e9119e41SJim Grosbach   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
7505c582b2fSDaniel Sanders                                      Rt)));
751e9119e41SJim Grosbach   MI.addOperand(MCOperand::createImm(Imm));
7525c582b2fSDaniel Sanders 
7535c582b2fSDaniel Sanders   return MCDisassembler::Success;
7545c582b2fSDaniel Sanders }
7555c582b2fSDaniel Sanders 
7565c582b2fSDaniel Sanders template <typename InsnType>
757c962c493SHrvoje Varga static DecodeStatus DecodePOP37GroupBranchMMR6(MCInst &MI, InsnType insn,
758c962c493SHrvoje Varga                                                uint64_t Address,
759c962c493SHrvoje Varga                                                const void *Decoder) {
760c962c493SHrvoje Varga   InsnType Rt = fieldFromInstruction(insn, 21, 5);
761c962c493SHrvoje Varga   InsnType Rs = fieldFromInstruction(insn, 16, 5);
762f0ed16eaSHrvoje Varga   int64_t Imm = 0;
763c962c493SHrvoje Varga 
764c962c493SHrvoje Varga   if (Rs >= Rt) {
765c962c493SHrvoje Varga     MI.setOpcode(Mips::BNVC_MMR6);
766c962c493SHrvoje Varga     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
767c962c493SHrvoje Varga                                        Rt)));
768c962c493SHrvoje Varga     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
769c962c493SHrvoje Varga                                        Rs)));
770f0ed16eaSHrvoje Varga     Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
771c962c493SHrvoje Varga   } else if (Rs != 0 && Rs < Rt) {
772c962c493SHrvoje Varga     MI.setOpcode(Mips::BNEC_MMR6);
773c962c493SHrvoje Varga     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
774c962c493SHrvoje Varga                                        Rs)));
775c962c493SHrvoje Varga     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
776c962c493SHrvoje Varga                                        Rt)));
777f0ed16eaSHrvoje Varga     Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
778c962c493SHrvoje Varga   } else {
779c962c493SHrvoje Varga     MI.setOpcode(Mips::BNEZALC_MMR6);
780c962c493SHrvoje Varga     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
781c962c493SHrvoje Varga                                        Rt)));
782f0ed16eaSHrvoje Varga     Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
783c962c493SHrvoje Varga   }
784c962c493SHrvoje Varga 
785c962c493SHrvoje Varga   MI.addOperand(MCOperand::createImm(Imm));
786c962c493SHrvoje Varga 
787c962c493SHrvoje Varga   return MCDisassembler::Success;
788c962c493SHrvoje Varga }
789c962c493SHrvoje Varga 
790c962c493SHrvoje Varga template <typename InsnType>
791f0ed16eaSHrvoje Varga static DecodeStatus DecodePOP65GroupBranchMMR6(MCInst &MI, InsnType insn,
792f0ed16eaSHrvoje Varga                                                uint64_t Address,
793f0ed16eaSHrvoje Varga                                                const void *Decoder) {
794f0ed16eaSHrvoje Varga   // We have:
795f0ed16eaSHrvoje Varga   //    0b110101 ttttt sssss iiiiiiiiiiiiiiii
796f0ed16eaSHrvoje Varga   //      Invalid if rt == 0
797f0ed16eaSHrvoje Varga   //      BGTZC_MMR6   if rs == 0  && rt != 0
798f0ed16eaSHrvoje Varga   //      BLTZC_MMR6   if rs == rt && rt != 0
799f0ed16eaSHrvoje Varga   //      BLTC_MMR6    if rs != rt && rs != 0  && rt != 0
800f0ed16eaSHrvoje Varga 
801f0ed16eaSHrvoje Varga   InsnType Rt = fieldFromInstruction(insn, 21, 5);
802f0ed16eaSHrvoje Varga   InsnType Rs = fieldFromInstruction(insn, 16, 5);
803f0ed16eaSHrvoje Varga   int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
804f0ed16eaSHrvoje Varga   bool HasRs = false;
805f0ed16eaSHrvoje Varga 
806f0ed16eaSHrvoje Varga   if (Rt == 0)
807f0ed16eaSHrvoje Varga     return MCDisassembler::Fail;
808f0ed16eaSHrvoje Varga   else if (Rs == 0)
809f0ed16eaSHrvoje Varga     MI.setOpcode(Mips::BGTZC_MMR6);
810f0ed16eaSHrvoje Varga   else if (Rs == Rt)
811f0ed16eaSHrvoje Varga     MI.setOpcode(Mips::BLTZC_MMR6);
812f0ed16eaSHrvoje Varga   else {
813f0ed16eaSHrvoje Varga     MI.setOpcode(Mips::BLTC_MMR6);
814f0ed16eaSHrvoje Varga     HasRs = true;
815f0ed16eaSHrvoje Varga   }
816f0ed16eaSHrvoje Varga 
817f0ed16eaSHrvoje Varga   if (HasRs)
818f0ed16eaSHrvoje Varga     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
819f0ed16eaSHrvoje Varga                                               Rs)));
820f0ed16eaSHrvoje Varga 
821f0ed16eaSHrvoje Varga   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
822f0ed16eaSHrvoje Varga                                      Rt)));
823f0ed16eaSHrvoje Varga 
824f0ed16eaSHrvoje Varga   MI.addOperand(MCOperand::createImm(Imm));
825f0ed16eaSHrvoje Varga 
826f0ed16eaSHrvoje Varga   return MCDisassembler::Success;
827f0ed16eaSHrvoje Varga }
828f0ed16eaSHrvoje Varga 
829f0ed16eaSHrvoje Varga template <typename InsnType>
830f0ed16eaSHrvoje Varga static DecodeStatus DecodePOP75GroupBranchMMR6(MCInst &MI, InsnType insn,
831f0ed16eaSHrvoje Varga                                                uint64_t Address,
832f0ed16eaSHrvoje Varga                                                const void *Decoder) {
833f0ed16eaSHrvoje Varga   // We have:
834f0ed16eaSHrvoje Varga   //    0b111101 ttttt sssss iiiiiiiiiiiiiiii
835f0ed16eaSHrvoje Varga   //      Invalid if rt == 0
836f0ed16eaSHrvoje Varga   //      BLEZC_MMR6   if rs == 0  && rt != 0
837f0ed16eaSHrvoje Varga   //      BGEZC_MMR6   if rs == rt && rt != 0
838f0ed16eaSHrvoje Varga   //      BGEC_MMR6    if rs != rt && rs != 0  && rt != 0
839f0ed16eaSHrvoje Varga 
840f0ed16eaSHrvoje Varga   InsnType Rt = fieldFromInstruction(insn, 21, 5);
841f0ed16eaSHrvoje Varga   InsnType Rs = fieldFromInstruction(insn, 16, 5);
842f0ed16eaSHrvoje Varga   int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
843f0ed16eaSHrvoje Varga   bool HasRs = false;
844f0ed16eaSHrvoje Varga 
845f0ed16eaSHrvoje Varga   if (Rt == 0)
846f0ed16eaSHrvoje Varga     return MCDisassembler::Fail;
847f0ed16eaSHrvoje Varga   else if (Rs == 0)
848f0ed16eaSHrvoje Varga     MI.setOpcode(Mips::BLEZC_MMR6);
849f0ed16eaSHrvoje Varga   else if (Rs == Rt)
850f0ed16eaSHrvoje Varga     MI.setOpcode(Mips::BGEZC_MMR6);
851f0ed16eaSHrvoje Varga   else {
852f0ed16eaSHrvoje Varga     HasRs = true;
853f0ed16eaSHrvoje Varga     MI.setOpcode(Mips::BGEC_MMR6);
854f0ed16eaSHrvoje Varga   }
855f0ed16eaSHrvoje Varga 
856f0ed16eaSHrvoje Varga   if (HasRs)
857f0ed16eaSHrvoje Varga     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
858f0ed16eaSHrvoje Varga                                        Rs)));
859f0ed16eaSHrvoje Varga 
860f0ed16eaSHrvoje Varga   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
861f0ed16eaSHrvoje Varga                                      Rt)));
862f0ed16eaSHrvoje Varga 
863f0ed16eaSHrvoje Varga   MI.addOperand(MCOperand::createImm(Imm));
864f0ed16eaSHrvoje Varga 
865f0ed16eaSHrvoje Varga   return MCDisassembler::Success;
866f0ed16eaSHrvoje Varga }
867f0ed16eaSHrvoje Varga 
868f0ed16eaSHrvoje Varga template <typename InsnType>
8695c582b2fSDaniel Sanders static DecodeStatus DecodeBlezlGroupBranch(MCInst &MI, InsnType insn,
8705c582b2fSDaniel Sanders                                            uint64_t Address,
8715c582b2fSDaniel Sanders                                            const void *Decoder) {
8725c582b2fSDaniel Sanders   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
8735c582b2fSDaniel Sanders   // (otherwise we would have matched the BLEZL instruction from the earlier
8745c582b2fSDaniel Sanders   // ISA's instead).
8755c582b2fSDaniel Sanders   //
8765c582b2fSDaniel Sanders   // We have:
8775c582b2fSDaniel Sanders   //    0b010110 sssss ttttt iiiiiiiiiiiiiiii
8785c582b2fSDaniel Sanders   //      Invalid if rs == 0
8795c582b2fSDaniel Sanders   //      BLEZC   if rs == 0  && rt != 0
8805c582b2fSDaniel Sanders   //      BGEZC   if rs == rt && rt != 0
8815c582b2fSDaniel Sanders   //      BGEC    if rs != rt && rs != 0  && rt != 0
8825c582b2fSDaniel Sanders 
8835c582b2fSDaniel Sanders   InsnType Rs = fieldFromInstruction(insn, 21, 5);
8845c582b2fSDaniel Sanders   InsnType Rt = fieldFromInstruction(insn, 16, 5);
885672c710dSSagar Thakur   int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
88628a0ca07SZoran Jovanovic   bool HasRs = false;
8875c582b2fSDaniel Sanders 
8885c582b2fSDaniel Sanders   if (Rt == 0)
8895c582b2fSDaniel Sanders     return MCDisassembler::Fail;
8905c582b2fSDaniel Sanders   else if (Rs == 0)
8915c582b2fSDaniel Sanders     MI.setOpcode(Mips::BLEZC);
8925c582b2fSDaniel Sanders   else if (Rs == Rt)
8935c582b2fSDaniel Sanders     MI.setOpcode(Mips::BGEZC);
89428a0ca07SZoran Jovanovic   else {
89528a0ca07SZoran Jovanovic     HasRs = true;
89628a0ca07SZoran Jovanovic     MI.setOpcode(Mips::BGEC);
89728a0ca07SZoran Jovanovic   }
89828a0ca07SZoran Jovanovic 
89928a0ca07SZoran Jovanovic   if (HasRs)
900e9119e41SJim Grosbach     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
90128a0ca07SZoran Jovanovic                                        Rs)));
9025c582b2fSDaniel Sanders 
903e9119e41SJim Grosbach   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
9045c582b2fSDaniel Sanders                                      Rt)));
9055c582b2fSDaniel Sanders 
906e9119e41SJim Grosbach   MI.addOperand(MCOperand::createImm(Imm));
9075c582b2fSDaniel Sanders 
9085c582b2fSDaniel Sanders   return MCDisassembler::Success;
9095c582b2fSDaniel Sanders }
9105c582b2fSDaniel Sanders 
9115c582b2fSDaniel Sanders template <typename InsnType>
9125c582b2fSDaniel Sanders static DecodeStatus DecodeBgtzlGroupBranch(MCInst &MI, InsnType insn,
9135c582b2fSDaniel Sanders                                            uint64_t Address,
9145c582b2fSDaniel Sanders                                            const void *Decoder) {
9155c582b2fSDaniel Sanders   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
9165c582b2fSDaniel Sanders   // (otherwise we would have matched the BGTZL instruction from the earlier
9175c582b2fSDaniel Sanders   // ISA's instead).
9185c582b2fSDaniel Sanders   //
9195c582b2fSDaniel Sanders   // We have:
9205c582b2fSDaniel Sanders   //    0b010111 sssss ttttt iiiiiiiiiiiiiiii
9215c582b2fSDaniel Sanders   //      Invalid if rs == 0
9225c582b2fSDaniel Sanders   //      BGTZC   if rs == 0  && rt != 0
9235c582b2fSDaniel Sanders   //      BLTZC   if rs == rt && rt != 0
9245c582b2fSDaniel Sanders   //      BLTC    if rs != rt && rs != 0  && rt != 0
9255c582b2fSDaniel Sanders 
9265c14b069SZoran Jovanovic   bool HasRs = false;
9275c14b069SZoran Jovanovic 
9285c582b2fSDaniel Sanders   InsnType Rs = fieldFromInstruction(insn, 21, 5);
9295c582b2fSDaniel Sanders   InsnType Rt = fieldFromInstruction(insn, 16, 5);
930672c710dSSagar Thakur   int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
9315c582b2fSDaniel Sanders 
9325c582b2fSDaniel Sanders   if (Rt == 0)
9335c582b2fSDaniel Sanders     return MCDisassembler::Fail;
9345c582b2fSDaniel Sanders   else if (Rs == 0)
9355c582b2fSDaniel Sanders     MI.setOpcode(Mips::BGTZC);
9365c582b2fSDaniel Sanders   else if (Rs == Rt)
9375c582b2fSDaniel Sanders     MI.setOpcode(Mips::BLTZC);
9385c14b069SZoran Jovanovic   else {
9395c14b069SZoran Jovanovic     MI.setOpcode(Mips::BLTC);
9405c14b069SZoran Jovanovic     HasRs = true;
9415c14b069SZoran Jovanovic   }
9425c14b069SZoran Jovanovic 
9435c14b069SZoran Jovanovic   if (HasRs)
944e9119e41SJim Grosbach     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
9455c14b069SZoran Jovanovic                                               Rs)));
9465c582b2fSDaniel Sanders 
947e9119e41SJim Grosbach   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
9485c582b2fSDaniel Sanders                                      Rt)));
9495c582b2fSDaniel Sanders 
950e9119e41SJim Grosbach   MI.addOperand(MCOperand::createImm(Imm));
9515c582b2fSDaniel Sanders 
9525c582b2fSDaniel Sanders   return MCDisassembler::Success;
9535c582b2fSDaniel Sanders }
9545c582b2fSDaniel Sanders 
9555c582b2fSDaniel Sanders template <typename InsnType>
9565c582b2fSDaniel Sanders static DecodeStatus DecodeBgtzGroupBranch(MCInst &MI, InsnType insn,
9575c582b2fSDaniel Sanders                                           uint64_t Address,
9585c582b2fSDaniel Sanders                                           const void *Decoder) {
9595c582b2fSDaniel Sanders   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
9605c582b2fSDaniel Sanders   // (otherwise we would have matched the BGTZ instruction from the earlier
9615c582b2fSDaniel Sanders   // ISA's instead).
9625c582b2fSDaniel Sanders   //
9635c582b2fSDaniel Sanders   // We have:
9645c582b2fSDaniel Sanders   //    0b000111 sssss ttttt iiiiiiiiiiiiiiii
9655c582b2fSDaniel Sanders   //      BGTZ    if rt == 0
9665c582b2fSDaniel Sanders   //      BGTZALC if rs == 0 && rt != 0
9675c582b2fSDaniel Sanders   //      BLTZALC if rs != 0 && rs == rt
9685c582b2fSDaniel Sanders   //      BLTUC   if rs != 0 && rs != rt
9695c582b2fSDaniel Sanders 
9705c582b2fSDaniel Sanders   InsnType Rs = fieldFromInstruction(insn, 21, 5);
9715c582b2fSDaniel Sanders   InsnType Rt = fieldFromInstruction(insn, 16, 5);
972672c710dSSagar Thakur   int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
9735c582b2fSDaniel Sanders   bool HasRs = false;
9745c582b2fSDaniel Sanders   bool HasRt = false;
9755c582b2fSDaniel Sanders 
9765c582b2fSDaniel Sanders   if (Rt == 0) {
9775c582b2fSDaniel Sanders     MI.setOpcode(Mips::BGTZ);
9785c582b2fSDaniel Sanders     HasRs = true;
9795c582b2fSDaniel Sanders   } else if (Rs == 0) {
9805c582b2fSDaniel Sanders     MI.setOpcode(Mips::BGTZALC);
9815c582b2fSDaniel Sanders     HasRt = true;
9825c582b2fSDaniel Sanders   } else if (Rs == Rt) {
9835c582b2fSDaniel Sanders     MI.setOpcode(Mips::BLTZALC);
9845c582b2fSDaniel Sanders     HasRs = true;
9855c14b069SZoran Jovanovic   } else {
9865c14b069SZoran Jovanovic     MI.setOpcode(Mips::BLTUC);
9875c14b069SZoran Jovanovic     HasRs = true;
9885c14b069SZoran Jovanovic     HasRt = true;
9895c14b069SZoran Jovanovic   }
9905c582b2fSDaniel Sanders 
9915c582b2fSDaniel Sanders   if (HasRs)
992e9119e41SJim Grosbach     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
9935c582b2fSDaniel Sanders                                        Rs)));
9945c582b2fSDaniel Sanders 
9955c582b2fSDaniel Sanders   if (HasRt)
996e9119e41SJim Grosbach     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
9975c582b2fSDaniel Sanders                                        Rt)));
9985c582b2fSDaniel Sanders 
999e9119e41SJim Grosbach   MI.addOperand(MCOperand::createImm(Imm));
10005c582b2fSDaniel Sanders 
10015c582b2fSDaniel Sanders   return MCDisassembler::Success;
10025c582b2fSDaniel Sanders }
10035c582b2fSDaniel Sanders 
100428a0ca07SZoran Jovanovic template <typename InsnType>
100528a0ca07SZoran Jovanovic static DecodeStatus DecodeBlezGroupBranch(MCInst &MI, InsnType insn,
100628a0ca07SZoran Jovanovic                                            uint64_t Address,
100728a0ca07SZoran Jovanovic                                            const void *Decoder) {
100828a0ca07SZoran Jovanovic   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
100928a0ca07SZoran Jovanovic   // (otherwise we would have matched the BLEZL instruction from the earlier
101028a0ca07SZoran Jovanovic   // ISA's instead).
101128a0ca07SZoran Jovanovic   //
101228a0ca07SZoran Jovanovic   // We have:
101328a0ca07SZoran Jovanovic   //    0b000110 sssss ttttt iiiiiiiiiiiiiiii
101428a0ca07SZoran Jovanovic   //      Invalid   if rs == 0
101528a0ca07SZoran Jovanovic   //      BLEZALC   if rs == 0  && rt != 0
101628a0ca07SZoran Jovanovic   //      BGEZALC   if rs == rt && rt != 0
101728a0ca07SZoran Jovanovic   //      BGEUC     if rs != rt && rs != 0  && rt != 0
101828a0ca07SZoran Jovanovic 
101928a0ca07SZoran Jovanovic   InsnType Rs = fieldFromInstruction(insn, 21, 5);
102028a0ca07SZoran Jovanovic   InsnType Rt = fieldFromInstruction(insn, 16, 5);
1021672c710dSSagar Thakur   int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
102228a0ca07SZoran Jovanovic   bool HasRs = false;
102328a0ca07SZoran Jovanovic 
102428a0ca07SZoran Jovanovic   if (Rt == 0)
102528a0ca07SZoran Jovanovic     return MCDisassembler::Fail;
102628a0ca07SZoran Jovanovic   else if (Rs == 0)
102728a0ca07SZoran Jovanovic     MI.setOpcode(Mips::BLEZALC);
102828a0ca07SZoran Jovanovic   else if (Rs == Rt)
102928a0ca07SZoran Jovanovic     MI.setOpcode(Mips::BGEZALC);
103028a0ca07SZoran Jovanovic   else {
103128a0ca07SZoran Jovanovic     HasRs = true;
103228a0ca07SZoran Jovanovic     MI.setOpcode(Mips::BGEUC);
103328a0ca07SZoran Jovanovic   }
103428a0ca07SZoran Jovanovic 
103528a0ca07SZoran Jovanovic   if (HasRs)
1036e9119e41SJim Grosbach     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
103728a0ca07SZoran Jovanovic                                        Rs)));
1038e9119e41SJim Grosbach   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
103928a0ca07SZoran Jovanovic                                      Rt)));
104028a0ca07SZoran Jovanovic 
1041e9119e41SJim Grosbach   MI.addOperand(MCOperand::createImm(Imm));
104228a0ca07SZoran Jovanovic 
104328a0ca07SZoran Jovanovic   return MCDisassembler::Success;
104428a0ca07SZoran Jovanovic }
104528a0ca07SZoran Jovanovic 
1046ea22c4cfSJozef Kolek /// Read two bytes from the ArrayRef and return 16 bit halfword sorted
1047*dcd84335SSimon Pilgrim /// according to the given endianness.
1048ea22c4cfSJozef Kolek static DecodeStatus readInstruction16(ArrayRef<uint8_t> Bytes, uint64_t Address,
1049ea22c4cfSJozef Kolek                                       uint64_t &Size, uint32_t &Insn,
1050ea22c4cfSJozef Kolek                                       bool IsBigEndian) {
1051ea22c4cfSJozef Kolek   // We want to read exactly 2 Bytes of data.
1052ea22c4cfSJozef Kolek   if (Bytes.size() < 2) {
1053ea22c4cfSJozef Kolek     Size = 0;
1054ea22c4cfSJozef Kolek     return MCDisassembler::Fail;
1055ea22c4cfSJozef Kolek   }
1056ea22c4cfSJozef Kolek 
1057ea22c4cfSJozef Kolek   if (IsBigEndian) {
1058ea22c4cfSJozef Kolek     Insn = (Bytes[0] << 8) | Bytes[1];
1059ea22c4cfSJozef Kolek   } else {
1060ea22c4cfSJozef Kolek     Insn = (Bytes[1] << 8) | Bytes[0];
1061ea22c4cfSJozef Kolek   }
1062ea22c4cfSJozef Kolek 
1063ea22c4cfSJozef Kolek   return MCDisassembler::Success;
1064ea22c4cfSJozef Kolek }
1065ea22c4cfSJozef Kolek 
10667fc5b874SRafael Espindola /// Read four bytes from the ArrayRef and return 32 bit word sorted
1067*dcd84335SSimon Pilgrim /// according to the given endianness.
10687fc5b874SRafael Espindola static DecodeStatus readInstruction32(ArrayRef<uint8_t> Bytes, uint64_t Address,
10697fc5b874SRafael Espindola                                       uint64_t &Size, uint32_t &Insn,
10707fc5b874SRafael Espindola                                       bool IsBigEndian, bool IsMicroMips) {
107171928e68SAkira Hatanaka   // We want to read exactly 4 Bytes of data.
10727fc5b874SRafael Espindola   if (Bytes.size() < 4) {
10734aa6bea7SRafael Espindola     Size = 0;
107471928e68SAkira Hatanaka     return MCDisassembler::Fail;
107571928e68SAkira Hatanaka   }
107671928e68SAkira Hatanaka 
1077ea22c4cfSJozef Kolek   // High 16 bits of a 32-bit microMIPS instruction (where the opcode is)
1078ea22c4cfSJozef Kolek   // always precede the low 16 bits in the instruction stream (that is, they
1079ea22c4cfSJozef Kolek   // are placed at lower addresses in the instruction stream).
1080ea22c4cfSJozef Kolek   //
1081ea22c4cfSJozef Kolek   // microMIPS byte ordering:
1082ea22c4cfSJozef Kolek   //   Big-endian:    0 | 1 | 2 | 3
1083ea22c4cfSJozef Kolek   //   Little-endian: 1 | 0 | 3 | 2
1084ea22c4cfSJozef Kolek 
10854aa6bea7SRafael Espindola   if (IsBigEndian) {
108671928e68SAkira Hatanaka     // Encoded as a big-endian 32-bit word in the stream.
10874aa6bea7SRafael Espindola     Insn =
10884aa6bea7SRafael Espindola         (Bytes[3] << 0) | (Bytes[2] << 8) | (Bytes[1] << 16) | (Bytes[0] << 24);
10894aa6bea7SRafael Espindola   } else {
1090dde3d582SVladimir Medic     if (IsMicroMips) {
10914aa6bea7SRafael Espindola       Insn = (Bytes[2] << 0) | (Bytes[3] << 8) | (Bytes[0] << 16) |
1092dde3d582SVladimir Medic              (Bytes[1] << 24);
1093dde3d582SVladimir Medic     } else {
10944aa6bea7SRafael Espindola       Insn = (Bytes[0] << 0) | (Bytes[1] << 8) | (Bytes[2] << 16) |
109571928e68SAkira Hatanaka              (Bytes[3] << 24);
109671928e68SAkira Hatanaka     }
1097dde3d582SVladimir Medic   }
109871928e68SAkira Hatanaka 
109971928e68SAkira Hatanaka   return MCDisassembler::Success;
110071928e68SAkira Hatanaka }
110171928e68SAkira Hatanaka 
11024aa6bea7SRafael Espindola DecodeStatus MipsDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,
11037fc5b874SRafael Espindola                                               ArrayRef<uint8_t> Bytes,
110471928e68SAkira Hatanaka                                               uint64_t Address,
11054aa6bea7SRafael Espindola                                               raw_ostream &VStream,
11064aa6bea7SRafael Espindola                                               raw_ostream &CStream) const {
110771928e68SAkira Hatanaka   uint32_t Insn;
1108ea22c4cfSJozef Kolek   DecodeStatus Result;
110971928e68SAkira Hatanaka 
1110ea22c4cfSJozef Kolek   if (IsMicroMips) {
1111ea22c4cfSJozef Kolek     Result = readInstruction16(Bytes, Address, Size, Insn, IsBigEndian);
1112ebee6129SReid Kleckner     if (Result == MCDisassembler::Fail)
1113ebee6129SReid Kleckner       return MCDisassembler::Fail;
1114ea22c4cfSJozef Kolek 
1115ada70918SZoran Jovanovic     if (hasMips32r6()) {
1116ada70918SZoran Jovanovic       DEBUG(dbgs() << "Trying MicroMipsR616 table (16-bit instructions):\n");
1117ada70918SZoran Jovanovic       // Calling the auto-generated decoder function for microMIPS32R6
1118ada70918SZoran Jovanovic       // (and microMIPS64R6) 16-bit instructions.
1119ada70918SZoran Jovanovic       Result = decodeInstruction(DecoderTableMicroMipsR616, Instr, Insn,
1120ada70918SZoran Jovanovic                                  Address, this, STI);
1121ada70918SZoran Jovanovic       if (Result != MCDisassembler::Fail) {
1122ada70918SZoran Jovanovic         Size = 2;
1123ada70918SZoran Jovanovic         return Result;
1124ada70918SZoran Jovanovic       }
1125ada70918SZoran Jovanovic     }
1126ada70918SZoran Jovanovic 
1127ea22c4cfSJozef Kolek     DEBUG(dbgs() << "Trying MicroMips16 table (16-bit instructions):\n");
1128ada70918SZoran Jovanovic     // Calling the auto-generated decoder function for microMIPS 16-bit
1129ada70918SZoran Jovanovic     // instructions.
1130ea22c4cfSJozef Kolek     Result = decodeInstruction(DecoderTableMicroMips16, Instr, Insn, Address,
1131ea22c4cfSJozef Kolek                                this, STI);
1132ea22c4cfSJozef Kolek     if (Result != MCDisassembler::Fail) {
1133ea22c4cfSJozef Kolek       Size = 2;
1134ea22c4cfSJozef Kolek       return Result;
1135ea22c4cfSJozef Kolek     }
1136ea22c4cfSJozef Kolek 
1137ea22c4cfSJozef Kolek     Result = readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, true);
113871928e68SAkira Hatanaka     if (Result == MCDisassembler::Fail)
113971928e68SAkira Hatanaka       return MCDisassembler::Fail;
114071928e68SAkira Hatanaka 
1141676d6012SJozef Kolek     if (hasMips32r6()) {
1142676d6012SJozef Kolek       DEBUG(dbgs() << "Trying MicroMips32r632 table (32-bit instructions):\n");
1143676d6012SJozef Kolek       // Calling the auto-generated decoder function.
1144366783e1SZoran Jovanovic       Result = decodeInstruction(DecoderTableMicroMipsR632, Instr, Insn, Address,
1145676d6012SJozef Kolek                                  this, STI);
1146ada70918SZoran Jovanovic       if (Result != MCDisassembler::Fail) {
1147ada70918SZoran Jovanovic         Size = 4;
1148ada70918SZoran Jovanovic         return Result;
1149ada70918SZoran Jovanovic       }
1150ada70918SZoran Jovanovic     }
1151ada70918SZoran Jovanovic 
1152ea22c4cfSJozef Kolek     DEBUG(dbgs() << "Trying MicroMips32 table (32-bit instructions):\n");
1153dde3d582SVladimir Medic     // Calling the auto-generated decoder function.
11544aa6bea7SRafael Espindola     Result = decodeInstruction(DecoderTableMicroMips32, Instr, Insn, Address,
1155dde3d582SVladimir Medic                                this, STI);
1156dde3d582SVladimir Medic     if (Result != MCDisassembler::Fail) {
1157dde3d582SVladimir Medic       Size = 4;
1158dde3d582SVladimir Medic       return Result;
1159dde3d582SVladimir Medic     }
11602cb74ac3SHrvoje Varga 
11616221be8eSZlatko Buljan     if (hasMips32r6() && isFP64()) {
11626221be8eSZlatko Buljan       DEBUG(dbgs() << "Trying MicroMips32r6FP64 table (32-bit opcodes):\n");
11636221be8eSZlatko Buljan       Result = decodeInstruction(DecoderTableMicroMips32r6FP6432, Instr, Insn,
11642cb74ac3SHrvoje Varga                                  Address, this, STI);
11652cb74ac3SHrvoje Varga       if (Result != MCDisassembler::Fail) {
11662cb74ac3SHrvoje Varga         Size = 4;
11672cb74ac3SHrvoje Varga         return Result;
11682cb74ac3SHrvoje Varga       }
11692cb74ac3SHrvoje Varga     }
11702cb74ac3SHrvoje Varga 
1171ebee6129SReid Kleckner     // This is an invalid instruction. Let the disassembler move forward by the
1172ebee6129SReid Kleckner     // minimum instruction size.
1173ebee6129SReid Kleckner     Size = 2;
1174dde3d582SVladimir Medic     return MCDisassembler::Fail;
1175dde3d582SVladimir Medic   }
1176dde3d582SVladimir Medic 
1177ea22c4cfSJozef Kolek   Result = readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, false);
1178ebee6129SReid Kleckner   if (Result == MCDisassembler::Fail) {
1179ebee6129SReid Kleckner     Size = 4;
1180ea22c4cfSJozef Kolek     return MCDisassembler::Fail;
1181ebee6129SReid Kleckner   }
1182ea22c4cfSJozef Kolek 
1183c171f65aSDaniel Sanders   if (hasCOP3()) {
1184c171f65aSDaniel Sanders     DEBUG(dbgs() << "Trying COP3_ table (32-bit opcodes):\n");
1185c171f65aSDaniel Sanders     Result =
11864aa6bea7SRafael Espindola         decodeInstruction(DecoderTableCOP3_32, Instr, Insn, Address, this, STI);
1187c171f65aSDaniel Sanders     if (Result != MCDisassembler::Fail) {
1188c171f65aSDaniel Sanders       Size = 4;
1189c171f65aSDaniel Sanders       return Result;
1190c171f65aSDaniel Sanders     }
1191c171f65aSDaniel Sanders   }
1192c171f65aSDaniel Sanders 
1193c171f65aSDaniel Sanders   if (hasMips32r6() && isGP64()) {
119436901dd1SVasileios Kalintiris     DEBUG(dbgs() << "Trying Mips32r6_64r6 (GPR64) table (32-bit opcodes):\n");
119536901dd1SVasileios Kalintiris     Result = decodeInstruction(DecoderTableMips32r6_64r6_GP6432, Instr, Insn,
119636901dd1SVasileios Kalintiris                                Address, this, STI);
11970fa60416SDaniel Sanders     if (Result != MCDisassembler::Fail) {
11980fa60416SDaniel Sanders       Size = 4;
11990fa60416SDaniel Sanders       return Result;
12000fa60416SDaniel Sanders     }
12010fa60416SDaniel Sanders   }
12020fa60416SDaniel Sanders 
12034fbf76f7SSimon Dardis   if (hasMips32r6() && isPTR64()) {
12044fbf76f7SSimon Dardis     DEBUG(dbgs() << "Trying Mips32r6_64r6 (PTR64) table (32-bit opcodes):\n");
12054fbf76f7SSimon Dardis     Result = decodeInstruction(DecoderTableMips32r6_64r6_PTR6432, Instr, Insn,
12064fbf76f7SSimon Dardis                                Address, this, STI);
12074fbf76f7SSimon Dardis     if (Result != MCDisassembler::Fail) {
12084fbf76f7SSimon Dardis       Size = 4;
12094fbf76f7SSimon Dardis       return Result;
12104fbf76f7SSimon Dardis     }
12114fbf76f7SSimon Dardis   }
12124fbf76f7SSimon Dardis 
1213c171f65aSDaniel Sanders   if (hasMips32r6()) {
12140fa60416SDaniel Sanders     DEBUG(dbgs() << "Trying Mips32r6_64r6 table (32-bit opcodes):\n");
12154aa6bea7SRafael Espindola     Result = decodeInstruction(DecoderTableMips32r6_64r632, Instr, Insn,
12165c582b2fSDaniel Sanders                                Address, this, STI);
12175c582b2fSDaniel Sanders     if (Result != MCDisassembler::Fail) {
12185c582b2fSDaniel Sanders       Size = 4;
12195c582b2fSDaniel Sanders       return Result;
12205c582b2fSDaniel Sanders     }
12215c582b2fSDaniel Sanders   }
12225c582b2fSDaniel Sanders 
12234fbf76f7SSimon Dardis   if (hasMips2() && isPTR64()) {
12244fbf76f7SSimon Dardis     DEBUG(dbgs() << "Trying Mips32r6_64r6 (PTR64) table (32-bit opcodes):\n");
12254fbf76f7SSimon Dardis     Result = decodeInstruction(DecoderTableMips32_64_PTR6432, Instr, Insn,
12264fbf76f7SSimon Dardis                                Address, this, STI);
12274fbf76f7SSimon Dardis     if (Result != MCDisassembler::Fail) {
12284fbf76f7SSimon Dardis       Size = 4;
12294fbf76f7SSimon Dardis       return Result;
12304fbf76f7SSimon Dardis     }
12314fbf76f7SSimon Dardis   }
12324fbf76f7SSimon Dardis 
12333adf9b8dSKai Nacke   if (hasCnMips()) {
12343adf9b8dSKai Nacke     DEBUG(dbgs() << "Trying CnMips table (32-bit opcodes):\n");
12353adf9b8dSKai Nacke     Result = decodeInstruction(DecoderTableCnMips32, Instr, Insn,
12363adf9b8dSKai Nacke                                Address, this, STI);
12373adf9b8dSKai Nacke     if (Result != MCDisassembler::Fail) {
12383adf9b8dSKai Nacke       Size = 4;
12393adf9b8dSKai Nacke       return Result;
12403adf9b8dSKai Nacke     }
12413adf9b8dSKai Nacke   }
12423adf9b8dSKai Nacke 
1243a19216c8SDaniel Sanders   if (isGP64()) {
1244a19216c8SDaniel Sanders     DEBUG(dbgs() << "Trying Mips64 (GPR64) table (32-bit opcodes):\n");
1245a19216c8SDaniel Sanders     Result = decodeInstruction(DecoderTableMips6432, Instr, Insn,
1246a19216c8SDaniel Sanders                                Address, this, STI);
1247a19216c8SDaniel Sanders     if (Result != MCDisassembler::Fail) {
1248a19216c8SDaniel Sanders       Size = 4;
1249a19216c8SDaniel Sanders       return Result;
1250a19216c8SDaniel Sanders     }
1251a19216c8SDaniel Sanders   }
1252a19216c8SDaniel Sanders 
12530fa60416SDaniel Sanders   DEBUG(dbgs() << "Trying Mips table (32-bit opcodes):\n");
125471928e68SAkira Hatanaka   // Calling the auto-generated decoder function.
12554aa6bea7SRafael Espindola   Result =
12564aa6bea7SRafael Espindola       decodeInstruction(DecoderTableMips32, Instr, Insn, Address, this, STI);
125771928e68SAkira Hatanaka   if (Result != MCDisassembler::Fail) {
125871928e68SAkira Hatanaka     Size = 4;
125971928e68SAkira Hatanaka     return Result;
126071928e68SAkira Hatanaka   }
126171928e68SAkira Hatanaka 
1262ebee6129SReid Kleckner   Size = 4;
126371928e68SAkira Hatanaka   return MCDisassembler::Fail;
126471928e68SAkira Hatanaka }
126571928e68SAkira Hatanaka 
1266ec8a5490SReed Kotler static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst,
1267ec8a5490SReed Kotler                                                  unsigned RegNo,
1268ec8a5490SReed Kotler                                                  uint64_t Address,
1269ec8a5490SReed Kotler                                                  const void *Decoder) {
1270ec8a5490SReed Kotler 
1271ec8a5490SReed Kotler   return MCDisassembler::Fail;
1272ec8a5490SReed Kotler 
1273ec8a5490SReed Kotler }
1274ec8a5490SReed Kotler 
127513e6ccf3SAkira Hatanaka static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst,
127671928e68SAkira Hatanaka                                              unsigned RegNo,
127771928e68SAkira Hatanaka                                              uint64_t Address,
127871928e68SAkira Hatanaka                                              const void *Decoder) {
127971928e68SAkira Hatanaka 
128071928e68SAkira Hatanaka   if (RegNo > 31)
128171928e68SAkira Hatanaka     return MCDisassembler::Fail;
128271928e68SAkira Hatanaka 
128313e6ccf3SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::GPR64RegClassID, RegNo);
1284e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
128571928e68SAkira Hatanaka   return MCDisassembler::Success;
128671928e68SAkira Hatanaka }
128771928e68SAkira Hatanaka 
1288b0852e54SZoran Jovanovic static DecodeStatus DecodeGPRMM16RegisterClass(MCInst &Inst,
1289b0852e54SZoran Jovanovic                                                unsigned RegNo,
1290b0852e54SZoran Jovanovic                                                uint64_t Address,
1291b0852e54SZoran Jovanovic                                                const void *Decoder) {
1292ea22c4cfSJozef Kolek   if (RegNo > 7)
1293b0852e54SZoran Jovanovic     return MCDisassembler::Fail;
1294ea22c4cfSJozef Kolek   unsigned Reg = getReg(Decoder, Mips::GPRMM16RegClassID, RegNo);
1295e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1296ea22c4cfSJozef Kolek   return MCDisassembler::Success;
1297b0852e54SZoran Jovanovic }
1298b0852e54SZoran Jovanovic 
12991904fa21SJozef Kolek static DecodeStatus DecodeGPRMM16ZeroRegisterClass(MCInst &Inst,
13001904fa21SJozef Kolek                                                    unsigned RegNo,
13011904fa21SJozef Kolek                                                    uint64_t Address,
13021904fa21SJozef Kolek                                                    const void *Decoder) {
1303315e7ecaSJozef Kolek   if (RegNo > 7)
13041904fa21SJozef Kolek     return MCDisassembler::Fail;
1305315e7ecaSJozef Kolek   unsigned Reg = getReg(Decoder, Mips::GPRMM16ZeroRegClassID, RegNo);
1306e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1307315e7ecaSJozef Kolek   return MCDisassembler::Success;
13081904fa21SJozef Kolek }
13091904fa21SJozef Kolek 
131041688679SZoran Jovanovic static DecodeStatus DecodeGPRMM16MovePRegisterClass(MCInst &Inst,
131141688679SZoran Jovanovic                                                     unsigned RegNo,
131241688679SZoran Jovanovic                                                     uint64_t Address,
131341688679SZoran Jovanovic                                                     const void *Decoder) {
131441688679SZoran Jovanovic   if (RegNo > 7)
131541688679SZoran Jovanovic     return MCDisassembler::Fail;
131641688679SZoran Jovanovic   unsigned Reg = getReg(Decoder, Mips::GPRMM16MovePRegClassID, RegNo);
1317e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
131841688679SZoran Jovanovic   return MCDisassembler::Success;
131941688679SZoran Jovanovic }
132041688679SZoran Jovanovic 
132113e6ccf3SAkira Hatanaka static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst,
132271928e68SAkira Hatanaka                                              unsigned RegNo,
132371928e68SAkira Hatanaka                                              uint64_t Address,
132471928e68SAkira Hatanaka                                              const void *Decoder) {
132571928e68SAkira Hatanaka   if (RegNo > 31)
132671928e68SAkira Hatanaka     return MCDisassembler::Fail;
132713e6ccf3SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::GPR32RegClassID, RegNo);
1328e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
132971928e68SAkira Hatanaka   return MCDisassembler::Success;
133071928e68SAkira Hatanaka }
133171928e68SAkira Hatanaka 
13329bfa2e2eSAkira Hatanaka static DecodeStatus DecodePtrRegisterClass(MCInst &Inst,
13339bfa2e2eSAkira Hatanaka                                            unsigned RegNo,
13349bfa2e2eSAkira Hatanaka                                            uint64_t Address,
13359bfa2e2eSAkira Hatanaka                                            const void *Decoder) {
1336a19216c8SDaniel Sanders   if (static_cast<const MipsDisassembler *>(Decoder)->isGP64())
13379bfa2e2eSAkira Hatanaka     return DecodeGPR64RegisterClass(Inst, RegNo, Address, Decoder);
13389bfa2e2eSAkira Hatanaka 
13399bfa2e2eSAkira Hatanaka   return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
13409bfa2e2eSAkira Hatanaka }
13419bfa2e2eSAkira Hatanaka 
1342654655f1SAkira Hatanaka static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst,
1343ecabd1a5SAkira Hatanaka                                             unsigned RegNo,
1344ecabd1a5SAkira Hatanaka                                             uint64_t Address,
1345ecabd1a5SAkira Hatanaka                                             const void *Decoder) {
134613e6ccf3SAkira Hatanaka   return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
1347ecabd1a5SAkira Hatanaka }
1348ecabd1a5SAkira Hatanaka 
134971928e68SAkira Hatanaka static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
135071928e68SAkira Hatanaka                                              unsigned RegNo,
135171928e68SAkira Hatanaka                                              uint64_t Address,
135271928e68SAkira Hatanaka                                              const void *Decoder) {
135371928e68SAkira Hatanaka   if (RegNo > 31)
135471928e68SAkira Hatanaka     return MCDisassembler::Fail;
135571928e68SAkira Hatanaka 
13569bf2b567SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::FGR64RegClassID, RegNo);
1357e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
135871928e68SAkira Hatanaka   return MCDisassembler::Success;
135971928e68SAkira Hatanaka }
136071928e68SAkira Hatanaka 
136171928e68SAkira Hatanaka static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
136271928e68SAkira Hatanaka                                              unsigned RegNo,
136371928e68SAkira Hatanaka                                              uint64_t Address,
136471928e68SAkira Hatanaka                                              const void *Decoder) {
136571928e68SAkira Hatanaka   if (RegNo > 31)
136671928e68SAkira Hatanaka     return MCDisassembler::Fail;
136771928e68SAkira Hatanaka 
13689bf2b567SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::FGR32RegClassID, RegNo);
1369e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
137071928e68SAkira Hatanaka   return MCDisassembler::Success;
137171928e68SAkira Hatanaka }
137271928e68SAkira Hatanaka 
137371928e68SAkira Hatanaka static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
137471928e68SAkira Hatanaka                                            unsigned RegNo,
137571928e68SAkira Hatanaka                                            uint64_t Address,
137671928e68SAkira Hatanaka                                            const void *Decoder) {
1377253777fdSChad Rosier   if (RegNo > 31)
1378253777fdSChad Rosier     return MCDisassembler::Fail;
1379253777fdSChad Rosier   unsigned Reg = getReg(Decoder, Mips::CCRRegClassID, RegNo);
1380e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
138171928e68SAkira Hatanaka   return MCDisassembler::Success;
138271928e68SAkira Hatanaka }
138371928e68SAkira Hatanaka 
13841fb1b8b8SAkira Hatanaka static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst,
13851fb1b8b8SAkira Hatanaka                                            unsigned RegNo,
13861fb1b8b8SAkira Hatanaka                                            uint64_t Address,
13871fb1b8b8SAkira Hatanaka                                            const void *Decoder) {
13881fb1b8b8SAkira Hatanaka   if (RegNo > 7)
13891fb1b8b8SAkira Hatanaka     return MCDisassembler::Fail;
13901fb1b8b8SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::FCCRegClassID, RegNo);
1391e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
13921fb1b8b8SAkira Hatanaka   return MCDisassembler::Success;
13931fb1b8b8SAkira Hatanaka }
13941fb1b8b8SAkira Hatanaka 
139536901dd1SVasileios Kalintiris static DecodeStatus DecodeFGRCCRegisterClass(MCInst &Inst, unsigned RegNo,
13960fa60416SDaniel Sanders                                              uint64_t Address,
13970fa60416SDaniel Sanders                                              const void *Decoder) {
13980fa60416SDaniel Sanders   if (RegNo > 31)
13990fa60416SDaniel Sanders     return MCDisassembler::Fail;
14000fa60416SDaniel Sanders 
140136901dd1SVasileios Kalintiris   unsigned Reg = getReg(Decoder, Mips::FGRCCRegClassID, RegNo);
1402e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
14030fa60416SDaniel Sanders   return MCDisassembler::Success;
14040fa60416SDaniel Sanders }
14050fa60416SDaniel Sanders 
140671928e68SAkira Hatanaka static DecodeStatus DecodeMem(MCInst &Inst,
140771928e68SAkira Hatanaka                               unsigned Insn,
140871928e68SAkira Hatanaka                               uint64_t Address,
140971928e68SAkira Hatanaka                               const void *Decoder) {
141071928e68SAkira Hatanaka   int Offset = SignExtend32<16>(Insn & 0xffff);
1411ecaef49fSJim Grosbach   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1412ecaef49fSJim Grosbach   unsigned Base = fieldFromInstruction(Insn, 21, 5);
14139bf2b567SAkira Hatanaka 
141413e6ccf3SAkira Hatanaka   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
141513e6ccf3SAkira Hatanaka   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
141671928e68SAkira Hatanaka 
1417d7ecf49eSVladimir Medic   if (Inst.getOpcode() == Mips::SC ||
1418e4e83a7bSDaniel Sanders       Inst.getOpcode() == Mips::SCD)
1419e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Reg));
1420e4e83a7bSDaniel Sanders 
1421e4e83a7bSDaniel Sanders   Inst.addOperand(MCOperand::createReg(Reg));
1422e4e83a7bSDaniel Sanders   Inst.addOperand(MCOperand::createReg(Base));
1423e4e83a7bSDaniel Sanders   Inst.addOperand(MCOperand::createImm(Offset));
1424e4e83a7bSDaniel Sanders 
1425e4e83a7bSDaniel Sanders   return MCDisassembler::Success;
142671928e68SAkira Hatanaka }
142771928e68SAkira Hatanaka 
1428e4e83a7bSDaniel Sanders static DecodeStatus DecodeMemEVA(MCInst &Inst,
1429e4e83a7bSDaniel Sanders                                  unsigned Insn,
1430e4e83a7bSDaniel Sanders                                  uint64_t Address,
1431e4e83a7bSDaniel Sanders                                  const void *Decoder) {
1432e4e83a7bSDaniel Sanders   int Offset = SignExtend32<9>(Insn >> 7);
1433e4e83a7bSDaniel Sanders   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1434e4e83a7bSDaniel Sanders   unsigned Base = fieldFromInstruction(Insn, 21, 5);
1435e4e83a7bSDaniel Sanders 
1436e4e83a7bSDaniel Sanders   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1437e4e83a7bSDaniel Sanders   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1438e4e83a7bSDaniel Sanders 
1439e4e83a7bSDaniel Sanders    if (Inst.getOpcode() == Mips::SCE)
1440e4e83a7bSDaniel Sanders      Inst.addOperand(MCOperand::createReg(Reg));
1441e4e83a7bSDaniel Sanders 
1442e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1443e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1444e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
144571928e68SAkira Hatanaka 
144671928e68SAkira Hatanaka   return MCDisassembler::Success;
144771928e68SAkira Hatanaka }
144871928e68SAkira Hatanaka 
14493c88fbd3SHrvoje Varga static DecodeStatus DecodeLoadByte9(MCInst &Inst,
14503c88fbd3SHrvoje Varga                                     unsigned Insn,
14513c88fbd3SHrvoje Varga                                     uint64_t Address,
14523c88fbd3SHrvoje Varga                                     const void *Decoder) {
14533c88fbd3SHrvoje Varga   int Offset = SignExtend32<9>(Insn & 0x1ff);
14543c88fbd3SHrvoje Varga   unsigned Base = fieldFromInstruction(Insn, 16, 5);
14553c88fbd3SHrvoje Varga   unsigned Reg = fieldFromInstruction(Insn, 21, 5);
14563c88fbd3SHrvoje Varga 
14573c88fbd3SHrvoje Varga   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
14583c88fbd3SHrvoje Varga   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
14593c88fbd3SHrvoje Varga 
14603c88fbd3SHrvoje Varga   Inst.addOperand(MCOperand::createReg(Reg));
14613c88fbd3SHrvoje Varga   Inst.addOperand(MCOperand::createReg(Base));
14623c88fbd3SHrvoje Varga   Inst.addOperand(MCOperand::createImm(Offset));
14633c88fbd3SHrvoje Varga 
14643c88fbd3SHrvoje Varga   return MCDisassembler::Success;
14653c88fbd3SHrvoje Varga }
14663c88fbd3SHrvoje Varga 
14673c88fbd3SHrvoje Varga static DecodeStatus DecodeLoadByte15(MCInst &Inst,
14683c88fbd3SHrvoje Varga                                      unsigned Insn,
14693c88fbd3SHrvoje Varga                                      uint64_t Address,
14703c88fbd3SHrvoje Varga                                      const void *Decoder) {
14713c88fbd3SHrvoje Varga   int Offset = SignExtend32<16>(Insn & 0xffff);
14723c88fbd3SHrvoje Varga   unsigned Base = fieldFromInstruction(Insn, 16, 5);
14733c88fbd3SHrvoje Varga   unsigned Reg = fieldFromInstruction(Insn, 21, 5);
14743c88fbd3SHrvoje Varga 
14753c88fbd3SHrvoje Varga   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
14763c88fbd3SHrvoje Varga   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
14773c88fbd3SHrvoje Varga 
14783c88fbd3SHrvoje Varga   Inst.addOperand(MCOperand::createReg(Reg));
14793c88fbd3SHrvoje Varga   Inst.addOperand(MCOperand::createReg(Base));
14803c88fbd3SHrvoje Varga   Inst.addOperand(MCOperand::createImm(Offset));
14813c88fbd3SHrvoje Varga 
14823c88fbd3SHrvoje Varga   return MCDisassembler::Success;
14833c88fbd3SHrvoje Varga }
14843c88fbd3SHrvoje Varga 
148592db6b78SDaniel Sanders static DecodeStatus DecodeCacheOp(MCInst &Inst,
148692db6b78SDaniel Sanders                               unsigned Insn,
148792db6b78SDaniel Sanders                               uint64_t Address,
148892db6b78SDaniel Sanders                               const void *Decoder) {
148992db6b78SDaniel Sanders   int Offset = SignExtend32<16>(Insn & 0xffff);
149092db6b78SDaniel Sanders   unsigned Hint = fieldFromInstruction(Insn, 16, 5);
149192db6b78SDaniel Sanders   unsigned Base = fieldFromInstruction(Insn, 21, 5);
149292db6b78SDaniel Sanders 
149392db6b78SDaniel Sanders   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
149492db6b78SDaniel Sanders 
1495e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1496e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
1497e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Hint));
149892db6b78SDaniel Sanders 
149992db6b78SDaniel Sanders   return MCDisassembler::Success;
150092db6b78SDaniel Sanders }
150192db6b78SDaniel Sanders 
1502ab6d1cceSJozef Kolek static DecodeStatus DecodeCacheOpMM(MCInst &Inst,
1503ab6d1cceSJozef Kolek                                     unsigned Insn,
1504ab6d1cceSJozef Kolek                                     uint64_t Address,
1505ab6d1cceSJozef Kolek                                     const void *Decoder) {
1506ab6d1cceSJozef Kolek   int Offset = SignExtend32<12>(Insn & 0xfff);
1507ab6d1cceSJozef Kolek   unsigned Base = fieldFromInstruction(Insn, 16, 5);
1508ab6d1cceSJozef Kolek   unsigned Hint = fieldFromInstruction(Insn, 21, 5);
1509ab6d1cceSJozef Kolek 
1510ab6d1cceSJozef Kolek   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1511ab6d1cceSJozef Kolek 
1512e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1513e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
1514e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Hint));
1515ab6d1cceSJozef Kolek 
1516ab6d1cceSJozef Kolek   return MCDisassembler::Success;
1517ab6d1cceSJozef Kolek }
1518ab6d1cceSJozef Kolek 
1519d9790793SZoran Jovanovic static DecodeStatus DecodePrefeOpMM(MCInst &Inst,
1520d9790793SZoran Jovanovic                                     unsigned Insn,
1521d9790793SZoran Jovanovic                                     uint64_t Address,
1522d9790793SZoran Jovanovic                                     const void *Decoder) {
1523d9790793SZoran Jovanovic   int Offset = SignExtend32<9>(Insn & 0x1ff);
1524d9790793SZoran Jovanovic   unsigned Base = fieldFromInstruction(Insn, 16, 5);
1525d9790793SZoran Jovanovic   unsigned Hint = fieldFromInstruction(Insn, 21, 5);
1526d9790793SZoran Jovanovic 
1527d9790793SZoran Jovanovic   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1528d9790793SZoran Jovanovic 
1529d9790793SZoran Jovanovic   Inst.addOperand(MCOperand::createReg(Base));
1530d9790793SZoran Jovanovic   Inst.addOperand(MCOperand::createImm(Offset));
1531d9790793SZoran Jovanovic   Inst.addOperand(MCOperand::createImm(Hint));
1532d9790793SZoran Jovanovic 
1533d9790793SZoran Jovanovic   return MCDisassembler::Success;
1534d9790793SZoran Jovanovic }
1535d9790793SZoran Jovanovic 
1536e4e83a7bSDaniel Sanders static DecodeStatus DecodeCacheeOp_CacheOpR6(MCInst &Inst,
1537df464ae2SVladimir Medic                                              unsigned Insn,
1538df464ae2SVladimir Medic                                              uint64_t Address,
1539df464ae2SVladimir Medic                                              const void *Decoder) {
1540e4e83a7bSDaniel Sanders   int Offset = SignExtend32<9>(Insn >> 7);
1541df464ae2SVladimir Medic   unsigned Hint = fieldFromInstruction(Insn, 16, 5);
1542df464ae2SVladimir Medic   unsigned Base = fieldFromInstruction(Insn, 21, 5);
1543df464ae2SVladimir Medic 
1544df464ae2SVladimir Medic   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1545df464ae2SVladimir Medic 
1546e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1547e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
1548e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Hint));
1549df464ae2SVladimir Medic 
1550df464ae2SVladimir Medic   return MCDisassembler::Success;
1551df464ae2SVladimir Medic }
1552df464ae2SVladimir Medic 
15539eaa30d2SZoran Jovanovic static DecodeStatus DecodeStoreEvaOpMM(MCInst &Inst,
15549eaa30d2SZoran Jovanovic                                        unsigned Insn,
15559eaa30d2SZoran Jovanovic                                        uint64_t Address,
15569eaa30d2SZoran Jovanovic                                        const void *Decoder) {
15579eaa30d2SZoran Jovanovic   int Offset = SignExtend32<9>(Insn & 0x1ff);
15589eaa30d2SZoran Jovanovic   unsigned Reg = fieldFromInstruction(Insn, 21, 5);
15599eaa30d2SZoran Jovanovic   unsigned Base = fieldFromInstruction(Insn, 16, 5);
15609eaa30d2SZoran Jovanovic 
15619eaa30d2SZoran Jovanovic   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
15629eaa30d2SZoran Jovanovic   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
15639eaa30d2SZoran Jovanovic 
15649eaa30d2SZoran Jovanovic   Inst.addOperand(MCOperand::createReg(Reg));
15659eaa30d2SZoran Jovanovic   Inst.addOperand(MCOperand::createReg(Base));
15669eaa30d2SZoran Jovanovic   Inst.addOperand(MCOperand::createImm(Offset));
15679eaa30d2SZoran Jovanovic 
15689eaa30d2SZoran Jovanovic   return MCDisassembler::Success;
15699eaa30d2SZoran Jovanovic }
15709eaa30d2SZoran Jovanovic 
1571b4484d62SDaniel Sanders static DecodeStatus DecodeSyncI(MCInst &Inst,
1572b4484d62SDaniel Sanders                               unsigned Insn,
1573b4484d62SDaniel Sanders                               uint64_t Address,
1574b4484d62SDaniel Sanders                               const void *Decoder) {
1575b4484d62SDaniel Sanders   int Offset = SignExtend32<16>(Insn & 0xffff);
1576b4484d62SDaniel Sanders   unsigned Base = fieldFromInstruction(Insn, 21, 5);
1577b4484d62SDaniel Sanders 
1578b4484d62SDaniel Sanders   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1579b4484d62SDaniel Sanders 
1580e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1581e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
1582b4484d62SDaniel Sanders 
1583b4484d62SDaniel Sanders   return MCDisassembler::Success;
1584b4484d62SDaniel Sanders }
1585b4484d62SDaniel Sanders 
158618148671SHrvoje Varga static DecodeStatus DecodeSynciR6(MCInst &Inst,
158718148671SHrvoje Varga                                   unsigned Insn,
158818148671SHrvoje Varga                                   uint64_t Address,
158918148671SHrvoje Varga                                   const void *Decoder) {
159018148671SHrvoje Varga   int Immediate = SignExtend32<16>(Insn & 0xffff);
159118148671SHrvoje Varga   unsigned Base = fieldFromInstruction(Insn, 16, 5);
159218148671SHrvoje Varga 
159318148671SHrvoje Varga   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
159418148671SHrvoje Varga 
159518148671SHrvoje Varga   Inst.addOperand(MCOperand::createReg(Base));
159618148671SHrvoje Varga   Inst.addOperand(MCOperand::createImm(Immediate));
159718148671SHrvoje Varga 
159818148671SHrvoje Varga   return MCDisassembler::Success;
159918148671SHrvoje Varga }
160018148671SHrvoje Varga 
1601fe0bf9f6SMatheus Almeida static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn,
1602fe0bf9f6SMatheus Almeida                                     uint64_t Address, const void *Decoder) {
1603fe0bf9f6SMatheus Almeida   int Offset = SignExtend32<10>(fieldFromInstruction(Insn, 16, 10));
1604fe0bf9f6SMatheus Almeida   unsigned Reg = fieldFromInstruction(Insn, 6, 5);
1605fe0bf9f6SMatheus Almeida   unsigned Base = fieldFromInstruction(Insn, 11, 5);
1606fe0bf9f6SMatheus Almeida 
1607fe0bf9f6SMatheus Almeida   Reg = getReg(Decoder, Mips::MSA128BRegClassID, Reg);
1608fe0bf9f6SMatheus Almeida   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1609fe0bf9f6SMatheus Almeida 
1610e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1611e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
16126b59c449SMatheus Almeida 
16136b59c449SMatheus Almeida   // The immediate field of an LD/ST instruction is scaled which means it must
16146b59c449SMatheus Almeida   // be multiplied (when decoding) by the size (in bytes) of the instructions'
16156b59c449SMatheus Almeida   // data format.
16166b59c449SMatheus Almeida   // .b - 1 byte
16176b59c449SMatheus Almeida   // .h - 2 bytes
16186b59c449SMatheus Almeida   // .w - 4 bytes
16196b59c449SMatheus Almeida   // .d - 8 bytes
16206b59c449SMatheus Almeida   switch(Inst.getOpcode())
16216b59c449SMatheus Almeida   {
16226b59c449SMatheus Almeida   default:
16236b59c449SMatheus Almeida     assert (0 && "Unexpected instruction");
16246b59c449SMatheus Almeida     return MCDisassembler::Fail;
16256b59c449SMatheus Almeida     break;
16266b59c449SMatheus Almeida   case Mips::LD_B:
16276b59c449SMatheus Almeida   case Mips::ST_B:
1628e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(Offset));
16296b59c449SMatheus Almeida     break;
16306b59c449SMatheus Almeida   case Mips::LD_H:
16316b59c449SMatheus Almeida   case Mips::ST_H:
1632e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(Offset * 2));
16336b59c449SMatheus Almeida     break;
16346b59c449SMatheus Almeida   case Mips::LD_W:
16356b59c449SMatheus Almeida   case Mips::ST_W:
1636e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(Offset * 4));
16376b59c449SMatheus Almeida     break;
16386b59c449SMatheus Almeida   case Mips::LD_D:
16396b59c449SMatheus Almeida   case Mips::ST_D:
1640e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(Offset * 8));
16416b59c449SMatheus Almeida     break;
16426b59c449SMatheus Almeida   }
1643fe0bf9f6SMatheus Almeida 
1644fe0bf9f6SMatheus Almeida   return MCDisassembler::Success;
1645fe0bf9f6SMatheus Almeida }
1646fe0bf9f6SMatheus Almeida 
1647315e7ecaSJozef Kolek static DecodeStatus DecodeMemMMImm4(MCInst &Inst,
1648315e7ecaSJozef Kolek                                     unsigned Insn,
1649315e7ecaSJozef Kolek                                     uint64_t Address,
1650315e7ecaSJozef Kolek                                     const void *Decoder) {
1651315e7ecaSJozef Kolek   unsigned Offset = Insn & 0xf;
1652315e7ecaSJozef Kolek   unsigned Reg = fieldFromInstruction(Insn, 7, 3);
1653315e7ecaSJozef Kolek   unsigned Base = fieldFromInstruction(Insn, 4, 3);
1654315e7ecaSJozef Kolek 
1655315e7ecaSJozef Kolek   switch (Inst.getOpcode()) {
1656315e7ecaSJozef Kolek     case Mips::LBU16_MM:
1657315e7ecaSJozef Kolek     case Mips::LHU16_MM:
1658315e7ecaSJozef Kolek     case Mips::LW16_MM:
1659315e7ecaSJozef Kolek       if (DecodeGPRMM16RegisterClass(Inst, Reg, Address, Decoder)
1660315e7ecaSJozef Kolek             == MCDisassembler::Fail)
1661315e7ecaSJozef Kolek         return MCDisassembler::Fail;
1662315e7ecaSJozef Kolek       break;
1663315e7ecaSJozef Kolek     case Mips::SB16_MM:
1664797c2aecSZlatko Buljan     case Mips::SB16_MMR6:
1665315e7ecaSJozef Kolek     case Mips::SH16_MM:
1666797c2aecSZlatko Buljan     case Mips::SH16_MMR6:
1667315e7ecaSJozef Kolek     case Mips::SW16_MM:
1668797c2aecSZlatko Buljan     case Mips::SW16_MMR6:
1669315e7ecaSJozef Kolek       if (DecodeGPRMM16ZeroRegisterClass(Inst, Reg, Address, Decoder)
1670315e7ecaSJozef Kolek             == MCDisassembler::Fail)
1671315e7ecaSJozef Kolek         return MCDisassembler::Fail;
1672315e7ecaSJozef Kolek       break;
1673315e7ecaSJozef Kolek   }
1674315e7ecaSJozef Kolek 
1675315e7ecaSJozef Kolek   if (DecodeGPRMM16RegisterClass(Inst, Base, Address, Decoder)
1676315e7ecaSJozef Kolek         == MCDisassembler::Fail)
1677315e7ecaSJozef Kolek     return MCDisassembler::Fail;
1678315e7ecaSJozef Kolek 
1679315e7ecaSJozef Kolek   switch (Inst.getOpcode()) {
1680315e7ecaSJozef Kolek     case Mips::LBU16_MM:
1681315e7ecaSJozef Kolek       if (Offset == 0xf)
1682e9119e41SJim Grosbach         Inst.addOperand(MCOperand::createImm(-1));
1683315e7ecaSJozef Kolek       else
1684e9119e41SJim Grosbach         Inst.addOperand(MCOperand::createImm(Offset));
1685315e7ecaSJozef Kolek       break;
1686315e7ecaSJozef Kolek     case Mips::SB16_MM:
1687797c2aecSZlatko Buljan     case Mips::SB16_MMR6:
1688e9119e41SJim Grosbach       Inst.addOperand(MCOperand::createImm(Offset));
1689315e7ecaSJozef Kolek       break;
1690315e7ecaSJozef Kolek     case Mips::LHU16_MM:
1691315e7ecaSJozef Kolek     case Mips::SH16_MM:
1692797c2aecSZlatko Buljan     case Mips::SH16_MMR6:
1693e9119e41SJim Grosbach       Inst.addOperand(MCOperand::createImm(Offset << 1));
1694315e7ecaSJozef Kolek       break;
1695315e7ecaSJozef Kolek     case Mips::LW16_MM:
1696315e7ecaSJozef Kolek     case Mips::SW16_MM:
1697797c2aecSZlatko Buljan     case Mips::SW16_MMR6:
1698e9119e41SJim Grosbach       Inst.addOperand(MCOperand::createImm(Offset << 2));
1699315e7ecaSJozef Kolek       break;
1700315e7ecaSJozef Kolek   }
1701315e7ecaSJozef Kolek 
1702315e7ecaSJozef Kolek   return MCDisassembler::Success;
1703315e7ecaSJozef Kolek }
1704315e7ecaSJozef Kolek 
170512c6982bSJozef Kolek static DecodeStatus DecodeMemMMSPImm5Lsl2(MCInst &Inst,
170612c6982bSJozef Kolek                                           unsigned Insn,
170712c6982bSJozef Kolek                                           uint64_t Address,
170812c6982bSJozef Kolek                                           const void *Decoder) {
170912c6982bSJozef Kolek   unsigned Offset = Insn & 0x1F;
171012c6982bSJozef Kolek   unsigned Reg = fieldFromInstruction(Insn, 5, 5);
171112c6982bSJozef Kolek 
171212c6982bSJozef Kolek   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
171312c6982bSJozef Kolek 
1714e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1715e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Mips::SP));
1716e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset << 2));
171712c6982bSJozef Kolek 
171812c6982bSJozef Kolek   return MCDisassembler::Success;
171912c6982bSJozef Kolek }
172012c6982bSJozef Kolek 
1721e10a02ecSJozef Kolek static DecodeStatus DecodeMemMMGPImm7Lsl2(MCInst &Inst,
1722e10a02ecSJozef Kolek                                           unsigned Insn,
1723e10a02ecSJozef Kolek                                           uint64_t Address,
1724e10a02ecSJozef Kolek                                           const void *Decoder) {
1725e10a02ecSJozef Kolek   unsigned Offset = Insn & 0x7F;
1726e10a02ecSJozef Kolek   unsigned Reg = fieldFromInstruction(Insn, 7, 3);
1727e10a02ecSJozef Kolek 
1728e10a02ecSJozef Kolek   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1729e10a02ecSJozef Kolek 
1730e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1731e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Mips::GP));
1732e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset << 2));
1733e10a02ecSJozef Kolek 
1734e10a02ecSJozef Kolek   return MCDisassembler::Success;
1735e10a02ecSJozef Kolek }
1736e10a02ecSJozef Kolek 
1737d68d424aSJozef Kolek static DecodeStatus DecodeMemMMReglistImm4Lsl2(MCInst &Inst,
1738d68d424aSJozef Kolek                                                unsigned Insn,
1739d68d424aSJozef Kolek                                                uint64_t Address,
1740d68d424aSJozef Kolek                                                const void *Decoder) {
1741797c2aecSZlatko Buljan   int Offset;
1742797c2aecSZlatko Buljan   switch (Inst.getOpcode()) {
1743797c2aecSZlatko Buljan   case Mips::LWM16_MMR6:
1744797c2aecSZlatko Buljan   case Mips::SWM16_MMR6:
1745797c2aecSZlatko Buljan     Offset = fieldFromInstruction(Insn, 4, 4);
1746797c2aecSZlatko Buljan     break;
1747797c2aecSZlatko Buljan   default:
1748797c2aecSZlatko Buljan     Offset = SignExtend32<4>(Insn & 0xf);
1749797c2aecSZlatko Buljan     break;
1750797c2aecSZlatko Buljan   }
1751d68d424aSJozef Kolek 
1752d68d424aSJozef Kolek   if (DecodeRegListOperand16(Inst, Insn, Address, Decoder)
1753d68d424aSJozef Kolek       == MCDisassembler::Fail)
1754d68d424aSJozef Kolek     return MCDisassembler::Fail;
1755d68d424aSJozef Kolek 
1756e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Mips::SP));
1757e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset << 2));
1758d68d424aSJozef Kolek 
1759d68d424aSJozef Kolek   return MCDisassembler::Success;
1760d68d424aSJozef Kolek }
1761d68d424aSJozef Kolek 
1762a6593ff6SZoran Jovanovic static DecodeStatus DecodeMemMMImm9(MCInst &Inst,
1763a6593ff6SZoran Jovanovic                                     unsigned Insn,
1764a6593ff6SZoran Jovanovic                                     uint64_t Address,
1765a6593ff6SZoran Jovanovic                                     const void *Decoder) {
1766a6593ff6SZoran Jovanovic   int Offset = SignExtend32<9>(Insn & 0x1ff);
1767a6593ff6SZoran Jovanovic   unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1768a6593ff6SZoran Jovanovic   unsigned Base = fieldFromInstruction(Insn, 16, 5);
1769a6593ff6SZoran Jovanovic 
1770a6593ff6SZoran Jovanovic   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1771a6593ff6SZoran Jovanovic   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1772a6593ff6SZoran Jovanovic 
17733ef4dd7bSHrvoje Varga   if (Inst.getOpcode() == Mips::SCE_MM)
17743ef4dd7bSHrvoje Varga     Inst.addOperand(MCOperand::createReg(Reg));
17753ef4dd7bSHrvoje Varga 
1776a6593ff6SZoran Jovanovic   Inst.addOperand(MCOperand::createReg(Reg));
1777a6593ff6SZoran Jovanovic   Inst.addOperand(MCOperand::createReg(Base));
1778a6593ff6SZoran Jovanovic   Inst.addOperand(MCOperand::createImm(Offset));
1779a6593ff6SZoran Jovanovic 
1780a6593ff6SZoran Jovanovic   return MCDisassembler::Success;
1781a6593ff6SZoran Jovanovic }
1782a6593ff6SZoran Jovanovic 
1783dde3d582SVladimir Medic static DecodeStatus DecodeMemMMImm12(MCInst &Inst,
1784dde3d582SVladimir Medic                                      unsigned Insn,
1785dde3d582SVladimir Medic                                      uint64_t Address,
1786dde3d582SVladimir Medic                                      const void *Decoder) {
1787dde3d582SVladimir Medic   int Offset = SignExtend32<12>(Insn & 0x0fff);
1788dde3d582SVladimir Medic   unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1789dde3d582SVladimir Medic   unsigned Base = fieldFromInstruction(Insn, 16, 5);
1790dde3d582SVladimir Medic 
1791dde3d582SVladimir Medic   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1792dde3d582SVladimir Medic   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1793dde3d582SVladimir Medic 
1794a4c4b5fcSZoran Jovanovic   switch (Inst.getOpcode()) {
1795a4c4b5fcSZoran Jovanovic   case Mips::SWM32_MM:
1796a4c4b5fcSZoran Jovanovic   case Mips::LWM32_MM:
1797a4c4b5fcSZoran Jovanovic     if (DecodeRegListOperand(Inst, Insn, Address, Decoder)
1798a4c4b5fcSZoran Jovanovic         == MCDisassembler::Fail)
1799a4c4b5fcSZoran Jovanovic       return MCDisassembler::Fail;
1800e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Base));
1801e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(Offset));
1802a4c4b5fcSZoran Jovanovic     break;
1803a4c4b5fcSZoran Jovanovic   case Mips::SC_MM:
1804e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Reg));
1805b03fd12cSJustin Bogner     LLVM_FALLTHROUGH;
1806a4c4b5fcSZoran Jovanovic   default:
1807e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Reg));
1808ba553a6eSZlatko Buljan     if (Inst.getOpcode() == Mips::LWP_MM || Inst.getOpcode() == Mips::SWP_MM ||
1809ba553a6eSZlatko Buljan         Inst.getOpcode() == Mips::LWP_MMR6 || Inst.getOpcode() == Mips::SWP_MMR6)
1810e9119e41SJim Grosbach       Inst.addOperand(MCOperand::createReg(Reg+1));
18112deca348SZoran Jovanovic 
1812e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Base));
1813e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(Offset));
1814a4c4b5fcSZoran Jovanovic   }
1815dde3d582SVladimir Medic 
1816dde3d582SVladimir Medic   return MCDisassembler::Success;
1817dde3d582SVladimir Medic }
1818dde3d582SVladimir Medic 
1819dde3d582SVladimir Medic static DecodeStatus DecodeMemMMImm16(MCInst &Inst,
1820dde3d582SVladimir Medic                                      unsigned Insn,
1821dde3d582SVladimir Medic                                      uint64_t Address,
1822dde3d582SVladimir Medic                                      const void *Decoder) {
1823dde3d582SVladimir Medic   int Offset = SignExtend32<16>(Insn & 0xffff);
1824dde3d582SVladimir Medic   unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1825dde3d582SVladimir Medic   unsigned Base = fieldFromInstruction(Insn, 16, 5);
1826dde3d582SVladimir Medic 
1827dde3d582SVladimir Medic   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1828dde3d582SVladimir Medic   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1829dde3d582SVladimir Medic 
1830e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1831e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1832e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
1833dde3d582SVladimir Medic 
1834dde3d582SVladimir Medic   return MCDisassembler::Success;
1835dde3d582SVladimir Medic }
1836dde3d582SVladimir Medic 
183771928e68SAkira Hatanaka static DecodeStatus DecodeFMem(MCInst &Inst,
183871928e68SAkira Hatanaka                                unsigned Insn,
183971928e68SAkira Hatanaka                                uint64_t Address,
184071928e68SAkira Hatanaka                                const void *Decoder) {
184171928e68SAkira Hatanaka   int Offset = SignExtend32<16>(Insn & 0xffff);
1842ecaef49fSJim Grosbach   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1843ecaef49fSJim Grosbach   unsigned Base = fieldFromInstruction(Insn, 21, 5);
184471928e68SAkira Hatanaka 
18459bf2b567SAkira Hatanaka   Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg);
184613e6ccf3SAkira Hatanaka   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
18479bf2b567SAkira Hatanaka 
1848e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1849e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1850e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
185171928e68SAkira Hatanaka 
185271928e68SAkira Hatanaka   return MCDisassembler::Success;
185371928e68SAkira Hatanaka }
185471928e68SAkira Hatanaka 
1855cba9f80bSZlatko Buljan static DecodeStatus DecodeFMemMMR2(MCInst &Inst, unsigned Insn,
1856cba9f80bSZlatko Buljan                                    uint64_t Address, const void *Decoder) {
1857cba9f80bSZlatko Buljan   // This function is the same as DecodeFMem but with the Reg and Base fields
1858cba9f80bSZlatko Buljan   // swapped according to microMIPS spec.
1859cba9f80bSZlatko Buljan   int Offset = SignExtend32<16>(Insn & 0xffff);
1860cba9f80bSZlatko Buljan   unsigned Base = fieldFromInstruction(Insn, 16, 5);
1861cba9f80bSZlatko Buljan   unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1862cba9f80bSZlatko Buljan 
1863cba9f80bSZlatko Buljan   Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg);
1864cba9f80bSZlatko Buljan   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1865cba9f80bSZlatko Buljan 
1866cba9f80bSZlatko Buljan   Inst.addOperand(MCOperand::createReg(Reg));
1867cba9f80bSZlatko Buljan   Inst.addOperand(MCOperand::createReg(Base));
1868cba9f80bSZlatko Buljan   Inst.addOperand(MCOperand::createImm(Offset));
1869cba9f80bSZlatko Buljan 
1870cba9f80bSZlatko Buljan   return MCDisassembler::Success;
1871cba9f80bSZlatko Buljan }
1872cba9f80bSZlatko Buljan 
187392db6b78SDaniel Sanders static DecodeStatus DecodeFMem2(MCInst &Inst,
187492db6b78SDaniel Sanders                                unsigned Insn,
187592db6b78SDaniel Sanders                                uint64_t Address,
187692db6b78SDaniel Sanders                                const void *Decoder) {
187792db6b78SDaniel Sanders   int Offset = SignExtend32<16>(Insn & 0xffff);
187892db6b78SDaniel Sanders   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
187992db6b78SDaniel Sanders   unsigned Base = fieldFromInstruction(Insn, 21, 5);
188092db6b78SDaniel Sanders 
188192db6b78SDaniel Sanders   Reg = getReg(Decoder, Mips::COP2RegClassID, Reg);
188292db6b78SDaniel Sanders   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
188392db6b78SDaniel Sanders 
1884e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1885e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1886e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
188792db6b78SDaniel Sanders 
188892db6b78SDaniel Sanders   return MCDisassembler::Success;
188992db6b78SDaniel Sanders }
189092db6b78SDaniel Sanders 
189192db6b78SDaniel Sanders static DecodeStatus DecodeFMem3(MCInst &Inst,
189292db6b78SDaniel Sanders                                unsigned Insn,
189392db6b78SDaniel Sanders                                uint64_t Address,
189492db6b78SDaniel Sanders                                const void *Decoder) {
189592db6b78SDaniel Sanders   int Offset = SignExtend32<16>(Insn & 0xffff);
189692db6b78SDaniel Sanders   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
189792db6b78SDaniel Sanders   unsigned Base = fieldFromInstruction(Insn, 21, 5);
189892db6b78SDaniel Sanders 
189992db6b78SDaniel Sanders   Reg = getReg(Decoder, Mips::COP3RegClassID, Reg);
190092db6b78SDaniel Sanders   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
190192db6b78SDaniel Sanders 
1902e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1903e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1904e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
190592db6b78SDaniel Sanders 
190692db6b78SDaniel Sanders   return MCDisassembler::Success;
190792db6b78SDaniel Sanders }
190892db6b78SDaniel Sanders 
1909435cf8a4SVladimir Medic static DecodeStatus DecodeFMemCop2R6(MCInst &Inst,
1910435cf8a4SVladimir Medic                                     unsigned Insn,
1911435cf8a4SVladimir Medic                                     uint64_t Address,
1912435cf8a4SVladimir Medic                                     const void *Decoder) {
1913435cf8a4SVladimir Medic   int Offset = SignExtend32<11>(Insn & 0x07ff);
1914435cf8a4SVladimir Medic   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1915435cf8a4SVladimir Medic   unsigned Base = fieldFromInstruction(Insn, 11, 5);
1916435cf8a4SVladimir Medic 
1917435cf8a4SVladimir Medic   Reg = getReg(Decoder, Mips::COP2RegClassID, Reg);
1918435cf8a4SVladimir Medic   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1919435cf8a4SVladimir Medic 
1920e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1921e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1922e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
1923435cf8a4SVladimir Medic 
1924435cf8a4SVladimir Medic   return MCDisassembler::Success;
1925435cf8a4SVladimir Medic }
1926cba9f80bSZlatko Buljan 
1927cba9f80bSZlatko Buljan static DecodeStatus DecodeFMemCop2MMR6(MCInst &Inst, unsigned Insn,
1928cba9f80bSZlatko Buljan                                        uint64_t Address, const void *Decoder) {
1929cba9f80bSZlatko Buljan   int Offset = SignExtend32<11>(Insn & 0x07ff);
1930cba9f80bSZlatko Buljan   unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1931cba9f80bSZlatko Buljan   unsigned Base = fieldFromInstruction(Insn, 16, 5);
1932cba9f80bSZlatko Buljan 
1933cba9f80bSZlatko Buljan   Reg = getReg(Decoder, Mips::COP2RegClassID, Reg);
1934cba9f80bSZlatko Buljan   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1935cba9f80bSZlatko Buljan 
1936cba9f80bSZlatko Buljan   Inst.addOperand(MCOperand::createReg(Reg));
1937cba9f80bSZlatko Buljan   Inst.addOperand(MCOperand::createReg(Base));
1938cba9f80bSZlatko Buljan   Inst.addOperand(MCOperand::createImm(Offset));
1939cba9f80bSZlatko Buljan 
1940cba9f80bSZlatko Buljan   return MCDisassembler::Success;
1941cba9f80bSZlatko Buljan }
1942cba9f80bSZlatko Buljan 
19436a803f61SDaniel Sanders static DecodeStatus DecodeSpecial3LlSc(MCInst &Inst,
19446a803f61SDaniel Sanders                                        unsigned Insn,
19456a803f61SDaniel Sanders                                        uint64_t Address,
19466a803f61SDaniel Sanders                                        const void *Decoder) {
19476a803f61SDaniel Sanders   int64_t Offset = SignExtend64<9>((Insn >> 7) & 0x1ff);
19486a803f61SDaniel Sanders   unsigned Rt = fieldFromInstruction(Insn, 16, 5);
19496a803f61SDaniel Sanders   unsigned Base = fieldFromInstruction(Insn, 21, 5);
19506a803f61SDaniel Sanders 
19516a803f61SDaniel Sanders   Rt = getReg(Decoder, Mips::GPR32RegClassID, Rt);
19526a803f61SDaniel Sanders   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
19536a803f61SDaniel Sanders 
19546a803f61SDaniel Sanders   if(Inst.getOpcode() == Mips::SC_R6 || Inst.getOpcode() == Mips::SCD_R6){
1955e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Rt));
19566a803f61SDaniel Sanders   }
19576a803f61SDaniel Sanders 
1958e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Rt));
1959e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1960e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
19616a803f61SDaniel Sanders 
19626a803f61SDaniel Sanders   return MCDisassembler::Success;
19636a803f61SDaniel Sanders }
196471928e68SAkira Hatanaka 
196571928e68SAkira Hatanaka static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
196671928e68SAkira Hatanaka                                               unsigned RegNo,
196771928e68SAkira Hatanaka                                               uint64_t Address,
196871928e68SAkira Hatanaka                                               const void *Decoder) {
196971928e68SAkira Hatanaka   // Currently only hardware register 29 is supported.
197071928e68SAkira Hatanaka   if (RegNo != 29)
197171928e68SAkira Hatanaka     return  MCDisassembler::Fail;
1972e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Mips::HWR29));
197371928e68SAkira Hatanaka   return MCDisassembler::Success;
197471928e68SAkira Hatanaka }
197571928e68SAkira Hatanaka 
197671928e68SAkira Hatanaka static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
197771928e68SAkira Hatanaka                                               unsigned RegNo,
197871928e68SAkira Hatanaka                                               uint64_t Address,
197971928e68SAkira Hatanaka                                               const void *Decoder) {
19809bf2b567SAkira Hatanaka   if (RegNo > 30 || RegNo %2)
198171928e68SAkira Hatanaka     return MCDisassembler::Fail;
198271928e68SAkira Hatanaka 
19839bf2b567SAkira Hatanaka   ;
19849bf2b567SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::AFGR64RegClassID, RegNo /2);
1985e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
198671928e68SAkira Hatanaka   return MCDisassembler::Success;
198771928e68SAkira Hatanaka }
198871928e68SAkira Hatanaka 
198900fcf2e1SAkira Hatanaka static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst,
1990ecabd1a5SAkira Hatanaka                                                 unsigned RegNo,
1991ecabd1a5SAkira Hatanaka                                                 uint64_t Address,
1992ecabd1a5SAkira Hatanaka                                                 const void *Decoder) {
1993ecabd1a5SAkira Hatanaka   if (RegNo >= 4)
1994ecabd1a5SAkira Hatanaka     return MCDisassembler::Fail;
1995ecabd1a5SAkira Hatanaka 
199600fcf2e1SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::ACC64DSPRegClassID, RegNo);
1997e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1998ecabd1a5SAkira Hatanaka   return MCDisassembler::Success;
1999ecabd1a5SAkira Hatanaka }
2000ecabd1a5SAkira Hatanaka 
20018002a3f6SAkira Hatanaka static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst,
200259bfaf77SAkira Hatanaka                                                unsigned RegNo,
200359bfaf77SAkira Hatanaka                                                uint64_t Address,
200459bfaf77SAkira Hatanaka                                                const void *Decoder) {
200559bfaf77SAkira Hatanaka   if (RegNo >= 4)
200659bfaf77SAkira Hatanaka     return MCDisassembler::Fail;
200759bfaf77SAkira Hatanaka 
20088002a3f6SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::HI32DSPRegClassID, RegNo);
2009e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
201059bfaf77SAkira Hatanaka   return MCDisassembler::Success;
201159bfaf77SAkira Hatanaka }
201259bfaf77SAkira Hatanaka 
20138002a3f6SAkira Hatanaka static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst,
201459bfaf77SAkira Hatanaka                                                unsigned RegNo,
201559bfaf77SAkira Hatanaka                                                uint64_t Address,
201659bfaf77SAkira Hatanaka                                                const void *Decoder) {
201759bfaf77SAkira Hatanaka   if (RegNo >= 4)
201859bfaf77SAkira Hatanaka     return MCDisassembler::Fail;
201959bfaf77SAkira Hatanaka 
20208002a3f6SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::LO32DSPRegClassID, RegNo);
2021e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
202259bfaf77SAkira Hatanaka   return MCDisassembler::Success;
202359bfaf77SAkira Hatanaka }
202459bfaf77SAkira Hatanaka 
20253eb663b0SJack Carter static DecodeStatus DecodeMSA128BRegisterClass(MCInst &Inst,
20263eb663b0SJack Carter                                                unsigned RegNo,
20273eb663b0SJack Carter                                                uint64_t Address,
20283eb663b0SJack Carter                                                const void *Decoder) {
20293eb663b0SJack Carter   if (RegNo > 31)
20303eb663b0SJack Carter     return MCDisassembler::Fail;
20313eb663b0SJack Carter 
20323eb663b0SJack Carter   unsigned Reg = getReg(Decoder, Mips::MSA128BRegClassID, RegNo);
2033e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
20343eb663b0SJack Carter   return MCDisassembler::Success;
20353eb663b0SJack Carter }
20363eb663b0SJack Carter 
20375dc8ac92SJack Carter static DecodeStatus DecodeMSA128HRegisterClass(MCInst &Inst,
20385dc8ac92SJack Carter                                                unsigned RegNo,
20395dc8ac92SJack Carter                                                uint64_t Address,
20405dc8ac92SJack Carter                                                const void *Decoder) {
20415dc8ac92SJack Carter   if (RegNo > 31)
20425dc8ac92SJack Carter     return MCDisassembler::Fail;
20435dc8ac92SJack Carter 
20445dc8ac92SJack Carter   unsigned Reg = getReg(Decoder, Mips::MSA128HRegClassID, RegNo);
2045e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
20465dc8ac92SJack Carter   return MCDisassembler::Success;
20475dc8ac92SJack Carter }
20485dc8ac92SJack Carter 
20495dc8ac92SJack Carter static DecodeStatus DecodeMSA128WRegisterClass(MCInst &Inst,
20505dc8ac92SJack Carter                                                unsigned RegNo,
20515dc8ac92SJack Carter                                                uint64_t Address,
20525dc8ac92SJack Carter                                                const void *Decoder) {
20535dc8ac92SJack Carter   if (RegNo > 31)
20545dc8ac92SJack Carter     return MCDisassembler::Fail;
20555dc8ac92SJack Carter 
20565dc8ac92SJack Carter   unsigned Reg = getReg(Decoder, Mips::MSA128WRegClassID, RegNo);
2057e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
20585dc8ac92SJack Carter   return MCDisassembler::Success;
20595dc8ac92SJack Carter }
20605dc8ac92SJack Carter 
20615dc8ac92SJack Carter static DecodeStatus DecodeMSA128DRegisterClass(MCInst &Inst,
20625dc8ac92SJack Carter                                                unsigned RegNo,
20635dc8ac92SJack Carter                                                uint64_t Address,
20645dc8ac92SJack Carter                                                const void *Decoder) {
20655dc8ac92SJack Carter   if (RegNo > 31)
20665dc8ac92SJack Carter     return MCDisassembler::Fail;
20675dc8ac92SJack Carter 
20685dc8ac92SJack Carter   unsigned Reg = getReg(Decoder, Mips::MSA128DRegClassID, RegNo);
2069e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
20705dc8ac92SJack Carter   return MCDisassembler::Success;
20715dc8ac92SJack Carter }
20725dc8ac92SJack Carter 
2073a591fdc6SMatheus Almeida static DecodeStatus DecodeMSACtrlRegisterClass(MCInst &Inst,
2074a591fdc6SMatheus Almeida                                                unsigned RegNo,
2075a591fdc6SMatheus Almeida                                                uint64_t Address,
2076a591fdc6SMatheus Almeida                                                const void *Decoder) {
2077a591fdc6SMatheus Almeida   if (RegNo > 7)
2078a591fdc6SMatheus Almeida     return MCDisassembler::Fail;
2079a591fdc6SMatheus Almeida 
2080a591fdc6SMatheus Almeida   unsigned Reg = getReg(Decoder, Mips::MSACtrlRegClassID, RegNo);
2081e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
2082a591fdc6SMatheus Almeida   return MCDisassembler::Success;
2083a591fdc6SMatheus Almeida }
2084a591fdc6SMatheus Almeida 
2085a3134faeSDaniel Sanders static DecodeStatus DecodeCOP0RegisterClass(MCInst &Inst,
2086a3134faeSDaniel Sanders                                             unsigned RegNo,
2087a3134faeSDaniel Sanders                                             uint64_t Address,
2088a3134faeSDaniel Sanders                                             const void *Decoder) {
2089a3134faeSDaniel Sanders   if (RegNo > 31)
2090a3134faeSDaniel Sanders     return MCDisassembler::Fail;
2091a3134faeSDaniel Sanders 
2092a3134faeSDaniel Sanders   unsigned Reg = getReg(Decoder, Mips::COP0RegClassID, RegNo);
2093a3134faeSDaniel Sanders   Inst.addOperand(MCOperand::createReg(Reg));
2094a3134faeSDaniel Sanders   return MCDisassembler::Success;
2095a3134faeSDaniel Sanders }
2096a3134faeSDaniel Sanders 
20972a83d680SDaniel Sanders static DecodeStatus DecodeCOP2RegisterClass(MCInst &Inst,
20982a83d680SDaniel Sanders                                             unsigned RegNo,
20992a83d680SDaniel Sanders                                             uint64_t Address,
21002a83d680SDaniel Sanders                                             const void *Decoder) {
21012a83d680SDaniel Sanders   if (RegNo > 31)
21022a83d680SDaniel Sanders     return MCDisassembler::Fail;
21032a83d680SDaniel Sanders 
21042a83d680SDaniel Sanders   unsigned Reg = getReg(Decoder, Mips::COP2RegClassID, RegNo);
2105e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
21062a83d680SDaniel Sanders   return MCDisassembler::Success;
21072a83d680SDaniel Sanders }
21082a83d680SDaniel Sanders 
210971928e68SAkira Hatanaka static DecodeStatus DecodeBranchTarget(MCInst &Inst,
211071928e68SAkira Hatanaka                                        unsigned Offset,
211171928e68SAkira Hatanaka                                        uint64_t Address,
211271928e68SAkira Hatanaka                                        const void *Decoder) {
2113d37bab61SAlexey Samsonov   int32_t BranchOffset = (SignExtend32<16>(Offset) * 4) + 4;
2114e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(BranchOffset));
211571928e68SAkira Hatanaka   return MCDisassembler::Success;
211671928e68SAkira Hatanaka }
211771928e68SAkira Hatanaka 
21186f09cdfdSHrvoje Varga static DecodeStatus DecodeBranchTarget1SImm16(MCInst &Inst,
21196f09cdfdSHrvoje Varga                                               unsigned Offset,
21206f09cdfdSHrvoje Varga                                               uint64_t Address,
21216f09cdfdSHrvoje Varga                                               const void *Decoder) {
21226f09cdfdSHrvoje Varga   int32_t BranchOffset = (SignExtend32<16>(Offset) * 2);
21236f09cdfdSHrvoje Varga   Inst.addOperand(MCOperand::createImm(BranchOffset));
21246f09cdfdSHrvoje Varga   return MCDisassembler::Success;
21256f09cdfdSHrvoje Varga }
21266f09cdfdSHrvoje Varga 
212771928e68SAkira Hatanaka static DecodeStatus DecodeJumpTarget(MCInst &Inst,
212871928e68SAkira Hatanaka                                      unsigned Insn,
212971928e68SAkira Hatanaka                                      uint64_t Address,
213071928e68SAkira Hatanaka                                      const void *Decoder) {
213171928e68SAkira Hatanaka 
2132ecaef49fSJim Grosbach   unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 2;
2133e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(JumpOffset));
213471928e68SAkira Hatanaka   return MCDisassembler::Success;
213571928e68SAkira Hatanaka }
213671928e68SAkira Hatanaka 
21373c8869dcSZoran Jovanovic static DecodeStatus DecodeBranchTarget21(MCInst &Inst,
21383c8869dcSZoran Jovanovic                                          unsigned Offset,
21393c8869dcSZoran Jovanovic                                          uint64_t Address,
21403c8869dcSZoran Jovanovic                                          const void *Decoder) {
2141672c710dSSagar Thakur   int32_t BranchOffset = SignExtend32<21>(Offset) * 4 + 4;
21423c8869dcSZoran Jovanovic 
2143e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(BranchOffset));
21443c8869dcSZoran Jovanovic   return MCDisassembler::Success;
21453c8869dcSZoran Jovanovic }
21463c8869dcSZoran Jovanovic 
214784e4d59eSZoran Jovanovic static DecodeStatus DecodeBranchTarget21MM(MCInst &Inst,
214884e4d59eSZoran Jovanovic                                            unsigned Offset,
214984e4d59eSZoran Jovanovic                                            uint64_t Address,
215084e4d59eSZoran Jovanovic                                            const void *Decoder) {
2151f0ed16eaSHrvoje Varga   int32_t BranchOffset = SignExtend32<21>(Offset) * 4 + 4;
215284e4d59eSZoran Jovanovic 
215384e4d59eSZoran Jovanovic   Inst.addOperand(MCOperand::createImm(BranchOffset));
215484e4d59eSZoran Jovanovic   return MCDisassembler::Success;
215584e4d59eSZoran Jovanovic }
215684e4d59eSZoran Jovanovic 
21573c8869dcSZoran Jovanovic static DecodeStatus DecodeBranchTarget26(MCInst &Inst,
21583c8869dcSZoran Jovanovic                                          unsigned Offset,
21593c8869dcSZoran Jovanovic                                          uint64_t Address,
21603c8869dcSZoran Jovanovic                                          const void *Decoder) {
2161672c710dSSagar Thakur   int32_t BranchOffset = SignExtend32<26>(Offset) * 4 + 4;
21623c8869dcSZoran Jovanovic 
2163e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(BranchOffset));
21643c8869dcSZoran Jovanovic   return MCDisassembler::Success;
21653c8869dcSZoran Jovanovic }
21663c8869dcSZoran Jovanovic 
21679761e96bSJozef Kolek static DecodeStatus DecodeBranchTarget7MM(MCInst &Inst,
21689761e96bSJozef Kolek                                           unsigned Offset,
21699761e96bSJozef Kolek                                           uint64_t Address,
21709761e96bSJozef Kolek                                           const void *Decoder) {
21719761e96bSJozef Kolek   int32_t BranchOffset = SignExtend32<7>(Offset) << 1;
2172e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(BranchOffset));
21739761e96bSJozef Kolek   return MCDisassembler::Success;
21749761e96bSJozef Kolek }
21759761e96bSJozef Kolek 
21765cfebddeSJozef Kolek static DecodeStatus DecodeBranchTarget10MM(MCInst &Inst,
21775cfebddeSJozef Kolek                                            unsigned Offset,
21785cfebddeSJozef Kolek                                            uint64_t Address,
21795cfebddeSJozef Kolek                                            const void *Decoder) {
21805cfebddeSJozef Kolek   int32_t BranchOffset = SignExtend32<10>(Offset) << 1;
2181e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(BranchOffset));
21825cfebddeSJozef Kolek   return MCDisassembler::Success;
21835cfebddeSJozef Kolek }
21845cfebddeSJozef Kolek 
21858a80aa76SZoran Jovanovic static DecodeStatus DecodeBranchTargetMM(MCInst &Inst,
21868a80aa76SZoran Jovanovic                                          unsigned Offset,
21878a80aa76SZoran Jovanovic                                          uint64_t Address,
21888a80aa76SZoran Jovanovic                                          const void *Decoder) {
2189f0ed16eaSHrvoje Varga   int32_t BranchOffset = SignExtend32<16>(Offset) * 2 + 4;
2190e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(BranchOffset));
21918a80aa76SZoran Jovanovic   return MCDisassembler::Success;
21928a80aa76SZoran Jovanovic }
21938a80aa76SZoran Jovanovic 
2194a887b361SZoran Jovanovic static DecodeStatus DecodeBranchTarget26MM(MCInst &Inst,
2195a887b361SZoran Jovanovic   unsigned Offset,
2196a887b361SZoran Jovanovic   uint64_t Address,
2197a887b361SZoran Jovanovic   const void *Decoder) {
2198a887b361SZoran Jovanovic   int32_t BranchOffset = SignExtend32<26>(Offset) << 1;
2199a887b361SZoran Jovanovic 
2200a887b361SZoran Jovanovic   Inst.addOperand(MCOperand::createImm(BranchOffset));
2201a887b361SZoran Jovanovic   return MCDisassembler::Success;
2202a887b361SZoran Jovanovic }
2203a887b361SZoran Jovanovic 
2204507e084aSZoran Jovanovic static DecodeStatus DecodeJumpTargetMM(MCInst &Inst,
2205507e084aSZoran Jovanovic                                        unsigned Insn,
2206507e084aSZoran Jovanovic                                        uint64_t Address,
2207507e084aSZoran Jovanovic                                        const void *Decoder) {
2208507e084aSZoran Jovanovic   unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 1;
2209e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(JumpOffset));
2210507e084aSZoran Jovanovic   return MCDisassembler::Success;
2211507e084aSZoran Jovanovic }
221271928e68SAkira Hatanaka 
2213aa2b9278SJozef Kolek static DecodeStatus DecodeAddiur2Simm7(MCInst &Inst,
2214aa2b9278SJozef Kolek                                        unsigned Value,
2215aa2b9278SJozef Kolek                                        uint64_t Address,
2216aa2b9278SJozef Kolek                                        const void *Decoder) {
2217aa2b9278SJozef Kolek   if (Value == 0)
2218e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(1));
2219aa2b9278SJozef Kolek   else if (Value == 0x7)
2220e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(-1));
2221aa2b9278SJozef Kolek   else
2222e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(Value << 2));
2223aa2b9278SJozef Kolek   return MCDisassembler::Success;
2224aa2b9278SJozef Kolek }
2225aa2b9278SJozef Kolek 
222697297770SDaniel Sanders static DecodeStatus DecodeLi16Imm(MCInst &Inst,
2227aa2b9278SJozef Kolek                                   unsigned Value,
2228aa2b9278SJozef Kolek                                   uint64_t Address,
2229aa2b9278SJozef Kolek                                   const void *Decoder) {
2230aa2b9278SJozef Kolek   if (Value == 0x7F)
2231e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(-1));
2232aa2b9278SJozef Kolek   else
2233e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(Value));
2234aa2b9278SJozef Kolek   return MCDisassembler::Success;
2235aa2b9278SJozef Kolek }
2236aa2b9278SJozef Kolek 
22376b28f09dSZoran Jovanovic static DecodeStatus DecodePOOL16BEncodedField(MCInst &Inst,
22386b28f09dSZoran Jovanovic                                               unsigned Value,
22396b28f09dSZoran Jovanovic                                               uint64_t Address,
22406b28f09dSZoran Jovanovic                                               const void *Decoder) {
22416b28f09dSZoran Jovanovic   Inst.addOperand(MCOperand::createImm(Value == 0x0 ? 8 : Value));
22426b28f09dSZoran Jovanovic   return MCDisassembler::Success;
22436b28f09dSZoran Jovanovic }
22446b28f09dSZoran Jovanovic 
224519b7f76aSDaniel Sanders template <unsigned Bits, int Offset, int Scale>
224619b7f76aSDaniel Sanders static DecodeStatus DecodeUImmWithOffsetAndScale(MCInst &Inst, unsigned Value,
2247779c5937SMatheus Almeida                                                  uint64_t Address,
2248779c5937SMatheus Almeida                                                  const void *Decoder) {
2249ea4f653dSDaniel Sanders   Value &= ((1 << Bits) - 1);
225019b7f76aSDaniel Sanders   Value *= Scale;
2251ea4f653dSDaniel Sanders   Inst.addOperand(MCOperand::createImm(Value + Offset));
2252779c5937SMatheus Almeida   return MCDisassembler::Success;
2253779c5937SMatheus Almeida }
2254779c5937SMatheus Almeida 
225597297770SDaniel Sanders template <unsigned Bits, int Offset, int ScaleBy>
225697297770SDaniel Sanders static DecodeStatus DecodeSImmWithOffsetAndScale(MCInst &Inst, unsigned Value,
225778e89020SDaniel Sanders                                                  uint64_t Address,
225878e89020SDaniel Sanders                                                  const void *Decoder) {
225997297770SDaniel Sanders   int32_t Imm = SignExtend32<Bits>(Value) * ScaleBy;
226078e89020SDaniel Sanders   Inst.addOperand(MCOperand::createImm(Imm + Offset));
226178e89020SDaniel Sanders   return MCDisassembler::Success;
226278e89020SDaniel Sanders }
226378e89020SDaniel Sanders 
226471928e68SAkira Hatanaka static DecodeStatus DecodeInsSize(MCInst &Inst,
226571928e68SAkira Hatanaka                                   unsigned Insn,
226671928e68SAkira Hatanaka                                   uint64_t Address,
226771928e68SAkira Hatanaka                                   const void *Decoder) {
226871928e68SAkira Hatanaka   // First we need to grab the pos(lsb) from MCInst.
226971928e68SAkira Hatanaka   int Pos = Inst.getOperand(2).getImm();
227071928e68SAkira Hatanaka   int Size = (int) Insn - Pos + 1;
2271e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(SignExtend32<16>(Size)));
227271928e68SAkira Hatanaka   return MCDisassembler::Success;
227371928e68SAkira Hatanaka }
227471928e68SAkira Hatanaka 
2275b59e1a41SDaniel Sanders static DecodeStatus DecodeSimm19Lsl2(MCInst &Inst, unsigned Insn,
2276b59e1a41SDaniel Sanders                                      uint64_t Address, const void *Decoder) {
2277e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(SignExtend32<19>(Insn) * 4));
2278b59e1a41SDaniel Sanders   return MCDisassembler::Success;
2279b59e1a41SDaniel Sanders }
22802855142aSZoran Jovanovic 
22812855142aSZoran Jovanovic static DecodeStatus DecodeSimm18Lsl3(MCInst &Inst, unsigned Insn,
22822855142aSZoran Jovanovic                                      uint64_t Address, const void *Decoder) {
2283e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(SignExtend32<18>(Insn) * 8));
22842855142aSZoran Jovanovic   return MCDisassembler::Success;
22852855142aSZoran Jovanovic }
2286a4c4b5fcSZoran Jovanovic 
2287b682ddf3SVladimir Medic static DecodeStatus DecodeSimm9SP(MCInst &Inst, unsigned Insn,
2288b682ddf3SVladimir Medic                                   uint64_t Address, const void *Decoder) {
2289b682ddf3SVladimir Medic   int32_t DecodedValue;
2290b682ddf3SVladimir Medic   switch (Insn) {
2291b682ddf3SVladimir Medic   case 0: DecodedValue = 256; break;
2292b682ddf3SVladimir Medic   case 1: DecodedValue = 257; break;
2293b682ddf3SVladimir Medic   case 510: DecodedValue = -258; break;
2294b682ddf3SVladimir Medic   case 511: DecodedValue = -257; break;
2295b682ddf3SVladimir Medic   default: DecodedValue = SignExtend32<9>(Insn); break;
2296b682ddf3SVladimir Medic   }
2297e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(DecodedValue * 4));
2298b682ddf3SVladimir Medic   return MCDisassembler::Success;
2299b682ddf3SVladimir Medic }
2300b682ddf3SVladimir Medic 
2301b682ddf3SVladimir Medic static DecodeStatus DecodeANDI16Imm(MCInst &Inst, unsigned Insn,
2302b682ddf3SVladimir Medic                                     uint64_t Address, const void *Decoder) {
2303b682ddf3SVladimir Medic   // Insn must be >= 0, since it is unsigned that condition is always true.
2304b682ddf3SVladimir Medic   assert(Insn < 16);
2305b682ddf3SVladimir Medic   int32_t DecodedValues[] = {128, 1, 2, 3, 4, 7, 8, 15, 16, 31, 32, 63, 64,
2306b682ddf3SVladimir Medic                              255, 32768, 65535};
2307e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(DecodedValues[Insn]));
2308b682ddf3SVladimir Medic   return MCDisassembler::Success;
2309b682ddf3SVladimir Medic }
2310b682ddf3SVladimir Medic 
2311a4c4b5fcSZoran Jovanovic static DecodeStatus DecodeRegListOperand(MCInst &Inst,
2312a4c4b5fcSZoran Jovanovic                                          unsigned Insn,
2313a4c4b5fcSZoran Jovanovic                                          uint64_t Address,
2314a4c4b5fcSZoran Jovanovic                                          const void *Decoder) {
2315a4c4b5fcSZoran Jovanovic   unsigned Regs[] = {Mips::S0, Mips::S1, Mips::S2, Mips::S3, Mips::S4, Mips::S5,
2316dc4b8c27SZoran Jovanovic                      Mips::S6, Mips::S7, Mips::FP};
2317a4c4b5fcSZoran Jovanovic   unsigned RegNum;
2318a4c4b5fcSZoran Jovanovic 
2319a4c4b5fcSZoran Jovanovic   unsigned RegLst = fieldFromInstruction(Insn, 21, 5);
2320df19a5e6SDaniel Sanders 
2321a4c4b5fcSZoran Jovanovic   // Empty register lists are not allowed.
2322a4c4b5fcSZoran Jovanovic   if (RegLst == 0)
2323a4c4b5fcSZoran Jovanovic     return MCDisassembler::Fail;
2324a4c4b5fcSZoran Jovanovic 
2325a4c4b5fcSZoran Jovanovic   RegNum = RegLst & 0xf;
2326df19a5e6SDaniel Sanders 
2327df19a5e6SDaniel Sanders   // RegLst values 10-15, and 26-31 are reserved.
2328df19a5e6SDaniel Sanders   if (RegNum > 9)
2329df19a5e6SDaniel Sanders     return MCDisassembler::Fail;
2330df19a5e6SDaniel Sanders 
2331a4c4b5fcSZoran Jovanovic   for (unsigned i = 0; i < RegNum; i++)
2332e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Regs[i]));
2333a4c4b5fcSZoran Jovanovic 
2334a4c4b5fcSZoran Jovanovic   if (RegLst & 0x10)
2335e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::RA));
2336a4c4b5fcSZoran Jovanovic 
2337a4c4b5fcSZoran Jovanovic   return MCDisassembler::Success;
2338a4c4b5fcSZoran Jovanovic }
2339f9a02500SZoran Jovanovic 
2340f9a02500SZoran Jovanovic static DecodeStatus DecodeRegListOperand16(MCInst &Inst, unsigned Insn,
2341f9a02500SZoran Jovanovic                                            uint64_t Address,
2342f9a02500SZoran Jovanovic                                            const void *Decoder) {
2343f9a02500SZoran Jovanovic   unsigned Regs[] = {Mips::S0, Mips::S1, Mips::S2, Mips::S3};
2344797c2aecSZlatko Buljan   unsigned RegLst;
2345797c2aecSZlatko Buljan   switch(Inst.getOpcode()) {
2346797c2aecSZlatko Buljan   default:
2347797c2aecSZlatko Buljan     RegLst = fieldFromInstruction(Insn, 4, 2);
2348797c2aecSZlatko Buljan     break;
2349797c2aecSZlatko Buljan   case Mips::LWM16_MMR6:
2350797c2aecSZlatko Buljan   case Mips::SWM16_MMR6:
2351797c2aecSZlatko Buljan     RegLst = fieldFromInstruction(Insn, 8, 2);
2352797c2aecSZlatko Buljan     break;
2353797c2aecSZlatko Buljan   }
2354d68d424aSJozef Kolek   unsigned RegNum = RegLst & 0x3;
2355f9a02500SZoran Jovanovic 
2356d68d424aSJozef Kolek   for (unsigned i = 0; i <= RegNum; i++)
2357e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Regs[i]));
2358f9a02500SZoran Jovanovic 
2359e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Mips::RA));
2360f9a02500SZoran Jovanovic 
2361f9a02500SZoran Jovanovic   return MCDisassembler::Success;
2362f9a02500SZoran Jovanovic }
23632c6d7320SJozef Kolek 
236441688679SZoran Jovanovic static DecodeStatus DecodeMovePRegPair(MCInst &Inst, unsigned Insn,
236541688679SZoran Jovanovic                                        uint64_t Address, const void *Decoder) {
236641688679SZoran Jovanovic 
236741688679SZoran Jovanovic   unsigned RegPair = fieldFromInstruction(Insn, 7, 3);
236841688679SZoran Jovanovic 
236941688679SZoran Jovanovic   switch (RegPair) {
237041688679SZoran Jovanovic   default:
237141688679SZoran Jovanovic     return MCDisassembler::Fail;
237241688679SZoran Jovanovic   case 0:
2373e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A1));
2374e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A2));
237541688679SZoran Jovanovic     break;
237641688679SZoran Jovanovic   case 1:
2377e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A1));
2378e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A3));
237941688679SZoran Jovanovic     break;
238041688679SZoran Jovanovic   case 2:
2381e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A2));
2382e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A3));
238341688679SZoran Jovanovic     break;
238441688679SZoran Jovanovic   case 3:
2385e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A0));
2386e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::S5));
238741688679SZoran Jovanovic     break;
238841688679SZoran Jovanovic   case 4:
2389e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A0));
2390e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::S6));
239141688679SZoran Jovanovic     break;
239241688679SZoran Jovanovic   case 5:
2393e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A0));
2394e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A1));
239541688679SZoran Jovanovic     break;
239641688679SZoran Jovanovic   case 6:
2397e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A0));
2398e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A2));
239941688679SZoran Jovanovic     break;
240041688679SZoran Jovanovic   case 7:
2401e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A0));
2402e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A3));
240341688679SZoran Jovanovic     break;
240441688679SZoran Jovanovic   }
240541688679SZoran Jovanovic 
240641688679SZoran Jovanovic   return MCDisassembler::Success;
240741688679SZoran Jovanovic }
240841688679SZoran Jovanovic 
24092c6d7320SJozef Kolek static DecodeStatus DecodeSimm23Lsl2(MCInst &Inst, unsigned Insn,
24102c6d7320SJozef Kolek                                      uint64_t Address, const void *Decoder) {
24116499b5f0SJustin Bogner   Inst.addOperand(MCOperand::createImm(SignExtend32<25>(Insn << 2)));
24122c6d7320SJozef Kolek   return MCDisassembler::Success;
24132c6d7320SJozef Kolek }
2414fdbd0a37SZoran Jovanovic 
2415fdbd0a37SZoran Jovanovic template <typename InsnType>
2416fdbd0a37SZoran Jovanovic static DecodeStatus DecodeBgtzGroupBranchMMR6(MCInst &MI, InsnType insn,
2417fdbd0a37SZoran Jovanovic   uint64_t Address,
2418fdbd0a37SZoran Jovanovic   const void *Decoder) {
2419fdbd0a37SZoran Jovanovic   // We have:
2420fdbd0a37SZoran Jovanovic   //    0b000111 ttttt sssss iiiiiiiiiiiiiiii
2421fdbd0a37SZoran Jovanovic   //      Invalid      if rt == 0
2422fdbd0a37SZoran Jovanovic   //      BGTZALC_MMR6 if rs == 0 && rt != 0
2423fdbd0a37SZoran Jovanovic   //      BLTZALC_MMR6 if rs != 0 && rs == rt
2424fdbd0a37SZoran Jovanovic   //      BLTUC_MMR6   if rs != 0 && rs != rt
2425fdbd0a37SZoran Jovanovic 
2426fdbd0a37SZoran Jovanovic   InsnType Rt = fieldFromInstruction(insn, 21, 5);
2427fdbd0a37SZoran Jovanovic   InsnType Rs = fieldFromInstruction(insn, 16, 5);
2428f0ed16eaSHrvoje Varga   InsnType Imm = 0;
2429fdbd0a37SZoran Jovanovic   bool HasRs = false;
2430fdbd0a37SZoran Jovanovic   bool HasRt = false;
2431fdbd0a37SZoran Jovanovic 
2432fdbd0a37SZoran Jovanovic   if (Rt == 0)
2433fdbd0a37SZoran Jovanovic     return MCDisassembler::Fail;
2434fdbd0a37SZoran Jovanovic   else if (Rs == 0) {
2435fdbd0a37SZoran Jovanovic     MI.setOpcode(Mips::BGTZALC_MMR6);
2436fdbd0a37SZoran Jovanovic     HasRt = true;
2437f0ed16eaSHrvoje Varga     Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
2438fdbd0a37SZoran Jovanovic   }
2439fdbd0a37SZoran Jovanovic   else if (Rs == Rt) {
2440fdbd0a37SZoran Jovanovic     MI.setOpcode(Mips::BLTZALC_MMR6);
2441fdbd0a37SZoran Jovanovic     HasRs = true;
2442f0ed16eaSHrvoje Varga     Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
2443fdbd0a37SZoran Jovanovic   }
2444fdbd0a37SZoran Jovanovic   else {
2445fdbd0a37SZoran Jovanovic     MI.setOpcode(Mips::BLTUC_MMR6);
2446fdbd0a37SZoran Jovanovic     HasRs = true;
2447fdbd0a37SZoran Jovanovic     HasRt = true;
2448f0ed16eaSHrvoje Varga     Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
2449fdbd0a37SZoran Jovanovic   }
2450fdbd0a37SZoran Jovanovic 
2451fdbd0a37SZoran Jovanovic   if (HasRs)
2452fdbd0a37SZoran Jovanovic     MI.addOperand(
2453fdbd0a37SZoran Jovanovic     MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rs)));
2454fdbd0a37SZoran Jovanovic 
2455fdbd0a37SZoran Jovanovic   if (HasRt)
2456fdbd0a37SZoran Jovanovic     MI.addOperand(
2457fdbd0a37SZoran Jovanovic     MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rt)));
2458fdbd0a37SZoran Jovanovic 
2459fdbd0a37SZoran Jovanovic   MI.addOperand(MCOperand::createImm(Imm));
2460fdbd0a37SZoran Jovanovic 
2461fdbd0a37SZoran Jovanovic   return MCDisassembler::Success;
2462fdbd0a37SZoran Jovanovic }
2463fdbd0a37SZoran Jovanovic 
2464fdbd0a37SZoran Jovanovic template <typename InsnType>
2465fdbd0a37SZoran Jovanovic static DecodeStatus DecodeBlezGroupBranchMMR6(MCInst &MI, InsnType insn,
2466fdbd0a37SZoran Jovanovic   uint64_t Address,
2467fdbd0a37SZoran Jovanovic   const void *Decoder) {
2468fdbd0a37SZoran Jovanovic   // We have:
2469fdbd0a37SZoran Jovanovic   //    0b000110 ttttt sssss iiiiiiiiiiiiiiii
2470f0ed16eaSHrvoje Varga   //      Invalid        if rt == 0
2471fdbd0a37SZoran Jovanovic   //      BLEZALC_MMR6   if rs == 0  && rt != 0
2472fdbd0a37SZoran Jovanovic   //      BGEZALC_MMR6   if rs == rt && rt != 0
2473fdbd0a37SZoran Jovanovic   //      BGEUC_MMR6     if rs != rt && rs != 0  && rt != 0
2474fdbd0a37SZoran Jovanovic 
2475fdbd0a37SZoran Jovanovic   InsnType Rt = fieldFromInstruction(insn, 21, 5);
2476fdbd0a37SZoran Jovanovic   InsnType Rs = fieldFromInstruction(insn, 16, 5);
2477f0ed16eaSHrvoje Varga   InsnType Imm = 0;
2478fdbd0a37SZoran Jovanovic   bool HasRs = false;
2479fdbd0a37SZoran Jovanovic 
2480fdbd0a37SZoran Jovanovic   if (Rt == 0)
2481fdbd0a37SZoran Jovanovic     return MCDisassembler::Fail;
2482f0ed16eaSHrvoje Varga   else if (Rs == 0) {
2483fdbd0a37SZoran Jovanovic     MI.setOpcode(Mips::BLEZALC_MMR6);
2484f0ed16eaSHrvoje Varga     Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
2485f0ed16eaSHrvoje Varga   }
2486f0ed16eaSHrvoje Varga   else if (Rs == Rt) {
2487fdbd0a37SZoran Jovanovic     MI.setOpcode(Mips::BGEZALC_MMR6);
2488f0ed16eaSHrvoje Varga     Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
2489f0ed16eaSHrvoje Varga   }
2490fdbd0a37SZoran Jovanovic   else {
2491fdbd0a37SZoran Jovanovic     HasRs = true;
2492fdbd0a37SZoran Jovanovic     MI.setOpcode(Mips::BGEUC_MMR6);
2493f0ed16eaSHrvoje Varga     Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
2494fdbd0a37SZoran Jovanovic   }
2495fdbd0a37SZoran Jovanovic 
2496fdbd0a37SZoran Jovanovic   if (HasRs)
2497fdbd0a37SZoran Jovanovic     MI.addOperand(
2498fdbd0a37SZoran Jovanovic     MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rs)));
2499fdbd0a37SZoran Jovanovic   MI.addOperand(
2500fdbd0a37SZoran Jovanovic     MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rt)));
2501fdbd0a37SZoran Jovanovic 
2502fdbd0a37SZoran Jovanovic   MI.addOperand(MCOperand::createImm(Imm));
2503fdbd0a37SZoran Jovanovic 
2504fdbd0a37SZoran Jovanovic   return MCDisassembler::Success;
2505fdbd0a37SZoran Jovanovic }
2506