1926883e1SEugene Zelenko //===- MipsDisassembler.cpp - Disassembler for Mips -----------------------===//
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 
1479220eaeSEugene Zelenko #include "MCTargetDesc/MipsMCTargetDesc.h"
1571928e68SAkira Hatanaka #include "Mips.h"
16926883e1SEugene Zelenko #include "llvm/ADT/ArrayRef.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"
21926883e1SEugene Zelenko #include "llvm/MC/MCRegisterInfo.h"
226bda14b3SChandler Carruth #include "llvm/MC/MCSubtargetInfo.h"
23926883e1SEugene Zelenko #include "llvm/Support/Compiler.h"
24926883e1SEugene Zelenko #include "llvm/Support/Debug.h"
25926883e1SEugene Zelenko #include "llvm/Support/ErrorHandling.h"
26ed0881b2SChandler Carruth #include "llvm/Support/MathExtras.h"
2771928e68SAkira Hatanaka #include "llvm/Support/TargetRegistry.h"
286bda14b3SChandler Carruth #include "llvm/Support/raw_ostream.h"
29926883e1SEugene Zelenko #include <cassert>
30926883e1SEugene Zelenko #include <cstdint>
3171928e68SAkira Hatanaka 
3271928e68SAkira Hatanaka using namespace llvm;
3371928e68SAkira Hatanaka 
34e96dd897SChandler Carruth #define DEBUG_TYPE "mips-disassembler"
35e96dd897SChandler Carruth 
3679220eaeSEugene Zelenko using DecodeStatus = MCDisassembler::DecodeStatus;
3771928e68SAkira Hatanaka 
38cb3e98cfSBenjamin Kramer namespace {
39cb3e98cfSBenjamin Kramer 
40a19216c8SDaniel Sanders class MipsDisassembler : public MCDisassembler {
41dde3d582SVladimir Medic   bool IsMicroMips;
42a19216c8SDaniel Sanders   bool IsBigEndian;
43926883e1SEugene Zelenko 
449bf2b567SAkira Hatanaka public:
45a19216c8SDaniel Sanders   MipsDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx, bool IsBigEndian)
46a19216c8SDaniel Sanders       : MCDisassembler(STI, Ctx),
47db0712f9SMichael Kuperstein         IsMicroMips(STI.getFeatureBits()[Mips::FeatureMicroMips]),
48a19216c8SDaniel Sanders         IsBigEndian(IsBigEndian) {}
4971928e68SAkira Hatanaka 
504fbf76f7SSimon Dardis   bool hasMips2() const { return STI.getFeatureBits()[Mips::FeatureMips2]; }
51db0712f9SMichael Kuperstein   bool hasMips3() const { return STI.getFeatureBits()[Mips::FeatureMips3]; }
52db0712f9SMichael Kuperstein   bool hasMips32() const { return STI.getFeatureBits()[Mips::FeatureMips32]; }
53926883e1SEugene Zelenko 
54c171f65aSDaniel Sanders   bool hasMips32r6() const {
55db0712f9SMichael Kuperstein     return STI.getFeatureBits()[Mips::FeatureMips32r6];
565c582b2fSDaniel Sanders   }
57926883e1SEugene Zelenko 
586221be8eSZlatko Buljan   bool isFP64() const { return STI.getFeatureBits()[Mips::FeatureFP64Bit]; }
595c582b2fSDaniel Sanders 
60db0712f9SMichael Kuperstein   bool isGP64() const { return STI.getFeatureBits()[Mips::FeatureGP64Bit]; }
610fa60416SDaniel Sanders 
624fbf76f7SSimon Dardis   bool isPTR64() const { return STI.getFeatureBits()[Mips::FeaturePTR64Bit]; }
634fbf76f7SSimon Dardis 
643adf9b8dSKai Nacke   bool hasCnMips() const { return STI.getFeatureBits()[Mips::FeatureCnMips]; }
653adf9b8dSKai Nacke 
66c171f65aSDaniel Sanders   bool hasCOP3() const {
67c171f65aSDaniel Sanders     // Only present in MIPS-I and MIPS-II
68c171f65aSDaniel Sanders     return !hasMips32() && !hasMips3();
69c171f65aSDaniel Sanders   }
70c171f65aSDaniel Sanders 
714aa6bea7SRafael Espindola   DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
727fc5b874SRafael Espindola                               ArrayRef<uint8_t> Bytes, uint64_t Address,
734aa6bea7SRafael Espindola                               raw_ostream &VStream,
744aa6bea7SRafael Espindola                               raw_ostream &CStream) const override;
7571928e68SAkira Hatanaka };
7671928e68SAkira Hatanaka 
77cb3e98cfSBenjamin Kramer } // end anonymous namespace
78cb3e98cfSBenjamin Kramer 
7971928e68SAkira Hatanaka // Forward declare these because the autogenerated code will reference them.
8071928e68SAkira Hatanaka // Definitions are further down.
8113e6ccf3SAkira Hatanaka static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst,
8271928e68SAkira Hatanaka                                              unsigned RegNo,
8371928e68SAkira Hatanaka                                              uint64_t Address,
8471928e68SAkira Hatanaka                                              const void *Decoder);
8571928e68SAkira Hatanaka 
86ec8a5490SReed Kotler static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst,
87ec8a5490SReed Kotler                                                  unsigned RegNo,
88ec8a5490SReed Kotler                                                  uint64_t Address,
89ec8a5490SReed Kotler                                                  const void *Decoder);
90ec8a5490SReed Kotler 
91b0852e54SZoran Jovanovic static DecodeStatus DecodeGPRMM16RegisterClass(MCInst &Inst,
92b0852e54SZoran Jovanovic                                                unsigned RegNo,
93b0852e54SZoran Jovanovic                                                uint64_t Address,
94b0852e54SZoran Jovanovic                                                const void *Decoder);
95b0852e54SZoran Jovanovic 
961904fa21SJozef Kolek static DecodeStatus DecodeGPRMM16ZeroRegisterClass(MCInst &Inst,
971904fa21SJozef Kolek                                                    unsigned RegNo,
981904fa21SJozef Kolek                                                    uint64_t Address,
991904fa21SJozef Kolek                                                    const void *Decoder);
1001904fa21SJozef Kolek 
10141688679SZoran Jovanovic static DecodeStatus DecodeGPRMM16MovePRegisterClass(MCInst &Inst,
10241688679SZoran Jovanovic                                                     unsigned RegNo,
10341688679SZoran Jovanovic                                                     uint64_t Address,
10441688679SZoran Jovanovic                                                     const void *Decoder);
10541688679SZoran Jovanovic 
10613e6ccf3SAkira Hatanaka static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst,
10771928e68SAkira Hatanaka                                              unsigned RegNo,
10871928e68SAkira Hatanaka                                              uint64_t Address,
10971928e68SAkira Hatanaka                                              const void *Decoder);
11071928e68SAkira Hatanaka 
1119bfa2e2eSAkira Hatanaka static DecodeStatus DecodePtrRegisterClass(MCInst &Inst,
1129bfa2e2eSAkira Hatanaka                                            unsigned Insn,
1139bfa2e2eSAkira Hatanaka                                            uint64_t Address,
1149bfa2e2eSAkira Hatanaka                                            const void *Decoder);
1159bfa2e2eSAkira Hatanaka 
116654655f1SAkira Hatanaka static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst,
117ecabd1a5SAkira Hatanaka                                             unsigned RegNo,
118ecabd1a5SAkira Hatanaka                                             uint64_t Address,
119ecabd1a5SAkira Hatanaka                                             const void *Decoder);
120ecabd1a5SAkira Hatanaka 
12171928e68SAkira Hatanaka static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
12271928e68SAkira Hatanaka                                              unsigned RegNo,
12371928e68SAkira Hatanaka                                              uint64_t Address,
12471928e68SAkira Hatanaka                                              const void *Decoder);
12571928e68SAkira Hatanaka 
12671928e68SAkira Hatanaka static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
12771928e68SAkira Hatanaka                                              unsigned RegNo,
12871928e68SAkira Hatanaka                                              uint64_t Address,
12971928e68SAkira Hatanaka                                              const void *Decoder);
13071928e68SAkira Hatanaka 
13171928e68SAkira Hatanaka static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
13271928e68SAkira Hatanaka                                            unsigned RegNo,
13371928e68SAkira Hatanaka                                            uint64_t Address,
13471928e68SAkira Hatanaka                                            const void *Decoder);
13571928e68SAkira Hatanaka 
1361fb1b8b8SAkira Hatanaka static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst,
1371fb1b8b8SAkira Hatanaka                                            unsigned RegNo,
1381fb1b8b8SAkira Hatanaka                                            uint64_t Address,
1391fb1b8b8SAkira Hatanaka                                            const void *Decoder);
1401fb1b8b8SAkira Hatanaka 
14136901dd1SVasileios Kalintiris static DecodeStatus DecodeFGRCCRegisterClass(MCInst &Inst, unsigned RegNo,
1420fa60416SDaniel Sanders                                              uint64_t Address,
1430fa60416SDaniel Sanders                                              const void *Decoder);
1440fa60416SDaniel Sanders 
14571928e68SAkira Hatanaka static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
14671928e68SAkira Hatanaka                                               unsigned Insn,
14771928e68SAkira Hatanaka                                               uint64_t Address,
14871928e68SAkira Hatanaka                                               const void *Decoder);
14971928e68SAkira Hatanaka 
15071928e68SAkira Hatanaka static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
15171928e68SAkira Hatanaka                                               unsigned RegNo,
15271928e68SAkira Hatanaka                                               uint64_t Address,
15371928e68SAkira Hatanaka                                               const void *Decoder);
15471928e68SAkira Hatanaka 
15500fcf2e1SAkira Hatanaka static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst,
156ecabd1a5SAkira Hatanaka                                                 unsigned RegNo,
157ecabd1a5SAkira Hatanaka                                                 uint64_t Address,
158ecabd1a5SAkira Hatanaka                                                 const void *Decoder);
159ecabd1a5SAkira Hatanaka 
1608002a3f6SAkira Hatanaka static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst,
16159bfaf77SAkira Hatanaka                                                unsigned RegNo,
16259bfaf77SAkira Hatanaka                                                uint64_t Address,
16359bfaf77SAkira Hatanaka                                                const void *Decoder);
16459bfaf77SAkira Hatanaka 
1658002a3f6SAkira Hatanaka static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst,
16659bfaf77SAkira Hatanaka                                                unsigned RegNo,
16759bfaf77SAkira Hatanaka                                                uint64_t Address,
16859bfaf77SAkira Hatanaka                                                const void *Decoder);
16959bfaf77SAkira Hatanaka 
1703eb663b0SJack Carter static DecodeStatus DecodeMSA128BRegisterClass(MCInst &Inst,
1713eb663b0SJack Carter                                                unsigned RegNo,
1723eb663b0SJack Carter                                                uint64_t Address,
1733eb663b0SJack Carter                                                const void *Decoder);
1743eb663b0SJack Carter 
1755dc8ac92SJack Carter static DecodeStatus DecodeMSA128HRegisterClass(MCInst &Inst,
1765dc8ac92SJack Carter                                                unsigned RegNo,
1775dc8ac92SJack Carter                                                uint64_t Address,
1785dc8ac92SJack Carter                                                const void *Decoder);
1795dc8ac92SJack Carter 
1805dc8ac92SJack Carter static DecodeStatus DecodeMSA128WRegisterClass(MCInst &Inst,
1815dc8ac92SJack Carter                                                unsigned RegNo,
1825dc8ac92SJack Carter                                                uint64_t Address,
1835dc8ac92SJack Carter                                                const void *Decoder);
1845dc8ac92SJack Carter 
1855dc8ac92SJack Carter static DecodeStatus DecodeMSA128DRegisterClass(MCInst &Inst,
1865dc8ac92SJack Carter                                                unsigned RegNo,
1875dc8ac92SJack Carter                                                uint64_t Address,
1885dc8ac92SJack Carter                                                const void *Decoder);
1895dc8ac92SJack Carter 
190a591fdc6SMatheus Almeida static DecodeStatus DecodeMSACtrlRegisterClass(MCInst &Inst,
191a591fdc6SMatheus Almeida                                                unsigned RegNo,
192a591fdc6SMatheus Almeida                                                uint64_t Address,
193a591fdc6SMatheus Almeida                                                const void *Decoder);
194a591fdc6SMatheus Almeida 
195a3134faeSDaniel Sanders static DecodeStatus DecodeCOP0RegisterClass(MCInst &Inst,
196a3134faeSDaniel Sanders                                             unsigned RegNo,
197a3134faeSDaniel Sanders                                             uint64_t Address,
198a3134faeSDaniel Sanders                                             const void *Decoder);
199a3134faeSDaniel Sanders 
2002a83d680SDaniel Sanders static DecodeStatus DecodeCOP2RegisterClass(MCInst &Inst,
2012a83d680SDaniel Sanders                                             unsigned RegNo,
2022a83d680SDaniel Sanders                                             uint64_t Address,
2032a83d680SDaniel Sanders                                             const void *Decoder);
2042a83d680SDaniel Sanders 
20571928e68SAkira Hatanaka static DecodeStatus DecodeBranchTarget(MCInst &Inst,
20671928e68SAkira Hatanaka                                        unsigned Offset,
20771928e68SAkira Hatanaka                                        uint64_t Address,
20871928e68SAkira Hatanaka                                        const void *Decoder);
20971928e68SAkira Hatanaka 
2106f09cdfdSHrvoje Varga static DecodeStatus DecodeBranchTarget1SImm16(MCInst &Inst,
2116f09cdfdSHrvoje Varga                                               unsigned Offset,
2126f09cdfdSHrvoje Varga                                               uint64_t Address,
2136f09cdfdSHrvoje Varga                                               const void *Decoder);
2146f09cdfdSHrvoje Varga 
21571928e68SAkira Hatanaka static DecodeStatus DecodeJumpTarget(MCInst &Inst,
21671928e68SAkira Hatanaka                                      unsigned Insn,
21771928e68SAkira Hatanaka                                      uint64_t Address,
21871928e68SAkira Hatanaka                                      const void *Decoder);
21971928e68SAkira Hatanaka 
2203c8869dcSZoran Jovanovic static DecodeStatus DecodeBranchTarget21(MCInst &Inst,
2213c8869dcSZoran Jovanovic                                          unsigned Offset,
2223c8869dcSZoran Jovanovic                                          uint64_t Address,
2233c8869dcSZoran Jovanovic                                          const void *Decoder);
2243c8869dcSZoran Jovanovic 
22584e4d59eSZoran Jovanovic static DecodeStatus DecodeBranchTarget21MM(MCInst &Inst,
22684e4d59eSZoran Jovanovic                                            unsigned Offset,
22784e4d59eSZoran Jovanovic                                            uint64_t Address,
22884e4d59eSZoran Jovanovic                                            const void *Decoder);
22984e4d59eSZoran Jovanovic 
2303c8869dcSZoran Jovanovic static DecodeStatus DecodeBranchTarget26(MCInst &Inst,
2313c8869dcSZoran Jovanovic                                          unsigned Offset,
2323c8869dcSZoran Jovanovic                                          uint64_t Address,
2333c8869dcSZoran Jovanovic                                          const void *Decoder);
2343c8869dcSZoran Jovanovic 
2359761e96bSJozef Kolek // DecodeBranchTarget7MM - Decode microMIPS branch offset, which is
2369761e96bSJozef Kolek // shifted left by 1 bit.
2379761e96bSJozef Kolek static DecodeStatus DecodeBranchTarget7MM(MCInst &Inst,
2389761e96bSJozef Kolek                                           unsigned Offset,
2399761e96bSJozef Kolek                                           uint64_t Address,
2409761e96bSJozef Kolek                                           const void *Decoder);
2419761e96bSJozef Kolek 
2425cfebddeSJozef Kolek // DecodeBranchTarget10MM - Decode microMIPS branch offset, which is
2435cfebddeSJozef Kolek // shifted left by 1 bit.
2445cfebddeSJozef Kolek static DecodeStatus DecodeBranchTarget10MM(MCInst &Inst,
2455cfebddeSJozef Kolek                                            unsigned Offset,
2465cfebddeSJozef Kolek                                            uint64_t Address,
2475cfebddeSJozef Kolek                                            const void *Decoder);
2485cfebddeSJozef Kolek 
2498a80aa76SZoran Jovanovic // DecodeBranchTargetMM - Decode microMIPS branch offset, which is
2508a80aa76SZoran Jovanovic // shifted left by 1 bit.
2518a80aa76SZoran Jovanovic static DecodeStatus DecodeBranchTargetMM(MCInst &Inst,
2528a80aa76SZoran Jovanovic                                          unsigned Offset,
2538a80aa76SZoran Jovanovic                                          uint64_t Address,
2548a80aa76SZoran Jovanovic                                          const void *Decoder);
2558a80aa76SZoran Jovanovic 
256a887b361SZoran Jovanovic // DecodeBranchTarget26MM - Decode microMIPS branch offset, which is
257a887b361SZoran Jovanovic // shifted left by 1 bit.
258a887b361SZoran Jovanovic static DecodeStatus DecodeBranchTarget26MM(MCInst &Inst,
259a887b361SZoran Jovanovic                                            unsigned Offset,
260a887b361SZoran Jovanovic                                            uint64_t Address,
261a887b361SZoran Jovanovic                                            const void *Decoder);
262a887b361SZoran Jovanovic 
263507e084aSZoran Jovanovic // DecodeJumpTargetMM - Decode microMIPS jump target, which is
264507e084aSZoran Jovanovic // shifted left by 1 bit.
265507e084aSZoran Jovanovic static DecodeStatus DecodeJumpTargetMM(MCInst &Inst,
266507e084aSZoran Jovanovic                                        unsigned Insn,
267507e084aSZoran Jovanovic                                        uint64_t Address,
268507e084aSZoran Jovanovic                                        const void *Decoder);
269507e084aSZoran Jovanovic 
27071928e68SAkira Hatanaka static DecodeStatus DecodeMem(MCInst &Inst,
27171928e68SAkira Hatanaka                               unsigned Insn,
27271928e68SAkira Hatanaka                               uint64_t Address,
27371928e68SAkira Hatanaka                               const void *Decoder);
27471928e68SAkira Hatanaka 
275e4e83a7bSDaniel Sanders static DecodeStatus DecodeMemEVA(MCInst &Inst,
276e4e83a7bSDaniel Sanders                                  unsigned Insn,
277e4e83a7bSDaniel Sanders                                  uint64_t Address,
278e4e83a7bSDaniel Sanders                                  const void *Decoder);
279e4e83a7bSDaniel Sanders 
2803c88fbd3SHrvoje Varga static DecodeStatus DecodeLoadByte15(MCInst &Inst,
2813c88fbd3SHrvoje Varga                                      unsigned Insn,
2823c88fbd3SHrvoje Varga                                      uint64_t Address,
2833c88fbd3SHrvoje Varga                                      const void *Decoder);
2843c88fbd3SHrvoje Varga 
28579220eaeSEugene Zelenko static DecodeStatus DecodeCacheOp(MCInst &Inst, unsigned Insn, uint64_t Address,
28692db6b78SDaniel Sanders                                   const void *Decoder);
28792db6b78SDaniel Sanders 
288e4e83a7bSDaniel Sanders static DecodeStatus DecodeCacheeOp_CacheOpR6(MCInst &Inst,
289df464ae2SVladimir Medic                                              unsigned Insn,
290df464ae2SVladimir Medic                                              uint64_t Address,
291df464ae2SVladimir Medic                                              const void *Decoder);
292df464ae2SVladimir Medic 
293ab6d1cceSJozef Kolek static DecodeStatus DecodeCacheOpMM(MCInst &Inst,
294ab6d1cceSJozef Kolek                                     unsigned Insn,
295ab6d1cceSJozef Kolek                                     uint64_t Address,
296ab6d1cceSJozef Kolek                                     const void *Decoder);
297ab6d1cceSJozef Kolek 
298d9790793SZoran Jovanovic static DecodeStatus DecodePrefeOpMM(MCInst &Inst,
299d9790793SZoran Jovanovic                                     unsigned Insn,
300d9790793SZoran Jovanovic                                     uint64_t Address,
301d9790793SZoran Jovanovic                                     const void *Decoder);
302d9790793SZoran Jovanovic 
303b4484d62SDaniel Sanders static DecodeStatus DecodeSyncI(MCInst &Inst,
304b4484d62SDaniel Sanders                                 unsigned Insn,
305b4484d62SDaniel Sanders                                 uint64_t Address,
306b4484d62SDaniel Sanders                                 const void *Decoder);
307b4484d62SDaniel Sanders 
308eac9301cSSimon Dardis static DecodeStatus DecodeSyncI_MM(MCInst &Inst,
309eac9301cSSimon Dardis                                    unsigned Insn,
310eac9301cSSimon Dardis                                    uint64_t Address,
311eac9301cSSimon Dardis                                    const void *Decoder);
312eac9301cSSimon Dardis 
31318148671SHrvoje Varga static DecodeStatus DecodeSynciR6(MCInst &Inst,
31418148671SHrvoje Varga                                   unsigned Insn,
31518148671SHrvoje Varga                                   uint64_t Address,
31618148671SHrvoje Varga                                   const void *Decoder);
31718148671SHrvoje Varga 
318fe0bf9f6SMatheus Almeida static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn,
319fe0bf9f6SMatheus Almeida                                     uint64_t Address, const void *Decoder);
320fe0bf9f6SMatheus Almeida 
321315e7ecaSJozef Kolek static DecodeStatus DecodeMemMMImm4(MCInst &Inst,
322315e7ecaSJozef Kolek                                     unsigned Insn,
323315e7ecaSJozef Kolek                                     uint64_t Address,
324315e7ecaSJozef Kolek                                     const void *Decoder);
325315e7ecaSJozef Kolek 
32612c6982bSJozef Kolek static DecodeStatus DecodeMemMMSPImm5Lsl2(MCInst &Inst,
32712c6982bSJozef Kolek                                           unsigned Insn,
32812c6982bSJozef Kolek                                           uint64_t Address,
32912c6982bSJozef Kolek                                           const void *Decoder);
33012c6982bSJozef Kolek 
331e10a02ecSJozef Kolek static DecodeStatus DecodeMemMMGPImm7Lsl2(MCInst &Inst,
332e10a02ecSJozef Kolek                                           unsigned Insn,
333e10a02ecSJozef Kolek                                           uint64_t Address,
334e10a02ecSJozef Kolek                                           const void *Decoder);
335e10a02ecSJozef Kolek 
336d68d424aSJozef Kolek static DecodeStatus DecodeMemMMReglistImm4Lsl2(MCInst &Inst,
337d68d424aSJozef Kolek                                                unsigned Insn,
338d68d424aSJozef Kolek                                                uint64_t Address,
339d68d424aSJozef Kolek                                                const void *Decoder);
340d68d424aSJozef Kolek 
341a6593ff6SZoran Jovanovic static DecodeStatus DecodeMemMMImm9(MCInst &Inst,
342a6593ff6SZoran Jovanovic                                     unsigned Insn,
343a6593ff6SZoran Jovanovic                                     uint64_t Address,
344a6593ff6SZoran Jovanovic                                     const void *Decoder);
345a6593ff6SZoran Jovanovic 
346dde3d582SVladimir Medic static DecodeStatus DecodeMemMMImm12(MCInst &Inst,
347dde3d582SVladimir Medic                                      unsigned Insn,
348dde3d582SVladimir Medic                                      uint64_t Address,
349dde3d582SVladimir Medic                                      const void *Decoder);
350dde3d582SVladimir Medic 
351dde3d582SVladimir Medic static DecodeStatus DecodeMemMMImm16(MCInst &Inst,
352dde3d582SVladimir Medic                                      unsigned Insn,
353dde3d582SVladimir Medic                                      uint64_t Address,
354dde3d582SVladimir Medic                                      const void *Decoder);
355dde3d582SVladimir Medic 
35671928e68SAkira Hatanaka static DecodeStatus DecodeFMem(MCInst &Inst, unsigned Insn,
35771928e68SAkira Hatanaka                                uint64_t Address,
35871928e68SAkira Hatanaka                                const void *Decoder);
35971928e68SAkira Hatanaka 
360cba9f80bSZlatko Buljan static DecodeStatus DecodeFMemMMR2(MCInst &Inst, unsigned Insn,
361cba9f80bSZlatko Buljan                                    uint64_t Address,
362cba9f80bSZlatko Buljan                                    const void *Decoder);
363cba9f80bSZlatko Buljan 
36479220eaeSEugene Zelenko static DecodeStatus DecodeFMem2(MCInst &Inst, unsigned Insn, uint64_t Address,
36592db6b78SDaniel Sanders                                 const void *Decoder);
36692db6b78SDaniel Sanders 
36779220eaeSEugene Zelenko static DecodeStatus DecodeFMem3(MCInst &Inst, unsigned Insn, uint64_t Address,
36892db6b78SDaniel Sanders                                 const void *Decoder);
36992db6b78SDaniel Sanders 
370435cf8a4SVladimir Medic static DecodeStatus DecodeFMemCop2R6(MCInst &Inst, unsigned Insn,
37179220eaeSEugene Zelenko                                      uint64_t Address, const void *Decoder);
372435cf8a4SVladimir Medic 
373cba9f80bSZlatko Buljan static DecodeStatus DecodeFMemCop2MMR6(MCInst &Inst, unsigned Insn,
374cba9f80bSZlatko Buljan                                        uint64_t Address,
375cba9f80bSZlatko Buljan                                        const void *Decoder);
376cba9f80bSZlatko Buljan 
3776a803f61SDaniel Sanders static DecodeStatus DecodeSpecial3LlSc(MCInst &Inst,
3786a803f61SDaniel Sanders                                        unsigned Insn,
3796a803f61SDaniel Sanders                                        uint64_t Address,
3806a803f61SDaniel Sanders                                        const void *Decoder);
3816a803f61SDaniel Sanders 
382aa2b9278SJozef Kolek static DecodeStatus DecodeAddiur2Simm7(MCInst &Inst,
383aa2b9278SJozef Kolek                                        unsigned Value,
384aa2b9278SJozef Kolek                                        uint64_t Address,
385aa2b9278SJozef Kolek                                        const void *Decoder);
386aa2b9278SJozef Kolek 
38797297770SDaniel Sanders static DecodeStatus DecodeLi16Imm(MCInst &Inst,
388aa2b9278SJozef Kolek                                   unsigned Value,
389aa2b9278SJozef Kolek                                   uint64_t Address,
390aa2b9278SJozef Kolek                                   const void *Decoder);
391aa2b9278SJozef Kolek 
3926b28f09dSZoran Jovanovic static DecodeStatus DecodePOOL16BEncodedField(MCInst &Inst,
3936b28f09dSZoran Jovanovic                                               unsigned Value,
3946b28f09dSZoran Jovanovic                                               uint64_t Address,
3956b28f09dSZoran Jovanovic                                               const void *Decoder);
3966b28f09dSZoran Jovanovic 
39719b7f76aSDaniel Sanders template <unsigned Bits, int Offset, int Scale>
39819b7f76aSDaniel Sanders static DecodeStatus DecodeUImmWithOffsetAndScale(MCInst &Inst, unsigned Value,
39919b7f76aSDaniel Sanders                                                  uint64_t Address,
40019b7f76aSDaniel Sanders                                                  const void *Decoder);
40119b7f76aSDaniel Sanders 
402ea4f653dSDaniel Sanders template <unsigned Bits, int Offset>
403ea4f653dSDaniel Sanders static DecodeStatus DecodeUImmWithOffset(MCInst &Inst, unsigned Value,
40419b7f76aSDaniel Sanders                                          uint64_t Address,
40519b7f76aSDaniel Sanders                                          const void *Decoder) {
40619b7f76aSDaniel Sanders   return DecodeUImmWithOffsetAndScale<Bits, Offset, 1>(Inst, Value, Address,
40719b7f76aSDaniel Sanders                                                        Decoder);
40819b7f76aSDaniel Sanders }
409779c5937SMatheus Almeida 
41097297770SDaniel Sanders template <unsigned Bits, int Offset = 0, int ScaleBy = 1>
41197297770SDaniel Sanders static DecodeStatus DecodeSImmWithOffsetAndScale(MCInst &Inst, unsigned Value,
41297297770SDaniel Sanders                                                  uint64_t Address,
41397297770SDaniel Sanders                                                  const void *Decoder);
41478e89020SDaniel Sanders 
41571928e68SAkira Hatanaka static DecodeStatus DecodeInsSize(MCInst &Inst,
41671928e68SAkira Hatanaka                                   unsigned Insn,
41771928e68SAkira Hatanaka                                   uint64_t Address,
41871928e68SAkira Hatanaka                                   const void *Decoder);
41971928e68SAkira Hatanaka 
420b59e1a41SDaniel Sanders static DecodeStatus DecodeSimm19Lsl2(MCInst &Inst, unsigned Insn,
421b59e1a41SDaniel Sanders                                      uint64_t Address, const void *Decoder);
422b59e1a41SDaniel Sanders 
4232855142aSZoran Jovanovic static DecodeStatus DecodeSimm18Lsl3(MCInst &Inst, unsigned Insn,
4242855142aSZoran Jovanovic                                      uint64_t Address, const void *Decoder);
4252855142aSZoran Jovanovic 
426b682ddf3SVladimir Medic static DecodeStatus DecodeSimm9SP(MCInst &Inst, unsigned Insn,
427b682ddf3SVladimir Medic                                   uint64_t Address, const void *Decoder);
428b682ddf3SVladimir Medic 
429b682ddf3SVladimir Medic static DecodeStatus DecodeANDI16Imm(MCInst &Inst, unsigned Insn,
430b682ddf3SVladimir Medic                                     uint64_t Address, const void *Decoder);
431b682ddf3SVladimir Medic 
4322c6d7320SJozef Kolek static DecodeStatus DecodeSimm23Lsl2(MCInst &Inst, unsigned Insn,
4332c6d7320SJozef Kolek                                      uint64_t Address, const void *Decoder);
4342c6d7320SJozef Kolek 
435b50ccf8eSDaniel Sanders /// INSVE_[BHWD] have an implicit operand that the generated decoder doesn't
436b50ccf8eSDaniel Sanders /// handle.
437b50ccf8eSDaniel Sanders template <typename InsnType>
438b50ccf8eSDaniel Sanders static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address,
439b50ccf8eSDaniel Sanders                                    const void *Decoder);
4405c582b2fSDaniel Sanders 
4415c582b2fSDaniel Sanders template <typename InsnType>
442cf060794SSimon Dardis static DecodeStatus DecodeDAHIDATIMMR6(MCInst &MI, InsnType insn, uint64_t Address,
443cf060794SSimon Dardis                                    const void *Decoder);
444cf060794SSimon Dardis 
445cf060794SSimon Dardis template <typename InsnType>
446cf060794SSimon Dardis static DecodeStatus DecodeDAHIDATI(MCInst &MI, InsnType insn, uint64_t Address,
447cf060794SSimon Dardis                                    const void *Decoder);
448cf060794SSimon Dardis 
449cf060794SSimon Dardis template <typename InsnType>
450b3fd189cSSimon Dardis static DecodeStatus DecodeDAHIDATIMMR6(MCInst &MI, InsnType insn, uint64_t Address,
451b3fd189cSSimon Dardis                                    const void *Decoder);
452b3fd189cSSimon Dardis 
453b3fd189cSSimon Dardis template <typename InsnType>
454b3fd189cSSimon Dardis static DecodeStatus DecodeDAHIDATI(MCInst &MI, InsnType insn, uint64_t Address,
455b3fd189cSSimon Dardis                                    const void *Decoder);
456b3fd189cSSimon Dardis 
457b3fd189cSSimon Dardis template <typename InsnType>
4585c582b2fSDaniel Sanders static DecodeStatus
4595c582b2fSDaniel Sanders DecodeAddiGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
4605c582b2fSDaniel Sanders                       const void *Decoder);
4615c582b2fSDaniel Sanders 
4625c582b2fSDaniel Sanders template <typename InsnType>
4635c582b2fSDaniel Sanders static DecodeStatus
464c962c493SHrvoje Varga DecodePOP35GroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address,
465c962c493SHrvoje Varga                            const void *Decoder);
466c962c493SHrvoje Varga 
467c962c493SHrvoje Varga template <typename InsnType>
468c962c493SHrvoje Varga static DecodeStatus
4695c582b2fSDaniel Sanders DecodeDaddiGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
4705c582b2fSDaniel Sanders                        const void *Decoder);
4715c582b2fSDaniel Sanders 
4725c582b2fSDaniel Sanders template <typename InsnType>
4735c582b2fSDaniel Sanders static DecodeStatus
474c962c493SHrvoje Varga DecodePOP37GroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address,
475c962c493SHrvoje Varga                            const void *Decoder);
476c962c493SHrvoje Varga 
477c962c493SHrvoje Varga template <typename InsnType>
478c962c493SHrvoje Varga static DecodeStatus
479f0ed16eaSHrvoje Varga DecodePOP65GroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address,
480f0ed16eaSHrvoje Varga                            const void *Decoder);
481f0ed16eaSHrvoje Varga 
482f0ed16eaSHrvoje Varga template <typename InsnType>
483f0ed16eaSHrvoje Varga static DecodeStatus
484f0ed16eaSHrvoje Varga DecodePOP75GroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address,
485f0ed16eaSHrvoje Varga                            const void *Decoder);
486f0ed16eaSHrvoje Varga 
487f0ed16eaSHrvoje Varga template <typename InsnType>
488f0ed16eaSHrvoje Varga static DecodeStatus
4895c582b2fSDaniel Sanders DecodeBlezlGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
4905c582b2fSDaniel Sanders                        const void *Decoder);
4915c582b2fSDaniel Sanders 
4925c582b2fSDaniel Sanders template <typename InsnType>
4935c582b2fSDaniel Sanders static DecodeStatus
4945c582b2fSDaniel Sanders DecodeBgtzlGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
4955c582b2fSDaniel Sanders                        const void *Decoder);
4965c582b2fSDaniel Sanders 
4975c582b2fSDaniel Sanders template <typename InsnType>
4985c582b2fSDaniel Sanders static DecodeStatus
4995c582b2fSDaniel Sanders DecodeBgtzGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
5005c582b2fSDaniel Sanders                       const void *Decoder);
5015c582b2fSDaniel Sanders 
50228a0ca07SZoran Jovanovic template <typename InsnType>
50328a0ca07SZoran Jovanovic static DecodeStatus
50428a0ca07SZoran Jovanovic DecodeBlezGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
50528a0ca07SZoran Jovanovic                        const void *Decoder);
50628a0ca07SZoran Jovanovic 
507fdbd0a37SZoran Jovanovic template <typename InsnType>
508fdbd0a37SZoran Jovanovic static DecodeStatus
509fdbd0a37SZoran Jovanovic DecodeBgtzGroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address,
510fdbd0a37SZoran Jovanovic                           const void *Decoder);
511fdbd0a37SZoran Jovanovic 
512fdbd0a37SZoran Jovanovic template <typename InsnType>
513fdbd0a37SZoran Jovanovic static DecodeStatus
514fdbd0a37SZoran Jovanovic DecodeBlezGroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address,
515fdbd0a37SZoran Jovanovic                           const void *Decoder);
516fdbd0a37SZoran Jovanovic 
5176f83ae38SSimon Dardis template <typename InsnType>
5186f83ae38SSimon Dardis static DecodeStatus DecodeDINS(MCInst &MI, InsnType Insn, uint64_t Address,
5196f83ae38SSimon Dardis                                const void *Decoder);
5206f83ae38SSimon Dardis 
52155e44673SSimon Dardis template <typename InsnType>
52255e44673SSimon Dardis static DecodeStatus DecodeDEXT(MCInst &MI, InsnType Insn, uint64_t Address,
52355e44673SSimon Dardis                                const void *Decoder);
52455e44673SSimon Dardis 
5253408caf6SPetar Jovanovic template <typename InsnType>
5263408caf6SPetar Jovanovic static DecodeStatus DecodeCRC(MCInst &MI, InsnType Insn, uint64_t Address,
5273408caf6SPetar Jovanovic                               const void *Decoder);
5283408caf6SPetar Jovanovic 
529a4c4b5fcSZoran Jovanovic static DecodeStatus DecodeRegListOperand(MCInst &Inst, unsigned Insn,
530a4c4b5fcSZoran Jovanovic                                          uint64_t Address,
531a4c4b5fcSZoran Jovanovic                                          const void *Decoder);
532a4c4b5fcSZoran Jovanovic 
533f9a02500SZoran Jovanovic static DecodeStatus DecodeRegListOperand16(MCInst &Inst, unsigned Insn,
534f9a02500SZoran Jovanovic                                            uint64_t Address,
535f9a02500SZoran Jovanovic                                            const void *Decoder);
536f9a02500SZoran Jovanovic 
537169df4e2SSimon Dardis static DecodeStatus DecodeMovePRegPair(MCInst &Inst, unsigned RegPair,
53841688679SZoran Jovanovic                                        uint64_t Address,
53941688679SZoran Jovanovic                                        const void *Decoder);
54041688679SZoran Jovanovic 
54171928e68SAkira Hatanaka namespace llvm {
542926883e1SEugene Zelenko 
543f42454b9SMehdi Amini Target &getTheMipselTarget();
544f42454b9SMehdi Amini Target &getTheMipsTarget();
545f42454b9SMehdi Amini Target &getTheMips64Target();
546f42454b9SMehdi Amini Target &getTheMips64elTarget();
547926883e1SEugene Zelenko 
548926883e1SEugene Zelenko } // end namespace llvm
54971928e68SAkira Hatanaka 
55071928e68SAkira Hatanaka static MCDisassembler *createMipsDisassembler(
55171928e68SAkira Hatanaka                        const Target &T,
552a1bc0f56SLang Hames                        const MCSubtargetInfo &STI,
553a1bc0f56SLang Hames                        MCContext &Ctx) {
554a1bc0f56SLang Hames   return new MipsDisassembler(STI, Ctx, true);
55571928e68SAkira Hatanaka }
55671928e68SAkira Hatanaka 
55771928e68SAkira Hatanaka static MCDisassembler *createMipselDisassembler(
55871928e68SAkira Hatanaka                        const Target &T,
559a1bc0f56SLang Hames                        const MCSubtargetInfo &STI,
560a1bc0f56SLang Hames                        MCContext &Ctx) {
561a1bc0f56SLang Hames   return new MipsDisassembler(STI, Ctx, false);
56271928e68SAkira Hatanaka }
56371928e68SAkira Hatanaka 
56471928e68SAkira Hatanaka extern "C" void LLVMInitializeMipsDisassembler() {
56571928e68SAkira Hatanaka   // Register the disassembler.
566f42454b9SMehdi Amini   TargetRegistry::RegisterMCDisassembler(getTheMipsTarget(),
56771928e68SAkira Hatanaka                                          createMipsDisassembler);
568f42454b9SMehdi Amini   TargetRegistry::RegisterMCDisassembler(getTheMipselTarget(),
56971928e68SAkira Hatanaka                                          createMipselDisassembler);
570f42454b9SMehdi Amini   TargetRegistry::RegisterMCDisassembler(getTheMips64Target(),
571a19216c8SDaniel Sanders                                          createMipsDisassembler);
572f42454b9SMehdi Amini   TargetRegistry::RegisterMCDisassembler(getTheMips64elTarget(),
573a19216c8SDaniel Sanders                                          createMipselDisassembler);
57471928e68SAkira Hatanaka }
57571928e68SAkira Hatanaka 
57671928e68SAkira Hatanaka #include "MipsGenDisassemblerTables.inc"
57771928e68SAkira Hatanaka 
5785c582b2fSDaniel Sanders static unsigned getReg(const void *D, unsigned RC, unsigned RegNo) {
579a19216c8SDaniel Sanders   const MipsDisassembler *Dis = static_cast<const MipsDisassembler*>(D);
5805c582b2fSDaniel Sanders   const MCRegisterInfo *RegInfo = Dis->getContext().getRegisterInfo();
5815c582b2fSDaniel Sanders   return *(RegInfo->getRegClass(RC).begin() + RegNo);
5825c582b2fSDaniel Sanders }
5835c582b2fSDaniel Sanders 
584b50ccf8eSDaniel Sanders template <typename InsnType>
585b50ccf8eSDaniel Sanders static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address,
586b50ccf8eSDaniel Sanders                                    const void *Decoder) {
58779220eaeSEugene Zelenko   using DecodeFN = DecodeStatus (*)(MCInst &, unsigned, uint64_t, const void *);
58879220eaeSEugene Zelenko 
589b50ccf8eSDaniel Sanders   // The size of the n field depends on the element size
590b50ccf8eSDaniel Sanders   // The register class also depends on this.
591b50ccf8eSDaniel Sanders   InsnType tmp = fieldFromInstruction(insn, 17, 5);
592b50ccf8eSDaniel Sanders   unsigned NSize = 0;
593b50ccf8eSDaniel Sanders   DecodeFN RegDecoder = nullptr;
594b50ccf8eSDaniel Sanders   if ((tmp & 0x18) == 0x00) { // INSVE_B
595b50ccf8eSDaniel Sanders     NSize = 4;
596b50ccf8eSDaniel Sanders     RegDecoder = DecodeMSA128BRegisterClass;
597b50ccf8eSDaniel Sanders   } else if ((tmp & 0x1c) == 0x10) { // INSVE_H
598b50ccf8eSDaniel Sanders     NSize = 3;
599b50ccf8eSDaniel Sanders     RegDecoder = DecodeMSA128HRegisterClass;
600b50ccf8eSDaniel Sanders   } else if ((tmp & 0x1e) == 0x18) { // INSVE_W
601b50ccf8eSDaniel Sanders     NSize = 2;
602b50ccf8eSDaniel Sanders     RegDecoder = DecodeMSA128WRegisterClass;
603b50ccf8eSDaniel Sanders   } else if ((tmp & 0x1f) == 0x1c) { // INSVE_D
604b50ccf8eSDaniel Sanders     NSize = 1;
605b50ccf8eSDaniel Sanders     RegDecoder = DecodeMSA128DRegisterClass;
606b50ccf8eSDaniel Sanders   } else
607b50ccf8eSDaniel Sanders     llvm_unreachable("Invalid encoding");
608b50ccf8eSDaniel Sanders 
609b50ccf8eSDaniel Sanders   assert(NSize != 0 && RegDecoder != nullptr);
610b50ccf8eSDaniel Sanders 
611b50ccf8eSDaniel Sanders   // $wd
612b50ccf8eSDaniel Sanders   tmp = fieldFromInstruction(insn, 6, 5);
613b50ccf8eSDaniel Sanders   if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
614b50ccf8eSDaniel Sanders     return MCDisassembler::Fail;
615b50ccf8eSDaniel Sanders   // $wd_in
616b50ccf8eSDaniel Sanders   if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
617b50ccf8eSDaniel Sanders     return MCDisassembler::Fail;
618b50ccf8eSDaniel Sanders   // $n
619b50ccf8eSDaniel Sanders   tmp = fieldFromInstruction(insn, 16, NSize);
620e9119e41SJim Grosbach   MI.addOperand(MCOperand::createImm(tmp));
621b50ccf8eSDaniel Sanders   // $ws
622b50ccf8eSDaniel Sanders   tmp = fieldFromInstruction(insn, 11, 5);
623b50ccf8eSDaniel Sanders   if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
624b50ccf8eSDaniel Sanders     return MCDisassembler::Fail;
625b50ccf8eSDaniel Sanders   // $n2
626e9119e41SJim Grosbach   MI.addOperand(MCOperand::createImm(0));
627b50ccf8eSDaniel Sanders 
628b50ccf8eSDaniel Sanders   return MCDisassembler::Success;
629b50ccf8eSDaniel Sanders }
630b50ccf8eSDaniel Sanders 
6315c582b2fSDaniel Sanders template <typename InsnType>
632cf060794SSimon Dardis static DecodeStatus DecodeDAHIDATIMMR6(MCInst &MI, InsnType insn, uint64_t Address,
633cf060794SSimon Dardis                                const void *Decoder) {
634b3fd189cSSimon Dardis   InsnType Rs = fieldFromInstruction(insn, 16, 5);
635cf060794SSimon Dardis   InsnType Imm = fieldFromInstruction(insn, 0, 16);
636cf060794SSimon Dardis   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID,
637b3fd189cSSimon Dardis                                        Rs)));
638cf060794SSimon Dardis   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID,
639b3fd189cSSimon Dardis                                        Rs)));
640cf060794SSimon Dardis   MI.addOperand(MCOperand::createImm(Imm));
641cf060794SSimon Dardis 
642cf060794SSimon Dardis   return MCDisassembler::Success;
643cf060794SSimon Dardis }
644cf060794SSimon Dardis 
645cf060794SSimon Dardis template <typename InsnType>
646cf060794SSimon Dardis static DecodeStatus DecodeDAHIDATI(MCInst &MI, InsnType insn, uint64_t Address,
647cf060794SSimon Dardis                                const void *Decoder) {
648b3fd189cSSimon Dardis   InsnType Rs = fieldFromInstruction(insn, 21, 5);
649cf060794SSimon Dardis   InsnType Imm = fieldFromInstruction(insn, 0, 16);
650cf060794SSimon Dardis   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID,
651b3fd189cSSimon Dardis                                        Rs)));
652cf060794SSimon Dardis   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID,
653b3fd189cSSimon Dardis                                        Rs)));
654cf060794SSimon Dardis   MI.addOperand(MCOperand::createImm(Imm));
655cf060794SSimon Dardis 
656cf060794SSimon Dardis   return MCDisassembler::Success;
657cf060794SSimon Dardis }
658cf060794SSimon Dardis 
659cf060794SSimon Dardis template <typename InsnType>
6605c582b2fSDaniel Sanders static DecodeStatus DecodeAddiGroupBranch(MCInst &MI, InsnType insn,
6615c582b2fSDaniel Sanders                                           uint64_t Address,
6625c582b2fSDaniel Sanders                                           const void *Decoder) {
6635c582b2fSDaniel Sanders   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
6645c582b2fSDaniel Sanders   // (otherwise we would have matched the ADDI instruction from the earlier
6655c582b2fSDaniel Sanders   // ISA's instead).
6665c582b2fSDaniel Sanders   //
6675c582b2fSDaniel Sanders   // We have:
6685c582b2fSDaniel Sanders   //    0b001000 sssss ttttt iiiiiiiiiiiiiiii
6695c582b2fSDaniel Sanders   //      BOVC if rs >= rt
6705c582b2fSDaniel Sanders   //      BEQZALC if rs == 0 && rt != 0
6715c582b2fSDaniel Sanders   //      BEQC if rs < rt && rs != 0
6725c582b2fSDaniel Sanders 
6735c582b2fSDaniel Sanders   InsnType Rs = fieldFromInstruction(insn, 21, 5);
6745c582b2fSDaniel Sanders   InsnType Rt = fieldFromInstruction(insn, 16, 5);
675672c710dSSagar Thakur   int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
6765c582b2fSDaniel Sanders   bool HasRs = false;
6775c582b2fSDaniel Sanders 
6785c582b2fSDaniel Sanders   if (Rs >= Rt) {
6795c582b2fSDaniel Sanders     MI.setOpcode(Mips::BOVC);
6805c582b2fSDaniel Sanders     HasRs = true;
6815c582b2fSDaniel Sanders   } else if (Rs != 0 && Rs < Rt) {
6825c582b2fSDaniel Sanders     MI.setOpcode(Mips::BEQC);
6835c582b2fSDaniel Sanders     HasRs = true;
6845c582b2fSDaniel Sanders   } else
6855c582b2fSDaniel Sanders     MI.setOpcode(Mips::BEQZALC);
6865c582b2fSDaniel Sanders 
6875c582b2fSDaniel Sanders   if (HasRs)
688e9119e41SJim Grosbach     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
6895c582b2fSDaniel Sanders                                        Rs)));
6905c582b2fSDaniel Sanders 
691e9119e41SJim Grosbach   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
6925c582b2fSDaniel Sanders                                      Rt)));
693e9119e41SJim Grosbach   MI.addOperand(MCOperand::createImm(Imm));
6945c582b2fSDaniel Sanders 
6955c582b2fSDaniel Sanders   return MCDisassembler::Success;
6965c582b2fSDaniel Sanders }
6975c582b2fSDaniel Sanders 
6985c582b2fSDaniel Sanders template <typename InsnType>
699c962c493SHrvoje Varga static DecodeStatus DecodePOP35GroupBranchMMR6(MCInst &MI, InsnType insn,
700c962c493SHrvoje Varga                                                uint64_t Address,
701c962c493SHrvoje Varga                                                const void *Decoder) {
702c962c493SHrvoje Varga   InsnType Rt = fieldFromInstruction(insn, 21, 5);
703c962c493SHrvoje Varga   InsnType Rs = fieldFromInstruction(insn, 16, 5);
704f0ed16eaSHrvoje Varga   int64_t Imm = 0;
705c962c493SHrvoje Varga 
706c962c493SHrvoje Varga   if (Rs >= Rt) {
707c962c493SHrvoje Varga     MI.setOpcode(Mips::BOVC_MMR6);
708c962c493SHrvoje Varga     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
709c962c493SHrvoje Varga                                        Rt)));
710c962c493SHrvoje Varga     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
711c962c493SHrvoje Varga                                        Rs)));
712f0ed16eaSHrvoje Varga     Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
713c962c493SHrvoje Varga   } else if (Rs != 0 && Rs < Rt) {
714c962c493SHrvoje Varga     MI.setOpcode(Mips::BEQC_MMR6);
715c962c493SHrvoje Varga     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
716c962c493SHrvoje Varga                                        Rs)));
717c962c493SHrvoje Varga     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
718c962c493SHrvoje Varga                                        Rt)));
719f0ed16eaSHrvoje Varga     Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
720c962c493SHrvoje Varga   } else {
721c962c493SHrvoje Varga     MI.setOpcode(Mips::BEQZALC_MMR6);
722c962c493SHrvoje Varga     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
723c962c493SHrvoje Varga                                        Rt)));
724f0ed16eaSHrvoje Varga     Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
725c962c493SHrvoje Varga   }
726c962c493SHrvoje Varga 
727c962c493SHrvoje Varga   MI.addOperand(MCOperand::createImm(Imm));
728c962c493SHrvoje Varga 
729c962c493SHrvoje Varga   return MCDisassembler::Success;
730c962c493SHrvoje Varga }
731c962c493SHrvoje Varga 
732c962c493SHrvoje Varga template <typename InsnType>
7335c582b2fSDaniel Sanders static DecodeStatus DecodeDaddiGroupBranch(MCInst &MI, InsnType insn,
7345c582b2fSDaniel Sanders                                            uint64_t Address,
7355c582b2fSDaniel Sanders                                            const void *Decoder) {
7365c582b2fSDaniel Sanders   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
7375c582b2fSDaniel Sanders   // (otherwise we would have matched the ADDI instruction from the earlier
7385c582b2fSDaniel Sanders   // ISA's instead).
7395c582b2fSDaniel Sanders   //
7405c582b2fSDaniel Sanders   // We have:
7415c582b2fSDaniel Sanders   //    0b011000 sssss ttttt iiiiiiiiiiiiiiii
7425c582b2fSDaniel Sanders   //      BNVC if rs >= rt
7435c582b2fSDaniel Sanders   //      BNEZALC if rs == 0 && rt != 0
7445c582b2fSDaniel Sanders   //      BNEC if rs < rt && rs != 0
7455c582b2fSDaniel Sanders 
7465c582b2fSDaniel Sanders   InsnType Rs = fieldFromInstruction(insn, 21, 5);
7475c582b2fSDaniel Sanders   InsnType Rt = fieldFromInstruction(insn, 16, 5);
748672c710dSSagar Thakur   int64_t  Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
7495c582b2fSDaniel Sanders   bool HasRs = false;
7505c582b2fSDaniel Sanders 
7515c582b2fSDaniel Sanders   if (Rs >= Rt) {
7525c582b2fSDaniel Sanders     MI.setOpcode(Mips::BNVC);
7535c582b2fSDaniel Sanders     HasRs = true;
7545c582b2fSDaniel Sanders   } else if (Rs != 0 && Rs < Rt) {
7555c582b2fSDaniel Sanders     MI.setOpcode(Mips::BNEC);
7565c582b2fSDaniel Sanders     HasRs = true;
7575c582b2fSDaniel Sanders   } else
7585c582b2fSDaniel Sanders     MI.setOpcode(Mips::BNEZALC);
7595c582b2fSDaniel Sanders 
7605c582b2fSDaniel Sanders   if (HasRs)
761e9119e41SJim Grosbach     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
7625c582b2fSDaniel Sanders                                        Rs)));
7635c582b2fSDaniel Sanders 
764e9119e41SJim Grosbach   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
7655c582b2fSDaniel Sanders                                      Rt)));
766e9119e41SJim Grosbach   MI.addOperand(MCOperand::createImm(Imm));
7675c582b2fSDaniel Sanders 
7685c582b2fSDaniel Sanders   return MCDisassembler::Success;
7695c582b2fSDaniel Sanders }
7705c582b2fSDaniel Sanders 
7715c582b2fSDaniel Sanders template <typename InsnType>
772c962c493SHrvoje Varga static DecodeStatus DecodePOP37GroupBranchMMR6(MCInst &MI, InsnType insn,
773c962c493SHrvoje Varga                                                uint64_t Address,
774c962c493SHrvoje Varga                                                const void *Decoder) {
775c962c493SHrvoje Varga   InsnType Rt = fieldFromInstruction(insn, 21, 5);
776c962c493SHrvoje Varga   InsnType Rs = fieldFromInstruction(insn, 16, 5);
777f0ed16eaSHrvoje Varga   int64_t Imm = 0;
778c962c493SHrvoje Varga 
779c962c493SHrvoje Varga   if (Rs >= Rt) {
780c962c493SHrvoje Varga     MI.setOpcode(Mips::BNVC_MMR6);
781c962c493SHrvoje Varga     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
782c962c493SHrvoje Varga                                        Rt)));
783c962c493SHrvoje Varga     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
784c962c493SHrvoje Varga                                        Rs)));
785f0ed16eaSHrvoje Varga     Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
786c962c493SHrvoje Varga   } else if (Rs != 0 && Rs < Rt) {
787c962c493SHrvoje Varga     MI.setOpcode(Mips::BNEC_MMR6);
788c962c493SHrvoje Varga     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
789c962c493SHrvoje Varga                                        Rs)));
790c962c493SHrvoje Varga     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
791c962c493SHrvoje Varga                                        Rt)));
792f0ed16eaSHrvoje Varga     Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
793c962c493SHrvoje Varga   } else {
794c962c493SHrvoje Varga     MI.setOpcode(Mips::BNEZALC_MMR6);
795c962c493SHrvoje Varga     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
796c962c493SHrvoje Varga                                        Rt)));
797f0ed16eaSHrvoje Varga     Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
798c962c493SHrvoje Varga   }
799c962c493SHrvoje Varga 
800c962c493SHrvoje Varga   MI.addOperand(MCOperand::createImm(Imm));
801c962c493SHrvoje Varga 
802c962c493SHrvoje Varga   return MCDisassembler::Success;
803c962c493SHrvoje Varga }
804c962c493SHrvoje Varga 
805c962c493SHrvoje Varga template <typename InsnType>
806f0ed16eaSHrvoje Varga static DecodeStatus DecodePOP65GroupBranchMMR6(MCInst &MI, InsnType insn,
807f0ed16eaSHrvoje Varga                                                uint64_t Address,
808f0ed16eaSHrvoje Varga                                                const void *Decoder) {
809f0ed16eaSHrvoje Varga   // We have:
810f0ed16eaSHrvoje Varga   //    0b110101 ttttt sssss iiiiiiiiiiiiiiii
811f0ed16eaSHrvoje Varga   //      Invalid if rt == 0
812f0ed16eaSHrvoje Varga   //      BGTZC_MMR6   if rs == 0  && rt != 0
813f0ed16eaSHrvoje Varga   //      BLTZC_MMR6   if rs == rt && rt != 0
814f0ed16eaSHrvoje Varga   //      BLTC_MMR6    if rs != rt && rs != 0  && rt != 0
815f0ed16eaSHrvoje Varga 
816f0ed16eaSHrvoje Varga   InsnType Rt = fieldFromInstruction(insn, 21, 5);
817f0ed16eaSHrvoje Varga   InsnType Rs = fieldFromInstruction(insn, 16, 5);
818f0ed16eaSHrvoje Varga   int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
819f0ed16eaSHrvoje Varga   bool HasRs = false;
820f0ed16eaSHrvoje Varga 
821f0ed16eaSHrvoje Varga   if (Rt == 0)
822f0ed16eaSHrvoje Varga     return MCDisassembler::Fail;
823f0ed16eaSHrvoje Varga   else if (Rs == 0)
824f0ed16eaSHrvoje Varga     MI.setOpcode(Mips::BGTZC_MMR6);
825f0ed16eaSHrvoje Varga   else if (Rs == Rt)
826f0ed16eaSHrvoje Varga     MI.setOpcode(Mips::BLTZC_MMR6);
827f0ed16eaSHrvoje Varga   else {
828f0ed16eaSHrvoje Varga     MI.setOpcode(Mips::BLTC_MMR6);
829f0ed16eaSHrvoje Varga     HasRs = true;
830f0ed16eaSHrvoje Varga   }
831f0ed16eaSHrvoje Varga 
832f0ed16eaSHrvoje Varga   if (HasRs)
833f0ed16eaSHrvoje Varga     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
834f0ed16eaSHrvoje Varga                                               Rs)));
835f0ed16eaSHrvoje Varga 
836f0ed16eaSHrvoje Varga   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
837f0ed16eaSHrvoje Varga                                      Rt)));
838f0ed16eaSHrvoje Varga 
839f0ed16eaSHrvoje Varga   MI.addOperand(MCOperand::createImm(Imm));
840f0ed16eaSHrvoje Varga 
841f0ed16eaSHrvoje Varga   return MCDisassembler::Success;
842f0ed16eaSHrvoje Varga }
843f0ed16eaSHrvoje Varga 
844f0ed16eaSHrvoje Varga template <typename InsnType>
845f0ed16eaSHrvoje Varga static DecodeStatus DecodePOP75GroupBranchMMR6(MCInst &MI, InsnType insn,
846f0ed16eaSHrvoje Varga                                                uint64_t Address,
847f0ed16eaSHrvoje Varga                                                const void *Decoder) {
848f0ed16eaSHrvoje Varga   // We have:
849f0ed16eaSHrvoje Varga   //    0b111101 ttttt sssss iiiiiiiiiiiiiiii
850f0ed16eaSHrvoje Varga   //      Invalid if rt == 0
851f0ed16eaSHrvoje Varga   //      BLEZC_MMR6   if rs == 0  && rt != 0
852f0ed16eaSHrvoje Varga   //      BGEZC_MMR6   if rs == rt && rt != 0
853f0ed16eaSHrvoje Varga   //      BGEC_MMR6    if rs != rt && rs != 0  && rt != 0
854f0ed16eaSHrvoje Varga 
855f0ed16eaSHrvoje Varga   InsnType Rt = fieldFromInstruction(insn, 21, 5);
856f0ed16eaSHrvoje Varga   InsnType Rs = fieldFromInstruction(insn, 16, 5);
857f0ed16eaSHrvoje Varga   int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
858f0ed16eaSHrvoje Varga   bool HasRs = false;
859f0ed16eaSHrvoje Varga 
860f0ed16eaSHrvoje Varga   if (Rt == 0)
861f0ed16eaSHrvoje Varga     return MCDisassembler::Fail;
862f0ed16eaSHrvoje Varga   else if (Rs == 0)
863f0ed16eaSHrvoje Varga     MI.setOpcode(Mips::BLEZC_MMR6);
864f0ed16eaSHrvoje Varga   else if (Rs == Rt)
865f0ed16eaSHrvoje Varga     MI.setOpcode(Mips::BGEZC_MMR6);
866f0ed16eaSHrvoje Varga   else {
867f0ed16eaSHrvoje Varga     HasRs = true;
868f0ed16eaSHrvoje Varga     MI.setOpcode(Mips::BGEC_MMR6);
869f0ed16eaSHrvoje Varga   }
870f0ed16eaSHrvoje Varga 
871f0ed16eaSHrvoje Varga   if (HasRs)
872f0ed16eaSHrvoje Varga     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
873f0ed16eaSHrvoje Varga                                        Rs)));
874f0ed16eaSHrvoje Varga 
875f0ed16eaSHrvoje Varga   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
876f0ed16eaSHrvoje Varga                                      Rt)));
877f0ed16eaSHrvoje Varga 
878f0ed16eaSHrvoje Varga   MI.addOperand(MCOperand::createImm(Imm));
879f0ed16eaSHrvoje Varga 
880f0ed16eaSHrvoje Varga   return MCDisassembler::Success;
881f0ed16eaSHrvoje Varga }
882f0ed16eaSHrvoje Varga 
883f0ed16eaSHrvoje Varga template <typename InsnType>
8845c582b2fSDaniel Sanders static DecodeStatus DecodeBlezlGroupBranch(MCInst &MI, InsnType insn,
8855c582b2fSDaniel Sanders                                            uint64_t Address,
8865c582b2fSDaniel Sanders                                            const void *Decoder) {
8875c582b2fSDaniel Sanders   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
8885c582b2fSDaniel Sanders   // (otherwise we would have matched the BLEZL instruction from the earlier
8895c582b2fSDaniel Sanders   // ISA's instead).
8905c582b2fSDaniel Sanders   //
8915c582b2fSDaniel Sanders   // We have:
8925c582b2fSDaniel Sanders   //    0b010110 sssss ttttt iiiiiiiiiiiiiiii
8935c582b2fSDaniel Sanders   //      Invalid if rs == 0
8945c582b2fSDaniel Sanders   //      BLEZC   if rs == 0  && rt != 0
8955c582b2fSDaniel Sanders   //      BGEZC   if rs == rt && rt != 0
8965c582b2fSDaniel Sanders   //      BGEC    if rs != rt && rs != 0  && rt != 0
8975c582b2fSDaniel Sanders 
8985c582b2fSDaniel Sanders   InsnType Rs = fieldFromInstruction(insn, 21, 5);
8995c582b2fSDaniel Sanders   InsnType Rt = fieldFromInstruction(insn, 16, 5);
900672c710dSSagar Thakur   int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
90128a0ca07SZoran Jovanovic   bool HasRs = false;
9025c582b2fSDaniel Sanders 
9035c582b2fSDaniel Sanders   if (Rt == 0)
9045c582b2fSDaniel Sanders     return MCDisassembler::Fail;
9055c582b2fSDaniel Sanders   else if (Rs == 0)
9065c582b2fSDaniel Sanders     MI.setOpcode(Mips::BLEZC);
9075c582b2fSDaniel Sanders   else if (Rs == Rt)
9085c582b2fSDaniel Sanders     MI.setOpcode(Mips::BGEZC);
90928a0ca07SZoran Jovanovic   else {
91028a0ca07SZoran Jovanovic     HasRs = true;
91128a0ca07SZoran Jovanovic     MI.setOpcode(Mips::BGEC);
91228a0ca07SZoran Jovanovic   }
91328a0ca07SZoran Jovanovic 
91428a0ca07SZoran Jovanovic   if (HasRs)
915e9119e41SJim Grosbach     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
91628a0ca07SZoran Jovanovic                                        Rs)));
9175c582b2fSDaniel Sanders 
918e9119e41SJim Grosbach   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
9195c582b2fSDaniel Sanders                                      Rt)));
9205c582b2fSDaniel Sanders 
921e9119e41SJim Grosbach   MI.addOperand(MCOperand::createImm(Imm));
9225c582b2fSDaniel Sanders 
9235c582b2fSDaniel Sanders   return MCDisassembler::Success;
9245c582b2fSDaniel Sanders }
9255c582b2fSDaniel Sanders 
9265c582b2fSDaniel Sanders template <typename InsnType>
9275c582b2fSDaniel Sanders static DecodeStatus DecodeBgtzlGroupBranch(MCInst &MI, InsnType insn,
9285c582b2fSDaniel Sanders                                            uint64_t Address,
9295c582b2fSDaniel Sanders                                            const void *Decoder) {
9305c582b2fSDaniel Sanders   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
9315c582b2fSDaniel Sanders   // (otherwise we would have matched the BGTZL instruction from the earlier
9325c582b2fSDaniel Sanders   // ISA's instead).
9335c582b2fSDaniel Sanders   //
9345c582b2fSDaniel Sanders   // We have:
9355c582b2fSDaniel Sanders   //    0b010111 sssss ttttt iiiiiiiiiiiiiiii
9365c582b2fSDaniel Sanders   //      Invalid if rs == 0
9375c582b2fSDaniel Sanders   //      BGTZC   if rs == 0  && rt != 0
9385c582b2fSDaniel Sanders   //      BLTZC   if rs == rt && rt != 0
9395c582b2fSDaniel Sanders   //      BLTC    if rs != rt && rs != 0  && rt != 0
9405c582b2fSDaniel Sanders 
9415c14b069SZoran Jovanovic   bool HasRs = false;
9425c14b069SZoran Jovanovic 
9435c582b2fSDaniel Sanders   InsnType Rs = fieldFromInstruction(insn, 21, 5);
9445c582b2fSDaniel Sanders   InsnType Rt = fieldFromInstruction(insn, 16, 5);
945672c710dSSagar Thakur   int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
9465c582b2fSDaniel Sanders 
9475c582b2fSDaniel Sanders   if (Rt == 0)
9485c582b2fSDaniel Sanders     return MCDisassembler::Fail;
9495c582b2fSDaniel Sanders   else if (Rs == 0)
9505c582b2fSDaniel Sanders     MI.setOpcode(Mips::BGTZC);
9515c582b2fSDaniel Sanders   else if (Rs == Rt)
9525c582b2fSDaniel Sanders     MI.setOpcode(Mips::BLTZC);
9535c14b069SZoran Jovanovic   else {
9545c14b069SZoran Jovanovic     MI.setOpcode(Mips::BLTC);
9555c14b069SZoran Jovanovic     HasRs = true;
9565c14b069SZoran Jovanovic   }
9575c14b069SZoran Jovanovic 
9585c14b069SZoran Jovanovic   if (HasRs)
959e9119e41SJim Grosbach     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
9605c14b069SZoran Jovanovic                                               Rs)));
9615c582b2fSDaniel Sanders 
962e9119e41SJim Grosbach   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
9635c582b2fSDaniel Sanders                                      Rt)));
9645c582b2fSDaniel Sanders 
965e9119e41SJim Grosbach   MI.addOperand(MCOperand::createImm(Imm));
9665c582b2fSDaniel Sanders 
9675c582b2fSDaniel Sanders   return MCDisassembler::Success;
9685c582b2fSDaniel Sanders }
9695c582b2fSDaniel Sanders 
9705c582b2fSDaniel Sanders template <typename InsnType>
9715c582b2fSDaniel Sanders static DecodeStatus DecodeBgtzGroupBranch(MCInst &MI, InsnType insn,
9725c582b2fSDaniel Sanders                                           uint64_t Address,
9735c582b2fSDaniel Sanders                                           const void *Decoder) {
9745c582b2fSDaniel Sanders   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
9755c582b2fSDaniel Sanders   // (otherwise we would have matched the BGTZ instruction from the earlier
9765c582b2fSDaniel Sanders   // ISA's instead).
9775c582b2fSDaniel Sanders   //
9785c582b2fSDaniel Sanders   // We have:
9795c582b2fSDaniel Sanders   //    0b000111 sssss ttttt iiiiiiiiiiiiiiii
9805c582b2fSDaniel Sanders   //      BGTZ    if rt == 0
9815c582b2fSDaniel Sanders   //      BGTZALC if rs == 0 && rt != 0
9825c582b2fSDaniel Sanders   //      BLTZALC if rs != 0 && rs == rt
9835c582b2fSDaniel Sanders   //      BLTUC   if rs != 0 && rs != rt
9845c582b2fSDaniel Sanders 
9855c582b2fSDaniel Sanders   InsnType Rs = fieldFromInstruction(insn, 21, 5);
9865c582b2fSDaniel Sanders   InsnType Rt = fieldFromInstruction(insn, 16, 5);
987672c710dSSagar Thakur   int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
9885c582b2fSDaniel Sanders   bool HasRs = false;
9895c582b2fSDaniel Sanders   bool HasRt = false;
9905c582b2fSDaniel Sanders 
9915c582b2fSDaniel Sanders   if (Rt == 0) {
9925c582b2fSDaniel Sanders     MI.setOpcode(Mips::BGTZ);
9935c582b2fSDaniel Sanders     HasRs = true;
9945c582b2fSDaniel Sanders   } else if (Rs == 0) {
9955c582b2fSDaniel Sanders     MI.setOpcode(Mips::BGTZALC);
9965c582b2fSDaniel Sanders     HasRt = true;
9975c582b2fSDaniel Sanders   } else if (Rs == Rt) {
9985c582b2fSDaniel Sanders     MI.setOpcode(Mips::BLTZALC);
9995c582b2fSDaniel Sanders     HasRs = true;
10005c14b069SZoran Jovanovic   } else {
10015c14b069SZoran Jovanovic     MI.setOpcode(Mips::BLTUC);
10025c14b069SZoran Jovanovic     HasRs = true;
10035c14b069SZoran Jovanovic     HasRt = true;
10045c14b069SZoran Jovanovic   }
10055c582b2fSDaniel Sanders 
10065c582b2fSDaniel Sanders   if (HasRs)
1007e9119e41SJim Grosbach     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
10085c582b2fSDaniel Sanders                                        Rs)));
10095c582b2fSDaniel Sanders 
10105c582b2fSDaniel Sanders   if (HasRt)
1011e9119e41SJim Grosbach     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
10125c582b2fSDaniel Sanders                                        Rt)));
10135c582b2fSDaniel Sanders 
1014e9119e41SJim Grosbach   MI.addOperand(MCOperand::createImm(Imm));
10155c582b2fSDaniel Sanders 
10165c582b2fSDaniel Sanders   return MCDisassembler::Success;
10175c582b2fSDaniel Sanders }
10185c582b2fSDaniel Sanders 
101928a0ca07SZoran Jovanovic template <typename InsnType>
102028a0ca07SZoran Jovanovic static DecodeStatus DecodeBlezGroupBranch(MCInst &MI, InsnType insn,
102128a0ca07SZoran Jovanovic                                            uint64_t Address,
102228a0ca07SZoran Jovanovic                                            const void *Decoder) {
102328a0ca07SZoran Jovanovic   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
102428a0ca07SZoran Jovanovic   // (otherwise we would have matched the BLEZL instruction from the earlier
102528a0ca07SZoran Jovanovic   // ISA's instead).
102628a0ca07SZoran Jovanovic   //
102728a0ca07SZoran Jovanovic   // We have:
102828a0ca07SZoran Jovanovic   //    0b000110 sssss ttttt iiiiiiiiiiiiiiii
102928a0ca07SZoran Jovanovic   //      Invalid   if rs == 0
103028a0ca07SZoran Jovanovic   //      BLEZALC   if rs == 0  && rt != 0
103128a0ca07SZoran Jovanovic   //      BGEZALC   if rs == rt && rt != 0
103228a0ca07SZoran Jovanovic   //      BGEUC     if rs != rt && rs != 0  && rt != 0
103328a0ca07SZoran Jovanovic 
103428a0ca07SZoran Jovanovic   InsnType Rs = fieldFromInstruction(insn, 21, 5);
103528a0ca07SZoran Jovanovic   InsnType Rt = fieldFromInstruction(insn, 16, 5);
1036672c710dSSagar Thakur   int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
103728a0ca07SZoran Jovanovic   bool HasRs = false;
103828a0ca07SZoran Jovanovic 
103928a0ca07SZoran Jovanovic   if (Rt == 0)
104028a0ca07SZoran Jovanovic     return MCDisassembler::Fail;
104128a0ca07SZoran Jovanovic   else if (Rs == 0)
104228a0ca07SZoran Jovanovic     MI.setOpcode(Mips::BLEZALC);
104328a0ca07SZoran Jovanovic   else if (Rs == Rt)
104428a0ca07SZoran Jovanovic     MI.setOpcode(Mips::BGEZALC);
104528a0ca07SZoran Jovanovic   else {
104628a0ca07SZoran Jovanovic     HasRs = true;
104728a0ca07SZoran Jovanovic     MI.setOpcode(Mips::BGEUC);
104828a0ca07SZoran Jovanovic   }
104928a0ca07SZoran Jovanovic 
105028a0ca07SZoran Jovanovic   if (HasRs)
1051e9119e41SJim Grosbach     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
105228a0ca07SZoran Jovanovic                                        Rs)));
1053e9119e41SJim Grosbach   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
105428a0ca07SZoran Jovanovic                                      Rt)));
105528a0ca07SZoran Jovanovic 
1056e9119e41SJim Grosbach   MI.addOperand(MCOperand::createImm(Imm));
105728a0ca07SZoran Jovanovic 
105828a0ca07SZoran Jovanovic   return MCDisassembler::Success;
105928a0ca07SZoran Jovanovic }
106028a0ca07SZoran Jovanovic 
106155e44673SSimon Dardis // Override the generated disassembler to produce DEXT all the time. This is
106255e44673SSimon Dardis // for feature / behaviour parity with  binutils.
106355e44673SSimon Dardis template <typename InsnType>
106455e44673SSimon Dardis static DecodeStatus DecodeDEXT(MCInst &MI, InsnType Insn, uint64_t Address,
106555e44673SSimon Dardis                                const void *Decoder) {
106655e44673SSimon Dardis   unsigned Msbd = fieldFromInstruction(Insn, 11, 5);
106755e44673SSimon Dardis   unsigned Lsb = fieldFromInstruction(Insn, 6, 5);
106855e44673SSimon Dardis   unsigned Size = 0;
106955e44673SSimon Dardis   unsigned Pos = 0;
107055e44673SSimon Dardis 
107155e44673SSimon Dardis   switch (MI.getOpcode()) {
107255e44673SSimon Dardis     case Mips::DEXT:
107355e44673SSimon Dardis       Pos = Lsb;
107455e44673SSimon Dardis       Size = Msbd + 1;
107555e44673SSimon Dardis       break;
107655e44673SSimon Dardis     case Mips::DEXTM:
107755e44673SSimon Dardis       Pos = Lsb;
107855e44673SSimon Dardis       Size = Msbd + 1 + 32;
107955e44673SSimon Dardis       break;
108055e44673SSimon Dardis     case Mips::DEXTU:
108155e44673SSimon Dardis       Pos = Lsb + 32;
108255e44673SSimon Dardis       Size = Msbd + 1;
108355e44673SSimon Dardis       break;
108455e44673SSimon Dardis     default:
108555e44673SSimon Dardis       llvm_unreachable("Unknown DEXT instruction!");
108655e44673SSimon Dardis   }
108755e44673SSimon Dardis 
1088d6dada17SAleksandar Beserminji   MI.setOpcode(Mips::DEXT);
108955e44673SSimon Dardis 
109055e44673SSimon Dardis   InsnType Rs = fieldFromInstruction(Insn, 21, 5);
109155e44673SSimon Dardis   InsnType Rt = fieldFromInstruction(Insn, 16, 5);
109255e44673SSimon Dardis 
109355e44673SSimon Dardis   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID, Rt)));
109455e44673SSimon Dardis   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID, Rs)));
109555e44673SSimon Dardis   MI.addOperand(MCOperand::createImm(Pos));
109655e44673SSimon Dardis   MI.addOperand(MCOperand::createImm(Size));
109755e44673SSimon Dardis 
109855e44673SSimon Dardis   return MCDisassembler::Success;
109955e44673SSimon Dardis }
110055e44673SSimon Dardis 
11016f83ae38SSimon Dardis // Override the generated disassembler to produce DINS all the time. This is
11026f83ae38SSimon Dardis // for feature / behaviour parity with binutils.
11036f83ae38SSimon Dardis template <typename InsnType>
11046f83ae38SSimon Dardis static DecodeStatus DecodeDINS(MCInst &MI, InsnType Insn, uint64_t Address,
11056f83ae38SSimon Dardis                                const void *Decoder) {
11066f83ae38SSimon Dardis   unsigned Msbd = fieldFromInstruction(Insn, 11, 5);
11076f83ae38SSimon Dardis   unsigned Lsb = fieldFromInstruction(Insn, 6, 5);
11086f83ae38SSimon Dardis   unsigned Size = 0;
11096f83ae38SSimon Dardis   unsigned Pos = 0;
11106f83ae38SSimon Dardis 
11116f83ae38SSimon Dardis   switch (MI.getOpcode()) {
11126f83ae38SSimon Dardis     case Mips::DINS:
11136f83ae38SSimon Dardis       Pos = Lsb;
11146f83ae38SSimon Dardis       Size = Msbd + 1 - Pos;
11156f83ae38SSimon Dardis       break;
11166f83ae38SSimon Dardis     case Mips::DINSM:
11176f83ae38SSimon Dardis       Pos = Lsb;
11186f83ae38SSimon Dardis       Size = Msbd + 33 - Pos;
11196f83ae38SSimon Dardis       break;
11206f83ae38SSimon Dardis     case Mips::DINSU:
11216f83ae38SSimon Dardis       Pos = Lsb + 32;
11226f83ae38SSimon Dardis       // mbsd = pos + size - 33
11236f83ae38SSimon Dardis       // mbsd - pos + 33 = size
11246f83ae38SSimon Dardis       Size = Msbd + 33 - Pos;
11256f83ae38SSimon Dardis       break;
11266f83ae38SSimon Dardis     default:
11276f83ae38SSimon Dardis       llvm_unreachable("Unknown DINS instruction!");
11286f83ae38SSimon Dardis   }
11296f83ae38SSimon Dardis 
11306f83ae38SSimon Dardis   InsnType Rs = fieldFromInstruction(Insn, 21, 5);
11316f83ae38SSimon Dardis   InsnType Rt = fieldFromInstruction(Insn, 16, 5);
11326f83ae38SSimon Dardis 
1133d6dada17SAleksandar Beserminji   MI.setOpcode(Mips::DINS);
11346f83ae38SSimon Dardis   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID, Rt)));
11356f83ae38SSimon Dardis   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID, Rs)));
11366f83ae38SSimon Dardis   MI.addOperand(MCOperand::createImm(Pos));
11376f83ae38SSimon Dardis   MI.addOperand(MCOperand::createImm(Size));
11386f83ae38SSimon Dardis 
11396f83ae38SSimon Dardis   return MCDisassembler::Success;
11406f83ae38SSimon Dardis }
11413408caf6SPetar Jovanovic 
11423408caf6SPetar Jovanovic // Auto-generated decoder wouldn't add the third operand for CRC32*.
11433408caf6SPetar Jovanovic template <typename InsnType>
11443408caf6SPetar Jovanovic static DecodeStatus DecodeCRC(MCInst &MI, InsnType Insn, uint64_t Address,
11453408caf6SPetar Jovanovic                               const void *Decoder) {
11463408caf6SPetar Jovanovic   InsnType Rs = fieldFromInstruction(Insn, 21, 5);
11473408caf6SPetar Jovanovic   InsnType Rt = fieldFromInstruction(Insn, 16, 5);
11483408caf6SPetar Jovanovic   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
11493408caf6SPetar Jovanovic                                      Rt)));
11503408caf6SPetar Jovanovic   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
11513408caf6SPetar Jovanovic                                      Rs)));
11523408caf6SPetar Jovanovic   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
11533408caf6SPetar Jovanovic                                      Rt)));
11543408caf6SPetar Jovanovic   return MCDisassembler::Success;
11553408caf6SPetar Jovanovic }
11563408caf6SPetar Jovanovic 
1157ea22c4cfSJozef Kolek /// Read two bytes from the ArrayRef and return 16 bit halfword sorted
1158dcd84335SSimon Pilgrim /// according to the given endianness.
1159ea22c4cfSJozef Kolek static DecodeStatus readInstruction16(ArrayRef<uint8_t> Bytes, uint64_t Address,
1160ea22c4cfSJozef Kolek                                       uint64_t &Size, uint32_t &Insn,
1161ea22c4cfSJozef Kolek                                       bool IsBigEndian) {
1162ea22c4cfSJozef Kolek   // We want to read exactly 2 Bytes of data.
1163ea22c4cfSJozef Kolek   if (Bytes.size() < 2) {
1164ea22c4cfSJozef Kolek     Size = 0;
1165ea22c4cfSJozef Kolek     return MCDisassembler::Fail;
1166ea22c4cfSJozef Kolek   }
1167ea22c4cfSJozef Kolek 
1168ea22c4cfSJozef Kolek   if (IsBigEndian) {
1169ea22c4cfSJozef Kolek     Insn = (Bytes[0] << 8) | Bytes[1];
1170ea22c4cfSJozef Kolek   } else {
1171ea22c4cfSJozef Kolek     Insn = (Bytes[1] << 8) | Bytes[0];
1172ea22c4cfSJozef Kolek   }
1173ea22c4cfSJozef Kolek 
1174ea22c4cfSJozef Kolek   return MCDisassembler::Success;
1175ea22c4cfSJozef Kolek }
1176ea22c4cfSJozef Kolek 
11777fc5b874SRafael Espindola /// Read four bytes from the ArrayRef and return 32 bit word sorted
1178dcd84335SSimon Pilgrim /// according to the given endianness.
11797fc5b874SRafael Espindola static DecodeStatus readInstruction32(ArrayRef<uint8_t> Bytes, uint64_t Address,
11807fc5b874SRafael Espindola                                       uint64_t &Size, uint32_t &Insn,
11817fc5b874SRafael Espindola                                       bool IsBigEndian, bool IsMicroMips) {
118271928e68SAkira Hatanaka   // We want to read exactly 4 Bytes of data.
11837fc5b874SRafael Espindola   if (Bytes.size() < 4) {
11844aa6bea7SRafael Espindola     Size = 0;
118571928e68SAkira Hatanaka     return MCDisassembler::Fail;
118671928e68SAkira Hatanaka   }
118771928e68SAkira Hatanaka 
1188ea22c4cfSJozef Kolek   // High 16 bits of a 32-bit microMIPS instruction (where the opcode is)
1189ea22c4cfSJozef Kolek   // always precede the low 16 bits in the instruction stream (that is, they
1190ea22c4cfSJozef Kolek   // are placed at lower addresses in the instruction stream).
1191ea22c4cfSJozef Kolek   //
1192ea22c4cfSJozef Kolek   // microMIPS byte ordering:
1193ea22c4cfSJozef Kolek   //   Big-endian:    0 | 1 | 2 | 3
1194ea22c4cfSJozef Kolek   //   Little-endian: 1 | 0 | 3 | 2
1195ea22c4cfSJozef Kolek 
11964aa6bea7SRafael Espindola   if (IsBigEndian) {
119771928e68SAkira Hatanaka     // Encoded as a big-endian 32-bit word in the stream.
11984aa6bea7SRafael Espindola     Insn =
11994aa6bea7SRafael Espindola         (Bytes[3] << 0) | (Bytes[2] << 8) | (Bytes[1] << 16) | (Bytes[0] << 24);
12004aa6bea7SRafael Espindola   } else {
1201dde3d582SVladimir Medic     if (IsMicroMips) {
12024aa6bea7SRafael Espindola       Insn = (Bytes[2] << 0) | (Bytes[3] << 8) | (Bytes[0] << 16) |
1203dde3d582SVladimir Medic              (Bytes[1] << 24);
1204dde3d582SVladimir Medic     } else {
12054aa6bea7SRafael Espindola       Insn = (Bytes[0] << 0) | (Bytes[1] << 8) | (Bytes[2] << 16) |
120671928e68SAkira Hatanaka              (Bytes[3] << 24);
120771928e68SAkira Hatanaka     }
1208dde3d582SVladimir Medic   }
120971928e68SAkira Hatanaka 
121071928e68SAkira Hatanaka   return MCDisassembler::Success;
121171928e68SAkira Hatanaka }
121271928e68SAkira Hatanaka 
12134aa6bea7SRafael Espindola DecodeStatus MipsDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,
12147fc5b874SRafael Espindola                                               ArrayRef<uint8_t> Bytes,
121571928e68SAkira Hatanaka                                               uint64_t Address,
12164aa6bea7SRafael Espindola                                               raw_ostream &VStream,
12174aa6bea7SRafael Espindola                                               raw_ostream &CStream) const {
121871928e68SAkira Hatanaka   uint32_t Insn;
1219ea22c4cfSJozef Kolek   DecodeStatus Result;
1220a5f52dc0SSimon Dardis   Size = 0;
122171928e68SAkira Hatanaka 
1222ea22c4cfSJozef Kolek   if (IsMicroMips) {
1223ea22c4cfSJozef Kolek     Result = readInstruction16(Bytes, Address, Size, Insn, IsBigEndian);
1224ebee6129SReid Kleckner     if (Result == MCDisassembler::Fail)
1225ebee6129SReid Kleckner       return MCDisassembler::Fail;
1226ea22c4cfSJozef Kolek 
1227ada70918SZoran Jovanovic     if (hasMips32r6()) {
1228*d34e60caSNicola Zaghen       LLVM_DEBUG(
1229*d34e60caSNicola Zaghen           dbgs() << "Trying MicroMipsR616 table (16-bit instructions):\n");
1230ada70918SZoran Jovanovic       // Calling the auto-generated decoder function for microMIPS32R6
1231d6dada17SAleksandar Beserminji       // 16-bit instructions.
1232ada70918SZoran Jovanovic       Result = decodeInstruction(DecoderTableMicroMipsR616, Instr, Insn,
1233ada70918SZoran Jovanovic                                  Address, this, STI);
1234ada70918SZoran Jovanovic       if (Result != MCDisassembler::Fail) {
1235ada70918SZoran Jovanovic         Size = 2;
1236ada70918SZoran Jovanovic         return Result;
1237ada70918SZoran Jovanovic       }
1238ada70918SZoran Jovanovic     }
1239ada70918SZoran Jovanovic 
1240*d34e60caSNicola Zaghen     LLVM_DEBUG(dbgs() << "Trying MicroMips16 table (16-bit instructions):\n");
1241ada70918SZoran Jovanovic     // Calling the auto-generated decoder function for microMIPS 16-bit
1242ada70918SZoran Jovanovic     // instructions.
1243ea22c4cfSJozef Kolek     Result = decodeInstruction(DecoderTableMicroMips16, Instr, Insn, Address,
1244ea22c4cfSJozef Kolek                                this, STI);
1245ea22c4cfSJozef Kolek     if (Result != MCDisassembler::Fail) {
1246ea22c4cfSJozef Kolek       Size = 2;
1247ea22c4cfSJozef Kolek       return Result;
1248ea22c4cfSJozef Kolek     }
1249ea22c4cfSJozef Kolek 
1250ea22c4cfSJozef Kolek     Result = readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, true);
125171928e68SAkira Hatanaka     if (Result == MCDisassembler::Fail)
125271928e68SAkira Hatanaka       return MCDisassembler::Fail;
125371928e68SAkira Hatanaka 
1254676d6012SJozef Kolek     if (hasMips32r6()) {
1255*d34e60caSNicola Zaghen       LLVM_DEBUG(
1256*d34e60caSNicola Zaghen           dbgs() << "Trying MicroMips32r632 table (32-bit instructions):\n");
1257676d6012SJozef Kolek       // Calling the auto-generated decoder function.
1258366783e1SZoran Jovanovic       Result = decodeInstruction(DecoderTableMicroMipsR632, Instr, Insn, Address,
1259676d6012SJozef Kolek                                  this, STI);
1260ada70918SZoran Jovanovic       if (Result != MCDisassembler::Fail) {
1261ada70918SZoran Jovanovic         Size = 4;
1262ada70918SZoran Jovanovic         return Result;
1263ada70918SZoran Jovanovic       }
1264ada70918SZoran Jovanovic     }
1265ada70918SZoran Jovanovic 
1266*d34e60caSNicola Zaghen     LLVM_DEBUG(dbgs() << "Trying MicroMips32 table (32-bit instructions):\n");
1267dde3d582SVladimir Medic     // Calling the auto-generated decoder function.
12684aa6bea7SRafael Espindola     Result = decodeInstruction(DecoderTableMicroMips32, Instr, Insn, Address,
1269dde3d582SVladimir Medic                                this, STI);
1270dde3d582SVladimir Medic     if (Result != MCDisassembler::Fail) {
1271dde3d582SVladimir Medic       Size = 4;
1272dde3d582SVladimir Medic       return Result;
1273dde3d582SVladimir Medic     }
12742cb74ac3SHrvoje Varga 
127551a7ae2aSSimon Dardis     if (isFP64()) {
1276*d34e60caSNicola Zaghen       LLVM_DEBUG(dbgs() << "Trying MicroMipsFP64 table (32-bit opcodes):\n");
127751a7ae2aSSimon Dardis       Result = decodeInstruction(DecoderTableMicroMipsFP6432, Instr, Insn,
12782cb74ac3SHrvoje Varga                                  Address, this, STI);
12792cb74ac3SHrvoje Varga       if (Result != MCDisassembler::Fail) {
12802cb74ac3SHrvoje Varga         Size = 4;
12812cb74ac3SHrvoje Varga         return Result;
12822cb74ac3SHrvoje Varga       }
12832cb74ac3SHrvoje Varga     }
12842cb74ac3SHrvoje Varga 
1285a5f52dc0SSimon Dardis     // This is an invalid instruction. Claim that the Size is 2 bytes. Since
1286a5f52dc0SSimon Dardis     // microMIPS instructions have a minimum alignment of 2, the next 2 bytes
1287a5f52dc0SSimon Dardis     // could form a valid instruction. The two bytes we rejected as an
1288a5f52dc0SSimon Dardis     // instruction could have actually beeen an inline constant pool that is
1289a5f52dc0SSimon Dardis     // unconditionally branched over.
1290ebee6129SReid Kleckner     Size = 2;
1291dde3d582SVladimir Medic     return MCDisassembler::Fail;
1292dde3d582SVladimir Medic   }
1293dde3d582SVladimir Medic 
1294a5f52dc0SSimon Dardis   // Attempt to read the instruction so that we can attempt to decode it. If
1295a5f52dc0SSimon Dardis   // the buffer is not 4 bytes long, let the higher level logic figure out
1296a5f52dc0SSimon Dardis   // what to do with a size of zero and MCDisassembler::Fail.
1297ea22c4cfSJozef Kolek   Result = readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, false);
1298a5f52dc0SSimon Dardis   if (Result == MCDisassembler::Fail)
1299ea22c4cfSJozef Kolek     return MCDisassembler::Fail;
1300a5f52dc0SSimon Dardis 
1301a5f52dc0SSimon Dardis   // The only instruction size for standard encoded MIPS.
1302a5f52dc0SSimon Dardis   Size = 4;
1303ea22c4cfSJozef Kolek 
1304c171f65aSDaniel Sanders   if (hasCOP3()) {
1305*d34e60caSNicola Zaghen     LLVM_DEBUG(dbgs() << "Trying COP3_ table (32-bit opcodes):\n");
1306c171f65aSDaniel Sanders     Result =
13074aa6bea7SRafael Espindola         decodeInstruction(DecoderTableCOP3_32, Instr, Insn, Address, this, STI);
1308a5f52dc0SSimon Dardis     if (Result != MCDisassembler::Fail)
1309c171f65aSDaniel Sanders       return Result;
1310c171f65aSDaniel Sanders   }
1311c171f65aSDaniel Sanders 
1312c171f65aSDaniel Sanders   if (hasMips32r6() && isGP64()) {
1313*d34e60caSNicola Zaghen     LLVM_DEBUG(
1314*d34e60caSNicola Zaghen         dbgs() << "Trying Mips32r6_64r6 (GPR64) table (32-bit opcodes):\n");
131536901dd1SVasileios Kalintiris     Result = decodeInstruction(DecoderTableMips32r6_64r6_GP6432, Instr, Insn,
131636901dd1SVasileios Kalintiris                                Address, this, STI);
1317a5f52dc0SSimon Dardis     if (Result != MCDisassembler::Fail)
13180fa60416SDaniel Sanders       return Result;
13190fa60416SDaniel Sanders   }
13200fa60416SDaniel Sanders 
13214fbf76f7SSimon Dardis   if (hasMips32r6() && isPTR64()) {
1322*d34e60caSNicola Zaghen     LLVM_DEBUG(
1323*d34e60caSNicola Zaghen         dbgs() << "Trying Mips32r6_64r6 (PTR64) table (32-bit opcodes):\n");
13244fbf76f7SSimon Dardis     Result = decodeInstruction(DecoderTableMips32r6_64r6_PTR6432, Instr, Insn,
13254fbf76f7SSimon Dardis                                Address, this, STI);
1326a5f52dc0SSimon Dardis     if (Result != MCDisassembler::Fail)
13274fbf76f7SSimon Dardis       return Result;
13284fbf76f7SSimon Dardis   }
13294fbf76f7SSimon Dardis 
1330c171f65aSDaniel Sanders   if (hasMips32r6()) {
1331*d34e60caSNicola Zaghen     LLVM_DEBUG(dbgs() << "Trying Mips32r6_64r6 table (32-bit opcodes):\n");
13324aa6bea7SRafael Espindola     Result = decodeInstruction(DecoderTableMips32r6_64r632, Instr, Insn,
13335c582b2fSDaniel Sanders                                Address, this, STI);
1334a5f52dc0SSimon Dardis     if (Result != MCDisassembler::Fail)
13355c582b2fSDaniel Sanders       return Result;
13365c582b2fSDaniel Sanders   }
13375c582b2fSDaniel Sanders 
13384fbf76f7SSimon Dardis   if (hasMips2() && isPTR64()) {
1339*d34e60caSNicola Zaghen     LLVM_DEBUG(
1340*d34e60caSNicola Zaghen         dbgs() << "Trying Mips32r6_64r6 (PTR64) table (32-bit opcodes):\n");
13414fbf76f7SSimon Dardis     Result = decodeInstruction(DecoderTableMips32_64_PTR6432, Instr, Insn,
13424fbf76f7SSimon Dardis                                Address, this, STI);
1343a5f52dc0SSimon Dardis     if (Result != MCDisassembler::Fail)
13444fbf76f7SSimon Dardis       return Result;
13454fbf76f7SSimon Dardis   }
13464fbf76f7SSimon Dardis 
13473adf9b8dSKai Nacke   if (hasCnMips()) {
1348*d34e60caSNicola Zaghen     LLVM_DEBUG(dbgs() << "Trying CnMips table (32-bit opcodes):\n");
13493adf9b8dSKai Nacke     Result = decodeInstruction(DecoderTableCnMips32, Instr, Insn,
13503adf9b8dSKai Nacke                                Address, this, STI);
1351a5f52dc0SSimon Dardis     if (Result != MCDisassembler::Fail)
13523adf9b8dSKai Nacke       return Result;
13533adf9b8dSKai Nacke   }
13543adf9b8dSKai Nacke 
1355a19216c8SDaniel Sanders   if (isGP64()) {
1356*d34e60caSNicola Zaghen     LLVM_DEBUG(dbgs() << "Trying Mips64 (GPR64) table (32-bit opcodes):\n");
1357a19216c8SDaniel Sanders     Result = decodeInstruction(DecoderTableMips6432, Instr, Insn,
1358a19216c8SDaniel Sanders                                Address, this, STI);
1359a5f52dc0SSimon Dardis     if (Result != MCDisassembler::Fail)
1360a19216c8SDaniel Sanders       return Result;
1361a19216c8SDaniel Sanders   }
1362a19216c8SDaniel Sanders 
136351a7ae2aSSimon Dardis   if (isFP64()) {
1364*d34e60caSNicola Zaghen     LLVM_DEBUG(
1365*d34e60caSNicola Zaghen         dbgs() << "Trying MipsFP64 (64 bit FPU) table (32-bit opcodes):\n");
136651a7ae2aSSimon Dardis     Result = decodeInstruction(DecoderTableMipsFP6432, Instr, Insn,
136751a7ae2aSSimon Dardis                                Address, this, STI);
136851a7ae2aSSimon Dardis     if (Result != MCDisassembler::Fail)
136951a7ae2aSSimon Dardis       return Result;
137051a7ae2aSSimon Dardis   }
137151a7ae2aSSimon Dardis 
1372*d34e60caSNicola Zaghen   LLVM_DEBUG(dbgs() << "Trying Mips table (32-bit opcodes):\n");
137371928e68SAkira Hatanaka   // Calling the auto-generated decoder function.
13744aa6bea7SRafael Espindola   Result =
13754aa6bea7SRafael Espindola       decodeInstruction(DecoderTableMips32, Instr, Insn, Address, this, STI);
1376a5f52dc0SSimon Dardis   if (Result != MCDisassembler::Fail)
137771928e68SAkira Hatanaka     return Result;
137871928e68SAkira Hatanaka 
137971928e68SAkira Hatanaka   return MCDisassembler::Fail;
138071928e68SAkira Hatanaka }
138171928e68SAkira Hatanaka 
1382ec8a5490SReed Kotler static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst,
1383ec8a5490SReed Kotler                                                  unsigned RegNo,
1384ec8a5490SReed Kotler                                                  uint64_t Address,
1385ec8a5490SReed Kotler                                                  const void *Decoder) {
1386ec8a5490SReed Kotler   return MCDisassembler::Fail;
1387ec8a5490SReed Kotler }
1388ec8a5490SReed Kotler 
138913e6ccf3SAkira Hatanaka static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst,
139071928e68SAkira Hatanaka                                              unsigned RegNo,
139171928e68SAkira Hatanaka                                              uint64_t Address,
139271928e68SAkira Hatanaka                                              const void *Decoder) {
139371928e68SAkira Hatanaka   if (RegNo > 31)
139471928e68SAkira Hatanaka     return MCDisassembler::Fail;
139571928e68SAkira Hatanaka 
139613e6ccf3SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::GPR64RegClassID, RegNo);
1397e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
139871928e68SAkira Hatanaka   return MCDisassembler::Success;
139971928e68SAkira Hatanaka }
140071928e68SAkira Hatanaka 
1401b0852e54SZoran Jovanovic static DecodeStatus DecodeGPRMM16RegisterClass(MCInst &Inst,
1402b0852e54SZoran Jovanovic                                                unsigned RegNo,
1403b0852e54SZoran Jovanovic                                                uint64_t Address,
1404b0852e54SZoran Jovanovic                                                const void *Decoder) {
1405ea22c4cfSJozef Kolek   if (RegNo > 7)
1406b0852e54SZoran Jovanovic     return MCDisassembler::Fail;
1407ea22c4cfSJozef Kolek   unsigned Reg = getReg(Decoder, Mips::GPRMM16RegClassID, RegNo);
1408e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1409ea22c4cfSJozef Kolek   return MCDisassembler::Success;
1410b0852e54SZoran Jovanovic }
1411b0852e54SZoran Jovanovic 
14121904fa21SJozef Kolek static DecodeStatus DecodeGPRMM16ZeroRegisterClass(MCInst &Inst,
14131904fa21SJozef Kolek                                                    unsigned RegNo,
14141904fa21SJozef Kolek                                                    uint64_t Address,
14151904fa21SJozef Kolek                                                    const void *Decoder) {
1416315e7ecaSJozef Kolek   if (RegNo > 7)
14171904fa21SJozef Kolek     return MCDisassembler::Fail;
1418315e7ecaSJozef Kolek   unsigned Reg = getReg(Decoder, Mips::GPRMM16ZeroRegClassID, RegNo);
1419e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1420315e7ecaSJozef Kolek   return MCDisassembler::Success;
14211904fa21SJozef Kolek }
14221904fa21SJozef Kolek 
142341688679SZoran Jovanovic static DecodeStatus DecodeGPRMM16MovePRegisterClass(MCInst &Inst,
142441688679SZoran Jovanovic                                                     unsigned RegNo,
142541688679SZoran Jovanovic                                                     uint64_t Address,
142641688679SZoran Jovanovic                                                     const void *Decoder) {
142741688679SZoran Jovanovic   if (RegNo > 7)
142841688679SZoran Jovanovic     return MCDisassembler::Fail;
142941688679SZoran Jovanovic   unsigned Reg = getReg(Decoder, Mips::GPRMM16MovePRegClassID, RegNo);
1430e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
143141688679SZoran Jovanovic   return MCDisassembler::Success;
143241688679SZoran Jovanovic }
143341688679SZoran Jovanovic 
143413e6ccf3SAkira Hatanaka static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst,
143571928e68SAkira Hatanaka                                              unsigned RegNo,
143671928e68SAkira Hatanaka                                              uint64_t Address,
143771928e68SAkira Hatanaka                                              const void *Decoder) {
143871928e68SAkira Hatanaka   if (RegNo > 31)
143971928e68SAkira Hatanaka     return MCDisassembler::Fail;
144013e6ccf3SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::GPR32RegClassID, RegNo);
1441e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
144271928e68SAkira Hatanaka   return MCDisassembler::Success;
144371928e68SAkira Hatanaka }
144471928e68SAkira Hatanaka 
14459bfa2e2eSAkira Hatanaka static DecodeStatus DecodePtrRegisterClass(MCInst &Inst,
14469bfa2e2eSAkira Hatanaka                                            unsigned RegNo,
14479bfa2e2eSAkira Hatanaka                                            uint64_t Address,
14489bfa2e2eSAkira Hatanaka                                            const void *Decoder) {
1449a19216c8SDaniel Sanders   if (static_cast<const MipsDisassembler *>(Decoder)->isGP64())
14509bfa2e2eSAkira Hatanaka     return DecodeGPR64RegisterClass(Inst, RegNo, Address, Decoder);
14519bfa2e2eSAkira Hatanaka 
14529bfa2e2eSAkira Hatanaka   return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
14539bfa2e2eSAkira Hatanaka }
14549bfa2e2eSAkira Hatanaka 
1455654655f1SAkira Hatanaka static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst,
1456ecabd1a5SAkira Hatanaka                                             unsigned RegNo,
1457ecabd1a5SAkira Hatanaka                                             uint64_t Address,
1458ecabd1a5SAkira Hatanaka                                             const void *Decoder) {
145913e6ccf3SAkira Hatanaka   return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
1460ecabd1a5SAkira Hatanaka }
1461ecabd1a5SAkira Hatanaka 
146271928e68SAkira Hatanaka static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
146371928e68SAkira Hatanaka                                              unsigned RegNo,
146471928e68SAkira Hatanaka                                              uint64_t Address,
146571928e68SAkira Hatanaka                                              const void *Decoder) {
146671928e68SAkira Hatanaka   if (RegNo > 31)
146771928e68SAkira Hatanaka     return MCDisassembler::Fail;
146871928e68SAkira Hatanaka 
14699bf2b567SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::FGR64RegClassID, RegNo);
1470e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
147171928e68SAkira Hatanaka   return MCDisassembler::Success;
147271928e68SAkira Hatanaka }
147371928e68SAkira Hatanaka 
147471928e68SAkira Hatanaka static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
147571928e68SAkira Hatanaka                                              unsigned RegNo,
147671928e68SAkira Hatanaka                                              uint64_t Address,
147771928e68SAkira Hatanaka                                              const void *Decoder) {
147871928e68SAkira Hatanaka   if (RegNo > 31)
147971928e68SAkira Hatanaka     return MCDisassembler::Fail;
148071928e68SAkira Hatanaka 
14819bf2b567SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::FGR32RegClassID, RegNo);
1482e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
148371928e68SAkira Hatanaka   return MCDisassembler::Success;
148471928e68SAkira Hatanaka }
148571928e68SAkira Hatanaka 
148671928e68SAkira Hatanaka static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
148771928e68SAkira Hatanaka                                            unsigned RegNo,
148871928e68SAkira Hatanaka                                            uint64_t Address,
148971928e68SAkira Hatanaka                                            const void *Decoder) {
1490253777fdSChad Rosier   if (RegNo > 31)
1491253777fdSChad Rosier     return MCDisassembler::Fail;
1492253777fdSChad Rosier   unsigned Reg = getReg(Decoder, Mips::CCRRegClassID, RegNo);
1493e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
149471928e68SAkira Hatanaka   return MCDisassembler::Success;
149571928e68SAkira Hatanaka }
149671928e68SAkira Hatanaka 
14971fb1b8b8SAkira Hatanaka static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst,
14981fb1b8b8SAkira Hatanaka                                            unsigned RegNo,
14991fb1b8b8SAkira Hatanaka                                            uint64_t Address,
15001fb1b8b8SAkira Hatanaka                                            const void *Decoder) {
15011fb1b8b8SAkira Hatanaka   if (RegNo > 7)
15021fb1b8b8SAkira Hatanaka     return MCDisassembler::Fail;
15031fb1b8b8SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::FCCRegClassID, RegNo);
1504e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
15051fb1b8b8SAkira Hatanaka   return MCDisassembler::Success;
15061fb1b8b8SAkira Hatanaka }
15071fb1b8b8SAkira Hatanaka 
150836901dd1SVasileios Kalintiris static DecodeStatus DecodeFGRCCRegisterClass(MCInst &Inst, unsigned RegNo,
15090fa60416SDaniel Sanders                                              uint64_t Address,
15100fa60416SDaniel Sanders                                              const void *Decoder) {
15110fa60416SDaniel Sanders   if (RegNo > 31)
15120fa60416SDaniel Sanders     return MCDisassembler::Fail;
15130fa60416SDaniel Sanders 
151436901dd1SVasileios Kalintiris   unsigned Reg = getReg(Decoder, Mips::FGRCCRegClassID, RegNo);
1515e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
15160fa60416SDaniel Sanders   return MCDisassembler::Success;
15170fa60416SDaniel Sanders }
15180fa60416SDaniel Sanders 
151971928e68SAkira Hatanaka static DecodeStatus DecodeMem(MCInst &Inst,
152071928e68SAkira Hatanaka                               unsigned Insn,
152171928e68SAkira Hatanaka                               uint64_t Address,
152271928e68SAkira Hatanaka                               const void *Decoder) {
152371928e68SAkira Hatanaka   int Offset = SignExtend32<16>(Insn & 0xffff);
1524ecaef49fSJim Grosbach   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1525ecaef49fSJim Grosbach   unsigned Base = fieldFromInstruction(Insn, 21, 5);
15269bf2b567SAkira Hatanaka 
152713e6ccf3SAkira Hatanaka   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
152813e6ccf3SAkira Hatanaka   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
152971928e68SAkira Hatanaka 
1530d7ecf49eSVladimir Medic   if (Inst.getOpcode() == Mips::SC ||
1531e4e83a7bSDaniel Sanders       Inst.getOpcode() == Mips::SCD)
1532e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Reg));
1533e4e83a7bSDaniel Sanders 
1534e4e83a7bSDaniel Sanders   Inst.addOperand(MCOperand::createReg(Reg));
1535e4e83a7bSDaniel Sanders   Inst.addOperand(MCOperand::createReg(Base));
1536e4e83a7bSDaniel Sanders   Inst.addOperand(MCOperand::createImm(Offset));
1537e4e83a7bSDaniel Sanders 
1538e4e83a7bSDaniel Sanders   return MCDisassembler::Success;
153971928e68SAkira Hatanaka }
154071928e68SAkira Hatanaka 
1541e4e83a7bSDaniel Sanders static DecodeStatus DecodeMemEVA(MCInst &Inst,
1542e4e83a7bSDaniel Sanders                                  unsigned Insn,
1543e4e83a7bSDaniel Sanders                                  uint64_t Address,
1544e4e83a7bSDaniel Sanders                                  const void *Decoder) {
1545e4e83a7bSDaniel Sanders   int Offset = SignExtend32<9>(Insn >> 7);
1546e4e83a7bSDaniel Sanders   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1547e4e83a7bSDaniel Sanders   unsigned Base = fieldFromInstruction(Insn, 21, 5);
1548e4e83a7bSDaniel Sanders 
1549e4e83a7bSDaniel Sanders   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1550e4e83a7bSDaniel Sanders   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1551e4e83a7bSDaniel Sanders 
1552e4e83a7bSDaniel Sanders    if (Inst.getOpcode() == Mips::SCE)
1553e4e83a7bSDaniel Sanders      Inst.addOperand(MCOperand::createReg(Reg));
1554e4e83a7bSDaniel Sanders 
1555e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1556e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1557e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
155871928e68SAkira Hatanaka 
155971928e68SAkira Hatanaka   return MCDisassembler::Success;
156071928e68SAkira Hatanaka }
156171928e68SAkira Hatanaka 
15623c88fbd3SHrvoje Varga static DecodeStatus DecodeLoadByte15(MCInst &Inst,
15633c88fbd3SHrvoje Varga                                      unsigned Insn,
15643c88fbd3SHrvoje Varga                                      uint64_t Address,
15653c88fbd3SHrvoje Varga                                      const void *Decoder) {
15663c88fbd3SHrvoje Varga   int Offset = SignExtend32<16>(Insn & 0xffff);
15673c88fbd3SHrvoje Varga   unsigned Base = fieldFromInstruction(Insn, 16, 5);
15683c88fbd3SHrvoje Varga   unsigned Reg = fieldFromInstruction(Insn, 21, 5);
15693c88fbd3SHrvoje Varga 
15703c88fbd3SHrvoje Varga   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
15713c88fbd3SHrvoje Varga   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
15723c88fbd3SHrvoje Varga 
15733c88fbd3SHrvoje Varga   Inst.addOperand(MCOperand::createReg(Reg));
15743c88fbd3SHrvoje Varga   Inst.addOperand(MCOperand::createReg(Base));
15753c88fbd3SHrvoje Varga   Inst.addOperand(MCOperand::createImm(Offset));
15763c88fbd3SHrvoje Varga 
15773c88fbd3SHrvoje Varga   return MCDisassembler::Success;
15783c88fbd3SHrvoje Varga }
15793c88fbd3SHrvoje Varga 
158092db6b78SDaniel Sanders static DecodeStatus DecodeCacheOp(MCInst &Inst,
158192db6b78SDaniel Sanders                               unsigned Insn,
158292db6b78SDaniel Sanders                               uint64_t Address,
158392db6b78SDaniel Sanders                               const void *Decoder) {
158492db6b78SDaniel Sanders   int Offset = SignExtend32<16>(Insn & 0xffff);
158592db6b78SDaniel Sanders   unsigned Hint = fieldFromInstruction(Insn, 16, 5);
158692db6b78SDaniel Sanders   unsigned Base = fieldFromInstruction(Insn, 21, 5);
158792db6b78SDaniel Sanders 
158892db6b78SDaniel Sanders   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
158992db6b78SDaniel Sanders 
1590e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1591e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
1592e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Hint));
159392db6b78SDaniel Sanders 
159492db6b78SDaniel Sanders   return MCDisassembler::Success;
159592db6b78SDaniel Sanders }
159692db6b78SDaniel Sanders 
1597ab6d1cceSJozef Kolek static DecodeStatus DecodeCacheOpMM(MCInst &Inst,
1598ab6d1cceSJozef Kolek                                     unsigned Insn,
1599ab6d1cceSJozef Kolek                                     uint64_t Address,
1600ab6d1cceSJozef Kolek                                     const void *Decoder) {
1601ab6d1cceSJozef Kolek   int Offset = SignExtend32<12>(Insn & 0xfff);
1602ab6d1cceSJozef Kolek   unsigned Base = fieldFromInstruction(Insn, 16, 5);
1603ab6d1cceSJozef Kolek   unsigned Hint = fieldFromInstruction(Insn, 21, 5);
1604ab6d1cceSJozef Kolek 
1605ab6d1cceSJozef Kolek   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1606ab6d1cceSJozef Kolek 
1607e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1608e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
1609e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Hint));
1610ab6d1cceSJozef Kolek 
1611ab6d1cceSJozef Kolek   return MCDisassembler::Success;
1612ab6d1cceSJozef Kolek }
1613ab6d1cceSJozef Kolek 
1614d9790793SZoran Jovanovic static DecodeStatus DecodePrefeOpMM(MCInst &Inst,
1615d9790793SZoran Jovanovic                                     unsigned Insn,
1616d9790793SZoran Jovanovic                                     uint64_t Address,
1617d9790793SZoran Jovanovic                                     const void *Decoder) {
1618d9790793SZoran Jovanovic   int Offset = SignExtend32<9>(Insn & 0x1ff);
1619d9790793SZoran Jovanovic   unsigned Base = fieldFromInstruction(Insn, 16, 5);
1620d9790793SZoran Jovanovic   unsigned Hint = fieldFromInstruction(Insn, 21, 5);
1621d9790793SZoran Jovanovic 
1622d9790793SZoran Jovanovic   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1623d9790793SZoran Jovanovic 
1624d9790793SZoran Jovanovic   Inst.addOperand(MCOperand::createReg(Base));
1625d9790793SZoran Jovanovic   Inst.addOperand(MCOperand::createImm(Offset));
1626d9790793SZoran Jovanovic   Inst.addOperand(MCOperand::createImm(Hint));
1627d9790793SZoran Jovanovic 
1628d9790793SZoran Jovanovic   return MCDisassembler::Success;
1629d9790793SZoran Jovanovic }
1630d9790793SZoran Jovanovic 
1631e4e83a7bSDaniel Sanders static DecodeStatus DecodeCacheeOp_CacheOpR6(MCInst &Inst,
1632df464ae2SVladimir Medic                                              unsigned Insn,
1633df464ae2SVladimir Medic                                              uint64_t Address,
1634df464ae2SVladimir Medic                                              const void *Decoder) {
1635e4e83a7bSDaniel Sanders   int Offset = SignExtend32<9>(Insn >> 7);
1636df464ae2SVladimir Medic   unsigned Hint = fieldFromInstruction(Insn, 16, 5);
1637df464ae2SVladimir Medic   unsigned Base = fieldFromInstruction(Insn, 21, 5);
1638df464ae2SVladimir Medic 
1639df464ae2SVladimir Medic   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1640df464ae2SVladimir Medic 
1641e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1642e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
1643e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Hint));
1644df464ae2SVladimir Medic 
1645df464ae2SVladimir Medic   return MCDisassembler::Success;
1646df464ae2SVladimir Medic }
1647df464ae2SVladimir Medic 
1648b4484d62SDaniel Sanders static DecodeStatus DecodeSyncI(MCInst &Inst,
1649b4484d62SDaniel Sanders                               unsigned Insn,
1650b4484d62SDaniel Sanders                               uint64_t Address,
1651b4484d62SDaniel Sanders                               const void *Decoder) {
1652b4484d62SDaniel Sanders   int Offset = SignExtend32<16>(Insn & 0xffff);
1653b4484d62SDaniel Sanders   unsigned Base = fieldFromInstruction(Insn, 21, 5);
1654b4484d62SDaniel Sanders 
1655b4484d62SDaniel Sanders   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1656b4484d62SDaniel Sanders 
1657e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1658e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
1659b4484d62SDaniel Sanders 
1660b4484d62SDaniel Sanders   return MCDisassembler::Success;
1661b4484d62SDaniel Sanders }
1662b4484d62SDaniel Sanders 
1663eac9301cSSimon Dardis static DecodeStatus DecodeSyncI_MM(MCInst &Inst, unsigned Insn,
1664eac9301cSSimon Dardis                                    uint64_t Address, const void *Decoder) {
1665eac9301cSSimon Dardis   int Offset = SignExtend32<16>(Insn & 0xffff);
1666eac9301cSSimon Dardis   unsigned Base = fieldFromInstruction(Insn, 16, 5);
1667eac9301cSSimon Dardis 
1668eac9301cSSimon Dardis   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1669eac9301cSSimon Dardis 
1670eac9301cSSimon Dardis   Inst.addOperand(MCOperand::createReg(Base));
1671eac9301cSSimon Dardis   Inst.addOperand(MCOperand::createImm(Offset));
1672eac9301cSSimon Dardis 
1673eac9301cSSimon Dardis   return MCDisassembler::Success;
1674eac9301cSSimon Dardis }
1675eac9301cSSimon Dardis 
167618148671SHrvoje Varga static DecodeStatus DecodeSynciR6(MCInst &Inst,
167718148671SHrvoje Varga                                   unsigned Insn,
167818148671SHrvoje Varga                                   uint64_t Address,
167918148671SHrvoje Varga                                   const void *Decoder) {
168018148671SHrvoje Varga   int Immediate = SignExtend32<16>(Insn & 0xffff);
168118148671SHrvoje Varga   unsigned Base = fieldFromInstruction(Insn, 16, 5);
168218148671SHrvoje Varga 
168318148671SHrvoje Varga   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
168418148671SHrvoje Varga 
168518148671SHrvoje Varga   Inst.addOperand(MCOperand::createReg(Base));
168618148671SHrvoje Varga   Inst.addOperand(MCOperand::createImm(Immediate));
168718148671SHrvoje Varga 
168818148671SHrvoje Varga   return MCDisassembler::Success;
168918148671SHrvoje Varga }
169018148671SHrvoje Varga 
1691fe0bf9f6SMatheus Almeida static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn,
1692fe0bf9f6SMatheus Almeida                                     uint64_t Address, const void *Decoder) {
1693fe0bf9f6SMatheus Almeida   int Offset = SignExtend32<10>(fieldFromInstruction(Insn, 16, 10));
1694fe0bf9f6SMatheus Almeida   unsigned Reg = fieldFromInstruction(Insn, 6, 5);
1695fe0bf9f6SMatheus Almeida   unsigned Base = fieldFromInstruction(Insn, 11, 5);
1696fe0bf9f6SMatheus Almeida 
1697fe0bf9f6SMatheus Almeida   Reg = getReg(Decoder, Mips::MSA128BRegClassID, Reg);
1698fe0bf9f6SMatheus Almeida   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1699fe0bf9f6SMatheus Almeida 
1700e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1701e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
17026b59c449SMatheus Almeida 
17036b59c449SMatheus Almeida   // The immediate field of an LD/ST instruction is scaled which means it must
17046b59c449SMatheus Almeida   // be multiplied (when decoding) by the size (in bytes) of the instructions'
17056b59c449SMatheus Almeida   // data format.
17066b59c449SMatheus Almeida   // .b - 1 byte
17076b59c449SMatheus Almeida   // .h - 2 bytes
17086b59c449SMatheus Almeida   // .w - 4 bytes
17096b59c449SMatheus Almeida   // .d - 8 bytes
17106b59c449SMatheus Almeida   switch(Inst.getOpcode())
17116b59c449SMatheus Almeida   {
17126b59c449SMatheus Almeida   default:
1713926883e1SEugene Zelenko     assert(false && "Unexpected instruction");
17146b59c449SMatheus Almeida     return MCDisassembler::Fail;
17156b59c449SMatheus Almeida     break;
17166b59c449SMatheus Almeida   case Mips::LD_B:
17176b59c449SMatheus Almeida   case Mips::ST_B:
1718e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(Offset));
17196b59c449SMatheus Almeida     break;
17206b59c449SMatheus Almeida   case Mips::LD_H:
17216b59c449SMatheus Almeida   case Mips::ST_H:
1722e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(Offset * 2));
17236b59c449SMatheus Almeida     break;
17246b59c449SMatheus Almeida   case Mips::LD_W:
17256b59c449SMatheus Almeida   case Mips::ST_W:
1726e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(Offset * 4));
17276b59c449SMatheus Almeida     break;
17286b59c449SMatheus Almeida   case Mips::LD_D:
17296b59c449SMatheus Almeida   case Mips::ST_D:
1730e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(Offset * 8));
17316b59c449SMatheus Almeida     break;
17326b59c449SMatheus Almeida   }
1733fe0bf9f6SMatheus Almeida 
1734fe0bf9f6SMatheus Almeida   return MCDisassembler::Success;
1735fe0bf9f6SMatheus Almeida }
1736fe0bf9f6SMatheus Almeida 
1737315e7ecaSJozef Kolek static DecodeStatus DecodeMemMMImm4(MCInst &Inst,
1738315e7ecaSJozef Kolek                                     unsigned Insn,
1739315e7ecaSJozef Kolek                                     uint64_t Address,
1740315e7ecaSJozef Kolek                                     const void *Decoder) {
1741315e7ecaSJozef Kolek   unsigned Offset = Insn & 0xf;
1742315e7ecaSJozef Kolek   unsigned Reg = fieldFromInstruction(Insn, 7, 3);
1743315e7ecaSJozef Kolek   unsigned Base = fieldFromInstruction(Insn, 4, 3);
1744315e7ecaSJozef Kolek 
1745315e7ecaSJozef Kolek   switch (Inst.getOpcode()) {
1746315e7ecaSJozef Kolek     case Mips::LBU16_MM:
1747315e7ecaSJozef Kolek     case Mips::LHU16_MM:
1748315e7ecaSJozef Kolek     case Mips::LW16_MM:
1749315e7ecaSJozef Kolek       if (DecodeGPRMM16RegisterClass(Inst, Reg, Address, Decoder)
1750315e7ecaSJozef Kolek             == MCDisassembler::Fail)
1751315e7ecaSJozef Kolek         return MCDisassembler::Fail;
1752315e7ecaSJozef Kolek       break;
1753315e7ecaSJozef Kolek     case Mips::SB16_MM:
1754797c2aecSZlatko Buljan     case Mips::SB16_MMR6:
1755315e7ecaSJozef Kolek     case Mips::SH16_MM:
1756797c2aecSZlatko Buljan     case Mips::SH16_MMR6:
1757315e7ecaSJozef Kolek     case Mips::SW16_MM:
1758797c2aecSZlatko Buljan     case Mips::SW16_MMR6:
1759315e7ecaSJozef Kolek       if (DecodeGPRMM16ZeroRegisterClass(Inst, Reg, Address, Decoder)
1760315e7ecaSJozef Kolek             == MCDisassembler::Fail)
1761315e7ecaSJozef Kolek         return MCDisassembler::Fail;
1762315e7ecaSJozef Kolek       break;
1763315e7ecaSJozef Kolek   }
1764315e7ecaSJozef Kolek 
1765315e7ecaSJozef Kolek   if (DecodeGPRMM16RegisterClass(Inst, Base, Address, Decoder)
1766315e7ecaSJozef Kolek         == MCDisassembler::Fail)
1767315e7ecaSJozef Kolek     return MCDisassembler::Fail;
1768315e7ecaSJozef Kolek 
1769315e7ecaSJozef Kolek   switch (Inst.getOpcode()) {
1770315e7ecaSJozef Kolek     case Mips::LBU16_MM:
1771315e7ecaSJozef Kolek       if (Offset == 0xf)
1772e9119e41SJim Grosbach         Inst.addOperand(MCOperand::createImm(-1));
1773315e7ecaSJozef Kolek       else
1774e9119e41SJim Grosbach         Inst.addOperand(MCOperand::createImm(Offset));
1775315e7ecaSJozef Kolek       break;
1776315e7ecaSJozef Kolek     case Mips::SB16_MM:
1777797c2aecSZlatko Buljan     case Mips::SB16_MMR6:
1778e9119e41SJim Grosbach       Inst.addOperand(MCOperand::createImm(Offset));
1779315e7ecaSJozef Kolek       break;
1780315e7ecaSJozef Kolek     case Mips::LHU16_MM:
1781315e7ecaSJozef Kolek     case Mips::SH16_MM:
1782797c2aecSZlatko Buljan     case Mips::SH16_MMR6:
1783e9119e41SJim Grosbach       Inst.addOperand(MCOperand::createImm(Offset << 1));
1784315e7ecaSJozef Kolek       break;
1785315e7ecaSJozef Kolek     case Mips::LW16_MM:
1786315e7ecaSJozef Kolek     case Mips::SW16_MM:
1787797c2aecSZlatko Buljan     case Mips::SW16_MMR6:
1788e9119e41SJim Grosbach       Inst.addOperand(MCOperand::createImm(Offset << 2));
1789315e7ecaSJozef Kolek       break;
1790315e7ecaSJozef Kolek   }
1791315e7ecaSJozef Kolek 
1792315e7ecaSJozef Kolek   return MCDisassembler::Success;
1793315e7ecaSJozef Kolek }
1794315e7ecaSJozef Kolek 
179512c6982bSJozef Kolek static DecodeStatus DecodeMemMMSPImm5Lsl2(MCInst &Inst,
179612c6982bSJozef Kolek                                           unsigned Insn,
179712c6982bSJozef Kolek                                           uint64_t Address,
179812c6982bSJozef Kolek                                           const void *Decoder) {
179912c6982bSJozef Kolek   unsigned Offset = Insn & 0x1F;
180012c6982bSJozef Kolek   unsigned Reg = fieldFromInstruction(Insn, 5, 5);
180112c6982bSJozef Kolek 
180212c6982bSJozef Kolek   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
180312c6982bSJozef Kolek 
1804e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1805e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Mips::SP));
1806e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset << 2));
180712c6982bSJozef Kolek 
180812c6982bSJozef Kolek   return MCDisassembler::Success;
180912c6982bSJozef Kolek }
181012c6982bSJozef Kolek 
1811e10a02ecSJozef Kolek static DecodeStatus DecodeMemMMGPImm7Lsl2(MCInst &Inst,
1812e10a02ecSJozef Kolek                                           unsigned Insn,
1813e10a02ecSJozef Kolek                                           uint64_t Address,
1814e10a02ecSJozef Kolek                                           const void *Decoder) {
1815e10a02ecSJozef Kolek   unsigned Offset = Insn & 0x7F;
1816e10a02ecSJozef Kolek   unsigned Reg = fieldFromInstruction(Insn, 7, 3);
1817e10a02ecSJozef Kolek 
1818e10a02ecSJozef Kolek   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1819e10a02ecSJozef Kolek 
1820e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1821e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Mips::GP));
1822e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset << 2));
1823e10a02ecSJozef Kolek 
1824e10a02ecSJozef Kolek   return MCDisassembler::Success;
1825e10a02ecSJozef Kolek }
1826e10a02ecSJozef Kolek 
1827d68d424aSJozef Kolek static DecodeStatus DecodeMemMMReglistImm4Lsl2(MCInst &Inst,
1828d68d424aSJozef Kolek                                                unsigned Insn,
1829d68d424aSJozef Kolek                                                uint64_t Address,
1830d68d424aSJozef Kolek                                                const void *Decoder) {
1831797c2aecSZlatko Buljan   int Offset;
1832797c2aecSZlatko Buljan   switch (Inst.getOpcode()) {
1833797c2aecSZlatko Buljan   case Mips::LWM16_MMR6:
1834797c2aecSZlatko Buljan   case Mips::SWM16_MMR6:
1835797c2aecSZlatko Buljan     Offset = fieldFromInstruction(Insn, 4, 4);
1836797c2aecSZlatko Buljan     break;
1837797c2aecSZlatko Buljan   default:
1838797c2aecSZlatko Buljan     Offset = SignExtend32<4>(Insn & 0xf);
1839797c2aecSZlatko Buljan     break;
1840797c2aecSZlatko Buljan   }
1841d68d424aSJozef Kolek 
1842d68d424aSJozef Kolek   if (DecodeRegListOperand16(Inst, Insn, Address, Decoder)
1843d68d424aSJozef Kolek       == MCDisassembler::Fail)
1844d68d424aSJozef Kolek     return MCDisassembler::Fail;
1845d68d424aSJozef Kolek 
1846e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Mips::SP));
1847e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset << 2));
1848d68d424aSJozef Kolek 
1849d68d424aSJozef Kolek   return MCDisassembler::Success;
1850d68d424aSJozef Kolek }
1851d68d424aSJozef Kolek 
1852a6593ff6SZoran Jovanovic static DecodeStatus DecodeMemMMImm9(MCInst &Inst,
1853a6593ff6SZoran Jovanovic                                     unsigned Insn,
1854a6593ff6SZoran Jovanovic                                     uint64_t Address,
1855a6593ff6SZoran Jovanovic                                     const void *Decoder) {
1856a6593ff6SZoran Jovanovic   int Offset = SignExtend32<9>(Insn & 0x1ff);
1857a6593ff6SZoran Jovanovic   unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1858a6593ff6SZoran Jovanovic   unsigned Base = fieldFromInstruction(Insn, 16, 5);
1859a6593ff6SZoran Jovanovic 
1860a6593ff6SZoran Jovanovic   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1861a6593ff6SZoran Jovanovic   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1862a6593ff6SZoran Jovanovic 
18633ef4dd7bSHrvoje Varga   if (Inst.getOpcode() == Mips::SCE_MM)
18643ef4dd7bSHrvoje Varga     Inst.addOperand(MCOperand::createReg(Reg));
18653ef4dd7bSHrvoje Varga 
1866a6593ff6SZoran Jovanovic   Inst.addOperand(MCOperand::createReg(Reg));
1867a6593ff6SZoran Jovanovic   Inst.addOperand(MCOperand::createReg(Base));
1868a6593ff6SZoran Jovanovic   Inst.addOperand(MCOperand::createImm(Offset));
1869a6593ff6SZoran Jovanovic 
1870a6593ff6SZoran Jovanovic   return MCDisassembler::Success;
1871a6593ff6SZoran Jovanovic }
1872a6593ff6SZoran Jovanovic 
1873dde3d582SVladimir Medic static DecodeStatus DecodeMemMMImm12(MCInst &Inst,
1874dde3d582SVladimir Medic                                      unsigned Insn,
1875dde3d582SVladimir Medic                                      uint64_t Address,
1876dde3d582SVladimir Medic                                      const void *Decoder) {
1877dde3d582SVladimir Medic   int Offset = SignExtend32<12>(Insn & 0x0fff);
1878dde3d582SVladimir Medic   unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1879dde3d582SVladimir Medic   unsigned Base = fieldFromInstruction(Insn, 16, 5);
1880dde3d582SVladimir Medic 
1881dde3d582SVladimir Medic   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1882dde3d582SVladimir Medic   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1883dde3d582SVladimir Medic 
1884a4c4b5fcSZoran Jovanovic   switch (Inst.getOpcode()) {
1885a4c4b5fcSZoran Jovanovic   case Mips::SWM32_MM:
1886a4c4b5fcSZoran Jovanovic   case Mips::LWM32_MM:
1887a4c4b5fcSZoran Jovanovic     if (DecodeRegListOperand(Inst, Insn, Address, Decoder)
1888a4c4b5fcSZoran Jovanovic         == MCDisassembler::Fail)
1889a4c4b5fcSZoran Jovanovic       return MCDisassembler::Fail;
1890e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Base));
1891e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(Offset));
1892a4c4b5fcSZoran Jovanovic     break;
1893a4c4b5fcSZoran Jovanovic   case Mips::SC_MM:
1894e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Reg));
1895b03fd12cSJustin Bogner     LLVM_FALLTHROUGH;
1896a4c4b5fcSZoran Jovanovic   default:
1897e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Reg));
1898ba553a6eSZlatko Buljan     if (Inst.getOpcode() == Mips::LWP_MM || Inst.getOpcode() == Mips::SWP_MM ||
1899ba553a6eSZlatko Buljan         Inst.getOpcode() == Mips::LWP_MMR6 || Inst.getOpcode() == Mips::SWP_MMR6)
1900e9119e41SJim Grosbach       Inst.addOperand(MCOperand::createReg(Reg+1));
19012deca348SZoran Jovanovic 
1902e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Base));
1903e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(Offset));
1904a4c4b5fcSZoran Jovanovic   }
1905dde3d582SVladimir Medic 
1906dde3d582SVladimir Medic   return MCDisassembler::Success;
1907dde3d582SVladimir Medic }
1908dde3d582SVladimir Medic 
1909dde3d582SVladimir Medic static DecodeStatus DecodeMemMMImm16(MCInst &Inst,
1910dde3d582SVladimir Medic                                      unsigned Insn,
1911dde3d582SVladimir Medic                                      uint64_t Address,
1912dde3d582SVladimir Medic                                      const void *Decoder) {
1913dde3d582SVladimir Medic   int Offset = SignExtend32<16>(Insn & 0xffff);
1914dde3d582SVladimir Medic   unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1915dde3d582SVladimir Medic   unsigned Base = fieldFromInstruction(Insn, 16, 5);
1916dde3d582SVladimir Medic 
1917dde3d582SVladimir Medic   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1918dde3d582SVladimir Medic   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1919dde3d582SVladimir Medic 
1920e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1921e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1922e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
1923dde3d582SVladimir Medic 
1924dde3d582SVladimir Medic   return MCDisassembler::Success;
1925dde3d582SVladimir Medic }
1926dde3d582SVladimir Medic 
192771928e68SAkira Hatanaka static DecodeStatus DecodeFMem(MCInst &Inst,
192871928e68SAkira Hatanaka                                unsigned Insn,
192971928e68SAkira Hatanaka                                uint64_t Address,
193071928e68SAkira Hatanaka                                const void *Decoder) {
193171928e68SAkira Hatanaka   int Offset = SignExtend32<16>(Insn & 0xffff);
1932ecaef49fSJim Grosbach   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1933ecaef49fSJim Grosbach   unsigned Base = fieldFromInstruction(Insn, 21, 5);
193471928e68SAkira Hatanaka 
19359bf2b567SAkira Hatanaka   Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg);
193613e6ccf3SAkira Hatanaka   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
19379bf2b567SAkira Hatanaka 
1938e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1939e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1940e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
194171928e68SAkira Hatanaka 
194271928e68SAkira Hatanaka   return MCDisassembler::Success;
194371928e68SAkira Hatanaka }
194471928e68SAkira Hatanaka 
1945cba9f80bSZlatko Buljan static DecodeStatus DecodeFMemMMR2(MCInst &Inst, unsigned Insn,
1946cba9f80bSZlatko Buljan                                    uint64_t Address, const void *Decoder) {
1947cba9f80bSZlatko Buljan   // This function is the same as DecodeFMem but with the Reg and Base fields
1948cba9f80bSZlatko Buljan   // swapped according to microMIPS spec.
1949cba9f80bSZlatko Buljan   int Offset = SignExtend32<16>(Insn & 0xffff);
1950cba9f80bSZlatko Buljan   unsigned Base = fieldFromInstruction(Insn, 16, 5);
1951cba9f80bSZlatko Buljan   unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1952cba9f80bSZlatko Buljan 
1953cba9f80bSZlatko Buljan   Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg);
1954cba9f80bSZlatko Buljan   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1955cba9f80bSZlatko Buljan 
1956cba9f80bSZlatko Buljan   Inst.addOperand(MCOperand::createReg(Reg));
1957cba9f80bSZlatko Buljan   Inst.addOperand(MCOperand::createReg(Base));
1958cba9f80bSZlatko Buljan   Inst.addOperand(MCOperand::createImm(Offset));
1959cba9f80bSZlatko Buljan 
1960cba9f80bSZlatko Buljan   return MCDisassembler::Success;
1961cba9f80bSZlatko Buljan }
1962cba9f80bSZlatko Buljan 
196392db6b78SDaniel Sanders static DecodeStatus DecodeFMem2(MCInst &Inst,
196492db6b78SDaniel Sanders                                unsigned Insn,
196592db6b78SDaniel Sanders                                uint64_t Address,
196692db6b78SDaniel Sanders                                const void *Decoder) {
196792db6b78SDaniel Sanders   int Offset = SignExtend32<16>(Insn & 0xffff);
196892db6b78SDaniel Sanders   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
196992db6b78SDaniel Sanders   unsigned Base = fieldFromInstruction(Insn, 21, 5);
197092db6b78SDaniel Sanders 
197192db6b78SDaniel Sanders   Reg = getReg(Decoder, Mips::COP2RegClassID, Reg);
197292db6b78SDaniel Sanders   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
197392db6b78SDaniel Sanders 
1974e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1975e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1976e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
197792db6b78SDaniel Sanders 
197892db6b78SDaniel Sanders   return MCDisassembler::Success;
197992db6b78SDaniel Sanders }
198092db6b78SDaniel Sanders 
198192db6b78SDaniel Sanders static DecodeStatus DecodeFMem3(MCInst &Inst,
198292db6b78SDaniel Sanders                                unsigned Insn,
198392db6b78SDaniel Sanders                                uint64_t Address,
198492db6b78SDaniel Sanders                                const void *Decoder) {
198592db6b78SDaniel Sanders   int Offset = SignExtend32<16>(Insn & 0xffff);
198692db6b78SDaniel Sanders   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
198792db6b78SDaniel Sanders   unsigned Base = fieldFromInstruction(Insn, 21, 5);
198892db6b78SDaniel Sanders 
198992db6b78SDaniel Sanders   Reg = getReg(Decoder, Mips::COP3RegClassID, Reg);
199092db6b78SDaniel Sanders   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
199192db6b78SDaniel Sanders 
1992e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1993e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1994e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
199592db6b78SDaniel Sanders 
199692db6b78SDaniel Sanders   return MCDisassembler::Success;
199792db6b78SDaniel Sanders }
199892db6b78SDaniel Sanders 
1999435cf8a4SVladimir Medic static DecodeStatus DecodeFMemCop2R6(MCInst &Inst,
2000435cf8a4SVladimir Medic                                     unsigned Insn,
2001435cf8a4SVladimir Medic                                     uint64_t Address,
2002435cf8a4SVladimir Medic                                     const void *Decoder) {
2003435cf8a4SVladimir Medic   int Offset = SignExtend32<11>(Insn & 0x07ff);
2004435cf8a4SVladimir Medic   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
2005435cf8a4SVladimir Medic   unsigned Base = fieldFromInstruction(Insn, 11, 5);
2006435cf8a4SVladimir Medic 
2007435cf8a4SVladimir Medic   Reg = getReg(Decoder, Mips::COP2RegClassID, Reg);
2008435cf8a4SVladimir Medic   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
2009435cf8a4SVladimir Medic 
2010e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
2011e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
2012e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
2013435cf8a4SVladimir Medic 
2014435cf8a4SVladimir Medic   return MCDisassembler::Success;
2015435cf8a4SVladimir Medic }
2016cba9f80bSZlatko Buljan 
2017cba9f80bSZlatko Buljan static DecodeStatus DecodeFMemCop2MMR6(MCInst &Inst, unsigned Insn,
2018cba9f80bSZlatko Buljan                                        uint64_t Address, const void *Decoder) {
2019cba9f80bSZlatko Buljan   int Offset = SignExtend32<11>(Insn & 0x07ff);
2020cba9f80bSZlatko Buljan   unsigned Reg = fieldFromInstruction(Insn, 21, 5);
2021cba9f80bSZlatko Buljan   unsigned Base = fieldFromInstruction(Insn, 16, 5);
2022cba9f80bSZlatko Buljan 
2023cba9f80bSZlatko Buljan   Reg = getReg(Decoder, Mips::COP2RegClassID, Reg);
2024cba9f80bSZlatko Buljan   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
2025cba9f80bSZlatko Buljan 
2026cba9f80bSZlatko Buljan   Inst.addOperand(MCOperand::createReg(Reg));
2027cba9f80bSZlatko Buljan   Inst.addOperand(MCOperand::createReg(Base));
2028cba9f80bSZlatko Buljan   Inst.addOperand(MCOperand::createImm(Offset));
2029cba9f80bSZlatko Buljan 
2030cba9f80bSZlatko Buljan   return MCDisassembler::Success;
2031cba9f80bSZlatko Buljan }
2032cba9f80bSZlatko Buljan 
20336a803f61SDaniel Sanders static DecodeStatus DecodeSpecial3LlSc(MCInst &Inst,
20346a803f61SDaniel Sanders                                        unsigned Insn,
20356a803f61SDaniel Sanders                                        uint64_t Address,
20366a803f61SDaniel Sanders                                        const void *Decoder) {
20376a803f61SDaniel Sanders   int64_t Offset = SignExtend64<9>((Insn >> 7) & 0x1ff);
20386a803f61SDaniel Sanders   unsigned Rt = fieldFromInstruction(Insn, 16, 5);
20396a803f61SDaniel Sanders   unsigned Base = fieldFromInstruction(Insn, 21, 5);
20406a803f61SDaniel Sanders 
20416a803f61SDaniel Sanders   Rt = getReg(Decoder, Mips::GPR32RegClassID, Rt);
20426a803f61SDaniel Sanders   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
20436a803f61SDaniel Sanders 
20446a803f61SDaniel Sanders   if(Inst.getOpcode() == Mips::SC_R6 || Inst.getOpcode() == Mips::SCD_R6){
2045e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Rt));
20466a803f61SDaniel Sanders   }
20476a803f61SDaniel Sanders 
2048e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Rt));
2049e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
2050e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
20516a803f61SDaniel Sanders 
20526a803f61SDaniel Sanders   return MCDisassembler::Success;
20536a803f61SDaniel Sanders }
205471928e68SAkira Hatanaka 
205571928e68SAkira Hatanaka static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
205671928e68SAkira Hatanaka                                               unsigned RegNo,
205771928e68SAkira Hatanaka                                               uint64_t Address,
205871928e68SAkira Hatanaka                                               const void *Decoder) {
205971928e68SAkira Hatanaka   // Currently only hardware register 29 is supported.
206071928e68SAkira Hatanaka   if (RegNo != 29)
206171928e68SAkira Hatanaka     return  MCDisassembler::Fail;
2062e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Mips::HWR29));
206371928e68SAkira Hatanaka   return MCDisassembler::Success;
206471928e68SAkira Hatanaka }
206571928e68SAkira Hatanaka 
206671928e68SAkira Hatanaka static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
206771928e68SAkira Hatanaka                                               unsigned RegNo,
206871928e68SAkira Hatanaka                                               uint64_t Address,
206971928e68SAkira Hatanaka                                               const void *Decoder) {
20709bf2b567SAkira Hatanaka   if (RegNo > 30 || RegNo %2)
207171928e68SAkira Hatanaka     return MCDisassembler::Fail;
207271928e68SAkira Hatanaka 
20739bf2b567SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::AFGR64RegClassID, RegNo /2);
2074e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
207571928e68SAkira Hatanaka   return MCDisassembler::Success;
207671928e68SAkira Hatanaka }
207771928e68SAkira Hatanaka 
207800fcf2e1SAkira Hatanaka static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst,
2079ecabd1a5SAkira Hatanaka                                                 unsigned RegNo,
2080ecabd1a5SAkira Hatanaka                                                 uint64_t Address,
2081ecabd1a5SAkira Hatanaka                                                 const void *Decoder) {
2082ecabd1a5SAkira Hatanaka   if (RegNo >= 4)
2083ecabd1a5SAkira Hatanaka     return MCDisassembler::Fail;
2084ecabd1a5SAkira Hatanaka 
208500fcf2e1SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::ACC64DSPRegClassID, RegNo);
2086e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
2087ecabd1a5SAkira Hatanaka   return MCDisassembler::Success;
2088ecabd1a5SAkira Hatanaka }
2089ecabd1a5SAkira Hatanaka 
20908002a3f6SAkira Hatanaka static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst,
209159bfaf77SAkira Hatanaka                                                unsigned RegNo,
209259bfaf77SAkira Hatanaka                                                uint64_t Address,
209359bfaf77SAkira Hatanaka                                                const void *Decoder) {
209459bfaf77SAkira Hatanaka   if (RegNo >= 4)
209559bfaf77SAkira Hatanaka     return MCDisassembler::Fail;
209659bfaf77SAkira Hatanaka 
20978002a3f6SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::HI32DSPRegClassID, RegNo);
2098e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
209959bfaf77SAkira Hatanaka   return MCDisassembler::Success;
210059bfaf77SAkira Hatanaka }
210159bfaf77SAkira Hatanaka 
21028002a3f6SAkira Hatanaka static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst,
210359bfaf77SAkira Hatanaka                                                unsigned RegNo,
210459bfaf77SAkira Hatanaka                                                uint64_t Address,
210559bfaf77SAkira Hatanaka                                                const void *Decoder) {
210659bfaf77SAkira Hatanaka   if (RegNo >= 4)
210759bfaf77SAkira Hatanaka     return MCDisassembler::Fail;
210859bfaf77SAkira Hatanaka 
21098002a3f6SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::LO32DSPRegClassID, RegNo);
2110e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
211159bfaf77SAkira Hatanaka   return MCDisassembler::Success;
211259bfaf77SAkira Hatanaka }
211359bfaf77SAkira Hatanaka 
21143eb663b0SJack Carter static DecodeStatus DecodeMSA128BRegisterClass(MCInst &Inst,
21153eb663b0SJack Carter                                                unsigned RegNo,
21163eb663b0SJack Carter                                                uint64_t Address,
21173eb663b0SJack Carter                                                const void *Decoder) {
21183eb663b0SJack Carter   if (RegNo > 31)
21193eb663b0SJack Carter     return MCDisassembler::Fail;
21203eb663b0SJack Carter 
21213eb663b0SJack Carter   unsigned Reg = getReg(Decoder, Mips::MSA128BRegClassID, RegNo);
2122e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
21233eb663b0SJack Carter   return MCDisassembler::Success;
21243eb663b0SJack Carter }
21253eb663b0SJack Carter 
21265dc8ac92SJack Carter static DecodeStatus DecodeMSA128HRegisterClass(MCInst &Inst,
21275dc8ac92SJack Carter                                                unsigned RegNo,
21285dc8ac92SJack Carter                                                uint64_t Address,
21295dc8ac92SJack Carter                                                const void *Decoder) {
21305dc8ac92SJack Carter   if (RegNo > 31)
21315dc8ac92SJack Carter     return MCDisassembler::Fail;
21325dc8ac92SJack Carter 
21335dc8ac92SJack Carter   unsigned Reg = getReg(Decoder, Mips::MSA128HRegClassID, RegNo);
2134e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
21355dc8ac92SJack Carter   return MCDisassembler::Success;
21365dc8ac92SJack Carter }
21375dc8ac92SJack Carter 
21385dc8ac92SJack Carter static DecodeStatus DecodeMSA128WRegisterClass(MCInst &Inst,
21395dc8ac92SJack Carter                                                unsigned RegNo,
21405dc8ac92SJack Carter                                                uint64_t Address,
21415dc8ac92SJack Carter                                                const void *Decoder) {
21425dc8ac92SJack Carter   if (RegNo > 31)
21435dc8ac92SJack Carter     return MCDisassembler::Fail;
21445dc8ac92SJack Carter 
21455dc8ac92SJack Carter   unsigned Reg = getReg(Decoder, Mips::MSA128WRegClassID, RegNo);
2146e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
21475dc8ac92SJack Carter   return MCDisassembler::Success;
21485dc8ac92SJack Carter }
21495dc8ac92SJack Carter 
21505dc8ac92SJack Carter static DecodeStatus DecodeMSA128DRegisterClass(MCInst &Inst,
21515dc8ac92SJack Carter                                                unsigned RegNo,
21525dc8ac92SJack Carter                                                uint64_t Address,
21535dc8ac92SJack Carter                                                const void *Decoder) {
21545dc8ac92SJack Carter   if (RegNo > 31)
21555dc8ac92SJack Carter     return MCDisassembler::Fail;
21565dc8ac92SJack Carter 
21575dc8ac92SJack Carter   unsigned Reg = getReg(Decoder, Mips::MSA128DRegClassID, RegNo);
2158e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
21595dc8ac92SJack Carter   return MCDisassembler::Success;
21605dc8ac92SJack Carter }
21615dc8ac92SJack Carter 
2162a591fdc6SMatheus Almeida static DecodeStatus DecodeMSACtrlRegisterClass(MCInst &Inst,
2163a591fdc6SMatheus Almeida                                                unsigned RegNo,
2164a591fdc6SMatheus Almeida                                                uint64_t Address,
2165a591fdc6SMatheus Almeida                                                const void *Decoder) {
2166a591fdc6SMatheus Almeida   if (RegNo > 7)
2167a591fdc6SMatheus Almeida     return MCDisassembler::Fail;
2168a591fdc6SMatheus Almeida 
2169a591fdc6SMatheus Almeida   unsigned Reg = getReg(Decoder, Mips::MSACtrlRegClassID, RegNo);
2170e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
2171a591fdc6SMatheus Almeida   return MCDisassembler::Success;
2172a591fdc6SMatheus Almeida }
2173a591fdc6SMatheus Almeida 
2174a3134faeSDaniel Sanders static DecodeStatus DecodeCOP0RegisterClass(MCInst &Inst,
2175a3134faeSDaniel Sanders                                             unsigned RegNo,
2176a3134faeSDaniel Sanders                                             uint64_t Address,
2177a3134faeSDaniel Sanders                                             const void *Decoder) {
2178a3134faeSDaniel Sanders   if (RegNo > 31)
2179a3134faeSDaniel Sanders     return MCDisassembler::Fail;
2180a3134faeSDaniel Sanders 
2181a3134faeSDaniel Sanders   unsigned Reg = getReg(Decoder, Mips::COP0RegClassID, RegNo);
2182a3134faeSDaniel Sanders   Inst.addOperand(MCOperand::createReg(Reg));
2183a3134faeSDaniel Sanders   return MCDisassembler::Success;
2184a3134faeSDaniel Sanders }
2185a3134faeSDaniel Sanders 
21862a83d680SDaniel Sanders static DecodeStatus DecodeCOP2RegisterClass(MCInst &Inst,
21872a83d680SDaniel Sanders                                             unsigned RegNo,
21882a83d680SDaniel Sanders                                             uint64_t Address,
21892a83d680SDaniel Sanders                                             const void *Decoder) {
21902a83d680SDaniel Sanders   if (RegNo > 31)
21912a83d680SDaniel Sanders     return MCDisassembler::Fail;
21922a83d680SDaniel Sanders 
21932a83d680SDaniel Sanders   unsigned Reg = getReg(Decoder, Mips::COP2RegClassID, RegNo);
2194e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
21952a83d680SDaniel Sanders   return MCDisassembler::Success;
21962a83d680SDaniel Sanders }
21972a83d680SDaniel Sanders 
219871928e68SAkira Hatanaka static DecodeStatus DecodeBranchTarget(MCInst &Inst,
219971928e68SAkira Hatanaka                                        unsigned Offset,
220071928e68SAkira Hatanaka                                        uint64_t Address,
220171928e68SAkira Hatanaka                                        const void *Decoder) {
2202d37bab61SAlexey Samsonov   int32_t BranchOffset = (SignExtend32<16>(Offset) * 4) + 4;
2203e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(BranchOffset));
220471928e68SAkira Hatanaka   return MCDisassembler::Success;
220571928e68SAkira Hatanaka }
220671928e68SAkira Hatanaka 
22076f09cdfdSHrvoje Varga static DecodeStatus DecodeBranchTarget1SImm16(MCInst &Inst,
22086f09cdfdSHrvoje Varga                                               unsigned Offset,
22096f09cdfdSHrvoje Varga                                               uint64_t Address,
22106f09cdfdSHrvoje Varga                                               const void *Decoder) {
22116f09cdfdSHrvoje Varga   int32_t BranchOffset = (SignExtend32<16>(Offset) * 2);
22126f09cdfdSHrvoje Varga   Inst.addOperand(MCOperand::createImm(BranchOffset));
22136f09cdfdSHrvoje Varga   return MCDisassembler::Success;
22146f09cdfdSHrvoje Varga }
22156f09cdfdSHrvoje Varga 
221671928e68SAkira Hatanaka static DecodeStatus DecodeJumpTarget(MCInst &Inst,
221771928e68SAkira Hatanaka                                      unsigned Insn,
221871928e68SAkira Hatanaka                                      uint64_t Address,
221971928e68SAkira Hatanaka                                      const void *Decoder) {
2220ecaef49fSJim Grosbach   unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 2;
2221e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(JumpOffset));
222271928e68SAkira Hatanaka   return MCDisassembler::Success;
222371928e68SAkira Hatanaka }
222471928e68SAkira Hatanaka 
22253c8869dcSZoran Jovanovic static DecodeStatus DecodeBranchTarget21(MCInst &Inst,
22263c8869dcSZoran Jovanovic                                          unsigned Offset,
22273c8869dcSZoran Jovanovic                                          uint64_t Address,
22283c8869dcSZoran Jovanovic                                          const void *Decoder) {
2229672c710dSSagar Thakur   int32_t BranchOffset = SignExtend32<21>(Offset) * 4 + 4;
22303c8869dcSZoran Jovanovic 
2231e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(BranchOffset));
22323c8869dcSZoran Jovanovic   return MCDisassembler::Success;
22333c8869dcSZoran Jovanovic }
22343c8869dcSZoran Jovanovic 
223584e4d59eSZoran Jovanovic static DecodeStatus DecodeBranchTarget21MM(MCInst &Inst,
223684e4d59eSZoran Jovanovic                                            unsigned Offset,
223784e4d59eSZoran Jovanovic                                            uint64_t Address,
223884e4d59eSZoran Jovanovic                                            const void *Decoder) {
2239f0ed16eaSHrvoje Varga   int32_t BranchOffset = SignExtend32<21>(Offset) * 4 + 4;
224084e4d59eSZoran Jovanovic 
224184e4d59eSZoran Jovanovic   Inst.addOperand(MCOperand::createImm(BranchOffset));
224284e4d59eSZoran Jovanovic   return MCDisassembler::Success;
224384e4d59eSZoran Jovanovic }
224484e4d59eSZoran Jovanovic 
22453c8869dcSZoran Jovanovic static DecodeStatus DecodeBranchTarget26(MCInst &Inst,
22463c8869dcSZoran Jovanovic                                          unsigned Offset,
22473c8869dcSZoran Jovanovic                                          uint64_t Address,
22483c8869dcSZoran Jovanovic                                          const void *Decoder) {
2249672c710dSSagar Thakur   int32_t BranchOffset = SignExtend32<26>(Offset) * 4 + 4;
22503c8869dcSZoran Jovanovic 
2251e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(BranchOffset));
22523c8869dcSZoran Jovanovic   return MCDisassembler::Success;
22533c8869dcSZoran Jovanovic }
22543c8869dcSZoran Jovanovic 
22559761e96bSJozef Kolek static DecodeStatus DecodeBranchTarget7MM(MCInst &Inst,
22569761e96bSJozef Kolek                                           unsigned Offset,
22579761e96bSJozef Kolek                                           uint64_t Address,
22589761e96bSJozef Kolek                                           const void *Decoder) {
225972982e69SSimon Atanasyan   int32_t BranchOffset = SignExtend32<8>(Offset << 1);
2260e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(BranchOffset));
22619761e96bSJozef Kolek   return MCDisassembler::Success;
22629761e96bSJozef Kolek }
22639761e96bSJozef Kolek 
22645cfebddeSJozef Kolek static DecodeStatus DecodeBranchTarget10MM(MCInst &Inst,
22655cfebddeSJozef Kolek                                            unsigned Offset,
22665cfebddeSJozef Kolek                                            uint64_t Address,
22675cfebddeSJozef Kolek                                            const void *Decoder) {
226872982e69SSimon Atanasyan   int32_t BranchOffset = SignExtend32<11>(Offset << 1);
2269e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(BranchOffset));
22705cfebddeSJozef Kolek   return MCDisassembler::Success;
22715cfebddeSJozef Kolek }
22725cfebddeSJozef Kolek 
22738a80aa76SZoran Jovanovic static DecodeStatus DecodeBranchTargetMM(MCInst &Inst,
22748a80aa76SZoran Jovanovic                                          unsigned Offset,
22758a80aa76SZoran Jovanovic                                          uint64_t Address,
22768a80aa76SZoran Jovanovic                                          const void *Decoder) {
2277f0ed16eaSHrvoje Varga   int32_t BranchOffset = SignExtend32<16>(Offset) * 2 + 4;
2278e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(BranchOffset));
22798a80aa76SZoran Jovanovic   return MCDisassembler::Success;
22808a80aa76SZoran Jovanovic }
22818a80aa76SZoran Jovanovic 
2282a887b361SZoran Jovanovic static DecodeStatus DecodeBranchTarget26MM(MCInst &Inst,
2283a887b361SZoran Jovanovic   unsigned Offset,
2284a887b361SZoran Jovanovic   uint64_t Address,
2285a887b361SZoran Jovanovic   const void *Decoder) {
228672982e69SSimon Atanasyan   int32_t BranchOffset = SignExtend32<27>(Offset << 1);
2287a887b361SZoran Jovanovic 
2288a887b361SZoran Jovanovic   Inst.addOperand(MCOperand::createImm(BranchOffset));
2289a887b361SZoran Jovanovic   return MCDisassembler::Success;
2290a887b361SZoran Jovanovic }
2291a887b361SZoran Jovanovic 
2292507e084aSZoran Jovanovic static DecodeStatus DecodeJumpTargetMM(MCInst &Inst,
2293507e084aSZoran Jovanovic                                        unsigned Insn,
2294507e084aSZoran Jovanovic                                        uint64_t Address,
2295507e084aSZoran Jovanovic                                        const void *Decoder) {
2296507e084aSZoran Jovanovic   unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 1;
2297e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(JumpOffset));
2298507e084aSZoran Jovanovic   return MCDisassembler::Success;
2299507e084aSZoran Jovanovic }
230071928e68SAkira Hatanaka 
2301aa2b9278SJozef Kolek static DecodeStatus DecodeAddiur2Simm7(MCInst &Inst,
2302aa2b9278SJozef Kolek                                        unsigned Value,
2303aa2b9278SJozef Kolek                                        uint64_t Address,
2304aa2b9278SJozef Kolek                                        const void *Decoder) {
2305aa2b9278SJozef Kolek   if (Value == 0)
2306e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(1));
2307aa2b9278SJozef Kolek   else if (Value == 0x7)
2308e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(-1));
2309aa2b9278SJozef Kolek   else
2310e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(Value << 2));
2311aa2b9278SJozef Kolek   return MCDisassembler::Success;
2312aa2b9278SJozef Kolek }
2313aa2b9278SJozef Kolek 
231497297770SDaniel Sanders static DecodeStatus DecodeLi16Imm(MCInst &Inst,
2315aa2b9278SJozef Kolek                                   unsigned Value,
2316aa2b9278SJozef Kolek                                   uint64_t Address,
2317aa2b9278SJozef Kolek                                   const void *Decoder) {
2318aa2b9278SJozef Kolek   if (Value == 0x7F)
2319e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(-1));
2320aa2b9278SJozef Kolek   else
2321e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(Value));
2322aa2b9278SJozef Kolek   return MCDisassembler::Success;
2323aa2b9278SJozef Kolek }
2324aa2b9278SJozef Kolek 
23256b28f09dSZoran Jovanovic static DecodeStatus DecodePOOL16BEncodedField(MCInst &Inst,
23266b28f09dSZoran Jovanovic                                               unsigned Value,
23276b28f09dSZoran Jovanovic                                               uint64_t Address,
23286b28f09dSZoran Jovanovic                                               const void *Decoder) {
23296b28f09dSZoran Jovanovic   Inst.addOperand(MCOperand::createImm(Value == 0x0 ? 8 : Value));
23306b28f09dSZoran Jovanovic   return MCDisassembler::Success;
23316b28f09dSZoran Jovanovic }
23326b28f09dSZoran Jovanovic 
233319b7f76aSDaniel Sanders template <unsigned Bits, int Offset, int Scale>
233419b7f76aSDaniel Sanders static DecodeStatus DecodeUImmWithOffsetAndScale(MCInst &Inst, unsigned Value,
2335779c5937SMatheus Almeida                                                  uint64_t Address,
2336779c5937SMatheus Almeida                                                  const void *Decoder) {
2337ea4f653dSDaniel Sanders   Value &= ((1 << Bits) - 1);
233819b7f76aSDaniel Sanders   Value *= Scale;
2339ea4f653dSDaniel Sanders   Inst.addOperand(MCOperand::createImm(Value + Offset));
2340779c5937SMatheus Almeida   return MCDisassembler::Success;
2341779c5937SMatheus Almeida }
2342779c5937SMatheus Almeida 
234397297770SDaniel Sanders template <unsigned Bits, int Offset, int ScaleBy>
234497297770SDaniel Sanders static DecodeStatus DecodeSImmWithOffsetAndScale(MCInst &Inst, unsigned Value,
234578e89020SDaniel Sanders                                                  uint64_t Address,
234678e89020SDaniel Sanders                                                  const void *Decoder) {
234797297770SDaniel Sanders   int32_t Imm = SignExtend32<Bits>(Value) * ScaleBy;
234878e89020SDaniel Sanders   Inst.addOperand(MCOperand::createImm(Imm + Offset));
234978e89020SDaniel Sanders   return MCDisassembler::Success;
235078e89020SDaniel Sanders }
235178e89020SDaniel Sanders 
235271928e68SAkira Hatanaka static DecodeStatus DecodeInsSize(MCInst &Inst,
235371928e68SAkira Hatanaka                                   unsigned Insn,
235471928e68SAkira Hatanaka                                   uint64_t Address,
235571928e68SAkira Hatanaka                                   const void *Decoder) {
235671928e68SAkira Hatanaka   // First we need to grab the pos(lsb) from MCInst.
23576f83ae38SSimon Dardis   // This function only handles the 32 bit variants of ins, as dins
23586f83ae38SSimon Dardis   // variants are handled differently.
235971928e68SAkira Hatanaka   int Pos = Inst.getOperand(2).getImm();
23606f83ae38SSimon Dardis   int Size = (int) Insn - Pos + 1;
2361e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(SignExtend32<16>(Size)));
236271928e68SAkira Hatanaka   return MCDisassembler::Success;
236371928e68SAkira Hatanaka }
236471928e68SAkira Hatanaka 
2365b59e1a41SDaniel Sanders static DecodeStatus DecodeSimm19Lsl2(MCInst &Inst, unsigned Insn,
2366b59e1a41SDaniel Sanders                                      uint64_t Address, const void *Decoder) {
2367e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(SignExtend32<19>(Insn) * 4));
2368b59e1a41SDaniel Sanders   return MCDisassembler::Success;
2369b59e1a41SDaniel Sanders }
23702855142aSZoran Jovanovic 
23712855142aSZoran Jovanovic static DecodeStatus DecodeSimm18Lsl3(MCInst &Inst, unsigned Insn,
23722855142aSZoran Jovanovic                                      uint64_t Address, const void *Decoder) {
2373e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(SignExtend32<18>(Insn) * 8));
23742855142aSZoran Jovanovic   return MCDisassembler::Success;
23752855142aSZoran Jovanovic }
2376a4c4b5fcSZoran Jovanovic 
2377b682ddf3SVladimir Medic static DecodeStatus DecodeSimm9SP(MCInst &Inst, unsigned Insn,
2378b682ddf3SVladimir Medic                                   uint64_t Address, const void *Decoder) {
2379b682ddf3SVladimir Medic   int32_t DecodedValue;
2380b682ddf3SVladimir Medic   switch (Insn) {
2381b682ddf3SVladimir Medic   case 0: DecodedValue = 256; break;
2382b682ddf3SVladimir Medic   case 1: DecodedValue = 257; break;
2383b682ddf3SVladimir Medic   case 510: DecodedValue = -258; break;
2384b682ddf3SVladimir Medic   case 511: DecodedValue = -257; break;
2385b682ddf3SVladimir Medic   default: DecodedValue = SignExtend32<9>(Insn); break;
2386b682ddf3SVladimir Medic   }
2387e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(DecodedValue * 4));
2388b682ddf3SVladimir Medic   return MCDisassembler::Success;
2389b682ddf3SVladimir Medic }
2390b682ddf3SVladimir Medic 
2391b682ddf3SVladimir Medic static DecodeStatus DecodeANDI16Imm(MCInst &Inst, unsigned Insn,
2392b682ddf3SVladimir Medic                                     uint64_t Address, const void *Decoder) {
2393b682ddf3SVladimir Medic   // Insn must be >= 0, since it is unsigned that condition is always true.
2394b682ddf3SVladimir Medic   assert(Insn < 16);
2395b682ddf3SVladimir Medic   int32_t DecodedValues[] = {128, 1, 2, 3, 4, 7, 8, 15, 16, 31, 32, 63, 64,
2396b682ddf3SVladimir Medic                              255, 32768, 65535};
2397e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(DecodedValues[Insn]));
2398b682ddf3SVladimir Medic   return MCDisassembler::Success;
2399b682ddf3SVladimir Medic }
2400b682ddf3SVladimir Medic 
2401a4c4b5fcSZoran Jovanovic static DecodeStatus DecodeRegListOperand(MCInst &Inst,
2402a4c4b5fcSZoran Jovanovic                                          unsigned Insn,
2403a4c4b5fcSZoran Jovanovic                                          uint64_t Address,
2404a4c4b5fcSZoran Jovanovic                                          const void *Decoder) {
2405a4c4b5fcSZoran Jovanovic   unsigned Regs[] = {Mips::S0, Mips::S1, Mips::S2, Mips::S3, Mips::S4, Mips::S5,
2406dc4b8c27SZoran Jovanovic                      Mips::S6, Mips::S7, Mips::FP};
2407a4c4b5fcSZoran Jovanovic   unsigned RegNum;
2408a4c4b5fcSZoran Jovanovic 
2409a4c4b5fcSZoran Jovanovic   unsigned RegLst = fieldFromInstruction(Insn, 21, 5);
2410df19a5e6SDaniel Sanders 
2411a4c4b5fcSZoran Jovanovic   // Empty register lists are not allowed.
2412a4c4b5fcSZoran Jovanovic   if (RegLst == 0)
2413a4c4b5fcSZoran Jovanovic     return MCDisassembler::Fail;
2414a4c4b5fcSZoran Jovanovic 
2415a4c4b5fcSZoran Jovanovic   RegNum = RegLst & 0xf;
2416df19a5e6SDaniel Sanders 
2417df19a5e6SDaniel Sanders   // RegLst values 10-15, and 26-31 are reserved.
2418df19a5e6SDaniel Sanders   if (RegNum > 9)
2419df19a5e6SDaniel Sanders     return MCDisassembler::Fail;
2420df19a5e6SDaniel Sanders 
2421a4c4b5fcSZoran Jovanovic   for (unsigned i = 0; i < RegNum; i++)
2422e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Regs[i]));
2423a4c4b5fcSZoran Jovanovic 
2424a4c4b5fcSZoran Jovanovic   if (RegLst & 0x10)
2425e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::RA));
2426a4c4b5fcSZoran Jovanovic 
2427a4c4b5fcSZoran Jovanovic   return MCDisassembler::Success;
2428a4c4b5fcSZoran Jovanovic }
2429f9a02500SZoran Jovanovic 
2430f9a02500SZoran Jovanovic static DecodeStatus DecodeRegListOperand16(MCInst &Inst, unsigned Insn,
2431f9a02500SZoran Jovanovic                                            uint64_t Address,
2432f9a02500SZoran Jovanovic                                            const void *Decoder) {
2433f9a02500SZoran Jovanovic   unsigned Regs[] = {Mips::S0, Mips::S1, Mips::S2, Mips::S3};
2434797c2aecSZlatko Buljan   unsigned RegLst;
2435797c2aecSZlatko Buljan   switch(Inst.getOpcode()) {
2436797c2aecSZlatko Buljan   default:
2437797c2aecSZlatko Buljan     RegLst = fieldFromInstruction(Insn, 4, 2);
2438797c2aecSZlatko Buljan     break;
2439797c2aecSZlatko Buljan   case Mips::LWM16_MMR6:
2440797c2aecSZlatko Buljan   case Mips::SWM16_MMR6:
2441797c2aecSZlatko Buljan     RegLst = fieldFromInstruction(Insn, 8, 2);
2442797c2aecSZlatko Buljan     break;
2443797c2aecSZlatko Buljan   }
2444d68d424aSJozef Kolek   unsigned RegNum = RegLst & 0x3;
2445f9a02500SZoran Jovanovic 
2446d68d424aSJozef Kolek   for (unsigned i = 0; i <= RegNum; i++)
2447e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Regs[i]));
2448f9a02500SZoran Jovanovic 
2449e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Mips::RA));
2450f9a02500SZoran Jovanovic 
2451f9a02500SZoran Jovanovic   return MCDisassembler::Success;
2452f9a02500SZoran Jovanovic }
24532c6d7320SJozef Kolek 
2454169df4e2SSimon Dardis static DecodeStatus DecodeMovePRegPair(MCInst &Inst, unsigned RegPair,
245541688679SZoran Jovanovic                                        uint64_t Address, const void *Decoder) {
245641688679SZoran Jovanovic   switch (RegPair) {
245741688679SZoran Jovanovic   default:
245841688679SZoran Jovanovic     return MCDisassembler::Fail;
245941688679SZoran Jovanovic   case 0:
2460e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A1));
2461e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A2));
246241688679SZoran Jovanovic     break;
246341688679SZoran Jovanovic   case 1:
2464e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A1));
2465e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A3));
246641688679SZoran Jovanovic     break;
246741688679SZoran Jovanovic   case 2:
2468e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A2));
2469e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A3));
247041688679SZoran Jovanovic     break;
247141688679SZoran Jovanovic   case 3:
2472e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A0));
2473e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::S5));
247441688679SZoran Jovanovic     break;
247541688679SZoran Jovanovic   case 4:
2476e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A0));
2477e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::S6));
247841688679SZoran Jovanovic     break;
247941688679SZoran Jovanovic   case 5:
2480e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A0));
2481e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A1));
248241688679SZoran Jovanovic     break;
248341688679SZoran Jovanovic   case 6:
2484e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A0));
2485e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A2));
248641688679SZoran Jovanovic     break;
248741688679SZoran Jovanovic   case 7:
2488e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A0));
2489e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A3));
249041688679SZoran Jovanovic     break;
249141688679SZoran Jovanovic   }
249241688679SZoran Jovanovic 
249341688679SZoran Jovanovic   return MCDisassembler::Success;
249441688679SZoran Jovanovic }
249541688679SZoran Jovanovic 
24962c6d7320SJozef Kolek static DecodeStatus DecodeSimm23Lsl2(MCInst &Inst, unsigned Insn,
24972c6d7320SJozef Kolek                                      uint64_t Address, const void *Decoder) {
24986499b5f0SJustin Bogner   Inst.addOperand(MCOperand::createImm(SignExtend32<25>(Insn << 2)));
24992c6d7320SJozef Kolek   return MCDisassembler::Success;
25002c6d7320SJozef Kolek }
2501fdbd0a37SZoran Jovanovic 
2502fdbd0a37SZoran Jovanovic template <typename InsnType>
2503fdbd0a37SZoran Jovanovic static DecodeStatus DecodeBgtzGroupBranchMMR6(MCInst &MI, InsnType insn,
2504fdbd0a37SZoran Jovanovic   uint64_t Address,
2505fdbd0a37SZoran Jovanovic   const void *Decoder) {
2506fdbd0a37SZoran Jovanovic   // We have:
2507fdbd0a37SZoran Jovanovic   //    0b000111 ttttt sssss iiiiiiiiiiiiiiii
2508fdbd0a37SZoran Jovanovic   //      Invalid      if rt == 0
2509fdbd0a37SZoran Jovanovic   //      BGTZALC_MMR6 if rs == 0 && rt != 0
2510fdbd0a37SZoran Jovanovic   //      BLTZALC_MMR6 if rs != 0 && rs == rt
2511fdbd0a37SZoran Jovanovic   //      BLTUC_MMR6   if rs != 0 && rs != rt
2512fdbd0a37SZoran Jovanovic 
2513fdbd0a37SZoran Jovanovic   InsnType Rt = fieldFromInstruction(insn, 21, 5);
2514fdbd0a37SZoran Jovanovic   InsnType Rs = fieldFromInstruction(insn, 16, 5);
2515f0ed16eaSHrvoje Varga   InsnType Imm = 0;
2516fdbd0a37SZoran Jovanovic   bool HasRs = false;
2517fdbd0a37SZoran Jovanovic   bool HasRt = false;
2518fdbd0a37SZoran Jovanovic 
2519fdbd0a37SZoran Jovanovic   if (Rt == 0)
2520fdbd0a37SZoran Jovanovic     return MCDisassembler::Fail;
2521fdbd0a37SZoran Jovanovic   else if (Rs == 0) {
2522fdbd0a37SZoran Jovanovic     MI.setOpcode(Mips::BGTZALC_MMR6);
2523fdbd0a37SZoran Jovanovic     HasRt = true;
2524f0ed16eaSHrvoje Varga     Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
2525fdbd0a37SZoran Jovanovic   }
2526fdbd0a37SZoran Jovanovic   else if (Rs == Rt) {
2527fdbd0a37SZoran Jovanovic     MI.setOpcode(Mips::BLTZALC_MMR6);
2528fdbd0a37SZoran Jovanovic     HasRs = true;
2529f0ed16eaSHrvoje Varga     Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
2530fdbd0a37SZoran Jovanovic   }
2531fdbd0a37SZoran Jovanovic   else {
2532fdbd0a37SZoran Jovanovic     MI.setOpcode(Mips::BLTUC_MMR6);
2533fdbd0a37SZoran Jovanovic     HasRs = true;
2534fdbd0a37SZoran Jovanovic     HasRt = true;
2535f0ed16eaSHrvoje Varga     Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
2536fdbd0a37SZoran Jovanovic   }
2537fdbd0a37SZoran Jovanovic 
2538fdbd0a37SZoran Jovanovic   if (HasRs)
2539fdbd0a37SZoran Jovanovic     MI.addOperand(
2540fdbd0a37SZoran Jovanovic     MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rs)));
2541fdbd0a37SZoran Jovanovic 
2542fdbd0a37SZoran Jovanovic   if (HasRt)
2543fdbd0a37SZoran Jovanovic     MI.addOperand(
2544fdbd0a37SZoran Jovanovic     MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rt)));
2545fdbd0a37SZoran Jovanovic 
2546fdbd0a37SZoran Jovanovic   MI.addOperand(MCOperand::createImm(Imm));
2547fdbd0a37SZoran Jovanovic 
2548fdbd0a37SZoran Jovanovic   return MCDisassembler::Success;
2549fdbd0a37SZoran Jovanovic }
2550fdbd0a37SZoran Jovanovic 
2551fdbd0a37SZoran Jovanovic template <typename InsnType>
2552fdbd0a37SZoran Jovanovic static DecodeStatus DecodeBlezGroupBranchMMR6(MCInst &MI, InsnType insn,
2553fdbd0a37SZoran Jovanovic   uint64_t Address,
2554fdbd0a37SZoran Jovanovic   const void *Decoder) {
2555fdbd0a37SZoran Jovanovic   // We have:
2556fdbd0a37SZoran Jovanovic   //    0b000110 ttttt sssss iiiiiiiiiiiiiiii
2557f0ed16eaSHrvoje Varga   //      Invalid        if rt == 0
2558fdbd0a37SZoran Jovanovic   //      BLEZALC_MMR6   if rs == 0  && rt != 0
2559fdbd0a37SZoran Jovanovic   //      BGEZALC_MMR6   if rs == rt && rt != 0
2560fdbd0a37SZoran Jovanovic   //      BGEUC_MMR6     if rs != rt && rs != 0  && rt != 0
2561fdbd0a37SZoran Jovanovic 
2562fdbd0a37SZoran Jovanovic   InsnType Rt = fieldFromInstruction(insn, 21, 5);
2563fdbd0a37SZoran Jovanovic   InsnType Rs = fieldFromInstruction(insn, 16, 5);
2564f0ed16eaSHrvoje Varga   InsnType Imm = 0;
2565fdbd0a37SZoran Jovanovic   bool HasRs = false;
2566fdbd0a37SZoran Jovanovic 
2567fdbd0a37SZoran Jovanovic   if (Rt == 0)
2568fdbd0a37SZoran Jovanovic     return MCDisassembler::Fail;
2569f0ed16eaSHrvoje Varga   else if (Rs == 0) {
2570fdbd0a37SZoran Jovanovic     MI.setOpcode(Mips::BLEZALC_MMR6);
2571f0ed16eaSHrvoje Varga     Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
2572f0ed16eaSHrvoje Varga   }
2573f0ed16eaSHrvoje Varga   else if (Rs == Rt) {
2574fdbd0a37SZoran Jovanovic     MI.setOpcode(Mips::BGEZALC_MMR6);
2575f0ed16eaSHrvoje Varga     Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
2576f0ed16eaSHrvoje Varga   }
2577fdbd0a37SZoran Jovanovic   else {
2578fdbd0a37SZoran Jovanovic     HasRs = true;
2579fdbd0a37SZoran Jovanovic     MI.setOpcode(Mips::BGEUC_MMR6);
2580f0ed16eaSHrvoje Varga     Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
2581fdbd0a37SZoran Jovanovic   }
2582fdbd0a37SZoran Jovanovic 
2583fdbd0a37SZoran Jovanovic   if (HasRs)
2584fdbd0a37SZoran Jovanovic     MI.addOperand(
2585fdbd0a37SZoran Jovanovic     MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rs)));
2586fdbd0a37SZoran Jovanovic   MI.addOperand(
2587fdbd0a37SZoran Jovanovic     MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rt)));
2588fdbd0a37SZoran Jovanovic 
2589fdbd0a37SZoran Jovanovic   MI.addOperand(MCOperand::createImm(Imm));
2590fdbd0a37SZoran Jovanovic 
2591fdbd0a37SZoran Jovanovic   return MCDisassembler::Success;
2592fdbd0a37SZoran Jovanovic }
2593