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>
4425c582b2fSDaniel Sanders static DecodeStatus
4435c582b2fSDaniel Sanders DecodeAddiGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
4445c582b2fSDaniel Sanders                       const void *Decoder);
4455c582b2fSDaniel Sanders 
4465c582b2fSDaniel Sanders template <typename InsnType>
4475c582b2fSDaniel Sanders static DecodeStatus
448c962c493SHrvoje Varga DecodePOP35GroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address,
449c962c493SHrvoje Varga                            const void *Decoder);
450c962c493SHrvoje Varga 
451c962c493SHrvoje Varga template <typename InsnType>
452c962c493SHrvoje Varga static DecodeStatus
4535c582b2fSDaniel Sanders DecodeDaddiGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
4545c582b2fSDaniel Sanders                        const void *Decoder);
4555c582b2fSDaniel Sanders 
4565c582b2fSDaniel Sanders template <typename InsnType>
4575c582b2fSDaniel Sanders static DecodeStatus
458c962c493SHrvoje Varga DecodePOP37GroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address,
459c962c493SHrvoje Varga                            const void *Decoder);
460c962c493SHrvoje Varga 
461c962c493SHrvoje Varga template <typename InsnType>
462c962c493SHrvoje Varga static DecodeStatus
463*f0ed16eaSHrvoje Varga DecodePOP65GroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address,
464*f0ed16eaSHrvoje Varga                            const void *Decoder);
465*f0ed16eaSHrvoje Varga 
466*f0ed16eaSHrvoje Varga template <typename InsnType>
467*f0ed16eaSHrvoje Varga static DecodeStatus
468*f0ed16eaSHrvoje Varga DecodePOP75GroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address,
469*f0ed16eaSHrvoje Varga                            const void *Decoder);
470*f0ed16eaSHrvoje Varga 
471*f0ed16eaSHrvoje Varga template <typename InsnType>
472*f0ed16eaSHrvoje Varga static DecodeStatus
4735c582b2fSDaniel Sanders DecodeBlezlGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
4745c582b2fSDaniel Sanders                        const void *Decoder);
4755c582b2fSDaniel Sanders 
4765c582b2fSDaniel Sanders template <typename InsnType>
4775c582b2fSDaniel Sanders static DecodeStatus
4785c582b2fSDaniel Sanders DecodeBgtzlGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
4795c582b2fSDaniel Sanders                        const void *Decoder);
4805c582b2fSDaniel Sanders 
4815c582b2fSDaniel Sanders template <typename InsnType>
4825c582b2fSDaniel Sanders static DecodeStatus
4835c582b2fSDaniel Sanders DecodeBgtzGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
4845c582b2fSDaniel Sanders                       const void *Decoder);
4855c582b2fSDaniel Sanders 
48628a0ca07SZoran Jovanovic template <typename InsnType>
48728a0ca07SZoran Jovanovic static DecodeStatus
48828a0ca07SZoran Jovanovic DecodeBlezGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
48928a0ca07SZoran Jovanovic                        const void *Decoder);
49028a0ca07SZoran Jovanovic 
491fdbd0a37SZoran Jovanovic template <typename InsnType>
492fdbd0a37SZoran Jovanovic static DecodeStatus
493fdbd0a37SZoran Jovanovic DecodeBgtzGroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address,
494fdbd0a37SZoran Jovanovic                           const void *Decoder);
495fdbd0a37SZoran Jovanovic 
496fdbd0a37SZoran Jovanovic template <typename InsnType>
497fdbd0a37SZoran Jovanovic static DecodeStatus
498fdbd0a37SZoran Jovanovic DecodeBlezGroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address,
499fdbd0a37SZoran Jovanovic                           const void *Decoder);
500fdbd0a37SZoran Jovanovic 
501a4c4b5fcSZoran Jovanovic static DecodeStatus DecodeRegListOperand(MCInst &Inst, unsigned Insn,
502a4c4b5fcSZoran Jovanovic                                          uint64_t Address,
503a4c4b5fcSZoran Jovanovic                                          const void *Decoder);
504a4c4b5fcSZoran Jovanovic 
505f9a02500SZoran Jovanovic static DecodeStatus DecodeRegListOperand16(MCInst &Inst, unsigned Insn,
506f9a02500SZoran Jovanovic                                            uint64_t Address,
507f9a02500SZoran Jovanovic                                            const void *Decoder);
508f9a02500SZoran Jovanovic 
50941688679SZoran Jovanovic static DecodeStatus DecodeMovePRegPair(MCInst &Inst, unsigned Insn,
51041688679SZoran Jovanovic                                        uint64_t Address,
51141688679SZoran Jovanovic                                        const void *Decoder);
51241688679SZoran Jovanovic 
51371928e68SAkira Hatanaka namespace llvm {
51471928e68SAkira Hatanaka extern Target TheMipselTarget, TheMipsTarget, TheMips64Target,
51571928e68SAkira Hatanaka               TheMips64elTarget;
51671928e68SAkira Hatanaka }
51771928e68SAkira Hatanaka 
51871928e68SAkira Hatanaka static MCDisassembler *createMipsDisassembler(
51971928e68SAkira Hatanaka                        const Target &T,
520a1bc0f56SLang Hames                        const MCSubtargetInfo &STI,
521a1bc0f56SLang Hames                        MCContext &Ctx) {
522a1bc0f56SLang Hames   return new MipsDisassembler(STI, Ctx, true);
52371928e68SAkira Hatanaka }
52471928e68SAkira Hatanaka 
52571928e68SAkira Hatanaka static MCDisassembler *createMipselDisassembler(
52671928e68SAkira Hatanaka                        const Target &T,
527a1bc0f56SLang Hames                        const MCSubtargetInfo &STI,
528a1bc0f56SLang Hames                        MCContext &Ctx) {
529a1bc0f56SLang Hames   return new MipsDisassembler(STI, Ctx, false);
53071928e68SAkira Hatanaka }
53171928e68SAkira Hatanaka 
53271928e68SAkira Hatanaka extern "C" void LLVMInitializeMipsDisassembler() {
53371928e68SAkira Hatanaka   // Register the disassembler.
53471928e68SAkira Hatanaka   TargetRegistry::RegisterMCDisassembler(TheMipsTarget,
53571928e68SAkira Hatanaka                                          createMipsDisassembler);
53671928e68SAkira Hatanaka   TargetRegistry::RegisterMCDisassembler(TheMipselTarget,
53771928e68SAkira Hatanaka                                          createMipselDisassembler);
53871928e68SAkira Hatanaka   TargetRegistry::RegisterMCDisassembler(TheMips64Target,
539a19216c8SDaniel Sanders                                          createMipsDisassembler);
54071928e68SAkira Hatanaka   TargetRegistry::RegisterMCDisassembler(TheMips64elTarget,
541a19216c8SDaniel Sanders                                          createMipselDisassembler);
54271928e68SAkira Hatanaka }
54371928e68SAkira Hatanaka 
54471928e68SAkira Hatanaka #include "MipsGenDisassemblerTables.inc"
54571928e68SAkira Hatanaka 
5465c582b2fSDaniel Sanders static unsigned getReg(const void *D, unsigned RC, unsigned RegNo) {
547a19216c8SDaniel Sanders   const MipsDisassembler *Dis = static_cast<const MipsDisassembler*>(D);
5485c582b2fSDaniel Sanders   const MCRegisterInfo *RegInfo = Dis->getContext().getRegisterInfo();
5495c582b2fSDaniel Sanders   return *(RegInfo->getRegClass(RC).begin() + RegNo);
5505c582b2fSDaniel Sanders }
5515c582b2fSDaniel Sanders 
552b50ccf8eSDaniel Sanders template <typename InsnType>
553b50ccf8eSDaniel Sanders static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address,
554b50ccf8eSDaniel Sanders                                    const void *Decoder) {
555b50ccf8eSDaniel Sanders   typedef DecodeStatus (*DecodeFN)(MCInst &, unsigned, uint64_t, const void *);
556b50ccf8eSDaniel Sanders   // The size of the n field depends on the element size
557b50ccf8eSDaniel Sanders   // The register class also depends on this.
558b50ccf8eSDaniel Sanders   InsnType tmp = fieldFromInstruction(insn, 17, 5);
559b50ccf8eSDaniel Sanders   unsigned NSize = 0;
560b50ccf8eSDaniel Sanders   DecodeFN RegDecoder = nullptr;
561b50ccf8eSDaniel Sanders   if ((tmp & 0x18) == 0x00) { // INSVE_B
562b50ccf8eSDaniel Sanders     NSize = 4;
563b50ccf8eSDaniel Sanders     RegDecoder = DecodeMSA128BRegisterClass;
564b50ccf8eSDaniel Sanders   } else if ((tmp & 0x1c) == 0x10) { // INSVE_H
565b50ccf8eSDaniel Sanders     NSize = 3;
566b50ccf8eSDaniel Sanders     RegDecoder = DecodeMSA128HRegisterClass;
567b50ccf8eSDaniel Sanders   } else if ((tmp & 0x1e) == 0x18) { // INSVE_W
568b50ccf8eSDaniel Sanders     NSize = 2;
569b50ccf8eSDaniel Sanders     RegDecoder = DecodeMSA128WRegisterClass;
570b50ccf8eSDaniel Sanders   } else if ((tmp & 0x1f) == 0x1c) { // INSVE_D
571b50ccf8eSDaniel Sanders     NSize = 1;
572b50ccf8eSDaniel Sanders     RegDecoder = DecodeMSA128DRegisterClass;
573b50ccf8eSDaniel Sanders   } else
574b50ccf8eSDaniel Sanders     llvm_unreachable("Invalid encoding");
575b50ccf8eSDaniel Sanders 
576b50ccf8eSDaniel Sanders   assert(NSize != 0 && RegDecoder != nullptr);
577b50ccf8eSDaniel Sanders 
578b50ccf8eSDaniel Sanders   // $wd
579b50ccf8eSDaniel Sanders   tmp = fieldFromInstruction(insn, 6, 5);
580b50ccf8eSDaniel Sanders   if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
581b50ccf8eSDaniel Sanders     return MCDisassembler::Fail;
582b50ccf8eSDaniel Sanders   // $wd_in
583b50ccf8eSDaniel Sanders   if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
584b50ccf8eSDaniel Sanders     return MCDisassembler::Fail;
585b50ccf8eSDaniel Sanders   // $n
586b50ccf8eSDaniel Sanders   tmp = fieldFromInstruction(insn, 16, NSize);
587e9119e41SJim Grosbach   MI.addOperand(MCOperand::createImm(tmp));
588b50ccf8eSDaniel Sanders   // $ws
589b50ccf8eSDaniel Sanders   tmp = fieldFromInstruction(insn, 11, 5);
590b50ccf8eSDaniel Sanders   if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
591b50ccf8eSDaniel Sanders     return MCDisassembler::Fail;
592b50ccf8eSDaniel Sanders   // $n2
593e9119e41SJim Grosbach   MI.addOperand(MCOperand::createImm(0));
594b50ccf8eSDaniel Sanders 
595b50ccf8eSDaniel Sanders   return MCDisassembler::Success;
596b50ccf8eSDaniel Sanders }
597b50ccf8eSDaniel Sanders 
5985c582b2fSDaniel Sanders template <typename InsnType>
5995c582b2fSDaniel Sanders static DecodeStatus DecodeAddiGroupBranch(MCInst &MI, InsnType insn,
6005c582b2fSDaniel Sanders                                           uint64_t Address,
6015c582b2fSDaniel Sanders                                           const void *Decoder) {
6025c582b2fSDaniel Sanders   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
6035c582b2fSDaniel Sanders   // (otherwise we would have matched the ADDI instruction from the earlier
6045c582b2fSDaniel Sanders   // ISA's instead).
6055c582b2fSDaniel Sanders   //
6065c582b2fSDaniel Sanders   // We have:
6075c582b2fSDaniel Sanders   //    0b001000 sssss ttttt iiiiiiiiiiiiiiii
6085c582b2fSDaniel Sanders   //      BOVC if rs >= rt
6095c582b2fSDaniel Sanders   //      BEQZALC if rs == 0 && rt != 0
6105c582b2fSDaniel Sanders   //      BEQC if rs < rt && rs != 0
6115c582b2fSDaniel Sanders 
6125c582b2fSDaniel Sanders   InsnType Rs = fieldFromInstruction(insn, 21, 5);
6135c582b2fSDaniel Sanders   InsnType Rt = fieldFromInstruction(insn, 16, 5);
614672c710dSSagar Thakur   int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
6155c582b2fSDaniel Sanders   bool HasRs = false;
6165c582b2fSDaniel Sanders 
6175c582b2fSDaniel Sanders   if (Rs >= Rt) {
6185c582b2fSDaniel Sanders     MI.setOpcode(Mips::BOVC);
6195c582b2fSDaniel Sanders     HasRs = true;
6205c582b2fSDaniel Sanders   } else if (Rs != 0 && Rs < Rt) {
6215c582b2fSDaniel Sanders     MI.setOpcode(Mips::BEQC);
6225c582b2fSDaniel Sanders     HasRs = true;
6235c582b2fSDaniel Sanders   } else
6245c582b2fSDaniel Sanders     MI.setOpcode(Mips::BEQZALC);
6255c582b2fSDaniel Sanders 
6265c582b2fSDaniel Sanders   if (HasRs)
627e9119e41SJim Grosbach     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
6285c582b2fSDaniel Sanders                                        Rs)));
6295c582b2fSDaniel Sanders 
630e9119e41SJim Grosbach   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
6315c582b2fSDaniel Sanders                                      Rt)));
632e9119e41SJim Grosbach   MI.addOperand(MCOperand::createImm(Imm));
6335c582b2fSDaniel Sanders 
6345c582b2fSDaniel Sanders   return MCDisassembler::Success;
6355c582b2fSDaniel Sanders }
6365c582b2fSDaniel Sanders 
6375c582b2fSDaniel Sanders template <typename InsnType>
638c962c493SHrvoje Varga static DecodeStatus DecodePOP35GroupBranchMMR6(MCInst &MI, InsnType insn,
639c962c493SHrvoje Varga                                                uint64_t Address,
640c962c493SHrvoje Varga                                                const void *Decoder) {
641c962c493SHrvoje Varga   InsnType Rt = fieldFromInstruction(insn, 21, 5);
642c962c493SHrvoje Varga   InsnType Rs = fieldFromInstruction(insn, 16, 5);
643*f0ed16eaSHrvoje Varga   int64_t Imm = 0;
644c962c493SHrvoje Varga 
645c962c493SHrvoje Varga   if (Rs >= Rt) {
646c962c493SHrvoje Varga     MI.setOpcode(Mips::BOVC_MMR6);
647c962c493SHrvoje Varga     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
648c962c493SHrvoje Varga                                        Rt)));
649c962c493SHrvoje Varga     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
650c962c493SHrvoje Varga                                        Rs)));
651*f0ed16eaSHrvoje Varga     Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
652c962c493SHrvoje Varga   } else if (Rs != 0 && Rs < Rt) {
653c962c493SHrvoje Varga     MI.setOpcode(Mips::BEQC_MMR6);
654c962c493SHrvoje Varga     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
655c962c493SHrvoje Varga                                        Rs)));
656c962c493SHrvoje Varga     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
657c962c493SHrvoje Varga                                        Rt)));
658*f0ed16eaSHrvoje Varga     Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
659c962c493SHrvoje Varga   } else {
660c962c493SHrvoje Varga     MI.setOpcode(Mips::BEQZALC_MMR6);
661c962c493SHrvoje Varga     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
662c962c493SHrvoje Varga                                        Rt)));
663*f0ed16eaSHrvoje Varga     Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
664c962c493SHrvoje Varga   }
665c962c493SHrvoje Varga 
666c962c493SHrvoje Varga   MI.addOperand(MCOperand::createImm(Imm));
667c962c493SHrvoje Varga 
668c962c493SHrvoje Varga   return MCDisassembler::Success;
669c962c493SHrvoje Varga }
670c962c493SHrvoje Varga 
671c962c493SHrvoje Varga template <typename InsnType>
6725c582b2fSDaniel Sanders static DecodeStatus DecodeDaddiGroupBranch(MCInst &MI, InsnType insn,
6735c582b2fSDaniel Sanders                                            uint64_t Address,
6745c582b2fSDaniel Sanders                                            const void *Decoder) {
6755c582b2fSDaniel Sanders   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
6765c582b2fSDaniel Sanders   // (otherwise we would have matched the ADDI instruction from the earlier
6775c582b2fSDaniel Sanders   // ISA's instead).
6785c582b2fSDaniel Sanders   //
6795c582b2fSDaniel Sanders   // We have:
6805c582b2fSDaniel Sanders   //    0b011000 sssss ttttt iiiiiiiiiiiiiiii
6815c582b2fSDaniel Sanders   //      BNVC if rs >= rt
6825c582b2fSDaniel Sanders   //      BNEZALC if rs == 0 && rt != 0
6835c582b2fSDaniel Sanders   //      BNEC if rs < rt && rs != 0
6845c582b2fSDaniel Sanders 
6855c582b2fSDaniel Sanders   InsnType Rs = fieldFromInstruction(insn, 21, 5);
6865c582b2fSDaniel Sanders   InsnType Rt = fieldFromInstruction(insn, 16, 5);
687672c710dSSagar Thakur   int64_t  Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
6885c582b2fSDaniel Sanders   bool HasRs = false;
6895c582b2fSDaniel Sanders 
6905c582b2fSDaniel Sanders   if (Rs >= Rt) {
6915c582b2fSDaniel Sanders     MI.setOpcode(Mips::BNVC);
6925c582b2fSDaniel Sanders     HasRs = true;
6935c582b2fSDaniel Sanders   } else if (Rs != 0 && Rs < Rt) {
6945c582b2fSDaniel Sanders     MI.setOpcode(Mips::BNEC);
6955c582b2fSDaniel Sanders     HasRs = true;
6965c582b2fSDaniel Sanders   } else
6975c582b2fSDaniel Sanders     MI.setOpcode(Mips::BNEZALC);
6985c582b2fSDaniel Sanders 
6995c582b2fSDaniel Sanders   if (HasRs)
700e9119e41SJim Grosbach     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
7015c582b2fSDaniel Sanders                                        Rs)));
7025c582b2fSDaniel Sanders 
703e9119e41SJim Grosbach   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
7045c582b2fSDaniel Sanders                                      Rt)));
705e9119e41SJim Grosbach   MI.addOperand(MCOperand::createImm(Imm));
7065c582b2fSDaniel Sanders 
7075c582b2fSDaniel Sanders   return MCDisassembler::Success;
7085c582b2fSDaniel Sanders }
7095c582b2fSDaniel Sanders 
7105c582b2fSDaniel Sanders template <typename InsnType>
711c962c493SHrvoje Varga static DecodeStatus DecodePOP37GroupBranchMMR6(MCInst &MI, InsnType insn,
712c962c493SHrvoje Varga                                                uint64_t Address,
713c962c493SHrvoje Varga                                                const void *Decoder) {
714c962c493SHrvoje Varga   InsnType Rt = fieldFromInstruction(insn, 21, 5);
715c962c493SHrvoje Varga   InsnType Rs = fieldFromInstruction(insn, 16, 5);
716*f0ed16eaSHrvoje Varga   int64_t Imm = 0;
717c962c493SHrvoje Varga 
718c962c493SHrvoje Varga   if (Rs >= Rt) {
719c962c493SHrvoje Varga     MI.setOpcode(Mips::BNVC_MMR6);
720c962c493SHrvoje Varga     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
721c962c493SHrvoje Varga                                        Rt)));
722c962c493SHrvoje Varga     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
723c962c493SHrvoje Varga                                        Rs)));
724*f0ed16eaSHrvoje Varga     Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
725c962c493SHrvoje Varga   } else if (Rs != 0 && Rs < Rt) {
726c962c493SHrvoje Varga     MI.setOpcode(Mips::BNEC_MMR6);
727c962c493SHrvoje Varga     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
728c962c493SHrvoje Varga                                        Rs)));
729c962c493SHrvoje Varga     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
730c962c493SHrvoje Varga                                        Rt)));
731*f0ed16eaSHrvoje Varga     Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
732c962c493SHrvoje Varga   } else {
733c962c493SHrvoje Varga     MI.setOpcode(Mips::BNEZALC_MMR6);
734c962c493SHrvoje Varga     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
735c962c493SHrvoje Varga                                        Rt)));
736*f0ed16eaSHrvoje Varga     Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
737c962c493SHrvoje Varga   }
738c962c493SHrvoje Varga 
739c962c493SHrvoje Varga   MI.addOperand(MCOperand::createImm(Imm));
740c962c493SHrvoje Varga 
741c962c493SHrvoje Varga   return MCDisassembler::Success;
742c962c493SHrvoje Varga }
743c962c493SHrvoje Varga 
744c962c493SHrvoje Varga template <typename InsnType>
745*f0ed16eaSHrvoje Varga static DecodeStatus DecodePOP65GroupBranchMMR6(MCInst &MI, InsnType insn,
746*f0ed16eaSHrvoje Varga                                                uint64_t Address,
747*f0ed16eaSHrvoje Varga                                                const void *Decoder) {
748*f0ed16eaSHrvoje Varga   // We have:
749*f0ed16eaSHrvoje Varga   //    0b110101 ttttt sssss iiiiiiiiiiiiiiii
750*f0ed16eaSHrvoje Varga   //      Invalid if rt == 0
751*f0ed16eaSHrvoje Varga   //      BGTZC_MMR6   if rs == 0  && rt != 0
752*f0ed16eaSHrvoje Varga   //      BLTZC_MMR6   if rs == rt && rt != 0
753*f0ed16eaSHrvoje Varga   //      BLTC_MMR6    if rs != rt && rs != 0  && rt != 0
754*f0ed16eaSHrvoje Varga 
755*f0ed16eaSHrvoje Varga   InsnType Rt = fieldFromInstruction(insn, 21, 5);
756*f0ed16eaSHrvoje Varga   InsnType Rs = fieldFromInstruction(insn, 16, 5);
757*f0ed16eaSHrvoje Varga   int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
758*f0ed16eaSHrvoje Varga   bool HasRs = false;
759*f0ed16eaSHrvoje Varga 
760*f0ed16eaSHrvoje Varga   if (Rt == 0)
761*f0ed16eaSHrvoje Varga     return MCDisassembler::Fail;
762*f0ed16eaSHrvoje Varga   else if (Rs == 0)
763*f0ed16eaSHrvoje Varga     MI.setOpcode(Mips::BGTZC_MMR6);
764*f0ed16eaSHrvoje Varga   else if (Rs == Rt)
765*f0ed16eaSHrvoje Varga     MI.setOpcode(Mips::BLTZC_MMR6);
766*f0ed16eaSHrvoje Varga   else {
767*f0ed16eaSHrvoje Varga     MI.setOpcode(Mips::BLTC_MMR6);
768*f0ed16eaSHrvoje Varga     HasRs = true;
769*f0ed16eaSHrvoje Varga   }
770*f0ed16eaSHrvoje Varga 
771*f0ed16eaSHrvoje Varga   if (HasRs)
772*f0ed16eaSHrvoje Varga     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
773*f0ed16eaSHrvoje Varga                                               Rs)));
774*f0ed16eaSHrvoje Varga 
775*f0ed16eaSHrvoje Varga   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
776*f0ed16eaSHrvoje Varga                                      Rt)));
777*f0ed16eaSHrvoje Varga 
778*f0ed16eaSHrvoje Varga   MI.addOperand(MCOperand::createImm(Imm));
779*f0ed16eaSHrvoje Varga 
780*f0ed16eaSHrvoje Varga   return MCDisassembler::Success;
781*f0ed16eaSHrvoje Varga }
782*f0ed16eaSHrvoje Varga 
783*f0ed16eaSHrvoje Varga template <typename InsnType>
784*f0ed16eaSHrvoje Varga static DecodeStatus DecodePOP75GroupBranchMMR6(MCInst &MI, InsnType insn,
785*f0ed16eaSHrvoje Varga                                                uint64_t Address,
786*f0ed16eaSHrvoje Varga                                                const void *Decoder) {
787*f0ed16eaSHrvoje Varga   // We have:
788*f0ed16eaSHrvoje Varga   //    0b111101 ttttt sssss iiiiiiiiiiiiiiii
789*f0ed16eaSHrvoje Varga   //      Invalid if rt == 0
790*f0ed16eaSHrvoje Varga   //      BLEZC_MMR6   if rs == 0  && rt != 0
791*f0ed16eaSHrvoje Varga   //      BGEZC_MMR6   if rs == rt && rt != 0
792*f0ed16eaSHrvoje Varga   //      BGEC_MMR6    if rs != rt && rs != 0  && rt != 0
793*f0ed16eaSHrvoje Varga 
794*f0ed16eaSHrvoje Varga   InsnType Rt = fieldFromInstruction(insn, 21, 5);
795*f0ed16eaSHrvoje Varga   InsnType Rs = fieldFromInstruction(insn, 16, 5);
796*f0ed16eaSHrvoje Varga   int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
797*f0ed16eaSHrvoje Varga   bool HasRs = false;
798*f0ed16eaSHrvoje Varga 
799*f0ed16eaSHrvoje Varga   if (Rt == 0)
800*f0ed16eaSHrvoje Varga     return MCDisassembler::Fail;
801*f0ed16eaSHrvoje Varga   else if (Rs == 0)
802*f0ed16eaSHrvoje Varga     MI.setOpcode(Mips::BLEZC_MMR6);
803*f0ed16eaSHrvoje Varga   else if (Rs == Rt)
804*f0ed16eaSHrvoje Varga     MI.setOpcode(Mips::BGEZC_MMR6);
805*f0ed16eaSHrvoje Varga   else {
806*f0ed16eaSHrvoje Varga     HasRs = true;
807*f0ed16eaSHrvoje Varga     MI.setOpcode(Mips::BGEC_MMR6);
808*f0ed16eaSHrvoje Varga   }
809*f0ed16eaSHrvoje Varga 
810*f0ed16eaSHrvoje Varga   if (HasRs)
811*f0ed16eaSHrvoje Varga     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
812*f0ed16eaSHrvoje Varga                                        Rs)));
813*f0ed16eaSHrvoje Varga 
814*f0ed16eaSHrvoje Varga   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
815*f0ed16eaSHrvoje Varga                                      Rt)));
816*f0ed16eaSHrvoje Varga 
817*f0ed16eaSHrvoje Varga   MI.addOperand(MCOperand::createImm(Imm));
818*f0ed16eaSHrvoje Varga 
819*f0ed16eaSHrvoje Varga   return MCDisassembler::Success;
820*f0ed16eaSHrvoje Varga }
821*f0ed16eaSHrvoje Varga 
822*f0ed16eaSHrvoje Varga template <typename InsnType>
8235c582b2fSDaniel Sanders static DecodeStatus DecodeBlezlGroupBranch(MCInst &MI, InsnType insn,
8245c582b2fSDaniel Sanders                                            uint64_t Address,
8255c582b2fSDaniel Sanders                                            const void *Decoder) {
8265c582b2fSDaniel Sanders   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
8275c582b2fSDaniel Sanders   // (otherwise we would have matched the BLEZL instruction from the earlier
8285c582b2fSDaniel Sanders   // ISA's instead).
8295c582b2fSDaniel Sanders   //
8305c582b2fSDaniel Sanders   // We have:
8315c582b2fSDaniel Sanders   //    0b010110 sssss ttttt iiiiiiiiiiiiiiii
8325c582b2fSDaniel Sanders   //      Invalid if rs == 0
8335c582b2fSDaniel Sanders   //      BLEZC   if rs == 0  && rt != 0
8345c582b2fSDaniel Sanders   //      BGEZC   if rs == rt && rt != 0
8355c582b2fSDaniel Sanders   //      BGEC    if rs != rt && rs != 0  && rt != 0
8365c582b2fSDaniel Sanders 
8375c582b2fSDaniel Sanders   InsnType Rs = fieldFromInstruction(insn, 21, 5);
8385c582b2fSDaniel Sanders   InsnType Rt = fieldFromInstruction(insn, 16, 5);
839672c710dSSagar Thakur   int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
84028a0ca07SZoran Jovanovic   bool HasRs = false;
8415c582b2fSDaniel Sanders 
8425c582b2fSDaniel Sanders   if (Rt == 0)
8435c582b2fSDaniel Sanders     return MCDisassembler::Fail;
8445c582b2fSDaniel Sanders   else if (Rs == 0)
8455c582b2fSDaniel Sanders     MI.setOpcode(Mips::BLEZC);
8465c582b2fSDaniel Sanders   else if (Rs == Rt)
8475c582b2fSDaniel Sanders     MI.setOpcode(Mips::BGEZC);
84828a0ca07SZoran Jovanovic   else {
84928a0ca07SZoran Jovanovic     HasRs = true;
85028a0ca07SZoran Jovanovic     MI.setOpcode(Mips::BGEC);
85128a0ca07SZoran Jovanovic   }
85228a0ca07SZoran Jovanovic 
85328a0ca07SZoran Jovanovic   if (HasRs)
854e9119e41SJim Grosbach     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
85528a0ca07SZoran Jovanovic                                        Rs)));
8565c582b2fSDaniel Sanders 
857e9119e41SJim Grosbach   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
8585c582b2fSDaniel Sanders                                      Rt)));
8595c582b2fSDaniel Sanders 
860e9119e41SJim Grosbach   MI.addOperand(MCOperand::createImm(Imm));
8615c582b2fSDaniel Sanders 
8625c582b2fSDaniel Sanders   return MCDisassembler::Success;
8635c582b2fSDaniel Sanders }
8645c582b2fSDaniel Sanders 
8655c582b2fSDaniel Sanders template <typename InsnType>
8665c582b2fSDaniel Sanders static DecodeStatus DecodeBgtzlGroupBranch(MCInst &MI, InsnType insn,
8675c582b2fSDaniel Sanders                                            uint64_t Address,
8685c582b2fSDaniel Sanders                                            const void *Decoder) {
8695c582b2fSDaniel Sanders   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
8705c582b2fSDaniel Sanders   // (otherwise we would have matched the BGTZL instruction from the earlier
8715c582b2fSDaniel Sanders   // ISA's instead).
8725c582b2fSDaniel Sanders   //
8735c582b2fSDaniel Sanders   // We have:
8745c582b2fSDaniel Sanders   //    0b010111 sssss ttttt iiiiiiiiiiiiiiii
8755c582b2fSDaniel Sanders   //      Invalid if rs == 0
8765c582b2fSDaniel Sanders   //      BGTZC   if rs == 0  && rt != 0
8775c582b2fSDaniel Sanders   //      BLTZC   if rs == rt && rt != 0
8785c582b2fSDaniel Sanders   //      BLTC    if rs != rt && rs != 0  && rt != 0
8795c582b2fSDaniel Sanders 
8805c14b069SZoran Jovanovic   bool HasRs = false;
8815c14b069SZoran Jovanovic 
8825c582b2fSDaniel Sanders   InsnType Rs = fieldFromInstruction(insn, 21, 5);
8835c582b2fSDaniel Sanders   InsnType Rt = fieldFromInstruction(insn, 16, 5);
884672c710dSSagar Thakur   int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
8855c582b2fSDaniel Sanders 
8865c582b2fSDaniel Sanders   if (Rt == 0)
8875c582b2fSDaniel Sanders     return MCDisassembler::Fail;
8885c582b2fSDaniel Sanders   else if (Rs == 0)
8895c582b2fSDaniel Sanders     MI.setOpcode(Mips::BGTZC);
8905c582b2fSDaniel Sanders   else if (Rs == Rt)
8915c582b2fSDaniel Sanders     MI.setOpcode(Mips::BLTZC);
8925c14b069SZoran Jovanovic   else {
8935c14b069SZoran Jovanovic     MI.setOpcode(Mips::BLTC);
8945c14b069SZoran Jovanovic     HasRs = true;
8955c14b069SZoran Jovanovic   }
8965c14b069SZoran Jovanovic 
8975c14b069SZoran Jovanovic   if (HasRs)
898e9119e41SJim Grosbach     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
8995c14b069SZoran Jovanovic                                               Rs)));
9005c582b2fSDaniel Sanders 
901e9119e41SJim Grosbach   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
9025c582b2fSDaniel Sanders                                      Rt)));
9035c582b2fSDaniel Sanders 
904e9119e41SJim Grosbach   MI.addOperand(MCOperand::createImm(Imm));
9055c582b2fSDaniel Sanders 
9065c582b2fSDaniel Sanders   return MCDisassembler::Success;
9075c582b2fSDaniel Sanders }
9085c582b2fSDaniel Sanders 
9095c582b2fSDaniel Sanders template <typename InsnType>
9105c582b2fSDaniel Sanders static DecodeStatus DecodeBgtzGroupBranch(MCInst &MI, InsnType insn,
9115c582b2fSDaniel Sanders                                           uint64_t Address,
9125c582b2fSDaniel Sanders                                           const void *Decoder) {
9135c582b2fSDaniel Sanders   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
9145c582b2fSDaniel Sanders   // (otherwise we would have matched the BGTZ instruction from the earlier
9155c582b2fSDaniel Sanders   // ISA's instead).
9165c582b2fSDaniel Sanders   //
9175c582b2fSDaniel Sanders   // We have:
9185c582b2fSDaniel Sanders   //    0b000111 sssss ttttt iiiiiiiiiiiiiiii
9195c582b2fSDaniel Sanders   //      BGTZ    if rt == 0
9205c582b2fSDaniel Sanders   //      BGTZALC if rs == 0 && rt != 0
9215c582b2fSDaniel Sanders   //      BLTZALC if rs != 0 && rs == rt
9225c582b2fSDaniel Sanders   //      BLTUC   if rs != 0 && rs != rt
9235c582b2fSDaniel Sanders 
9245c582b2fSDaniel Sanders   InsnType Rs = fieldFromInstruction(insn, 21, 5);
9255c582b2fSDaniel Sanders   InsnType Rt = fieldFromInstruction(insn, 16, 5);
926672c710dSSagar Thakur   int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
9275c582b2fSDaniel Sanders   bool HasRs = false;
9285c582b2fSDaniel Sanders   bool HasRt = false;
9295c582b2fSDaniel Sanders 
9305c582b2fSDaniel Sanders   if (Rt == 0) {
9315c582b2fSDaniel Sanders     MI.setOpcode(Mips::BGTZ);
9325c582b2fSDaniel Sanders     HasRs = true;
9335c582b2fSDaniel Sanders   } else if (Rs == 0) {
9345c582b2fSDaniel Sanders     MI.setOpcode(Mips::BGTZALC);
9355c582b2fSDaniel Sanders     HasRt = true;
9365c582b2fSDaniel Sanders   } else if (Rs == Rt) {
9375c582b2fSDaniel Sanders     MI.setOpcode(Mips::BLTZALC);
9385c582b2fSDaniel Sanders     HasRs = true;
9395c14b069SZoran Jovanovic   } else {
9405c14b069SZoran Jovanovic     MI.setOpcode(Mips::BLTUC);
9415c14b069SZoran Jovanovic     HasRs = true;
9425c14b069SZoran Jovanovic     HasRt = true;
9435c14b069SZoran Jovanovic   }
9445c582b2fSDaniel Sanders 
9455c582b2fSDaniel Sanders   if (HasRs)
946e9119e41SJim Grosbach     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
9475c582b2fSDaniel Sanders                                        Rs)));
9485c582b2fSDaniel Sanders 
9495c582b2fSDaniel Sanders   if (HasRt)
950e9119e41SJim Grosbach     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
9515c582b2fSDaniel Sanders                                        Rt)));
9525c582b2fSDaniel Sanders 
953e9119e41SJim Grosbach   MI.addOperand(MCOperand::createImm(Imm));
9545c582b2fSDaniel Sanders 
9555c582b2fSDaniel Sanders   return MCDisassembler::Success;
9565c582b2fSDaniel Sanders }
9575c582b2fSDaniel Sanders 
95828a0ca07SZoran Jovanovic template <typename InsnType>
95928a0ca07SZoran Jovanovic static DecodeStatus DecodeBlezGroupBranch(MCInst &MI, InsnType insn,
96028a0ca07SZoran Jovanovic                                            uint64_t Address,
96128a0ca07SZoran Jovanovic                                            const void *Decoder) {
96228a0ca07SZoran Jovanovic   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
96328a0ca07SZoran Jovanovic   // (otherwise we would have matched the BLEZL instruction from the earlier
96428a0ca07SZoran Jovanovic   // ISA's instead).
96528a0ca07SZoran Jovanovic   //
96628a0ca07SZoran Jovanovic   // We have:
96728a0ca07SZoran Jovanovic   //    0b000110 sssss ttttt iiiiiiiiiiiiiiii
96828a0ca07SZoran Jovanovic   //      Invalid   if rs == 0
96928a0ca07SZoran Jovanovic   //      BLEZALC   if rs == 0  && rt != 0
97028a0ca07SZoran Jovanovic   //      BGEZALC   if rs == rt && rt != 0
97128a0ca07SZoran Jovanovic   //      BGEUC     if rs != rt && rs != 0  && rt != 0
97228a0ca07SZoran Jovanovic 
97328a0ca07SZoran Jovanovic   InsnType Rs = fieldFromInstruction(insn, 21, 5);
97428a0ca07SZoran Jovanovic   InsnType Rt = fieldFromInstruction(insn, 16, 5);
975672c710dSSagar Thakur   int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
97628a0ca07SZoran Jovanovic   bool HasRs = false;
97728a0ca07SZoran Jovanovic 
97828a0ca07SZoran Jovanovic   if (Rt == 0)
97928a0ca07SZoran Jovanovic     return MCDisassembler::Fail;
98028a0ca07SZoran Jovanovic   else if (Rs == 0)
98128a0ca07SZoran Jovanovic     MI.setOpcode(Mips::BLEZALC);
98228a0ca07SZoran Jovanovic   else if (Rs == Rt)
98328a0ca07SZoran Jovanovic     MI.setOpcode(Mips::BGEZALC);
98428a0ca07SZoran Jovanovic   else {
98528a0ca07SZoran Jovanovic     HasRs = true;
98628a0ca07SZoran Jovanovic     MI.setOpcode(Mips::BGEUC);
98728a0ca07SZoran Jovanovic   }
98828a0ca07SZoran Jovanovic 
98928a0ca07SZoran Jovanovic   if (HasRs)
990e9119e41SJim Grosbach     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
99128a0ca07SZoran Jovanovic                                        Rs)));
992e9119e41SJim Grosbach   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
99328a0ca07SZoran Jovanovic                                      Rt)));
99428a0ca07SZoran Jovanovic 
995e9119e41SJim Grosbach   MI.addOperand(MCOperand::createImm(Imm));
99628a0ca07SZoran Jovanovic 
99728a0ca07SZoran Jovanovic   return MCDisassembler::Success;
99828a0ca07SZoran Jovanovic }
99928a0ca07SZoran Jovanovic 
1000ea22c4cfSJozef Kolek /// Read two bytes from the ArrayRef and return 16 bit halfword sorted
1001ea22c4cfSJozef Kolek /// according to the given endianess.
1002ea22c4cfSJozef Kolek static DecodeStatus readInstruction16(ArrayRef<uint8_t> Bytes, uint64_t Address,
1003ea22c4cfSJozef Kolek                                       uint64_t &Size, uint32_t &Insn,
1004ea22c4cfSJozef Kolek                                       bool IsBigEndian) {
1005ea22c4cfSJozef Kolek   // We want to read exactly 2 Bytes of data.
1006ea22c4cfSJozef Kolek   if (Bytes.size() < 2) {
1007ea22c4cfSJozef Kolek     Size = 0;
1008ea22c4cfSJozef Kolek     return MCDisassembler::Fail;
1009ea22c4cfSJozef Kolek   }
1010ea22c4cfSJozef Kolek 
1011ea22c4cfSJozef Kolek   if (IsBigEndian) {
1012ea22c4cfSJozef Kolek     Insn = (Bytes[0] << 8) | Bytes[1];
1013ea22c4cfSJozef Kolek   } else {
1014ea22c4cfSJozef Kolek     Insn = (Bytes[1] << 8) | Bytes[0];
1015ea22c4cfSJozef Kolek   }
1016ea22c4cfSJozef Kolek 
1017ea22c4cfSJozef Kolek   return MCDisassembler::Success;
1018ea22c4cfSJozef Kolek }
1019ea22c4cfSJozef Kolek 
10207fc5b874SRafael Espindola /// Read four bytes from the ArrayRef and return 32 bit word sorted
10214aa6bea7SRafael Espindola /// according to the given endianess
10227fc5b874SRafael Espindola static DecodeStatus readInstruction32(ArrayRef<uint8_t> Bytes, uint64_t Address,
10237fc5b874SRafael Espindola                                       uint64_t &Size, uint32_t &Insn,
10247fc5b874SRafael Espindola                                       bool IsBigEndian, bool IsMicroMips) {
102571928e68SAkira Hatanaka   // We want to read exactly 4 Bytes of data.
10267fc5b874SRafael Espindola   if (Bytes.size() < 4) {
10274aa6bea7SRafael Espindola     Size = 0;
102871928e68SAkira Hatanaka     return MCDisassembler::Fail;
102971928e68SAkira Hatanaka   }
103071928e68SAkira Hatanaka 
1031ea22c4cfSJozef Kolek   // High 16 bits of a 32-bit microMIPS instruction (where the opcode is)
1032ea22c4cfSJozef Kolek   // always precede the low 16 bits in the instruction stream (that is, they
1033ea22c4cfSJozef Kolek   // are placed at lower addresses in the instruction stream).
1034ea22c4cfSJozef Kolek   //
1035ea22c4cfSJozef Kolek   // microMIPS byte ordering:
1036ea22c4cfSJozef Kolek   //   Big-endian:    0 | 1 | 2 | 3
1037ea22c4cfSJozef Kolek   //   Little-endian: 1 | 0 | 3 | 2
1038ea22c4cfSJozef Kolek 
10394aa6bea7SRafael Espindola   if (IsBigEndian) {
104071928e68SAkira Hatanaka     // Encoded as a big-endian 32-bit word in the stream.
10414aa6bea7SRafael Espindola     Insn =
10424aa6bea7SRafael Espindola         (Bytes[3] << 0) | (Bytes[2] << 8) | (Bytes[1] << 16) | (Bytes[0] << 24);
10434aa6bea7SRafael Espindola   } else {
1044dde3d582SVladimir Medic     if (IsMicroMips) {
10454aa6bea7SRafael Espindola       Insn = (Bytes[2] << 0) | (Bytes[3] << 8) | (Bytes[0] << 16) |
1046dde3d582SVladimir Medic              (Bytes[1] << 24);
1047dde3d582SVladimir Medic     } else {
10484aa6bea7SRafael Espindola       Insn = (Bytes[0] << 0) | (Bytes[1] << 8) | (Bytes[2] << 16) |
104971928e68SAkira Hatanaka              (Bytes[3] << 24);
105071928e68SAkira Hatanaka     }
1051dde3d582SVladimir Medic   }
105271928e68SAkira Hatanaka 
105371928e68SAkira Hatanaka   return MCDisassembler::Success;
105471928e68SAkira Hatanaka }
105571928e68SAkira Hatanaka 
10564aa6bea7SRafael Espindola DecodeStatus MipsDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,
10577fc5b874SRafael Espindola                                               ArrayRef<uint8_t> Bytes,
105871928e68SAkira Hatanaka                                               uint64_t Address,
10594aa6bea7SRafael Espindola                                               raw_ostream &VStream,
10604aa6bea7SRafael Espindola                                               raw_ostream &CStream) const {
106171928e68SAkira Hatanaka   uint32_t Insn;
1062ea22c4cfSJozef Kolek   DecodeStatus Result;
106371928e68SAkira Hatanaka 
1064ea22c4cfSJozef Kolek   if (IsMicroMips) {
1065ea22c4cfSJozef Kolek     Result = readInstruction16(Bytes, Address, Size, Insn, IsBigEndian);
1066ebee6129SReid Kleckner     if (Result == MCDisassembler::Fail)
1067ebee6129SReid Kleckner       return MCDisassembler::Fail;
1068ea22c4cfSJozef Kolek 
1069ada70918SZoran Jovanovic     if (hasMips32r6()) {
1070ada70918SZoran Jovanovic       DEBUG(dbgs() << "Trying MicroMipsR616 table (16-bit instructions):\n");
1071ada70918SZoran Jovanovic       // Calling the auto-generated decoder function for microMIPS32R6
1072ada70918SZoran Jovanovic       // (and microMIPS64R6) 16-bit instructions.
1073ada70918SZoran Jovanovic       Result = decodeInstruction(DecoderTableMicroMipsR616, Instr, Insn,
1074ada70918SZoran Jovanovic                                  Address, this, STI);
1075ada70918SZoran Jovanovic       if (Result != MCDisassembler::Fail) {
1076ada70918SZoran Jovanovic         Size = 2;
1077ada70918SZoran Jovanovic         return Result;
1078ada70918SZoran Jovanovic       }
1079ada70918SZoran Jovanovic     }
1080ada70918SZoran Jovanovic 
1081ea22c4cfSJozef Kolek     DEBUG(dbgs() << "Trying MicroMips16 table (16-bit instructions):\n");
1082ada70918SZoran Jovanovic     // Calling the auto-generated decoder function for microMIPS 16-bit
1083ada70918SZoran Jovanovic     // instructions.
1084ea22c4cfSJozef Kolek     Result = decodeInstruction(DecoderTableMicroMips16, Instr, Insn, Address,
1085ea22c4cfSJozef Kolek                                this, STI);
1086ea22c4cfSJozef Kolek     if (Result != MCDisassembler::Fail) {
1087ea22c4cfSJozef Kolek       Size = 2;
1088ea22c4cfSJozef Kolek       return Result;
1089ea22c4cfSJozef Kolek     }
1090ea22c4cfSJozef Kolek 
1091ea22c4cfSJozef Kolek     Result = readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, true);
109271928e68SAkira Hatanaka     if (Result == MCDisassembler::Fail)
109371928e68SAkira Hatanaka       return MCDisassembler::Fail;
109471928e68SAkira Hatanaka 
1095676d6012SJozef Kolek     if (hasMips32r6()) {
1096676d6012SJozef Kolek       DEBUG(dbgs() << "Trying MicroMips32r632 table (32-bit instructions):\n");
1097676d6012SJozef Kolek       // Calling the auto-generated decoder function.
1098366783e1SZoran Jovanovic       Result = decodeInstruction(DecoderTableMicroMipsR632, Instr, Insn, Address,
1099676d6012SJozef Kolek                                  this, STI);
1100ada70918SZoran Jovanovic       if (Result != MCDisassembler::Fail) {
1101ada70918SZoran Jovanovic         Size = 4;
1102ada70918SZoran Jovanovic         return Result;
1103ada70918SZoran Jovanovic       }
1104ada70918SZoran Jovanovic     }
1105ada70918SZoran Jovanovic 
1106ea22c4cfSJozef Kolek     DEBUG(dbgs() << "Trying MicroMips32 table (32-bit instructions):\n");
1107dde3d582SVladimir Medic     // Calling the auto-generated decoder function.
11084aa6bea7SRafael Espindola     Result = decodeInstruction(DecoderTableMicroMips32, Instr, Insn, Address,
1109dde3d582SVladimir Medic                                this, STI);
1110dde3d582SVladimir Medic     if (Result != MCDisassembler::Fail) {
1111dde3d582SVladimir Medic       Size = 4;
1112dde3d582SVladimir Medic       return Result;
1113dde3d582SVladimir Medic     }
11142cb74ac3SHrvoje Varga 
11156221be8eSZlatko Buljan     if (hasMips32r6() && isFP64()) {
11166221be8eSZlatko Buljan       DEBUG(dbgs() << "Trying MicroMips32r6FP64 table (32-bit opcodes):\n");
11176221be8eSZlatko Buljan       Result = decodeInstruction(DecoderTableMicroMips32r6FP6432, Instr, Insn,
11182cb74ac3SHrvoje Varga                                  Address, this, STI);
11192cb74ac3SHrvoje Varga       if (Result != MCDisassembler::Fail) {
11202cb74ac3SHrvoje Varga         Size = 4;
11212cb74ac3SHrvoje Varga         return Result;
11222cb74ac3SHrvoje Varga       }
11232cb74ac3SHrvoje Varga     }
11242cb74ac3SHrvoje Varga 
1125ebee6129SReid Kleckner     // This is an invalid instruction. Let the disassembler move forward by the
1126ebee6129SReid Kleckner     // minimum instruction size.
1127ebee6129SReid Kleckner     Size = 2;
1128dde3d582SVladimir Medic     return MCDisassembler::Fail;
1129dde3d582SVladimir Medic   }
1130dde3d582SVladimir Medic 
1131ea22c4cfSJozef Kolek   Result = readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, false);
1132ebee6129SReid Kleckner   if (Result == MCDisassembler::Fail) {
1133ebee6129SReid Kleckner     Size = 4;
1134ea22c4cfSJozef Kolek     return MCDisassembler::Fail;
1135ebee6129SReid Kleckner   }
1136ea22c4cfSJozef Kolek 
1137c171f65aSDaniel Sanders   if (hasCOP3()) {
1138c171f65aSDaniel Sanders     DEBUG(dbgs() << "Trying COP3_ table (32-bit opcodes):\n");
1139c171f65aSDaniel Sanders     Result =
11404aa6bea7SRafael Espindola         decodeInstruction(DecoderTableCOP3_32, Instr, Insn, Address, this, STI);
1141c171f65aSDaniel Sanders     if (Result != MCDisassembler::Fail) {
1142c171f65aSDaniel Sanders       Size = 4;
1143c171f65aSDaniel Sanders       return Result;
1144c171f65aSDaniel Sanders     }
1145c171f65aSDaniel Sanders   }
1146c171f65aSDaniel Sanders 
1147c171f65aSDaniel Sanders   if (hasMips32r6() && isGP64()) {
114836901dd1SVasileios Kalintiris     DEBUG(dbgs() << "Trying Mips32r6_64r6 (GPR64) table (32-bit opcodes):\n");
114936901dd1SVasileios Kalintiris     Result = decodeInstruction(DecoderTableMips32r6_64r6_GP6432, Instr, Insn,
115036901dd1SVasileios Kalintiris                                Address, this, STI);
11510fa60416SDaniel Sanders     if (Result != MCDisassembler::Fail) {
11520fa60416SDaniel Sanders       Size = 4;
11530fa60416SDaniel Sanders       return Result;
11540fa60416SDaniel Sanders     }
11550fa60416SDaniel Sanders   }
11560fa60416SDaniel Sanders 
11574fbf76f7SSimon Dardis   if (hasMips32r6() && isPTR64()) {
11584fbf76f7SSimon Dardis     DEBUG(dbgs() << "Trying Mips32r6_64r6 (PTR64) table (32-bit opcodes):\n");
11594fbf76f7SSimon Dardis     Result = decodeInstruction(DecoderTableMips32r6_64r6_PTR6432, Instr, Insn,
11604fbf76f7SSimon Dardis                                Address, this, STI);
11614fbf76f7SSimon Dardis     if (Result != MCDisassembler::Fail) {
11624fbf76f7SSimon Dardis       Size = 4;
11634fbf76f7SSimon Dardis       return Result;
11644fbf76f7SSimon Dardis     }
11654fbf76f7SSimon Dardis   }
11664fbf76f7SSimon Dardis 
1167c171f65aSDaniel Sanders   if (hasMips32r6()) {
11680fa60416SDaniel Sanders     DEBUG(dbgs() << "Trying Mips32r6_64r6 table (32-bit opcodes):\n");
11694aa6bea7SRafael Espindola     Result = decodeInstruction(DecoderTableMips32r6_64r632, Instr, Insn,
11705c582b2fSDaniel Sanders                                Address, this, STI);
11715c582b2fSDaniel Sanders     if (Result != MCDisassembler::Fail) {
11725c582b2fSDaniel Sanders       Size = 4;
11735c582b2fSDaniel Sanders       return Result;
11745c582b2fSDaniel Sanders     }
11755c582b2fSDaniel Sanders   }
11765c582b2fSDaniel Sanders 
11774fbf76f7SSimon Dardis   if (hasMips2() && isPTR64()) {
11784fbf76f7SSimon Dardis     DEBUG(dbgs() << "Trying Mips32r6_64r6 (PTR64) table (32-bit opcodes):\n");
11794fbf76f7SSimon Dardis     Result = decodeInstruction(DecoderTableMips32_64_PTR6432, Instr, Insn,
11804fbf76f7SSimon Dardis                                Address, this, STI);
11814fbf76f7SSimon Dardis     if (Result != MCDisassembler::Fail) {
11824fbf76f7SSimon Dardis       Size = 4;
11834fbf76f7SSimon Dardis       return Result;
11844fbf76f7SSimon Dardis     }
11854fbf76f7SSimon Dardis   }
11864fbf76f7SSimon Dardis 
11873adf9b8dSKai Nacke   if (hasCnMips()) {
11883adf9b8dSKai Nacke     DEBUG(dbgs() << "Trying CnMips table (32-bit opcodes):\n");
11893adf9b8dSKai Nacke     Result = decodeInstruction(DecoderTableCnMips32, Instr, Insn,
11903adf9b8dSKai Nacke                                Address, this, STI);
11913adf9b8dSKai Nacke     if (Result != MCDisassembler::Fail) {
11923adf9b8dSKai Nacke       Size = 4;
11933adf9b8dSKai Nacke       return Result;
11943adf9b8dSKai Nacke     }
11953adf9b8dSKai Nacke   }
11963adf9b8dSKai Nacke 
1197a19216c8SDaniel Sanders   if (isGP64()) {
1198a19216c8SDaniel Sanders     DEBUG(dbgs() << "Trying Mips64 (GPR64) table (32-bit opcodes):\n");
1199a19216c8SDaniel Sanders     Result = decodeInstruction(DecoderTableMips6432, Instr, Insn,
1200a19216c8SDaniel Sanders                                Address, this, STI);
1201a19216c8SDaniel Sanders     if (Result != MCDisassembler::Fail) {
1202a19216c8SDaniel Sanders       Size = 4;
1203a19216c8SDaniel Sanders       return Result;
1204a19216c8SDaniel Sanders     }
1205a19216c8SDaniel Sanders   }
1206a19216c8SDaniel Sanders 
12070fa60416SDaniel Sanders   DEBUG(dbgs() << "Trying Mips table (32-bit opcodes):\n");
120871928e68SAkira Hatanaka   // Calling the auto-generated decoder function.
12094aa6bea7SRafael Espindola   Result =
12104aa6bea7SRafael Espindola       decodeInstruction(DecoderTableMips32, Instr, Insn, Address, this, STI);
121171928e68SAkira Hatanaka   if (Result != MCDisassembler::Fail) {
121271928e68SAkira Hatanaka     Size = 4;
121371928e68SAkira Hatanaka     return Result;
121471928e68SAkira Hatanaka   }
121571928e68SAkira Hatanaka 
1216ebee6129SReid Kleckner   Size = 4;
121771928e68SAkira Hatanaka   return MCDisassembler::Fail;
121871928e68SAkira Hatanaka }
121971928e68SAkira Hatanaka 
1220ec8a5490SReed Kotler static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst,
1221ec8a5490SReed Kotler                                                  unsigned RegNo,
1222ec8a5490SReed Kotler                                                  uint64_t Address,
1223ec8a5490SReed Kotler                                                  const void *Decoder) {
1224ec8a5490SReed Kotler 
1225ec8a5490SReed Kotler   return MCDisassembler::Fail;
1226ec8a5490SReed Kotler 
1227ec8a5490SReed Kotler }
1228ec8a5490SReed Kotler 
122913e6ccf3SAkira Hatanaka static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst,
123071928e68SAkira Hatanaka                                              unsigned RegNo,
123171928e68SAkira Hatanaka                                              uint64_t Address,
123271928e68SAkira Hatanaka                                              const void *Decoder) {
123371928e68SAkira Hatanaka 
123471928e68SAkira Hatanaka   if (RegNo > 31)
123571928e68SAkira Hatanaka     return MCDisassembler::Fail;
123671928e68SAkira Hatanaka 
123713e6ccf3SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::GPR64RegClassID, RegNo);
1238e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
123971928e68SAkira Hatanaka   return MCDisassembler::Success;
124071928e68SAkira Hatanaka }
124171928e68SAkira Hatanaka 
1242b0852e54SZoran Jovanovic static DecodeStatus DecodeGPRMM16RegisterClass(MCInst &Inst,
1243b0852e54SZoran Jovanovic                                                unsigned RegNo,
1244b0852e54SZoran Jovanovic                                                uint64_t Address,
1245b0852e54SZoran Jovanovic                                                const void *Decoder) {
1246ea22c4cfSJozef Kolek   if (RegNo > 7)
1247b0852e54SZoran Jovanovic     return MCDisassembler::Fail;
1248ea22c4cfSJozef Kolek   unsigned Reg = getReg(Decoder, Mips::GPRMM16RegClassID, RegNo);
1249e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1250ea22c4cfSJozef Kolek   return MCDisassembler::Success;
1251b0852e54SZoran Jovanovic }
1252b0852e54SZoran Jovanovic 
12531904fa21SJozef Kolek static DecodeStatus DecodeGPRMM16ZeroRegisterClass(MCInst &Inst,
12541904fa21SJozef Kolek                                                    unsigned RegNo,
12551904fa21SJozef Kolek                                                    uint64_t Address,
12561904fa21SJozef Kolek                                                    const void *Decoder) {
1257315e7ecaSJozef Kolek   if (RegNo > 7)
12581904fa21SJozef Kolek     return MCDisassembler::Fail;
1259315e7ecaSJozef Kolek   unsigned Reg = getReg(Decoder, Mips::GPRMM16ZeroRegClassID, RegNo);
1260e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1261315e7ecaSJozef Kolek   return MCDisassembler::Success;
12621904fa21SJozef Kolek }
12631904fa21SJozef Kolek 
126441688679SZoran Jovanovic static DecodeStatus DecodeGPRMM16MovePRegisterClass(MCInst &Inst,
126541688679SZoran Jovanovic                                                     unsigned RegNo,
126641688679SZoran Jovanovic                                                     uint64_t Address,
126741688679SZoran Jovanovic                                                     const void *Decoder) {
126841688679SZoran Jovanovic   if (RegNo > 7)
126941688679SZoran Jovanovic     return MCDisassembler::Fail;
127041688679SZoran Jovanovic   unsigned Reg = getReg(Decoder, Mips::GPRMM16MovePRegClassID, RegNo);
1271e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
127241688679SZoran Jovanovic   return MCDisassembler::Success;
127341688679SZoran Jovanovic }
127441688679SZoran Jovanovic 
127513e6ccf3SAkira Hatanaka static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst,
127671928e68SAkira Hatanaka                                              unsigned RegNo,
127771928e68SAkira Hatanaka                                              uint64_t Address,
127871928e68SAkira Hatanaka                                              const void *Decoder) {
127971928e68SAkira Hatanaka   if (RegNo > 31)
128071928e68SAkira Hatanaka     return MCDisassembler::Fail;
128113e6ccf3SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::GPR32RegClassID, RegNo);
1282e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
128371928e68SAkira Hatanaka   return MCDisassembler::Success;
128471928e68SAkira Hatanaka }
128571928e68SAkira Hatanaka 
12869bfa2e2eSAkira Hatanaka static DecodeStatus DecodePtrRegisterClass(MCInst &Inst,
12879bfa2e2eSAkira Hatanaka                                            unsigned RegNo,
12889bfa2e2eSAkira Hatanaka                                            uint64_t Address,
12899bfa2e2eSAkira Hatanaka                                            const void *Decoder) {
1290a19216c8SDaniel Sanders   if (static_cast<const MipsDisassembler *>(Decoder)->isGP64())
12919bfa2e2eSAkira Hatanaka     return DecodeGPR64RegisterClass(Inst, RegNo, Address, Decoder);
12929bfa2e2eSAkira Hatanaka 
12939bfa2e2eSAkira Hatanaka   return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
12949bfa2e2eSAkira Hatanaka }
12959bfa2e2eSAkira Hatanaka 
1296654655f1SAkira Hatanaka static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst,
1297ecabd1a5SAkira Hatanaka                                             unsigned RegNo,
1298ecabd1a5SAkira Hatanaka                                             uint64_t Address,
1299ecabd1a5SAkira Hatanaka                                             const void *Decoder) {
130013e6ccf3SAkira Hatanaka   return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
1301ecabd1a5SAkira Hatanaka }
1302ecabd1a5SAkira Hatanaka 
130371928e68SAkira Hatanaka static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
130471928e68SAkira Hatanaka                                              unsigned RegNo,
130571928e68SAkira Hatanaka                                              uint64_t Address,
130671928e68SAkira Hatanaka                                              const void *Decoder) {
130771928e68SAkira Hatanaka   if (RegNo > 31)
130871928e68SAkira Hatanaka     return MCDisassembler::Fail;
130971928e68SAkira Hatanaka 
13109bf2b567SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::FGR64RegClassID, RegNo);
1311e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
131271928e68SAkira Hatanaka   return MCDisassembler::Success;
131371928e68SAkira Hatanaka }
131471928e68SAkira Hatanaka 
131571928e68SAkira Hatanaka static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
131671928e68SAkira Hatanaka                                              unsigned RegNo,
131771928e68SAkira Hatanaka                                              uint64_t Address,
131871928e68SAkira Hatanaka                                              const void *Decoder) {
131971928e68SAkira Hatanaka   if (RegNo > 31)
132071928e68SAkira Hatanaka     return MCDisassembler::Fail;
132171928e68SAkira Hatanaka 
13229bf2b567SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::FGR32RegClassID, RegNo);
1323e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
132471928e68SAkira Hatanaka   return MCDisassembler::Success;
132571928e68SAkira Hatanaka }
132671928e68SAkira Hatanaka 
132771928e68SAkira Hatanaka static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
132871928e68SAkira Hatanaka                                            unsigned RegNo,
132971928e68SAkira Hatanaka                                            uint64_t Address,
133071928e68SAkira Hatanaka                                            const void *Decoder) {
1331253777fdSChad Rosier   if (RegNo > 31)
1332253777fdSChad Rosier     return MCDisassembler::Fail;
1333253777fdSChad Rosier   unsigned Reg = getReg(Decoder, Mips::CCRRegClassID, RegNo);
1334e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
133571928e68SAkira Hatanaka   return MCDisassembler::Success;
133671928e68SAkira Hatanaka }
133771928e68SAkira Hatanaka 
13381fb1b8b8SAkira Hatanaka static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst,
13391fb1b8b8SAkira Hatanaka                                            unsigned RegNo,
13401fb1b8b8SAkira Hatanaka                                            uint64_t Address,
13411fb1b8b8SAkira Hatanaka                                            const void *Decoder) {
13421fb1b8b8SAkira Hatanaka   if (RegNo > 7)
13431fb1b8b8SAkira Hatanaka     return MCDisassembler::Fail;
13441fb1b8b8SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::FCCRegClassID, RegNo);
1345e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
13461fb1b8b8SAkira Hatanaka   return MCDisassembler::Success;
13471fb1b8b8SAkira Hatanaka }
13481fb1b8b8SAkira Hatanaka 
134936901dd1SVasileios Kalintiris static DecodeStatus DecodeFGRCCRegisterClass(MCInst &Inst, unsigned RegNo,
13500fa60416SDaniel Sanders                                              uint64_t Address,
13510fa60416SDaniel Sanders                                              const void *Decoder) {
13520fa60416SDaniel Sanders   if (RegNo > 31)
13530fa60416SDaniel Sanders     return MCDisassembler::Fail;
13540fa60416SDaniel Sanders 
135536901dd1SVasileios Kalintiris   unsigned Reg = getReg(Decoder, Mips::FGRCCRegClassID, RegNo);
1356e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
13570fa60416SDaniel Sanders   return MCDisassembler::Success;
13580fa60416SDaniel Sanders }
13590fa60416SDaniel Sanders 
136071928e68SAkira Hatanaka static DecodeStatus DecodeMem(MCInst &Inst,
136171928e68SAkira Hatanaka                               unsigned Insn,
136271928e68SAkira Hatanaka                               uint64_t Address,
136371928e68SAkira Hatanaka                               const void *Decoder) {
136471928e68SAkira Hatanaka   int Offset = SignExtend32<16>(Insn & 0xffff);
1365ecaef49fSJim Grosbach   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1366ecaef49fSJim Grosbach   unsigned Base = fieldFromInstruction(Insn, 21, 5);
13679bf2b567SAkira Hatanaka 
136813e6ccf3SAkira Hatanaka   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
136913e6ccf3SAkira Hatanaka   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
137071928e68SAkira Hatanaka 
1371d7ecf49eSVladimir Medic   if (Inst.getOpcode() == Mips::SC ||
1372e4e83a7bSDaniel Sanders       Inst.getOpcode() == Mips::SCD)
1373e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Reg));
1374e4e83a7bSDaniel Sanders 
1375e4e83a7bSDaniel Sanders   Inst.addOperand(MCOperand::createReg(Reg));
1376e4e83a7bSDaniel Sanders   Inst.addOperand(MCOperand::createReg(Base));
1377e4e83a7bSDaniel Sanders   Inst.addOperand(MCOperand::createImm(Offset));
1378e4e83a7bSDaniel Sanders 
1379e4e83a7bSDaniel Sanders   return MCDisassembler::Success;
138071928e68SAkira Hatanaka }
138171928e68SAkira Hatanaka 
1382e4e83a7bSDaniel Sanders static DecodeStatus DecodeMemEVA(MCInst &Inst,
1383e4e83a7bSDaniel Sanders                                  unsigned Insn,
1384e4e83a7bSDaniel Sanders                                  uint64_t Address,
1385e4e83a7bSDaniel Sanders                                  const void *Decoder) {
1386e4e83a7bSDaniel Sanders   int Offset = SignExtend32<9>(Insn >> 7);
1387e4e83a7bSDaniel Sanders   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1388e4e83a7bSDaniel Sanders   unsigned Base = fieldFromInstruction(Insn, 21, 5);
1389e4e83a7bSDaniel Sanders 
1390e4e83a7bSDaniel Sanders   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1391e4e83a7bSDaniel Sanders   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1392e4e83a7bSDaniel Sanders 
1393e4e83a7bSDaniel Sanders    if (Inst.getOpcode() == Mips::SCE)
1394e4e83a7bSDaniel Sanders      Inst.addOperand(MCOperand::createReg(Reg));
1395e4e83a7bSDaniel Sanders 
1396e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1397e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1398e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
139971928e68SAkira Hatanaka 
140071928e68SAkira Hatanaka   return MCDisassembler::Success;
140171928e68SAkira Hatanaka }
140271928e68SAkira Hatanaka 
14033c88fbd3SHrvoje Varga static DecodeStatus DecodeLoadByte9(MCInst &Inst,
14043c88fbd3SHrvoje Varga                                     unsigned Insn,
14053c88fbd3SHrvoje Varga                                     uint64_t Address,
14063c88fbd3SHrvoje Varga                                     const void *Decoder) {
14073c88fbd3SHrvoje Varga   int Offset = SignExtend32<9>(Insn & 0x1ff);
14083c88fbd3SHrvoje Varga   unsigned Base = fieldFromInstruction(Insn, 16, 5);
14093c88fbd3SHrvoje Varga   unsigned Reg = fieldFromInstruction(Insn, 21, 5);
14103c88fbd3SHrvoje Varga 
14113c88fbd3SHrvoje Varga   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
14123c88fbd3SHrvoje Varga   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
14133c88fbd3SHrvoje Varga 
14143c88fbd3SHrvoje Varga   Inst.addOperand(MCOperand::createReg(Reg));
14153c88fbd3SHrvoje Varga   Inst.addOperand(MCOperand::createReg(Base));
14163c88fbd3SHrvoje Varga   Inst.addOperand(MCOperand::createImm(Offset));
14173c88fbd3SHrvoje Varga 
14183c88fbd3SHrvoje Varga   return MCDisassembler::Success;
14193c88fbd3SHrvoje Varga }
14203c88fbd3SHrvoje Varga 
14213c88fbd3SHrvoje Varga static DecodeStatus DecodeLoadByte15(MCInst &Inst,
14223c88fbd3SHrvoje Varga                                      unsigned Insn,
14233c88fbd3SHrvoje Varga                                      uint64_t Address,
14243c88fbd3SHrvoje Varga                                      const void *Decoder) {
14253c88fbd3SHrvoje Varga   int Offset = SignExtend32<16>(Insn & 0xffff);
14263c88fbd3SHrvoje Varga   unsigned Base = fieldFromInstruction(Insn, 16, 5);
14273c88fbd3SHrvoje Varga   unsigned Reg = fieldFromInstruction(Insn, 21, 5);
14283c88fbd3SHrvoje Varga 
14293c88fbd3SHrvoje Varga   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
14303c88fbd3SHrvoje Varga   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
14313c88fbd3SHrvoje Varga 
14323c88fbd3SHrvoje Varga   Inst.addOperand(MCOperand::createReg(Reg));
14333c88fbd3SHrvoje Varga   Inst.addOperand(MCOperand::createReg(Base));
14343c88fbd3SHrvoje Varga   Inst.addOperand(MCOperand::createImm(Offset));
14353c88fbd3SHrvoje Varga 
14363c88fbd3SHrvoje Varga   return MCDisassembler::Success;
14373c88fbd3SHrvoje Varga }
14383c88fbd3SHrvoje Varga 
143992db6b78SDaniel Sanders static DecodeStatus DecodeCacheOp(MCInst &Inst,
144092db6b78SDaniel Sanders                               unsigned Insn,
144192db6b78SDaniel Sanders                               uint64_t Address,
144292db6b78SDaniel Sanders                               const void *Decoder) {
144392db6b78SDaniel Sanders   int Offset = SignExtend32<16>(Insn & 0xffff);
144492db6b78SDaniel Sanders   unsigned Hint = fieldFromInstruction(Insn, 16, 5);
144592db6b78SDaniel Sanders   unsigned Base = fieldFromInstruction(Insn, 21, 5);
144692db6b78SDaniel Sanders 
144792db6b78SDaniel Sanders   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
144892db6b78SDaniel Sanders 
1449e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1450e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
1451e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Hint));
145292db6b78SDaniel Sanders 
145392db6b78SDaniel Sanders   return MCDisassembler::Success;
145492db6b78SDaniel Sanders }
145592db6b78SDaniel Sanders 
1456ab6d1cceSJozef Kolek static DecodeStatus DecodeCacheOpMM(MCInst &Inst,
1457ab6d1cceSJozef Kolek                                     unsigned Insn,
1458ab6d1cceSJozef Kolek                                     uint64_t Address,
1459ab6d1cceSJozef Kolek                                     const void *Decoder) {
1460ab6d1cceSJozef Kolek   int Offset = SignExtend32<12>(Insn & 0xfff);
1461ab6d1cceSJozef Kolek   unsigned Base = fieldFromInstruction(Insn, 16, 5);
1462ab6d1cceSJozef Kolek   unsigned Hint = fieldFromInstruction(Insn, 21, 5);
1463ab6d1cceSJozef Kolek 
1464ab6d1cceSJozef Kolek   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1465ab6d1cceSJozef Kolek 
1466e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1467e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
1468e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Hint));
1469ab6d1cceSJozef Kolek 
1470ab6d1cceSJozef Kolek   return MCDisassembler::Success;
1471ab6d1cceSJozef Kolek }
1472ab6d1cceSJozef Kolek 
1473d9790793SZoran Jovanovic static DecodeStatus DecodePrefeOpMM(MCInst &Inst,
1474d9790793SZoran Jovanovic                                     unsigned Insn,
1475d9790793SZoran Jovanovic                                     uint64_t Address,
1476d9790793SZoran Jovanovic                                     const void *Decoder) {
1477d9790793SZoran Jovanovic   int Offset = SignExtend32<9>(Insn & 0x1ff);
1478d9790793SZoran Jovanovic   unsigned Base = fieldFromInstruction(Insn, 16, 5);
1479d9790793SZoran Jovanovic   unsigned Hint = fieldFromInstruction(Insn, 21, 5);
1480d9790793SZoran Jovanovic 
1481d9790793SZoran Jovanovic   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1482d9790793SZoran Jovanovic 
1483d9790793SZoran Jovanovic   Inst.addOperand(MCOperand::createReg(Base));
1484d9790793SZoran Jovanovic   Inst.addOperand(MCOperand::createImm(Offset));
1485d9790793SZoran Jovanovic   Inst.addOperand(MCOperand::createImm(Hint));
1486d9790793SZoran Jovanovic 
1487d9790793SZoran Jovanovic   return MCDisassembler::Success;
1488d9790793SZoran Jovanovic }
1489d9790793SZoran Jovanovic 
1490e4e83a7bSDaniel Sanders static DecodeStatus DecodeCacheeOp_CacheOpR6(MCInst &Inst,
1491df464ae2SVladimir Medic                                              unsigned Insn,
1492df464ae2SVladimir Medic                                              uint64_t Address,
1493df464ae2SVladimir Medic                                              const void *Decoder) {
1494e4e83a7bSDaniel Sanders   int Offset = SignExtend32<9>(Insn >> 7);
1495df464ae2SVladimir Medic   unsigned Hint = fieldFromInstruction(Insn, 16, 5);
1496df464ae2SVladimir Medic   unsigned Base = fieldFromInstruction(Insn, 21, 5);
1497df464ae2SVladimir Medic 
1498df464ae2SVladimir Medic   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1499df464ae2SVladimir Medic 
1500e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1501e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
1502e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Hint));
1503df464ae2SVladimir Medic 
1504df464ae2SVladimir Medic   return MCDisassembler::Success;
1505df464ae2SVladimir Medic }
1506df464ae2SVladimir Medic 
15079eaa30d2SZoran Jovanovic static DecodeStatus DecodeStoreEvaOpMM(MCInst &Inst,
15089eaa30d2SZoran Jovanovic                                        unsigned Insn,
15099eaa30d2SZoran Jovanovic                                        uint64_t Address,
15109eaa30d2SZoran Jovanovic                                        const void *Decoder) {
15119eaa30d2SZoran Jovanovic   int Offset = SignExtend32<9>(Insn & 0x1ff);
15129eaa30d2SZoran Jovanovic   unsigned Reg = fieldFromInstruction(Insn, 21, 5);
15139eaa30d2SZoran Jovanovic   unsigned Base = fieldFromInstruction(Insn, 16, 5);
15149eaa30d2SZoran Jovanovic 
15159eaa30d2SZoran Jovanovic   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
15169eaa30d2SZoran Jovanovic   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
15179eaa30d2SZoran Jovanovic 
15189eaa30d2SZoran Jovanovic   Inst.addOperand(MCOperand::createReg(Reg));
15199eaa30d2SZoran Jovanovic   Inst.addOperand(MCOperand::createReg(Base));
15209eaa30d2SZoran Jovanovic   Inst.addOperand(MCOperand::createImm(Offset));
15219eaa30d2SZoran Jovanovic 
15229eaa30d2SZoran Jovanovic   return MCDisassembler::Success;
15239eaa30d2SZoran Jovanovic }
15249eaa30d2SZoran Jovanovic 
1525b4484d62SDaniel Sanders static DecodeStatus DecodeSyncI(MCInst &Inst,
1526b4484d62SDaniel Sanders                               unsigned Insn,
1527b4484d62SDaniel Sanders                               uint64_t Address,
1528b4484d62SDaniel Sanders                               const void *Decoder) {
1529b4484d62SDaniel Sanders   int Offset = SignExtend32<16>(Insn & 0xffff);
1530b4484d62SDaniel Sanders   unsigned Base = fieldFromInstruction(Insn, 21, 5);
1531b4484d62SDaniel Sanders 
1532b4484d62SDaniel Sanders   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1533b4484d62SDaniel Sanders 
1534e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1535e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
1536b4484d62SDaniel Sanders 
1537b4484d62SDaniel Sanders   return MCDisassembler::Success;
1538b4484d62SDaniel Sanders }
1539b4484d62SDaniel Sanders 
154018148671SHrvoje Varga static DecodeStatus DecodeSynciR6(MCInst &Inst,
154118148671SHrvoje Varga                                   unsigned Insn,
154218148671SHrvoje Varga                                   uint64_t Address,
154318148671SHrvoje Varga                                   const void *Decoder) {
154418148671SHrvoje Varga   int Immediate = SignExtend32<16>(Insn & 0xffff);
154518148671SHrvoje Varga   unsigned Base = fieldFromInstruction(Insn, 16, 5);
154618148671SHrvoje Varga 
154718148671SHrvoje Varga   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
154818148671SHrvoje Varga 
154918148671SHrvoje Varga   Inst.addOperand(MCOperand::createReg(Base));
155018148671SHrvoje Varga   Inst.addOperand(MCOperand::createImm(Immediate));
155118148671SHrvoje Varga 
155218148671SHrvoje Varga   return MCDisassembler::Success;
155318148671SHrvoje Varga }
155418148671SHrvoje Varga 
1555fe0bf9f6SMatheus Almeida static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn,
1556fe0bf9f6SMatheus Almeida                                     uint64_t Address, const void *Decoder) {
1557fe0bf9f6SMatheus Almeida   int Offset = SignExtend32<10>(fieldFromInstruction(Insn, 16, 10));
1558fe0bf9f6SMatheus Almeida   unsigned Reg = fieldFromInstruction(Insn, 6, 5);
1559fe0bf9f6SMatheus Almeida   unsigned Base = fieldFromInstruction(Insn, 11, 5);
1560fe0bf9f6SMatheus Almeida 
1561fe0bf9f6SMatheus Almeida   Reg = getReg(Decoder, Mips::MSA128BRegClassID, Reg);
1562fe0bf9f6SMatheus Almeida   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1563fe0bf9f6SMatheus Almeida 
1564e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1565e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
15666b59c449SMatheus Almeida 
15676b59c449SMatheus Almeida   // The immediate field of an LD/ST instruction is scaled which means it must
15686b59c449SMatheus Almeida   // be multiplied (when decoding) by the size (in bytes) of the instructions'
15696b59c449SMatheus Almeida   // data format.
15706b59c449SMatheus Almeida   // .b - 1 byte
15716b59c449SMatheus Almeida   // .h - 2 bytes
15726b59c449SMatheus Almeida   // .w - 4 bytes
15736b59c449SMatheus Almeida   // .d - 8 bytes
15746b59c449SMatheus Almeida   switch(Inst.getOpcode())
15756b59c449SMatheus Almeida   {
15766b59c449SMatheus Almeida   default:
15776b59c449SMatheus Almeida     assert (0 && "Unexpected instruction");
15786b59c449SMatheus Almeida     return MCDisassembler::Fail;
15796b59c449SMatheus Almeida     break;
15806b59c449SMatheus Almeida   case Mips::LD_B:
15816b59c449SMatheus Almeida   case Mips::ST_B:
1582e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(Offset));
15836b59c449SMatheus Almeida     break;
15846b59c449SMatheus Almeida   case Mips::LD_H:
15856b59c449SMatheus Almeida   case Mips::ST_H:
1586e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(Offset * 2));
15876b59c449SMatheus Almeida     break;
15886b59c449SMatheus Almeida   case Mips::LD_W:
15896b59c449SMatheus Almeida   case Mips::ST_W:
1590e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(Offset * 4));
15916b59c449SMatheus Almeida     break;
15926b59c449SMatheus Almeida   case Mips::LD_D:
15936b59c449SMatheus Almeida   case Mips::ST_D:
1594e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(Offset * 8));
15956b59c449SMatheus Almeida     break;
15966b59c449SMatheus Almeida   }
1597fe0bf9f6SMatheus Almeida 
1598fe0bf9f6SMatheus Almeida   return MCDisassembler::Success;
1599fe0bf9f6SMatheus Almeida }
1600fe0bf9f6SMatheus Almeida 
1601315e7ecaSJozef Kolek static DecodeStatus DecodeMemMMImm4(MCInst &Inst,
1602315e7ecaSJozef Kolek                                     unsigned Insn,
1603315e7ecaSJozef Kolek                                     uint64_t Address,
1604315e7ecaSJozef Kolek                                     const void *Decoder) {
1605315e7ecaSJozef Kolek   unsigned Offset = Insn & 0xf;
1606315e7ecaSJozef Kolek   unsigned Reg = fieldFromInstruction(Insn, 7, 3);
1607315e7ecaSJozef Kolek   unsigned Base = fieldFromInstruction(Insn, 4, 3);
1608315e7ecaSJozef Kolek 
1609315e7ecaSJozef Kolek   switch (Inst.getOpcode()) {
1610315e7ecaSJozef Kolek     case Mips::LBU16_MM:
1611315e7ecaSJozef Kolek     case Mips::LHU16_MM:
1612315e7ecaSJozef Kolek     case Mips::LW16_MM:
1613315e7ecaSJozef Kolek       if (DecodeGPRMM16RegisterClass(Inst, Reg, Address, Decoder)
1614315e7ecaSJozef Kolek             == MCDisassembler::Fail)
1615315e7ecaSJozef Kolek         return MCDisassembler::Fail;
1616315e7ecaSJozef Kolek       break;
1617315e7ecaSJozef Kolek     case Mips::SB16_MM:
1618797c2aecSZlatko Buljan     case Mips::SB16_MMR6:
1619315e7ecaSJozef Kolek     case Mips::SH16_MM:
1620797c2aecSZlatko Buljan     case Mips::SH16_MMR6:
1621315e7ecaSJozef Kolek     case Mips::SW16_MM:
1622797c2aecSZlatko Buljan     case Mips::SW16_MMR6:
1623315e7ecaSJozef Kolek       if (DecodeGPRMM16ZeroRegisterClass(Inst, Reg, Address, Decoder)
1624315e7ecaSJozef Kolek             == MCDisassembler::Fail)
1625315e7ecaSJozef Kolek         return MCDisassembler::Fail;
1626315e7ecaSJozef Kolek       break;
1627315e7ecaSJozef Kolek   }
1628315e7ecaSJozef Kolek 
1629315e7ecaSJozef Kolek   if (DecodeGPRMM16RegisterClass(Inst, Base, Address, Decoder)
1630315e7ecaSJozef Kolek         == MCDisassembler::Fail)
1631315e7ecaSJozef Kolek     return MCDisassembler::Fail;
1632315e7ecaSJozef Kolek 
1633315e7ecaSJozef Kolek   switch (Inst.getOpcode()) {
1634315e7ecaSJozef Kolek     case Mips::LBU16_MM:
1635315e7ecaSJozef Kolek       if (Offset == 0xf)
1636e9119e41SJim Grosbach         Inst.addOperand(MCOperand::createImm(-1));
1637315e7ecaSJozef Kolek       else
1638e9119e41SJim Grosbach         Inst.addOperand(MCOperand::createImm(Offset));
1639315e7ecaSJozef Kolek       break;
1640315e7ecaSJozef Kolek     case Mips::SB16_MM:
1641797c2aecSZlatko Buljan     case Mips::SB16_MMR6:
1642e9119e41SJim Grosbach       Inst.addOperand(MCOperand::createImm(Offset));
1643315e7ecaSJozef Kolek       break;
1644315e7ecaSJozef Kolek     case Mips::LHU16_MM:
1645315e7ecaSJozef Kolek     case Mips::SH16_MM:
1646797c2aecSZlatko Buljan     case Mips::SH16_MMR6:
1647e9119e41SJim Grosbach       Inst.addOperand(MCOperand::createImm(Offset << 1));
1648315e7ecaSJozef Kolek       break;
1649315e7ecaSJozef Kolek     case Mips::LW16_MM:
1650315e7ecaSJozef Kolek     case Mips::SW16_MM:
1651797c2aecSZlatko Buljan     case Mips::SW16_MMR6:
1652e9119e41SJim Grosbach       Inst.addOperand(MCOperand::createImm(Offset << 2));
1653315e7ecaSJozef Kolek       break;
1654315e7ecaSJozef Kolek   }
1655315e7ecaSJozef Kolek 
1656315e7ecaSJozef Kolek   return MCDisassembler::Success;
1657315e7ecaSJozef Kolek }
1658315e7ecaSJozef Kolek 
165912c6982bSJozef Kolek static DecodeStatus DecodeMemMMSPImm5Lsl2(MCInst &Inst,
166012c6982bSJozef Kolek                                           unsigned Insn,
166112c6982bSJozef Kolek                                           uint64_t Address,
166212c6982bSJozef Kolek                                           const void *Decoder) {
166312c6982bSJozef Kolek   unsigned Offset = Insn & 0x1F;
166412c6982bSJozef Kolek   unsigned Reg = fieldFromInstruction(Insn, 5, 5);
166512c6982bSJozef Kolek 
166612c6982bSJozef Kolek   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
166712c6982bSJozef Kolek 
1668e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1669e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Mips::SP));
1670e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset << 2));
167112c6982bSJozef Kolek 
167212c6982bSJozef Kolek   return MCDisassembler::Success;
167312c6982bSJozef Kolek }
167412c6982bSJozef Kolek 
1675e10a02ecSJozef Kolek static DecodeStatus DecodeMemMMGPImm7Lsl2(MCInst &Inst,
1676e10a02ecSJozef Kolek                                           unsigned Insn,
1677e10a02ecSJozef Kolek                                           uint64_t Address,
1678e10a02ecSJozef Kolek                                           const void *Decoder) {
1679e10a02ecSJozef Kolek   unsigned Offset = Insn & 0x7F;
1680e10a02ecSJozef Kolek   unsigned Reg = fieldFromInstruction(Insn, 7, 3);
1681e10a02ecSJozef Kolek 
1682e10a02ecSJozef Kolek   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1683e10a02ecSJozef Kolek 
1684e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1685e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Mips::GP));
1686e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset << 2));
1687e10a02ecSJozef Kolek 
1688e10a02ecSJozef Kolek   return MCDisassembler::Success;
1689e10a02ecSJozef Kolek }
1690e10a02ecSJozef Kolek 
1691d68d424aSJozef Kolek static DecodeStatus DecodeMemMMReglistImm4Lsl2(MCInst &Inst,
1692d68d424aSJozef Kolek                                                unsigned Insn,
1693d68d424aSJozef Kolek                                                uint64_t Address,
1694d68d424aSJozef Kolek                                                const void *Decoder) {
1695797c2aecSZlatko Buljan   int Offset;
1696797c2aecSZlatko Buljan   switch (Inst.getOpcode()) {
1697797c2aecSZlatko Buljan   case Mips::LWM16_MMR6:
1698797c2aecSZlatko Buljan   case Mips::SWM16_MMR6:
1699797c2aecSZlatko Buljan     Offset = fieldFromInstruction(Insn, 4, 4);
1700797c2aecSZlatko Buljan     break;
1701797c2aecSZlatko Buljan   default:
1702797c2aecSZlatko Buljan     Offset = SignExtend32<4>(Insn & 0xf);
1703797c2aecSZlatko Buljan     break;
1704797c2aecSZlatko Buljan   }
1705d68d424aSJozef Kolek 
1706d68d424aSJozef Kolek   if (DecodeRegListOperand16(Inst, Insn, Address, Decoder)
1707d68d424aSJozef Kolek       == MCDisassembler::Fail)
1708d68d424aSJozef Kolek     return MCDisassembler::Fail;
1709d68d424aSJozef Kolek 
1710e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Mips::SP));
1711e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset << 2));
1712d68d424aSJozef Kolek 
1713d68d424aSJozef Kolek   return MCDisassembler::Success;
1714d68d424aSJozef Kolek }
1715d68d424aSJozef Kolek 
1716a6593ff6SZoran Jovanovic static DecodeStatus DecodeMemMMImm9(MCInst &Inst,
1717a6593ff6SZoran Jovanovic                                     unsigned Insn,
1718a6593ff6SZoran Jovanovic                                     uint64_t Address,
1719a6593ff6SZoran Jovanovic                                     const void *Decoder) {
1720a6593ff6SZoran Jovanovic   int Offset = SignExtend32<9>(Insn & 0x1ff);
1721a6593ff6SZoran Jovanovic   unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1722a6593ff6SZoran Jovanovic   unsigned Base = fieldFromInstruction(Insn, 16, 5);
1723a6593ff6SZoran Jovanovic 
1724a6593ff6SZoran Jovanovic   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1725a6593ff6SZoran Jovanovic   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1726a6593ff6SZoran Jovanovic 
17273ef4dd7bSHrvoje Varga   if (Inst.getOpcode() == Mips::SCE_MM)
17283ef4dd7bSHrvoje Varga     Inst.addOperand(MCOperand::createReg(Reg));
17293ef4dd7bSHrvoje Varga 
1730a6593ff6SZoran Jovanovic   Inst.addOperand(MCOperand::createReg(Reg));
1731a6593ff6SZoran Jovanovic   Inst.addOperand(MCOperand::createReg(Base));
1732a6593ff6SZoran Jovanovic   Inst.addOperand(MCOperand::createImm(Offset));
1733a6593ff6SZoran Jovanovic 
1734a6593ff6SZoran Jovanovic   return MCDisassembler::Success;
1735a6593ff6SZoran Jovanovic }
1736a6593ff6SZoran Jovanovic 
1737dde3d582SVladimir Medic static DecodeStatus DecodeMemMMImm12(MCInst &Inst,
1738dde3d582SVladimir Medic                                      unsigned Insn,
1739dde3d582SVladimir Medic                                      uint64_t Address,
1740dde3d582SVladimir Medic                                      const void *Decoder) {
1741dde3d582SVladimir Medic   int Offset = SignExtend32<12>(Insn & 0x0fff);
1742dde3d582SVladimir Medic   unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1743dde3d582SVladimir Medic   unsigned Base = fieldFromInstruction(Insn, 16, 5);
1744dde3d582SVladimir Medic 
1745dde3d582SVladimir Medic   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1746dde3d582SVladimir Medic   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1747dde3d582SVladimir Medic 
1748a4c4b5fcSZoran Jovanovic   switch (Inst.getOpcode()) {
1749a4c4b5fcSZoran Jovanovic   case Mips::SWM32_MM:
1750a4c4b5fcSZoran Jovanovic   case Mips::LWM32_MM:
1751a4c4b5fcSZoran Jovanovic     if (DecodeRegListOperand(Inst, Insn, Address, Decoder)
1752a4c4b5fcSZoran Jovanovic         == MCDisassembler::Fail)
1753a4c4b5fcSZoran Jovanovic       return MCDisassembler::Fail;
1754e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Base));
1755e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(Offset));
1756a4c4b5fcSZoran Jovanovic     break;
1757a4c4b5fcSZoran Jovanovic   case Mips::SC_MM:
1758e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Reg));
1759b03fd12cSJustin Bogner     LLVM_FALLTHROUGH;
1760a4c4b5fcSZoran Jovanovic   default:
1761e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Reg));
1762ba553a6eSZlatko Buljan     if (Inst.getOpcode() == Mips::LWP_MM || Inst.getOpcode() == Mips::SWP_MM ||
1763ba553a6eSZlatko Buljan         Inst.getOpcode() == Mips::LWP_MMR6 || Inst.getOpcode() == Mips::SWP_MMR6)
1764e9119e41SJim Grosbach       Inst.addOperand(MCOperand::createReg(Reg+1));
17652deca348SZoran Jovanovic 
1766e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Base));
1767e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(Offset));
1768a4c4b5fcSZoran Jovanovic   }
1769dde3d582SVladimir Medic 
1770dde3d582SVladimir Medic   return MCDisassembler::Success;
1771dde3d582SVladimir Medic }
1772dde3d582SVladimir Medic 
1773dde3d582SVladimir Medic static DecodeStatus DecodeMemMMImm16(MCInst &Inst,
1774dde3d582SVladimir Medic                                      unsigned Insn,
1775dde3d582SVladimir Medic                                      uint64_t Address,
1776dde3d582SVladimir Medic                                      const void *Decoder) {
1777dde3d582SVladimir Medic   int Offset = SignExtend32<16>(Insn & 0xffff);
1778dde3d582SVladimir Medic   unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1779dde3d582SVladimir Medic   unsigned Base = fieldFromInstruction(Insn, 16, 5);
1780dde3d582SVladimir Medic 
1781dde3d582SVladimir Medic   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1782dde3d582SVladimir Medic   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1783dde3d582SVladimir Medic 
1784e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1785e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1786e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
1787dde3d582SVladimir Medic 
1788dde3d582SVladimir Medic   return MCDisassembler::Success;
1789dde3d582SVladimir Medic }
1790dde3d582SVladimir Medic 
179171928e68SAkira Hatanaka static DecodeStatus DecodeFMem(MCInst &Inst,
179271928e68SAkira Hatanaka                                unsigned Insn,
179371928e68SAkira Hatanaka                                uint64_t Address,
179471928e68SAkira Hatanaka                                const void *Decoder) {
179571928e68SAkira Hatanaka   int Offset = SignExtend32<16>(Insn & 0xffff);
1796ecaef49fSJim Grosbach   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1797ecaef49fSJim Grosbach   unsigned Base = fieldFromInstruction(Insn, 21, 5);
179871928e68SAkira Hatanaka 
17999bf2b567SAkira Hatanaka   Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg);
180013e6ccf3SAkira Hatanaka   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
18019bf2b567SAkira Hatanaka 
1802e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1803e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1804e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
180571928e68SAkira Hatanaka 
180671928e68SAkira Hatanaka   return MCDisassembler::Success;
180771928e68SAkira Hatanaka }
180871928e68SAkira Hatanaka 
1809cba9f80bSZlatko Buljan static DecodeStatus DecodeFMemMMR2(MCInst &Inst, unsigned Insn,
1810cba9f80bSZlatko Buljan                                    uint64_t Address, const void *Decoder) {
1811cba9f80bSZlatko Buljan   // This function is the same as DecodeFMem but with the Reg and Base fields
1812cba9f80bSZlatko Buljan   // swapped according to microMIPS spec.
1813cba9f80bSZlatko Buljan   int Offset = SignExtend32<16>(Insn & 0xffff);
1814cba9f80bSZlatko Buljan   unsigned Base = fieldFromInstruction(Insn, 16, 5);
1815cba9f80bSZlatko Buljan   unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1816cba9f80bSZlatko Buljan 
1817cba9f80bSZlatko Buljan   Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg);
1818cba9f80bSZlatko Buljan   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1819cba9f80bSZlatko Buljan 
1820cba9f80bSZlatko Buljan   Inst.addOperand(MCOperand::createReg(Reg));
1821cba9f80bSZlatko Buljan   Inst.addOperand(MCOperand::createReg(Base));
1822cba9f80bSZlatko Buljan   Inst.addOperand(MCOperand::createImm(Offset));
1823cba9f80bSZlatko Buljan 
1824cba9f80bSZlatko Buljan   return MCDisassembler::Success;
1825cba9f80bSZlatko Buljan }
1826cba9f80bSZlatko Buljan 
182792db6b78SDaniel Sanders static DecodeStatus DecodeFMem2(MCInst &Inst,
182892db6b78SDaniel Sanders                                unsigned Insn,
182992db6b78SDaniel Sanders                                uint64_t Address,
183092db6b78SDaniel Sanders                                const void *Decoder) {
183192db6b78SDaniel Sanders   int Offset = SignExtend32<16>(Insn & 0xffff);
183292db6b78SDaniel Sanders   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
183392db6b78SDaniel Sanders   unsigned Base = fieldFromInstruction(Insn, 21, 5);
183492db6b78SDaniel Sanders 
183592db6b78SDaniel Sanders   Reg = getReg(Decoder, Mips::COP2RegClassID, Reg);
183692db6b78SDaniel Sanders   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
183792db6b78SDaniel Sanders 
1838e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1839e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1840e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
184192db6b78SDaniel Sanders 
184292db6b78SDaniel Sanders   return MCDisassembler::Success;
184392db6b78SDaniel Sanders }
184492db6b78SDaniel Sanders 
184592db6b78SDaniel Sanders static DecodeStatus DecodeFMem3(MCInst &Inst,
184692db6b78SDaniel Sanders                                unsigned Insn,
184792db6b78SDaniel Sanders                                uint64_t Address,
184892db6b78SDaniel Sanders                                const void *Decoder) {
184992db6b78SDaniel Sanders   int Offset = SignExtend32<16>(Insn & 0xffff);
185092db6b78SDaniel Sanders   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
185192db6b78SDaniel Sanders   unsigned Base = fieldFromInstruction(Insn, 21, 5);
185292db6b78SDaniel Sanders 
185392db6b78SDaniel Sanders   Reg = getReg(Decoder, Mips::COP3RegClassID, Reg);
185492db6b78SDaniel Sanders   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
185592db6b78SDaniel Sanders 
1856e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1857e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1858e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
185992db6b78SDaniel Sanders 
186092db6b78SDaniel Sanders   return MCDisassembler::Success;
186192db6b78SDaniel Sanders }
186292db6b78SDaniel Sanders 
1863435cf8a4SVladimir Medic static DecodeStatus DecodeFMemCop2R6(MCInst &Inst,
1864435cf8a4SVladimir Medic                                     unsigned Insn,
1865435cf8a4SVladimir Medic                                     uint64_t Address,
1866435cf8a4SVladimir Medic                                     const void *Decoder) {
1867435cf8a4SVladimir Medic   int Offset = SignExtend32<11>(Insn & 0x07ff);
1868435cf8a4SVladimir Medic   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1869435cf8a4SVladimir Medic   unsigned Base = fieldFromInstruction(Insn, 11, 5);
1870435cf8a4SVladimir Medic 
1871435cf8a4SVladimir Medic   Reg = getReg(Decoder, Mips::COP2RegClassID, Reg);
1872435cf8a4SVladimir Medic   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1873435cf8a4SVladimir Medic 
1874e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1875e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1876e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
1877435cf8a4SVladimir Medic 
1878435cf8a4SVladimir Medic   return MCDisassembler::Success;
1879435cf8a4SVladimir Medic }
1880cba9f80bSZlatko Buljan 
1881cba9f80bSZlatko Buljan static DecodeStatus DecodeFMemCop2MMR6(MCInst &Inst, unsigned Insn,
1882cba9f80bSZlatko Buljan                                        uint64_t Address, const void *Decoder) {
1883cba9f80bSZlatko Buljan   int Offset = SignExtend32<11>(Insn & 0x07ff);
1884cba9f80bSZlatko Buljan   unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1885cba9f80bSZlatko Buljan   unsigned Base = fieldFromInstruction(Insn, 16, 5);
1886cba9f80bSZlatko Buljan 
1887cba9f80bSZlatko Buljan   Reg = getReg(Decoder, Mips::COP2RegClassID, Reg);
1888cba9f80bSZlatko Buljan   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1889cba9f80bSZlatko Buljan 
1890cba9f80bSZlatko Buljan   Inst.addOperand(MCOperand::createReg(Reg));
1891cba9f80bSZlatko Buljan   Inst.addOperand(MCOperand::createReg(Base));
1892cba9f80bSZlatko Buljan   Inst.addOperand(MCOperand::createImm(Offset));
1893cba9f80bSZlatko Buljan 
1894cba9f80bSZlatko Buljan   return MCDisassembler::Success;
1895cba9f80bSZlatko Buljan }
1896cba9f80bSZlatko Buljan 
18976a803f61SDaniel Sanders static DecodeStatus DecodeSpecial3LlSc(MCInst &Inst,
18986a803f61SDaniel Sanders                                        unsigned Insn,
18996a803f61SDaniel Sanders                                        uint64_t Address,
19006a803f61SDaniel Sanders                                        const void *Decoder) {
19016a803f61SDaniel Sanders   int64_t Offset = SignExtend64<9>((Insn >> 7) & 0x1ff);
19026a803f61SDaniel Sanders   unsigned Rt = fieldFromInstruction(Insn, 16, 5);
19036a803f61SDaniel Sanders   unsigned Base = fieldFromInstruction(Insn, 21, 5);
19046a803f61SDaniel Sanders 
19056a803f61SDaniel Sanders   Rt = getReg(Decoder, Mips::GPR32RegClassID, Rt);
19066a803f61SDaniel Sanders   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
19076a803f61SDaniel Sanders 
19086a803f61SDaniel Sanders   if(Inst.getOpcode() == Mips::SC_R6 || Inst.getOpcode() == Mips::SCD_R6){
1909e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Rt));
19106a803f61SDaniel Sanders   }
19116a803f61SDaniel Sanders 
1912e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Rt));
1913e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1914e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
19156a803f61SDaniel Sanders 
19166a803f61SDaniel Sanders   return MCDisassembler::Success;
19176a803f61SDaniel Sanders }
191871928e68SAkira Hatanaka 
191971928e68SAkira Hatanaka static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
192071928e68SAkira Hatanaka                                               unsigned RegNo,
192171928e68SAkira Hatanaka                                               uint64_t Address,
192271928e68SAkira Hatanaka                                               const void *Decoder) {
192371928e68SAkira Hatanaka   // Currently only hardware register 29 is supported.
192471928e68SAkira Hatanaka   if (RegNo != 29)
192571928e68SAkira Hatanaka     return  MCDisassembler::Fail;
1926e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Mips::HWR29));
192771928e68SAkira Hatanaka   return MCDisassembler::Success;
192871928e68SAkira Hatanaka }
192971928e68SAkira Hatanaka 
193071928e68SAkira Hatanaka static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
193171928e68SAkira Hatanaka                                               unsigned RegNo,
193271928e68SAkira Hatanaka                                               uint64_t Address,
193371928e68SAkira Hatanaka                                               const void *Decoder) {
19349bf2b567SAkira Hatanaka   if (RegNo > 30 || RegNo %2)
193571928e68SAkira Hatanaka     return MCDisassembler::Fail;
193671928e68SAkira Hatanaka 
19379bf2b567SAkira Hatanaka   ;
19389bf2b567SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::AFGR64RegClassID, RegNo /2);
1939e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
194071928e68SAkira Hatanaka   return MCDisassembler::Success;
194171928e68SAkira Hatanaka }
194271928e68SAkira Hatanaka 
194300fcf2e1SAkira Hatanaka static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst,
1944ecabd1a5SAkira Hatanaka                                                 unsigned RegNo,
1945ecabd1a5SAkira Hatanaka                                                 uint64_t Address,
1946ecabd1a5SAkira Hatanaka                                                 const void *Decoder) {
1947ecabd1a5SAkira Hatanaka   if (RegNo >= 4)
1948ecabd1a5SAkira Hatanaka     return MCDisassembler::Fail;
1949ecabd1a5SAkira Hatanaka 
195000fcf2e1SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::ACC64DSPRegClassID, RegNo);
1951e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1952ecabd1a5SAkira Hatanaka   return MCDisassembler::Success;
1953ecabd1a5SAkira Hatanaka }
1954ecabd1a5SAkira Hatanaka 
19558002a3f6SAkira Hatanaka static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst,
195659bfaf77SAkira Hatanaka                                                unsigned RegNo,
195759bfaf77SAkira Hatanaka                                                uint64_t Address,
195859bfaf77SAkira Hatanaka                                                const void *Decoder) {
195959bfaf77SAkira Hatanaka   if (RegNo >= 4)
196059bfaf77SAkira Hatanaka     return MCDisassembler::Fail;
196159bfaf77SAkira Hatanaka 
19628002a3f6SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::HI32DSPRegClassID, RegNo);
1963e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
196459bfaf77SAkira Hatanaka   return MCDisassembler::Success;
196559bfaf77SAkira Hatanaka }
196659bfaf77SAkira Hatanaka 
19678002a3f6SAkira Hatanaka static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst,
196859bfaf77SAkira Hatanaka                                                unsigned RegNo,
196959bfaf77SAkira Hatanaka                                                uint64_t Address,
197059bfaf77SAkira Hatanaka                                                const void *Decoder) {
197159bfaf77SAkira Hatanaka   if (RegNo >= 4)
197259bfaf77SAkira Hatanaka     return MCDisassembler::Fail;
197359bfaf77SAkira Hatanaka 
19748002a3f6SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::LO32DSPRegClassID, RegNo);
1975e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
197659bfaf77SAkira Hatanaka   return MCDisassembler::Success;
197759bfaf77SAkira Hatanaka }
197859bfaf77SAkira Hatanaka 
19793eb663b0SJack Carter static DecodeStatus DecodeMSA128BRegisterClass(MCInst &Inst,
19803eb663b0SJack Carter                                                unsigned RegNo,
19813eb663b0SJack Carter                                                uint64_t Address,
19823eb663b0SJack Carter                                                const void *Decoder) {
19833eb663b0SJack Carter   if (RegNo > 31)
19843eb663b0SJack Carter     return MCDisassembler::Fail;
19853eb663b0SJack Carter 
19863eb663b0SJack Carter   unsigned Reg = getReg(Decoder, Mips::MSA128BRegClassID, RegNo);
1987e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
19883eb663b0SJack Carter   return MCDisassembler::Success;
19893eb663b0SJack Carter }
19903eb663b0SJack Carter 
19915dc8ac92SJack Carter static DecodeStatus DecodeMSA128HRegisterClass(MCInst &Inst,
19925dc8ac92SJack Carter                                                unsigned RegNo,
19935dc8ac92SJack Carter                                                uint64_t Address,
19945dc8ac92SJack Carter                                                const void *Decoder) {
19955dc8ac92SJack Carter   if (RegNo > 31)
19965dc8ac92SJack Carter     return MCDisassembler::Fail;
19975dc8ac92SJack Carter 
19985dc8ac92SJack Carter   unsigned Reg = getReg(Decoder, Mips::MSA128HRegClassID, RegNo);
1999e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
20005dc8ac92SJack Carter   return MCDisassembler::Success;
20015dc8ac92SJack Carter }
20025dc8ac92SJack Carter 
20035dc8ac92SJack Carter static DecodeStatus DecodeMSA128WRegisterClass(MCInst &Inst,
20045dc8ac92SJack Carter                                                unsigned RegNo,
20055dc8ac92SJack Carter                                                uint64_t Address,
20065dc8ac92SJack Carter                                                const void *Decoder) {
20075dc8ac92SJack Carter   if (RegNo > 31)
20085dc8ac92SJack Carter     return MCDisassembler::Fail;
20095dc8ac92SJack Carter 
20105dc8ac92SJack Carter   unsigned Reg = getReg(Decoder, Mips::MSA128WRegClassID, RegNo);
2011e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
20125dc8ac92SJack Carter   return MCDisassembler::Success;
20135dc8ac92SJack Carter }
20145dc8ac92SJack Carter 
20155dc8ac92SJack Carter static DecodeStatus DecodeMSA128DRegisterClass(MCInst &Inst,
20165dc8ac92SJack Carter                                                unsigned RegNo,
20175dc8ac92SJack Carter                                                uint64_t Address,
20185dc8ac92SJack Carter                                                const void *Decoder) {
20195dc8ac92SJack Carter   if (RegNo > 31)
20205dc8ac92SJack Carter     return MCDisassembler::Fail;
20215dc8ac92SJack Carter 
20225dc8ac92SJack Carter   unsigned Reg = getReg(Decoder, Mips::MSA128DRegClassID, RegNo);
2023e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
20245dc8ac92SJack Carter   return MCDisassembler::Success;
20255dc8ac92SJack Carter }
20265dc8ac92SJack Carter 
2027a591fdc6SMatheus Almeida static DecodeStatus DecodeMSACtrlRegisterClass(MCInst &Inst,
2028a591fdc6SMatheus Almeida                                                unsigned RegNo,
2029a591fdc6SMatheus Almeida                                                uint64_t Address,
2030a591fdc6SMatheus Almeida                                                const void *Decoder) {
2031a591fdc6SMatheus Almeida   if (RegNo > 7)
2032a591fdc6SMatheus Almeida     return MCDisassembler::Fail;
2033a591fdc6SMatheus Almeida 
2034a591fdc6SMatheus Almeida   unsigned Reg = getReg(Decoder, Mips::MSACtrlRegClassID, RegNo);
2035e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
2036a591fdc6SMatheus Almeida   return MCDisassembler::Success;
2037a591fdc6SMatheus Almeida }
2038a591fdc6SMatheus Almeida 
2039a3134faeSDaniel Sanders static DecodeStatus DecodeCOP0RegisterClass(MCInst &Inst,
2040a3134faeSDaniel Sanders                                             unsigned RegNo,
2041a3134faeSDaniel Sanders                                             uint64_t Address,
2042a3134faeSDaniel Sanders                                             const void *Decoder) {
2043a3134faeSDaniel Sanders   if (RegNo > 31)
2044a3134faeSDaniel Sanders     return MCDisassembler::Fail;
2045a3134faeSDaniel Sanders 
2046a3134faeSDaniel Sanders   unsigned Reg = getReg(Decoder, Mips::COP0RegClassID, RegNo);
2047a3134faeSDaniel Sanders   Inst.addOperand(MCOperand::createReg(Reg));
2048a3134faeSDaniel Sanders   return MCDisassembler::Success;
2049a3134faeSDaniel Sanders }
2050a3134faeSDaniel Sanders 
20512a83d680SDaniel Sanders static DecodeStatus DecodeCOP2RegisterClass(MCInst &Inst,
20522a83d680SDaniel Sanders                                             unsigned RegNo,
20532a83d680SDaniel Sanders                                             uint64_t Address,
20542a83d680SDaniel Sanders                                             const void *Decoder) {
20552a83d680SDaniel Sanders   if (RegNo > 31)
20562a83d680SDaniel Sanders     return MCDisassembler::Fail;
20572a83d680SDaniel Sanders 
20582a83d680SDaniel Sanders   unsigned Reg = getReg(Decoder, Mips::COP2RegClassID, RegNo);
2059e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
20602a83d680SDaniel Sanders   return MCDisassembler::Success;
20612a83d680SDaniel Sanders }
20622a83d680SDaniel Sanders 
206371928e68SAkira Hatanaka static DecodeStatus DecodeBranchTarget(MCInst &Inst,
206471928e68SAkira Hatanaka                                        unsigned Offset,
206571928e68SAkira Hatanaka                                        uint64_t Address,
206671928e68SAkira Hatanaka                                        const void *Decoder) {
2067d37bab61SAlexey Samsonov   int32_t BranchOffset = (SignExtend32<16>(Offset) * 4) + 4;
2068e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(BranchOffset));
206971928e68SAkira Hatanaka   return MCDisassembler::Success;
207071928e68SAkira Hatanaka }
207171928e68SAkira Hatanaka 
20726f09cdfdSHrvoje Varga static DecodeStatus DecodeBranchTarget1SImm16(MCInst &Inst,
20736f09cdfdSHrvoje Varga                                               unsigned Offset,
20746f09cdfdSHrvoje Varga                                               uint64_t Address,
20756f09cdfdSHrvoje Varga                                               const void *Decoder) {
20766f09cdfdSHrvoje Varga   int32_t BranchOffset = (SignExtend32<16>(Offset) * 2);
20776f09cdfdSHrvoje Varga   Inst.addOperand(MCOperand::createImm(BranchOffset));
20786f09cdfdSHrvoje Varga   return MCDisassembler::Success;
20796f09cdfdSHrvoje Varga }
20806f09cdfdSHrvoje Varga 
208171928e68SAkira Hatanaka static DecodeStatus DecodeJumpTarget(MCInst &Inst,
208271928e68SAkira Hatanaka                                      unsigned Insn,
208371928e68SAkira Hatanaka                                      uint64_t Address,
208471928e68SAkira Hatanaka                                      const void *Decoder) {
208571928e68SAkira Hatanaka 
2086ecaef49fSJim Grosbach   unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 2;
2087e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(JumpOffset));
208871928e68SAkira Hatanaka   return MCDisassembler::Success;
208971928e68SAkira Hatanaka }
209071928e68SAkira Hatanaka 
20913c8869dcSZoran Jovanovic static DecodeStatus DecodeBranchTarget21(MCInst &Inst,
20923c8869dcSZoran Jovanovic                                          unsigned Offset,
20933c8869dcSZoran Jovanovic                                          uint64_t Address,
20943c8869dcSZoran Jovanovic                                          const void *Decoder) {
2095672c710dSSagar Thakur   int32_t BranchOffset = SignExtend32<21>(Offset) * 4 + 4;
20963c8869dcSZoran Jovanovic 
2097e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(BranchOffset));
20983c8869dcSZoran Jovanovic   return MCDisassembler::Success;
20993c8869dcSZoran Jovanovic }
21003c8869dcSZoran Jovanovic 
210184e4d59eSZoran Jovanovic static DecodeStatus DecodeBranchTarget21MM(MCInst &Inst,
210284e4d59eSZoran Jovanovic                                            unsigned Offset,
210384e4d59eSZoran Jovanovic                                            uint64_t Address,
210484e4d59eSZoran Jovanovic                                            const void *Decoder) {
2105*f0ed16eaSHrvoje Varga   int32_t BranchOffset = SignExtend32<21>(Offset) * 4 + 4;
210684e4d59eSZoran Jovanovic 
210784e4d59eSZoran Jovanovic   Inst.addOperand(MCOperand::createImm(BranchOffset));
210884e4d59eSZoran Jovanovic   return MCDisassembler::Success;
210984e4d59eSZoran Jovanovic }
211084e4d59eSZoran Jovanovic 
21113c8869dcSZoran Jovanovic static DecodeStatus DecodeBranchTarget26(MCInst &Inst,
21123c8869dcSZoran Jovanovic                                          unsigned Offset,
21133c8869dcSZoran Jovanovic                                          uint64_t Address,
21143c8869dcSZoran Jovanovic                                          const void *Decoder) {
2115672c710dSSagar Thakur   int32_t BranchOffset = SignExtend32<26>(Offset) * 4 + 4;
21163c8869dcSZoran Jovanovic 
2117e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(BranchOffset));
21183c8869dcSZoran Jovanovic   return MCDisassembler::Success;
21193c8869dcSZoran Jovanovic }
21203c8869dcSZoran Jovanovic 
21219761e96bSJozef Kolek static DecodeStatus DecodeBranchTarget7MM(MCInst &Inst,
21229761e96bSJozef Kolek                                           unsigned Offset,
21239761e96bSJozef Kolek                                           uint64_t Address,
21249761e96bSJozef Kolek                                           const void *Decoder) {
21259761e96bSJozef Kolek   int32_t BranchOffset = SignExtend32<7>(Offset) << 1;
2126e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(BranchOffset));
21279761e96bSJozef Kolek   return MCDisassembler::Success;
21289761e96bSJozef Kolek }
21299761e96bSJozef Kolek 
21305cfebddeSJozef Kolek static DecodeStatus DecodeBranchTarget10MM(MCInst &Inst,
21315cfebddeSJozef Kolek                                            unsigned Offset,
21325cfebddeSJozef Kolek                                            uint64_t Address,
21335cfebddeSJozef Kolek                                            const void *Decoder) {
21345cfebddeSJozef Kolek   int32_t BranchOffset = SignExtend32<10>(Offset) << 1;
2135e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(BranchOffset));
21365cfebddeSJozef Kolek   return MCDisassembler::Success;
21375cfebddeSJozef Kolek }
21385cfebddeSJozef Kolek 
21398a80aa76SZoran Jovanovic static DecodeStatus DecodeBranchTargetMM(MCInst &Inst,
21408a80aa76SZoran Jovanovic                                          unsigned Offset,
21418a80aa76SZoran Jovanovic                                          uint64_t Address,
21428a80aa76SZoran Jovanovic                                          const void *Decoder) {
2143*f0ed16eaSHrvoje Varga   int32_t BranchOffset = SignExtend32<16>(Offset) * 2 + 4;
2144e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(BranchOffset));
21458a80aa76SZoran Jovanovic   return MCDisassembler::Success;
21468a80aa76SZoran Jovanovic }
21478a80aa76SZoran Jovanovic 
2148a887b361SZoran Jovanovic static DecodeStatus DecodeBranchTarget26MM(MCInst &Inst,
2149a887b361SZoran Jovanovic   unsigned Offset,
2150a887b361SZoran Jovanovic   uint64_t Address,
2151a887b361SZoran Jovanovic   const void *Decoder) {
2152a887b361SZoran Jovanovic   int32_t BranchOffset = SignExtend32<26>(Offset) << 1;
2153a887b361SZoran Jovanovic 
2154a887b361SZoran Jovanovic   Inst.addOperand(MCOperand::createImm(BranchOffset));
2155a887b361SZoran Jovanovic   return MCDisassembler::Success;
2156a887b361SZoran Jovanovic }
2157a887b361SZoran Jovanovic 
2158507e084aSZoran Jovanovic static DecodeStatus DecodeJumpTargetMM(MCInst &Inst,
2159507e084aSZoran Jovanovic                                        unsigned Insn,
2160507e084aSZoran Jovanovic                                        uint64_t Address,
2161507e084aSZoran Jovanovic                                        const void *Decoder) {
2162507e084aSZoran Jovanovic   unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 1;
2163e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(JumpOffset));
2164507e084aSZoran Jovanovic   return MCDisassembler::Success;
2165507e084aSZoran Jovanovic }
216671928e68SAkira Hatanaka 
2167aa2b9278SJozef Kolek static DecodeStatus DecodeAddiur2Simm7(MCInst &Inst,
2168aa2b9278SJozef Kolek                                        unsigned Value,
2169aa2b9278SJozef Kolek                                        uint64_t Address,
2170aa2b9278SJozef Kolek                                        const void *Decoder) {
2171aa2b9278SJozef Kolek   if (Value == 0)
2172e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(1));
2173aa2b9278SJozef Kolek   else if (Value == 0x7)
2174e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(-1));
2175aa2b9278SJozef Kolek   else
2176e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(Value << 2));
2177aa2b9278SJozef Kolek   return MCDisassembler::Success;
2178aa2b9278SJozef Kolek }
2179aa2b9278SJozef Kolek 
218097297770SDaniel Sanders static DecodeStatus DecodeLi16Imm(MCInst &Inst,
2181aa2b9278SJozef Kolek                                   unsigned Value,
2182aa2b9278SJozef Kolek                                   uint64_t Address,
2183aa2b9278SJozef Kolek                                   const void *Decoder) {
2184aa2b9278SJozef Kolek   if (Value == 0x7F)
2185e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(-1));
2186aa2b9278SJozef Kolek   else
2187e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(Value));
2188aa2b9278SJozef Kolek   return MCDisassembler::Success;
2189aa2b9278SJozef Kolek }
2190aa2b9278SJozef Kolek 
21916b28f09dSZoran Jovanovic static DecodeStatus DecodePOOL16BEncodedField(MCInst &Inst,
21926b28f09dSZoran Jovanovic                                               unsigned Value,
21936b28f09dSZoran Jovanovic                                               uint64_t Address,
21946b28f09dSZoran Jovanovic                                               const void *Decoder) {
21956b28f09dSZoran Jovanovic   Inst.addOperand(MCOperand::createImm(Value == 0x0 ? 8 : Value));
21966b28f09dSZoran Jovanovic   return MCDisassembler::Success;
21976b28f09dSZoran Jovanovic }
21986b28f09dSZoran Jovanovic 
219919b7f76aSDaniel Sanders template <unsigned Bits, int Offset, int Scale>
220019b7f76aSDaniel Sanders static DecodeStatus DecodeUImmWithOffsetAndScale(MCInst &Inst, unsigned Value,
2201779c5937SMatheus Almeida                                                  uint64_t Address,
2202779c5937SMatheus Almeida                                                  const void *Decoder) {
2203ea4f653dSDaniel Sanders   Value &= ((1 << Bits) - 1);
220419b7f76aSDaniel Sanders   Value *= Scale;
2205ea4f653dSDaniel Sanders   Inst.addOperand(MCOperand::createImm(Value + Offset));
2206779c5937SMatheus Almeida   return MCDisassembler::Success;
2207779c5937SMatheus Almeida }
2208779c5937SMatheus Almeida 
220997297770SDaniel Sanders template <unsigned Bits, int Offset, int ScaleBy>
221097297770SDaniel Sanders static DecodeStatus DecodeSImmWithOffsetAndScale(MCInst &Inst, unsigned Value,
221178e89020SDaniel Sanders                                                  uint64_t Address,
221278e89020SDaniel Sanders                                                  const void *Decoder) {
221397297770SDaniel Sanders   int32_t Imm = SignExtend32<Bits>(Value) * ScaleBy;
221478e89020SDaniel Sanders   Inst.addOperand(MCOperand::createImm(Imm + Offset));
221578e89020SDaniel Sanders   return MCDisassembler::Success;
221678e89020SDaniel Sanders }
221778e89020SDaniel Sanders 
221871928e68SAkira Hatanaka static DecodeStatus DecodeInsSize(MCInst &Inst,
221971928e68SAkira Hatanaka                                   unsigned Insn,
222071928e68SAkira Hatanaka                                   uint64_t Address,
222171928e68SAkira Hatanaka                                   const void *Decoder) {
222271928e68SAkira Hatanaka   // First we need to grab the pos(lsb) from MCInst.
222371928e68SAkira Hatanaka   int Pos = Inst.getOperand(2).getImm();
222471928e68SAkira Hatanaka   int Size = (int) Insn - Pos + 1;
2225e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(SignExtend32<16>(Size)));
222671928e68SAkira Hatanaka   return MCDisassembler::Success;
222771928e68SAkira Hatanaka }
222871928e68SAkira Hatanaka 
2229b59e1a41SDaniel Sanders static DecodeStatus DecodeSimm19Lsl2(MCInst &Inst, unsigned Insn,
2230b59e1a41SDaniel Sanders                                      uint64_t Address, const void *Decoder) {
2231e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(SignExtend32<19>(Insn) * 4));
2232b59e1a41SDaniel Sanders   return MCDisassembler::Success;
2233b59e1a41SDaniel Sanders }
22342855142aSZoran Jovanovic 
22352855142aSZoran Jovanovic static DecodeStatus DecodeSimm18Lsl3(MCInst &Inst, unsigned Insn,
22362855142aSZoran Jovanovic                                      uint64_t Address, const void *Decoder) {
2237e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(SignExtend32<18>(Insn) * 8));
22382855142aSZoran Jovanovic   return MCDisassembler::Success;
22392855142aSZoran Jovanovic }
2240a4c4b5fcSZoran Jovanovic 
2241b682ddf3SVladimir Medic static DecodeStatus DecodeSimm9SP(MCInst &Inst, unsigned Insn,
2242b682ddf3SVladimir Medic                                   uint64_t Address, const void *Decoder) {
2243b682ddf3SVladimir Medic   int32_t DecodedValue;
2244b682ddf3SVladimir Medic   switch (Insn) {
2245b682ddf3SVladimir Medic   case 0: DecodedValue = 256; break;
2246b682ddf3SVladimir Medic   case 1: DecodedValue = 257; break;
2247b682ddf3SVladimir Medic   case 510: DecodedValue = -258; break;
2248b682ddf3SVladimir Medic   case 511: DecodedValue = -257; break;
2249b682ddf3SVladimir Medic   default: DecodedValue = SignExtend32<9>(Insn); break;
2250b682ddf3SVladimir Medic   }
2251e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(DecodedValue * 4));
2252b682ddf3SVladimir Medic   return MCDisassembler::Success;
2253b682ddf3SVladimir Medic }
2254b682ddf3SVladimir Medic 
2255b682ddf3SVladimir Medic static DecodeStatus DecodeANDI16Imm(MCInst &Inst, unsigned Insn,
2256b682ddf3SVladimir Medic                                     uint64_t Address, const void *Decoder) {
2257b682ddf3SVladimir Medic   // Insn must be >= 0, since it is unsigned that condition is always true.
2258b682ddf3SVladimir Medic   assert(Insn < 16);
2259b682ddf3SVladimir Medic   int32_t DecodedValues[] = {128, 1, 2, 3, 4, 7, 8, 15, 16, 31, 32, 63, 64,
2260b682ddf3SVladimir Medic                              255, 32768, 65535};
2261e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(DecodedValues[Insn]));
2262b682ddf3SVladimir Medic   return MCDisassembler::Success;
2263b682ddf3SVladimir Medic }
2264b682ddf3SVladimir Medic 
2265a4c4b5fcSZoran Jovanovic static DecodeStatus DecodeRegListOperand(MCInst &Inst,
2266a4c4b5fcSZoran Jovanovic                                          unsigned Insn,
2267a4c4b5fcSZoran Jovanovic                                          uint64_t Address,
2268a4c4b5fcSZoran Jovanovic                                          const void *Decoder) {
2269a4c4b5fcSZoran Jovanovic   unsigned Regs[] = {Mips::S0, Mips::S1, Mips::S2, Mips::S3, Mips::S4, Mips::S5,
2270dc4b8c27SZoran Jovanovic                      Mips::S6, Mips::S7, Mips::FP};
2271a4c4b5fcSZoran Jovanovic   unsigned RegNum;
2272a4c4b5fcSZoran Jovanovic 
2273a4c4b5fcSZoran Jovanovic   unsigned RegLst = fieldFromInstruction(Insn, 21, 5);
2274df19a5e6SDaniel Sanders 
2275a4c4b5fcSZoran Jovanovic   // Empty register lists are not allowed.
2276a4c4b5fcSZoran Jovanovic   if (RegLst == 0)
2277a4c4b5fcSZoran Jovanovic     return MCDisassembler::Fail;
2278a4c4b5fcSZoran Jovanovic 
2279a4c4b5fcSZoran Jovanovic   RegNum = RegLst & 0xf;
2280df19a5e6SDaniel Sanders 
2281df19a5e6SDaniel Sanders   // RegLst values 10-15, and 26-31 are reserved.
2282df19a5e6SDaniel Sanders   if (RegNum > 9)
2283df19a5e6SDaniel Sanders     return MCDisassembler::Fail;
2284df19a5e6SDaniel Sanders 
2285a4c4b5fcSZoran Jovanovic   for (unsigned i = 0; i < RegNum; i++)
2286e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Regs[i]));
2287a4c4b5fcSZoran Jovanovic 
2288a4c4b5fcSZoran Jovanovic   if (RegLst & 0x10)
2289e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::RA));
2290a4c4b5fcSZoran Jovanovic 
2291a4c4b5fcSZoran Jovanovic   return MCDisassembler::Success;
2292a4c4b5fcSZoran Jovanovic }
2293f9a02500SZoran Jovanovic 
2294f9a02500SZoran Jovanovic static DecodeStatus DecodeRegListOperand16(MCInst &Inst, unsigned Insn,
2295f9a02500SZoran Jovanovic                                            uint64_t Address,
2296f9a02500SZoran Jovanovic                                            const void *Decoder) {
2297f9a02500SZoran Jovanovic   unsigned Regs[] = {Mips::S0, Mips::S1, Mips::S2, Mips::S3};
2298797c2aecSZlatko Buljan   unsigned RegLst;
2299797c2aecSZlatko Buljan   switch(Inst.getOpcode()) {
2300797c2aecSZlatko Buljan   default:
2301797c2aecSZlatko Buljan     RegLst = fieldFromInstruction(Insn, 4, 2);
2302797c2aecSZlatko Buljan     break;
2303797c2aecSZlatko Buljan   case Mips::LWM16_MMR6:
2304797c2aecSZlatko Buljan   case Mips::SWM16_MMR6:
2305797c2aecSZlatko Buljan     RegLst = fieldFromInstruction(Insn, 8, 2);
2306797c2aecSZlatko Buljan     break;
2307797c2aecSZlatko Buljan   }
2308d68d424aSJozef Kolek   unsigned RegNum = RegLst & 0x3;
2309f9a02500SZoran Jovanovic 
2310d68d424aSJozef Kolek   for (unsigned i = 0; i <= RegNum; i++)
2311e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Regs[i]));
2312f9a02500SZoran Jovanovic 
2313e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Mips::RA));
2314f9a02500SZoran Jovanovic 
2315f9a02500SZoran Jovanovic   return MCDisassembler::Success;
2316f9a02500SZoran Jovanovic }
23172c6d7320SJozef Kolek 
231841688679SZoran Jovanovic static DecodeStatus DecodeMovePRegPair(MCInst &Inst, unsigned Insn,
231941688679SZoran Jovanovic                                        uint64_t Address, const void *Decoder) {
232041688679SZoran Jovanovic 
232141688679SZoran Jovanovic   unsigned RegPair = fieldFromInstruction(Insn, 7, 3);
232241688679SZoran Jovanovic 
232341688679SZoran Jovanovic   switch (RegPair) {
232441688679SZoran Jovanovic   default:
232541688679SZoran Jovanovic     return MCDisassembler::Fail;
232641688679SZoran Jovanovic   case 0:
2327e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A1));
2328e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A2));
232941688679SZoran Jovanovic     break;
233041688679SZoran Jovanovic   case 1:
2331e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A1));
2332e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A3));
233341688679SZoran Jovanovic     break;
233441688679SZoran Jovanovic   case 2:
2335e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A2));
2336e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A3));
233741688679SZoran Jovanovic     break;
233841688679SZoran Jovanovic   case 3:
2339e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A0));
2340e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::S5));
234141688679SZoran Jovanovic     break;
234241688679SZoran Jovanovic   case 4:
2343e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A0));
2344e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::S6));
234541688679SZoran Jovanovic     break;
234641688679SZoran Jovanovic   case 5:
2347e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A0));
2348e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A1));
234941688679SZoran Jovanovic     break;
235041688679SZoran Jovanovic   case 6:
2351e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A0));
2352e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A2));
235341688679SZoran Jovanovic     break;
235441688679SZoran Jovanovic   case 7:
2355e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A0));
2356e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A3));
235741688679SZoran Jovanovic     break;
235841688679SZoran Jovanovic   }
235941688679SZoran Jovanovic 
236041688679SZoran Jovanovic   return MCDisassembler::Success;
236141688679SZoran Jovanovic }
236241688679SZoran Jovanovic 
23632c6d7320SJozef Kolek static DecodeStatus DecodeSimm23Lsl2(MCInst &Inst, unsigned Insn,
23642c6d7320SJozef Kolek                                      uint64_t Address, const void *Decoder) {
23656499b5f0SJustin Bogner   Inst.addOperand(MCOperand::createImm(SignExtend32<25>(Insn << 2)));
23662c6d7320SJozef Kolek   return MCDisassembler::Success;
23672c6d7320SJozef Kolek }
2368fdbd0a37SZoran Jovanovic 
2369fdbd0a37SZoran Jovanovic template <typename InsnType>
2370fdbd0a37SZoran Jovanovic static DecodeStatus DecodeBgtzGroupBranchMMR6(MCInst &MI, InsnType insn,
2371fdbd0a37SZoran Jovanovic   uint64_t Address,
2372fdbd0a37SZoran Jovanovic   const void *Decoder) {
2373fdbd0a37SZoran Jovanovic   // We have:
2374fdbd0a37SZoran Jovanovic   //    0b000111 ttttt sssss iiiiiiiiiiiiiiii
2375fdbd0a37SZoran Jovanovic   //      Invalid      if rt == 0
2376fdbd0a37SZoran Jovanovic   //      BGTZALC_MMR6 if rs == 0 && rt != 0
2377fdbd0a37SZoran Jovanovic   //      BLTZALC_MMR6 if rs != 0 && rs == rt
2378fdbd0a37SZoran Jovanovic   //      BLTUC_MMR6   if rs != 0 && rs != rt
2379fdbd0a37SZoran Jovanovic 
2380fdbd0a37SZoran Jovanovic   InsnType Rt = fieldFromInstruction(insn, 21, 5);
2381fdbd0a37SZoran Jovanovic   InsnType Rs = fieldFromInstruction(insn, 16, 5);
2382*f0ed16eaSHrvoje Varga   InsnType Imm = 0;
2383fdbd0a37SZoran Jovanovic   bool HasRs = false;
2384fdbd0a37SZoran Jovanovic   bool HasRt = false;
2385fdbd0a37SZoran Jovanovic 
2386fdbd0a37SZoran Jovanovic   if (Rt == 0)
2387fdbd0a37SZoran Jovanovic     return MCDisassembler::Fail;
2388fdbd0a37SZoran Jovanovic   else if (Rs == 0) {
2389fdbd0a37SZoran Jovanovic     MI.setOpcode(Mips::BGTZALC_MMR6);
2390fdbd0a37SZoran Jovanovic     HasRt = true;
2391*f0ed16eaSHrvoje Varga     Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
2392fdbd0a37SZoran Jovanovic   }
2393fdbd0a37SZoran Jovanovic   else if (Rs == Rt) {
2394fdbd0a37SZoran Jovanovic     MI.setOpcode(Mips::BLTZALC_MMR6);
2395fdbd0a37SZoran Jovanovic     HasRs = true;
2396*f0ed16eaSHrvoje Varga     Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
2397fdbd0a37SZoran Jovanovic   }
2398fdbd0a37SZoran Jovanovic   else {
2399fdbd0a37SZoran Jovanovic     MI.setOpcode(Mips::BLTUC_MMR6);
2400fdbd0a37SZoran Jovanovic     HasRs = true;
2401fdbd0a37SZoran Jovanovic     HasRt = true;
2402*f0ed16eaSHrvoje Varga     Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
2403fdbd0a37SZoran Jovanovic   }
2404fdbd0a37SZoran Jovanovic 
2405fdbd0a37SZoran Jovanovic   if (HasRs)
2406fdbd0a37SZoran Jovanovic     MI.addOperand(
2407fdbd0a37SZoran Jovanovic     MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rs)));
2408fdbd0a37SZoran Jovanovic 
2409fdbd0a37SZoran Jovanovic   if (HasRt)
2410fdbd0a37SZoran Jovanovic     MI.addOperand(
2411fdbd0a37SZoran Jovanovic     MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rt)));
2412fdbd0a37SZoran Jovanovic 
2413fdbd0a37SZoran Jovanovic   MI.addOperand(MCOperand::createImm(Imm));
2414fdbd0a37SZoran Jovanovic 
2415fdbd0a37SZoran Jovanovic   return MCDisassembler::Success;
2416fdbd0a37SZoran Jovanovic }
2417fdbd0a37SZoran Jovanovic 
2418fdbd0a37SZoran Jovanovic template <typename InsnType>
2419fdbd0a37SZoran Jovanovic static DecodeStatus DecodeBlezGroupBranchMMR6(MCInst &MI, InsnType insn,
2420fdbd0a37SZoran Jovanovic   uint64_t Address,
2421fdbd0a37SZoran Jovanovic   const void *Decoder) {
2422fdbd0a37SZoran Jovanovic   // We have:
2423fdbd0a37SZoran Jovanovic   //    0b000110 ttttt sssss iiiiiiiiiiiiiiii
2424*f0ed16eaSHrvoje Varga   //      Invalid        if rt == 0
2425fdbd0a37SZoran Jovanovic   //      BLEZALC_MMR6   if rs == 0  && rt != 0
2426fdbd0a37SZoran Jovanovic   //      BGEZALC_MMR6   if rs == rt && rt != 0
2427fdbd0a37SZoran Jovanovic   //      BGEUC_MMR6     if rs != rt && rs != 0  && rt != 0
2428fdbd0a37SZoran Jovanovic 
2429fdbd0a37SZoran Jovanovic   InsnType Rt = fieldFromInstruction(insn, 21, 5);
2430fdbd0a37SZoran Jovanovic   InsnType Rs = fieldFromInstruction(insn, 16, 5);
2431*f0ed16eaSHrvoje Varga   InsnType Imm = 0;
2432fdbd0a37SZoran Jovanovic   bool HasRs = false;
2433fdbd0a37SZoran Jovanovic 
2434fdbd0a37SZoran Jovanovic   if (Rt == 0)
2435fdbd0a37SZoran Jovanovic     return MCDisassembler::Fail;
2436*f0ed16eaSHrvoje Varga   else if (Rs == 0) {
2437fdbd0a37SZoran Jovanovic     MI.setOpcode(Mips::BLEZALC_MMR6);
2438*f0ed16eaSHrvoje Varga     Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
2439*f0ed16eaSHrvoje Varga   }
2440*f0ed16eaSHrvoje Varga   else if (Rs == Rt) {
2441fdbd0a37SZoran Jovanovic     MI.setOpcode(Mips::BGEZALC_MMR6);
2442*f0ed16eaSHrvoje Varga     Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
2443*f0ed16eaSHrvoje Varga   }
2444fdbd0a37SZoran Jovanovic   else {
2445fdbd0a37SZoran Jovanovic     HasRs = true;
2446fdbd0a37SZoran Jovanovic     MI.setOpcode(Mips::BGEUC_MMR6);
2447*f0ed16eaSHrvoje Varga     Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
2448fdbd0a37SZoran Jovanovic   }
2449fdbd0a37SZoran Jovanovic 
2450fdbd0a37SZoran Jovanovic   if (HasRs)
2451fdbd0a37SZoran Jovanovic     MI.addOperand(
2452fdbd0a37SZoran Jovanovic     MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rs)));
2453fdbd0a37SZoran Jovanovic   MI.addOperand(
2454fdbd0a37SZoran Jovanovic     MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rt)));
2455fdbd0a37SZoran Jovanovic 
2456fdbd0a37SZoran Jovanovic   MI.addOperand(MCOperand::createImm(Imm));
2457fdbd0a37SZoran Jovanovic 
2458fdbd0a37SZoran Jovanovic   return MCDisassembler::Success;
2459fdbd0a37SZoran Jovanovic }
2460