1926883e1SEugene Zelenko //===- MipsDisassembler.cpp - Disassembler for Mips -----------------------===//
271928e68SAkira Hatanaka //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
671928e68SAkira Hatanaka //
771928e68SAkira Hatanaka //===----------------------------------------------------------------------===//
871928e68SAkira Hatanaka //
971928e68SAkira Hatanaka // This file is part of the Mips Disassembler.
1071928e68SAkira Hatanaka //
1171928e68SAkira Hatanaka //===----------------------------------------------------------------------===//
1271928e68SAkira Hatanaka 
1379220eaeSEugene Zelenko #include "MCTargetDesc/MipsMCTargetDesc.h"
1471928e68SAkira Hatanaka #include "Mips.h"
15313b7815SRichard Trieu #include "TargetInfo/MipsTargetInfo.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 
270*56e4ea2bSSimon Atanasyan // DecodeJumpTargetXMM - Decode microMIPS jump and link exchange target,
271*56e4ea2bSSimon Atanasyan // which is shifted left by 2 bit.
272*56e4ea2bSSimon Atanasyan static DecodeStatus DecodeJumpTargetXMM(MCInst &Inst,
273*56e4ea2bSSimon Atanasyan                                         unsigned Insn,
274*56e4ea2bSSimon Atanasyan                                         uint64_t Address,
275*56e4ea2bSSimon Atanasyan                                         const void *Decoder);
276*56e4ea2bSSimon Atanasyan 
27771928e68SAkira Hatanaka static DecodeStatus DecodeMem(MCInst &Inst,
27871928e68SAkira Hatanaka                               unsigned Insn,
27971928e68SAkira Hatanaka                               uint64_t Address,
28071928e68SAkira Hatanaka                               const void *Decoder);
28171928e68SAkira Hatanaka 
282e4e83a7bSDaniel Sanders static DecodeStatus DecodeMemEVA(MCInst &Inst,
283e4e83a7bSDaniel Sanders                                  unsigned Insn,
284e4e83a7bSDaniel Sanders                                  uint64_t Address,
285e4e83a7bSDaniel Sanders                                  const void *Decoder);
286e4e83a7bSDaniel Sanders 
2873c88fbd3SHrvoje Varga static DecodeStatus DecodeLoadByte15(MCInst &Inst,
2883c88fbd3SHrvoje Varga                                      unsigned Insn,
2893c88fbd3SHrvoje Varga                                      uint64_t Address,
2903c88fbd3SHrvoje Varga                                      const void *Decoder);
2913c88fbd3SHrvoje Varga 
29279220eaeSEugene Zelenko static DecodeStatus DecodeCacheOp(MCInst &Inst, unsigned Insn, uint64_t Address,
29392db6b78SDaniel Sanders                                   const void *Decoder);
29492db6b78SDaniel Sanders 
295e4e83a7bSDaniel Sanders static DecodeStatus DecodeCacheeOp_CacheOpR6(MCInst &Inst,
296df464ae2SVladimir Medic                                              unsigned Insn,
297df464ae2SVladimir Medic                                              uint64_t Address,
298df464ae2SVladimir Medic                                              const void *Decoder);
299df464ae2SVladimir Medic 
300ab6d1cceSJozef Kolek static DecodeStatus DecodeCacheOpMM(MCInst &Inst,
301ab6d1cceSJozef Kolek                                     unsigned Insn,
302ab6d1cceSJozef Kolek                                     uint64_t Address,
303ab6d1cceSJozef Kolek                                     const void *Decoder);
304ab6d1cceSJozef Kolek 
305d9790793SZoran Jovanovic static DecodeStatus DecodePrefeOpMM(MCInst &Inst,
306d9790793SZoran Jovanovic                                     unsigned Insn,
307d9790793SZoran Jovanovic                                     uint64_t Address,
308d9790793SZoran Jovanovic                                     const void *Decoder);
309d9790793SZoran Jovanovic 
310b4484d62SDaniel Sanders static DecodeStatus DecodeSyncI(MCInst &Inst,
311b4484d62SDaniel Sanders                                 unsigned Insn,
312b4484d62SDaniel Sanders                                 uint64_t Address,
313b4484d62SDaniel Sanders                                 const void *Decoder);
314b4484d62SDaniel Sanders 
315eac9301cSSimon Dardis static DecodeStatus DecodeSyncI_MM(MCInst &Inst,
316eac9301cSSimon Dardis                                    unsigned Insn,
317eac9301cSSimon Dardis                                    uint64_t Address,
318eac9301cSSimon Dardis                                    const void *Decoder);
319eac9301cSSimon Dardis 
32018148671SHrvoje Varga static DecodeStatus DecodeSynciR6(MCInst &Inst,
32118148671SHrvoje Varga                                   unsigned Insn,
32218148671SHrvoje Varga                                   uint64_t Address,
32318148671SHrvoje Varga                                   const void *Decoder);
32418148671SHrvoje Varga 
325fe0bf9f6SMatheus Almeida static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn,
326fe0bf9f6SMatheus Almeida                                     uint64_t Address, const void *Decoder);
327fe0bf9f6SMatheus Almeida 
328315e7ecaSJozef Kolek static DecodeStatus DecodeMemMMImm4(MCInst &Inst,
329315e7ecaSJozef Kolek                                     unsigned Insn,
330315e7ecaSJozef Kolek                                     uint64_t Address,
331315e7ecaSJozef Kolek                                     const void *Decoder);
332315e7ecaSJozef Kolek 
33312c6982bSJozef Kolek static DecodeStatus DecodeMemMMSPImm5Lsl2(MCInst &Inst,
33412c6982bSJozef Kolek                                           unsigned Insn,
33512c6982bSJozef Kolek                                           uint64_t Address,
33612c6982bSJozef Kolek                                           const void *Decoder);
33712c6982bSJozef Kolek 
338e10a02ecSJozef Kolek static DecodeStatus DecodeMemMMGPImm7Lsl2(MCInst &Inst,
339e10a02ecSJozef Kolek                                           unsigned Insn,
340e10a02ecSJozef Kolek                                           uint64_t Address,
341e10a02ecSJozef Kolek                                           const void *Decoder);
342e10a02ecSJozef Kolek 
343d68d424aSJozef Kolek static DecodeStatus DecodeMemMMReglistImm4Lsl2(MCInst &Inst,
344d68d424aSJozef Kolek                                                unsigned Insn,
345d68d424aSJozef Kolek                                                uint64_t Address,
346d68d424aSJozef Kolek                                                const void *Decoder);
347d68d424aSJozef Kolek 
348a6593ff6SZoran Jovanovic static DecodeStatus DecodeMemMMImm9(MCInst &Inst,
349a6593ff6SZoran Jovanovic                                     unsigned Insn,
350a6593ff6SZoran Jovanovic                                     uint64_t Address,
351a6593ff6SZoran Jovanovic                                     const void *Decoder);
352a6593ff6SZoran Jovanovic 
353dde3d582SVladimir Medic static DecodeStatus DecodeMemMMImm12(MCInst &Inst,
354dde3d582SVladimir Medic                                      unsigned Insn,
355dde3d582SVladimir Medic                                      uint64_t Address,
356dde3d582SVladimir Medic                                      const void *Decoder);
357dde3d582SVladimir Medic 
358dde3d582SVladimir Medic static DecodeStatus DecodeMemMMImm16(MCInst &Inst,
359dde3d582SVladimir Medic                                      unsigned Insn,
360dde3d582SVladimir Medic                                      uint64_t Address,
361dde3d582SVladimir Medic                                      const void *Decoder);
362dde3d582SVladimir Medic 
36371928e68SAkira Hatanaka static DecodeStatus DecodeFMem(MCInst &Inst, unsigned Insn,
36471928e68SAkira Hatanaka                                uint64_t Address,
36571928e68SAkira Hatanaka                                const void *Decoder);
36671928e68SAkira Hatanaka 
367cba9f80bSZlatko Buljan static DecodeStatus DecodeFMemMMR2(MCInst &Inst, unsigned Insn,
368cba9f80bSZlatko Buljan                                    uint64_t Address,
369cba9f80bSZlatko Buljan                                    const void *Decoder);
370cba9f80bSZlatko Buljan 
37179220eaeSEugene Zelenko static DecodeStatus DecodeFMem2(MCInst &Inst, unsigned Insn, uint64_t Address,
37292db6b78SDaniel Sanders                                 const void *Decoder);
37392db6b78SDaniel Sanders 
37479220eaeSEugene Zelenko static DecodeStatus DecodeFMem3(MCInst &Inst, unsigned Insn, uint64_t Address,
37592db6b78SDaniel Sanders                                 const void *Decoder);
37692db6b78SDaniel Sanders 
377435cf8a4SVladimir Medic static DecodeStatus DecodeFMemCop2R6(MCInst &Inst, unsigned Insn,
37879220eaeSEugene Zelenko                                      uint64_t Address, const void *Decoder);
379435cf8a4SVladimir Medic 
380cba9f80bSZlatko Buljan static DecodeStatus DecodeFMemCop2MMR6(MCInst &Inst, unsigned Insn,
381cba9f80bSZlatko Buljan                                        uint64_t Address,
382cba9f80bSZlatko Buljan                                        const void *Decoder);
383cba9f80bSZlatko Buljan 
3846a803f61SDaniel Sanders static DecodeStatus DecodeSpecial3LlSc(MCInst &Inst,
3856a803f61SDaniel Sanders                                        unsigned Insn,
3866a803f61SDaniel Sanders                                        uint64_t Address,
3876a803f61SDaniel Sanders                                        const void *Decoder);
3886a803f61SDaniel Sanders 
389aa2b9278SJozef Kolek static DecodeStatus DecodeAddiur2Simm7(MCInst &Inst,
390aa2b9278SJozef Kolek                                        unsigned Value,
391aa2b9278SJozef Kolek                                        uint64_t Address,
392aa2b9278SJozef Kolek                                        const void *Decoder);
393aa2b9278SJozef Kolek 
39497297770SDaniel Sanders static DecodeStatus DecodeLi16Imm(MCInst &Inst,
395aa2b9278SJozef Kolek                                   unsigned Value,
396aa2b9278SJozef Kolek                                   uint64_t Address,
397aa2b9278SJozef Kolek                                   const void *Decoder);
398aa2b9278SJozef Kolek 
3996b28f09dSZoran Jovanovic static DecodeStatus DecodePOOL16BEncodedField(MCInst &Inst,
4006b28f09dSZoran Jovanovic                                               unsigned Value,
4016b28f09dSZoran Jovanovic                                               uint64_t Address,
4026b28f09dSZoran Jovanovic                                               const void *Decoder);
4036b28f09dSZoran Jovanovic 
40419b7f76aSDaniel Sanders template <unsigned Bits, int Offset, int Scale>
40519b7f76aSDaniel Sanders static DecodeStatus DecodeUImmWithOffsetAndScale(MCInst &Inst, unsigned Value,
40619b7f76aSDaniel Sanders                                                  uint64_t Address,
40719b7f76aSDaniel Sanders                                                  const void *Decoder);
40819b7f76aSDaniel Sanders 
409ea4f653dSDaniel Sanders template <unsigned Bits, int Offset>
410ea4f653dSDaniel Sanders static DecodeStatus DecodeUImmWithOffset(MCInst &Inst, unsigned Value,
41119b7f76aSDaniel Sanders                                          uint64_t Address,
41219b7f76aSDaniel Sanders                                          const void *Decoder) {
41319b7f76aSDaniel Sanders   return DecodeUImmWithOffsetAndScale<Bits, Offset, 1>(Inst, Value, Address,
41419b7f76aSDaniel Sanders                                                        Decoder);
41519b7f76aSDaniel Sanders }
416779c5937SMatheus Almeida 
41797297770SDaniel Sanders template <unsigned Bits, int Offset = 0, int ScaleBy = 1>
41897297770SDaniel Sanders static DecodeStatus DecodeSImmWithOffsetAndScale(MCInst &Inst, unsigned Value,
41997297770SDaniel Sanders                                                  uint64_t Address,
42097297770SDaniel Sanders                                                  const void *Decoder);
42178e89020SDaniel Sanders 
42271928e68SAkira Hatanaka static DecodeStatus DecodeInsSize(MCInst &Inst,
42371928e68SAkira Hatanaka                                   unsigned Insn,
42471928e68SAkira Hatanaka                                   uint64_t Address,
42571928e68SAkira Hatanaka                                   const void *Decoder);
42671928e68SAkira Hatanaka 
427b59e1a41SDaniel Sanders static DecodeStatus DecodeSimm19Lsl2(MCInst &Inst, unsigned Insn,
428b59e1a41SDaniel Sanders                                      uint64_t Address, const void *Decoder);
429b59e1a41SDaniel Sanders 
4302855142aSZoran Jovanovic static DecodeStatus DecodeSimm18Lsl3(MCInst &Inst, unsigned Insn,
4312855142aSZoran Jovanovic                                      uint64_t Address, const void *Decoder);
4322855142aSZoran Jovanovic 
433b682ddf3SVladimir Medic static DecodeStatus DecodeSimm9SP(MCInst &Inst, unsigned Insn,
434b682ddf3SVladimir Medic                                   uint64_t Address, const void *Decoder);
435b682ddf3SVladimir Medic 
436b682ddf3SVladimir Medic static DecodeStatus DecodeANDI16Imm(MCInst &Inst, unsigned Insn,
437b682ddf3SVladimir Medic                                     uint64_t Address, const void *Decoder);
438b682ddf3SVladimir Medic 
4392c6d7320SJozef Kolek static DecodeStatus DecodeSimm23Lsl2(MCInst &Inst, unsigned Insn,
4402c6d7320SJozef Kolek                                      uint64_t Address, const void *Decoder);
4412c6d7320SJozef Kolek 
442b50ccf8eSDaniel Sanders /// INSVE_[BHWD] have an implicit operand that the generated decoder doesn't
443b50ccf8eSDaniel Sanders /// handle.
444b50ccf8eSDaniel Sanders template <typename InsnType>
445b50ccf8eSDaniel Sanders static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address,
446b50ccf8eSDaniel Sanders                                    const void *Decoder);
4475c582b2fSDaniel Sanders 
4485c582b2fSDaniel Sanders template <typename InsnType>
449cf060794SSimon Dardis static DecodeStatus DecodeDAHIDATIMMR6(MCInst &MI, InsnType insn, uint64_t Address,
450cf060794SSimon Dardis                                    const void *Decoder);
451cf060794SSimon Dardis 
452cf060794SSimon Dardis template <typename InsnType>
453cf060794SSimon Dardis static DecodeStatus DecodeDAHIDATI(MCInst &MI, InsnType insn, uint64_t Address,
454cf060794SSimon Dardis                                    const void *Decoder);
455cf060794SSimon Dardis 
456cf060794SSimon Dardis template <typename InsnType>
457b3fd189cSSimon Dardis static DecodeStatus DecodeDAHIDATIMMR6(MCInst &MI, InsnType insn, uint64_t Address,
458b3fd189cSSimon Dardis                                    const void *Decoder);
459b3fd189cSSimon Dardis 
460b3fd189cSSimon Dardis template <typename InsnType>
461b3fd189cSSimon Dardis static DecodeStatus DecodeDAHIDATI(MCInst &MI, InsnType insn, uint64_t Address,
462b3fd189cSSimon Dardis                                    const void *Decoder);
463b3fd189cSSimon Dardis 
464b3fd189cSSimon Dardis template <typename InsnType>
4655c582b2fSDaniel Sanders static DecodeStatus
4665c582b2fSDaniel Sanders DecodeAddiGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
4675c582b2fSDaniel Sanders                       const void *Decoder);
4685c582b2fSDaniel Sanders 
4695c582b2fSDaniel Sanders template <typename InsnType>
4705c582b2fSDaniel Sanders static DecodeStatus
471c962c493SHrvoje Varga DecodePOP35GroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address,
472c962c493SHrvoje Varga                            const void *Decoder);
473c962c493SHrvoje Varga 
474c962c493SHrvoje Varga template <typename InsnType>
475c962c493SHrvoje Varga static DecodeStatus
4765c582b2fSDaniel Sanders DecodeDaddiGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
4775c582b2fSDaniel Sanders                        const void *Decoder);
4785c582b2fSDaniel Sanders 
4795c582b2fSDaniel Sanders template <typename InsnType>
4805c582b2fSDaniel Sanders static DecodeStatus
481c962c493SHrvoje Varga DecodePOP37GroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address,
482c962c493SHrvoje Varga                            const void *Decoder);
483c962c493SHrvoje Varga 
484c962c493SHrvoje Varga template <typename InsnType>
485c962c493SHrvoje Varga static DecodeStatus
486f0ed16eaSHrvoje Varga DecodePOP65GroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address,
487f0ed16eaSHrvoje Varga                            const void *Decoder);
488f0ed16eaSHrvoje Varga 
489f0ed16eaSHrvoje Varga template <typename InsnType>
490f0ed16eaSHrvoje Varga static DecodeStatus
491f0ed16eaSHrvoje Varga DecodePOP75GroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address,
492f0ed16eaSHrvoje Varga                            const void *Decoder);
493f0ed16eaSHrvoje Varga 
494f0ed16eaSHrvoje Varga template <typename InsnType>
495f0ed16eaSHrvoje Varga static DecodeStatus
4965c582b2fSDaniel Sanders DecodeBlezlGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
4975c582b2fSDaniel Sanders                        const void *Decoder);
4985c582b2fSDaniel Sanders 
4995c582b2fSDaniel Sanders template <typename InsnType>
5005c582b2fSDaniel Sanders static DecodeStatus
5015c582b2fSDaniel Sanders DecodeBgtzlGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
5025c582b2fSDaniel Sanders                        const void *Decoder);
5035c582b2fSDaniel Sanders 
5045c582b2fSDaniel Sanders template <typename InsnType>
5055c582b2fSDaniel Sanders static DecodeStatus
5065c582b2fSDaniel Sanders DecodeBgtzGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
5075c582b2fSDaniel Sanders                       const void *Decoder);
5085c582b2fSDaniel Sanders 
50928a0ca07SZoran Jovanovic template <typename InsnType>
51028a0ca07SZoran Jovanovic static DecodeStatus
51128a0ca07SZoran Jovanovic DecodeBlezGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
51228a0ca07SZoran Jovanovic                        const void *Decoder);
51328a0ca07SZoran Jovanovic 
514fdbd0a37SZoran Jovanovic template <typename InsnType>
515fdbd0a37SZoran Jovanovic static DecodeStatus
516fdbd0a37SZoran Jovanovic DecodeBgtzGroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address,
517fdbd0a37SZoran Jovanovic                           const void *Decoder);
518fdbd0a37SZoran Jovanovic 
519fdbd0a37SZoran Jovanovic template <typename InsnType>
520fdbd0a37SZoran Jovanovic static DecodeStatus
521fdbd0a37SZoran Jovanovic DecodeBlezGroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address,
522fdbd0a37SZoran Jovanovic                           const void *Decoder);
523fdbd0a37SZoran Jovanovic 
5246f83ae38SSimon Dardis template <typename InsnType>
5256f83ae38SSimon Dardis static DecodeStatus DecodeDINS(MCInst &MI, InsnType Insn, uint64_t Address,
5266f83ae38SSimon Dardis                                const void *Decoder);
5276f83ae38SSimon Dardis 
52855e44673SSimon Dardis template <typename InsnType>
52955e44673SSimon Dardis static DecodeStatus DecodeDEXT(MCInst &MI, InsnType Insn, uint64_t Address,
53055e44673SSimon Dardis                                const void *Decoder);
53155e44673SSimon Dardis 
5323408caf6SPetar Jovanovic template <typename InsnType>
5333408caf6SPetar Jovanovic static DecodeStatus DecodeCRC(MCInst &MI, InsnType Insn, uint64_t Address,
5343408caf6SPetar Jovanovic                               const void *Decoder);
5353408caf6SPetar Jovanovic 
536a4c4b5fcSZoran Jovanovic static DecodeStatus DecodeRegListOperand(MCInst &Inst, unsigned Insn,
537a4c4b5fcSZoran Jovanovic                                          uint64_t Address,
538a4c4b5fcSZoran Jovanovic                                          const void *Decoder);
539a4c4b5fcSZoran Jovanovic 
540f9a02500SZoran Jovanovic static DecodeStatus DecodeRegListOperand16(MCInst &Inst, unsigned Insn,
541f9a02500SZoran Jovanovic                                            uint64_t Address,
542f9a02500SZoran Jovanovic                                            const void *Decoder);
543f9a02500SZoran Jovanovic 
544169df4e2SSimon Dardis static DecodeStatus DecodeMovePRegPair(MCInst &Inst, unsigned RegPair,
54541688679SZoran Jovanovic                                        uint64_t Address,
54641688679SZoran Jovanovic                                        const void *Decoder);
54741688679SZoran Jovanovic 
548852dd83bSSimon Atanasyan static DecodeStatus DecodeMovePOperands(MCInst &Inst, unsigned Insn,
549852dd83bSSimon Atanasyan                                         uint64_t Address, const void *Decoder);
550852dd83bSSimon Atanasyan 
55171928e68SAkira Hatanaka static MCDisassembler *createMipsDisassembler(
55271928e68SAkira Hatanaka                        const Target &T,
553a1bc0f56SLang Hames                        const MCSubtargetInfo &STI,
554a1bc0f56SLang Hames                        MCContext &Ctx) {
555a1bc0f56SLang Hames   return new MipsDisassembler(STI, Ctx, true);
55671928e68SAkira Hatanaka }
55771928e68SAkira Hatanaka 
55871928e68SAkira Hatanaka static MCDisassembler *createMipselDisassembler(
55971928e68SAkira Hatanaka                        const Target &T,
560a1bc0f56SLang Hames                        const MCSubtargetInfo &STI,
561a1bc0f56SLang Hames                        MCContext &Ctx) {
562a1bc0f56SLang Hames   return new MipsDisassembler(STI, Ctx, false);
56371928e68SAkira Hatanaka }
56471928e68SAkira Hatanaka 
5654b0b2619STom Stellard extern "C" void LLVMInitializeMipsDisassembler() {
56671928e68SAkira Hatanaka   // Register the disassembler.
567f42454b9SMehdi Amini   TargetRegistry::RegisterMCDisassembler(getTheMipsTarget(),
56871928e68SAkira Hatanaka                                          createMipsDisassembler);
569f42454b9SMehdi Amini   TargetRegistry::RegisterMCDisassembler(getTheMipselTarget(),
57071928e68SAkira Hatanaka                                          createMipselDisassembler);
571f42454b9SMehdi Amini   TargetRegistry::RegisterMCDisassembler(getTheMips64Target(),
572a19216c8SDaniel Sanders                                          createMipsDisassembler);
573f42454b9SMehdi Amini   TargetRegistry::RegisterMCDisassembler(getTheMips64elTarget(),
574a19216c8SDaniel Sanders                                          createMipselDisassembler);
57571928e68SAkira Hatanaka }
57671928e68SAkira Hatanaka 
57771928e68SAkira Hatanaka #include "MipsGenDisassemblerTables.inc"
57871928e68SAkira Hatanaka 
5795c582b2fSDaniel Sanders static unsigned getReg(const void *D, unsigned RC, unsigned RegNo) {
580a19216c8SDaniel Sanders   const MipsDisassembler *Dis = static_cast<const MipsDisassembler*>(D);
5815c582b2fSDaniel Sanders   const MCRegisterInfo *RegInfo = Dis->getContext().getRegisterInfo();
5825c582b2fSDaniel Sanders   return *(RegInfo->getRegClass(RC).begin() + RegNo);
5835c582b2fSDaniel Sanders }
5845c582b2fSDaniel Sanders 
585b50ccf8eSDaniel Sanders template <typename InsnType>
586b50ccf8eSDaniel Sanders static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address,
587b50ccf8eSDaniel Sanders                                    const void *Decoder) {
58879220eaeSEugene Zelenko   using DecodeFN = DecodeStatus (*)(MCInst &, unsigned, uint64_t, const void *);
58979220eaeSEugene Zelenko 
590b50ccf8eSDaniel Sanders   // The size of the n field depends on the element size
591b50ccf8eSDaniel Sanders   // The register class also depends on this.
592b50ccf8eSDaniel Sanders   InsnType tmp = fieldFromInstruction(insn, 17, 5);
593b50ccf8eSDaniel Sanders   unsigned NSize = 0;
594b50ccf8eSDaniel Sanders   DecodeFN RegDecoder = nullptr;
595b50ccf8eSDaniel Sanders   if ((tmp & 0x18) == 0x00) { // INSVE_B
596b50ccf8eSDaniel Sanders     NSize = 4;
597b50ccf8eSDaniel Sanders     RegDecoder = DecodeMSA128BRegisterClass;
598b50ccf8eSDaniel Sanders   } else if ((tmp & 0x1c) == 0x10) { // INSVE_H
599b50ccf8eSDaniel Sanders     NSize = 3;
600b50ccf8eSDaniel Sanders     RegDecoder = DecodeMSA128HRegisterClass;
601b50ccf8eSDaniel Sanders   } else if ((tmp & 0x1e) == 0x18) { // INSVE_W
602b50ccf8eSDaniel Sanders     NSize = 2;
603b50ccf8eSDaniel Sanders     RegDecoder = DecodeMSA128WRegisterClass;
604b50ccf8eSDaniel Sanders   } else if ((tmp & 0x1f) == 0x1c) { // INSVE_D
605b50ccf8eSDaniel Sanders     NSize = 1;
606b50ccf8eSDaniel Sanders     RegDecoder = DecodeMSA128DRegisterClass;
607b50ccf8eSDaniel Sanders   } else
608b50ccf8eSDaniel Sanders     llvm_unreachable("Invalid encoding");
609b50ccf8eSDaniel Sanders 
610b50ccf8eSDaniel Sanders   assert(NSize != 0 && RegDecoder != nullptr);
611b50ccf8eSDaniel Sanders 
612b50ccf8eSDaniel Sanders   // $wd
613b50ccf8eSDaniel Sanders   tmp = fieldFromInstruction(insn, 6, 5);
614b50ccf8eSDaniel Sanders   if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
615b50ccf8eSDaniel Sanders     return MCDisassembler::Fail;
616b50ccf8eSDaniel Sanders   // $wd_in
617b50ccf8eSDaniel Sanders   if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
618b50ccf8eSDaniel Sanders     return MCDisassembler::Fail;
619b50ccf8eSDaniel Sanders   // $n
620b50ccf8eSDaniel Sanders   tmp = fieldFromInstruction(insn, 16, NSize);
621e9119e41SJim Grosbach   MI.addOperand(MCOperand::createImm(tmp));
622b50ccf8eSDaniel Sanders   // $ws
623b50ccf8eSDaniel Sanders   tmp = fieldFromInstruction(insn, 11, 5);
624b50ccf8eSDaniel Sanders   if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
625b50ccf8eSDaniel Sanders     return MCDisassembler::Fail;
626b50ccf8eSDaniel Sanders   // $n2
627e9119e41SJim Grosbach   MI.addOperand(MCOperand::createImm(0));
628b50ccf8eSDaniel Sanders 
629b50ccf8eSDaniel Sanders   return MCDisassembler::Success;
630b50ccf8eSDaniel Sanders }
631b50ccf8eSDaniel Sanders 
6325c582b2fSDaniel Sanders template <typename InsnType>
633cf060794SSimon Dardis static DecodeStatus DecodeDAHIDATIMMR6(MCInst &MI, InsnType insn, uint64_t Address,
634cf060794SSimon Dardis                                const void *Decoder) {
635b3fd189cSSimon Dardis   InsnType Rs = fieldFromInstruction(insn, 16, 5);
636cf060794SSimon Dardis   InsnType Imm = fieldFromInstruction(insn, 0, 16);
637cf060794SSimon Dardis   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID,
638b3fd189cSSimon Dardis                                        Rs)));
639cf060794SSimon Dardis   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID,
640b3fd189cSSimon Dardis                                        Rs)));
641cf060794SSimon Dardis   MI.addOperand(MCOperand::createImm(Imm));
642cf060794SSimon Dardis 
643cf060794SSimon Dardis   return MCDisassembler::Success;
644cf060794SSimon Dardis }
645cf060794SSimon Dardis 
646cf060794SSimon Dardis template <typename InsnType>
647cf060794SSimon Dardis static DecodeStatus DecodeDAHIDATI(MCInst &MI, InsnType insn, uint64_t Address,
648cf060794SSimon Dardis                                const void *Decoder) {
649b3fd189cSSimon Dardis   InsnType Rs = fieldFromInstruction(insn, 21, 5);
650cf060794SSimon Dardis   InsnType Imm = fieldFromInstruction(insn, 0, 16);
651cf060794SSimon Dardis   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID,
652b3fd189cSSimon Dardis                                        Rs)));
653cf060794SSimon Dardis   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID,
654b3fd189cSSimon Dardis                                        Rs)));
655cf060794SSimon Dardis   MI.addOperand(MCOperand::createImm(Imm));
656cf060794SSimon Dardis 
657cf060794SSimon Dardis   return MCDisassembler::Success;
658cf060794SSimon Dardis }
659cf060794SSimon Dardis 
660cf060794SSimon Dardis template <typename InsnType>
6615c582b2fSDaniel Sanders static DecodeStatus DecodeAddiGroupBranch(MCInst &MI, InsnType insn,
6625c582b2fSDaniel Sanders                                           uint64_t Address,
6635c582b2fSDaniel Sanders                                           const void *Decoder) {
6645c582b2fSDaniel Sanders   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
6655c582b2fSDaniel Sanders   // (otherwise we would have matched the ADDI instruction from the earlier
6665c582b2fSDaniel Sanders   // ISA's instead).
6675c582b2fSDaniel Sanders   //
6685c582b2fSDaniel Sanders   // We have:
6695c582b2fSDaniel Sanders   //    0b001000 sssss ttttt iiiiiiiiiiiiiiii
6705c582b2fSDaniel Sanders   //      BOVC if rs >= rt
6715c582b2fSDaniel Sanders   //      BEQZALC if rs == 0 && rt != 0
6725c582b2fSDaniel Sanders   //      BEQC if rs < rt && rs != 0
6735c582b2fSDaniel Sanders 
6745c582b2fSDaniel Sanders   InsnType Rs = fieldFromInstruction(insn, 21, 5);
6755c582b2fSDaniel Sanders   InsnType Rt = fieldFromInstruction(insn, 16, 5);
676672c710dSSagar Thakur   int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
6775c582b2fSDaniel Sanders   bool HasRs = false;
6785c582b2fSDaniel Sanders 
6795c582b2fSDaniel Sanders   if (Rs >= Rt) {
6805c582b2fSDaniel Sanders     MI.setOpcode(Mips::BOVC);
6815c582b2fSDaniel Sanders     HasRs = true;
6825c582b2fSDaniel Sanders   } else if (Rs != 0 && Rs < Rt) {
6835c582b2fSDaniel Sanders     MI.setOpcode(Mips::BEQC);
6845c582b2fSDaniel Sanders     HasRs = true;
6855c582b2fSDaniel Sanders   } else
6865c582b2fSDaniel Sanders     MI.setOpcode(Mips::BEQZALC);
6875c582b2fSDaniel Sanders 
6885c582b2fSDaniel Sanders   if (HasRs)
689e9119e41SJim Grosbach     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
6905c582b2fSDaniel Sanders                                        Rs)));
6915c582b2fSDaniel Sanders 
692e9119e41SJim Grosbach   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
6935c582b2fSDaniel Sanders                                      Rt)));
694e9119e41SJim Grosbach   MI.addOperand(MCOperand::createImm(Imm));
6955c582b2fSDaniel Sanders 
6965c582b2fSDaniel Sanders   return MCDisassembler::Success;
6975c582b2fSDaniel Sanders }
6985c582b2fSDaniel Sanders 
6995c582b2fSDaniel Sanders template <typename InsnType>
700c962c493SHrvoje Varga static DecodeStatus DecodePOP35GroupBranchMMR6(MCInst &MI, InsnType insn,
701c962c493SHrvoje Varga                                                uint64_t Address,
702c962c493SHrvoje Varga                                                const void *Decoder) {
703c962c493SHrvoje Varga   InsnType Rt = fieldFromInstruction(insn, 21, 5);
704c962c493SHrvoje Varga   InsnType Rs = fieldFromInstruction(insn, 16, 5);
705f0ed16eaSHrvoje Varga   int64_t Imm = 0;
706c962c493SHrvoje Varga 
707c962c493SHrvoje Varga   if (Rs >= Rt) {
708c962c493SHrvoje Varga     MI.setOpcode(Mips::BOVC_MMR6);
709c962c493SHrvoje Varga     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
710c962c493SHrvoje Varga                                        Rt)));
711c962c493SHrvoje Varga     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
712c962c493SHrvoje Varga                                        Rs)));
713f0ed16eaSHrvoje Varga     Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
714c962c493SHrvoje Varga   } else if (Rs != 0 && Rs < Rt) {
715c962c493SHrvoje Varga     MI.setOpcode(Mips::BEQC_MMR6);
716c962c493SHrvoje Varga     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
717c962c493SHrvoje Varga                                        Rs)));
718c962c493SHrvoje Varga     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
719c962c493SHrvoje Varga                                        Rt)));
720f0ed16eaSHrvoje Varga     Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
721c962c493SHrvoje Varga   } else {
722c962c493SHrvoje Varga     MI.setOpcode(Mips::BEQZALC_MMR6);
723c962c493SHrvoje Varga     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
724c962c493SHrvoje Varga                                        Rt)));
725f0ed16eaSHrvoje Varga     Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
726c962c493SHrvoje Varga   }
727c962c493SHrvoje Varga 
728c962c493SHrvoje Varga   MI.addOperand(MCOperand::createImm(Imm));
729c962c493SHrvoje Varga 
730c962c493SHrvoje Varga   return MCDisassembler::Success;
731c962c493SHrvoje Varga }
732c962c493SHrvoje Varga 
733c962c493SHrvoje Varga template <typename InsnType>
7345c582b2fSDaniel Sanders static DecodeStatus DecodeDaddiGroupBranch(MCInst &MI, InsnType insn,
7355c582b2fSDaniel Sanders                                            uint64_t Address,
7365c582b2fSDaniel Sanders                                            const void *Decoder) {
7375c582b2fSDaniel Sanders   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
7385c582b2fSDaniel Sanders   // (otherwise we would have matched the ADDI instruction from the earlier
7395c582b2fSDaniel Sanders   // ISA's instead).
7405c582b2fSDaniel Sanders   //
7415c582b2fSDaniel Sanders   // We have:
7425c582b2fSDaniel Sanders   //    0b011000 sssss ttttt iiiiiiiiiiiiiiii
7435c582b2fSDaniel Sanders   //      BNVC if rs >= rt
7445c582b2fSDaniel Sanders   //      BNEZALC if rs == 0 && rt != 0
7455c582b2fSDaniel Sanders   //      BNEC if rs < rt && rs != 0
7465c582b2fSDaniel Sanders 
7475c582b2fSDaniel Sanders   InsnType Rs = fieldFromInstruction(insn, 21, 5);
7485c582b2fSDaniel Sanders   InsnType Rt = fieldFromInstruction(insn, 16, 5);
749672c710dSSagar Thakur   int64_t  Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
7505c582b2fSDaniel Sanders   bool HasRs = false;
7515c582b2fSDaniel Sanders 
7525c582b2fSDaniel Sanders   if (Rs >= Rt) {
7535c582b2fSDaniel Sanders     MI.setOpcode(Mips::BNVC);
7545c582b2fSDaniel Sanders     HasRs = true;
7555c582b2fSDaniel Sanders   } else if (Rs != 0 && Rs < Rt) {
7565c582b2fSDaniel Sanders     MI.setOpcode(Mips::BNEC);
7575c582b2fSDaniel Sanders     HasRs = true;
7585c582b2fSDaniel Sanders   } else
7595c582b2fSDaniel Sanders     MI.setOpcode(Mips::BNEZALC);
7605c582b2fSDaniel Sanders 
7615c582b2fSDaniel Sanders   if (HasRs)
762e9119e41SJim Grosbach     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
7635c582b2fSDaniel Sanders                                        Rs)));
7645c582b2fSDaniel Sanders 
765e9119e41SJim Grosbach   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
7665c582b2fSDaniel Sanders                                      Rt)));
767e9119e41SJim Grosbach   MI.addOperand(MCOperand::createImm(Imm));
7685c582b2fSDaniel Sanders 
7695c582b2fSDaniel Sanders   return MCDisassembler::Success;
7705c582b2fSDaniel Sanders }
7715c582b2fSDaniel Sanders 
7725c582b2fSDaniel Sanders template <typename InsnType>
773c962c493SHrvoje Varga static DecodeStatus DecodePOP37GroupBranchMMR6(MCInst &MI, InsnType insn,
774c962c493SHrvoje Varga                                                uint64_t Address,
775c962c493SHrvoje Varga                                                const void *Decoder) {
776c962c493SHrvoje Varga   InsnType Rt = fieldFromInstruction(insn, 21, 5);
777c962c493SHrvoje Varga   InsnType Rs = fieldFromInstruction(insn, 16, 5);
778f0ed16eaSHrvoje Varga   int64_t Imm = 0;
779c962c493SHrvoje Varga 
780c962c493SHrvoje Varga   if (Rs >= Rt) {
781c962c493SHrvoje Varga     MI.setOpcode(Mips::BNVC_MMR6);
782c962c493SHrvoje Varga     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
783c962c493SHrvoje Varga                                        Rt)));
784c962c493SHrvoje Varga     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
785c962c493SHrvoje Varga                                        Rs)));
786f0ed16eaSHrvoje Varga     Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
787c962c493SHrvoje Varga   } else if (Rs != 0 && Rs < Rt) {
788c962c493SHrvoje Varga     MI.setOpcode(Mips::BNEC_MMR6);
789c962c493SHrvoje Varga     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
790c962c493SHrvoje Varga                                        Rs)));
791c962c493SHrvoje Varga     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
792c962c493SHrvoje Varga                                        Rt)));
793f0ed16eaSHrvoje Varga     Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
794c962c493SHrvoje Varga   } else {
795c962c493SHrvoje Varga     MI.setOpcode(Mips::BNEZALC_MMR6);
796c962c493SHrvoje Varga     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
797c962c493SHrvoje Varga                                        Rt)));
798f0ed16eaSHrvoje Varga     Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
799c962c493SHrvoje Varga   }
800c962c493SHrvoje Varga 
801c962c493SHrvoje Varga   MI.addOperand(MCOperand::createImm(Imm));
802c962c493SHrvoje Varga 
803c962c493SHrvoje Varga   return MCDisassembler::Success;
804c962c493SHrvoje Varga }
805c962c493SHrvoje Varga 
806c962c493SHrvoje Varga template <typename InsnType>
807f0ed16eaSHrvoje Varga static DecodeStatus DecodePOP65GroupBranchMMR6(MCInst &MI, InsnType insn,
808f0ed16eaSHrvoje Varga                                                uint64_t Address,
809f0ed16eaSHrvoje Varga                                                const void *Decoder) {
810f0ed16eaSHrvoje Varga   // We have:
811f0ed16eaSHrvoje Varga   //    0b110101 ttttt sssss iiiiiiiiiiiiiiii
812f0ed16eaSHrvoje Varga   //      Invalid if rt == 0
813f0ed16eaSHrvoje Varga   //      BGTZC_MMR6   if rs == 0  && rt != 0
814f0ed16eaSHrvoje Varga   //      BLTZC_MMR6   if rs == rt && rt != 0
815f0ed16eaSHrvoje Varga   //      BLTC_MMR6    if rs != rt && rs != 0  && rt != 0
816f0ed16eaSHrvoje Varga 
817f0ed16eaSHrvoje Varga   InsnType Rt = fieldFromInstruction(insn, 21, 5);
818f0ed16eaSHrvoje Varga   InsnType Rs = fieldFromInstruction(insn, 16, 5);
819f0ed16eaSHrvoje Varga   int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
820f0ed16eaSHrvoje Varga   bool HasRs = false;
821f0ed16eaSHrvoje Varga 
822f0ed16eaSHrvoje Varga   if (Rt == 0)
823f0ed16eaSHrvoje Varga     return MCDisassembler::Fail;
824f0ed16eaSHrvoje Varga   else if (Rs == 0)
825f0ed16eaSHrvoje Varga     MI.setOpcode(Mips::BGTZC_MMR6);
826f0ed16eaSHrvoje Varga   else if (Rs == Rt)
827f0ed16eaSHrvoje Varga     MI.setOpcode(Mips::BLTZC_MMR6);
828f0ed16eaSHrvoje Varga   else {
829f0ed16eaSHrvoje Varga     MI.setOpcode(Mips::BLTC_MMR6);
830f0ed16eaSHrvoje Varga     HasRs = true;
831f0ed16eaSHrvoje Varga   }
832f0ed16eaSHrvoje Varga 
833f0ed16eaSHrvoje Varga   if (HasRs)
834f0ed16eaSHrvoje Varga     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
835f0ed16eaSHrvoje Varga                                               Rs)));
836f0ed16eaSHrvoje Varga 
837f0ed16eaSHrvoje Varga   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
838f0ed16eaSHrvoje Varga                                      Rt)));
839f0ed16eaSHrvoje Varga 
840f0ed16eaSHrvoje Varga   MI.addOperand(MCOperand::createImm(Imm));
841f0ed16eaSHrvoje Varga 
842f0ed16eaSHrvoje Varga   return MCDisassembler::Success;
843f0ed16eaSHrvoje Varga }
844f0ed16eaSHrvoje Varga 
845f0ed16eaSHrvoje Varga template <typename InsnType>
846f0ed16eaSHrvoje Varga static DecodeStatus DecodePOP75GroupBranchMMR6(MCInst &MI, InsnType insn,
847f0ed16eaSHrvoje Varga                                                uint64_t Address,
848f0ed16eaSHrvoje Varga                                                const void *Decoder) {
849f0ed16eaSHrvoje Varga   // We have:
850f0ed16eaSHrvoje Varga   //    0b111101 ttttt sssss iiiiiiiiiiiiiiii
851f0ed16eaSHrvoje Varga   //      Invalid if rt == 0
852f0ed16eaSHrvoje Varga   //      BLEZC_MMR6   if rs == 0  && rt != 0
853f0ed16eaSHrvoje Varga   //      BGEZC_MMR6   if rs == rt && rt != 0
854f0ed16eaSHrvoje Varga   //      BGEC_MMR6    if rs != rt && rs != 0  && rt != 0
855f0ed16eaSHrvoje Varga 
856f0ed16eaSHrvoje Varga   InsnType Rt = fieldFromInstruction(insn, 21, 5);
857f0ed16eaSHrvoje Varga   InsnType Rs = fieldFromInstruction(insn, 16, 5);
858f0ed16eaSHrvoje Varga   int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
859f0ed16eaSHrvoje Varga   bool HasRs = false;
860f0ed16eaSHrvoje Varga 
861f0ed16eaSHrvoje Varga   if (Rt == 0)
862f0ed16eaSHrvoje Varga     return MCDisassembler::Fail;
863f0ed16eaSHrvoje Varga   else if (Rs == 0)
864f0ed16eaSHrvoje Varga     MI.setOpcode(Mips::BLEZC_MMR6);
865f0ed16eaSHrvoje Varga   else if (Rs == Rt)
866f0ed16eaSHrvoje Varga     MI.setOpcode(Mips::BGEZC_MMR6);
867f0ed16eaSHrvoje Varga   else {
868f0ed16eaSHrvoje Varga     HasRs = true;
869f0ed16eaSHrvoje Varga     MI.setOpcode(Mips::BGEC_MMR6);
870f0ed16eaSHrvoje Varga   }
871f0ed16eaSHrvoje Varga 
872f0ed16eaSHrvoje Varga   if (HasRs)
873f0ed16eaSHrvoje Varga     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
874f0ed16eaSHrvoje Varga                                        Rs)));
875f0ed16eaSHrvoje Varga 
876f0ed16eaSHrvoje Varga   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
877f0ed16eaSHrvoje Varga                                      Rt)));
878f0ed16eaSHrvoje Varga 
879f0ed16eaSHrvoje Varga   MI.addOperand(MCOperand::createImm(Imm));
880f0ed16eaSHrvoje Varga 
881f0ed16eaSHrvoje Varga   return MCDisassembler::Success;
882f0ed16eaSHrvoje Varga }
883f0ed16eaSHrvoje Varga 
884f0ed16eaSHrvoje Varga template <typename InsnType>
8855c582b2fSDaniel Sanders static DecodeStatus DecodeBlezlGroupBranch(MCInst &MI, InsnType insn,
8865c582b2fSDaniel Sanders                                            uint64_t Address,
8875c582b2fSDaniel Sanders                                            const void *Decoder) {
8885c582b2fSDaniel Sanders   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
8895c582b2fSDaniel Sanders   // (otherwise we would have matched the BLEZL instruction from the earlier
8905c582b2fSDaniel Sanders   // ISA's instead).
8915c582b2fSDaniel Sanders   //
8925c582b2fSDaniel Sanders   // We have:
8935c582b2fSDaniel Sanders   //    0b010110 sssss ttttt iiiiiiiiiiiiiiii
8945c582b2fSDaniel Sanders   //      Invalid if rs == 0
8955c582b2fSDaniel Sanders   //      BLEZC   if rs == 0  && rt != 0
8965c582b2fSDaniel Sanders   //      BGEZC   if rs == rt && rt != 0
8975c582b2fSDaniel Sanders   //      BGEC    if rs != rt && rs != 0  && rt != 0
8985c582b2fSDaniel Sanders 
8995c582b2fSDaniel Sanders   InsnType Rs = fieldFromInstruction(insn, 21, 5);
9005c582b2fSDaniel Sanders   InsnType Rt = fieldFromInstruction(insn, 16, 5);
901672c710dSSagar Thakur   int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
90228a0ca07SZoran Jovanovic   bool HasRs = false;
9035c582b2fSDaniel Sanders 
9045c582b2fSDaniel Sanders   if (Rt == 0)
9055c582b2fSDaniel Sanders     return MCDisassembler::Fail;
9065c582b2fSDaniel Sanders   else if (Rs == 0)
9075c582b2fSDaniel Sanders     MI.setOpcode(Mips::BLEZC);
9085c582b2fSDaniel Sanders   else if (Rs == Rt)
9095c582b2fSDaniel Sanders     MI.setOpcode(Mips::BGEZC);
91028a0ca07SZoran Jovanovic   else {
91128a0ca07SZoran Jovanovic     HasRs = true;
91228a0ca07SZoran Jovanovic     MI.setOpcode(Mips::BGEC);
91328a0ca07SZoran Jovanovic   }
91428a0ca07SZoran Jovanovic 
91528a0ca07SZoran Jovanovic   if (HasRs)
916e9119e41SJim Grosbach     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
91728a0ca07SZoran Jovanovic                                        Rs)));
9185c582b2fSDaniel Sanders 
919e9119e41SJim Grosbach   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
9205c582b2fSDaniel Sanders                                      Rt)));
9215c582b2fSDaniel Sanders 
922e9119e41SJim Grosbach   MI.addOperand(MCOperand::createImm(Imm));
9235c582b2fSDaniel Sanders 
9245c582b2fSDaniel Sanders   return MCDisassembler::Success;
9255c582b2fSDaniel Sanders }
9265c582b2fSDaniel Sanders 
9275c582b2fSDaniel Sanders template <typename InsnType>
9285c582b2fSDaniel Sanders static DecodeStatus DecodeBgtzlGroupBranch(MCInst &MI, InsnType insn,
9295c582b2fSDaniel Sanders                                            uint64_t Address,
9305c582b2fSDaniel Sanders                                            const void *Decoder) {
9315c582b2fSDaniel Sanders   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
9325c582b2fSDaniel Sanders   // (otherwise we would have matched the BGTZL instruction from the earlier
9335c582b2fSDaniel Sanders   // ISA's instead).
9345c582b2fSDaniel Sanders   //
9355c582b2fSDaniel Sanders   // We have:
9365c582b2fSDaniel Sanders   //    0b010111 sssss ttttt iiiiiiiiiiiiiiii
9375c582b2fSDaniel Sanders   //      Invalid if rs == 0
9385c582b2fSDaniel Sanders   //      BGTZC   if rs == 0  && rt != 0
9395c582b2fSDaniel Sanders   //      BLTZC   if rs == rt && rt != 0
9405c582b2fSDaniel Sanders   //      BLTC    if rs != rt && rs != 0  && rt != 0
9415c582b2fSDaniel Sanders 
9425c14b069SZoran Jovanovic   bool HasRs = false;
9435c14b069SZoran Jovanovic 
9445c582b2fSDaniel Sanders   InsnType Rs = fieldFromInstruction(insn, 21, 5);
9455c582b2fSDaniel Sanders   InsnType Rt = fieldFromInstruction(insn, 16, 5);
946672c710dSSagar Thakur   int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
9475c582b2fSDaniel Sanders 
9485c582b2fSDaniel Sanders   if (Rt == 0)
9495c582b2fSDaniel Sanders     return MCDisassembler::Fail;
9505c582b2fSDaniel Sanders   else if (Rs == 0)
9515c582b2fSDaniel Sanders     MI.setOpcode(Mips::BGTZC);
9525c582b2fSDaniel Sanders   else if (Rs == Rt)
9535c582b2fSDaniel Sanders     MI.setOpcode(Mips::BLTZC);
9545c14b069SZoran Jovanovic   else {
9555c14b069SZoran Jovanovic     MI.setOpcode(Mips::BLTC);
9565c14b069SZoran Jovanovic     HasRs = true;
9575c14b069SZoran Jovanovic   }
9585c14b069SZoran Jovanovic 
9595c14b069SZoran Jovanovic   if (HasRs)
960e9119e41SJim Grosbach     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
9615c14b069SZoran Jovanovic                                               Rs)));
9625c582b2fSDaniel Sanders 
963e9119e41SJim Grosbach   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
9645c582b2fSDaniel Sanders                                      Rt)));
9655c582b2fSDaniel Sanders 
966e9119e41SJim Grosbach   MI.addOperand(MCOperand::createImm(Imm));
9675c582b2fSDaniel Sanders 
9685c582b2fSDaniel Sanders   return MCDisassembler::Success;
9695c582b2fSDaniel Sanders }
9705c582b2fSDaniel Sanders 
9715c582b2fSDaniel Sanders template <typename InsnType>
9725c582b2fSDaniel Sanders static DecodeStatus DecodeBgtzGroupBranch(MCInst &MI, InsnType insn,
9735c582b2fSDaniel Sanders                                           uint64_t Address,
9745c582b2fSDaniel Sanders                                           const void *Decoder) {
9755c582b2fSDaniel Sanders   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
9765c582b2fSDaniel Sanders   // (otherwise we would have matched the BGTZ instruction from the earlier
9775c582b2fSDaniel Sanders   // ISA's instead).
9785c582b2fSDaniel Sanders   //
9795c582b2fSDaniel Sanders   // We have:
9805c582b2fSDaniel Sanders   //    0b000111 sssss ttttt iiiiiiiiiiiiiiii
9815c582b2fSDaniel Sanders   //      BGTZ    if rt == 0
9825c582b2fSDaniel Sanders   //      BGTZALC if rs == 0 && rt != 0
9835c582b2fSDaniel Sanders   //      BLTZALC if rs != 0 && rs == rt
9845c582b2fSDaniel Sanders   //      BLTUC   if rs != 0 && rs != rt
9855c582b2fSDaniel Sanders 
9865c582b2fSDaniel Sanders   InsnType Rs = fieldFromInstruction(insn, 21, 5);
9875c582b2fSDaniel Sanders   InsnType Rt = fieldFromInstruction(insn, 16, 5);
988672c710dSSagar Thakur   int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
9895c582b2fSDaniel Sanders   bool HasRs = false;
9905c582b2fSDaniel Sanders   bool HasRt = false;
9915c582b2fSDaniel Sanders 
9925c582b2fSDaniel Sanders   if (Rt == 0) {
9935c582b2fSDaniel Sanders     MI.setOpcode(Mips::BGTZ);
9945c582b2fSDaniel Sanders     HasRs = true;
9955c582b2fSDaniel Sanders   } else if (Rs == 0) {
9965c582b2fSDaniel Sanders     MI.setOpcode(Mips::BGTZALC);
9975c582b2fSDaniel Sanders     HasRt = true;
9985c582b2fSDaniel Sanders   } else if (Rs == Rt) {
9995c582b2fSDaniel Sanders     MI.setOpcode(Mips::BLTZALC);
10005c582b2fSDaniel Sanders     HasRs = true;
10015c14b069SZoran Jovanovic   } else {
10025c14b069SZoran Jovanovic     MI.setOpcode(Mips::BLTUC);
10035c14b069SZoran Jovanovic     HasRs = true;
10045c14b069SZoran Jovanovic     HasRt = true;
10055c14b069SZoran Jovanovic   }
10065c582b2fSDaniel Sanders 
10075c582b2fSDaniel Sanders   if (HasRs)
1008e9119e41SJim Grosbach     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
10095c582b2fSDaniel Sanders                                        Rs)));
10105c582b2fSDaniel Sanders 
10115c582b2fSDaniel Sanders   if (HasRt)
1012e9119e41SJim Grosbach     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
10135c582b2fSDaniel Sanders                                        Rt)));
10145c582b2fSDaniel Sanders 
1015e9119e41SJim Grosbach   MI.addOperand(MCOperand::createImm(Imm));
10165c582b2fSDaniel Sanders 
10175c582b2fSDaniel Sanders   return MCDisassembler::Success;
10185c582b2fSDaniel Sanders }
10195c582b2fSDaniel Sanders 
102028a0ca07SZoran Jovanovic template <typename InsnType>
102128a0ca07SZoran Jovanovic static DecodeStatus DecodeBlezGroupBranch(MCInst &MI, InsnType insn,
102228a0ca07SZoran Jovanovic                                            uint64_t Address,
102328a0ca07SZoran Jovanovic                                            const void *Decoder) {
102428a0ca07SZoran Jovanovic   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
102528a0ca07SZoran Jovanovic   // (otherwise we would have matched the BLEZL instruction from the earlier
102628a0ca07SZoran Jovanovic   // ISA's instead).
102728a0ca07SZoran Jovanovic   //
102828a0ca07SZoran Jovanovic   // We have:
102928a0ca07SZoran Jovanovic   //    0b000110 sssss ttttt iiiiiiiiiiiiiiii
103028a0ca07SZoran Jovanovic   //      Invalid   if rs == 0
103128a0ca07SZoran Jovanovic   //      BLEZALC   if rs == 0  && rt != 0
103228a0ca07SZoran Jovanovic   //      BGEZALC   if rs == rt && rt != 0
103328a0ca07SZoran Jovanovic   //      BGEUC     if rs != rt && rs != 0  && rt != 0
103428a0ca07SZoran Jovanovic 
103528a0ca07SZoran Jovanovic   InsnType Rs = fieldFromInstruction(insn, 21, 5);
103628a0ca07SZoran Jovanovic   InsnType Rt = fieldFromInstruction(insn, 16, 5);
1037672c710dSSagar Thakur   int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
103828a0ca07SZoran Jovanovic   bool HasRs = false;
103928a0ca07SZoran Jovanovic 
104028a0ca07SZoran Jovanovic   if (Rt == 0)
104128a0ca07SZoran Jovanovic     return MCDisassembler::Fail;
104228a0ca07SZoran Jovanovic   else if (Rs == 0)
104328a0ca07SZoran Jovanovic     MI.setOpcode(Mips::BLEZALC);
104428a0ca07SZoran Jovanovic   else if (Rs == Rt)
104528a0ca07SZoran Jovanovic     MI.setOpcode(Mips::BGEZALC);
104628a0ca07SZoran Jovanovic   else {
104728a0ca07SZoran Jovanovic     HasRs = true;
104828a0ca07SZoran Jovanovic     MI.setOpcode(Mips::BGEUC);
104928a0ca07SZoran Jovanovic   }
105028a0ca07SZoran Jovanovic 
105128a0ca07SZoran Jovanovic   if (HasRs)
1052e9119e41SJim Grosbach     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
105328a0ca07SZoran Jovanovic                                        Rs)));
1054e9119e41SJim Grosbach   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
105528a0ca07SZoran Jovanovic                                      Rt)));
105628a0ca07SZoran Jovanovic 
1057e9119e41SJim Grosbach   MI.addOperand(MCOperand::createImm(Imm));
105828a0ca07SZoran Jovanovic 
105928a0ca07SZoran Jovanovic   return MCDisassembler::Success;
106028a0ca07SZoran Jovanovic }
106128a0ca07SZoran Jovanovic 
106255e44673SSimon Dardis // Override the generated disassembler to produce DEXT all the time. This is
106355e44673SSimon Dardis // for feature / behaviour parity with  binutils.
106455e44673SSimon Dardis template <typename InsnType>
106555e44673SSimon Dardis static DecodeStatus DecodeDEXT(MCInst &MI, InsnType Insn, uint64_t Address,
106655e44673SSimon Dardis                                const void *Decoder) {
106755e44673SSimon Dardis   unsigned Msbd = fieldFromInstruction(Insn, 11, 5);
106855e44673SSimon Dardis   unsigned Lsb = fieldFromInstruction(Insn, 6, 5);
106955e44673SSimon Dardis   unsigned Size = 0;
107055e44673SSimon Dardis   unsigned Pos = 0;
107155e44673SSimon Dardis 
107255e44673SSimon Dardis   switch (MI.getOpcode()) {
107355e44673SSimon Dardis     case Mips::DEXT:
107455e44673SSimon Dardis       Pos = Lsb;
107555e44673SSimon Dardis       Size = Msbd + 1;
107655e44673SSimon Dardis       break;
107755e44673SSimon Dardis     case Mips::DEXTM:
107855e44673SSimon Dardis       Pos = Lsb;
107955e44673SSimon Dardis       Size = Msbd + 1 + 32;
108055e44673SSimon Dardis       break;
108155e44673SSimon Dardis     case Mips::DEXTU:
108255e44673SSimon Dardis       Pos = Lsb + 32;
108355e44673SSimon Dardis       Size = Msbd + 1;
108455e44673SSimon Dardis       break;
108555e44673SSimon Dardis     default:
108655e44673SSimon Dardis       llvm_unreachable("Unknown DEXT instruction!");
108755e44673SSimon Dardis   }
108855e44673SSimon Dardis 
1089d6dada17SAleksandar Beserminji   MI.setOpcode(Mips::DEXT);
109055e44673SSimon Dardis 
109155e44673SSimon Dardis   InsnType Rs = fieldFromInstruction(Insn, 21, 5);
109255e44673SSimon Dardis   InsnType Rt = fieldFromInstruction(Insn, 16, 5);
109355e44673SSimon Dardis 
109455e44673SSimon Dardis   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID, Rt)));
109555e44673SSimon Dardis   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID, Rs)));
109655e44673SSimon Dardis   MI.addOperand(MCOperand::createImm(Pos));
109755e44673SSimon Dardis   MI.addOperand(MCOperand::createImm(Size));
109855e44673SSimon Dardis 
109955e44673SSimon Dardis   return MCDisassembler::Success;
110055e44673SSimon Dardis }
110155e44673SSimon Dardis 
11026f83ae38SSimon Dardis // Override the generated disassembler to produce DINS all the time. This is
11036f83ae38SSimon Dardis // for feature / behaviour parity with binutils.
11046f83ae38SSimon Dardis template <typename InsnType>
11056f83ae38SSimon Dardis static DecodeStatus DecodeDINS(MCInst &MI, InsnType Insn, uint64_t Address,
11066f83ae38SSimon Dardis                                const void *Decoder) {
11076f83ae38SSimon Dardis   unsigned Msbd = fieldFromInstruction(Insn, 11, 5);
11086f83ae38SSimon Dardis   unsigned Lsb = fieldFromInstruction(Insn, 6, 5);
11096f83ae38SSimon Dardis   unsigned Size = 0;
11106f83ae38SSimon Dardis   unsigned Pos = 0;
11116f83ae38SSimon Dardis 
11126f83ae38SSimon Dardis   switch (MI.getOpcode()) {
11136f83ae38SSimon Dardis     case Mips::DINS:
11146f83ae38SSimon Dardis       Pos = Lsb;
11156f83ae38SSimon Dardis       Size = Msbd + 1 - Pos;
11166f83ae38SSimon Dardis       break;
11176f83ae38SSimon Dardis     case Mips::DINSM:
11186f83ae38SSimon Dardis       Pos = Lsb;
11196f83ae38SSimon Dardis       Size = Msbd + 33 - Pos;
11206f83ae38SSimon Dardis       break;
11216f83ae38SSimon Dardis     case Mips::DINSU:
11226f83ae38SSimon Dardis       Pos = Lsb + 32;
11236f83ae38SSimon Dardis       // mbsd = pos + size - 33
11246f83ae38SSimon Dardis       // mbsd - pos + 33 = size
11256f83ae38SSimon Dardis       Size = Msbd + 33 - Pos;
11266f83ae38SSimon Dardis       break;
11276f83ae38SSimon Dardis     default:
11286f83ae38SSimon Dardis       llvm_unreachable("Unknown DINS instruction!");
11296f83ae38SSimon Dardis   }
11306f83ae38SSimon Dardis 
11316f83ae38SSimon Dardis   InsnType Rs = fieldFromInstruction(Insn, 21, 5);
11326f83ae38SSimon Dardis   InsnType Rt = fieldFromInstruction(Insn, 16, 5);
11336f83ae38SSimon Dardis 
1134d6dada17SAleksandar Beserminji   MI.setOpcode(Mips::DINS);
11356f83ae38SSimon Dardis   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID, Rt)));
11366f83ae38SSimon Dardis   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID, Rs)));
11376f83ae38SSimon Dardis   MI.addOperand(MCOperand::createImm(Pos));
11386f83ae38SSimon Dardis   MI.addOperand(MCOperand::createImm(Size));
11396f83ae38SSimon Dardis 
11406f83ae38SSimon Dardis   return MCDisassembler::Success;
11416f83ae38SSimon Dardis }
11423408caf6SPetar Jovanovic 
11433408caf6SPetar Jovanovic // Auto-generated decoder wouldn't add the third operand for CRC32*.
11443408caf6SPetar Jovanovic template <typename InsnType>
11453408caf6SPetar Jovanovic static DecodeStatus DecodeCRC(MCInst &MI, InsnType Insn, uint64_t Address,
11463408caf6SPetar Jovanovic                               const void *Decoder) {
11473408caf6SPetar Jovanovic   InsnType Rs = fieldFromInstruction(Insn, 21, 5);
11483408caf6SPetar Jovanovic   InsnType Rt = fieldFromInstruction(Insn, 16, 5);
11493408caf6SPetar Jovanovic   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
11503408caf6SPetar Jovanovic                                      Rt)));
11513408caf6SPetar Jovanovic   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
11523408caf6SPetar Jovanovic                                      Rs)));
11533408caf6SPetar Jovanovic   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
11543408caf6SPetar Jovanovic                                      Rt)));
11553408caf6SPetar Jovanovic   return MCDisassembler::Success;
11563408caf6SPetar Jovanovic }
11573408caf6SPetar Jovanovic 
1158ea22c4cfSJozef Kolek /// Read two bytes from the ArrayRef and return 16 bit halfword sorted
1159dcd84335SSimon Pilgrim /// according to the given endianness.
1160ea22c4cfSJozef Kolek static DecodeStatus readInstruction16(ArrayRef<uint8_t> Bytes, uint64_t Address,
1161ea22c4cfSJozef Kolek                                       uint64_t &Size, uint32_t &Insn,
1162ea22c4cfSJozef Kolek                                       bool IsBigEndian) {
1163ea22c4cfSJozef Kolek   // We want to read exactly 2 Bytes of data.
1164ea22c4cfSJozef Kolek   if (Bytes.size() < 2) {
1165ea22c4cfSJozef Kolek     Size = 0;
1166ea22c4cfSJozef Kolek     return MCDisassembler::Fail;
1167ea22c4cfSJozef Kolek   }
1168ea22c4cfSJozef Kolek 
1169ea22c4cfSJozef Kolek   if (IsBigEndian) {
1170ea22c4cfSJozef Kolek     Insn = (Bytes[0] << 8) | Bytes[1];
1171ea22c4cfSJozef Kolek   } else {
1172ea22c4cfSJozef Kolek     Insn = (Bytes[1] << 8) | Bytes[0];
1173ea22c4cfSJozef Kolek   }
1174ea22c4cfSJozef Kolek 
1175ea22c4cfSJozef Kolek   return MCDisassembler::Success;
1176ea22c4cfSJozef Kolek }
1177ea22c4cfSJozef Kolek 
11787fc5b874SRafael Espindola /// Read four bytes from the ArrayRef and return 32 bit word sorted
1179dcd84335SSimon Pilgrim /// according to the given endianness.
11807fc5b874SRafael Espindola static DecodeStatus readInstruction32(ArrayRef<uint8_t> Bytes, uint64_t Address,
11817fc5b874SRafael Espindola                                       uint64_t &Size, uint32_t &Insn,
11827fc5b874SRafael Espindola                                       bool IsBigEndian, bool IsMicroMips) {
118371928e68SAkira Hatanaka   // We want to read exactly 4 Bytes of data.
11847fc5b874SRafael Espindola   if (Bytes.size() < 4) {
11854aa6bea7SRafael Espindola     Size = 0;
118671928e68SAkira Hatanaka     return MCDisassembler::Fail;
118771928e68SAkira Hatanaka   }
118871928e68SAkira Hatanaka 
1189ea22c4cfSJozef Kolek   // High 16 bits of a 32-bit microMIPS instruction (where the opcode is)
1190ea22c4cfSJozef Kolek   // always precede the low 16 bits in the instruction stream (that is, they
1191ea22c4cfSJozef Kolek   // are placed at lower addresses in the instruction stream).
1192ea22c4cfSJozef Kolek   //
1193ea22c4cfSJozef Kolek   // microMIPS byte ordering:
1194ea22c4cfSJozef Kolek   //   Big-endian:    0 | 1 | 2 | 3
1195ea22c4cfSJozef Kolek   //   Little-endian: 1 | 0 | 3 | 2
1196ea22c4cfSJozef Kolek 
11974aa6bea7SRafael Espindola   if (IsBigEndian) {
119871928e68SAkira Hatanaka     // Encoded as a big-endian 32-bit word in the stream.
11994aa6bea7SRafael Espindola     Insn =
12004aa6bea7SRafael Espindola         (Bytes[3] << 0) | (Bytes[2] << 8) | (Bytes[1] << 16) | (Bytes[0] << 24);
12014aa6bea7SRafael Espindola   } else {
1202dde3d582SVladimir Medic     if (IsMicroMips) {
12034aa6bea7SRafael Espindola       Insn = (Bytes[2] << 0) | (Bytes[3] << 8) | (Bytes[0] << 16) |
1204dde3d582SVladimir Medic              (Bytes[1] << 24);
1205dde3d582SVladimir Medic     } else {
12064aa6bea7SRafael Espindola       Insn = (Bytes[0] << 0) | (Bytes[1] << 8) | (Bytes[2] << 16) |
120771928e68SAkira Hatanaka              (Bytes[3] << 24);
120871928e68SAkira Hatanaka     }
1209dde3d582SVladimir Medic   }
121071928e68SAkira Hatanaka 
121171928e68SAkira Hatanaka   return MCDisassembler::Success;
121271928e68SAkira Hatanaka }
121371928e68SAkira Hatanaka 
12144aa6bea7SRafael Espindola DecodeStatus MipsDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,
12157fc5b874SRafael Espindola                                               ArrayRef<uint8_t> Bytes,
121671928e68SAkira Hatanaka                                               uint64_t Address,
12174aa6bea7SRafael Espindola                                               raw_ostream &VStream,
12184aa6bea7SRafael Espindola                                               raw_ostream &CStream) const {
121971928e68SAkira Hatanaka   uint32_t Insn;
1220ea22c4cfSJozef Kolek   DecodeStatus Result;
1221a5f52dc0SSimon Dardis   Size = 0;
122271928e68SAkira Hatanaka 
1223ea22c4cfSJozef Kolek   if (IsMicroMips) {
1224ea22c4cfSJozef Kolek     Result = readInstruction16(Bytes, Address, Size, Insn, IsBigEndian);
1225ebee6129SReid Kleckner     if (Result == MCDisassembler::Fail)
1226ebee6129SReid Kleckner       return MCDisassembler::Fail;
1227ea22c4cfSJozef Kolek 
1228ada70918SZoran Jovanovic     if (hasMips32r6()) {
1229d34e60caSNicola Zaghen       LLVM_DEBUG(
1230d34e60caSNicola Zaghen           dbgs() << "Trying MicroMipsR616 table (16-bit instructions):\n");
1231ada70918SZoran Jovanovic       // Calling the auto-generated decoder function for microMIPS32R6
1232d6dada17SAleksandar Beserminji       // 16-bit instructions.
1233ada70918SZoran Jovanovic       Result = decodeInstruction(DecoderTableMicroMipsR616, Instr, Insn,
1234ada70918SZoran Jovanovic                                  Address, this, STI);
1235ada70918SZoran Jovanovic       if (Result != MCDisassembler::Fail) {
1236ada70918SZoran Jovanovic         Size = 2;
1237ada70918SZoran Jovanovic         return Result;
1238ada70918SZoran Jovanovic       }
1239ada70918SZoran Jovanovic     }
1240ada70918SZoran Jovanovic 
1241d34e60caSNicola Zaghen     LLVM_DEBUG(dbgs() << "Trying MicroMips16 table (16-bit instructions):\n");
1242ada70918SZoran Jovanovic     // Calling the auto-generated decoder function for microMIPS 16-bit
1243ada70918SZoran Jovanovic     // instructions.
1244ea22c4cfSJozef Kolek     Result = decodeInstruction(DecoderTableMicroMips16, Instr, Insn, Address,
1245ea22c4cfSJozef Kolek                                this, STI);
1246ea22c4cfSJozef Kolek     if (Result != MCDisassembler::Fail) {
1247ea22c4cfSJozef Kolek       Size = 2;
1248ea22c4cfSJozef Kolek       return Result;
1249ea22c4cfSJozef Kolek     }
1250ea22c4cfSJozef Kolek 
1251ea22c4cfSJozef Kolek     Result = readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, true);
125271928e68SAkira Hatanaka     if (Result == MCDisassembler::Fail)
125371928e68SAkira Hatanaka       return MCDisassembler::Fail;
125471928e68SAkira Hatanaka 
1255676d6012SJozef Kolek     if (hasMips32r6()) {
1256d34e60caSNicola Zaghen       LLVM_DEBUG(
1257d34e60caSNicola Zaghen           dbgs() << "Trying MicroMips32r632 table (32-bit instructions):\n");
1258676d6012SJozef Kolek       // Calling the auto-generated decoder function.
1259366783e1SZoran Jovanovic       Result = decodeInstruction(DecoderTableMicroMipsR632, Instr, Insn, Address,
1260676d6012SJozef Kolek                                  this, STI);
1261ada70918SZoran Jovanovic       if (Result != MCDisassembler::Fail) {
1262ada70918SZoran Jovanovic         Size = 4;
1263ada70918SZoran Jovanovic         return Result;
1264ada70918SZoran Jovanovic       }
1265ada70918SZoran Jovanovic     }
1266ada70918SZoran Jovanovic 
1267d34e60caSNicola Zaghen     LLVM_DEBUG(dbgs() << "Trying MicroMips32 table (32-bit instructions):\n");
1268dde3d582SVladimir Medic     // Calling the auto-generated decoder function.
12694aa6bea7SRafael Espindola     Result = decodeInstruction(DecoderTableMicroMips32, Instr, Insn, Address,
1270dde3d582SVladimir Medic                                this, STI);
1271dde3d582SVladimir Medic     if (Result != MCDisassembler::Fail) {
1272dde3d582SVladimir Medic       Size = 4;
1273dde3d582SVladimir Medic       return Result;
1274dde3d582SVladimir Medic     }
12752cb74ac3SHrvoje Varga 
127651a7ae2aSSimon Dardis     if (isFP64()) {
1277d34e60caSNicola Zaghen       LLVM_DEBUG(dbgs() << "Trying MicroMipsFP64 table (32-bit opcodes):\n");
127851a7ae2aSSimon Dardis       Result = decodeInstruction(DecoderTableMicroMipsFP6432, Instr, Insn,
12792cb74ac3SHrvoje Varga                                  Address, this, STI);
12802cb74ac3SHrvoje Varga       if (Result != MCDisassembler::Fail) {
12812cb74ac3SHrvoje Varga         Size = 4;
12822cb74ac3SHrvoje Varga         return Result;
12832cb74ac3SHrvoje Varga       }
12842cb74ac3SHrvoje Varga     }
12852cb74ac3SHrvoje Varga 
1286a5f52dc0SSimon Dardis     // This is an invalid instruction. Claim that the Size is 2 bytes. Since
1287a5f52dc0SSimon Dardis     // microMIPS instructions have a minimum alignment of 2, the next 2 bytes
1288a5f52dc0SSimon Dardis     // could form a valid instruction. The two bytes we rejected as an
1289a5f52dc0SSimon Dardis     // instruction could have actually beeen an inline constant pool that is
1290a5f52dc0SSimon Dardis     // unconditionally branched over.
1291ebee6129SReid Kleckner     Size = 2;
1292dde3d582SVladimir Medic     return MCDisassembler::Fail;
1293dde3d582SVladimir Medic   }
1294dde3d582SVladimir Medic 
1295a5f52dc0SSimon Dardis   // Attempt to read the instruction so that we can attempt to decode it. If
1296a5f52dc0SSimon Dardis   // the buffer is not 4 bytes long, let the higher level logic figure out
1297a5f52dc0SSimon Dardis   // what to do with a size of zero and MCDisassembler::Fail.
1298ea22c4cfSJozef Kolek   Result = readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, false);
1299a5f52dc0SSimon Dardis   if (Result == MCDisassembler::Fail)
1300ea22c4cfSJozef Kolek     return MCDisassembler::Fail;
1301a5f52dc0SSimon Dardis 
1302a5f52dc0SSimon Dardis   // The only instruction size for standard encoded MIPS.
1303a5f52dc0SSimon Dardis   Size = 4;
1304ea22c4cfSJozef Kolek 
1305c171f65aSDaniel Sanders   if (hasCOP3()) {
1306d34e60caSNicola Zaghen     LLVM_DEBUG(dbgs() << "Trying COP3_ table (32-bit opcodes):\n");
1307c171f65aSDaniel Sanders     Result =
13084aa6bea7SRafael Espindola         decodeInstruction(DecoderTableCOP3_32, Instr, Insn, Address, this, STI);
1309a5f52dc0SSimon Dardis     if (Result != MCDisassembler::Fail)
1310c171f65aSDaniel Sanders       return Result;
1311c171f65aSDaniel Sanders   }
1312c171f65aSDaniel Sanders 
1313c171f65aSDaniel Sanders   if (hasMips32r6() && isGP64()) {
1314d34e60caSNicola Zaghen     LLVM_DEBUG(
1315d34e60caSNicola Zaghen         dbgs() << "Trying Mips32r6_64r6 (GPR64) table (32-bit opcodes):\n");
131636901dd1SVasileios Kalintiris     Result = decodeInstruction(DecoderTableMips32r6_64r6_GP6432, Instr, Insn,
131736901dd1SVasileios Kalintiris                                Address, this, STI);
1318a5f52dc0SSimon Dardis     if (Result != MCDisassembler::Fail)
13190fa60416SDaniel Sanders       return Result;
13200fa60416SDaniel Sanders   }
13210fa60416SDaniel Sanders 
13224fbf76f7SSimon Dardis   if (hasMips32r6() && isPTR64()) {
1323d34e60caSNicola Zaghen     LLVM_DEBUG(
1324d34e60caSNicola Zaghen         dbgs() << "Trying Mips32r6_64r6 (PTR64) table (32-bit opcodes):\n");
13254fbf76f7SSimon Dardis     Result = decodeInstruction(DecoderTableMips32r6_64r6_PTR6432, Instr, Insn,
13264fbf76f7SSimon Dardis                                Address, this, STI);
1327a5f52dc0SSimon Dardis     if (Result != MCDisassembler::Fail)
13284fbf76f7SSimon Dardis       return Result;
13294fbf76f7SSimon Dardis   }
13304fbf76f7SSimon Dardis 
1331c171f65aSDaniel Sanders   if (hasMips32r6()) {
1332d34e60caSNicola Zaghen     LLVM_DEBUG(dbgs() << "Trying Mips32r6_64r6 table (32-bit opcodes):\n");
13334aa6bea7SRafael Espindola     Result = decodeInstruction(DecoderTableMips32r6_64r632, Instr, Insn,
13345c582b2fSDaniel Sanders                                Address, this, STI);
1335a5f52dc0SSimon Dardis     if (Result != MCDisassembler::Fail)
13365c582b2fSDaniel Sanders       return Result;
13375c582b2fSDaniel Sanders   }
13385c582b2fSDaniel Sanders 
13394fbf76f7SSimon Dardis   if (hasMips2() && isPTR64()) {
1340d34e60caSNicola Zaghen     LLVM_DEBUG(
1341d34e60caSNicola Zaghen         dbgs() << "Trying Mips32r6_64r6 (PTR64) table (32-bit opcodes):\n");
13424fbf76f7SSimon Dardis     Result = decodeInstruction(DecoderTableMips32_64_PTR6432, Instr, Insn,
13434fbf76f7SSimon Dardis                                Address, this, STI);
1344a5f52dc0SSimon Dardis     if (Result != MCDisassembler::Fail)
13454fbf76f7SSimon Dardis       return Result;
13464fbf76f7SSimon Dardis   }
13474fbf76f7SSimon Dardis 
13483adf9b8dSKai Nacke   if (hasCnMips()) {
1349d34e60caSNicola Zaghen     LLVM_DEBUG(dbgs() << "Trying CnMips table (32-bit opcodes):\n");
13503adf9b8dSKai Nacke     Result = decodeInstruction(DecoderTableCnMips32, Instr, Insn,
13513adf9b8dSKai Nacke                                Address, this, STI);
1352a5f52dc0SSimon Dardis     if (Result != MCDisassembler::Fail)
13533adf9b8dSKai Nacke       return Result;
13543adf9b8dSKai Nacke   }
13553adf9b8dSKai Nacke 
1356a19216c8SDaniel Sanders   if (isGP64()) {
1357d34e60caSNicola Zaghen     LLVM_DEBUG(dbgs() << "Trying Mips64 (GPR64) table (32-bit opcodes):\n");
1358a19216c8SDaniel Sanders     Result = decodeInstruction(DecoderTableMips6432, Instr, Insn,
1359a19216c8SDaniel Sanders                                Address, this, STI);
1360a5f52dc0SSimon Dardis     if (Result != MCDisassembler::Fail)
1361a19216c8SDaniel Sanders       return Result;
1362a19216c8SDaniel Sanders   }
1363a19216c8SDaniel Sanders 
136451a7ae2aSSimon Dardis   if (isFP64()) {
1365d34e60caSNicola Zaghen     LLVM_DEBUG(
1366d34e60caSNicola Zaghen         dbgs() << "Trying MipsFP64 (64 bit FPU) table (32-bit opcodes):\n");
136751a7ae2aSSimon Dardis     Result = decodeInstruction(DecoderTableMipsFP6432, Instr, Insn,
136851a7ae2aSSimon Dardis                                Address, this, STI);
136951a7ae2aSSimon Dardis     if (Result != MCDisassembler::Fail)
137051a7ae2aSSimon Dardis       return Result;
137151a7ae2aSSimon Dardis   }
137251a7ae2aSSimon Dardis 
1373d34e60caSNicola Zaghen   LLVM_DEBUG(dbgs() << "Trying Mips table (32-bit opcodes):\n");
137471928e68SAkira Hatanaka   // Calling the auto-generated decoder function.
13754aa6bea7SRafael Espindola   Result =
13764aa6bea7SRafael Espindola       decodeInstruction(DecoderTableMips32, Instr, Insn, Address, this, STI);
1377a5f52dc0SSimon Dardis   if (Result != MCDisassembler::Fail)
137871928e68SAkira Hatanaka     return Result;
137971928e68SAkira Hatanaka 
138071928e68SAkira Hatanaka   return MCDisassembler::Fail;
138171928e68SAkira Hatanaka }
138271928e68SAkira Hatanaka 
1383ec8a5490SReed Kotler static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst,
1384ec8a5490SReed Kotler                                                  unsigned RegNo,
1385ec8a5490SReed Kotler                                                  uint64_t Address,
1386ec8a5490SReed Kotler                                                  const void *Decoder) {
1387ec8a5490SReed Kotler   return MCDisassembler::Fail;
1388ec8a5490SReed Kotler }
1389ec8a5490SReed Kotler 
139013e6ccf3SAkira Hatanaka static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst,
139171928e68SAkira Hatanaka                                              unsigned RegNo,
139271928e68SAkira Hatanaka                                              uint64_t Address,
139371928e68SAkira Hatanaka                                              const void *Decoder) {
139471928e68SAkira Hatanaka   if (RegNo > 31)
139571928e68SAkira Hatanaka     return MCDisassembler::Fail;
139671928e68SAkira Hatanaka 
139713e6ccf3SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::GPR64RegClassID, RegNo);
1398e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
139971928e68SAkira Hatanaka   return MCDisassembler::Success;
140071928e68SAkira Hatanaka }
140171928e68SAkira Hatanaka 
1402b0852e54SZoran Jovanovic static DecodeStatus DecodeGPRMM16RegisterClass(MCInst &Inst,
1403b0852e54SZoran Jovanovic                                                unsigned RegNo,
1404b0852e54SZoran Jovanovic                                                uint64_t Address,
1405b0852e54SZoran Jovanovic                                                const void *Decoder) {
1406ea22c4cfSJozef Kolek   if (RegNo > 7)
1407b0852e54SZoran Jovanovic     return MCDisassembler::Fail;
1408ea22c4cfSJozef Kolek   unsigned Reg = getReg(Decoder, Mips::GPRMM16RegClassID, RegNo);
1409e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1410ea22c4cfSJozef Kolek   return MCDisassembler::Success;
1411b0852e54SZoran Jovanovic }
1412b0852e54SZoran Jovanovic 
14131904fa21SJozef Kolek static DecodeStatus DecodeGPRMM16ZeroRegisterClass(MCInst &Inst,
14141904fa21SJozef Kolek                                                    unsigned RegNo,
14151904fa21SJozef Kolek                                                    uint64_t Address,
14161904fa21SJozef Kolek                                                    const void *Decoder) {
1417315e7ecaSJozef Kolek   if (RegNo > 7)
14181904fa21SJozef Kolek     return MCDisassembler::Fail;
1419315e7ecaSJozef Kolek   unsigned Reg = getReg(Decoder, Mips::GPRMM16ZeroRegClassID, RegNo);
1420e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1421315e7ecaSJozef Kolek   return MCDisassembler::Success;
14221904fa21SJozef Kolek }
14231904fa21SJozef Kolek 
142441688679SZoran Jovanovic static DecodeStatus DecodeGPRMM16MovePRegisterClass(MCInst &Inst,
142541688679SZoran Jovanovic                                                     unsigned RegNo,
142641688679SZoran Jovanovic                                                     uint64_t Address,
142741688679SZoran Jovanovic                                                     const void *Decoder) {
142841688679SZoran Jovanovic   if (RegNo > 7)
142941688679SZoran Jovanovic     return MCDisassembler::Fail;
143041688679SZoran Jovanovic   unsigned Reg = getReg(Decoder, Mips::GPRMM16MovePRegClassID, RegNo);
1431e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
143241688679SZoran Jovanovic   return MCDisassembler::Success;
143341688679SZoran Jovanovic }
143441688679SZoran Jovanovic 
143513e6ccf3SAkira Hatanaka static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst,
143671928e68SAkira Hatanaka                                              unsigned RegNo,
143771928e68SAkira Hatanaka                                              uint64_t Address,
143871928e68SAkira Hatanaka                                              const void *Decoder) {
143971928e68SAkira Hatanaka   if (RegNo > 31)
144071928e68SAkira Hatanaka     return MCDisassembler::Fail;
144113e6ccf3SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::GPR32RegClassID, RegNo);
1442e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
144371928e68SAkira Hatanaka   return MCDisassembler::Success;
144471928e68SAkira Hatanaka }
144571928e68SAkira Hatanaka 
14469bfa2e2eSAkira Hatanaka static DecodeStatus DecodePtrRegisterClass(MCInst &Inst,
14479bfa2e2eSAkira Hatanaka                                            unsigned RegNo,
14489bfa2e2eSAkira Hatanaka                                            uint64_t Address,
14499bfa2e2eSAkira Hatanaka                                            const void *Decoder) {
1450a19216c8SDaniel Sanders   if (static_cast<const MipsDisassembler *>(Decoder)->isGP64())
14519bfa2e2eSAkira Hatanaka     return DecodeGPR64RegisterClass(Inst, RegNo, Address, Decoder);
14529bfa2e2eSAkira Hatanaka 
14539bfa2e2eSAkira Hatanaka   return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
14549bfa2e2eSAkira Hatanaka }
14559bfa2e2eSAkira Hatanaka 
1456654655f1SAkira Hatanaka static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst,
1457ecabd1a5SAkira Hatanaka                                             unsigned RegNo,
1458ecabd1a5SAkira Hatanaka                                             uint64_t Address,
1459ecabd1a5SAkira Hatanaka                                             const void *Decoder) {
146013e6ccf3SAkira Hatanaka   return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
1461ecabd1a5SAkira Hatanaka }
1462ecabd1a5SAkira Hatanaka 
146371928e68SAkira Hatanaka static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
146471928e68SAkira Hatanaka                                              unsigned RegNo,
146571928e68SAkira Hatanaka                                              uint64_t Address,
146671928e68SAkira Hatanaka                                              const void *Decoder) {
146771928e68SAkira Hatanaka   if (RegNo > 31)
146871928e68SAkira Hatanaka     return MCDisassembler::Fail;
146971928e68SAkira Hatanaka 
14709bf2b567SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::FGR64RegClassID, RegNo);
1471e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
147271928e68SAkira Hatanaka   return MCDisassembler::Success;
147371928e68SAkira Hatanaka }
147471928e68SAkira Hatanaka 
147571928e68SAkira Hatanaka static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
147671928e68SAkira Hatanaka                                              unsigned RegNo,
147771928e68SAkira Hatanaka                                              uint64_t Address,
147871928e68SAkira Hatanaka                                              const void *Decoder) {
147971928e68SAkira Hatanaka   if (RegNo > 31)
148071928e68SAkira Hatanaka     return MCDisassembler::Fail;
148171928e68SAkira Hatanaka 
14829bf2b567SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::FGR32RegClassID, RegNo);
1483e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
148471928e68SAkira Hatanaka   return MCDisassembler::Success;
148571928e68SAkira Hatanaka }
148671928e68SAkira Hatanaka 
148771928e68SAkira Hatanaka static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
148871928e68SAkira Hatanaka                                            unsigned RegNo,
148971928e68SAkira Hatanaka                                            uint64_t Address,
149071928e68SAkira Hatanaka                                            const void *Decoder) {
1491253777fdSChad Rosier   if (RegNo > 31)
1492253777fdSChad Rosier     return MCDisassembler::Fail;
1493253777fdSChad Rosier   unsigned Reg = getReg(Decoder, Mips::CCRRegClassID, RegNo);
1494e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
149571928e68SAkira Hatanaka   return MCDisassembler::Success;
149671928e68SAkira Hatanaka }
149771928e68SAkira Hatanaka 
14981fb1b8b8SAkira Hatanaka static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst,
14991fb1b8b8SAkira Hatanaka                                            unsigned RegNo,
15001fb1b8b8SAkira Hatanaka                                            uint64_t Address,
15011fb1b8b8SAkira Hatanaka                                            const void *Decoder) {
15021fb1b8b8SAkira Hatanaka   if (RegNo > 7)
15031fb1b8b8SAkira Hatanaka     return MCDisassembler::Fail;
15041fb1b8b8SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::FCCRegClassID, RegNo);
1505e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
15061fb1b8b8SAkira Hatanaka   return MCDisassembler::Success;
15071fb1b8b8SAkira Hatanaka }
15081fb1b8b8SAkira Hatanaka 
150936901dd1SVasileios Kalintiris static DecodeStatus DecodeFGRCCRegisterClass(MCInst &Inst, unsigned RegNo,
15100fa60416SDaniel Sanders                                              uint64_t Address,
15110fa60416SDaniel Sanders                                              const void *Decoder) {
15120fa60416SDaniel Sanders   if (RegNo > 31)
15130fa60416SDaniel Sanders     return MCDisassembler::Fail;
15140fa60416SDaniel Sanders 
151536901dd1SVasileios Kalintiris   unsigned Reg = getReg(Decoder, Mips::FGRCCRegClassID, RegNo);
1516e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
15170fa60416SDaniel Sanders   return MCDisassembler::Success;
15180fa60416SDaniel Sanders }
15190fa60416SDaniel Sanders 
152071928e68SAkira Hatanaka static DecodeStatus DecodeMem(MCInst &Inst,
152171928e68SAkira Hatanaka                               unsigned Insn,
152271928e68SAkira Hatanaka                               uint64_t Address,
152371928e68SAkira Hatanaka                               const void *Decoder) {
152471928e68SAkira Hatanaka   int Offset = SignExtend32<16>(Insn & 0xffff);
1525ecaef49fSJim Grosbach   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1526ecaef49fSJim Grosbach   unsigned Base = fieldFromInstruction(Insn, 21, 5);
15279bf2b567SAkira Hatanaka 
152813e6ccf3SAkira Hatanaka   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
152913e6ccf3SAkira Hatanaka   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
153071928e68SAkira Hatanaka 
1531d7ecf49eSVladimir Medic   if (Inst.getOpcode() == Mips::SC ||
1532e4e83a7bSDaniel Sanders       Inst.getOpcode() == Mips::SCD)
1533e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Reg));
1534e4e83a7bSDaniel Sanders 
1535e4e83a7bSDaniel Sanders   Inst.addOperand(MCOperand::createReg(Reg));
1536e4e83a7bSDaniel Sanders   Inst.addOperand(MCOperand::createReg(Base));
1537e4e83a7bSDaniel Sanders   Inst.addOperand(MCOperand::createImm(Offset));
1538e4e83a7bSDaniel Sanders 
1539e4e83a7bSDaniel Sanders   return MCDisassembler::Success;
154071928e68SAkira Hatanaka }
154171928e68SAkira Hatanaka 
1542e4e83a7bSDaniel Sanders static DecodeStatus DecodeMemEVA(MCInst &Inst,
1543e4e83a7bSDaniel Sanders                                  unsigned Insn,
1544e4e83a7bSDaniel Sanders                                  uint64_t Address,
1545e4e83a7bSDaniel Sanders                                  const void *Decoder) {
1546e4e83a7bSDaniel Sanders   int Offset = SignExtend32<9>(Insn >> 7);
1547e4e83a7bSDaniel Sanders   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1548e4e83a7bSDaniel Sanders   unsigned Base = fieldFromInstruction(Insn, 21, 5);
1549e4e83a7bSDaniel Sanders 
1550e4e83a7bSDaniel Sanders   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1551e4e83a7bSDaniel Sanders   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1552e4e83a7bSDaniel Sanders 
1553e4e83a7bSDaniel Sanders    if (Inst.getOpcode() == Mips::SCE)
1554e4e83a7bSDaniel Sanders      Inst.addOperand(MCOperand::createReg(Reg));
1555e4e83a7bSDaniel Sanders 
1556e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1557e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1558e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
155971928e68SAkira Hatanaka 
156071928e68SAkira Hatanaka   return MCDisassembler::Success;
156171928e68SAkira Hatanaka }
156271928e68SAkira Hatanaka 
15633c88fbd3SHrvoje Varga static DecodeStatus DecodeLoadByte15(MCInst &Inst,
15643c88fbd3SHrvoje Varga                                      unsigned Insn,
15653c88fbd3SHrvoje Varga                                      uint64_t Address,
15663c88fbd3SHrvoje Varga                                      const void *Decoder) {
15673c88fbd3SHrvoje Varga   int Offset = SignExtend32<16>(Insn & 0xffff);
15683c88fbd3SHrvoje Varga   unsigned Base = fieldFromInstruction(Insn, 16, 5);
15693c88fbd3SHrvoje Varga   unsigned Reg = fieldFromInstruction(Insn, 21, 5);
15703c88fbd3SHrvoje Varga 
15713c88fbd3SHrvoje Varga   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
15723c88fbd3SHrvoje Varga   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
15733c88fbd3SHrvoje Varga 
15743c88fbd3SHrvoje Varga   Inst.addOperand(MCOperand::createReg(Reg));
15753c88fbd3SHrvoje Varga   Inst.addOperand(MCOperand::createReg(Base));
15763c88fbd3SHrvoje Varga   Inst.addOperand(MCOperand::createImm(Offset));
15773c88fbd3SHrvoje Varga 
15783c88fbd3SHrvoje Varga   return MCDisassembler::Success;
15793c88fbd3SHrvoje Varga }
15803c88fbd3SHrvoje Varga 
158192db6b78SDaniel Sanders static DecodeStatus DecodeCacheOp(MCInst &Inst,
158292db6b78SDaniel Sanders                               unsigned Insn,
158392db6b78SDaniel Sanders                               uint64_t Address,
158492db6b78SDaniel Sanders                               const void *Decoder) {
158592db6b78SDaniel Sanders   int Offset = SignExtend32<16>(Insn & 0xffff);
158692db6b78SDaniel Sanders   unsigned Hint = fieldFromInstruction(Insn, 16, 5);
158792db6b78SDaniel Sanders   unsigned Base = fieldFromInstruction(Insn, 21, 5);
158892db6b78SDaniel Sanders 
158992db6b78SDaniel Sanders   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
159092db6b78SDaniel Sanders 
1591e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1592e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
1593e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Hint));
159492db6b78SDaniel Sanders 
159592db6b78SDaniel Sanders   return MCDisassembler::Success;
159692db6b78SDaniel Sanders }
159792db6b78SDaniel Sanders 
1598ab6d1cceSJozef Kolek static DecodeStatus DecodeCacheOpMM(MCInst &Inst,
1599ab6d1cceSJozef Kolek                                     unsigned Insn,
1600ab6d1cceSJozef Kolek                                     uint64_t Address,
1601ab6d1cceSJozef Kolek                                     const void *Decoder) {
1602ab6d1cceSJozef Kolek   int Offset = SignExtend32<12>(Insn & 0xfff);
1603ab6d1cceSJozef Kolek   unsigned Base = fieldFromInstruction(Insn, 16, 5);
1604ab6d1cceSJozef Kolek   unsigned Hint = fieldFromInstruction(Insn, 21, 5);
1605ab6d1cceSJozef Kolek 
1606ab6d1cceSJozef Kolek   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1607ab6d1cceSJozef Kolek 
1608e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1609e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
1610e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Hint));
1611ab6d1cceSJozef Kolek 
1612ab6d1cceSJozef Kolek   return MCDisassembler::Success;
1613ab6d1cceSJozef Kolek }
1614ab6d1cceSJozef Kolek 
1615d9790793SZoran Jovanovic static DecodeStatus DecodePrefeOpMM(MCInst &Inst,
1616d9790793SZoran Jovanovic                                     unsigned Insn,
1617d9790793SZoran Jovanovic                                     uint64_t Address,
1618d9790793SZoran Jovanovic                                     const void *Decoder) {
1619d9790793SZoran Jovanovic   int Offset = SignExtend32<9>(Insn & 0x1ff);
1620d9790793SZoran Jovanovic   unsigned Base = fieldFromInstruction(Insn, 16, 5);
1621d9790793SZoran Jovanovic   unsigned Hint = fieldFromInstruction(Insn, 21, 5);
1622d9790793SZoran Jovanovic 
1623d9790793SZoran Jovanovic   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1624d9790793SZoran Jovanovic 
1625d9790793SZoran Jovanovic   Inst.addOperand(MCOperand::createReg(Base));
1626d9790793SZoran Jovanovic   Inst.addOperand(MCOperand::createImm(Offset));
1627d9790793SZoran Jovanovic   Inst.addOperand(MCOperand::createImm(Hint));
1628d9790793SZoran Jovanovic 
1629d9790793SZoran Jovanovic   return MCDisassembler::Success;
1630d9790793SZoran Jovanovic }
1631d9790793SZoran Jovanovic 
1632e4e83a7bSDaniel Sanders static DecodeStatus DecodeCacheeOp_CacheOpR6(MCInst &Inst,
1633df464ae2SVladimir Medic                                              unsigned Insn,
1634df464ae2SVladimir Medic                                              uint64_t Address,
1635df464ae2SVladimir Medic                                              const void *Decoder) {
1636e4e83a7bSDaniel Sanders   int Offset = SignExtend32<9>(Insn >> 7);
1637df464ae2SVladimir Medic   unsigned Hint = fieldFromInstruction(Insn, 16, 5);
1638df464ae2SVladimir Medic   unsigned Base = fieldFromInstruction(Insn, 21, 5);
1639df464ae2SVladimir Medic 
1640df464ae2SVladimir Medic   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1641df464ae2SVladimir Medic 
1642e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1643e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
1644e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Hint));
1645df464ae2SVladimir Medic 
1646df464ae2SVladimir Medic   return MCDisassembler::Success;
1647df464ae2SVladimir Medic }
1648df464ae2SVladimir Medic 
1649b4484d62SDaniel Sanders static DecodeStatus DecodeSyncI(MCInst &Inst,
1650b4484d62SDaniel Sanders                               unsigned Insn,
1651b4484d62SDaniel Sanders                               uint64_t Address,
1652b4484d62SDaniel Sanders                               const void *Decoder) {
1653b4484d62SDaniel Sanders   int Offset = SignExtend32<16>(Insn & 0xffff);
1654b4484d62SDaniel Sanders   unsigned Base = fieldFromInstruction(Insn, 21, 5);
1655b4484d62SDaniel Sanders 
1656b4484d62SDaniel Sanders   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1657b4484d62SDaniel Sanders 
1658e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1659e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
1660b4484d62SDaniel Sanders 
1661b4484d62SDaniel Sanders   return MCDisassembler::Success;
1662b4484d62SDaniel Sanders }
1663b4484d62SDaniel Sanders 
1664eac9301cSSimon Dardis static DecodeStatus DecodeSyncI_MM(MCInst &Inst, unsigned Insn,
1665eac9301cSSimon Dardis                                    uint64_t Address, const void *Decoder) {
1666eac9301cSSimon Dardis   int Offset = SignExtend32<16>(Insn & 0xffff);
1667eac9301cSSimon Dardis   unsigned Base = fieldFromInstruction(Insn, 16, 5);
1668eac9301cSSimon Dardis 
1669eac9301cSSimon Dardis   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1670eac9301cSSimon Dardis 
1671eac9301cSSimon Dardis   Inst.addOperand(MCOperand::createReg(Base));
1672eac9301cSSimon Dardis   Inst.addOperand(MCOperand::createImm(Offset));
1673eac9301cSSimon Dardis 
1674eac9301cSSimon Dardis   return MCDisassembler::Success;
1675eac9301cSSimon Dardis }
1676eac9301cSSimon Dardis 
167718148671SHrvoje Varga static DecodeStatus DecodeSynciR6(MCInst &Inst,
167818148671SHrvoje Varga                                   unsigned Insn,
167918148671SHrvoje Varga                                   uint64_t Address,
168018148671SHrvoje Varga                                   const void *Decoder) {
168118148671SHrvoje Varga   int Immediate = SignExtend32<16>(Insn & 0xffff);
168218148671SHrvoje Varga   unsigned Base = fieldFromInstruction(Insn, 16, 5);
168318148671SHrvoje Varga 
168418148671SHrvoje Varga   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
168518148671SHrvoje Varga 
168618148671SHrvoje Varga   Inst.addOperand(MCOperand::createReg(Base));
168718148671SHrvoje Varga   Inst.addOperand(MCOperand::createImm(Immediate));
168818148671SHrvoje Varga 
168918148671SHrvoje Varga   return MCDisassembler::Success;
169018148671SHrvoje Varga }
169118148671SHrvoje Varga 
1692fe0bf9f6SMatheus Almeida static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn,
1693fe0bf9f6SMatheus Almeida                                     uint64_t Address, const void *Decoder) {
1694fe0bf9f6SMatheus Almeida   int Offset = SignExtend32<10>(fieldFromInstruction(Insn, 16, 10));
1695fe0bf9f6SMatheus Almeida   unsigned Reg = fieldFromInstruction(Insn, 6, 5);
1696fe0bf9f6SMatheus Almeida   unsigned Base = fieldFromInstruction(Insn, 11, 5);
1697fe0bf9f6SMatheus Almeida 
1698fe0bf9f6SMatheus Almeida   Reg = getReg(Decoder, Mips::MSA128BRegClassID, Reg);
1699fe0bf9f6SMatheus Almeida   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1700fe0bf9f6SMatheus Almeida 
1701e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1702e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
17036b59c449SMatheus Almeida 
17046b59c449SMatheus Almeida   // The immediate field of an LD/ST instruction is scaled which means it must
17056b59c449SMatheus Almeida   // be multiplied (when decoding) by the size (in bytes) of the instructions'
17066b59c449SMatheus Almeida   // data format.
17076b59c449SMatheus Almeida   // .b - 1 byte
17086b59c449SMatheus Almeida   // .h - 2 bytes
17096b59c449SMatheus Almeida   // .w - 4 bytes
17106b59c449SMatheus Almeida   // .d - 8 bytes
17116b59c449SMatheus Almeida   switch(Inst.getOpcode())
17126b59c449SMatheus Almeida   {
17136b59c449SMatheus Almeida   default:
1714926883e1SEugene Zelenko     assert(false && "Unexpected instruction");
17156b59c449SMatheus Almeida     return MCDisassembler::Fail;
17166b59c449SMatheus Almeida     break;
17176b59c449SMatheus Almeida   case Mips::LD_B:
17186b59c449SMatheus Almeida   case Mips::ST_B:
1719e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(Offset));
17206b59c449SMatheus Almeida     break;
17216b59c449SMatheus Almeida   case Mips::LD_H:
17226b59c449SMatheus Almeida   case Mips::ST_H:
1723e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(Offset * 2));
17246b59c449SMatheus Almeida     break;
17256b59c449SMatheus Almeida   case Mips::LD_W:
17266b59c449SMatheus Almeida   case Mips::ST_W:
1727e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(Offset * 4));
17286b59c449SMatheus Almeida     break;
17296b59c449SMatheus Almeida   case Mips::LD_D:
17306b59c449SMatheus Almeida   case Mips::ST_D:
1731e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(Offset * 8));
17326b59c449SMatheus Almeida     break;
17336b59c449SMatheus Almeida   }
1734fe0bf9f6SMatheus Almeida 
1735fe0bf9f6SMatheus Almeida   return MCDisassembler::Success;
1736fe0bf9f6SMatheus Almeida }
1737fe0bf9f6SMatheus Almeida 
1738315e7ecaSJozef Kolek static DecodeStatus DecodeMemMMImm4(MCInst &Inst,
1739315e7ecaSJozef Kolek                                     unsigned Insn,
1740315e7ecaSJozef Kolek                                     uint64_t Address,
1741315e7ecaSJozef Kolek                                     const void *Decoder) {
1742315e7ecaSJozef Kolek   unsigned Offset = Insn & 0xf;
1743315e7ecaSJozef Kolek   unsigned Reg = fieldFromInstruction(Insn, 7, 3);
1744315e7ecaSJozef Kolek   unsigned Base = fieldFromInstruction(Insn, 4, 3);
1745315e7ecaSJozef Kolek 
1746315e7ecaSJozef Kolek   switch (Inst.getOpcode()) {
1747315e7ecaSJozef Kolek     case Mips::LBU16_MM:
1748315e7ecaSJozef Kolek     case Mips::LHU16_MM:
1749315e7ecaSJozef Kolek     case Mips::LW16_MM:
1750315e7ecaSJozef Kolek       if (DecodeGPRMM16RegisterClass(Inst, Reg, Address, Decoder)
1751315e7ecaSJozef Kolek             == MCDisassembler::Fail)
1752315e7ecaSJozef Kolek         return MCDisassembler::Fail;
1753315e7ecaSJozef Kolek       break;
1754315e7ecaSJozef Kolek     case Mips::SB16_MM:
1755797c2aecSZlatko Buljan     case Mips::SB16_MMR6:
1756315e7ecaSJozef Kolek     case Mips::SH16_MM:
1757797c2aecSZlatko Buljan     case Mips::SH16_MMR6:
1758315e7ecaSJozef Kolek     case Mips::SW16_MM:
1759797c2aecSZlatko Buljan     case Mips::SW16_MMR6:
1760315e7ecaSJozef Kolek       if (DecodeGPRMM16ZeroRegisterClass(Inst, Reg, Address, Decoder)
1761315e7ecaSJozef Kolek             == MCDisassembler::Fail)
1762315e7ecaSJozef Kolek         return MCDisassembler::Fail;
1763315e7ecaSJozef Kolek       break;
1764315e7ecaSJozef Kolek   }
1765315e7ecaSJozef Kolek 
1766315e7ecaSJozef Kolek   if (DecodeGPRMM16RegisterClass(Inst, Base, Address, Decoder)
1767315e7ecaSJozef Kolek         == MCDisassembler::Fail)
1768315e7ecaSJozef Kolek     return MCDisassembler::Fail;
1769315e7ecaSJozef Kolek 
1770315e7ecaSJozef Kolek   switch (Inst.getOpcode()) {
1771315e7ecaSJozef Kolek     case Mips::LBU16_MM:
1772315e7ecaSJozef Kolek       if (Offset == 0xf)
1773e9119e41SJim Grosbach         Inst.addOperand(MCOperand::createImm(-1));
1774315e7ecaSJozef Kolek       else
1775e9119e41SJim Grosbach         Inst.addOperand(MCOperand::createImm(Offset));
1776315e7ecaSJozef Kolek       break;
1777315e7ecaSJozef Kolek     case Mips::SB16_MM:
1778797c2aecSZlatko Buljan     case Mips::SB16_MMR6:
1779e9119e41SJim Grosbach       Inst.addOperand(MCOperand::createImm(Offset));
1780315e7ecaSJozef Kolek       break;
1781315e7ecaSJozef Kolek     case Mips::LHU16_MM:
1782315e7ecaSJozef Kolek     case Mips::SH16_MM:
1783797c2aecSZlatko Buljan     case Mips::SH16_MMR6:
1784e9119e41SJim Grosbach       Inst.addOperand(MCOperand::createImm(Offset << 1));
1785315e7ecaSJozef Kolek       break;
1786315e7ecaSJozef Kolek     case Mips::LW16_MM:
1787315e7ecaSJozef Kolek     case Mips::SW16_MM:
1788797c2aecSZlatko Buljan     case Mips::SW16_MMR6:
1789e9119e41SJim Grosbach       Inst.addOperand(MCOperand::createImm(Offset << 2));
1790315e7ecaSJozef Kolek       break;
1791315e7ecaSJozef Kolek   }
1792315e7ecaSJozef Kolek 
1793315e7ecaSJozef Kolek   return MCDisassembler::Success;
1794315e7ecaSJozef Kolek }
1795315e7ecaSJozef Kolek 
179612c6982bSJozef Kolek static DecodeStatus DecodeMemMMSPImm5Lsl2(MCInst &Inst,
179712c6982bSJozef Kolek                                           unsigned Insn,
179812c6982bSJozef Kolek                                           uint64_t Address,
179912c6982bSJozef Kolek                                           const void *Decoder) {
180012c6982bSJozef Kolek   unsigned Offset = Insn & 0x1F;
180112c6982bSJozef Kolek   unsigned Reg = fieldFromInstruction(Insn, 5, 5);
180212c6982bSJozef Kolek 
180312c6982bSJozef Kolek   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
180412c6982bSJozef Kolek 
1805e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1806e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Mips::SP));
1807e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset << 2));
180812c6982bSJozef Kolek 
180912c6982bSJozef Kolek   return MCDisassembler::Success;
181012c6982bSJozef Kolek }
181112c6982bSJozef Kolek 
1812e10a02ecSJozef Kolek static DecodeStatus DecodeMemMMGPImm7Lsl2(MCInst &Inst,
1813e10a02ecSJozef Kolek                                           unsigned Insn,
1814e10a02ecSJozef Kolek                                           uint64_t Address,
1815e10a02ecSJozef Kolek                                           const void *Decoder) {
1816e10a02ecSJozef Kolek   unsigned Offset = Insn & 0x7F;
1817e10a02ecSJozef Kolek   unsigned Reg = fieldFromInstruction(Insn, 7, 3);
1818e10a02ecSJozef Kolek 
1819e10a02ecSJozef Kolek   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1820e10a02ecSJozef Kolek 
1821e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1822e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Mips::GP));
1823e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset << 2));
1824e10a02ecSJozef Kolek 
1825e10a02ecSJozef Kolek   return MCDisassembler::Success;
1826e10a02ecSJozef Kolek }
1827e10a02ecSJozef Kolek 
1828d68d424aSJozef Kolek static DecodeStatus DecodeMemMMReglistImm4Lsl2(MCInst &Inst,
1829d68d424aSJozef Kolek                                                unsigned Insn,
1830d68d424aSJozef Kolek                                                uint64_t Address,
1831d68d424aSJozef Kolek                                                const void *Decoder) {
1832797c2aecSZlatko Buljan   int Offset;
1833797c2aecSZlatko Buljan   switch (Inst.getOpcode()) {
1834797c2aecSZlatko Buljan   case Mips::LWM16_MMR6:
1835797c2aecSZlatko Buljan   case Mips::SWM16_MMR6:
1836797c2aecSZlatko Buljan     Offset = fieldFromInstruction(Insn, 4, 4);
1837797c2aecSZlatko Buljan     break;
1838797c2aecSZlatko Buljan   default:
1839797c2aecSZlatko Buljan     Offset = SignExtend32<4>(Insn & 0xf);
1840797c2aecSZlatko Buljan     break;
1841797c2aecSZlatko Buljan   }
1842d68d424aSJozef Kolek 
1843d68d424aSJozef Kolek   if (DecodeRegListOperand16(Inst, Insn, Address, Decoder)
1844d68d424aSJozef Kolek       == MCDisassembler::Fail)
1845d68d424aSJozef Kolek     return MCDisassembler::Fail;
1846d68d424aSJozef Kolek 
1847e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Mips::SP));
1848e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset << 2));
1849d68d424aSJozef Kolek 
1850d68d424aSJozef Kolek   return MCDisassembler::Success;
1851d68d424aSJozef Kolek }
1852d68d424aSJozef Kolek 
1853a6593ff6SZoran Jovanovic static DecodeStatus DecodeMemMMImm9(MCInst &Inst,
1854a6593ff6SZoran Jovanovic                                     unsigned Insn,
1855a6593ff6SZoran Jovanovic                                     uint64_t Address,
1856a6593ff6SZoran Jovanovic                                     const void *Decoder) {
1857a6593ff6SZoran Jovanovic   int Offset = SignExtend32<9>(Insn & 0x1ff);
1858a6593ff6SZoran Jovanovic   unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1859a6593ff6SZoran Jovanovic   unsigned Base = fieldFromInstruction(Insn, 16, 5);
1860a6593ff6SZoran Jovanovic 
1861a6593ff6SZoran Jovanovic   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1862a6593ff6SZoran Jovanovic   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1863a6593ff6SZoran Jovanovic 
1864777afc7fSSimon Dardis   if (Inst.getOpcode() == Mips::SCE_MM || Inst.getOpcode() == Mips::SC_MMR6)
18653ef4dd7bSHrvoje Varga     Inst.addOperand(MCOperand::createReg(Reg));
18663ef4dd7bSHrvoje Varga 
1867a6593ff6SZoran Jovanovic   Inst.addOperand(MCOperand::createReg(Reg));
1868a6593ff6SZoran Jovanovic   Inst.addOperand(MCOperand::createReg(Base));
1869a6593ff6SZoran Jovanovic   Inst.addOperand(MCOperand::createImm(Offset));
1870a6593ff6SZoran Jovanovic 
1871a6593ff6SZoran Jovanovic   return MCDisassembler::Success;
1872a6593ff6SZoran Jovanovic }
1873a6593ff6SZoran Jovanovic 
1874dde3d582SVladimir Medic static DecodeStatus DecodeMemMMImm12(MCInst &Inst,
1875dde3d582SVladimir Medic                                      unsigned Insn,
1876dde3d582SVladimir Medic                                      uint64_t Address,
1877dde3d582SVladimir Medic                                      const void *Decoder) {
1878dde3d582SVladimir Medic   int Offset = SignExtend32<12>(Insn & 0x0fff);
1879dde3d582SVladimir Medic   unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1880dde3d582SVladimir Medic   unsigned Base = fieldFromInstruction(Insn, 16, 5);
1881dde3d582SVladimir Medic 
1882dde3d582SVladimir Medic   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1883dde3d582SVladimir Medic   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1884dde3d582SVladimir Medic 
1885a4c4b5fcSZoran Jovanovic   switch (Inst.getOpcode()) {
1886a4c4b5fcSZoran Jovanovic   case Mips::SWM32_MM:
1887a4c4b5fcSZoran Jovanovic   case Mips::LWM32_MM:
1888a4c4b5fcSZoran Jovanovic     if (DecodeRegListOperand(Inst, Insn, Address, Decoder)
1889a4c4b5fcSZoran Jovanovic         == MCDisassembler::Fail)
1890a4c4b5fcSZoran Jovanovic       return MCDisassembler::Fail;
1891e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Base));
1892e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(Offset));
1893a4c4b5fcSZoran Jovanovic     break;
1894a4c4b5fcSZoran Jovanovic   case Mips::SC_MM:
1895e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Reg));
1896b03fd12cSJustin Bogner     LLVM_FALLTHROUGH;
1897a4c4b5fcSZoran Jovanovic   default:
1898e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Reg));
18996a319923SSimon Dardis     if (Inst.getOpcode() == Mips::LWP_MM || Inst.getOpcode() == Mips::SWP_MM)
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 
2301*56e4ea2bSSimon Atanasyan static DecodeStatus DecodeJumpTargetXMM(MCInst &Inst,
2302*56e4ea2bSSimon Atanasyan                                         unsigned Insn,
2303*56e4ea2bSSimon Atanasyan                                         uint64_t Address,
2304*56e4ea2bSSimon Atanasyan                                         const void *Decoder) {
2305*56e4ea2bSSimon Atanasyan   unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 2;
2306*56e4ea2bSSimon Atanasyan   Inst.addOperand(MCOperand::createImm(JumpOffset));
2307*56e4ea2bSSimon Atanasyan   return MCDisassembler::Success;
2308*56e4ea2bSSimon Atanasyan }
2309*56e4ea2bSSimon Atanasyan 
2310aa2b9278SJozef Kolek static DecodeStatus DecodeAddiur2Simm7(MCInst &Inst,
2311aa2b9278SJozef Kolek                                        unsigned Value,
2312aa2b9278SJozef Kolek                                        uint64_t Address,
2313aa2b9278SJozef Kolek                                        const void *Decoder) {
2314aa2b9278SJozef Kolek   if (Value == 0)
2315e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(1));
2316aa2b9278SJozef Kolek   else if (Value == 0x7)
2317e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(-1));
2318aa2b9278SJozef Kolek   else
2319e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(Value << 2));
2320aa2b9278SJozef Kolek   return MCDisassembler::Success;
2321aa2b9278SJozef Kolek }
2322aa2b9278SJozef Kolek 
232397297770SDaniel Sanders static DecodeStatus DecodeLi16Imm(MCInst &Inst,
2324aa2b9278SJozef Kolek                                   unsigned Value,
2325aa2b9278SJozef Kolek                                   uint64_t Address,
2326aa2b9278SJozef Kolek                                   const void *Decoder) {
2327aa2b9278SJozef Kolek   if (Value == 0x7F)
2328e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(-1));
2329aa2b9278SJozef Kolek   else
2330e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(Value));
2331aa2b9278SJozef Kolek   return MCDisassembler::Success;
2332aa2b9278SJozef Kolek }
2333aa2b9278SJozef Kolek 
23346b28f09dSZoran Jovanovic static DecodeStatus DecodePOOL16BEncodedField(MCInst &Inst,
23356b28f09dSZoran Jovanovic                                               unsigned Value,
23366b28f09dSZoran Jovanovic                                               uint64_t Address,
23376b28f09dSZoran Jovanovic                                               const void *Decoder) {
23386b28f09dSZoran Jovanovic   Inst.addOperand(MCOperand::createImm(Value == 0x0 ? 8 : Value));
23396b28f09dSZoran Jovanovic   return MCDisassembler::Success;
23406b28f09dSZoran Jovanovic }
23416b28f09dSZoran Jovanovic 
234219b7f76aSDaniel Sanders template <unsigned Bits, int Offset, int Scale>
234319b7f76aSDaniel Sanders static DecodeStatus DecodeUImmWithOffsetAndScale(MCInst &Inst, unsigned Value,
2344779c5937SMatheus Almeida                                                  uint64_t Address,
2345779c5937SMatheus Almeida                                                  const void *Decoder) {
2346ea4f653dSDaniel Sanders   Value &= ((1 << Bits) - 1);
234719b7f76aSDaniel Sanders   Value *= Scale;
2348ea4f653dSDaniel Sanders   Inst.addOperand(MCOperand::createImm(Value + Offset));
2349779c5937SMatheus Almeida   return MCDisassembler::Success;
2350779c5937SMatheus Almeida }
2351779c5937SMatheus Almeida 
235297297770SDaniel Sanders template <unsigned Bits, int Offset, int ScaleBy>
235397297770SDaniel Sanders static DecodeStatus DecodeSImmWithOffsetAndScale(MCInst &Inst, unsigned Value,
235478e89020SDaniel Sanders                                                  uint64_t Address,
235578e89020SDaniel Sanders                                                  const void *Decoder) {
235697297770SDaniel Sanders   int32_t Imm = SignExtend32<Bits>(Value) * ScaleBy;
235778e89020SDaniel Sanders   Inst.addOperand(MCOperand::createImm(Imm + Offset));
235878e89020SDaniel Sanders   return MCDisassembler::Success;
235978e89020SDaniel Sanders }
236078e89020SDaniel Sanders 
236171928e68SAkira Hatanaka static DecodeStatus DecodeInsSize(MCInst &Inst,
236271928e68SAkira Hatanaka                                   unsigned Insn,
236371928e68SAkira Hatanaka                                   uint64_t Address,
236471928e68SAkira Hatanaka                                   const void *Decoder) {
236571928e68SAkira Hatanaka   // First we need to grab the pos(lsb) from MCInst.
23666f83ae38SSimon Dardis   // This function only handles the 32 bit variants of ins, as dins
23676f83ae38SSimon Dardis   // variants are handled differently.
236871928e68SAkira Hatanaka   int Pos = Inst.getOperand(2).getImm();
23696f83ae38SSimon Dardis   int Size = (int) Insn - Pos + 1;
2370e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(SignExtend32<16>(Size)));
237171928e68SAkira Hatanaka   return MCDisassembler::Success;
237271928e68SAkira Hatanaka }
237371928e68SAkira Hatanaka 
2374b59e1a41SDaniel Sanders static DecodeStatus DecodeSimm19Lsl2(MCInst &Inst, unsigned Insn,
2375b59e1a41SDaniel Sanders                                      uint64_t Address, const void *Decoder) {
2376e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(SignExtend32<19>(Insn) * 4));
2377b59e1a41SDaniel Sanders   return MCDisassembler::Success;
2378b59e1a41SDaniel Sanders }
23792855142aSZoran Jovanovic 
23802855142aSZoran Jovanovic static DecodeStatus DecodeSimm18Lsl3(MCInst &Inst, unsigned Insn,
23812855142aSZoran Jovanovic                                      uint64_t Address, const void *Decoder) {
2382e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(SignExtend32<18>(Insn) * 8));
23832855142aSZoran Jovanovic   return MCDisassembler::Success;
23842855142aSZoran Jovanovic }
2385a4c4b5fcSZoran Jovanovic 
2386b682ddf3SVladimir Medic static DecodeStatus DecodeSimm9SP(MCInst &Inst, unsigned Insn,
2387b682ddf3SVladimir Medic                                   uint64_t Address, const void *Decoder) {
2388b682ddf3SVladimir Medic   int32_t DecodedValue;
2389b682ddf3SVladimir Medic   switch (Insn) {
2390b682ddf3SVladimir Medic   case 0: DecodedValue = 256; break;
2391b682ddf3SVladimir Medic   case 1: DecodedValue = 257; break;
2392b682ddf3SVladimir Medic   case 510: DecodedValue = -258; break;
2393b682ddf3SVladimir Medic   case 511: DecodedValue = -257; break;
2394b682ddf3SVladimir Medic   default: DecodedValue = SignExtend32<9>(Insn); break;
2395b682ddf3SVladimir Medic   }
2396e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(DecodedValue * 4));
2397b682ddf3SVladimir Medic   return MCDisassembler::Success;
2398b682ddf3SVladimir Medic }
2399b682ddf3SVladimir Medic 
2400b682ddf3SVladimir Medic static DecodeStatus DecodeANDI16Imm(MCInst &Inst, unsigned Insn,
2401b682ddf3SVladimir Medic                                     uint64_t Address, const void *Decoder) {
2402b682ddf3SVladimir Medic   // Insn must be >= 0, since it is unsigned that condition is always true.
2403b682ddf3SVladimir Medic   assert(Insn < 16);
2404b682ddf3SVladimir Medic   int32_t DecodedValues[] = {128, 1, 2, 3, 4, 7, 8, 15, 16, 31, 32, 63, 64,
2405b682ddf3SVladimir Medic                              255, 32768, 65535};
2406e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(DecodedValues[Insn]));
2407b682ddf3SVladimir Medic   return MCDisassembler::Success;
2408b682ddf3SVladimir Medic }
2409b682ddf3SVladimir Medic 
2410a4c4b5fcSZoran Jovanovic static DecodeStatus DecodeRegListOperand(MCInst &Inst,
2411a4c4b5fcSZoran Jovanovic                                          unsigned Insn,
2412a4c4b5fcSZoran Jovanovic                                          uint64_t Address,
2413a4c4b5fcSZoran Jovanovic                                          const void *Decoder) {
2414a4c4b5fcSZoran Jovanovic   unsigned Regs[] = {Mips::S0, Mips::S1, Mips::S2, Mips::S3, Mips::S4, Mips::S5,
2415dc4b8c27SZoran Jovanovic                      Mips::S6, Mips::S7, Mips::FP};
2416a4c4b5fcSZoran Jovanovic   unsigned RegNum;
2417a4c4b5fcSZoran Jovanovic 
2418a4c4b5fcSZoran Jovanovic   unsigned RegLst = fieldFromInstruction(Insn, 21, 5);
2419df19a5e6SDaniel Sanders 
2420a4c4b5fcSZoran Jovanovic   // Empty register lists are not allowed.
2421a4c4b5fcSZoran Jovanovic   if (RegLst == 0)
2422a4c4b5fcSZoran Jovanovic     return MCDisassembler::Fail;
2423a4c4b5fcSZoran Jovanovic 
2424a4c4b5fcSZoran Jovanovic   RegNum = RegLst & 0xf;
2425df19a5e6SDaniel Sanders 
2426df19a5e6SDaniel Sanders   // RegLst values 10-15, and 26-31 are reserved.
2427df19a5e6SDaniel Sanders   if (RegNum > 9)
2428df19a5e6SDaniel Sanders     return MCDisassembler::Fail;
2429df19a5e6SDaniel Sanders 
2430a4c4b5fcSZoran Jovanovic   for (unsigned i = 0; i < RegNum; i++)
2431e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Regs[i]));
2432a4c4b5fcSZoran Jovanovic 
2433a4c4b5fcSZoran Jovanovic   if (RegLst & 0x10)
2434e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::RA));
2435a4c4b5fcSZoran Jovanovic 
2436a4c4b5fcSZoran Jovanovic   return MCDisassembler::Success;
2437a4c4b5fcSZoran Jovanovic }
2438f9a02500SZoran Jovanovic 
2439f9a02500SZoran Jovanovic static DecodeStatus DecodeRegListOperand16(MCInst &Inst, unsigned Insn,
2440f9a02500SZoran Jovanovic                                            uint64_t Address,
2441f9a02500SZoran Jovanovic                                            const void *Decoder) {
2442f9a02500SZoran Jovanovic   unsigned Regs[] = {Mips::S0, Mips::S1, Mips::S2, Mips::S3};
2443797c2aecSZlatko Buljan   unsigned RegLst;
2444797c2aecSZlatko Buljan   switch(Inst.getOpcode()) {
2445797c2aecSZlatko Buljan   default:
2446797c2aecSZlatko Buljan     RegLst = fieldFromInstruction(Insn, 4, 2);
2447797c2aecSZlatko Buljan     break;
2448797c2aecSZlatko Buljan   case Mips::LWM16_MMR6:
2449797c2aecSZlatko Buljan   case Mips::SWM16_MMR6:
2450797c2aecSZlatko Buljan     RegLst = fieldFromInstruction(Insn, 8, 2);
2451797c2aecSZlatko Buljan     break;
2452797c2aecSZlatko Buljan   }
2453d68d424aSJozef Kolek   unsigned RegNum = RegLst & 0x3;
2454f9a02500SZoran Jovanovic 
2455d68d424aSJozef Kolek   for (unsigned i = 0; i <= RegNum; i++)
2456e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Regs[i]));
2457f9a02500SZoran Jovanovic 
2458e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Mips::RA));
2459f9a02500SZoran Jovanovic 
2460f9a02500SZoran Jovanovic   return MCDisassembler::Success;
2461f9a02500SZoran Jovanovic }
24622c6d7320SJozef Kolek 
2463852dd83bSSimon Atanasyan static DecodeStatus DecodeMovePOperands(MCInst &Inst, unsigned Insn,
2464852dd83bSSimon Atanasyan                                           uint64_t Address,
2465852dd83bSSimon Atanasyan                                           const void *Decoder) {
2466852dd83bSSimon Atanasyan   unsigned RegPair = fieldFromInstruction(Insn, 7, 3);
2467852dd83bSSimon Atanasyan   if (DecodeMovePRegPair(Inst, RegPair, Address, Decoder) ==
2468852dd83bSSimon Atanasyan       MCDisassembler::Fail)
2469852dd83bSSimon Atanasyan     return MCDisassembler::Fail;
2470852dd83bSSimon Atanasyan 
2471852dd83bSSimon Atanasyan   unsigned RegRs;
2472852dd83bSSimon Atanasyan   if (static_cast<const MipsDisassembler*>(Decoder)->hasMips32r6())
2473852dd83bSSimon Atanasyan     RegRs = fieldFromInstruction(Insn, 0, 2) |
2474852dd83bSSimon Atanasyan             (fieldFromInstruction(Insn, 3, 1) << 2);
2475852dd83bSSimon Atanasyan   else
2476852dd83bSSimon Atanasyan     RegRs = fieldFromInstruction(Insn, 1, 3);
2477852dd83bSSimon Atanasyan   if (DecodeGPRMM16MovePRegisterClass(Inst, RegRs, Address, Decoder) ==
2478852dd83bSSimon Atanasyan       MCDisassembler::Fail)
2479852dd83bSSimon Atanasyan     return MCDisassembler::Fail;
2480852dd83bSSimon Atanasyan 
2481852dd83bSSimon Atanasyan   unsigned RegRt = fieldFromInstruction(Insn, 4, 3);
2482852dd83bSSimon Atanasyan   if (DecodeGPRMM16MovePRegisterClass(Inst, RegRt, Address, Decoder) ==
2483852dd83bSSimon Atanasyan       MCDisassembler::Fail)
2484852dd83bSSimon Atanasyan     return MCDisassembler::Fail;
2485852dd83bSSimon Atanasyan 
2486852dd83bSSimon Atanasyan   return MCDisassembler::Success;
2487852dd83bSSimon Atanasyan }
2488852dd83bSSimon Atanasyan 
2489169df4e2SSimon Dardis static DecodeStatus DecodeMovePRegPair(MCInst &Inst, unsigned RegPair,
249041688679SZoran Jovanovic                                        uint64_t Address, const void *Decoder) {
249141688679SZoran Jovanovic   switch (RegPair) {
249241688679SZoran Jovanovic   default:
249341688679SZoran Jovanovic     return MCDisassembler::Fail;
249441688679SZoran Jovanovic   case 0:
2495e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A1));
2496e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A2));
249741688679SZoran Jovanovic     break;
249841688679SZoran Jovanovic   case 1:
2499e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A1));
2500e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A3));
250141688679SZoran Jovanovic     break;
250241688679SZoran Jovanovic   case 2:
2503e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A2));
2504e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A3));
250541688679SZoran Jovanovic     break;
250641688679SZoran Jovanovic   case 3:
2507e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A0));
2508e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::S5));
250941688679SZoran Jovanovic     break;
251041688679SZoran Jovanovic   case 4:
2511e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A0));
2512e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::S6));
251341688679SZoran Jovanovic     break;
251441688679SZoran Jovanovic   case 5:
2515e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A0));
2516e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A1));
251741688679SZoran Jovanovic     break;
251841688679SZoran Jovanovic   case 6:
2519e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A0));
2520e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A2));
252141688679SZoran Jovanovic     break;
252241688679SZoran Jovanovic   case 7:
2523e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A0));
2524e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A3));
252541688679SZoran Jovanovic     break;
252641688679SZoran Jovanovic   }
252741688679SZoran Jovanovic 
252841688679SZoran Jovanovic   return MCDisassembler::Success;
252941688679SZoran Jovanovic }
253041688679SZoran Jovanovic 
25312c6d7320SJozef Kolek static DecodeStatus DecodeSimm23Lsl2(MCInst &Inst, unsigned Insn,
25322c6d7320SJozef Kolek                                      uint64_t Address, const void *Decoder) {
25336499b5f0SJustin Bogner   Inst.addOperand(MCOperand::createImm(SignExtend32<25>(Insn << 2)));
25342c6d7320SJozef Kolek   return MCDisassembler::Success;
25352c6d7320SJozef Kolek }
2536fdbd0a37SZoran Jovanovic 
2537fdbd0a37SZoran Jovanovic template <typename InsnType>
2538fdbd0a37SZoran Jovanovic static DecodeStatus DecodeBgtzGroupBranchMMR6(MCInst &MI, InsnType insn,
2539fdbd0a37SZoran Jovanovic   uint64_t Address,
2540fdbd0a37SZoran Jovanovic   const void *Decoder) {
2541fdbd0a37SZoran Jovanovic   // We have:
2542fdbd0a37SZoran Jovanovic   //    0b000111 ttttt sssss iiiiiiiiiiiiiiii
2543fdbd0a37SZoran Jovanovic   //      Invalid      if rt == 0
2544fdbd0a37SZoran Jovanovic   //      BGTZALC_MMR6 if rs == 0 && rt != 0
2545fdbd0a37SZoran Jovanovic   //      BLTZALC_MMR6 if rs != 0 && rs == rt
2546fdbd0a37SZoran Jovanovic   //      BLTUC_MMR6   if rs != 0 && rs != rt
2547fdbd0a37SZoran Jovanovic 
2548fdbd0a37SZoran Jovanovic   InsnType Rt = fieldFromInstruction(insn, 21, 5);
2549fdbd0a37SZoran Jovanovic   InsnType Rs = fieldFromInstruction(insn, 16, 5);
2550f0ed16eaSHrvoje Varga   InsnType Imm = 0;
2551fdbd0a37SZoran Jovanovic   bool HasRs = false;
2552fdbd0a37SZoran Jovanovic   bool HasRt = false;
2553fdbd0a37SZoran Jovanovic 
2554fdbd0a37SZoran Jovanovic   if (Rt == 0)
2555fdbd0a37SZoran Jovanovic     return MCDisassembler::Fail;
2556fdbd0a37SZoran Jovanovic   else if (Rs == 0) {
2557fdbd0a37SZoran Jovanovic     MI.setOpcode(Mips::BGTZALC_MMR6);
2558fdbd0a37SZoran Jovanovic     HasRt = true;
2559f0ed16eaSHrvoje Varga     Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
2560fdbd0a37SZoran Jovanovic   }
2561fdbd0a37SZoran Jovanovic   else if (Rs == Rt) {
2562fdbd0a37SZoran Jovanovic     MI.setOpcode(Mips::BLTZALC_MMR6);
2563fdbd0a37SZoran Jovanovic     HasRs = true;
2564f0ed16eaSHrvoje Varga     Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
2565fdbd0a37SZoran Jovanovic   }
2566fdbd0a37SZoran Jovanovic   else {
2567fdbd0a37SZoran Jovanovic     MI.setOpcode(Mips::BLTUC_MMR6);
2568fdbd0a37SZoran Jovanovic     HasRs = true;
2569fdbd0a37SZoran Jovanovic     HasRt = true;
2570f0ed16eaSHrvoje Varga     Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
2571fdbd0a37SZoran Jovanovic   }
2572fdbd0a37SZoran Jovanovic 
2573fdbd0a37SZoran Jovanovic   if (HasRs)
2574fdbd0a37SZoran Jovanovic     MI.addOperand(
2575fdbd0a37SZoran Jovanovic     MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rs)));
2576fdbd0a37SZoran Jovanovic 
2577fdbd0a37SZoran Jovanovic   if (HasRt)
2578fdbd0a37SZoran Jovanovic     MI.addOperand(
2579fdbd0a37SZoran Jovanovic     MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rt)));
2580fdbd0a37SZoran Jovanovic 
2581fdbd0a37SZoran Jovanovic   MI.addOperand(MCOperand::createImm(Imm));
2582fdbd0a37SZoran Jovanovic 
2583fdbd0a37SZoran Jovanovic   return MCDisassembler::Success;
2584fdbd0a37SZoran Jovanovic }
2585fdbd0a37SZoran Jovanovic 
2586fdbd0a37SZoran Jovanovic template <typename InsnType>
2587fdbd0a37SZoran Jovanovic static DecodeStatus DecodeBlezGroupBranchMMR6(MCInst &MI, InsnType insn,
2588fdbd0a37SZoran Jovanovic   uint64_t Address,
2589fdbd0a37SZoran Jovanovic   const void *Decoder) {
2590fdbd0a37SZoran Jovanovic   // We have:
2591fdbd0a37SZoran Jovanovic   //    0b000110 ttttt sssss iiiiiiiiiiiiiiii
2592f0ed16eaSHrvoje Varga   //      Invalid        if rt == 0
2593fdbd0a37SZoran Jovanovic   //      BLEZALC_MMR6   if rs == 0  && rt != 0
2594fdbd0a37SZoran Jovanovic   //      BGEZALC_MMR6   if rs == rt && rt != 0
2595fdbd0a37SZoran Jovanovic   //      BGEUC_MMR6     if rs != rt && rs != 0  && rt != 0
2596fdbd0a37SZoran Jovanovic 
2597fdbd0a37SZoran Jovanovic   InsnType Rt = fieldFromInstruction(insn, 21, 5);
2598fdbd0a37SZoran Jovanovic   InsnType Rs = fieldFromInstruction(insn, 16, 5);
2599f0ed16eaSHrvoje Varga   InsnType Imm = 0;
2600fdbd0a37SZoran Jovanovic   bool HasRs = false;
2601fdbd0a37SZoran Jovanovic 
2602fdbd0a37SZoran Jovanovic   if (Rt == 0)
2603fdbd0a37SZoran Jovanovic     return MCDisassembler::Fail;
2604f0ed16eaSHrvoje Varga   else if (Rs == 0) {
2605fdbd0a37SZoran Jovanovic     MI.setOpcode(Mips::BLEZALC_MMR6);
2606f0ed16eaSHrvoje Varga     Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
2607f0ed16eaSHrvoje Varga   }
2608f0ed16eaSHrvoje Varga   else if (Rs == Rt) {
2609fdbd0a37SZoran Jovanovic     MI.setOpcode(Mips::BGEZALC_MMR6);
2610f0ed16eaSHrvoje Varga     Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
2611f0ed16eaSHrvoje Varga   }
2612fdbd0a37SZoran Jovanovic   else {
2613fdbd0a37SZoran Jovanovic     HasRs = true;
2614fdbd0a37SZoran Jovanovic     MI.setOpcode(Mips::BGEUC_MMR6);
2615f0ed16eaSHrvoje Varga     Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
2616fdbd0a37SZoran Jovanovic   }
2617fdbd0a37SZoran Jovanovic 
2618fdbd0a37SZoran Jovanovic   if (HasRs)
2619fdbd0a37SZoran Jovanovic     MI.addOperand(
2620fdbd0a37SZoran Jovanovic     MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rs)));
2621fdbd0a37SZoran Jovanovic   MI.addOperand(
2622fdbd0a37SZoran Jovanovic     MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rt)));
2623fdbd0a37SZoran Jovanovic 
2624fdbd0a37SZoran Jovanovic   MI.addOperand(MCOperand::createImm(Imm));
2625fdbd0a37SZoran Jovanovic 
2626fdbd0a37SZoran Jovanovic   return MCDisassembler::Success;
2627fdbd0a37SZoran Jovanovic }
2628