171928e68SAkira Hatanaka //===- MipsDisassembler.cpp - Disassembler for Mips -------------*- C++ -*-===//
271928e68SAkira Hatanaka //
371928e68SAkira Hatanaka //                     The LLVM Compiler Infrastructure
471928e68SAkira Hatanaka //
571928e68SAkira Hatanaka // This file is distributed under the University of Illinois Open Source
671928e68SAkira Hatanaka // License. See LICENSE.TXT for details.
771928e68SAkira Hatanaka //
871928e68SAkira Hatanaka //===----------------------------------------------------------------------===//
971928e68SAkira Hatanaka //
1071928e68SAkira Hatanaka // This file is part of the Mips Disassembler.
1171928e68SAkira Hatanaka //
1271928e68SAkira Hatanaka //===----------------------------------------------------------------------===//
1371928e68SAkira Hatanaka 
1471928e68SAkira Hatanaka #include "Mips.h"
159bf2b567SAkira Hatanaka #include "MipsRegisterInfo.h"
16ed0881b2SChandler Carruth #include "MipsSubtarget.h"
17a1bc0f56SLang Hames #include "llvm/MC/MCContext.h"
1871928e68SAkira Hatanaka #include "llvm/MC/MCDisassembler.h"
19ecaef49fSJim Grosbach #include "llvm/MC/MCFixedLenDisassembler.h"
20ed0881b2SChandler Carruth #include "llvm/MC/MCInst.h"
21ed0881b2SChandler Carruth #include "llvm/MC/MCSubtargetInfo.h"
22ed0881b2SChandler Carruth #include "llvm/Support/MathExtras.h"
2371928e68SAkira Hatanaka #include "llvm/Support/TargetRegistry.h"
2471928e68SAkira Hatanaka 
2571928e68SAkira Hatanaka using namespace llvm;
2671928e68SAkira Hatanaka 
27e96dd897SChandler Carruth #define DEBUG_TYPE "mips-disassembler"
28e96dd897SChandler Carruth 
2971928e68SAkira Hatanaka typedef MCDisassembler::DecodeStatus DecodeStatus;
3071928e68SAkira Hatanaka 
31cb3e98cfSBenjamin Kramer namespace {
32cb3e98cfSBenjamin Kramer 
33a19216c8SDaniel Sanders class MipsDisassembler : public MCDisassembler {
34dde3d582SVladimir Medic   bool IsMicroMips;
35a19216c8SDaniel Sanders   bool IsBigEndian;
369bf2b567SAkira Hatanaka public:
37a19216c8SDaniel Sanders   MipsDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx, bool IsBigEndian)
38a19216c8SDaniel Sanders       : MCDisassembler(STI, Ctx),
39db0712f9SMichael Kuperstein         IsMicroMips(STI.getFeatureBits()[Mips::FeatureMicroMips]),
40a19216c8SDaniel Sanders         IsBigEndian(IsBigEndian) {}
4171928e68SAkira Hatanaka 
42db0712f9SMichael Kuperstein   bool hasMips3() const { return STI.getFeatureBits()[Mips::FeatureMips3]; }
43db0712f9SMichael Kuperstein   bool hasMips32() const { return STI.getFeatureBits()[Mips::FeatureMips32]; }
44c171f65aSDaniel Sanders   bool hasMips32r6() const {
45db0712f9SMichael Kuperstein     return STI.getFeatureBits()[Mips::FeatureMips32r6];
465c582b2fSDaniel Sanders   }
475c582b2fSDaniel Sanders 
48db0712f9SMichael Kuperstein   bool isGP64() const { return STI.getFeatureBits()[Mips::FeatureGP64Bit]; }
490fa60416SDaniel Sanders 
503adf9b8dSKai Nacke   bool hasCnMips() const { return STI.getFeatureBits()[Mips::FeatureCnMips]; }
513adf9b8dSKai Nacke 
52c171f65aSDaniel Sanders   bool hasCOP3() const {
53c171f65aSDaniel Sanders     // Only present in MIPS-I and MIPS-II
54c171f65aSDaniel Sanders     return !hasMips32() && !hasMips3();
55c171f65aSDaniel Sanders   }
56c171f65aSDaniel Sanders 
574aa6bea7SRafael Espindola   DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
587fc5b874SRafael Espindola                               ArrayRef<uint8_t> Bytes, uint64_t Address,
594aa6bea7SRafael Espindola                               raw_ostream &VStream,
604aa6bea7SRafael Espindola                               raw_ostream &CStream) const override;
6171928e68SAkira Hatanaka };
6271928e68SAkira Hatanaka 
63cb3e98cfSBenjamin Kramer } // end anonymous namespace
64cb3e98cfSBenjamin Kramer 
6571928e68SAkira Hatanaka // Forward declare these because the autogenerated code will reference them.
6671928e68SAkira Hatanaka // Definitions are further down.
6713e6ccf3SAkira Hatanaka static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst,
6871928e68SAkira Hatanaka                                              unsigned RegNo,
6971928e68SAkira Hatanaka                                              uint64_t Address,
7071928e68SAkira Hatanaka                                              const void *Decoder);
7171928e68SAkira Hatanaka 
72ec8a5490SReed Kotler static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst,
73ec8a5490SReed Kotler                                                  unsigned RegNo,
74ec8a5490SReed Kotler                                                  uint64_t Address,
75ec8a5490SReed Kotler                                                  const void *Decoder);
76ec8a5490SReed Kotler 
77b0852e54SZoran Jovanovic static DecodeStatus DecodeGPRMM16RegisterClass(MCInst &Inst,
78b0852e54SZoran Jovanovic                                                unsigned RegNo,
79b0852e54SZoran Jovanovic                                                uint64_t Address,
80b0852e54SZoran Jovanovic                                                const void *Decoder);
81b0852e54SZoran Jovanovic 
821904fa21SJozef Kolek static DecodeStatus DecodeGPRMM16ZeroRegisterClass(MCInst &Inst,
831904fa21SJozef Kolek                                                    unsigned RegNo,
841904fa21SJozef Kolek                                                    uint64_t Address,
851904fa21SJozef Kolek                                                    const void *Decoder);
861904fa21SJozef Kolek 
8741688679SZoran Jovanovic static DecodeStatus DecodeGPRMM16MovePRegisterClass(MCInst &Inst,
8841688679SZoran Jovanovic                                                     unsigned RegNo,
8941688679SZoran Jovanovic                                                     uint64_t Address,
9041688679SZoran Jovanovic                                                     const void *Decoder);
9141688679SZoran Jovanovic 
9213e6ccf3SAkira Hatanaka static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst,
9371928e68SAkira Hatanaka                                              unsigned RegNo,
9471928e68SAkira Hatanaka                                              uint64_t Address,
9571928e68SAkira Hatanaka                                              const void *Decoder);
9671928e68SAkira Hatanaka 
979bfa2e2eSAkira Hatanaka static DecodeStatus DecodePtrRegisterClass(MCInst &Inst,
989bfa2e2eSAkira Hatanaka                                            unsigned Insn,
999bfa2e2eSAkira Hatanaka                                            uint64_t Address,
1009bfa2e2eSAkira Hatanaka                                            const void *Decoder);
1019bfa2e2eSAkira Hatanaka 
102654655f1SAkira Hatanaka static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst,
103ecabd1a5SAkira Hatanaka                                             unsigned RegNo,
104ecabd1a5SAkira Hatanaka                                             uint64_t Address,
105ecabd1a5SAkira Hatanaka                                             const void *Decoder);
106ecabd1a5SAkira Hatanaka 
10771928e68SAkira Hatanaka static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
10871928e68SAkira Hatanaka                                              unsigned RegNo,
10971928e68SAkira Hatanaka                                              uint64_t Address,
11071928e68SAkira Hatanaka                                              const void *Decoder);
11171928e68SAkira Hatanaka 
11271928e68SAkira Hatanaka static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
11371928e68SAkira Hatanaka                                              unsigned RegNo,
11471928e68SAkira Hatanaka                                              uint64_t Address,
11571928e68SAkira Hatanaka                                              const void *Decoder);
11671928e68SAkira Hatanaka 
11771928e68SAkira Hatanaka static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
11871928e68SAkira Hatanaka                                            unsigned RegNo,
11971928e68SAkira Hatanaka                                            uint64_t Address,
12071928e68SAkira Hatanaka                                            const void *Decoder);
12171928e68SAkira Hatanaka 
1221fb1b8b8SAkira Hatanaka static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst,
1231fb1b8b8SAkira Hatanaka                                            unsigned RegNo,
1241fb1b8b8SAkira Hatanaka                                            uint64_t Address,
1251fb1b8b8SAkira Hatanaka                                            const void *Decoder);
1261fb1b8b8SAkira Hatanaka 
1270fa60416SDaniel Sanders static DecodeStatus DecodeFGRCCRegisterClass(MCInst &Inst, unsigned RegNo,
1280fa60416SDaniel Sanders                                              uint64_t Address,
1290fa60416SDaniel Sanders                                              const void *Decoder);
1300fa60416SDaniel Sanders 
13171928e68SAkira Hatanaka static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
13271928e68SAkira Hatanaka                                               unsigned Insn,
13371928e68SAkira Hatanaka                                               uint64_t Address,
13471928e68SAkira Hatanaka                                               const void *Decoder);
13571928e68SAkira Hatanaka 
13671928e68SAkira Hatanaka static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
13771928e68SAkira Hatanaka                                               unsigned RegNo,
13871928e68SAkira Hatanaka                                               uint64_t Address,
13971928e68SAkira Hatanaka                                               const void *Decoder);
14071928e68SAkira Hatanaka 
14100fcf2e1SAkira Hatanaka static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst,
142ecabd1a5SAkira Hatanaka                                                 unsigned RegNo,
143ecabd1a5SAkira Hatanaka                                                 uint64_t Address,
144ecabd1a5SAkira Hatanaka                                                 const void *Decoder);
145ecabd1a5SAkira Hatanaka 
1468002a3f6SAkira Hatanaka static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst,
14759bfaf77SAkira Hatanaka                                                unsigned RegNo,
14859bfaf77SAkira Hatanaka                                                uint64_t Address,
14959bfaf77SAkira Hatanaka                                                const void *Decoder);
15059bfaf77SAkira Hatanaka 
1518002a3f6SAkira Hatanaka static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst,
15259bfaf77SAkira Hatanaka                                                unsigned RegNo,
15359bfaf77SAkira Hatanaka                                                uint64_t Address,
15459bfaf77SAkira Hatanaka                                                const void *Decoder);
15559bfaf77SAkira Hatanaka 
1563eb663b0SJack Carter static DecodeStatus DecodeMSA128BRegisterClass(MCInst &Inst,
1573eb663b0SJack Carter                                                unsigned RegNo,
1583eb663b0SJack Carter                                                uint64_t Address,
1593eb663b0SJack Carter                                                const void *Decoder);
1603eb663b0SJack Carter 
1615dc8ac92SJack Carter static DecodeStatus DecodeMSA128HRegisterClass(MCInst &Inst,
1625dc8ac92SJack Carter                                                unsigned RegNo,
1635dc8ac92SJack Carter                                                uint64_t Address,
1645dc8ac92SJack Carter                                                const void *Decoder);
1655dc8ac92SJack Carter 
1665dc8ac92SJack Carter static DecodeStatus DecodeMSA128WRegisterClass(MCInst &Inst,
1675dc8ac92SJack Carter                                                unsigned RegNo,
1685dc8ac92SJack Carter                                                uint64_t Address,
1695dc8ac92SJack Carter                                                const void *Decoder);
1705dc8ac92SJack Carter 
1715dc8ac92SJack Carter static DecodeStatus DecodeMSA128DRegisterClass(MCInst &Inst,
1725dc8ac92SJack Carter                                                unsigned RegNo,
1735dc8ac92SJack Carter                                                uint64_t Address,
1745dc8ac92SJack Carter                                                const void *Decoder);
1755dc8ac92SJack Carter 
176a591fdc6SMatheus Almeida static DecodeStatus DecodeMSACtrlRegisterClass(MCInst &Inst,
177a591fdc6SMatheus Almeida                                                unsigned RegNo,
178a591fdc6SMatheus Almeida                                                uint64_t Address,
179a591fdc6SMatheus Almeida                                                const void *Decoder);
180a591fdc6SMatheus Almeida 
181a3134faeSDaniel Sanders static DecodeStatus DecodeCOP0RegisterClass(MCInst &Inst,
182a3134faeSDaniel Sanders                                             unsigned RegNo,
183a3134faeSDaniel Sanders                                             uint64_t Address,
184a3134faeSDaniel Sanders                                             const void *Decoder);
185a3134faeSDaniel Sanders 
1862a83d680SDaniel Sanders static DecodeStatus DecodeCOP2RegisterClass(MCInst &Inst,
1872a83d680SDaniel Sanders                                             unsigned RegNo,
1882a83d680SDaniel Sanders                                             uint64_t Address,
1892a83d680SDaniel Sanders                                             const void *Decoder);
1902a83d680SDaniel Sanders 
19171928e68SAkira Hatanaka static DecodeStatus DecodeBranchTarget(MCInst &Inst,
19271928e68SAkira Hatanaka                                        unsigned Offset,
19371928e68SAkira Hatanaka                                        uint64_t Address,
19471928e68SAkira Hatanaka                                        const void *Decoder);
19571928e68SAkira Hatanaka 
19671928e68SAkira Hatanaka static DecodeStatus DecodeJumpTarget(MCInst &Inst,
19771928e68SAkira Hatanaka                                      unsigned Insn,
19871928e68SAkira Hatanaka                                      uint64_t Address,
19971928e68SAkira Hatanaka                                      const void *Decoder);
20071928e68SAkira Hatanaka 
2013c8869dcSZoran Jovanovic static DecodeStatus DecodeBranchTarget21(MCInst &Inst,
2023c8869dcSZoran Jovanovic                                          unsigned Offset,
2033c8869dcSZoran Jovanovic                                          uint64_t Address,
2043c8869dcSZoran Jovanovic                                          const void *Decoder);
2053c8869dcSZoran Jovanovic 
2063c8869dcSZoran Jovanovic static DecodeStatus DecodeBranchTarget26(MCInst &Inst,
2073c8869dcSZoran Jovanovic                                          unsigned Offset,
2083c8869dcSZoran Jovanovic                                          uint64_t Address,
2093c8869dcSZoran Jovanovic                                          const void *Decoder);
2103c8869dcSZoran Jovanovic 
2119761e96bSJozef Kolek // DecodeBranchTarget7MM - Decode microMIPS branch offset, which is
2129761e96bSJozef Kolek // shifted left by 1 bit.
2139761e96bSJozef Kolek static DecodeStatus DecodeBranchTarget7MM(MCInst &Inst,
2149761e96bSJozef Kolek                                           unsigned Offset,
2159761e96bSJozef Kolek                                           uint64_t Address,
2169761e96bSJozef Kolek                                           const void *Decoder);
2179761e96bSJozef Kolek 
2185cfebddeSJozef Kolek // DecodeBranchTarget10MM - Decode microMIPS branch offset, which is
2195cfebddeSJozef Kolek // shifted left by 1 bit.
2205cfebddeSJozef Kolek static DecodeStatus DecodeBranchTarget10MM(MCInst &Inst,
2215cfebddeSJozef Kolek                                            unsigned Offset,
2225cfebddeSJozef Kolek                                            uint64_t Address,
2235cfebddeSJozef Kolek                                            const void *Decoder);
2245cfebddeSJozef Kolek 
2258a80aa76SZoran Jovanovic // DecodeBranchTargetMM - Decode microMIPS branch offset, which is
2268a80aa76SZoran Jovanovic // shifted left by 1 bit.
2278a80aa76SZoran Jovanovic static DecodeStatus DecodeBranchTargetMM(MCInst &Inst,
2288a80aa76SZoran Jovanovic                                          unsigned Offset,
2298a80aa76SZoran Jovanovic                                          uint64_t Address,
2308a80aa76SZoran Jovanovic                                          const void *Decoder);
2318a80aa76SZoran Jovanovic 
232507e084aSZoran Jovanovic // DecodeJumpTargetMM - Decode microMIPS jump target, which is
233507e084aSZoran Jovanovic // shifted left by 1 bit.
234507e084aSZoran Jovanovic static DecodeStatus DecodeJumpTargetMM(MCInst &Inst,
235507e084aSZoran Jovanovic                                        unsigned Insn,
236507e084aSZoran Jovanovic                                        uint64_t Address,
237507e084aSZoran Jovanovic                                        const void *Decoder);
238507e084aSZoran Jovanovic 
23971928e68SAkira Hatanaka static DecodeStatus DecodeMem(MCInst &Inst,
24071928e68SAkira Hatanaka                               unsigned Insn,
24171928e68SAkira Hatanaka                               uint64_t Address,
24271928e68SAkira Hatanaka                               const void *Decoder);
24371928e68SAkira Hatanaka 
244*e4e83a7bSDaniel Sanders static DecodeStatus DecodeMemEVA(MCInst &Inst,
245*e4e83a7bSDaniel Sanders                                  unsigned Insn,
246*e4e83a7bSDaniel Sanders                                  uint64_t Address,
247*e4e83a7bSDaniel Sanders                                  const void *Decoder);
248*e4e83a7bSDaniel Sanders 
24992db6b78SDaniel Sanders static DecodeStatus DecodeCacheOp(MCInst &Inst,
25092db6b78SDaniel Sanders                               unsigned Insn,
25192db6b78SDaniel Sanders                               uint64_t Address,
25292db6b78SDaniel Sanders                               const void *Decoder);
25392db6b78SDaniel Sanders 
254*e4e83a7bSDaniel Sanders static DecodeStatus DecodeCacheeOp_CacheOpR6(MCInst &Inst,
255df464ae2SVladimir Medic                                              unsigned Insn,
256df464ae2SVladimir Medic                                              uint64_t Address,
257df464ae2SVladimir Medic                                              const void *Decoder);
258df464ae2SVladimir Medic 
259ab6d1cceSJozef Kolek static DecodeStatus DecodeCacheOpMM(MCInst &Inst,
260ab6d1cceSJozef Kolek                                     unsigned Insn,
261ab6d1cceSJozef Kolek                                     uint64_t Address,
262ab6d1cceSJozef Kolek                                     const void *Decoder);
263ab6d1cceSJozef Kolek 
2649eaa30d2SZoran Jovanovic static DecodeStatus DecodeStoreEvaOpMM(MCInst &Inst,
2659eaa30d2SZoran Jovanovic                                        unsigned Insn,
2669eaa30d2SZoran Jovanovic                                        uint64_t Address,
2679eaa30d2SZoran Jovanovic                                        const void *Decoder);
2689eaa30d2SZoran Jovanovic 
269d9790793SZoran Jovanovic static DecodeStatus DecodePrefeOpMM(MCInst &Inst,
270d9790793SZoran Jovanovic                                     unsigned Insn,
271d9790793SZoran Jovanovic                                     uint64_t Address,
272d9790793SZoran Jovanovic                                     const void *Decoder);
273d9790793SZoran Jovanovic 
274b4484d62SDaniel Sanders static DecodeStatus DecodeSyncI(MCInst &Inst,
275b4484d62SDaniel Sanders                                 unsigned Insn,
276b4484d62SDaniel Sanders                                 uint64_t Address,
277b4484d62SDaniel Sanders                                 const void *Decoder);
278b4484d62SDaniel Sanders 
279fe0bf9f6SMatheus Almeida static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn,
280fe0bf9f6SMatheus Almeida                                     uint64_t Address, const void *Decoder);
281fe0bf9f6SMatheus Almeida 
282315e7ecaSJozef Kolek static DecodeStatus DecodeMemMMImm4(MCInst &Inst,
283315e7ecaSJozef Kolek                                     unsigned Insn,
284315e7ecaSJozef Kolek                                     uint64_t Address,
285315e7ecaSJozef Kolek                                     const void *Decoder);
286315e7ecaSJozef Kolek 
28712c6982bSJozef Kolek static DecodeStatus DecodeMemMMSPImm5Lsl2(MCInst &Inst,
28812c6982bSJozef Kolek                                           unsigned Insn,
28912c6982bSJozef Kolek                                           uint64_t Address,
29012c6982bSJozef Kolek                                           const void *Decoder);
29112c6982bSJozef Kolek 
292e10a02ecSJozef Kolek static DecodeStatus DecodeMemMMGPImm7Lsl2(MCInst &Inst,
293e10a02ecSJozef Kolek                                           unsigned Insn,
294e10a02ecSJozef Kolek                                           uint64_t Address,
295e10a02ecSJozef Kolek                                           const void *Decoder);
296e10a02ecSJozef Kolek 
297d68d424aSJozef Kolek static DecodeStatus DecodeMemMMReglistImm4Lsl2(MCInst &Inst,
298d68d424aSJozef Kolek                                                unsigned Insn,
299d68d424aSJozef Kolek                                                uint64_t Address,
300d68d424aSJozef Kolek                                                const void *Decoder);
301d68d424aSJozef Kolek 
302a6593ff6SZoran Jovanovic static DecodeStatus DecodeMemMMImm9(MCInst &Inst,
303a6593ff6SZoran Jovanovic                                     unsigned Insn,
304a6593ff6SZoran Jovanovic                                     uint64_t Address,
305a6593ff6SZoran Jovanovic                                     const void *Decoder);
306a6593ff6SZoran Jovanovic 
307dde3d582SVladimir Medic static DecodeStatus DecodeMemMMImm12(MCInst &Inst,
308dde3d582SVladimir Medic                                      unsigned Insn,
309dde3d582SVladimir Medic                                      uint64_t Address,
310dde3d582SVladimir Medic                                      const void *Decoder);
311dde3d582SVladimir Medic 
312dde3d582SVladimir Medic static DecodeStatus DecodeMemMMImm16(MCInst &Inst,
313dde3d582SVladimir Medic                                      unsigned Insn,
314dde3d582SVladimir Medic                                      uint64_t Address,
315dde3d582SVladimir Medic                                      const void *Decoder);
316dde3d582SVladimir Medic 
31771928e68SAkira Hatanaka static DecodeStatus DecodeFMem(MCInst &Inst, unsigned Insn,
31871928e68SAkira Hatanaka                                uint64_t Address,
31971928e68SAkira Hatanaka                                const void *Decoder);
32071928e68SAkira Hatanaka 
32192db6b78SDaniel Sanders static DecodeStatus DecodeFMem2(MCInst &Inst, unsigned Insn,
32292db6b78SDaniel Sanders                                uint64_t Address,
32392db6b78SDaniel Sanders                                const void *Decoder);
32492db6b78SDaniel Sanders 
32592db6b78SDaniel Sanders static DecodeStatus DecodeFMem3(MCInst &Inst, unsigned Insn,
32692db6b78SDaniel Sanders                                uint64_t Address,
32792db6b78SDaniel Sanders                                const void *Decoder);
32892db6b78SDaniel Sanders 
329435cf8a4SVladimir Medic static DecodeStatus DecodeFMemCop2R6(MCInst &Inst, unsigned Insn,
330435cf8a4SVladimir Medic                                uint64_t Address,
331435cf8a4SVladimir Medic                                const void *Decoder);
332435cf8a4SVladimir Medic 
3336a803f61SDaniel Sanders static DecodeStatus DecodeSpecial3LlSc(MCInst &Inst,
3346a803f61SDaniel Sanders                                        unsigned Insn,
3356a803f61SDaniel Sanders                                        uint64_t Address,
3366a803f61SDaniel Sanders                                        const void *Decoder);
3376a803f61SDaniel Sanders 
338aa2b9278SJozef Kolek static DecodeStatus DecodeAddiur2Simm7(MCInst &Inst,
339aa2b9278SJozef Kolek                                        unsigned Value,
340aa2b9278SJozef Kolek                                        uint64_t Address,
341aa2b9278SJozef Kolek                                        const void *Decoder);
342aa2b9278SJozef Kolek 
343aa2b9278SJozef Kolek static DecodeStatus DecodeUImm6Lsl2(MCInst &Inst,
344aa2b9278SJozef Kolek                                     unsigned Value,
345aa2b9278SJozef Kolek                                     uint64_t Address,
346aa2b9278SJozef Kolek                                     const void *Decoder);
347aa2b9278SJozef Kolek 
348aa2b9278SJozef Kolek static DecodeStatus DecodeLiSimm7(MCInst &Inst,
349aa2b9278SJozef Kolek                                   unsigned Value,
350aa2b9278SJozef Kolek                                   uint64_t Address,
351aa2b9278SJozef Kolek                                   const void *Decoder);
352aa2b9278SJozef Kolek 
3536b28f09dSZoran Jovanovic static DecodeStatus DecodePOOL16BEncodedField(MCInst &Inst,
3546b28f09dSZoran Jovanovic                                               unsigned Value,
3556b28f09dSZoran Jovanovic                                               uint64_t Address,
3566b28f09dSZoran Jovanovic                                               const void *Decoder);
3576b28f09dSZoran Jovanovic 
358aa2b9278SJozef Kolek static DecodeStatus DecodeSimm4(MCInst &Inst,
359aa2b9278SJozef Kolek                                 unsigned Value,
360aa2b9278SJozef Kolek                                 uint64_t Address,
361aa2b9278SJozef Kolek                                 const void *Decoder);
362aa2b9278SJozef Kolek 
36371928e68SAkira Hatanaka static DecodeStatus DecodeSimm16(MCInst &Inst,
36471928e68SAkira Hatanaka                                  unsigned Insn,
36571928e68SAkira Hatanaka                                  uint64_t Address,
36671928e68SAkira Hatanaka                                  const void *Decoder);
36771928e68SAkira Hatanaka 
368779c5937SMatheus Almeida // Decode the immediate field of an LSA instruction which
369779c5937SMatheus Almeida // is off by one.
370779c5937SMatheus Almeida static DecodeStatus DecodeLSAImm(MCInst &Inst,
371779c5937SMatheus Almeida                                  unsigned Insn,
372779c5937SMatheus Almeida                                  uint64_t Address,
373779c5937SMatheus Almeida                                  const void *Decoder);
374779c5937SMatheus Almeida 
37571928e68SAkira Hatanaka static DecodeStatus DecodeInsSize(MCInst &Inst,
37671928e68SAkira Hatanaka                                   unsigned Insn,
37771928e68SAkira Hatanaka                                   uint64_t Address,
37871928e68SAkira Hatanaka                                   const void *Decoder);
37971928e68SAkira Hatanaka 
38071928e68SAkira Hatanaka static DecodeStatus DecodeExtSize(MCInst &Inst,
38171928e68SAkira Hatanaka                                   unsigned Insn,
38271928e68SAkira Hatanaka                                   uint64_t Address,
38371928e68SAkira Hatanaka                                   const void *Decoder);
38471928e68SAkira Hatanaka 
385b59e1a41SDaniel Sanders static DecodeStatus DecodeSimm19Lsl2(MCInst &Inst, unsigned Insn,
386b59e1a41SDaniel Sanders                                      uint64_t Address, const void *Decoder);
387b59e1a41SDaniel Sanders 
3882855142aSZoran Jovanovic static DecodeStatus DecodeSimm18Lsl3(MCInst &Inst, unsigned Insn,
3892855142aSZoran Jovanovic                                      uint64_t Address, const void *Decoder);
3902855142aSZoran Jovanovic 
391b682ddf3SVladimir Medic static DecodeStatus DecodeSimm9SP(MCInst &Inst, unsigned Insn,
392b682ddf3SVladimir Medic                                   uint64_t Address, const void *Decoder);
393b682ddf3SVladimir Medic 
394b682ddf3SVladimir Medic static DecodeStatus DecodeANDI16Imm(MCInst &Inst, unsigned Insn,
395b682ddf3SVladimir Medic                                     uint64_t Address, const void *Decoder);
396b682ddf3SVladimir Medic 
397b682ddf3SVladimir Medic static DecodeStatus DecodeUImm5lsl2(MCInst &Inst, unsigned Insn,
398b682ddf3SVladimir Medic                                    uint64_t Address, const void *Decoder);
399b682ddf3SVladimir Medic 
4002c6d7320SJozef Kolek static DecodeStatus DecodeSimm23Lsl2(MCInst &Inst, unsigned Insn,
4012c6d7320SJozef Kolek                                      uint64_t Address, const void *Decoder);
4022c6d7320SJozef Kolek 
403b50ccf8eSDaniel Sanders /// INSVE_[BHWD] have an implicit operand that the generated decoder doesn't
404b50ccf8eSDaniel Sanders /// handle.
405b50ccf8eSDaniel Sanders template <typename InsnType>
406b50ccf8eSDaniel Sanders static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address,
407b50ccf8eSDaniel Sanders                                    const void *Decoder);
4085c582b2fSDaniel Sanders 
4095c582b2fSDaniel Sanders template <typename InsnType>
4105c582b2fSDaniel Sanders static DecodeStatus
4115c582b2fSDaniel Sanders DecodeAddiGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
4125c582b2fSDaniel Sanders                       const void *Decoder);
4135c582b2fSDaniel Sanders 
4145c582b2fSDaniel Sanders template <typename InsnType>
4155c582b2fSDaniel Sanders static DecodeStatus
4165c582b2fSDaniel Sanders DecodeDaddiGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
4175c582b2fSDaniel Sanders                        const void *Decoder);
4185c582b2fSDaniel Sanders 
4195c582b2fSDaniel Sanders template <typename InsnType>
4205c582b2fSDaniel Sanders static DecodeStatus
4215c582b2fSDaniel Sanders DecodeBlezlGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
4225c582b2fSDaniel Sanders                        const void *Decoder);
4235c582b2fSDaniel Sanders 
4245c582b2fSDaniel Sanders template <typename InsnType>
4255c582b2fSDaniel Sanders static DecodeStatus
4265c582b2fSDaniel Sanders DecodeBgtzlGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
4275c582b2fSDaniel Sanders                        const void *Decoder);
4285c582b2fSDaniel Sanders 
4295c582b2fSDaniel Sanders template <typename InsnType>
4305c582b2fSDaniel Sanders static DecodeStatus
4315c582b2fSDaniel Sanders DecodeBgtzGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
4325c582b2fSDaniel Sanders                       const void *Decoder);
4335c582b2fSDaniel Sanders 
43428a0ca07SZoran Jovanovic template <typename InsnType>
43528a0ca07SZoran Jovanovic static DecodeStatus
43628a0ca07SZoran Jovanovic DecodeBlezGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
43728a0ca07SZoran Jovanovic                        const void *Decoder);
43828a0ca07SZoran Jovanovic 
439a4c4b5fcSZoran Jovanovic static DecodeStatus DecodeRegListOperand(MCInst &Inst, unsigned Insn,
440a4c4b5fcSZoran Jovanovic                                          uint64_t Address,
441a4c4b5fcSZoran Jovanovic                                          const void *Decoder);
442a4c4b5fcSZoran Jovanovic 
443f9a02500SZoran Jovanovic static DecodeStatus DecodeRegListOperand16(MCInst &Inst, unsigned Insn,
444f9a02500SZoran Jovanovic                                            uint64_t Address,
445f9a02500SZoran Jovanovic                                            const void *Decoder);
446f9a02500SZoran Jovanovic 
44741688679SZoran Jovanovic static DecodeStatus DecodeMovePRegPair(MCInst &Inst, unsigned Insn,
44841688679SZoran Jovanovic                                        uint64_t Address,
44941688679SZoran Jovanovic                                        const void *Decoder);
45041688679SZoran Jovanovic 
45171928e68SAkira Hatanaka namespace llvm {
45271928e68SAkira Hatanaka extern Target TheMipselTarget, TheMipsTarget, TheMips64Target,
45371928e68SAkira Hatanaka               TheMips64elTarget;
45471928e68SAkira Hatanaka }
45571928e68SAkira Hatanaka 
45671928e68SAkira Hatanaka static MCDisassembler *createMipsDisassembler(
45771928e68SAkira Hatanaka                        const Target &T,
458a1bc0f56SLang Hames                        const MCSubtargetInfo &STI,
459a1bc0f56SLang Hames                        MCContext &Ctx) {
460a1bc0f56SLang Hames   return new MipsDisassembler(STI, Ctx, true);
46171928e68SAkira Hatanaka }
46271928e68SAkira Hatanaka 
46371928e68SAkira Hatanaka static MCDisassembler *createMipselDisassembler(
46471928e68SAkira Hatanaka                        const Target &T,
465a1bc0f56SLang Hames                        const MCSubtargetInfo &STI,
466a1bc0f56SLang Hames                        MCContext &Ctx) {
467a1bc0f56SLang Hames   return new MipsDisassembler(STI, Ctx, false);
46871928e68SAkira Hatanaka }
46971928e68SAkira Hatanaka 
47071928e68SAkira Hatanaka extern "C" void LLVMInitializeMipsDisassembler() {
47171928e68SAkira Hatanaka   // Register the disassembler.
47271928e68SAkira Hatanaka   TargetRegistry::RegisterMCDisassembler(TheMipsTarget,
47371928e68SAkira Hatanaka                                          createMipsDisassembler);
47471928e68SAkira Hatanaka   TargetRegistry::RegisterMCDisassembler(TheMipselTarget,
47571928e68SAkira Hatanaka                                          createMipselDisassembler);
47671928e68SAkira Hatanaka   TargetRegistry::RegisterMCDisassembler(TheMips64Target,
477a19216c8SDaniel Sanders                                          createMipsDisassembler);
47871928e68SAkira Hatanaka   TargetRegistry::RegisterMCDisassembler(TheMips64elTarget,
479a19216c8SDaniel Sanders                                          createMipselDisassembler);
48071928e68SAkira Hatanaka }
48171928e68SAkira Hatanaka 
48271928e68SAkira Hatanaka #include "MipsGenDisassemblerTables.inc"
48371928e68SAkira Hatanaka 
4845c582b2fSDaniel Sanders static unsigned getReg(const void *D, unsigned RC, unsigned RegNo) {
485a19216c8SDaniel Sanders   const MipsDisassembler *Dis = static_cast<const MipsDisassembler*>(D);
4865c582b2fSDaniel Sanders   const MCRegisterInfo *RegInfo = Dis->getContext().getRegisterInfo();
4875c582b2fSDaniel Sanders   return *(RegInfo->getRegClass(RC).begin() + RegNo);
4885c582b2fSDaniel Sanders }
4895c582b2fSDaniel Sanders 
490b50ccf8eSDaniel Sanders template <typename InsnType>
491b50ccf8eSDaniel Sanders static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address,
492b50ccf8eSDaniel Sanders                                    const void *Decoder) {
493b50ccf8eSDaniel Sanders   typedef DecodeStatus (*DecodeFN)(MCInst &, unsigned, uint64_t, const void *);
494b50ccf8eSDaniel Sanders   // The size of the n field depends on the element size
495b50ccf8eSDaniel Sanders   // The register class also depends on this.
496b50ccf8eSDaniel Sanders   InsnType tmp = fieldFromInstruction(insn, 17, 5);
497b50ccf8eSDaniel Sanders   unsigned NSize = 0;
498b50ccf8eSDaniel Sanders   DecodeFN RegDecoder = nullptr;
499b50ccf8eSDaniel Sanders   if ((tmp & 0x18) == 0x00) { // INSVE_B
500b50ccf8eSDaniel Sanders     NSize = 4;
501b50ccf8eSDaniel Sanders     RegDecoder = DecodeMSA128BRegisterClass;
502b50ccf8eSDaniel Sanders   } else if ((tmp & 0x1c) == 0x10) { // INSVE_H
503b50ccf8eSDaniel Sanders     NSize = 3;
504b50ccf8eSDaniel Sanders     RegDecoder = DecodeMSA128HRegisterClass;
505b50ccf8eSDaniel Sanders   } else if ((tmp & 0x1e) == 0x18) { // INSVE_W
506b50ccf8eSDaniel Sanders     NSize = 2;
507b50ccf8eSDaniel Sanders     RegDecoder = DecodeMSA128WRegisterClass;
508b50ccf8eSDaniel Sanders   } else if ((tmp & 0x1f) == 0x1c) { // INSVE_D
509b50ccf8eSDaniel Sanders     NSize = 1;
510b50ccf8eSDaniel Sanders     RegDecoder = DecodeMSA128DRegisterClass;
511b50ccf8eSDaniel Sanders   } else
512b50ccf8eSDaniel Sanders     llvm_unreachable("Invalid encoding");
513b50ccf8eSDaniel Sanders 
514b50ccf8eSDaniel Sanders   assert(NSize != 0 && RegDecoder != nullptr);
515b50ccf8eSDaniel Sanders 
516b50ccf8eSDaniel Sanders   // $wd
517b50ccf8eSDaniel Sanders   tmp = fieldFromInstruction(insn, 6, 5);
518b50ccf8eSDaniel Sanders   if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
519b50ccf8eSDaniel Sanders     return MCDisassembler::Fail;
520b50ccf8eSDaniel Sanders   // $wd_in
521b50ccf8eSDaniel Sanders   if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
522b50ccf8eSDaniel Sanders     return MCDisassembler::Fail;
523b50ccf8eSDaniel Sanders   // $n
524b50ccf8eSDaniel Sanders   tmp = fieldFromInstruction(insn, 16, NSize);
525e9119e41SJim Grosbach   MI.addOperand(MCOperand::createImm(tmp));
526b50ccf8eSDaniel Sanders   // $ws
527b50ccf8eSDaniel Sanders   tmp = fieldFromInstruction(insn, 11, 5);
528b50ccf8eSDaniel Sanders   if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
529b50ccf8eSDaniel Sanders     return MCDisassembler::Fail;
530b50ccf8eSDaniel Sanders   // $n2
531e9119e41SJim Grosbach   MI.addOperand(MCOperand::createImm(0));
532b50ccf8eSDaniel Sanders 
533b50ccf8eSDaniel Sanders   return MCDisassembler::Success;
534b50ccf8eSDaniel Sanders }
535b50ccf8eSDaniel Sanders 
5365c582b2fSDaniel Sanders template <typename InsnType>
5375c582b2fSDaniel Sanders static DecodeStatus DecodeAddiGroupBranch(MCInst &MI, InsnType insn,
5385c582b2fSDaniel Sanders                                           uint64_t Address,
5395c582b2fSDaniel Sanders                                           const void *Decoder) {
5405c582b2fSDaniel Sanders   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
5415c582b2fSDaniel Sanders   // (otherwise we would have matched the ADDI instruction from the earlier
5425c582b2fSDaniel Sanders   // ISA's instead).
5435c582b2fSDaniel Sanders   //
5445c582b2fSDaniel Sanders   // We have:
5455c582b2fSDaniel Sanders   //    0b001000 sssss ttttt iiiiiiiiiiiiiiii
5465c582b2fSDaniel Sanders   //      BOVC if rs >= rt
5475c582b2fSDaniel Sanders   //      BEQZALC if rs == 0 && rt != 0
5485c582b2fSDaniel Sanders   //      BEQC if rs < rt && rs != 0
5495c582b2fSDaniel Sanders 
5505c582b2fSDaniel Sanders   InsnType Rs = fieldFromInstruction(insn, 21, 5);
5515c582b2fSDaniel Sanders   InsnType Rt = fieldFromInstruction(insn, 16, 5);
552d37bab61SAlexey Samsonov   InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4;
5535c582b2fSDaniel Sanders   bool HasRs = false;
5545c582b2fSDaniel Sanders 
5555c582b2fSDaniel Sanders   if (Rs >= Rt) {
5565c582b2fSDaniel Sanders     MI.setOpcode(Mips::BOVC);
5575c582b2fSDaniel Sanders     HasRs = true;
5585c582b2fSDaniel Sanders   } else if (Rs != 0 && Rs < Rt) {
5595c582b2fSDaniel Sanders     MI.setOpcode(Mips::BEQC);
5605c582b2fSDaniel Sanders     HasRs = true;
5615c582b2fSDaniel Sanders   } else
5625c582b2fSDaniel Sanders     MI.setOpcode(Mips::BEQZALC);
5635c582b2fSDaniel Sanders 
5645c582b2fSDaniel Sanders   if (HasRs)
565e9119e41SJim Grosbach     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
5665c582b2fSDaniel Sanders                                        Rs)));
5675c582b2fSDaniel Sanders 
568e9119e41SJim Grosbach   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
5695c582b2fSDaniel Sanders                                      Rt)));
570e9119e41SJim Grosbach   MI.addOperand(MCOperand::createImm(Imm));
5715c582b2fSDaniel Sanders 
5725c582b2fSDaniel Sanders   return MCDisassembler::Success;
5735c582b2fSDaniel Sanders }
5745c582b2fSDaniel Sanders 
5755c582b2fSDaniel Sanders template <typename InsnType>
5765c582b2fSDaniel Sanders static DecodeStatus DecodeDaddiGroupBranch(MCInst &MI, InsnType insn,
5775c582b2fSDaniel Sanders                                            uint64_t Address,
5785c582b2fSDaniel Sanders                                            const void *Decoder) {
5795c582b2fSDaniel Sanders   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
5805c582b2fSDaniel Sanders   // (otherwise we would have matched the ADDI instruction from the earlier
5815c582b2fSDaniel Sanders   // ISA's instead).
5825c582b2fSDaniel Sanders   //
5835c582b2fSDaniel Sanders   // We have:
5845c582b2fSDaniel Sanders   //    0b011000 sssss ttttt iiiiiiiiiiiiiiii
5855c582b2fSDaniel Sanders   //      BNVC if rs >= rt
5865c582b2fSDaniel Sanders   //      BNEZALC if rs == 0 && rt != 0
5875c582b2fSDaniel Sanders   //      BNEC if rs < rt && rs != 0
5885c582b2fSDaniel Sanders 
5895c582b2fSDaniel Sanders   InsnType Rs = fieldFromInstruction(insn, 21, 5);
5905c582b2fSDaniel Sanders   InsnType Rt = fieldFromInstruction(insn, 16, 5);
591d37bab61SAlexey Samsonov   InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4;
5925c582b2fSDaniel Sanders   bool HasRs = false;
5935c582b2fSDaniel Sanders 
5945c582b2fSDaniel Sanders   if (Rs >= Rt) {
5955c582b2fSDaniel Sanders     MI.setOpcode(Mips::BNVC);
5965c582b2fSDaniel Sanders     HasRs = true;
5975c582b2fSDaniel Sanders   } else if (Rs != 0 && Rs < Rt) {
5985c582b2fSDaniel Sanders     MI.setOpcode(Mips::BNEC);
5995c582b2fSDaniel Sanders     HasRs = true;
6005c582b2fSDaniel Sanders   } else
6015c582b2fSDaniel Sanders     MI.setOpcode(Mips::BNEZALC);
6025c582b2fSDaniel Sanders 
6035c582b2fSDaniel Sanders   if (HasRs)
604e9119e41SJim Grosbach     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
6055c582b2fSDaniel Sanders                                        Rs)));
6065c582b2fSDaniel Sanders 
607e9119e41SJim Grosbach   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
6085c582b2fSDaniel Sanders                                      Rt)));
609e9119e41SJim Grosbach   MI.addOperand(MCOperand::createImm(Imm));
6105c582b2fSDaniel Sanders 
6115c582b2fSDaniel Sanders   return MCDisassembler::Success;
6125c582b2fSDaniel Sanders }
6135c582b2fSDaniel Sanders 
6145c582b2fSDaniel Sanders template <typename InsnType>
6155c582b2fSDaniel Sanders static DecodeStatus DecodeBlezlGroupBranch(MCInst &MI, InsnType insn,
6165c582b2fSDaniel Sanders                                            uint64_t Address,
6175c582b2fSDaniel Sanders                                            const void *Decoder) {
6185c582b2fSDaniel Sanders   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
6195c582b2fSDaniel Sanders   // (otherwise we would have matched the BLEZL instruction from the earlier
6205c582b2fSDaniel Sanders   // ISA's instead).
6215c582b2fSDaniel Sanders   //
6225c582b2fSDaniel Sanders   // We have:
6235c582b2fSDaniel Sanders   //    0b010110 sssss ttttt iiiiiiiiiiiiiiii
6245c582b2fSDaniel Sanders   //      Invalid if rs == 0
6255c582b2fSDaniel Sanders   //      BLEZC   if rs == 0  && rt != 0
6265c582b2fSDaniel Sanders   //      BGEZC   if rs == rt && rt != 0
6275c582b2fSDaniel Sanders   //      BGEC    if rs != rt && rs != 0  && rt != 0
6285c582b2fSDaniel Sanders 
6295c582b2fSDaniel Sanders   InsnType Rs = fieldFromInstruction(insn, 21, 5);
6305c582b2fSDaniel Sanders   InsnType Rt = fieldFromInstruction(insn, 16, 5);
631d37bab61SAlexey Samsonov   InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4;
63228a0ca07SZoran Jovanovic   bool HasRs = false;
6335c582b2fSDaniel Sanders 
6345c582b2fSDaniel Sanders   if (Rt == 0)
6355c582b2fSDaniel Sanders     return MCDisassembler::Fail;
6365c582b2fSDaniel Sanders   else if (Rs == 0)
6375c582b2fSDaniel Sanders     MI.setOpcode(Mips::BLEZC);
6385c582b2fSDaniel Sanders   else if (Rs == Rt)
6395c582b2fSDaniel Sanders     MI.setOpcode(Mips::BGEZC);
64028a0ca07SZoran Jovanovic   else {
64128a0ca07SZoran Jovanovic     HasRs = true;
64228a0ca07SZoran Jovanovic     MI.setOpcode(Mips::BGEC);
64328a0ca07SZoran Jovanovic   }
64428a0ca07SZoran Jovanovic 
64528a0ca07SZoran Jovanovic   if (HasRs)
646e9119e41SJim Grosbach     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
64728a0ca07SZoran Jovanovic                                        Rs)));
6485c582b2fSDaniel Sanders 
649e9119e41SJim Grosbach   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
6505c582b2fSDaniel Sanders                                      Rt)));
6515c582b2fSDaniel Sanders 
652e9119e41SJim Grosbach   MI.addOperand(MCOperand::createImm(Imm));
6535c582b2fSDaniel Sanders 
6545c582b2fSDaniel Sanders   return MCDisassembler::Success;
6555c582b2fSDaniel Sanders }
6565c582b2fSDaniel Sanders 
6575c582b2fSDaniel Sanders template <typename InsnType>
6585c582b2fSDaniel Sanders static DecodeStatus DecodeBgtzlGroupBranch(MCInst &MI, InsnType insn,
6595c582b2fSDaniel Sanders                                            uint64_t Address,
6605c582b2fSDaniel Sanders                                            const void *Decoder) {
6615c582b2fSDaniel Sanders   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
6625c582b2fSDaniel Sanders   // (otherwise we would have matched the BGTZL instruction from the earlier
6635c582b2fSDaniel Sanders   // ISA's instead).
6645c582b2fSDaniel Sanders   //
6655c582b2fSDaniel Sanders   // We have:
6665c582b2fSDaniel Sanders   //    0b010111 sssss ttttt iiiiiiiiiiiiiiii
6675c582b2fSDaniel Sanders   //      Invalid if rs == 0
6685c582b2fSDaniel Sanders   //      BGTZC   if rs == 0  && rt != 0
6695c582b2fSDaniel Sanders   //      BLTZC   if rs == rt && rt != 0
6705c582b2fSDaniel Sanders   //      BLTC    if rs != rt && rs != 0  && rt != 0
6715c582b2fSDaniel Sanders 
6725c14b069SZoran Jovanovic   bool HasRs = false;
6735c14b069SZoran Jovanovic 
6745c582b2fSDaniel Sanders   InsnType Rs = fieldFromInstruction(insn, 21, 5);
6755c582b2fSDaniel Sanders   InsnType Rt = fieldFromInstruction(insn, 16, 5);
676d37bab61SAlexey Samsonov   InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4;
6775c582b2fSDaniel Sanders 
6785c582b2fSDaniel Sanders   if (Rt == 0)
6795c582b2fSDaniel Sanders     return MCDisassembler::Fail;
6805c582b2fSDaniel Sanders   else if (Rs == 0)
6815c582b2fSDaniel Sanders     MI.setOpcode(Mips::BGTZC);
6825c582b2fSDaniel Sanders   else if (Rs == Rt)
6835c582b2fSDaniel Sanders     MI.setOpcode(Mips::BLTZC);
6845c14b069SZoran Jovanovic   else {
6855c14b069SZoran Jovanovic     MI.setOpcode(Mips::BLTC);
6865c14b069SZoran Jovanovic     HasRs = true;
6875c14b069SZoran Jovanovic   }
6885c14b069SZoran Jovanovic 
6895c14b069SZoran Jovanovic   if (HasRs)
690e9119e41SJim Grosbach     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
6915c14b069SZoran Jovanovic                                               Rs)));
6925c582b2fSDaniel Sanders 
693e9119e41SJim Grosbach   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
6945c582b2fSDaniel Sanders                                      Rt)));
6955c582b2fSDaniel Sanders 
696e9119e41SJim Grosbach   MI.addOperand(MCOperand::createImm(Imm));
6975c582b2fSDaniel Sanders 
6985c582b2fSDaniel Sanders   return MCDisassembler::Success;
6995c582b2fSDaniel Sanders }
7005c582b2fSDaniel Sanders 
7015c582b2fSDaniel Sanders template <typename InsnType>
7025c582b2fSDaniel Sanders static DecodeStatus DecodeBgtzGroupBranch(MCInst &MI, InsnType insn,
7035c582b2fSDaniel Sanders                                           uint64_t Address,
7045c582b2fSDaniel Sanders                                           const void *Decoder) {
7055c582b2fSDaniel Sanders   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
7065c582b2fSDaniel Sanders   // (otherwise we would have matched the BGTZ instruction from the earlier
7075c582b2fSDaniel Sanders   // ISA's instead).
7085c582b2fSDaniel Sanders   //
7095c582b2fSDaniel Sanders   // We have:
7105c582b2fSDaniel Sanders   //    0b000111 sssss ttttt iiiiiiiiiiiiiiii
7115c582b2fSDaniel Sanders   //      BGTZ    if rt == 0
7125c582b2fSDaniel Sanders   //      BGTZALC if rs == 0 && rt != 0
7135c582b2fSDaniel Sanders   //      BLTZALC if rs != 0 && rs == rt
7145c582b2fSDaniel Sanders   //      BLTUC   if rs != 0 && rs != rt
7155c582b2fSDaniel Sanders 
7165c582b2fSDaniel Sanders   InsnType Rs = fieldFromInstruction(insn, 21, 5);
7175c582b2fSDaniel Sanders   InsnType Rt = fieldFromInstruction(insn, 16, 5);
718d37bab61SAlexey Samsonov   InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4;
7195c582b2fSDaniel Sanders   bool HasRs = false;
7205c582b2fSDaniel Sanders   bool HasRt = false;
7215c582b2fSDaniel Sanders 
7225c582b2fSDaniel Sanders   if (Rt == 0) {
7235c582b2fSDaniel Sanders     MI.setOpcode(Mips::BGTZ);
7245c582b2fSDaniel Sanders     HasRs = true;
7255c582b2fSDaniel Sanders   } else if (Rs == 0) {
7265c582b2fSDaniel Sanders     MI.setOpcode(Mips::BGTZALC);
7275c582b2fSDaniel Sanders     HasRt = true;
7285c582b2fSDaniel Sanders   } else if (Rs == Rt) {
7295c582b2fSDaniel Sanders     MI.setOpcode(Mips::BLTZALC);
7305c582b2fSDaniel Sanders     HasRs = true;
7315c14b069SZoran Jovanovic   } else {
7325c14b069SZoran Jovanovic     MI.setOpcode(Mips::BLTUC);
7335c14b069SZoran Jovanovic     HasRs = true;
7345c14b069SZoran Jovanovic     HasRt = true;
7355c14b069SZoran Jovanovic   }
7365c582b2fSDaniel Sanders 
7375c582b2fSDaniel Sanders   if (HasRs)
738e9119e41SJim Grosbach     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
7395c582b2fSDaniel Sanders                                        Rs)));
7405c582b2fSDaniel Sanders 
7415c582b2fSDaniel Sanders   if (HasRt)
742e9119e41SJim Grosbach     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
7435c582b2fSDaniel Sanders                                        Rt)));
7445c582b2fSDaniel Sanders 
745e9119e41SJim Grosbach   MI.addOperand(MCOperand::createImm(Imm));
7465c582b2fSDaniel Sanders 
7475c582b2fSDaniel Sanders   return MCDisassembler::Success;
7485c582b2fSDaniel Sanders }
7495c582b2fSDaniel Sanders 
75028a0ca07SZoran Jovanovic template <typename InsnType>
75128a0ca07SZoran Jovanovic static DecodeStatus DecodeBlezGroupBranch(MCInst &MI, InsnType insn,
75228a0ca07SZoran Jovanovic                                            uint64_t Address,
75328a0ca07SZoran Jovanovic                                            const void *Decoder) {
75428a0ca07SZoran Jovanovic   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
75528a0ca07SZoran Jovanovic   // (otherwise we would have matched the BLEZL instruction from the earlier
75628a0ca07SZoran Jovanovic   // ISA's instead).
75728a0ca07SZoran Jovanovic   //
75828a0ca07SZoran Jovanovic   // We have:
75928a0ca07SZoran Jovanovic   //    0b000110 sssss ttttt iiiiiiiiiiiiiiii
76028a0ca07SZoran Jovanovic   //      Invalid   if rs == 0
76128a0ca07SZoran Jovanovic   //      BLEZALC   if rs == 0  && rt != 0
76228a0ca07SZoran Jovanovic   //      BGEZALC   if rs == rt && rt != 0
76328a0ca07SZoran Jovanovic   //      BGEUC     if rs != rt && rs != 0  && rt != 0
76428a0ca07SZoran Jovanovic 
76528a0ca07SZoran Jovanovic   InsnType Rs = fieldFromInstruction(insn, 21, 5);
76628a0ca07SZoran Jovanovic   InsnType Rt = fieldFromInstruction(insn, 16, 5);
767d37bab61SAlexey Samsonov   InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4;
76828a0ca07SZoran Jovanovic   bool HasRs = false;
76928a0ca07SZoran Jovanovic 
77028a0ca07SZoran Jovanovic   if (Rt == 0)
77128a0ca07SZoran Jovanovic     return MCDisassembler::Fail;
77228a0ca07SZoran Jovanovic   else if (Rs == 0)
77328a0ca07SZoran Jovanovic     MI.setOpcode(Mips::BLEZALC);
77428a0ca07SZoran Jovanovic   else if (Rs == Rt)
77528a0ca07SZoran Jovanovic     MI.setOpcode(Mips::BGEZALC);
77628a0ca07SZoran Jovanovic   else {
77728a0ca07SZoran Jovanovic     HasRs = true;
77828a0ca07SZoran Jovanovic     MI.setOpcode(Mips::BGEUC);
77928a0ca07SZoran Jovanovic   }
78028a0ca07SZoran Jovanovic 
78128a0ca07SZoran Jovanovic   if (HasRs)
782e9119e41SJim Grosbach     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
78328a0ca07SZoran Jovanovic                                        Rs)));
784e9119e41SJim Grosbach   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
78528a0ca07SZoran Jovanovic                                      Rt)));
78628a0ca07SZoran Jovanovic 
787e9119e41SJim Grosbach   MI.addOperand(MCOperand::createImm(Imm));
78828a0ca07SZoran Jovanovic 
78928a0ca07SZoran Jovanovic   return MCDisassembler::Success;
79028a0ca07SZoran Jovanovic }
79128a0ca07SZoran Jovanovic 
792ea22c4cfSJozef Kolek /// Read two bytes from the ArrayRef and return 16 bit halfword sorted
793ea22c4cfSJozef Kolek /// according to the given endianess.
794ea22c4cfSJozef Kolek static DecodeStatus readInstruction16(ArrayRef<uint8_t> Bytes, uint64_t Address,
795ea22c4cfSJozef Kolek                                       uint64_t &Size, uint32_t &Insn,
796ea22c4cfSJozef Kolek                                       bool IsBigEndian) {
797ea22c4cfSJozef Kolek   // We want to read exactly 2 Bytes of data.
798ea22c4cfSJozef Kolek   if (Bytes.size() < 2) {
799ea22c4cfSJozef Kolek     Size = 0;
800ea22c4cfSJozef Kolek     return MCDisassembler::Fail;
801ea22c4cfSJozef Kolek   }
802ea22c4cfSJozef Kolek 
803ea22c4cfSJozef Kolek   if (IsBigEndian) {
804ea22c4cfSJozef Kolek     Insn = (Bytes[0] << 8) | Bytes[1];
805ea22c4cfSJozef Kolek   } else {
806ea22c4cfSJozef Kolek     Insn = (Bytes[1] << 8) | Bytes[0];
807ea22c4cfSJozef Kolek   }
808ea22c4cfSJozef Kolek 
809ea22c4cfSJozef Kolek   return MCDisassembler::Success;
810ea22c4cfSJozef Kolek }
811ea22c4cfSJozef Kolek 
8127fc5b874SRafael Espindola /// Read four bytes from the ArrayRef and return 32 bit word sorted
8134aa6bea7SRafael Espindola /// according to the given endianess
8147fc5b874SRafael Espindola static DecodeStatus readInstruction32(ArrayRef<uint8_t> Bytes, uint64_t Address,
8157fc5b874SRafael Espindola                                       uint64_t &Size, uint32_t &Insn,
8167fc5b874SRafael Espindola                                       bool IsBigEndian, bool IsMicroMips) {
81771928e68SAkira Hatanaka   // We want to read exactly 4 Bytes of data.
8187fc5b874SRafael Espindola   if (Bytes.size() < 4) {
8194aa6bea7SRafael Espindola     Size = 0;
82071928e68SAkira Hatanaka     return MCDisassembler::Fail;
82171928e68SAkira Hatanaka   }
82271928e68SAkira Hatanaka 
823ea22c4cfSJozef Kolek   // High 16 bits of a 32-bit microMIPS instruction (where the opcode is)
824ea22c4cfSJozef Kolek   // always precede the low 16 bits in the instruction stream (that is, they
825ea22c4cfSJozef Kolek   // are placed at lower addresses in the instruction stream).
826ea22c4cfSJozef Kolek   //
827ea22c4cfSJozef Kolek   // microMIPS byte ordering:
828ea22c4cfSJozef Kolek   //   Big-endian:    0 | 1 | 2 | 3
829ea22c4cfSJozef Kolek   //   Little-endian: 1 | 0 | 3 | 2
830ea22c4cfSJozef Kolek 
8314aa6bea7SRafael Espindola   if (IsBigEndian) {
83271928e68SAkira Hatanaka     // Encoded as a big-endian 32-bit word in the stream.
8334aa6bea7SRafael Espindola     Insn =
8344aa6bea7SRafael Espindola         (Bytes[3] << 0) | (Bytes[2] << 8) | (Bytes[1] << 16) | (Bytes[0] << 24);
8354aa6bea7SRafael Espindola   } else {
836dde3d582SVladimir Medic     if (IsMicroMips) {
8374aa6bea7SRafael Espindola       Insn = (Bytes[2] << 0) | (Bytes[3] << 8) | (Bytes[0] << 16) |
838dde3d582SVladimir Medic              (Bytes[1] << 24);
839dde3d582SVladimir Medic     } else {
8404aa6bea7SRafael Espindola       Insn = (Bytes[0] << 0) | (Bytes[1] << 8) | (Bytes[2] << 16) |
84171928e68SAkira Hatanaka              (Bytes[3] << 24);
84271928e68SAkira Hatanaka     }
843dde3d582SVladimir Medic   }
84471928e68SAkira Hatanaka 
84571928e68SAkira Hatanaka   return MCDisassembler::Success;
84671928e68SAkira Hatanaka }
84771928e68SAkira Hatanaka 
8484aa6bea7SRafael Espindola DecodeStatus MipsDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,
8497fc5b874SRafael Espindola                                               ArrayRef<uint8_t> Bytes,
85071928e68SAkira Hatanaka                                               uint64_t Address,
8514aa6bea7SRafael Espindola                                               raw_ostream &VStream,
8524aa6bea7SRafael Espindola                                               raw_ostream &CStream) const {
85371928e68SAkira Hatanaka   uint32_t Insn;
854ea22c4cfSJozef Kolek   DecodeStatus Result;
85571928e68SAkira Hatanaka 
856ea22c4cfSJozef Kolek   if (IsMicroMips) {
857ea22c4cfSJozef Kolek     Result = readInstruction16(Bytes, Address, Size, Insn, IsBigEndian);
858ea22c4cfSJozef Kolek 
859ada70918SZoran Jovanovic     if (hasMips32r6()) {
860ada70918SZoran Jovanovic       DEBUG(dbgs() << "Trying MicroMipsR616 table (16-bit instructions):\n");
861ada70918SZoran Jovanovic       // Calling the auto-generated decoder function for microMIPS32R6
862ada70918SZoran Jovanovic       // (and microMIPS64R6) 16-bit instructions.
863ada70918SZoran Jovanovic       Result = decodeInstruction(DecoderTableMicroMipsR616, Instr, Insn,
864ada70918SZoran Jovanovic                                  Address, this, STI);
865ada70918SZoran Jovanovic       if (Result != MCDisassembler::Fail) {
866ada70918SZoran Jovanovic         Size = 2;
867ada70918SZoran Jovanovic         return Result;
868ada70918SZoran Jovanovic       }
869ada70918SZoran Jovanovic     }
870ada70918SZoran Jovanovic 
871ea22c4cfSJozef Kolek     DEBUG(dbgs() << "Trying MicroMips16 table (16-bit instructions):\n");
872ada70918SZoran Jovanovic     // Calling the auto-generated decoder function for microMIPS 16-bit
873ada70918SZoran Jovanovic     // instructions.
874ea22c4cfSJozef Kolek     Result = decodeInstruction(DecoderTableMicroMips16, Instr, Insn, Address,
875ea22c4cfSJozef Kolek                                this, STI);
876ea22c4cfSJozef Kolek     if (Result != MCDisassembler::Fail) {
877ea22c4cfSJozef Kolek       Size = 2;
878ea22c4cfSJozef Kolek       return Result;
879ea22c4cfSJozef Kolek     }
880ea22c4cfSJozef Kolek 
881ea22c4cfSJozef Kolek     Result = readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, true);
88271928e68SAkira Hatanaka     if (Result == MCDisassembler::Fail)
88371928e68SAkira Hatanaka       return MCDisassembler::Fail;
88471928e68SAkira Hatanaka 
885676d6012SJozef Kolek     if (hasMips32r6()) {
886676d6012SJozef Kolek       DEBUG(dbgs() << "Trying MicroMips32r632 table (32-bit instructions):\n");
887676d6012SJozef Kolek       // Calling the auto-generated decoder function.
888366783e1SZoran Jovanovic       Result = decodeInstruction(DecoderTableMicroMipsR632, Instr, Insn, Address,
889676d6012SJozef Kolek                                  this, STI);
890ada70918SZoran Jovanovic       if (Result != MCDisassembler::Fail) {
891ada70918SZoran Jovanovic         Size = 4;
892ada70918SZoran Jovanovic         return Result;
893ada70918SZoran Jovanovic       }
894ada70918SZoran Jovanovic     }
895ada70918SZoran Jovanovic 
896ea22c4cfSJozef Kolek     DEBUG(dbgs() << "Trying MicroMips32 table (32-bit instructions):\n");
897dde3d582SVladimir Medic     // Calling the auto-generated decoder function.
8984aa6bea7SRafael Espindola     Result = decodeInstruction(DecoderTableMicroMips32, Instr, Insn, Address,
899dde3d582SVladimir Medic                                this, STI);
900dde3d582SVladimir Medic     if (Result != MCDisassembler::Fail) {
901dde3d582SVladimir Medic       Size = 4;
902dde3d582SVladimir Medic       return Result;
903dde3d582SVladimir Medic     }
904dde3d582SVladimir Medic     return MCDisassembler::Fail;
905dde3d582SVladimir Medic   }
906dde3d582SVladimir Medic 
907ea22c4cfSJozef Kolek   Result = readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, false);
908ea22c4cfSJozef Kolek   if (Result == MCDisassembler::Fail)
909ea22c4cfSJozef Kolek     return MCDisassembler::Fail;
910ea22c4cfSJozef Kolek 
911c171f65aSDaniel Sanders   if (hasCOP3()) {
912c171f65aSDaniel Sanders     DEBUG(dbgs() << "Trying COP3_ table (32-bit opcodes):\n");
913c171f65aSDaniel Sanders     Result =
9144aa6bea7SRafael Espindola         decodeInstruction(DecoderTableCOP3_32, Instr, Insn, Address, this, STI);
915c171f65aSDaniel Sanders     if (Result != MCDisassembler::Fail) {
916c171f65aSDaniel Sanders       Size = 4;
917c171f65aSDaniel Sanders       return Result;
918c171f65aSDaniel Sanders     }
919c171f65aSDaniel Sanders   }
920c171f65aSDaniel Sanders 
921c171f65aSDaniel Sanders   if (hasMips32r6() && isGP64()) {
9220fa60416SDaniel Sanders     DEBUG(dbgs() << "Trying Mips32r6_64r6 (GPR64) table (32-bit opcodes):\n");
9234aa6bea7SRafael Espindola     Result = decodeInstruction(DecoderTableMips32r6_64r6_GP6432, Instr, Insn,
9240fa60416SDaniel Sanders                                Address, this, STI);
9250fa60416SDaniel Sanders     if (Result != MCDisassembler::Fail) {
9260fa60416SDaniel Sanders       Size = 4;
9270fa60416SDaniel Sanders       return Result;
9280fa60416SDaniel Sanders     }
9290fa60416SDaniel Sanders   }
9300fa60416SDaniel Sanders 
931c171f65aSDaniel Sanders   if (hasMips32r6()) {
9320fa60416SDaniel Sanders     DEBUG(dbgs() << "Trying Mips32r6_64r6 table (32-bit opcodes):\n");
9334aa6bea7SRafael Espindola     Result = decodeInstruction(DecoderTableMips32r6_64r632, Instr, Insn,
9345c582b2fSDaniel Sanders                                Address, this, STI);
9355c582b2fSDaniel Sanders     if (Result != MCDisassembler::Fail) {
9365c582b2fSDaniel Sanders       Size = 4;
9375c582b2fSDaniel Sanders       return Result;
9385c582b2fSDaniel Sanders     }
9395c582b2fSDaniel Sanders   }
9405c582b2fSDaniel Sanders 
9413adf9b8dSKai Nacke   if (hasCnMips()) {
9423adf9b8dSKai Nacke     DEBUG(dbgs() << "Trying CnMips table (32-bit opcodes):\n");
9433adf9b8dSKai Nacke     Result = decodeInstruction(DecoderTableCnMips32, Instr, Insn,
9443adf9b8dSKai Nacke                                Address, this, STI);
9453adf9b8dSKai Nacke     if (Result != MCDisassembler::Fail) {
9463adf9b8dSKai Nacke       Size = 4;
9473adf9b8dSKai Nacke       return Result;
9483adf9b8dSKai Nacke     }
9493adf9b8dSKai Nacke   }
9503adf9b8dSKai Nacke 
951a19216c8SDaniel Sanders   if (isGP64()) {
952a19216c8SDaniel Sanders     DEBUG(dbgs() << "Trying Mips64 (GPR64) table (32-bit opcodes):\n");
953a19216c8SDaniel Sanders     Result = decodeInstruction(DecoderTableMips6432, Instr, Insn,
954a19216c8SDaniel Sanders                                Address, this, STI);
955a19216c8SDaniel Sanders     if (Result != MCDisassembler::Fail) {
956a19216c8SDaniel Sanders       Size = 4;
957a19216c8SDaniel Sanders       return Result;
958a19216c8SDaniel Sanders     }
959a19216c8SDaniel Sanders   }
960a19216c8SDaniel Sanders 
9610fa60416SDaniel Sanders   DEBUG(dbgs() << "Trying Mips table (32-bit opcodes):\n");
96271928e68SAkira Hatanaka   // Calling the auto-generated decoder function.
9634aa6bea7SRafael Espindola   Result =
9644aa6bea7SRafael Espindola       decodeInstruction(DecoderTableMips32, Instr, Insn, Address, this, STI);
96571928e68SAkira Hatanaka   if (Result != MCDisassembler::Fail) {
96671928e68SAkira Hatanaka     Size = 4;
96771928e68SAkira Hatanaka     return Result;
96871928e68SAkira Hatanaka   }
96971928e68SAkira Hatanaka 
97071928e68SAkira Hatanaka   return MCDisassembler::Fail;
97171928e68SAkira Hatanaka }
97271928e68SAkira Hatanaka 
973ec8a5490SReed Kotler static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst,
974ec8a5490SReed Kotler                                                  unsigned RegNo,
975ec8a5490SReed Kotler                                                  uint64_t Address,
976ec8a5490SReed Kotler                                                  const void *Decoder) {
977ec8a5490SReed Kotler 
978ec8a5490SReed Kotler   return MCDisassembler::Fail;
979ec8a5490SReed Kotler 
980ec8a5490SReed Kotler }
981ec8a5490SReed Kotler 
98213e6ccf3SAkira Hatanaka static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst,
98371928e68SAkira Hatanaka                                              unsigned RegNo,
98471928e68SAkira Hatanaka                                              uint64_t Address,
98571928e68SAkira Hatanaka                                              const void *Decoder) {
98671928e68SAkira Hatanaka 
98771928e68SAkira Hatanaka   if (RegNo > 31)
98871928e68SAkira Hatanaka     return MCDisassembler::Fail;
98971928e68SAkira Hatanaka 
99013e6ccf3SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::GPR64RegClassID, RegNo);
991e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
99271928e68SAkira Hatanaka   return MCDisassembler::Success;
99371928e68SAkira Hatanaka }
99471928e68SAkira Hatanaka 
995b0852e54SZoran Jovanovic static DecodeStatus DecodeGPRMM16RegisterClass(MCInst &Inst,
996b0852e54SZoran Jovanovic                                                unsigned RegNo,
997b0852e54SZoran Jovanovic                                                uint64_t Address,
998b0852e54SZoran Jovanovic                                                const void *Decoder) {
999ea22c4cfSJozef Kolek   if (RegNo > 7)
1000b0852e54SZoran Jovanovic     return MCDisassembler::Fail;
1001ea22c4cfSJozef Kolek   unsigned Reg = getReg(Decoder, Mips::GPRMM16RegClassID, RegNo);
1002e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1003ea22c4cfSJozef Kolek   return MCDisassembler::Success;
1004b0852e54SZoran Jovanovic }
1005b0852e54SZoran Jovanovic 
10061904fa21SJozef Kolek static DecodeStatus DecodeGPRMM16ZeroRegisterClass(MCInst &Inst,
10071904fa21SJozef Kolek                                                    unsigned RegNo,
10081904fa21SJozef Kolek                                                    uint64_t Address,
10091904fa21SJozef Kolek                                                    const void *Decoder) {
1010315e7ecaSJozef Kolek   if (RegNo > 7)
10111904fa21SJozef Kolek     return MCDisassembler::Fail;
1012315e7ecaSJozef Kolek   unsigned Reg = getReg(Decoder, Mips::GPRMM16ZeroRegClassID, RegNo);
1013e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1014315e7ecaSJozef Kolek   return MCDisassembler::Success;
10151904fa21SJozef Kolek }
10161904fa21SJozef Kolek 
101741688679SZoran Jovanovic static DecodeStatus DecodeGPRMM16MovePRegisterClass(MCInst &Inst,
101841688679SZoran Jovanovic                                                     unsigned RegNo,
101941688679SZoran Jovanovic                                                     uint64_t Address,
102041688679SZoran Jovanovic                                                     const void *Decoder) {
102141688679SZoran Jovanovic   if (RegNo > 7)
102241688679SZoran Jovanovic     return MCDisassembler::Fail;
102341688679SZoran Jovanovic   unsigned Reg = getReg(Decoder, Mips::GPRMM16MovePRegClassID, RegNo);
1024e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
102541688679SZoran Jovanovic   return MCDisassembler::Success;
102641688679SZoran Jovanovic }
102741688679SZoran Jovanovic 
102813e6ccf3SAkira Hatanaka static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst,
102971928e68SAkira Hatanaka                                              unsigned RegNo,
103071928e68SAkira Hatanaka                                              uint64_t Address,
103171928e68SAkira Hatanaka                                              const void *Decoder) {
103271928e68SAkira Hatanaka   if (RegNo > 31)
103371928e68SAkira Hatanaka     return MCDisassembler::Fail;
103413e6ccf3SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::GPR32RegClassID, RegNo);
1035e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
103671928e68SAkira Hatanaka   return MCDisassembler::Success;
103771928e68SAkira Hatanaka }
103871928e68SAkira Hatanaka 
10399bfa2e2eSAkira Hatanaka static DecodeStatus DecodePtrRegisterClass(MCInst &Inst,
10409bfa2e2eSAkira Hatanaka                                            unsigned RegNo,
10419bfa2e2eSAkira Hatanaka                                            uint64_t Address,
10429bfa2e2eSAkira Hatanaka                                            const void *Decoder) {
1043a19216c8SDaniel Sanders   if (static_cast<const MipsDisassembler *>(Decoder)->isGP64())
10449bfa2e2eSAkira Hatanaka     return DecodeGPR64RegisterClass(Inst, RegNo, Address, Decoder);
10459bfa2e2eSAkira Hatanaka 
10469bfa2e2eSAkira Hatanaka   return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
10479bfa2e2eSAkira Hatanaka }
10489bfa2e2eSAkira Hatanaka 
1049654655f1SAkira Hatanaka static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst,
1050ecabd1a5SAkira Hatanaka                                             unsigned RegNo,
1051ecabd1a5SAkira Hatanaka                                             uint64_t Address,
1052ecabd1a5SAkira Hatanaka                                             const void *Decoder) {
105313e6ccf3SAkira Hatanaka   return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
1054ecabd1a5SAkira Hatanaka }
1055ecabd1a5SAkira Hatanaka 
105671928e68SAkira Hatanaka static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
105771928e68SAkira Hatanaka                                              unsigned RegNo,
105871928e68SAkira Hatanaka                                              uint64_t Address,
105971928e68SAkira Hatanaka                                              const void *Decoder) {
106071928e68SAkira Hatanaka   if (RegNo > 31)
106171928e68SAkira Hatanaka     return MCDisassembler::Fail;
106271928e68SAkira Hatanaka 
10639bf2b567SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::FGR64RegClassID, RegNo);
1064e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
106571928e68SAkira Hatanaka   return MCDisassembler::Success;
106671928e68SAkira Hatanaka }
106771928e68SAkira Hatanaka 
106871928e68SAkira Hatanaka static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
106971928e68SAkira Hatanaka                                              unsigned RegNo,
107071928e68SAkira Hatanaka                                              uint64_t Address,
107171928e68SAkira Hatanaka                                              const void *Decoder) {
107271928e68SAkira Hatanaka   if (RegNo > 31)
107371928e68SAkira Hatanaka     return MCDisassembler::Fail;
107471928e68SAkira Hatanaka 
10759bf2b567SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::FGR32RegClassID, RegNo);
1076e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
107771928e68SAkira Hatanaka   return MCDisassembler::Success;
107871928e68SAkira Hatanaka }
107971928e68SAkira Hatanaka 
108071928e68SAkira Hatanaka static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
108171928e68SAkira Hatanaka                                            unsigned RegNo,
108271928e68SAkira Hatanaka                                            uint64_t Address,
108371928e68SAkira Hatanaka                                            const void *Decoder) {
1084253777fdSChad Rosier   if (RegNo > 31)
1085253777fdSChad Rosier     return MCDisassembler::Fail;
1086253777fdSChad Rosier   unsigned Reg = getReg(Decoder, Mips::CCRRegClassID, RegNo);
1087e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
108871928e68SAkira Hatanaka   return MCDisassembler::Success;
108971928e68SAkira Hatanaka }
109071928e68SAkira Hatanaka 
10911fb1b8b8SAkira Hatanaka static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst,
10921fb1b8b8SAkira Hatanaka                                            unsigned RegNo,
10931fb1b8b8SAkira Hatanaka                                            uint64_t Address,
10941fb1b8b8SAkira Hatanaka                                            const void *Decoder) {
10951fb1b8b8SAkira Hatanaka   if (RegNo > 7)
10961fb1b8b8SAkira Hatanaka     return MCDisassembler::Fail;
10971fb1b8b8SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::FCCRegClassID, RegNo);
1098e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
10991fb1b8b8SAkira Hatanaka   return MCDisassembler::Success;
11001fb1b8b8SAkira Hatanaka }
11011fb1b8b8SAkira Hatanaka 
11020fa60416SDaniel Sanders static DecodeStatus DecodeFGRCCRegisterClass(MCInst &Inst, unsigned RegNo,
11030fa60416SDaniel Sanders                                              uint64_t Address,
11040fa60416SDaniel Sanders                                              const void *Decoder) {
11050fa60416SDaniel Sanders   if (RegNo > 31)
11060fa60416SDaniel Sanders     return MCDisassembler::Fail;
11070fa60416SDaniel Sanders 
11080fa60416SDaniel Sanders   unsigned Reg = getReg(Decoder, Mips::FGRCCRegClassID, RegNo);
1109e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
11100fa60416SDaniel Sanders   return MCDisassembler::Success;
11110fa60416SDaniel Sanders }
11120fa60416SDaniel Sanders 
111371928e68SAkira Hatanaka static DecodeStatus DecodeMem(MCInst &Inst,
111471928e68SAkira Hatanaka                               unsigned Insn,
111571928e68SAkira Hatanaka                               uint64_t Address,
111671928e68SAkira Hatanaka                               const void *Decoder) {
111771928e68SAkira Hatanaka   int Offset = SignExtend32<16>(Insn & 0xffff);
1118ecaef49fSJim Grosbach   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1119ecaef49fSJim Grosbach   unsigned Base = fieldFromInstruction(Insn, 21, 5);
11209bf2b567SAkira Hatanaka 
112113e6ccf3SAkira Hatanaka   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
112213e6ccf3SAkira Hatanaka   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
112371928e68SAkira Hatanaka 
1124d7ecf49eSVladimir Medic   if (Inst.getOpcode() == Mips::SC ||
1125*e4e83a7bSDaniel Sanders       Inst.getOpcode() == Mips::SCD)
1126e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Reg));
1127*e4e83a7bSDaniel Sanders 
1128*e4e83a7bSDaniel Sanders   Inst.addOperand(MCOperand::createReg(Reg));
1129*e4e83a7bSDaniel Sanders   Inst.addOperand(MCOperand::createReg(Base));
1130*e4e83a7bSDaniel Sanders   Inst.addOperand(MCOperand::createImm(Offset));
1131*e4e83a7bSDaniel Sanders 
1132*e4e83a7bSDaniel Sanders   return MCDisassembler::Success;
113371928e68SAkira Hatanaka }
113471928e68SAkira Hatanaka 
1135*e4e83a7bSDaniel Sanders static DecodeStatus DecodeMemEVA(MCInst &Inst,
1136*e4e83a7bSDaniel Sanders                                  unsigned Insn,
1137*e4e83a7bSDaniel Sanders                                  uint64_t Address,
1138*e4e83a7bSDaniel Sanders                                  const void *Decoder) {
1139*e4e83a7bSDaniel Sanders   int Offset = SignExtend32<9>(Insn >> 7);
1140*e4e83a7bSDaniel Sanders   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1141*e4e83a7bSDaniel Sanders   unsigned Base = fieldFromInstruction(Insn, 21, 5);
1142*e4e83a7bSDaniel Sanders 
1143*e4e83a7bSDaniel Sanders   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1144*e4e83a7bSDaniel Sanders   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1145*e4e83a7bSDaniel Sanders 
1146*e4e83a7bSDaniel Sanders    if (Inst.getOpcode() == Mips::SCE)
1147*e4e83a7bSDaniel Sanders      Inst.addOperand(MCOperand::createReg(Reg));
1148*e4e83a7bSDaniel Sanders 
1149e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1150e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1151e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
115271928e68SAkira Hatanaka 
115371928e68SAkira Hatanaka   return MCDisassembler::Success;
115471928e68SAkira Hatanaka }
115571928e68SAkira Hatanaka 
115692db6b78SDaniel Sanders static DecodeStatus DecodeCacheOp(MCInst &Inst,
115792db6b78SDaniel Sanders                               unsigned Insn,
115892db6b78SDaniel Sanders                               uint64_t Address,
115992db6b78SDaniel Sanders                               const void *Decoder) {
116092db6b78SDaniel Sanders   int Offset = SignExtend32<16>(Insn & 0xffff);
116192db6b78SDaniel Sanders   unsigned Hint = fieldFromInstruction(Insn, 16, 5);
116292db6b78SDaniel Sanders   unsigned Base = fieldFromInstruction(Insn, 21, 5);
116392db6b78SDaniel Sanders 
116492db6b78SDaniel Sanders   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
116592db6b78SDaniel Sanders 
1166e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1167e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
1168e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Hint));
116992db6b78SDaniel Sanders 
117092db6b78SDaniel Sanders   return MCDisassembler::Success;
117192db6b78SDaniel Sanders }
117292db6b78SDaniel Sanders 
1173ab6d1cceSJozef Kolek static DecodeStatus DecodeCacheOpMM(MCInst &Inst,
1174ab6d1cceSJozef Kolek                                     unsigned Insn,
1175ab6d1cceSJozef Kolek                                     uint64_t Address,
1176ab6d1cceSJozef Kolek                                     const void *Decoder) {
1177ab6d1cceSJozef Kolek   int Offset = SignExtend32<12>(Insn & 0xfff);
1178ab6d1cceSJozef Kolek   unsigned Base = fieldFromInstruction(Insn, 16, 5);
1179ab6d1cceSJozef Kolek   unsigned Hint = fieldFromInstruction(Insn, 21, 5);
1180ab6d1cceSJozef Kolek 
1181ab6d1cceSJozef Kolek   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1182ab6d1cceSJozef Kolek 
1183e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1184e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
1185e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Hint));
1186ab6d1cceSJozef Kolek 
1187ab6d1cceSJozef Kolek   return MCDisassembler::Success;
1188ab6d1cceSJozef Kolek }
1189ab6d1cceSJozef Kolek 
1190d9790793SZoran Jovanovic static DecodeStatus DecodePrefeOpMM(MCInst &Inst,
1191d9790793SZoran Jovanovic                                     unsigned Insn,
1192d9790793SZoran Jovanovic                                     uint64_t Address,
1193d9790793SZoran Jovanovic                                     const void *Decoder) {
1194d9790793SZoran Jovanovic   int Offset = SignExtend32<9>(Insn & 0x1ff);
1195d9790793SZoran Jovanovic   unsigned Base = fieldFromInstruction(Insn, 16, 5);
1196d9790793SZoran Jovanovic   unsigned Hint = fieldFromInstruction(Insn, 21, 5);
1197d9790793SZoran Jovanovic 
1198d9790793SZoran Jovanovic   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1199d9790793SZoran Jovanovic 
1200d9790793SZoran Jovanovic   Inst.addOperand(MCOperand::createReg(Base));
1201d9790793SZoran Jovanovic   Inst.addOperand(MCOperand::createImm(Offset));
1202d9790793SZoran Jovanovic   Inst.addOperand(MCOperand::createImm(Hint));
1203d9790793SZoran Jovanovic 
1204d9790793SZoran Jovanovic   return MCDisassembler::Success;
1205d9790793SZoran Jovanovic }
1206d9790793SZoran Jovanovic 
1207*e4e83a7bSDaniel Sanders static DecodeStatus DecodeCacheeOp_CacheOpR6(MCInst &Inst,
1208df464ae2SVladimir Medic                                              unsigned Insn,
1209df464ae2SVladimir Medic                                              uint64_t Address,
1210df464ae2SVladimir Medic                                              const void *Decoder) {
1211*e4e83a7bSDaniel Sanders   int Offset = SignExtend32<9>(Insn >> 7);
1212df464ae2SVladimir Medic   unsigned Hint = fieldFromInstruction(Insn, 16, 5);
1213df464ae2SVladimir Medic   unsigned Base = fieldFromInstruction(Insn, 21, 5);
1214df464ae2SVladimir Medic 
1215df464ae2SVladimir Medic   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1216df464ae2SVladimir Medic 
1217e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1218e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
1219e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Hint));
1220df464ae2SVladimir Medic 
1221df464ae2SVladimir Medic   return MCDisassembler::Success;
1222df464ae2SVladimir Medic }
1223df464ae2SVladimir Medic 
12249eaa30d2SZoran Jovanovic static DecodeStatus DecodeStoreEvaOpMM(MCInst &Inst,
12259eaa30d2SZoran Jovanovic                                        unsigned Insn,
12269eaa30d2SZoran Jovanovic                                        uint64_t Address,
12279eaa30d2SZoran Jovanovic                                        const void *Decoder) {
12289eaa30d2SZoran Jovanovic   int Offset = SignExtend32<9>(Insn & 0x1ff);
12299eaa30d2SZoran Jovanovic   unsigned Reg = fieldFromInstruction(Insn, 21, 5);
12309eaa30d2SZoran Jovanovic   unsigned Base = fieldFromInstruction(Insn, 16, 5);
12319eaa30d2SZoran Jovanovic 
12329eaa30d2SZoran Jovanovic   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
12339eaa30d2SZoran Jovanovic   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
12349eaa30d2SZoran Jovanovic 
12359eaa30d2SZoran Jovanovic   Inst.addOperand(MCOperand::createReg(Reg));
12369eaa30d2SZoran Jovanovic   Inst.addOperand(MCOperand::createReg(Base));
12379eaa30d2SZoran Jovanovic   Inst.addOperand(MCOperand::createImm(Offset));
12389eaa30d2SZoran Jovanovic 
12399eaa30d2SZoran Jovanovic   return MCDisassembler::Success;
12409eaa30d2SZoran Jovanovic }
12419eaa30d2SZoran Jovanovic 
1242b4484d62SDaniel Sanders static DecodeStatus DecodeSyncI(MCInst &Inst,
1243b4484d62SDaniel Sanders                               unsigned Insn,
1244b4484d62SDaniel Sanders                               uint64_t Address,
1245b4484d62SDaniel Sanders                               const void *Decoder) {
1246b4484d62SDaniel Sanders   int Offset = SignExtend32<16>(Insn & 0xffff);
1247b4484d62SDaniel Sanders   unsigned Base = fieldFromInstruction(Insn, 21, 5);
1248b4484d62SDaniel Sanders 
1249b4484d62SDaniel Sanders   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1250b4484d62SDaniel Sanders 
1251e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1252e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
1253b4484d62SDaniel Sanders 
1254b4484d62SDaniel Sanders   return MCDisassembler::Success;
1255b4484d62SDaniel Sanders }
1256b4484d62SDaniel Sanders 
1257fe0bf9f6SMatheus Almeida static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn,
1258fe0bf9f6SMatheus Almeida                                     uint64_t Address, const void *Decoder) {
1259fe0bf9f6SMatheus Almeida   int Offset = SignExtend32<10>(fieldFromInstruction(Insn, 16, 10));
1260fe0bf9f6SMatheus Almeida   unsigned Reg = fieldFromInstruction(Insn, 6, 5);
1261fe0bf9f6SMatheus Almeida   unsigned Base = fieldFromInstruction(Insn, 11, 5);
1262fe0bf9f6SMatheus Almeida 
1263fe0bf9f6SMatheus Almeida   Reg = getReg(Decoder, Mips::MSA128BRegClassID, Reg);
1264fe0bf9f6SMatheus Almeida   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1265fe0bf9f6SMatheus Almeida 
1266e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1267e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
12686b59c449SMatheus Almeida 
12696b59c449SMatheus Almeida   // The immediate field of an LD/ST instruction is scaled which means it must
12706b59c449SMatheus Almeida   // be multiplied (when decoding) by the size (in bytes) of the instructions'
12716b59c449SMatheus Almeida   // data format.
12726b59c449SMatheus Almeida   // .b - 1 byte
12736b59c449SMatheus Almeida   // .h - 2 bytes
12746b59c449SMatheus Almeida   // .w - 4 bytes
12756b59c449SMatheus Almeida   // .d - 8 bytes
12766b59c449SMatheus Almeida   switch(Inst.getOpcode())
12776b59c449SMatheus Almeida   {
12786b59c449SMatheus Almeida   default:
12796b59c449SMatheus Almeida     assert (0 && "Unexpected instruction");
12806b59c449SMatheus Almeida     return MCDisassembler::Fail;
12816b59c449SMatheus Almeida     break;
12826b59c449SMatheus Almeida   case Mips::LD_B:
12836b59c449SMatheus Almeida   case Mips::ST_B:
1284e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(Offset));
12856b59c449SMatheus Almeida     break;
12866b59c449SMatheus Almeida   case Mips::LD_H:
12876b59c449SMatheus Almeida   case Mips::ST_H:
1288e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(Offset * 2));
12896b59c449SMatheus Almeida     break;
12906b59c449SMatheus Almeida   case Mips::LD_W:
12916b59c449SMatheus Almeida   case Mips::ST_W:
1292e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(Offset * 4));
12936b59c449SMatheus Almeida     break;
12946b59c449SMatheus Almeida   case Mips::LD_D:
12956b59c449SMatheus Almeida   case Mips::ST_D:
1296e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(Offset * 8));
12976b59c449SMatheus Almeida     break;
12986b59c449SMatheus Almeida   }
1299fe0bf9f6SMatheus Almeida 
1300fe0bf9f6SMatheus Almeida   return MCDisassembler::Success;
1301fe0bf9f6SMatheus Almeida }
1302fe0bf9f6SMatheus Almeida 
1303315e7ecaSJozef Kolek static DecodeStatus DecodeMemMMImm4(MCInst &Inst,
1304315e7ecaSJozef Kolek                                     unsigned Insn,
1305315e7ecaSJozef Kolek                                     uint64_t Address,
1306315e7ecaSJozef Kolek                                     const void *Decoder) {
1307315e7ecaSJozef Kolek   unsigned Offset = Insn & 0xf;
1308315e7ecaSJozef Kolek   unsigned Reg = fieldFromInstruction(Insn, 7, 3);
1309315e7ecaSJozef Kolek   unsigned Base = fieldFromInstruction(Insn, 4, 3);
1310315e7ecaSJozef Kolek 
1311315e7ecaSJozef Kolek   switch (Inst.getOpcode()) {
1312315e7ecaSJozef Kolek     case Mips::LBU16_MM:
1313315e7ecaSJozef Kolek     case Mips::LHU16_MM:
1314315e7ecaSJozef Kolek     case Mips::LW16_MM:
1315315e7ecaSJozef Kolek       if (DecodeGPRMM16RegisterClass(Inst, Reg, Address, Decoder)
1316315e7ecaSJozef Kolek             == MCDisassembler::Fail)
1317315e7ecaSJozef Kolek         return MCDisassembler::Fail;
1318315e7ecaSJozef Kolek       break;
1319315e7ecaSJozef Kolek     case Mips::SB16_MM:
1320315e7ecaSJozef Kolek     case Mips::SH16_MM:
1321315e7ecaSJozef Kolek     case Mips::SW16_MM:
1322315e7ecaSJozef Kolek       if (DecodeGPRMM16ZeroRegisterClass(Inst, Reg, Address, Decoder)
1323315e7ecaSJozef Kolek             == MCDisassembler::Fail)
1324315e7ecaSJozef Kolek         return MCDisassembler::Fail;
1325315e7ecaSJozef Kolek       break;
1326315e7ecaSJozef Kolek   }
1327315e7ecaSJozef Kolek 
1328315e7ecaSJozef Kolek   if (DecodeGPRMM16RegisterClass(Inst, Base, Address, Decoder)
1329315e7ecaSJozef Kolek         == MCDisassembler::Fail)
1330315e7ecaSJozef Kolek     return MCDisassembler::Fail;
1331315e7ecaSJozef Kolek 
1332315e7ecaSJozef Kolek   switch (Inst.getOpcode()) {
1333315e7ecaSJozef Kolek     case Mips::LBU16_MM:
1334315e7ecaSJozef Kolek       if (Offset == 0xf)
1335e9119e41SJim Grosbach         Inst.addOperand(MCOperand::createImm(-1));
1336315e7ecaSJozef Kolek       else
1337e9119e41SJim Grosbach         Inst.addOperand(MCOperand::createImm(Offset));
1338315e7ecaSJozef Kolek       break;
1339315e7ecaSJozef Kolek     case Mips::SB16_MM:
1340e9119e41SJim Grosbach       Inst.addOperand(MCOperand::createImm(Offset));
1341315e7ecaSJozef Kolek       break;
1342315e7ecaSJozef Kolek     case Mips::LHU16_MM:
1343315e7ecaSJozef Kolek     case Mips::SH16_MM:
1344e9119e41SJim Grosbach       Inst.addOperand(MCOperand::createImm(Offset << 1));
1345315e7ecaSJozef Kolek       break;
1346315e7ecaSJozef Kolek     case Mips::LW16_MM:
1347315e7ecaSJozef Kolek     case Mips::SW16_MM:
1348e9119e41SJim Grosbach       Inst.addOperand(MCOperand::createImm(Offset << 2));
1349315e7ecaSJozef Kolek       break;
1350315e7ecaSJozef Kolek   }
1351315e7ecaSJozef Kolek 
1352315e7ecaSJozef Kolek   return MCDisassembler::Success;
1353315e7ecaSJozef Kolek }
1354315e7ecaSJozef Kolek 
135512c6982bSJozef Kolek static DecodeStatus DecodeMemMMSPImm5Lsl2(MCInst &Inst,
135612c6982bSJozef Kolek                                           unsigned Insn,
135712c6982bSJozef Kolek                                           uint64_t Address,
135812c6982bSJozef Kolek                                           const void *Decoder) {
135912c6982bSJozef Kolek   unsigned Offset = Insn & 0x1F;
136012c6982bSJozef Kolek   unsigned Reg = fieldFromInstruction(Insn, 5, 5);
136112c6982bSJozef Kolek 
136212c6982bSJozef Kolek   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
136312c6982bSJozef Kolek 
1364e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1365e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Mips::SP));
1366e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset << 2));
136712c6982bSJozef Kolek 
136812c6982bSJozef Kolek   return MCDisassembler::Success;
136912c6982bSJozef Kolek }
137012c6982bSJozef Kolek 
1371e10a02ecSJozef Kolek static DecodeStatus DecodeMemMMGPImm7Lsl2(MCInst &Inst,
1372e10a02ecSJozef Kolek                                           unsigned Insn,
1373e10a02ecSJozef Kolek                                           uint64_t Address,
1374e10a02ecSJozef Kolek                                           const void *Decoder) {
1375e10a02ecSJozef Kolek   unsigned Offset = Insn & 0x7F;
1376e10a02ecSJozef Kolek   unsigned Reg = fieldFromInstruction(Insn, 7, 3);
1377e10a02ecSJozef Kolek 
1378e10a02ecSJozef Kolek   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1379e10a02ecSJozef Kolek 
1380e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1381e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Mips::GP));
1382e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset << 2));
1383e10a02ecSJozef Kolek 
1384e10a02ecSJozef Kolek   return MCDisassembler::Success;
1385e10a02ecSJozef Kolek }
1386e10a02ecSJozef Kolek 
1387d68d424aSJozef Kolek static DecodeStatus DecodeMemMMReglistImm4Lsl2(MCInst &Inst,
1388d68d424aSJozef Kolek                                                unsigned Insn,
1389d68d424aSJozef Kolek                                                uint64_t Address,
1390d68d424aSJozef Kolek                                                const void *Decoder) {
1391d68d424aSJozef Kolek   int Offset = SignExtend32<4>(Insn & 0xf);
1392d68d424aSJozef Kolek 
1393d68d424aSJozef Kolek   if (DecodeRegListOperand16(Inst, Insn, Address, Decoder)
1394d68d424aSJozef Kolek       == MCDisassembler::Fail)
1395d68d424aSJozef Kolek     return MCDisassembler::Fail;
1396d68d424aSJozef Kolek 
1397e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Mips::SP));
1398e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset << 2));
1399d68d424aSJozef Kolek 
1400d68d424aSJozef Kolek   return MCDisassembler::Success;
1401d68d424aSJozef Kolek }
1402d68d424aSJozef Kolek 
1403a6593ff6SZoran Jovanovic static DecodeStatus DecodeMemMMImm9(MCInst &Inst,
1404a6593ff6SZoran Jovanovic                                     unsigned Insn,
1405a6593ff6SZoran Jovanovic                                     uint64_t Address,
1406a6593ff6SZoran Jovanovic                                     const void *Decoder) {
1407a6593ff6SZoran Jovanovic   int Offset = SignExtend32<9>(Insn & 0x1ff);
1408a6593ff6SZoran Jovanovic   unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1409a6593ff6SZoran Jovanovic   unsigned Base = fieldFromInstruction(Insn, 16, 5);
1410a6593ff6SZoran Jovanovic 
1411a6593ff6SZoran Jovanovic   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1412a6593ff6SZoran Jovanovic   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1413a6593ff6SZoran Jovanovic 
1414a6593ff6SZoran Jovanovic   Inst.addOperand(MCOperand::createReg(Reg));
1415a6593ff6SZoran Jovanovic   Inst.addOperand(MCOperand::createReg(Base));
1416a6593ff6SZoran Jovanovic   Inst.addOperand(MCOperand::createImm(Offset));
1417a6593ff6SZoran Jovanovic 
1418a6593ff6SZoran Jovanovic   return MCDisassembler::Success;
1419a6593ff6SZoran Jovanovic }
1420a6593ff6SZoran Jovanovic 
1421dde3d582SVladimir Medic static DecodeStatus DecodeMemMMImm12(MCInst &Inst,
1422dde3d582SVladimir Medic                                      unsigned Insn,
1423dde3d582SVladimir Medic                                      uint64_t Address,
1424dde3d582SVladimir Medic                                      const void *Decoder) {
1425dde3d582SVladimir Medic   int Offset = SignExtend32<12>(Insn & 0x0fff);
1426dde3d582SVladimir Medic   unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1427dde3d582SVladimir Medic   unsigned Base = fieldFromInstruction(Insn, 16, 5);
1428dde3d582SVladimir Medic 
1429dde3d582SVladimir Medic   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1430dde3d582SVladimir Medic   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1431dde3d582SVladimir Medic 
1432a4c4b5fcSZoran Jovanovic   switch (Inst.getOpcode()) {
1433a4c4b5fcSZoran Jovanovic   case Mips::SWM32_MM:
1434a4c4b5fcSZoran Jovanovic   case Mips::LWM32_MM:
1435a4c4b5fcSZoran Jovanovic     if (DecodeRegListOperand(Inst, Insn, Address, Decoder)
1436a4c4b5fcSZoran Jovanovic         == MCDisassembler::Fail)
1437a4c4b5fcSZoran Jovanovic       return MCDisassembler::Fail;
1438e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Base));
1439e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(Offset));
1440a4c4b5fcSZoran Jovanovic     break;
1441a4c4b5fcSZoran Jovanovic   case Mips::SC_MM:
1442e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Reg));
1443a4c4b5fcSZoran Jovanovic     // fallthrough
1444a4c4b5fcSZoran Jovanovic   default:
1445e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Reg));
14462deca348SZoran Jovanovic     if (Inst.getOpcode() == Mips::LWP_MM || Inst.getOpcode() == Mips::SWP_MM)
1447e9119e41SJim Grosbach       Inst.addOperand(MCOperand::createReg(Reg+1));
14482deca348SZoran Jovanovic 
1449e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Base));
1450e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(Offset));
1451a4c4b5fcSZoran Jovanovic   }
1452dde3d582SVladimir Medic 
1453dde3d582SVladimir Medic   return MCDisassembler::Success;
1454dde3d582SVladimir Medic }
1455dde3d582SVladimir Medic 
1456dde3d582SVladimir Medic static DecodeStatus DecodeMemMMImm16(MCInst &Inst,
1457dde3d582SVladimir Medic                                      unsigned Insn,
1458dde3d582SVladimir Medic                                      uint64_t Address,
1459dde3d582SVladimir Medic                                      const void *Decoder) {
1460dde3d582SVladimir Medic   int Offset = SignExtend32<16>(Insn & 0xffff);
1461dde3d582SVladimir Medic   unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1462dde3d582SVladimir Medic   unsigned Base = fieldFromInstruction(Insn, 16, 5);
1463dde3d582SVladimir Medic 
1464dde3d582SVladimir Medic   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1465dde3d582SVladimir Medic   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1466dde3d582SVladimir Medic 
1467e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1468e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1469e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
1470dde3d582SVladimir Medic 
1471dde3d582SVladimir Medic   return MCDisassembler::Success;
1472dde3d582SVladimir Medic }
1473dde3d582SVladimir Medic 
147471928e68SAkira Hatanaka static DecodeStatus DecodeFMem(MCInst &Inst,
147571928e68SAkira Hatanaka                                unsigned Insn,
147671928e68SAkira Hatanaka                                uint64_t Address,
147771928e68SAkira Hatanaka                                const void *Decoder) {
147871928e68SAkira Hatanaka   int Offset = SignExtend32<16>(Insn & 0xffff);
1479ecaef49fSJim Grosbach   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1480ecaef49fSJim Grosbach   unsigned Base = fieldFromInstruction(Insn, 21, 5);
148171928e68SAkira Hatanaka 
14829bf2b567SAkira Hatanaka   Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg);
148313e6ccf3SAkira Hatanaka   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
14849bf2b567SAkira Hatanaka 
1485e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1486e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1487e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
148871928e68SAkira Hatanaka 
148971928e68SAkira Hatanaka   return MCDisassembler::Success;
149071928e68SAkira Hatanaka }
149171928e68SAkira Hatanaka 
149292db6b78SDaniel Sanders static DecodeStatus DecodeFMem2(MCInst &Inst,
149392db6b78SDaniel Sanders                                unsigned Insn,
149492db6b78SDaniel Sanders                                uint64_t Address,
149592db6b78SDaniel Sanders                                const void *Decoder) {
149692db6b78SDaniel Sanders   int Offset = SignExtend32<16>(Insn & 0xffff);
149792db6b78SDaniel Sanders   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
149892db6b78SDaniel Sanders   unsigned Base = fieldFromInstruction(Insn, 21, 5);
149992db6b78SDaniel Sanders 
150092db6b78SDaniel Sanders   Reg = getReg(Decoder, Mips::COP2RegClassID, Reg);
150192db6b78SDaniel Sanders   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
150292db6b78SDaniel Sanders 
1503e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1504e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1505e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
150692db6b78SDaniel Sanders 
150792db6b78SDaniel Sanders   return MCDisassembler::Success;
150892db6b78SDaniel Sanders }
150992db6b78SDaniel Sanders 
151092db6b78SDaniel Sanders static DecodeStatus DecodeFMem3(MCInst &Inst,
151192db6b78SDaniel Sanders                                unsigned Insn,
151292db6b78SDaniel Sanders                                uint64_t Address,
151392db6b78SDaniel Sanders                                const void *Decoder) {
151492db6b78SDaniel Sanders   int Offset = SignExtend32<16>(Insn & 0xffff);
151592db6b78SDaniel Sanders   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
151692db6b78SDaniel Sanders   unsigned Base = fieldFromInstruction(Insn, 21, 5);
151792db6b78SDaniel Sanders 
151892db6b78SDaniel Sanders   Reg = getReg(Decoder, Mips::COP3RegClassID, Reg);
151992db6b78SDaniel Sanders   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
152092db6b78SDaniel Sanders 
1521e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1522e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1523e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
152492db6b78SDaniel Sanders 
152592db6b78SDaniel Sanders   return MCDisassembler::Success;
152692db6b78SDaniel Sanders }
152792db6b78SDaniel Sanders 
1528435cf8a4SVladimir Medic static DecodeStatus DecodeFMemCop2R6(MCInst &Inst,
1529435cf8a4SVladimir Medic                                     unsigned Insn,
1530435cf8a4SVladimir Medic                                     uint64_t Address,
1531435cf8a4SVladimir Medic                                     const void *Decoder) {
1532435cf8a4SVladimir Medic   int Offset = SignExtend32<11>(Insn & 0x07ff);
1533435cf8a4SVladimir Medic   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1534435cf8a4SVladimir Medic   unsigned Base = fieldFromInstruction(Insn, 11, 5);
1535435cf8a4SVladimir Medic 
1536435cf8a4SVladimir Medic   Reg = getReg(Decoder, Mips::COP2RegClassID, Reg);
1537435cf8a4SVladimir Medic   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1538435cf8a4SVladimir Medic 
1539e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1540e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1541e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
1542435cf8a4SVladimir Medic 
1543435cf8a4SVladimir Medic   return MCDisassembler::Success;
1544435cf8a4SVladimir Medic }
15456a803f61SDaniel Sanders static DecodeStatus DecodeSpecial3LlSc(MCInst &Inst,
15466a803f61SDaniel Sanders                                        unsigned Insn,
15476a803f61SDaniel Sanders                                        uint64_t Address,
15486a803f61SDaniel Sanders                                        const void *Decoder) {
15496a803f61SDaniel Sanders   int64_t Offset = SignExtend64<9>((Insn >> 7) & 0x1ff);
15506a803f61SDaniel Sanders   unsigned Rt = fieldFromInstruction(Insn, 16, 5);
15516a803f61SDaniel Sanders   unsigned Base = fieldFromInstruction(Insn, 21, 5);
15526a803f61SDaniel Sanders 
15536a803f61SDaniel Sanders   Rt = getReg(Decoder, Mips::GPR32RegClassID, Rt);
15546a803f61SDaniel Sanders   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
15556a803f61SDaniel Sanders 
15566a803f61SDaniel Sanders   if(Inst.getOpcode() == Mips::SC_R6 || Inst.getOpcode() == Mips::SCD_R6){
1557e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Rt));
15586a803f61SDaniel Sanders   }
15596a803f61SDaniel Sanders 
1560e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Rt));
1561e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1562e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
15636a803f61SDaniel Sanders 
15646a803f61SDaniel Sanders   return MCDisassembler::Success;
15656a803f61SDaniel Sanders }
156671928e68SAkira Hatanaka 
156771928e68SAkira Hatanaka static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
156871928e68SAkira Hatanaka                                               unsigned RegNo,
156971928e68SAkira Hatanaka                                               uint64_t Address,
157071928e68SAkira Hatanaka                                               const void *Decoder) {
157171928e68SAkira Hatanaka   // Currently only hardware register 29 is supported.
157271928e68SAkira Hatanaka   if (RegNo != 29)
157371928e68SAkira Hatanaka     return  MCDisassembler::Fail;
1574e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Mips::HWR29));
157571928e68SAkira Hatanaka   return MCDisassembler::Success;
157671928e68SAkira Hatanaka }
157771928e68SAkira Hatanaka 
157871928e68SAkira Hatanaka static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
157971928e68SAkira Hatanaka                                               unsigned RegNo,
158071928e68SAkira Hatanaka                                               uint64_t Address,
158171928e68SAkira Hatanaka                                               const void *Decoder) {
15829bf2b567SAkira Hatanaka   if (RegNo > 30 || RegNo %2)
158371928e68SAkira Hatanaka     return MCDisassembler::Fail;
158471928e68SAkira Hatanaka 
15859bf2b567SAkira Hatanaka   ;
15869bf2b567SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::AFGR64RegClassID, RegNo /2);
1587e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
158871928e68SAkira Hatanaka   return MCDisassembler::Success;
158971928e68SAkira Hatanaka }
159071928e68SAkira Hatanaka 
159100fcf2e1SAkira Hatanaka static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst,
1592ecabd1a5SAkira Hatanaka                                                 unsigned RegNo,
1593ecabd1a5SAkira Hatanaka                                                 uint64_t Address,
1594ecabd1a5SAkira Hatanaka                                                 const void *Decoder) {
1595ecabd1a5SAkira Hatanaka   if (RegNo >= 4)
1596ecabd1a5SAkira Hatanaka     return MCDisassembler::Fail;
1597ecabd1a5SAkira Hatanaka 
159800fcf2e1SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::ACC64DSPRegClassID, RegNo);
1599e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1600ecabd1a5SAkira Hatanaka   return MCDisassembler::Success;
1601ecabd1a5SAkira Hatanaka }
1602ecabd1a5SAkira Hatanaka 
16038002a3f6SAkira Hatanaka static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst,
160459bfaf77SAkira Hatanaka                                                unsigned RegNo,
160559bfaf77SAkira Hatanaka                                                uint64_t Address,
160659bfaf77SAkira Hatanaka                                                const void *Decoder) {
160759bfaf77SAkira Hatanaka   if (RegNo >= 4)
160859bfaf77SAkira Hatanaka     return MCDisassembler::Fail;
160959bfaf77SAkira Hatanaka 
16108002a3f6SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::HI32DSPRegClassID, RegNo);
1611e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
161259bfaf77SAkira Hatanaka   return MCDisassembler::Success;
161359bfaf77SAkira Hatanaka }
161459bfaf77SAkira Hatanaka 
16158002a3f6SAkira Hatanaka static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst,
161659bfaf77SAkira Hatanaka                                                unsigned RegNo,
161759bfaf77SAkira Hatanaka                                                uint64_t Address,
161859bfaf77SAkira Hatanaka                                                const void *Decoder) {
161959bfaf77SAkira Hatanaka   if (RegNo >= 4)
162059bfaf77SAkira Hatanaka     return MCDisassembler::Fail;
162159bfaf77SAkira Hatanaka 
16228002a3f6SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::LO32DSPRegClassID, RegNo);
1623e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
162459bfaf77SAkira Hatanaka   return MCDisassembler::Success;
162559bfaf77SAkira Hatanaka }
162659bfaf77SAkira Hatanaka 
16273eb663b0SJack Carter static DecodeStatus DecodeMSA128BRegisterClass(MCInst &Inst,
16283eb663b0SJack Carter                                                unsigned RegNo,
16293eb663b0SJack Carter                                                uint64_t Address,
16303eb663b0SJack Carter                                                const void *Decoder) {
16313eb663b0SJack Carter   if (RegNo > 31)
16323eb663b0SJack Carter     return MCDisassembler::Fail;
16333eb663b0SJack Carter 
16343eb663b0SJack Carter   unsigned Reg = getReg(Decoder, Mips::MSA128BRegClassID, RegNo);
1635e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
16363eb663b0SJack Carter   return MCDisassembler::Success;
16373eb663b0SJack Carter }
16383eb663b0SJack Carter 
16395dc8ac92SJack Carter static DecodeStatus DecodeMSA128HRegisterClass(MCInst &Inst,
16405dc8ac92SJack Carter                                                unsigned RegNo,
16415dc8ac92SJack Carter                                                uint64_t Address,
16425dc8ac92SJack Carter                                                const void *Decoder) {
16435dc8ac92SJack Carter   if (RegNo > 31)
16445dc8ac92SJack Carter     return MCDisassembler::Fail;
16455dc8ac92SJack Carter 
16465dc8ac92SJack Carter   unsigned Reg = getReg(Decoder, Mips::MSA128HRegClassID, RegNo);
1647e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
16485dc8ac92SJack Carter   return MCDisassembler::Success;
16495dc8ac92SJack Carter }
16505dc8ac92SJack Carter 
16515dc8ac92SJack Carter static DecodeStatus DecodeMSA128WRegisterClass(MCInst &Inst,
16525dc8ac92SJack Carter                                                unsigned RegNo,
16535dc8ac92SJack Carter                                                uint64_t Address,
16545dc8ac92SJack Carter                                                const void *Decoder) {
16555dc8ac92SJack Carter   if (RegNo > 31)
16565dc8ac92SJack Carter     return MCDisassembler::Fail;
16575dc8ac92SJack Carter 
16585dc8ac92SJack Carter   unsigned Reg = getReg(Decoder, Mips::MSA128WRegClassID, RegNo);
1659e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
16605dc8ac92SJack Carter   return MCDisassembler::Success;
16615dc8ac92SJack Carter }
16625dc8ac92SJack Carter 
16635dc8ac92SJack Carter static DecodeStatus DecodeMSA128DRegisterClass(MCInst &Inst,
16645dc8ac92SJack Carter                                                unsigned RegNo,
16655dc8ac92SJack Carter                                                uint64_t Address,
16665dc8ac92SJack Carter                                                const void *Decoder) {
16675dc8ac92SJack Carter   if (RegNo > 31)
16685dc8ac92SJack Carter     return MCDisassembler::Fail;
16695dc8ac92SJack Carter 
16705dc8ac92SJack Carter   unsigned Reg = getReg(Decoder, Mips::MSA128DRegClassID, RegNo);
1671e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
16725dc8ac92SJack Carter   return MCDisassembler::Success;
16735dc8ac92SJack Carter }
16745dc8ac92SJack Carter 
1675a591fdc6SMatheus Almeida static DecodeStatus DecodeMSACtrlRegisterClass(MCInst &Inst,
1676a591fdc6SMatheus Almeida                                                unsigned RegNo,
1677a591fdc6SMatheus Almeida                                                uint64_t Address,
1678a591fdc6SMatheus Almeida                                                const void *Decoder) {
1679a591fdc6SMatheus Almeida   if (RegNo > 7)
1680a591fdc6SMatheus Almeida     return MCDisassembler::Fail;
1681a591fdc6SMatheus Almeida 
1682a591fdc6SMatheus Almeida   unsigned Reg = getReg(Decoder, Mips::MSACtrlRegClassID, RegNo);
1683e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1684a591fdc6SMatheus Almeida   return MCDisassembler::Success;
1685a591fdc6SMatheus Almeida }
1686a591fdc6SMatheus Almeida 
1687a3134faeSDaniel Sanders static DecodeStatus DecodeCOP0RegisterClass(MCInst &Inst,
1688a3134faeSDaniel Sanders                                             unsigned RegNo,
1689a3134faeSDaniel Sanders                                             uint64_t Address,
1690a3134faeSDaniel Sanders                                             const void *Decoder) {
1691a3134faeSDaniel Sanders   if (RegNo > 31)
1692a3134faeSDaniel Sanders     return MCDisassembler::Fail;
1693a3134faeSDaniel Sanders 
1694a3134faeSDaniel Sanders   unsigned Reg = getReg(Decoder, Mips::COP0RegClassID, RegNo);
1695a3134faeSDaniel Sanders   Inst.addOperand(MCOperand::createReg(Reg));
1696a3134faeSDaniel Sanders   return MCDisassembler::Success;
1697a3134faeSDaniel Sanders }
1698a3134faeSDaniel Sanders 
16992a83d680SDaniel Sanders static DecodeStatus DecodeCOP2RegisterClass(MCInst &Inst,
17002a83d680SDaniel Sanders                                             unsigned RegNo,
17012a83d680SDaniel Sanders                                             uint64_t Address,
17022a83d680SDaniel Sanders                                             const void *Decoder) {
17032a83d680SDaniel Sanders   if (RegNo > 31)
17042a83d680SDaniel Sanders     return MCDisassembler::Fail;
17052a83d680SDaniel Sanders 
17062a83d680SDaniel Sanders   unsigned Reg = getReg(Decoder, Mips::COP2RegClassID, RegNo);
1707e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
17082a83d680SDaniel Sanders   return MCDisassembler::Success;
17092a83d680SDaniel Sanders }
17102a83d680SDaniel Sanders 
171171928e68SAkira Hatanaka static DecodeStatus DecodeBranchTarget(MCInst &Inst,
171271928e68SAkira Hatanaka                                        unsigned Offset,
171371928e68SAkira Hatanaka                                        uint64_t Address,
171471928e68SAkira Hatanaka                                        const void *Decoder) {
1715d37bab61SAlexey Samsonov   int32_t BranchOffset = (SignExtend32<16>(Offset) * 4) + 4;
1716e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(BranchOffset));
171771928e68SAkira Hatanaka   return MCDisassembler::Success;
171871928e68SAkira Hatanaka }
171971928e68SAkira Hatanaka 
172071928e68SAkira Hatanaka static DecodeStatus DecodeJumpTarget(MCInst &Inst,
172171928e68SAkira Hatanaka                                      unsigned Insn,
172271928e68SAkira Hatanaka                                      uint64_t Address,
172371928e68SAkira Hatanaka                                      const void *Decoder) {
172471928e68SAkira Hatanaka 
1725ecaef49fSJim Grosbach   unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 2;
1726e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(JumpOffset));
172771928e68SAkira Hatanaka   return MCDisassembler::Success;
172871928e68SAkira Hatanaka }
172971928e68SAkira Hatanaka 
17303c8869dcSZoran Jovanovic static DecodeStatus DecodeBranchTarget21(MCInst &Inst,
17313c8869dcSZoran Jovanovic                                          unsigned Offset,
17323c8869dcSZoran Jovanovic                                          uint64_t Address,
17333c8869dcSZoran Jovanovic                                          const void *Decoder) {
1734d37bab61SAlexey Samsonov   int32_t BranchOffset = SignExtend32<21>(Offset) * 4;
17353c8869dcSZoran Jovanovic 
1736e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(BranchOffset));
17373c8869dcSZoran Jovanovic   return MCDisassembler::Success;
17383c8869dcSZoran Jovanovic }
17393c8869dcSZoran Jovanovic 
17403c8869dcSZoran Jovanovic static DecodeStatus DecodeBranchTarget26(MCInst &Inst,
17413c8869dcSZoran Jovanovic                                          unsigned Offset,
17423c8869dcSZoran Jovanovic                                          uint64_t Address,
17433c8869dcSZoran Jovanovic                                          const void *Decoder) {
1744d37bab61SAlexey Samsonov   int32_t BranchOffset = SignExtend32<26>(Offset) * 4;
17453c8869dcSZoran Jovanovic 
1746e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(BranchOffset));
17473c8869dcSZoran Jovanovic   return MCDisassembler::Success;
17483c8869dcSZoran Jovanovic }
17493c8869dcSZoran Jovanovic 
17509761e96bSJozef Kolek static DecodeStatus DecodeBranchTarget7MM(MCInst &Inst,
17519761e96bSJozef Kolek                                           unsigned Offset,
17529761e96bSJozef Kolek                                           uint64_t Address,
17539761e96bSJozef Kolek                                           const void *Decoder) {
17549761e96bSJozef Kolek   int32_t BranchOffset = SignExtend32<7>(Offset) << 1;
1755e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(BranchOffset));
17569761e96bSJozef Kolek   return MCDisassembler::Success;
17579761e96bSJozef Kolek }
17589761e96bSJozef Kolek 
17595cfebddeSJozef Kolek static DecodeStatus DecodeBranchTarget10MM(MCInst &Inst,
17605cfebddeSJozef Kolek                                            unsigned Offset,
17615cfebddeSJozef Kolek                                            uint64_t Address,
17625cfebddeSJozef Kolek                                            const void *Decoder) {
17635cfebddeSJozef Kolek   int32_t BranchOffset = SignExtend32<10>(Offset) << 1;
1764e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(BranchOffset));
17655cfebddeSJozef Kolek   return MCDisassembler::Success;
17665cfebddeSJozef Kolek }
17675cfebddeSJozef Kolek 
17688a80aa76SZoran Jovanovic static DecodeStatus DecodeBranchTargetMM(MCInst &Inst,
17698a80aa76SZoran Jovanovic                                          unsigned Offset,
17708a80aa76SZoran Jovanovic                                          uint64_t Address,
17718a80aa76SZoran Jovanovic                                          const void *Decoder) {
1772d37bab61SAlexey Samsonov   int32_t BranchOffset = SignExtend32<16>(Offset) * 2;
1773e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(BranchOffset));
17748a80aa76SZoran Jovanovic   return MCDisassembler::Success;
17758a80aa76SZoran Jovanovic }
17768a80aa76SZoran Jovanovic 
1777507e084aSZoran Jovanovic static DecodeStatus DecodeJumpTargetMM(MCInst &Inst,
1778507e084aSZoran Jovanovic                                        unsigned Insn,
1779507e084aSZoran Jovanovic                                        uint64_t Address,
1780507e084aSZoran Jovanovic                                        const void *Decoder) {
1781507e084aSZoran Jovanovic   unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 1;
1782e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(JumpOffset));
1783507e084aSZoran Jovanovic   return MCDisassembler::Success;
1784507e084aSZoran Jovanovic }
178571928e68SAkira Hatanaka 
1786aa2b9278SJozef Kolek static DecodeStatus DecodeAddiur2Simm7(MCInst &Inst,
1787aa2b9278SJozef Kolek                                        unsigned Value,
1788aa2b9278SJozef Kolek                                        uint64_t Address,
1789aa2b9278SJozef Kolek                                        const void *Decoder) {
1790aa2b9278SJozef Kolek   if (Value == 0)
1791e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(1));
1792aa2b9278SJozef Kolek   else if (Value == 0x7)
1793e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(-1));
1794aa2b9278SJozef Kolek   else
1795e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(Value << 2));
1796aa2b9278SJozef Kolek   return MCDisassembler::Success;
1797aa2b9278SJozef Kolek }
1798aa2b9278SJozef Kolek 
1799aa2b9278SJozef Kolek static DecodeStatus DecodeUImm6Lsl2(MCInst &Inst,
1800aa2b9278SJozef Kolek                                     unsigned Value,
1801aa2b9278SJozef Kolek                                     uint64_t Address,
1802aa2b9278SJozef Kolek                                     const void *Decoder) {
1803e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Value << 2));
1804aa2b9278SJozef Kolek   return MCDisassembler::Success;
1805aa2b9278SJozef Kolek }
1806aa2b9278SJozef Kolek 
1807aa2b9278SJozef Kolek static DecodeStatus DecodeLiSimm7(MCInst &Inst,
1808aa2b9278SJozef Kolek                                   unsigned Value,
1809aa2b9278SJozef Kolek                                   uint64_t Address,
1810aa2b9278SJozef Kolek                                   const void *Decoder) {
1811aa2b9278SJozef Kolek   if (Value == 0x7F)
1812e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(-1));
1813aa2b9278SJozef Kolek   else
1814e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(Value));
1815aa2b9278SJozef Kolek   return MCDisassembler::Success;
1816aa2b9278SJozef Kolek }
1817aa2b9278SJozef Kolek 
18186b28f09dSZoran Jovanovic static DecodeStatus DecodePOOL16BEncodedField(MCInst &Inst,
18196b28f09dSZoran Jovanovic                                               unsigned Value,
18206b28f09dSZoran Jovanovic                                               uint64_t Address,
18216b28f09dSZoran Jovanovic                                               const void *Decoder) {
18226b28f09dSZoran Jovanovic   Inst.addOperand(MCOperand::createImm(Value == 0x0 ? 8 : Value));
18236b28f09dSZoran Jovanovic   return MCDisassembler::Success;
18246b28f09dSZoran Jovanovic }
18256b28f09dSZoran Jovanovic 
1826aa2b9278SJozef Kolek static DecodeStatus DecodeSimm4(MCInst &Inst,
1827aa2b9278SJozef Kolek                                 unsigned Value,
1828aa2b9278SJozef Kolek                                 uint64_t Address,
1829aa2b9278SJozef Kolek                                 const void *Decoder) {
1830e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(SignExtend32<4>(Value)));
1831aa2b9278SJozef Kolek   return MCDisassembler::Success;
1832aa2b9278SJozef Kolek }
1833aa2b9278SJozef Kolek 
183471928e68SAkira Hatanaka static DecodeStatus DecodeSimm16(MCInst &Inst,
183571928e68SAkira Hatanaka                                  unsigned Insn,
183671928e68SAkira Hatanaka                                  uint64_t Address,
183771928e68SAkira Hatanaka                                  const void *Decoder) {
1838e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(SignExtend32<16>(Insn)));
183971928e68SAkira Hatanaka   return MCDisassembler::Success;
184071928e68SAkira Hatanaka }
184171928e68SAkira Hatanaka 
1842779c5937SMatheus Almeida static DecodeStatus DecodeLSAImm(MCInst &Inst,
1843779c5937SMatheus Almeida                                  unsigned Insn,
1844779c5937SMatheus Almeida                                  uint64_t Address,
1845779c5937SMatheus Almeida                                  const void *Decoder) {
1846779c5937SMatheus Almeida   // We add one to the immediate field as it was encoded as 'imm - 1'.
1847e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Insn + 1));
1848779c5937SMatheus Almeida   return MCDisassembler::Success;
1849779c5937SMatheus Almeida }
1850779c5937SMatheus Almeida 
185171928e68SAkira Hatanaka static DecodeStatus DecodeInsSize(MCInst &Inst,
185271928e68SAkira Hatanaka                                   unsigned Insn,
185371928e68SAkira Hatanaka                                   uint64_t Address,
185471928e68SAkira Hatanaka                                   const void *Decoder) {
185571928e68SAkira Hatanaka   // First we need to grab the pos(lsb) from MCInst.
185671928e68SAkira Hatanaka   int Pos = Inst.getOperand(2).getImm();
185771928e68SAkira Hatanaka   int Size = (int) Insn - Pos + 1;
1858e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(SignExtend32<16>(Size)));
185971928e68SAkira Hatanaka   return MCDisassembler::Success;
186071928e68SAkira Hatanaka }
186171928e68SAkira Hatanaka 
186271928e68SAkira Hatanaka static DecodeStatus DecodeExtSize(MCInst &Inst,
186371928e68SAkira Hatanaka                                   unsigned Insn,
186471928e68SAkira Hatanaka                                   uint64_t Address,
186571928e68SAkira Hatanaka                                   const void *Decoder) {
186671928e68SAkira Hatanaka   int Size = (int) Insn  + 1;
1867e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(SignExtend32<16>(Size)));
186871928e68SAkira Hatanaka   return MCDisassembler::Success;
186971928e68SAkira Hatanaka }
1870b59e1a41SDaniel Sanders 
1871b59e1a41SDaniel Sanders static DecodeStatus DecodeSimm19Lsl2(MCInst &Inst, unsigned Insn,
1872b59e1a41SDaniel Sanders                                      uint64_t Address, const void *Decoder) {
1873e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(SignExtend32<19>(Insn) * 4));
1874b59e1a41SDaniel Sanders   return MCDisassembler::Success;
1875b59e1a41SDaniel Sanders }
18762855142aSZoran Jovanovic 
18772855142aSZoran Jovanovic static DecodeStatus DecodeSimm18Lsl3(MCInst &Inst, unsigned Insn,
18782855142aSZoran Jovanovic                                      uint64_t Address, const void *Decoder) {
1879e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(SignExtend32<18>(Insn) * 8));
18802855142aSZoran Jovanovic   return MCDisassembler::Success;
18812855142aSZoran Jovanovic }
1882a4c4b5fcSZoran Jovanovic 
1883b682ddf3SVladimir Medic static DecodeStatus DecodeSimm9SP(MCInst &Inst, unsigned Insn,
1884b682ddf3SVladimir Medic                                   uint64_t Address, const void *Decoder) {
1885b682ddf3SVladimir Medic   int32_t DecodedValue;
1886b682ddf3SVladimir Medic   switch (Insn) {
1887b682ddf3SVladimir Medic   case 0: DecodedValue = 256; break;
1888b682ddf3SVladimir Medic   case 1: DecodedValue = 257; break;
1889b682ddf3SVladimir Medic   case 510: DecodedValue = -258; break;
1890b682ddf3SVladimir Medic   case 511: DecodedValue = -257; break;
1891b682ddf3SVladimir Medic   default: DecodedValue = SignExtend32<9>(Insn); break;
1892b682ddf3SVladimir Medic   }
1893e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(DecodedValue * 4));
1894b682ddf3SVladimir Medic   return MCDisassembler::Success;
1895b682ddf3SVladimir Medic }
1896b682ddf3SVladimir Medic 
1897b682ddf3SVladimir Medic static DecodeStatus DecodeANDI16Imm(MCInst &Inst, unsigned Insn,
1898b682ddf3SVladimir Medic                                     uint64_t Address, const void *Decoder) {
1899b682ddf3SVladimir Medic   // Insn must be >= 0, since it is unsigned that condition is always true.
1900b682ddf3SVladimir Medic   assert(Insn < 16);
1901b682ddf3SVladimir Medic   int32_t DecodedValues[] = {128, 1, 2, 3, 4, 7, 8, 15, 16, 31, 32, 63, 64,
1902b682ddf3SVladimir Medic                              255, 32768, 65535};
1903e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(DecodedValues[Insn]));
1904b682ddf3SVladimir Medic   return MCDisassembler::Success;
1905b682ddf3SVladimir Medic }
1906b682ddf3SVladimir Medic 
1907b682ddf3SVladimir Medic static DecodeStatus DecodeUImm5lsl2(MCInst &Inst, unsigned Insn,
1908b682ddf3SVladimir Medic                                     uint64_t Address, const void *Decoder) {
1909e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Insn << 2));
1910b682ddf3SVladimir Medic   return MCDisassembler::Success;
1911b682ddf3SVladimir Medic }
1912b682ddf3SVladimir Medic 
1913a4c4b5fcSZoran Jovanovic static DecodeStatus DecodeRegListOperand(MCInst &Inst,
1914a4c4b5fcSZoran Jovanovic                                          unsigned Insn,
1915a4c4b5fcSZoran Jovanovic                                          uint64_t Address,
1916a4c4b5fcSZoran Jovanovic                                          const void *Decoder) {
1917a4c4b5fcSZoran Jovanovic   unsigned Regs[] = {Mips::S0, Mips::S1, Mips::S2, Mips::S3, Mips::S4, Mips::S5,
1918a4c4b5fcSZoran Jovanovic                      Mips::S6, Mips::FP};
1919a4c4b5fcSZoran Jovanovic   unsigned RegNum;
1920a4c4b5fcSZoran Jovanovic 
1921a4c4b5fcSZoran Jovanovic   unsigned RegLst = fieldFromInstruction(Insn, 21, 5);
1922a4c4b5fcSZoran Jovanovic   // Empty register lists are not allowed.
1923a4c4b5fcSZoran Jovanovic   if (RegLst == 0)
1924a4c4b5fcSZoran Jovanovic     return MCDisassembler::Fail;
1925a4c4b5fcSZoran Jovanovic 
1926a4c4b5fcSZoran Jovanovic   RegNum = RegLst & 0xf;
1927a4c4b5fcSZoran Jovanovic   for (unsigned i = 0; i < RegNum; i++)
1928e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Regs[i]));
1929a4c4b5fcSZoran Jovanovic 
1930a4c4b5fcSZoran Jovanovic   if (RegLst & 0x10)
1931e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::RA));
1932a4c4b5fcSZoran Jovanovic 
1933a4c4b5fcSZoran Jovanovic   return MCDisassembler::Success;
1934a4c4b5fcSZoran Jovanovic }
1935f9a02500SZoran Jovanovic 
1936f9a02500SZoran Jovanovic static DecodeStatus DecodeRegListOperand16(MCInst &Inst, unsigned Insn,
1937f9a02500SZoran Jovanovic                                            uint64_t Address,
1938f9a02500SZoran Jovanovic                                            const void *Decoder) {
1939f9a02500SZoran Jovanovic   unsigned Regs[] = {Mips::S0, Mips::S1, Mips::S2, Mips::S3};
1940f9a02500SZoran Jovanovic   unsigned RegLst = fieldFromInstruction(Insn, 4, 2);
1941d68d424aSJozef Kolek   unsigned RegNum = RegLst & 0x3;
1942f9a02500SZoran Jovanovic 
1943d68d424aSJozef Kolek   for (unsigned i = 0; i <= RegNum; i++)
1944e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Regs[i]));
1945f9a02500SZoran Jovanovic 
1946e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Mips::RA));
1947f9a02500SZoran Jovanovic 
1948f9a02500SZoran Jovanovic   return MCDisassembler::Success;
1949f9a02500SZoran Jovanovic }
19502c6d7320SJozef Kolek 
195141688679SZoran Jovanovic static DecodeStatus DecodeMovePRegPair(MCInst &Inst, unsigned Insn,
195241688679SZoran Jovanovic                                        uint64_t Address, const void *Decoder) {
195341688679SZoran Jovanovic 
195441688679SZoran Jovanovic   unsigned RegPair = fieldFromInstruction(Insn, 7, 3);
195541688679SZoran Jovanovic 
195641688679SZoran Jovanovic   switch (RegPair) {
195741688679SZoran Jovanovic   default:
195841688679SZoran Jovanovic     return MCDisassembler::Fail;
195941688679SZoran Jovanovic   case 0:
1960e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A1));
1961e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A2));
196241688679SZoran Jovanovic     break;
196341688679SZoran Jovanovic   case 1:
1964e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A1));
1965e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A3));
196641688679SZoran Jovanovic     break;
196741688679SZoran Jovanovic   case 2:
1968e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A2));
1969e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A3));
197041688679SZoran Jovanovic     break;
197141688679SZoran Jovanovic   case 3:
1972e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A0));
1973e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::S5));
197441688679SZoran Jovanovic     break;
197541688679SZoran Jovanovic   case 4:
1976e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A0));
1977e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::S6));
197841688679SZoran Jovanovic     break;
197941688679SZoran Jovanovic   case 5:
1980e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A0));
1981e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A1));
198241688679SZoran Jovanovic     break;
198341688679SZoran Jovanovic   case 6:
1984e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A0));
1985e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A2));
198641688679SZoran Jovanovic     break;
198741688679SZoran Jovanovic   case 7:
1988e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A0));
1989e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A3));
199041688679SZoran Jovanovic     break;
199141688679SZoran Jovanovic   }
199241688679SZoran Jovanovic 
199341688679SZoran Jovanovic   return MCDisassembler::Success;
199441688679SZoran Jovanovic }
199541688679SZoran Jovanovic 
19962c6d7320SJozef Kolek static DecodeStatus DecodeSimm23Lsl2(MCInst &Inst, unsigned Insn,
19972c6d7320SJozef Kolek                                      uint64_t Address, const void *Decoder) {
19986499b5f0SJustin Bogner   Inst.addOperand(MCOperand::createImm(SignExtend32<25>(Insn << 2)));
19992c6d7320SJozef Kolek   return MCDisassembler::Success;
20002c6d7320SJozef Kolek }
2001