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 
24492db6b78SDaniel Sanders static DecodeStatus DecodeCacheOp(MCInst &Inst,
24592db6b78SDaniel Sanders                               unsigned Insn,
24692db6b78SDaniel Sanders                               uint64_t Address,
24792db6b78SDaniel Sanders                               const void *Decoder);
24892db6b78SDaniel Sanders 
249df464ae2SVladimir Medic static DecodeStatus DecodeCacheOpR6(MCInst &Inst,
250df464ae2SVladimir Medic                                     unsigned Insn,
251df464ae2SVladimir Medic                                     uint64_t Address,
252df464ae2SVladimir Medic                                     const void *Decoder);
253df464ae2SVladimir Medic 
254ab6d1cceSJozef Kolek static DecodeStatus DecodeCacheOpMM(MCInst &Inst,
255ab6d1cceSJozef Kolek                                     unsigned Insn,
256ab6d1cceSJozef Kolek                                     uint64_t Address,
257ab6d1cceSJozef Kolek                                     const void *Decoder);
258ab6d1cceSJozef Kolek 
259*9eaa30d2SZoran Jovanovic static DecodeStatus DecodeStoreEvaOpMM(MCInst &Inst,
260*9eaa30d2SZoran Jovanovic                                        unsigned Insn,
261*9eaa30d2SZoran Jovanovic                                        uint64_t Address,
262*9eaa30d2SZoran Jovanovic                                        const void *Decoder);
263*9eaa30d2SZoran Jovanovic 
264b4484d62SDaniel Sanders static DecodeStatus DecodeSyncI(MCInst &Inst,
265b4484d62SDaniel Sanders                                 unsigned Insn,
266b4484d62SDaniel Sanders                                 uint64_t Address,
267b4484d62SDaniel Sanders                                 const void *Decoder);
268b4484d62SDaniel Sanders 
269fe0bf9f6SMatheus Almeida static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn,
270fe0bf9f6SMatheus Almeida                                     uint64_t Address, const void *Decoder);
271fe0bf9f6SMatheus Almeida 
272315e7ecaSJozef Kolek static DecodeStatus DecodeMemMMImm4(MCInst &Inst,
273315e7ecaSJozef Kolek                                     unsigned Insn,
274315e7ecaSJozef Kolek                                     uint64_t Address,
275315e7ecaSJozef Kolek                                     const void *Decoder);
276315e7ecaSJozef Kolek 
27712c6982bSJozef Kolek static DecodeStatus DecodeMemMMSPImm5Lsl2(MCInst &Inst,
27812c6982bSJozef Kolek                                           unsigned Insn,
27912c6982bSJozef Kolek                                           uint64_t Address,
28012c6982bSJozef Kolek                                           const void *Decoder);
28112c6982bSJozef Kolek 
282e10a02ecSJozef Kolek static DecodeStatus DecodeMemMMGPImm7Lsl2(MCInst &Inst,
283e10a02ecSJozef Kolek                                           unsigned Insn,
284e10a02ecSJozef Kolek                                           uint64_t Address,
285e10a02ecSJozef Kolek                                           const void *Decoder);
286e10a02ecSJozef Kolek 
287d68d424aSJozef Kolek static DecodeStatus DecodeMemMMReglistImm4Lsl2(MCInst &Inst,
288d68d424aSJozef Kolek                                                unsigned Insn,
289d68d424aSJozef Kolek                                                uint64_t Address,
290d68d424aSJozef Kolek                                                const void *Decoder);
291d68d424aSJozef Kolek 
292a6593ff6SZoran Jovanovic static DecodeStatus DecodeMemMMImm9(MCInst &Inst,
293a6593ff6SZoran Jovanovic                                     unsigned Insn,
294a6593ff6SZoran Jovanovic                                     uint64_t Address,
295a6593ff6SZoran Jovanovic                                     const void *Decoder);
296a6593ff6SZoran Jovanovic 
297dde3d582SVladimir Medic static DecodeStatus DecodeMemMMImm12(MCInst &Inst,
298dde3d582SVladimir Medic                                      unsigned Insn,
299dde3d582SVladimir Medic                                      uint64_t Address,
300dde3d582SVladimir Medic                                      const void *Decoder);
301dde3d582SVladimir Medic 
302dde3d582SVladimir Medic static DecodeStatus DecodeMemMMImm16(MCInst &Inst,
303dde3d582SVladimir Medic                                      unsigned Insn,
304dde3d582SVladimir Medic                                      uint64_t Address,
305dde3d582SVladimir Medic                                      const void *Decoder);
306dde3d582SVladimir Medic 
30771928e68SAkira Hatanaka static DecodeStatus DecodeFMem(MCInst &Inst, unsigned Insn,
30871928e68SAkira Hatanaka                                uint64_t Address,
30971928e68SAkira Hatanaka                                const void *Decoder);
31071928e68SAkira Hatanaka 
31192db6b78SDaniel Sanders static DecodeStatus DecodeFMem2(MCInst &Inst, unsigned Insn,
31292db6b78SDaniel Sanders                                uint64_t Address,
31392db6b78SDaniel Sanders                                const void *Decoder);
31492db6b78SDaniel Sanders 
31592db6b78SDaniel Sanders static DecodeStatus DecodeFMem3(MCInst &Inst, unsigned Insn,
31692db6b78SDaniel Sanders                                uint64_t Address,
31792db6b78SDaniel Sanders                                const void *Decoder);
31892db6b78SDaniel Sanders 
319435cf8a4SVladimir Medic static DecodeStatus DecodeFMemCop2R6(MCInst &Inst, unsigned Insn,
320435cf8a4SVladimir Medic                                uint64_t Address,
321435cf8a4SVladimir Medic                                const void *Decoder);
322435cf8a4SVladimir Medic 
3236a803f61SDaniel Sanders static DecodeStatus DecodeSpecial3LlSc(MCInst &Inst,
3246a803f61SDaniel Sanders                                        unsigned Insn,
3256a803f61SDaniel Sanders                                        uint64_t Address,
3266a803f61SDaniel Sanders                                        const void *Decoder);
3276a803f61SDaniel Sanders 
328aa2b9278SJozef Kolek static DecodeStatus DecodeAddiur2Simm7(MCInst &Inst,
329aa2b9278SJozef Kolek                                        unsigned Value,
330aa2b9278SJozef Kolek                                        uint64_t Address,
331aa2b9278SJozef Kolek                                        const void *Decoder);
332aa2b9278SJozef Kolek 
333aa2b9278SJozef Kolek static DecodeStatus DecodeUImm6Lsl2(MCInst &Inst,
334aa2b9278SJozef Kolek                                     unsigned Value,
335aa2b9278SJozef Kolek                                     uint64_t Address,
336aa2b9278SJozef Kolek                                     const void *Decoder);
337aa2b9278SJozef Kolek 
338aa2b9278SJozef Kolek static DecodeStatus DecodeLiSimm7(MCInst &Inst,
339aa2b9278SJozef Kolek                                   unsigned Value,
340aa2b9278SJozef Kolek                                   uint64_t Address,
341aa2b9278SJozef Kolek                                   const void *Decoder);
342aa2b9278SJozef Kolek 
343aa2b9278SJozef Kolek static DecodeStatus DecodeSimm4(MCInst &Inst,
344aa2b9278SJozef Kolek                                 unsigned Value,
345aa2b9278SJozef Kolek                                 uint64_t Address,
346aa2b9278SJozef Kolek                                 const void *Decoder);
347aa2b9278SJozef Kolek 
34871928e68SAkira Hatanaka static DecodeStatus DecodeSimm16(MCInst &Inst,
34971928e68SAkira Hatanaka                                  unsigned Insn,
35071928e68SAkira Hatanaka                                  uint64_t Address,
35171928e68SAkira Hatanaka                                  const void *Decoder);
35271928e68SAkira Hatanaka 
353779c5937SMatheus Almeida // Decode the immediate field of an LSA instruction which
354779c5937SMatheus Almeida // is off by one.
355779c5937SMatheus Almeida static DecodeStatus DecodeLSAImm(MCInst &Inst,
356779c5937SMatheus Almeida                                  unsigned Insn,
357779c5937SMatheus Almeida                                  uint64_t Address,
358779c5937SMatheus Almeida                                  const void *Decoder);
359779c5937SMatheus Almeida 
36071928e68SAkira Hatanaka static DecodeStatus DecodeInsSize(MCInst &Inst,
36171928e68SAkira Hatanaka                                   unsigned Insn,
36271928e68SAkira Hatanaka                                   uint64_t Address,
36371928e68SAkira Hatanaka                                   const void *Decoder);
36471928e68SAkira Hatanaka 
36571928e68SAkira Hatanaka static DecodeStatus DecodeExtSize(MCInst &Inst,
36671928e68SAkira Hatanaka                                   unsigned Insn,
36771928e68SAkira Hatanaka                                   uint64_t Address,
36871928e68SAkira Hatanaka                                   const void *Decoder);
36971928e68SAkira Hatanaka 
370b59e1a41SDaniel Sanders static DecodeStatus DecodeSimm19Lsl2(MCInst &Inst, unsigned Insn,
371b59e1a41SDaniel Sanders                                      uint64_t Address, const void *Decoder);
372b59e1a41SDaniel Sanders 
3732855142aSZoran Jovanovic static DecodeStatus DecodeSimm18Lsl3(MCInst &Inst, unsigned Insn,
3742855142aSZoran Jovanovic                                      uint64_t Address, const void *Decoder);
3752855142aSZoran Jovanovic 
376b682ddf3SVladimir Medic static DecodeStatus DecodeSimm9SP(MCInst &Inst, unsigned Insn,
377b682ddf3SVladimir Medic                                   uint64_t Address, const void *Decoder);
378b682ddf3SVladimir Medic 
379b682ddf3SVladimir Medic static DecodeStatus DecodeANDI16Imm(MCInst &Inst, unsigned Insn,
380b682ddf3SVladimir Medic                                     uint64_t Address, const void *Decoder);
381b682ddf3SVladimir Medic 
382b682ddf3SVladimir Medic static DecodeStatus DecodeUImm5lsl2(MCInst &Inst, unsigned Insn,
383b682ddf3SVladimir Medic                                    uint64_t Address, const void *Decoder);
384b682ddf3SVladimir Medic 
3852c6d7320SJozef Kolek static DecodeStatus DecodeSimm23Lsl2(MCInst &Inst, unsigned Insn,
3862c6d7320SJozef Kolek                                      uint64_t Address, const void *Decoder);
3872c6d7320SJozef Kolek 
388b50ccf8eSDaniel Sanders /// INSVE_[BHWD] have an implicit operand that the generated decoder doesn't
389b50ccf8eSDaniel Sanders /// handle.
390b50ccf8eSDaniel Sanders template <typename InsnType>
391b50ccf8eSDaniel Sanders static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address,
392b50ccf8eSDaniel Sanders                                    const void *Decoder);
3935c582b2fSDaniel Sanders 
3945c582b2fSDaniel Sanders template <typename InsnType>
3955c582b2fSDaniel Sanders static DecodeStatus
3965c582b2fSDaniel Sanders DecodeAddiGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
3975c582b2fSDaniel Sanders                       const void *Decoder);
3985c582b2fSDaniel Sanders 
3995c582b2fSDaniel Sanders template <typename InsnType>
4005c582b2fSDaniel Sanders static DecodeStatus
4015c582b2fSDaniel Sanders DecodeDaddiGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
4025c582b2fSDaniel Sanders                        const void *Decoder);
4035c582b2fSDaniel Sanders 
4045c582b2fSDaniel Sanders template <typename InsnType>
4055c582b2fSDaniel Sanders static DecodeStatus
4065c582b2fSDaniel Sanders DecodeBlezlGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
4075c582b2fSDaniel Sanders                        const void *Decoder);
4085c582b2fSDaniel Sanders 
4095c582b2fSDaniel Sanders template <typename InsnType>
4105c582b2fSDaniel Sanders static DecodeStatus
4115c582b2fSDaniel Sanders DecodeBgtzlGroupBranch(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 DecodeBgtzGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
4175c582b2fSDaniel Sanders                       const void *Decoder);
4185c582b2fSDaniel Sanders 
41928a0ca07SZoran Jovanovic template <typename InsnType>
42028a0ca07SZoran Jovanovic static DecodeStatus
42128a0ca07SZoran Jovanovic DecodeBlezGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
42228a0ca07SZoran Jovanovic                        const void *Decoder);
42328a0ca07SZoran Jovanovic 
424a4c4b5fcSZoran Jovanovic static DecodeStatus DecodeRegListOperand(MCInst &Inst, unsigned Insn,
425a4c4b5fcSZoran Jovanovic                                          uint64_t Address,
426a4c4b5fcSZoran Jovanovic                                          const void *Decoder);
427a4c4b5fcSZoran Jovanovic 
428f9a02500SZoran Jovanovic static DecodeStatus DecodeRegListOperand16(MCInst &Inst, unsigned Insn,
429f9a02500SZoran Jovanovic                                            uint64_t Address,
430f9a02500SZoran Jovanovic                                            const void *Decoder);
431f9a02500SZoran Jovanovic 
43241688679SZoran Jovanovic static DecodeStatus DecodeMovePRegPair(MCInst &Inst, unsigned Insn,
43341688679SZoran Jovanovic                                        uint64_t Address,
43441688679SZoran Jovanovic                                        const void *Decoder);
43541688679SZoran Jovanovic 
43671928e68SAkira Hatanaka namespace llvm {
43771928e68SAkira Hatanaka extern Target TheMipselTarget, TheMipsTarget, TheMips64Target,
43871928e68SAkira Hatanaka               TheMips64elTarget;
43971928e68SAkira Hatanaka }
44071928e68SAkira Hatanaka 
44171928e68SAkira Hatanaka static MCDisassembler *createMipsDisassembler(
44271928e68SAkira Hatanaka                        const Target &T,
443a1bc0f56SLang Hames                        const MCSubtargetInfo &STI,
444a1bc0f56SLang Hames                        MCContext &Ctx) {
445a1bc0f56SLang Hames   return new MipsDisassembler(STI, Ctx, true);
44671928e68SAkira Hatanaka }
44771928e68SAkira Hatanaka 
44871928e68SAkira Hatanaka static MCDisassembler *createMipselDisassembler(
44971928e68SAkira Hatanaka                        const Target &T,
450a1bc0f56SLang Hames                        const MCSubtargetInfo &STI,
451a1bc0f56SLang Hames                        MCContext &Ctx) {
452a1bc0f56SLang Hames   return new MipsDisassembler(STI, Ctx, false);
45371928e68SAkira Hatanaka }
45471928e68SAkira Hatanaka 
45571928e68SAkira Hatanaka extern "C" void LLVMInitializeMipsDisassembler() {
45671928e68SAkira Hatanaka   // Register the disassembler.
45771928e68SAkira Hatanaka   TargetRegistry::RegisterMCDisassembler(TheMipsTarget,
45871928e68SAkira Hatanaka                                          createMipsDisassembler);
45971928e68SAkira Hatanaka   TargetRegistry::RegisterMCDisassembler(TheMipselTarget,
46071928e68SAkira Hatanaka                                          createMipselDisassembler);
46171928e68SAkira Hatanaka   TargetRegistry::RegisterMCDisassembler(TheMips64Target,
462a19216c8SDaniel Sanders                                          createMipsDisassembler);
46371928e68SAkira Hatanaka   TargetRegistry::RegisterMCDisassembler(TheMips64elTarget,
464a19216c8SDaniel Sanders                                          createMipselDisassembler);
46571928e68SAkira Hatanaka }
46671928e68SAkira Hatanaka 
46771928e68SAkira Hatanaka #include "MipsGenDisassemblerTables.inc"
46871928e68SAkira Hatanaka 
4695c582b2fSDaniel Sanders static unsigned getReg(const void *D, unsigned RC, unsigned RegNo) {
470a19216c8SDaniel Sanders   const MipsDisassembler *Dis = static_cast<const MipsDisassembler*>(D);
4715c582b2fSDaniel Sanders   const MCRegisterInfo *RegInfo = Dis->getContext().getRegisterInfo();
4725c582b2fSDaniel Sanders   return *(RegInfo->getRegClass(RC).begin() + RegNo);
4735c582b2fSDaniel Sanders }
4745c582b2fSDaniel Sanders 
475b50ccf8eSDaniel Sanders template <typename InsnType>
476b50ccf8eSDaniel Sanders static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address,
477b50ccf8eSDaniel Sanders                                    const void *Decoder) {
478b50ccf8eSDaniel Sanders   typedef DecodeStatus (*DecodeFN)(MCInst &, unsigned, uint64_t, const void *);
479b50ccf8eSDaniel Sanders   // The size of the n field depends on the element size
480b50ccf8eSDaniel Sanders   // The register class also depends on this.
481b50ccf8eSDaniel Sanders   InsnType tmp = fieldFromInstruction(insn, 17, 5);
482b50ccf8eSDaniel Sanders   unsigned NSize = 0;
483b50ccf8eSDaniel Sanders   DecodeFN RegDecoder = nullptr;
484b50ccf8eSDaniel Sanders   if ((tmp & 0x18) == 0x00) { // INSVE_B
485b50ccf8eSDaniel Sanders     NSize = 4;
486b50ccf8eSDaniel Sanders     RegDecoder = DecodeMSA128BRegisterClass;
487b50ccf8eSDaniel Sanders   } else if ((tmp & 0x1c) == 0x10) { // INSVE_H
488b50ccf8eSDaniel Sanders     NSize = 3;
489b50ccf8eSDaniel Sanders     RegDecoder = DecodeMSA128HRegisterClass;
490b50ccf8eSDaniel Sanders   } else if ((tmp & 0x1e) == 0x18) { // INSVE_W
491b50ccf8eSDaniel Sanders     NSize = 2;
492b50ccf8eSDaniel Sanders     RegDecoder = DecodeMSA128WRegisterClass;
493b50ccf8eSDaniel Sanders   } else if ((tmp & 0x1f) == 0x1c) { // INSVE_D
494b50ccf8eSDaniel Sanders     NSize = 1;
495b50ccf8eSDaniel Sanders     RegDecoder = DecodeMSA128DRegisterClass;
496b50ccf8eSDaniel Sanders   } else
497b50ccf8eSDaniel Sanders     llvm_unreachable("Invalid encoding");
498b50ccf8eSDaniel Sanders 
499b50ccf8eSDaniel Sanders   assert(NSize != 0 && RegDecoder != nullptr);
500b50ccf8eSDaniel Sanders 
501b50ccf8eSDaniel Sanders   // $wd
502b50ccf8eSDaniel Sanders   tmp = fieldFromInstruction(insn, 6, 5);
503b50ccf8eSDaniel Sanders   if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
504b50ccf8eSDaniel Sanders     return MCDisassembler::Fail;
505b50ccf8eSDaniel Sanders   // $wd_in
506b50ccf8eSDaniel Sanders   if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
507b50ccf8eSDaniel Sanders     return MCDisassembler::Fail;
508b50ccf8eSDaniel Sanders   // $n
509b50ccf8eSDaniel Sanders   tmp = fieldFromInstruction(insn, 16, NSize);
510e9119e41SJim Grosbach   MI.addOperand(MCOperand::createImm(tmp));
511b50ccf8eSDaniel Sanders   // $ws
512b50ccf8eSDaniel Sanders   tmp = fieldFromInstruction(insn, 11, 5);
513b50ccf8eSDaniel Sanders   if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
514b50ccf8eSDaniel Sanders     return MCDisassembler::Fail;
515b50ccf8eSDaniel Sanders   // $n2
516e9119e41SJim Grosbach   MI.addOperand(MCOperand::createImm(0));
517b50ccf8eSDaniel Sanders 
518b50ccf8eSDaniel Sanders   return MCDisassembler::Success;
519b50ccf8eSDaniel Sanders }
520b50ccf8eSDaniel Sanders 
5215c582b2fSDaniel Sanders template <typename InsnType>
5225c582b2fSDaniel Sanders static DecodeStatus DecodeAddiGroupBranch(MCInst &MI, InsnType insn,
5235c582b2fSDaniel Sanders                                           uint64_t Address,
5245c582b2fSDaniel Sanders                                           const void *Decoder) {
5255c582b2fSDaniel Sanders   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
5265c582b2fSDaniel Sanders   // (otherwise we would have matched the ADDI instruction from the earlier
5275c582b2fSDaniel Sanders   // ISA's instead).
5285c582b2fSDaniel Sanders   //
5295c582b2fSDaniel Sanders   // We have:
5305c582b2fSDaniel Sanders   //    0b001000 sssss ttttt iiiiiiiiiiiiiiii
5315c582b2fSDaniel Sanders   //      BOVC if rs >= rt
5325c582b2fSDaniel Sanders   //      BEQZALC if rs == 0 && rt != 0
5335c582b2fSDaniel Sanders   //      BEQC if rs < rt && rs != 0
5345c582b2fSDaniel Sanders 
5355c582b2fSDaniel Sanders   InsnType Rs = fieldFromInstruction(insn, 21, 5);
5365c582b2fSDaniel Sanders   InsnType Rt = fieldFromInstruction(insn, 16, 5);
537d37bab61SAlexey Samsonov   InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4;
5385c582b2fSDaniel Sanders   bool HasRs = false;
5395c582b2fSDaniel Sanders 
5405c582b2fSDaniel Sanders   if (Rs >= Rt) {
5415c582b2fSDaniel Sanders     MI.setOpcode(Mips::BOVC);
5425c582b2fSDaniel Sanders     HasRs = true;
5435c582b2fSDaniel Sanders   } else if (Rs != 0 && Rs < Rt) {
5445c582b2fSDaniel Sanders     MI.setOpcode(Mips::BEQC);
5455c582b2fSDaniel Sanders     HasRs = true;
5465c582b2fSDaniel Sanders   } else
5475c582b2fSDaniel Sanders     MI.setOpcode(Mips::BEQZALC);
5485c582b2fSDaniel Sanders 
5495c582b2fSDaniel Sanders   if (HasRs)
550e9119e41SJim Grosbach     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
5515c582b2fSDaniel Sanders                                        Rs)));
5525c582b2fSDaniel Sanders 
553e9119e41SJim Grosbach   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
5545c582b2fSDaniel Sanders                                      Rt)));
555e9119e41SJim Grosbach   MI.addOperand(MCOperand::createImm(Imm));
5565c582b2fSDaniel Sanders 
5575c582b2fSDaniel Sanders   return MCDisassembler::Success;
5585c582b2fSDaniel Sanders }
5595c582b2fSDaniel Sanders 
5605c582b2fSDaniel Sanders template <typename InsnType>
5615c582b2fSDaniel Sanders static DecodeStatus DecodeDaddiGroupBranch(MCInst &MI, InsnType insn,
5625c582b2fSDaniel Sanders                                            uint64_t Address,
5635c582b2fSDaniel Sanders                                            const void *Decoder) {
5645c582b2fSDaniel Sanders   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
5655c582b2fSDaniel Sanders   // (otherwise we would have matched the ADDI instruction from the earlier
5665c582b2fSDaniel Sanders   // ISA's instead).
5675c582b2fSDaniel Sanders   //
5685c582b2fSDaniel Sanders   // We have:
5695c582b2fSDaniel Sanders   //    0b011000 sssss ttttt iiiiiiiiiiiiiiii
5705c582b2fSDaniel Sanders   //      BNVC if rs >= rt
5715c582b2fSDaniel Sanders   //      BNEZALC if rs == 0 && rt != 0
5725c582b2fSDaniel Sanders   //      BNEC if rs < rt && rs != 0
5735c582b2fSDaniel Sanders 
5745c582b2fSDaniel Sanders   InsnType Rs = fieldFromInstruction(insn, 21, 5);
5755c582b2fSDaniel Sanders   InsnType Rt = fieldFromInstruction(insn, 16, 5);
576d37bab61SAlexey Samsonov   InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4;
5775c582b2fSDaniel Sanders   bool HasRs = false;
5785c582b2fSDaniel Sanders 
5795c582b2fSDaniel Sanders   if (Rs >= Rt) {
5805c582b2fSDaniel Sanders     MI.setOpcode(Mips::BNVC);
5815c582b2fSDaniel Sanders     HasRs = true;
5825c582b2fSDaniel Sanders   } else if (Rs != 0 && Rs < Rt) {
5835c582b2fSDaniel Sanders     MI.setOpcode(Mips::BNEC);
5845c582b2fSDaniel Sanders     HasRs = true;
5855c582b2fSDaniel Sanders   } else
5865c582b2fSDaniel Sanders     MI.setOpcode(Mips::BNEZALC);
5875c582b2fSDaniel Sanders 
5885c582b2fSDaniel Sanders   if (HasRs)
589e9119e41SJim Grosbach     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
5905c582b2fSDaniel Sanders                                        Rs)));
5915c582b2fSDaniel Sanders 
592e9119e41SJim Grosbach   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
5935c582b2fSDaniel Sanders                                      Rt)));
594e9119e41SJim Grosbach   MI.addOperand(MCOperand::createImm(Imm));
5955c582b2fSDaniel Sanders 
5965c582b2fSDaniel Sanders   return MCDisassembler::Success;
5975c582b2fSDaniel Sanders }
5985c582b2fSDaniel Sanders 
5995c582b2fSDaniel Sanders template <typename InsnType>
6005c582b2fSDaniel Sanders static DecodeStatus DecodeBlezlGroupBranch(MCInst &MI, InsnType insn,
6015c582b2fSDaniel Sanders                                            uint64_t Address,
6025c582b2fSDaniel Sanders                                            const void *Decoder) {
6035c582b2fSDaniel Sanders   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
6045c582b2fSDaniel Sanders   // (otherwise we would have matched the BLEZL instruction from the earlier
6055c582b2fSDaniel Sanders   // ISA's instead).
6065c582b2fSDaniel Sanders   //
6075c582b2fSDaniel Sanders   // We have:
6085c582b2fSDaniel Sanders   //    0b010110 sssss ttttt iiiiiiiiiiiiiiii
6095c582b2fSDaniel Sanders   //      Invalid if rs == 0
6105c582b2fSDaniel Sanders   //      BLEZC   if rs == 0  && rt != 0
6115c582b2fSDaniel Sanders   //      BGEZC   if rs == rt && rt != 0
6125c582b2fSDaniel Sanders   //      BGEC    if rs != rt && rs != 0  && rt != 0
6135c582b2fSDaniel Sanders 
6145c582b2fSDaniel Sanders   InsnType Rs = fieldFromInstruction(insn, 21, 5);
6155c582b2fSDaniel Sanders   InsnType Rt = fieldFromInstruction(insn, 16, 5);
616d37bab61SAlexey Samsonov   InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4;
61728a0ca07SZoran Jovanovic   bool HasRs = false;
6185c582b2fSDaniel Sanders 
6195c582b2fSDaniel Sanders   if (Rt == 0)
6205c582b2fSDaniel Sanders     return MCDisassembler::Fail;
6215c582b2fSDaniel Sanders   else if (Rs == 0)
6225c582b2fSDaniel Sanders     MI.setOpcode(Mips::BLEZC);
6235c582b2fSDaniel Sanders   else if (Rs == Rt)
6245c582b2fSDaniel Sanders     MI.setOpcode(Mips::BGEZC);
62528a0ca07SZoran Jovanovic   else {
62628a0ca07SZoran Jovanovic     HasRs = true;
62728a0ca07SZoran Jovanovic     MI.setOpcode(Mips::BGEC);
62828a0ca07SZoran Jovanovic   }
62928a0ca07SZoran Jovanovic 
63028a0ca07SZoran Jovanovic   if (HasRs)
631e9119e41SJim Grosbach     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
63228a0ca07SZoran Jovanovic                                        Rs)));
6335c582b2fSDaniel Sanders 
634e9119e41SJim Grosbach   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
6355c582b2fSDaniel Sanders                                      Rt)));
6365c582b2fSDaniel Sanders 
637e9119e41SJim Grosbach   MI.addOperand(MCOperand::createImm(Imm));
6385c582b2fSDaniel Sanders 
6395c582b2fSDaniel Sanders   return MCDisassembler::Success;
6405c582b2fSDaniel Sanders }
6415c582b2fSDaniel Sanders 
6425c582b2fSDaniel Sanders template <typename InsnType>
6435c582b2fSDaniel Sanders static DecodeStatus DecodeBgtzlGroupBranch(MCInst &MI, InsnType insn,
6445c582b2fSDaniel Sanders                                            uint64_t Address,
6455c582b2fSDaniel Sanders                                            const void *Decoder) {
6465c582b2fSDaniel Sanders   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
6475c582b2fSDaniel Sanders   // (otherwise we would have matched the BGTZL instruction from the earlier
6485c582b2fSDaniel Sanders   // ISA's instead).
6495c582b2fSDaniel Sanders   //
6505c582b2fSDaniel Sanders   // We have:
6515c582b2fSDaniel Sanders   //    0b010111 sssss ttttt iiiiiiiiiiiiiiii
6525c582b2fSDaniel Sanders   //      Invalid if rs == 0
6535c582b2fSDaniel Sanders   //      BGTZC   if rs == 0  && rt != 0
6545c582b2fSDaniel Sanders   //      BLTZC   if rs == rt && rt != 0
6555c582b2fSDaniel Sanders   //      BLTC    if rs != rt && rs != 0  && rt != 0
6565c582b2fSDaniel Sanders 
6575c14b069SZoran Jovanovic   bool HasRs = false;
6585c14b069SZoran Jovanovic 
6595c582b2fSDaniel Sanders   InsnType Rs = fieldFromInstruction(insn, 21, 5);
6605c582b2fSDaniel Sanders   InsnType Rt = fieldFromInstruction(insn, 16, 5);
661d37bab61SAlexey Samsonov   InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4;
6625c582b2fSDaniel Sanders 
6635c582b2fSDaniel Sanders   if (Rt == 0)
6645c582b2fSDaniel Sanders     return MCDisassembler::Fail;
6655c582b2fSDaniel Sanders   else if (Rs == 0)
6665c582b2fSDaniel Sanders     MI.setOpcode(Mips::BGTZC);
6675c582b2fSDaniel Sanders   else if (Rs == Rt)
6685c582b2fSDaniel Sanders     MI.setOpcode(Mips::BLTZC);
6695c14b069SZoran Jovanovic   else {
6705c14b069SZoran Jovanovic     MI.setOpcode(Mips::BLTC);
6715c14b069SZoran Jovanovic     HasRs = true;
6725c14b069SZoran Jovanovic   }
6735c14b069SZoran Jovanovic 
6745c14b069SZoran Jovanovic   if (HasRs)
675e9119e41SJim Grosbach     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
6765c14b069SZoran Jovanovic                                               Rs)));
6775c582b2fSDaniel Sanders 
678e9119e41SJim Grosbach   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
6795c582b2fSDaniel Sanders                                      Rt)));
6805c582b2fSDaniel Sanders 
681e9119e41SJim Grosbach   MI.addOperand(MCOperand::createImm(Imm));
6825c582b2fSDaniel Sanders 
6835c582b2fSDaniel Sanders   return MCDisassembler::Success;
6845c582b2fSDaniel Sanders }
6855c582b2fSDaniel Sanders 
6865c582b2fSDaniel Sanders template <typename InsnType>
6875c582b2fSDaniel Sanders static DecodeStatus DecodeBgtzGroupBranch(MCInst &MI, InsnType insn,
6885c582b2fSDaniel Sanders                                           uint64_t Address,
6895c582b2fSDaniel Sanders                                           const void *Decoder) {
6905c582b2fSDaniel Sanders   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
6915c582b2fSDaniel Sanders   // (otherwise we would have matched the BGTZ instruction from the earlier
6925c582b2fSDaniel Sanders   // ISA's instead).
6935c582b2fSDaniel Sanders   //
6945c582b2fSDaniel Sanders   // We have:
6955c582b2fSDaniel Sanders   //    0b000111 sssss ttttt iiiiiiiiiiiiiiii
6965c582b2fSDaniel Sanders   //      BGTZ    if rt == 0
6975c582b2fSDaniel Sanders   //      BGTZALC if rs == 0 && rt != 0
6985c582b2fSDaniel Sanders   //      BLTZALC if rs != 0 && rs == rt
6995c582b2fSDaniel Sanders   //      BLTUC   if rs != 0 && rs != rt
7005c582b2fSDaniel Sanders 
7015c582b2fSDaniel Sanders   InsnType Rs = fieldFromInstruction(insn, 21, 5);
7025c582b2fSDaniel Sanders   InsnType Rt = fieldFromInstruction(insn, 16, 5);
703d37bab61SAlexey Samsonov   InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4;
7045c582b2fSDaniel Sanders   bool HasRs = false;
7055c582b2fSDaniel Sanders   bool HasRt = false;
7065c582b2fSDaniel Sanders 
7075c582b2fSDaniel Sanders   if (Rt == 0) {
7085c582b2fSDaniel Sanders     MI.setOpcode(Mips::BGTZ);
7095c582b2fSDaniel Sanders     HasRs = true;
7105c582b2fSDaniel Sanders   } else if (Rs == 0) {
7115c582b2fSDaniel Sanders     MI.setOpcode(Mips::BGTZALC);
7125c582b2fSDaniel Sanders     HasRt = true;
7135c582b2fSDaniel Sanders   } else if (Rs == Rt) {
7145c582b2fSDaniel Sanders     MI.setOpcode(Mips::BLTZALC);
7155c582b2fSDaniel Sanders     HasRs = true;
7165c14b069SZoran Jovanovic   } else {
7175c14b069SZoran Jovanovic     MI.setOpcode(Mips::BLTUC);
7185c14b069SZoran Jovanovic     HasRs = true;
7195c14b069SZoran Jovanovic     HasRt = true;
7205c14b069SZoran Jovanovic   }
7215c582b2fSDaniel Sanders 
7225c582b2fSDaniel Sanders   if (HasRs)
723e9119e41SJim Grosbach     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
7245c582b2fSDaniel Sanders                                        Rs)));
7255c582b2fSDaniel Sanders 
7265c582b2fSDaniel Sanders   if (HasRt)
727e9119e41SJim Grosbach     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
7285c582b2fSDaniel Sanders                                        Rt)));
7295c582b2fSDaniel Sanders 
730e9119e41SJim Grosbach   MI.addOperand(MCOperand::createImm(Imm));
7315c582b2fSDaniel Sanders 
7325c582b2fSDaniel Sanders   return MCDisassembler::Success;
7335c582b2fSDaniel Sanders }
7345c582b2fSDaniel Sanders 
73528a0ca07SZoran Jovanovic template <typename InsnType>
73628a0ca07SZoran Jovanovic static DecodeStatus DecodeBlezGroupBranch(MCInst &MI, InsnType insn,
73728a0ca07SZoran Jovanovic                                            uint64_t Address,
73828a0ca07SZoran Jovanovic                                            const void *Decoder) {
73928a0ca07SZoran Jovanovic   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
74028a0ca07SZoran Jovanovic   // (otherwise we would have matched the BLEZL instruction from the earlier
74128a0ca07SZoran Jovanovic   // ISA's instead).
74228a0ca07SZoran Jovanovic   //
74328a0ca07SZoran Jovanovic   // We have:
74428a0ca07SZoran Jovanovic   //    0b000110 sssss ttttt iiiiiiiiiiiiiiii
74528a0ca07SZoran Jovanovic   //      Invalid   if rs == 0
74628a0ca07SZoran Jovanovic   //      BLEZALC   if rs == 0  && rt != 0
74728a0ca07SZoran Jovanovic   //      BGEZALC   if rs == rt && rt != 0
74828a0ca07SZoran Jovanovic   //      BGEUC     if rs != rt && rs != 0  && rt != 0
74928a0ca07SZoran Jovanovic 
75028a0ca07SZoran Jovanovic   InsnType Rs = fieldFromInstruction(insn, 21, 5);
75128a0ca07SZoran Jovanovic   InsnType Rt = fieldFromInstruction(insn, 16, 5);
752d37bab61SAlexey Samsonov   InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4;
75328a0ca07SZoran Jovanovic   bool HasRs = false;
75428a0ca07SZoran Jovanovic 
75528a0ca07SZoran Jovanovic   if (Rt == 0)
75628a0ca07SZoran Jovanovic     return MCDisassembler::Fail;
75728a0ca07SZoran Jovanovic   else if (Rs == 0)
75828a0ca07SZoran Jovanovic     MI.setOpcode(Mips::BLEZALC);
75928a0ca07SZoran Jovanovic   else if (Rs == Rt)
76028a0ca07SZoran Jovanovic     MI.setOpcode(Mips::BGEZALC);
76128a0ca07SZoran Jovanovic   else {
76228a0ca07SZoran Jovanovic     HasRs = true;
76328a0ca07SZoran Jovanovic     MI.setOpcode(Mips::BGEUC);
76428a0ca07SZoran Jovanovic   }
76528a0ca07SZoran Jovanovic 
76628a0ca07SZoran Jovanovic   if (HasRs)
767e9119e41SJim Grosbach     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
76828a0ca07SZoran Jovanovic                                        Rs)));
769e9119e41SJim Grosbach   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
77028a0ca07SZoran Jovanovic                                      Rt)));
77128a0ca07SZoran Jovanovic 
772e9119e41SJim Grosbach   MI.addOperand(MCOperand::createImm(Imm));
77328a0ca07SZoran Jovanovic 
77428a0ca07SZoran Jovanovic   return MCDisassembler::Success;
77528a0ca07SZoran Jovanovic }
77628a0ca07SZoran Jovanovic 
777ea22c4cfSJozef Kolek /// Read two bytes from the ArrayRef and return 16 bit halfword sorted
778ea22c4cfSJozef Kolek /// according to the given endianess.
779ea22c4cfSJozef Kolek static DecodeStatus readInstruction16(ArrayRef<uint8_t> Bytes, uint64_t Address,
780ea22c4cfSJozef Kolek                                       uint64_t &Size, uint32_t &Insn,
781ea22c4cfSJozef Kolek                                       bool IsBigEndian) {
782ea22c4cfSJozef Kolek   // We want to read exactly 2 Bytes of data.
783ea22c4cfSJozef Kolek   if (Bytes.size() < 2) {
784ea22c4cfSJozef Kolek     Size = 0;
785ea22c4cfSJozef Kolek     return MCDisassembler::Fail;
786ea22c4cfSJozef Kolek   }
787ea22c4cfSJozef Kolek 
788ea22c4cfSJozef Kolek   if (IsBigEndian) {
789ea22c4cfSJozef Kolek     Insn = (Bytes[0] << 8) | Bytes[1];
790ea22c4cfSJozef Kolek   } else {
791ea22c4cfSJozef Kolek     Insn = (Bytes[1] << 8) | Bytes[0];
792ea22c4cfSJozef Kolek   }
793ea22c4cfSJozef Kolek 
794ea22c4cfSJozef Kolek   return MCDisassembler::Success;
795ea22c4cfSJozef Kolek }
796ea22c4cfSJozef Kolek 
7977fc5b874SRafael Espindola /// Read four bytes from the ArrayRef and return 32 bit word sorted
7984aa6bea7SRafael Espindola /// according to the given endianess
7997fc5b874SRafael Espindola static DecodeStatus readInstruction32(ArrayRef<uint8_t> Bytes, uint64_t Address,
8007fc5b874SRafael Espindola                                       uint64_t &Size, uint32_t &Insn,
8017fc5b874SRafael Espindola                                       bool IsBigEndian, bool IsMicroMips) {
80271928e68SAkira Hatanaka   // We want to read exactly 4 Bytes of data.
8037fc5b874SRafael Espindola   if (Bytes.size() < 4) {
8044aa6bea7SRafael Espindola     Size = 0;
80571928e68SAkira Hatanaka     return MCDisassembler::Fail;
80671928e68SAkira Hatanaka   }
80771928e68SAkira Hatanaka 
808ea22c4cfSJozef Kolek   // High 16 bits of a 32-bit microMIPS instruction (where the opcode is)
809ea22c4cfSJozef Kolek   // always precede the low 16 bits in the instruction stream (that is, they
810ea22c4cfSJozef Kolek   // are placed at lower addresses in the instruction stream).
811ea22c4cfSJozef Kolek   //
812ea22c4cfSJozef Kolek   // microMIPS byte ordering:
813ea22c4cfSJozef Kolek   //   Big-endian:    0 | 1 | 2 | 3
814ea22c4cfSJozef Kolek   //   Little-endian: 1 | 0 | 3 | 2
815ea22c4cfSJozef Kolek 
8164aa6bea7SRafael Espindola   if (IsBigEndian) {
81771928e68SAkira Hatanaka     // Encoded as a big-endian 32-bit word in the stream.
8184aa6bea7SRafael Espindola     Insn =
8194aa6bea7SRafael Espindola         (Bytes[3] << 0) | (Bytes[2] << 8) | (Bytes[1] << 16) | (Bytes[0] << 24);
8204aa6bea7SRafael Espindola   } else {
821dde3d582SVladimir Medic     if (IsMicroMips) {
8224aa6bea7SRafael Espindola       Insn = (Bytes[2] << 0) | (Bytes[3] << 8) | (Bytes[0] << 16) |
823dde3d582SVladimir Medic              (Bytes[1] << 24);
824dde3d582SVladimir Medic     } else {
8254aa6bea7SRafael Espindola       Insn = (Bytes[0] << 0) | (Bytes[1] << 8) | (Bytes[2] << 16) |
82671928e68SAkira Hatanaka              (Bytes[3] << 24);
82771928e68SAkira Hatanaka     }
828dde3d582SVladimir Medic   }
82971928e68SAkira Hatanaka 
83071928e68SAkira Hatanaka   return MCDisassembler::Success;
83171928e68SAkira Hatanaka }
83271928e68SAkira Hatanaka 
8334aa6bea7SRafael Espindola DecodeStatus MipsDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,
8347fc5b874SRafael Espindola                                               ArrayRef<uint8_t> Bytes,
83571928e68SAkira Hatanaka                                               uint64_t Address,
8364aa6bea7SRafael Espindola                                               raw_ostream &VStream,
8374aa6bea7SRafael Espindola                                               raw_ostream &CStream) const {
83871928e68SAkira Hatanaka   uint32_t Insn;
839ea22c4cfSJozef Kolek   DecodeStatus Result;
84071928e68SAkira Hatanaka 
841ea22c4cfSJozef Kolek   if (IsMicroMips) {
842ea22c4cfSJozef Kolek     Result = readInstruction16(Bytes, Address, Size, Insn, IsBigEndian);
843ea22c4cfSJozef Kolek 
844ada70918SZoran Jovanovic     if (hasMips32r6()) {
845ada70918SZoran Jovanovic       DEBUG(dbgs() << "Trying MicroMipsR616 table (16-bit instructions):\n");
846ada70918SZoran Jovanovic       // Calling the auto-generated decoder function for microMIPS32R6
847ada70918SZoran Jovanovic       // (and microMIPS64R6) 16-bit instructions.
848ada70918SZoran Jovanovic       Result = decodeInstruction(DecoderTableMicroMipsR616, Instr, Insn,
849ada70918SZoran Jovanovic                                  Address, this, STI);
850ada70918SZoran Jovanovic       if (Result != MCDisassembler::Fail) {
851ada70918SZoran Jovanovic         Size = 2;
852ada70918SZoran Jovanovic         return Result;
853ada70918SZoran Jovanovic       }
854ada70918SZoran Jovanovic     }
855ada70918SZoran Jovanovic 
856ea22c4cfSJozef Kolek     DEBUG(dbgs() << "Trying MicroMips16 table (16-bit instructions):\n");
857ada70918SZoran Jovanovic     // Calling the auto-generated decoder function for microMIPS 16-bit
858ada70918SZoran Jovanovic     // instructions.
859ea22c4cfSJozef Kolek     Result = decodeInstruction(DecoderTableMicroMips16, Instr, Insn, Address,
860ea22c4cfSJozef Kolek                                this, STI);
861ea22c4cfSJozef Kolek     if (Result != MCDisassembler::Fail) {
862ea22c4cfSJozef Kolek       Size = 2;
863ea22c4cfSJozef Kolek       return Result;
864ea22c4cfSJozef Kolek     }
865ea22c4cfSJozef Kolek 
866ea22c4cfSJozef Kolek     Result = readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, true);
86771928e68SAkira Hatanaka     if (Result == MCDisassembler::Fail)
86871928e68SAkira Hatanaka       return MCDisassembler::Fail;
86971928e68SAkira Hatanaka 
870676d6012SJozef Kolek     if (hasMips32r6()) {
871676d6012SJozef Kolek       DEBUG(dbgs() << "Trying MicroMips32r632 table (32-bit instructions):\n");
872676d6012SJozef Kolek       // Calling the auto-generated decoder function.
873366783e1SZoran Jovanovic       Result = decodeInstruction(DecoderTableMicroMipsR632, Instr, Insn, Address,
874676d6012SJozef Kolek                                  this, STI);
875ada70918SZoran Jovanovic       if (Result != MCDisassembler::Fail) {
876ada70918SZoran Jovanovic         Size = 4;
877ada70918SZoran Jovanovic         return Result;
878ada70918SZoran Jovanovic       }
879ada70918SZoran Jovanovic     }
880ada70918SZoran Jovanovic 
881ea22c4cfSJozef Kolek     DEBUG(dbgs() << "Trying MicroMips32 table (32-bit instructions):\n");
882dde3d582SVladimir Medic     // Calling the auto-generated decoder function.
8834aa6bea7SRafael Espindola     Result = decodeInstruction(DecoderTableMicroMips32, Instr, Insn, Address,
884dde3d582SVladimir Medic                                this, STI);
885dde3d582SVladimir Medic     if (Result != MCDisassembler::Fail) {
886dde3d582SVladimir Medic       Size = 4;
887dde3d582SVladimir Medic       return Result;
888dde3d582SVladimir Medic     }
889dde3d582SVladimir Medic     return MCDisassembler::Fail;
890dde3d582SVladimir Medic   }
891dde3d582SVladimir Medic 
892ea22c4cfSJozef Kolek   Result = readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, false);
893ea22c4cfSJozef Kolek   if (Result == MCDisassembler::Fail)
894ea22c4cfSJozef Kolek     return MCDisassembler::Fail;
895ea22c4cfSJozef Kolek 
896c171f65aSDaniel Sanders   if (hasCOP3()) {
897c171f65aSDaniel Sanders     DEBUG(dbgs() << "Trying COP3_ table (32-bit opcodes):\n");
898c171f65aSDaniel Sanders     Result =
8994aa6bea7SRafael Espindola         decodeInstruction(DecoderTableCOP3_32, Instr, Insn, Address, this, STI);
900c171f65aSDaniel Sanders     if (Result != MCDisassembler::Fail) {
901c171f65aSDaniel Sanders       Size = 4;
902c171f65aSDaniel Sanders       return Result;
903c171f65aSDaniel Sanders     }
904c171f65aSDaniel Sanders   }
905c171f65aSDaniel Sanders 
906c171f65aSDaniel Sanders   if (hasMips32r6() && isGP64()) {
9070fa60416SDaniel Sanders     DEBUG(dbgs() << "Trying Mips32r6_64r6 (GPR64) table (32-bit opcodes):\n");
9084aa6bea7SRafael Espindola     Result = decodeInstruction(DecoderTableMips32r6_64r6_GP6432, Instr, Insn,
9090fa60416SDaniel Sanders                                Address, this, STI);
9100fa60416SDaniel Sanders     if (Result != MCDisassembler::Fail) {
9110fa60416SDaniel Sanders       Size = 4;
9120fa60416SDaniel Sanders       return Result;
9130fa60416SDaniel Sanders     }
9140fa60416SDaniel Sanders   }
9150fa60416SDaniel Sanders 
916c171f65aSDaniel Sanders   if (hasMips32r6()) {
9170fa60416SDaniel Sanders     DEBUG(dbgs() << "Trying Mips32r6_64r6 table (32-bit opcodes):\n");
9184aa6bea7SRafael Espindola     Result = decodeInstruction(DecoderTableMips32r6_64r632, Instr, Insn,
9195c582b2fSDaniel Sanders                                Address, this, STI);
9205c582b2fSDaniel Sanders     if (Result != MCDisassembler::Fail) {
9215c582b2fSDaniel Sanders       Size = 4;
9225c582b2fSDaniel Sanders       return Result;
9235c582b2fSDaniel Sanders     }
9245c582b2fSDaniel Sanders   }
9255c582b2fSDaniel Sanders 
9263adf9b8dSKai Nacke   if (hasCnMips()) {
9273adf9b8dSKai Nacke     DEBUG(dbgs() << "Trying CnMips table (32-bit opcodes):\n");
9283adf9b8dSKai Nacke     Result = decodeInstruction(DecoderTableCnMips32, Instr, Insn,
9293adf9b8dSKai Nacke                                Address, this, STI);
9303adf9b8dSKai Nacke     if (Result != MCDisassembler::Fail) {
9313adf9b8dSKai Nacke       Size = 4;
9323adf9b8dSKai Nacke       return Result;
9333adf9b8dSKai Nacke     }
9343adf9b8dSKai Nacke   }
9353adf9b8dSKai Nacke 
936a19216c8SDaniel Sanders   if (isGP64()) {
937a19216c8SDaniel Sanders     DEBUG(dbgs() << "Trying Mips64 (GPR64) table (32-bit opcodes):\n");
938a19216c8SDaniel Sanders     Result = decodeInstruction(DecoderTableMips6432, Instr, Insn,
939a19216c8SDaniel Sanders                                Address, this, STI);
940a19216c8SDaniel Sanders     if (Result != MCDisassembler::Fail) {
941a19216c8SDaniel Sanders       Size = 4;
942a19216c8SDaniel Sanders       return Result;
943a19216c8SDaniel Sanders     }
944a19216c8SDaniel Sanders   }
945a19216c8SDaniel Sanders 
9460fa60416SDaniel Sanders   DEBUG(dbgs() << "Trying Mips table (32-bit opcodes):\n");
94771928e68SAkira Hatanaka   // Calling the auto-generated decoder function.
9484aa6bea7SRafael Espindola   Result =
9494aa6bea7SRafael Espindola       decodeInstruction(DecoderTableMips32, Instr, Insn, Address, this, STI);
95071928e68SAkira Hatanaka   if (Result != MCDisassembler::Fail) {
95171928e68SAkira Hatanaka     Size = 4;
95271928e68SAkira Hatanaka     return Result;
95371928e68SAkira Hatanaka   }
95471928e68SAkira Hatanaka 
95571928e68SAkira Hatanaka   return MCDisassembler::Fail;
95671928e68SAkira Hatanaka }
95771928e68SAkira Hatanaka 
958ec8a5490SReed Kotler static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst,
959ec8a5490SReed Kotler                                                  unsigned RegNo,
960ec8a5490SReed Kotler                                                  uint64_t Address,
961ec8a5490SReed Kotler                                                  const void *Decoder) {
962ec8a5490SReed Kotler 
963ec8a5490SReed Kotler   return MCDisassembler::Fail;
964ec8a5490SReed Kotler 
965ec8a5490SReed Kotler }
966ec8a5490SReed Kotler 
96713e6ccf3SAkira Hatanaka static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst,
96871928e68SAkira Hatanaka                                              unsigned RegNo,
96971928e68SAkira Hatanaka                                              uint64_t Address,
97071928e68SAkira Hatanaka                                              const void *Decoder) {
97171928e68SAkira Hatanaka 
97271928e68SAkira Hatanaka   if (RegNo > 31)
97371928e68SAkira Hatanaka     return MCDisassembler::Fail;
97471928e68SAkira Hatanaka 
97513e6ccf3SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::GPR64RegClassID, RegNo);
976e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
97771928e68SAkira Hatanaka   return MCDisassembler::Success;
97871928e68SAkira Hatanaka }
97971928e68SAkira Hatanaka 
980b0852e54SZoran Jovanovic static DecodeStatus DecodeGPRMM16RegisterClass(MCInst &Inst,
981b0852e54SZoran Jovanovic                                                unsigned RegNo,
982b0852e54SZoran Jovanovic                                                uint64_t Address,
983b0852e54SZoran Jovanovic                                                const void *Decoder) {
984ea22c4cfSJozef Kolek   if (RegNo > 7)
985b0852e54SZoran Jovanovic     return MCDisassembler::Fail;
986ea22c4cfSJozef Kolek   unsigned Reg = getReg(Decoder, Mips::GPRMM16RegClassID, RegNo);
987e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
988ea22c4cfSJozef Kolek   return MCDisassembler::Success;
989b0852e54SZoran Jovanovic }
990b0852e54SZoran Jovanovic 
9911904fa21SJozef Kolek static DecodeStatus DecodeGPRMM16ZeroRegisterClass(MCInst &Inst,
9921904fa21SJozef Kolek                                                    unsigned RegNo,
9931904fa21SJozef Kolek                                                    uint64_t Address,
9941904fa21SJozef Kolek                                                    const void *Decoder) {
995315e7ecaSJozef Kolek   if (RegNo > 7)
9961904fa21SJozef Kolek     return MCDisassembler::Fail;
997315e7ecaSJozef Kolek   unsigned Reg = getReg(Decoder, Mips::GPRMM16ZeroRegClassID, RegNo);
998e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
999315e7ecaSJozef Kolek   return MCDisassembler::Success;
10001904fa21SJozef Kolek }
10011904fa21SJozef Kolek 
100241688679SZoran Jovanovic static DecodeStatus DecodeGPRMM16MovePRegisterClass(MCInst &Inst,
100341688679SZoran Jovanovic                                                     unsigned RegNo,
100441688679SZoran Jovanovic                                                     uint64_t Address,
100541688679SZoran Jovanovic                                                     const void *Decoder) {
100641688679SZoran Jovanovic   if (RegNo > 7)
100741688679SZoran Jovanovic     return MCDisassembler::Fail;
100841688679SZoran Jovanovic   unsigned Reg = getReg(Decoder, Mips::GPRMM16MovePRegClassID, RegNo);
1009e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
101041688679SZoran Jovanovic   return MCDisassembler::Success;
101141688679SZoran Jovanovic }
101241688679SZoran Jovanovic 
101313e6ccf3SAkira Hatanaka static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst,
101471928e68SAkira Hatanaka                                              unsigned RegNo,
101571928e68SAkira Hatanaka                                              uint64_t Address,
101671928e68SAkira Hatanaka                                              const void *Decoder) {
101771928e68SAkira Hatanaka   if (RegNo > 31)
101871928e68SAkira Hatanaka     return MCDisassembler::Fail;
101913e6ccf3SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::GPR32RegClassID, RegNo);
1020e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
102171928e68SAkira Hatanaka   return MCDisassembler::Success;
102271928e68SAkira Hatanaka }
102371928e68SAkira Hatanaka 
10249bfa2e2eSAkira Hatanaka static DecodeStatus DecodePtrRegisterClass(MCInst &Inst,
10259bfa2e2eSAkira Hatanaka                                            unsigned RegNo,
10269bfa2e2eSAkira Hatanaka                                            uint64_t Address,
10279bfa2e2eSAkira Hatanaka                                            const void *Decoder) {
1028a19216c8SDaniel Sanders   if (static_cast<const MipsDisassembler *>(Decoder)->isGP64())
10299bfa2e2eSAkira Hatanaka     return DecodeGPR64RegisterClass(Inst, RegNo, Address, Decoder);
10309bfa2e2eSAkira Hatanaka 
10319bfa2e2eSAkira Hatanaka   return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
10329bfa2e2eSAkira Hatanaka }
10339bfa2e2eSAkira Hatanaka 
1034654655f1SAkira Hatanaka static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst,
1035ecabd1a5SAkira Hatanaka                                             unsigned RegNo,
1036ecabd1a5SAkira Hatanaka                                             uint64_t Address,
1037ecabd1a5SAkira Hatanaka                                             const void *Decoder) {
103813e6ccf3SAkira Hatanaka   return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
1039ecabd1a5SAkira Hatanaka }
1040ecabd1a5SAkira Hatanaka 
104171928e68SAkira Hatanaka static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
104271928e68SAkira Hatanaka                                              unsigned RegNo,
104371928e68SAkira Hatanaka                                              uint64_t Address,
104471928e68SAkira Hatanaka                                              const void *Decoder) {
104571928e68SAkira Hatanaka   if (RegNo > 31)
104671928e68SAkira Hatanaka     return MCDisassembler::Fail;
104771928e68SAkira Hatanaka 
10489bf2b567SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::FGR64RegClassID, RegNo);
1049e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
105071928e68SAkira Hatanaka   return MCDisassembler::Success;
105171928e68SAkira Hatanaka }
105271928e68SAkira Hatanaka 
105371928e68SAkira Hatanaka static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
105471928e68SAkira Hatanaka                                              unsigned RegNo,
105571928e68SAkira Hatanaka                                              uint64_t Address,
105671928e68SAkira Hatanaka                                              const void *Decoder) {
105771928e68SAkira Hatanaka   if (RegNo > 31)
105871928e68SAkira Hatanaka     return MCDisassembler::Fail;
105971928e68SAkira Hatanaka 
10609bf2b567SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::FGR32RegClassID, RegNo);
1061e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
106271928e68SAkira Hatanaka   return MCDisassembler::Success;
106371928e68SAkira Hatanaka }
106471928e68SAkira Hatanaka 
106571928e68SAkira Hatanaka static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
106671928e68SAkira Hatanaka                                            unsigned RegNo,
106771928e68SAkira Hatanaka                                            uint64_t Address,
106871928e68SAkira Hatanaka                                            const void *Decoder) {
1069253777fdSChad Rosier   if (RegNo > 31)
1070253777fdSChad Rosier     return MCDisassembler::Fail;
1071253777fdSChad Rosier   unsigned Reg = getReg(Decoder, Mips::CCRRegClassID, RegNo);
1072e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
107371928e68SAkira Hatanaka   return MCDisassembler::Success;
107471928e68SAkira Hatanaka }
107571928e68SAkira Hatanaka 
10761fb1b8b8SAkira Hatanaka static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst,
10771fb1b8b8SAkira Hatanaka                                            unsigned RegNo,
10781fb1b8b8SAkira Hatanaka                                            uint64_t Address,
10791fb1b8b8SAkira Hatanaka                                            const void *Decoder) {
10801fb1b8b8SAkira Hatanaka   if (RegNo > 7)
10811fb1b8b8SAkira Hatanaka     return MCDisassembler::Fail;
10821fb1b8b8SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::FCCRegClassID, RegNo);
1083e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
10841fb1b8b8SAkira Hatanaka   return MCDisassembler::Success;
10851fb1b8b8SAkira Hatanaka }
10861fb1b8b8SAkira Hatanaka 
10870fa60416SDaniel Sanders static DecodeStatus DecodeFGRCCRegisterClass(MCInst &Inst, unsigned RegNo,
10880fa60416SDaniel Sanders                                              uint64_t Address,
10890fa60416SDaniel Sanders                                              const void *Decoder) {
10900fa60416SDaniel Sanders   if (RegNo > 31)
10910fa60416SDaniel Sanders     return MCDisassembler::Fail;
10920fa60416SDaniel Sanders 
10930fa60416SDaniel Sanders   unsigned Reg = getReg(Decoder, Mips::FGRCCRegClassID, RegNo);
1094e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
10950fa60416SDaniel Sanders   return MCDisassembler::Success;
10960fa60416SDaniel Sanders }
10970fa60416SDaniel Sanders 
109871928e68SAkira Hatanaka static DecodeStatus DecodeMem(MCInst &Inst,
109971928e68SAkira Hatanaka                               unsigned Insn,
110071928e68SAkira Hatanaka                               uint64_t Address,
110171928e68SAkira Hatanaka                               const void *Decoder) {
110271928e68SAkira Hatanaka   int Offset = SignExtend32<16>(Insn & 0xffff);
1103ecaef49fSJim Grosbach   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1104ecaef49fSJim Grosbach   unsigned Base = fieldFromInstruction(Insn, 21, 5);
11059bf2b567SAkira Hatanaka 
110613e6ccf3SAkira Hatanaka   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
110713e6ccf3SAkira Hatanaka   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
110871928e68SAkira Hatanaka 
1109d7ecf49eSVladimir Medic   if(Inst.getOpcode() == Mips::SC ||
1110d7ecf49eSVladimir Medic      Inst.getOpcode() == Mips::SCD){
1111e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Reg));
111271928e68SAkira Hatanaka   }
111371928e68SAkira Hatanaka 
1114e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1115e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1116e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
111771928e68SAkira Hatanaka 
111871928e68SAkira Hatanaka   return MCDisassembler::Success;
111971928e68SAkira Hatanaka }
112071928e68SAkira Hatanaka 
112192db6b78SDaniel Sanders static DecodeStatus DecodeCacheOp(MCInst &Inst,
112292db6b78SDaniel Sanders                               unsigned Insn,
112392db6b78SDaniel Sanders                               uint64_t Address,
112492db6b78SDaniel Sanders                               const void *Decoder) {
112592db6b78SDaniel Sanders   int Offset = SignExtend32<16>(Insn & 0xffff);
112692db6b78SDaniel Sanders   unsigned Hint = fieldFromInstruction(Insn, 16, 5);
112792db6b78SDaniel Sanders   unsigned Base = fieldFromInstruction(Insn, 21, 5);
112892db6b78SDaniel Sanders 
112992db6b78SDaniel Sanders   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
113092db6b78SDaniel Sanders 
1131e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1132e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
1133e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Hint));
113492db6b78SDaniel Sanders 
113592db6b78SDaniel Sanders   return MCDisassembler::Success;
113692db6b78SDaniel Sanders }
113792db6b78SDaniel Sanders 
1138ab6d1cceSJozef Kolek static DecodeStatus DecodeCacheOpMM(MCInst &Inst,
1139ab6d1cceSJozef Kolek                                     unsigned Insn,
1140ab6d1cceSJozef Kolek                                     uint64_t Address,
1141ab6d1cceSJozef Kolek                                     const void *Decoder) {
1142ab6d1cceSJozef Kolek   int Offset = SignExtend32<12>(Insn & 0xfff);
1143ab6d1cceSJozef Kolek   unsigned Base = fieldFromInstruction(Insn, 16, 5);
1144ab6d1cceSJozef Kolek   unsigned Hint = fieldFromInstruction(Insn, 21, 5);
1145ab6d1cceSJozef Kolek 
1146ab6d1cceSJozef Kolek   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1147ab6d1cceSJozef Kolek 
1148e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1149e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
1150e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Hint));
1151ab6d1cceSJozef Kolek 
1152ab6d1cceSJozef Kolek   return MCDisassembler::Success;
1153ab6d1cceSJozef Kolek }
1154ab6d1cceSJozef Kolek 
1155df464ae2SVladimir Medic static DecodeStatus DecodeCacheOpR6(MCInst &Inst,
1156df464ae2SVladimir Medic                                     unsigned Insn,
1157df464ae2SVladimir Medic                                     uint64_t Address,
1158df464ae2SVladimir Medic                                     const void *Decoder) {
1159df464ae2SVladimir Medic   int Offset = fieldFromInstruction(Insn, 7, 9);
1160df464ae2SVladimir Medic   unsigned Hint = fieldFromInstruction(Insn, 16, 5);
1161df464ae2SVladimir Medic   unsigned Base = fieldFromInstruction(Insn, 21, 5);
1162df464ae2SVladimir Medic 
1163df464ae2SVladimir Medic   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1164df464ae2SVladimir Medic 
1165e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1166e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
1167e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Hint));
1168df464ae2SVladimir Medic 
1169df464ae2SVladimir Medic   return MCDisassembler::Success;
1170df464ae2SVladimir Medic }
1171df464ae2SVladimir Medic 
1172*9eaa30d2SZoran Jovanovic static DecodeStatus DecodeStoreEvaOpMM(MCInst &Inst,
1173*9eaa30d2SZoran Jovanovic                                        unsigned Insn,
1174*9eaa30d2SZoran Jovanovic                                        uint64_t Address,
1175*9eaa30d2SZoran Jovanovic                                        const void *Decoder) {
1176*9eaa30d2SZoran Jovanovic   int Offset = SignExtend32<9>(Insn & 0x1ff);
1177*9eaa30d2SZoran Jovanovic   unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1178*9eaa30d2SZoran Jovanovic   unsigned Base = fieldFromInstruction(Insn, 16, 5);
1179*9eaa30d2SZoran Jovanovic 
1180*9eaa30d2SZoran Jovanovic   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1181*9eaa30d2SZoran Jovanovic   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1182*9eaa30d2SZoran Jovanovic 
1183*9eaa30d2SZoran Jovanovic   Inst.addOperand(MCOperand::createReg(Reg));
1184*9eaa30d2SZoran Jovanovic   Inst.addOperand(MCOperand::createReg(Base));
1185*9eaa30d2SZoran Jovanovic   Inst.addOperand(MCOperand::createImm(Offset));
1186*9eaa30d2SZoran Jovanovic 
1187*9eaa30d2SZoran Jovanovic   return MCDisassembler::Success;
1188*9eaa30d2SZoran Jovanovic }
1189*9eaa30d2SZoran Jovanovic 
1190b4484d62SDaniel Sanders static DecodeStatus DecodeSyncI(MCInst &Inst,
1191b4484d62SDaniel Sanders                               unsigned Insn,
1192b4484d62SDaniel Sanders                               uint64_t Address,
1193b4484d62SDaniel Sanders                               const void *Decoder) {
1194b4484d62SDaniel Sanders   int Offset = SignExtend32<16>(Insn & 0xffff);
1195b4484d62SDaniel Sanders   unsigned Base = fieldFromInstruction(Insn, 21, 5);
1196b4484d62SDaniel Sanders 
1197b4484d62SDaniel Sanders   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1198b4484d62SDaniel Sanders 
1199e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1200e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
1201b4484d62SDaniel Sanders 
1202b4484d62SDaniel Sanders   return MCDisassembler::Success;
1203b4484d62SDaniel Sanders }
1204b4484d62SDaniel Sanders 
1205fe0bf9f6SMatheus Almeida static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn,
1206fe0bf9f6SMatheus Almeida                                     uint64_t Address, const void *Decoder) {
1207fe0bf9f6SMatheus Almeida   int Offset = SignExtend32<10>(fieldFromInstruction(Insn, 16, 10));
1208fe0bf9f6SMatheus Almeida   unsigned Reg = fieldFromInstruction(Insn, 6, 5);
1209fe0bf9f6SMatheus Almeida   unsigned Base = fieldFromInstruction(Insn, 11, 5);
1210fe0bf9f6SMatheus Almeida 
1211fe0bf9f6SMatheus Almeida   Reg = getReg(Decoder, Mips::MSA128BRegClassID, Reg);
1212fe0bf9f6SMatheus Almeida   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1213fe0bf9f6SMatheus Almeida 
1214e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1215e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
12166b59c449SMatheus Almeida 
12176b59c449SMatheus Almeida   // The immediate field of an LD/ST instruction is scaled which means it must
12186b59c449SMatheus Almeida   // be multiplied (when decoding) by the size (in bytes) of the instructions'
12196b59c449SMatheus Almeida   // data format.
12206b59c449SMatheus Almeida   // .b - 1 byte
12216b59c449SMatheus Almeida   // .h - 2 bytes
12226b59c449SMatheus Almeida   // .w - 4 bytes
12236b59c449SMatheus Almeida   // .d - 8 bytes
12246b59c449SMatheus Almeida   switch(Inst.getOpcode())
12256b59c449SMatheus Almeida   {
12266b59c449SMatheus Almeida   default:
12276b59c449SMatheus Almeida     assert (0 && "Unexpected instruction");
12286b59c449SMatheus Almeida     return MCDisassembler::Fail;
12296b59c449SMatheus Almeida     break;
12306b59c449SMatheus Almeida   case Mips::LD_B:
12316b59c449SMatheus Almeida   case Mips::ST_B:
1232e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(Offset));
12336b59c449SMatheus Almeida     break;
12346b59c449SMatheus Almeida   case Mips::LD_H:
12356b59c449SMatheus Almeida   case Mips::ST_H:
1236e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(Offset * 2));
12376b59c449SMatheus Almeida     break;
12386b59c449SMatheus Almeida   case Mips::LD_W:
12396b59c449SMatheus Almeida   case Mips::ST_W:
1240e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(Offset * 4));
12416b59c449SMatheus Almeida     break;
12426b59c449SMatheus Almeida   case Mips::LD_D:
12436b59c449SMatheus Almeida   case Mips::ST_D:
1244e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(Offset * 8));
12456b59c449SMatheus Almeida     break;
12466b59c449SMatheus Almeida   }
1247fe0bf9f6SMatheus Almeida 
1248fe0bf9f6SMatheus Almeida   return MCDisassembler::Success;
1249fe0bf9f6SMatheus Almeida }
1250fe0bf9f6SMatheus Almeida 
1251315e7ecaSJozef Kolek static DecodeStatus DecodeMemMMImm4(MCInst &Inst,
1252315e7ecaSJozef Kolek                                     unsigned Insn,
1253315e7ecaSJozef Kolek                                     uint64_t Address,
1254315e7ecaSJozef Kolek                                     const void *Decoder) {
1255315e7ecaSJozef Kolek   unsigned Offset = Insn & 0xf;
1256315e7ecaSJozef Kolek   unsigned Reg = fieldFromInstruction(Insn, 7, 3);
1257315e7ecaSJozef Kolek   unsigned Base = fieldFromInstruction(Insn, 4, 3);
1258315e7ecaSJozef Kolek 
1259315e7ecaSJozef Kolek   switch (Inst.getOpcode()) {
1260315e7ecaSJozef Kolek     case Mips::LBU16_MM:
1261315e7ecaSJozef Kolek     case Mips::LHU16_MM:
1262315e7ecaSJozef Kolek     case Mips::LW16_MM:
1263315e7ecaSJozef Kolek       if (DecodeGPRMM16RegisterClass(Inst, Reg, Address, Decoder)
1264315e7ecaSJozef Kolek             == MCDisassembler::Fail)
1265315e7ecaSJozef Kolek         return MCDisassembler::Fail;
1266315e7ecaSJozef Kolek       break;
1267315e7ecaSJozef Kolek     case Mips::SB16_MM:
1268315e7ecaSJozef Kolek     case Mips::SH16_MM:
1269315e7ecaSJozef Kolek     case Mips::SW16_MM:
1270315e7ecaSJozef Kolek       if (DecodeGPRMM16ZeroRegisterClass(Inst, Reg, Address, Decoder)
1271315e7ecaSJozef Kolek             == MCDisassembler::Fail)
1272315e7ecaSJozef Kolek         return MCDisassembler::Fail;
1273315e7ecaSJozef Kolek       break;
1274315e7ecaSJozef Kolek   }
1275315e7ecaSJozef Kolek 
1276315e7ecaSJozef Kolek   if (DecodeGPRMM16RegisterClass(Inst, Base, Address, Decoder)
1277315e7ecaSJozef Kolek         == MCDisassembler::Fail)
1278315e7ecaSJozef Kolek     return MCDisassembler::Fail;
1279315e7ecaSJozef Kolek 
1280315e7ecaSJozef Kolek   switch (Inst.getOpcode()) {
1281315e7ecaSJozef Kolek     case Mips::LBU16_MM:
1282315e7ecaSJozef Kolek       if (Offset == 0xf)
1283e9119e41SJim Grosbach         Inst.addOperand(MCOperand::createImm(-1));
1284315e7ecaSJozef Kolek       else
1285e9119e41SJim Grosbach         Inst.addOperand(MCOperand::createImm(Offset));
1286315e7ecaSJozef Kolek       break;
1287315e7ecaSJozef Kolek     case Mips::SB16_MM:
1288e9119e41SJim Grosbach       Inst.addOperand(MCOperand::createImm(Offset));
1289315e7ecaSJozef Kolek       break;
1290315e7ecaSJozef Kolek     case Mips::LHU16_MM:
1291315e7ecaSJozef Kolek     case Mips::SH16_MM:
1292e9119e41SJim Grosbach       Inst.addOperand(MCOperand::createImm(Offset << 1));
1293315e7ecaSJozef Kolek       break;
1294315e7ecaSJozef Kolek     case Mips::LW16_MM:
1295315e7ecaSJozef Kolek     case Mips::SW16_MM:
1296e9119e41SJim Grosbach       Inst.addOperand(MCOperand::createImm(Offset << 2));
1297315e7ecaSJozef Kolek       break;
1298315e7ecaSJozef Kolek   }
1299315e7ecaSJozef Kolek 
1300315e7ecaSJozef Kolek   return MCDisassembler::Success;
1301315e7ecaSJozef Kolek }
1302315e7ecaSJozef Kolek 
130312c6982bSJozef Kolek static DecodeStatus DecodeMemMMSPImm5Lsl2(MCInst &Inst,
130412c6982bSJozef Kolek                                           unsigned Insn,
130512c6982bSJozef Kolek                                           uint64_t Address,
130612c6982bSJozef Kolek                                           const void *Decoder) {
130712c6982bSJozef Kolek   unsigned Offset = Insn & 0x1F;
130812c6982bSJozef Kolek   unsigned Reg = fieldFromInstruction(Insn, 5, 5);
130912c6982bSJozef Kolek 
131012c6982bSJozef Kolek   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
131112c6982bSJozef Kolek 
1312e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1313e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Mips::SP));
1314e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset << 2));
131512c6982bSJozef Kolek 
131612c6982bSJozef Kolek   return MCDisassembler::Success;
131712c6982bSJozef Kolek }
131812c6982bSJozef Kolek 
1319e10a02ecSJozef Kolek static DecodeStatus DecodeMemMMGPImm7Lsl2(MCInst &Inst,
1320e10a02ecSJozef Kolek                                           unsigned Insn,
1321e10a02ecSJozef Kolek                                           uint64_t Address,
1322e10a02ecSJozef Kolek                                           const void *Decoder) {
1323e10a02ecSJozef Kolek   unsigned Offset = Insn & 0x7F;
1324e10a02ecSJozef Kolek   unsigned Reg = fieldFromInstruction(Insn, 7, 3);
1325e10a02ecSJozef Kolek 
1326e10a02ecSJozef Kolek   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1327e10a02ecSJozef Kolek 
1328e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1329e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Mips::GP));
1330e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset << 2));
1331e10a02ecSJozef Kolek 
1332e10a02ecSJozef Kolek   return MCDisassembler::Success;
1333e10a02ecSJozef Kolek }
1334e10a02ecSJozef Kolek 
1335d68d424aSJozef Kolek static DecodeStatus DecodeMemMMReglistImm4Lsl2(MCInst &Inst,
1336d68d424aSJozef Kolek                                                unsigned Insn,
1337d68d424aSJozef Kolek                                                uint64_t Address,
1338d68d424aSJozef Kolek                                                const void *Decoder) {
1339d68d424aSJozef Kolek   int Offset = SignExtend32<4>(Insn & 0xf);
1340d68d424aSJozef Kolek 
1341d68d424aSJozef Kolek   if (DecodeRegListOperand16(Inst, Insn, Address, Decoder)
1342d68d424aSJozef Kolek       == MCDisassembler::Fail)
1343d68d424aSJozef Kolek     return MCDisassembler::Fail;
1344d68d424aSJozef Kolek 
1345e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Mips::SP));
1346e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset << 2));
1347d68d424aSJozef Kolek 
1348d68d424aSJozef Kolek   return MCDisassembler::Success;
1349d68d424aSJozef Kolek }
1350d68d424aSJozef Kolek 
1351a6593ff6SZoran Jovanovic static DecodeStatus DecodeMemMMImm9(MCInst &Inst,
1352a6593ff6SZoran Jovanovic                                     unsigned Insn,
1353a6593ff6SZoran Jovanovic                                     uint64_t Address,
1354a6593ff6SZoran Jovanovic                                     const void *Decoder) {
1355a6593ff6SZoran Jovanovic   int Offset = SignExtend32<9>(Insn & 0x1ff);
1356a6593ff6SZoran Jovanovic   unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1357a6593ff6SZoran Jovanovic   unsigned Base = fieldFromInstruction(Insn, 16, 5);
1358a6593ff6SZoran Jovanovic 
1359a6593ff6SZoran Jovanovic   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1360a6593ff6SZoran Jovanovic   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1361a6593ff6SZoran Jovanovic 
1362a6593ff6SZoran Jovanovic   Inst.addOperand(MCOperand::createReg(Reg));
1363a6593ff6SZoran Jovanovic   Inst.addOperand(MCOperand::createReg(Base));
1364a6593ff6SZoran Jovanovic   Inst.addOperand(MCOperand::createImm(Offset));
1365a6593ff6SZoran Jovanovic 
1366a6593ff6SZoran Jovanovic   return MCDisassembler::Success;
1367a6593ff6SZoran Jovanovic }
1368a6593ff6SZoran Jovanovic 
1369dde3d582SVladimir Medic static DecodeStatus DecodeMemMMImm12(MCInst &Inst,
1370dde3d582SVladimir Medic                                      unsigned Insn,
1371dde3d582SVladimir Medic                                      uint64_t Address,
1372dde3d582SVladimir Medic                                      const void *Decoder) {
1373dde3d582SVladimir Medic   int Offset = SignExtend32<12>(Insn & 0x0fff);
1374dde3d582SVladimir Medic   unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1375dde3d582SVladimir Medic   unsigned Base = fieldFromInstruction(Insn, 16, 5);
1376dde3d582SVladimir Medic 
1377dde3d582SVladimir Medic   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1378dde3d582SVladimir Medic   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1379dde3d582SVladimir Medic 
1380a4c4b5fcSZoran Jovanovic   switch (Inst.getOpcode()) {
1381a4c4b5fcSZoran Jovanovic   case Mips::SWM32_MM:
1382a4c4b5fcSZoran Jovanovic   case Mips::LWM32_MM:
1383a4c4b5fcSZoran Jovanovic     if (DecodeRegListOperand(Inst, Insn, Address, Decoder)
1384a4c4b5fcSZoran Jovanovic         == MCDisassembler::Fail)
1385a4c4b5fcSZoran Jovanovic       return MCDisassembler::Fail;
1386e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Base));
1387e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(Offset));
1388a4c4b5fcSZoran Jovanovic     break;
1389a4c4b5fcSZoran Jovanovic   case Mips::SC_MM:
1390e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Reg));
1391a4c4b5fcSZoran Jovanovic     // fallthrough
1392a4c4b5fcSZoran Jovanovic   default:
1393e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Reg));
13942deca348SZoran Jovanovic     if (Inst.getOpcode() == Mips::LWP_MM || Inst.getOpcode() == Mips::SWP_MM)
1395e9119e41SJim Grosbach       Inst.addOperand(MCOperand::createReg(Reg+1));
13962deca348SZoran Jovanovic 
1397e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Base));
1398e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(Offset));
1399a4c4b5fcSZoran Jovanovic   }
1400dde3d582SVladimir Medic 
1401dde3d582SVladimir Medic   return MCDisassembler::Success;
1402dde3d582SVladimir Medic }
1403dde3d582SVladimir Medic 
1404dde3d582SVladimir Medic static DecodeStatus DecodeMemMMImm16(MCInst &Inst,
1405dde3d582SVladimir Medic                                      unsigned Insn,
1406dde3d582SVladimir Medic                                      uint64_t Address,
1407dde3d582SVladimir Medic                                      const void *Decoder) {
1408dde3d582SVladimir Medic   int Offset = SignExtend32<16>(Insn & 0xffff);
1409dde3d582SVladimir Medic   unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1410dde3d582SVladimir Medic   unsigned Base = fieldFromInstruction(Insn, 16, 5);
1411dde3d582SVladimir Medic 
1412dde3d582SVladimir Medic   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1413dde3d582SVladimir Medic   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1414dde3d582SVladimir Medic 
1415e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1416e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1417e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
1418dde3d582SVladimir Medic 
1419dde3d582SVladimir Medic   return MCDisassembler::Success;
1420dde3d582SVladimir Medic }
1421dde3d582SVladimir Medic 
142271928e68SAkira Hatanaka static DecodeStatus DecodeFMem(MCInst &Inst,
142371928e68SAkira Hatanaka                                unsigned Insn,
142471928e68SAkira Hatanaka                                uint64_t Address,
142571928e68SAkira Hatanaka                                const void *Decoder) {
142671928e68SAkira Hatanaka   int Offset = SignExtend32<16>(Insn & 0xffff);
1427ecaef49fSJim Grosbach   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1428ecaef49fSJim Grosbach   unsigned Base = fieldFromInstruction(Insn, 21, 5);
142971928e68SAkira Hatanaka 
14309bf2b567SAkira Hatanaka   Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg);
143113e6ccf3SAkira Hatanaka   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
14329bf2b567SAkira Hatanaka 
1433e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1434e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1435e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
143671928e68SAkira Hatanaka 
143771928e68SAkira Hatanaka   return MCDisassembler::Success;
143871928e68SAkira Hatanaka }
143971928e68SAkira Hatanaka 
144092db6b78SDaniel Sanders static DecodeStatus DecodeFMem2(MCInst &Inst,
144192db6b78SDaniel Sanders                                unsigned Insn,
144292db6b78SDaniel Sanders                                uint64_t Address,
144392db6b78SDaniel Sanders                                const void *Decoder) {
144492db6b78SDaniel Sanders   int Offset = SignExtend32<16>(Insn & 0xffff);
144592db6b78SDaniel Sanders   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
144692db6b78SDaniel Sanders   unsigned Base = fieldFromInstruction(Insn, 21, 5);
144792db6b78SDaniel Sanders 
144892db6b78SDaniel Sanders   Reg = getReg(Decoder, Mips::COP2RegClassID, Reg);
144992db6b78SDaniel Sanders   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
145092db6b78SDaniel Sanders 
1451e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1452e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1453e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
145492db6b78SDaniel Sanders 
145592db6b78SDaniel Sanders   return MCDisassembler::Success;
145692db6b78SDaniel Sanders }
145792db6b78SDaniel Sanders 
145892db6b78SDaniel Sanders static DecodeStatus DecodeFMem3(MCInst &Inst,
145992db6b78SDaniel Sanders                                unsigned Insn,
146092db6b78SDaniel Sanders                                uint64_t Address,
146192db6b78SDaniel Sanders                                const void *Decoder) {
146292db6b78SDaniel Sanders   int Offset = SignExtend32<16>(Insn & 0xffff);
146392db6b78SDaniel Sanders   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
146492db6b78SDaniel Sanders   unsigned Base = fieldFromInstruction(Insn, 21, 5);
146592db6b78SDaniel Sanders 
146692db6b78SDaniel Sanders   Reg = getReg(Decoder, Mips::COP3RegClassID, Reg);
146792db6b78SDaniel Sanders   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
146892db6b78SDaniel Sanders 
1469e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1470e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1471e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
147292db6b78SDaniel Sanders 
147392db6b78SDaniel Sanders   return MCDisassembler::Success;
147492db6b78SDaniel Sanders }
147592db6b78SDaniel Sanders 
1476435cf8a4SVladimir Medic static DecodeStatus DecodeFMemCop2R6(MCInst &Inst,
1477435cf8a4SVladimir Medic                                     unsigned Insn,
1478435cf8a4SVladimir Medic                                     uint64_t Address,
1479435cf8a4SVladimir Medic                                     const void *Decoder) {
1480435cf8a4SVladimir Medic   int Offset = SignExtend32<11>(Insn & 0x07ff);
1481435cf8a4SVladimir Medic   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1482435cf8a4SVladimir Medic   unsigned Base = fieldFromInstruction(Insn, 11, 5);
1483435cf8a4SVladimir Medic 
1484435cf8a4SVladimir Medic   Reg = getReg(Decoder, Mips::COP2RegClassID, Reg);
1485435cf8a4SVladimir Medic   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1486435cf8a4SVladimir Medic 
1487e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1488e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1489e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
1490435cf8a4SVladimir Medic 
1491435cf8a4SVladimir Medic   return MCDisassembler::Success;
1492435cf8a4SVladimir Medic }
14936a803f61SDaniel Sanders static DecodeStatus DecodeSpecial3LlSc(MCInst &Inst,
14946a803f61SDaniel Sanders                                        unsigned Insn,
14956a803f61SDaniel Sanders                                        uint64_t Address,
14966a803f61SDaniel Sanders                                        const void *Decoder) {
14976a803f61SDaniel Sanders   int64_t Offset = SignExtend64<9>((Insn >> 7) & 0x1ff);
14986a803f61SDaniel Sanders   unsigned Rt = fieldFromInstruction(Insn, 16, 5);
14996a803f61SDaniel Sanders   unsigned Base = fieldFromInstruction(Insn, 21, 5);
15006a803f61SDaniel Sanders 
15016a803f61SDaniel Sanders   Rt = getReg(Decoder, Mips::GPR32RegClassID, Rt);
15026a803f61SDaniel Sanders   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
15036a803f61SDaniel Sanders 
15046a803f61SDaniel Sanders   if(Inst.getOpcode() == Mips::SC_R6 || Inst.getOpcode() == Mips::SCD_R6){
1505e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Rt));
15066a803f61SDaniel Sanders   }
15076a803f61SDaniel Sanders 
1508e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Rt));
1509e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1510e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
15116a803f61SDaniel Sanders 
15126a803f61SDaniel Sanders   return MCDisassembler::Success;
15136a803f61SDaniel Sanders }
151471928e68SAkira Hatanaka 
151571928e68SAkira Hatanaka static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
151671928e68SAkira Hatanaka                                               unsigned RegNo,
151771928e68SAkira Hatanaka                                               uint64_t Address,
151871928e68SAkira Hatanaka                                               const void *Decoder) {
151971928e68SAkira Hatanaka   // Currently only hardware register 29 is supported.
152071928e68SAkira Hatanaka   if (RegNo != 29)
152171928e68SAkira Hatanaka     return  MCDisassembler::Fail;
1522e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Mips::HWR29));
152371928e68SAkira Hatanaka   return MCDisassembler::Success;
152471928e68SAkira Hatanaka }
152571928e68SAkira Hatanaka 
152671928e68SAkira Hatanaka static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
152771928e68SAkira Hatanaka                                               unsigned RegNo,
152871928e68SAkira Hatanaka                                               uint64_t Address,
152971928e68SAkira Hatanaka                                               const void *Decoder) {
15309bf2b567SAkira Hatanaka   if (RegNo > 30 || RegNo %2)
153171928e68SAkira Hatanaka     return MCDisassembler::Fail;
153271928e68SAkira Hatanaka 
15339bf2b567SAkira Hatanaka   ;
15349bf2b567SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::AFGR64RegClassID, RegNo /2);
1535e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
153671928e68SAkira Hatanaka   return MCDisassembler::Success;
153771928e68SAkira Hatanaka }
153871928e68SAkira Hatanaka 
153900fcf2e1SAkira Hatanaka static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst,
1540ecabd1a5SAkira Hatanaka                                                 unsigned RegNo,
1541ecabd1a5SAkira Hatanaka                                                 uint64_t Address,
1542ecabd1a5SAkira Hatanaka                                                 const void *Decoder) {
1543ecabd1a5SAkira Hatanaka   if (RegNo >= 4)
1544ecabd1a5SAkira Hatanaka     return MCDisassembler::Fail;
1545ecabd1a5SAkira Hatanaka 
154600fcf2e1SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::ACC64DSPRegClassID, RegNo);
1547e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1548ecabd1a5SAkira Hatanaka   return MCDisassembler::Success;
1549ecabd1a5SAkira Hatanaka }
1550ecabd1a5SAkira Hatanaka 
15518002a3f6SAkira Hatanaka static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst,
155259bfaf77SAkira Hatanaka                                                unsigned RegNo,
155359bfaf77SAkira Hatanaka                                                uint64_t Address,
155459bfaf77SAkira Hatanaka                                                const void *Decoder) {
155559bfaf77SAkira Hatanaka   if (RegNo >= 4)
155659bfaf77SAkira Hatanaka     return MCDisassembler::Fail;
155759bfaf77SAkira Hatanaka 
15588002a3f6SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::HI32DSPRegClassID, RegNo);
1559e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
156059bfaf77SAkira Hatanaka   return MCDisassembler::Success;
156159bfaf77SAkira Hatanaka }
156259bfaf77SAkira Hatanaka 
15638002a3f6SAkira Hatanaka static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst,
156459bfaf77SAkira Hatanaka                                                unsigned RegNo,
156559bfaf77SAkira Hatanaka                                                uint64_t Address,
156659bfaf77SAkira Hatanaka                                                const void *Decoder) {
156759bfaf77SAkira Hatanaka   if (RegNo >= 4)
156859bfaf77SAkira Hatanaka     return MCDisassembler::Fail;
156959bfaf77SAkira Hatanaka 
15708002a3f6SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::LO32DSPRegClassID, RegNo);
1571e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
157259bfaf77SAkira Hatanaka   return MCDisassembler::Success;
157359bfaf77SAkira Hatanaka }
157459bfaf77SAkira Hatanaka 
15753eb663b0SJack Carter static DecodeStatus DecodeMSA128BRegisterClass(MCInst &Inst,
15763eb663b0SJack Carter                                                unsigned RegNo,
15773eb663b0SJack Carter                                                uint64_t Address,
15783eb663b0SJack Carter                                                const void *Decoder) {
15793eb663b0SJack Carter   if (RegNo > 31)
15803eb663b0SJack Carter     return MCDisassembler::Fail;
15813eb663b0SJack Carter 
15823eb663b0SJack Carter   unsigned Reg = getReg(Decoder, Mips::MSA128BRegClassID, RegNo);
1583e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
15843eb663b0SJack Carter   return MCDisassembler::Success;
15853eb663b0SJack Carter }
15863eb663b0SJack Carter 
15875dc8ac92SJack Carter static DecodeStatus DecodeMSA128HRegisterClass(MCInst &Inst,
15885dc8ac92SJack Carter                                                unsigned RegNo,
15895dc8ac92SJack Carter                                                uint64_t Address,
15905dc8ac92SJack Carter                                                const void *Decoder) {
15915dc8ac92SJack Carter   if (RegNo > 31)
15925dc8ac92SJack Carter     return MCDisassembler::Fail;
15935dc8ac92SJack Carter 
15945dc8ac92SJack Carter   unsigned Reg = getReg(Decoder, Mips::MSA128HRegClassID, RegNo);
1595e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
15965dc8ac92SJack Carter   return MCDisassembler::Success;
15975dc8ac92SJack Carter }
15985dc8ac92SJack Carter 
15995dc8ac92SJack Carter static DecodeStatus DecodeMSA128WRegisterClass(MCInst &Inst,
16005dc8ac92SJack Carter                                                unsigned RegNo,
16015dc8ac92SJack Carter                                                uint64_t Address,
16025dc8ac92SJack Carter                                                const void *Decoder) {
16035dc8ac92SJack Carter   if (RegNo > 31)
16045dc8ac92SJack Carter     return MCDisassembler::Fail;
16055dc8ac92SJack Carter 
16065dc8ac92SJack Carter   unsigned Reg = getReg(Decoder, Mips::MSA128WRegClassID, RegNo);
1607e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
16085dc8ac92SJack Carter   return MCDisassembler::Success;
16095dc8ac92SJack Carter }
16105dc8ac92SJack Carter 
16115dc8ac92SJack Carter static DecodeStatus DecodeMSA128DRegisterClass(MCInst &Inst,
16125dc8ac92SJack Carter                                                unsigned RegNo,
16135dc8ac92SJack Carter                                                uint64_t Address,
16145dc8ac92SJack Carter                                                const void *Decoder) {
16155dc8ac92SJack Carter   if (RegNo > 31)
16165dc8ac92SJack Carter     return MCDisassembler::Fail;
16175dc8ac92SJack Carter 
16185dc8ac92SJack Carter   unsigned Reg = getReg(Decoder, Mips::MSA128DRegClassID, RegNo);
1619e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
16205dc8ac92SJack Carter   return MCDisassembler::Success;
16215dc8ac92SJack Carter }
16225dc8ac92SJack Carter 
1623a591fdc6SMatheus Almeida static DecodeStatus DecodeMSACtrlRegisterClass(MCInst &Inst,
1624a591fdc6SMatheus Almeida                                                unsigned RegNo,
1625a591fdc6SMatheus Almeida                                                uint64_t Address,
1626a591fdc6SMatheus Almeida                                                const void *Decoder) {
1627a591fdc6SMatheus Almeida   if (RegNo > 7)
1628a591fdc6SMatheus Almeida     return MCDisassembler::Fail;
1629a591fdc6SMatheus Almeida 
1630a591fdc6SMatheus Almeida   unsigned Reg = getReg(Decoder, Mips::MSACtrlRegClassID, RegNo);
1631e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1632a591fdc6SMatheus Almeida   return MCDisassembler::Success;
1633a591fdc6SMatheus Almeida }
1634a591fdc6SMatheus Almeida 
1635a3134faeSDaniel Sanders static DecodeStatus DecodeCOP0RegisterClass(MCInst &Inst,
1636a3134faeSDaniel Sanders                                             unsigned RegNo,
1637a3134faeSDaniel Sanders                                             uint64_t Address,
1638a3134faeSDaniel Sanders                                             const void *Decoder) {
1639a3134faeSDaniel Sanders   if (RegNo > 31)
1640a3134faeSDaniel Sanders     return MCDisassembler::Fail;
1641a3134faeSDaniel Sanders 
1642a3134faeSDaniel Sanders   unsigned Reg = getReg(Decoder, Mips::COP0RegClassID, RegNo);
1643a3134faeSDaniel Sanders   Inst.addOperand(MCOperand::createReg(Reg));
1644a3134faeSDaniel Sanders   return MCDisassembler::Success;
1645a3134faeSDaniel Sanders }
1646a3134faeSDaniel Sanders 
16472a83d680SDaniel Sanders static DecodeStatus DecodeCOP2RegisterClass(MCInst &Inst,
16482a83d680SDaniel Sanders                                             unsigned RegNo,
16492a83d680SDaniel Sanders                                             uint64_t Address,
16502a83d680SDaniel Sanders                                             const void *Decoder) {
16512a83d680SDaniel Sanders   if (RegNo > 31)
16522a83d680SDaniel Sanders     return MCDisassembler::Fail;
16532a83d680SDaniel Sanders 
16542a83d680SDaniel Sanders   unsigned Reg = getReg(Decoder, Mips::COP2RegClassID, RegNo);
1655e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
16562a83d680SDaniel Sanders   return MCDisassembler::Success;
16572a83d680SDaniel Sanders }
16582a83d680SDaniel Sanders 
165971928e68SAkira Hatanaka static DecodeStatus DecodeBranchTarget(MCInst &Inst,
166071928e68SAkira Hatanaka                                        unsigned Offset,
166171928e68SAkira Hatanaka                                        uint64_t Address,
166271928e68SAkira Hatanaka                                        const void *Decoder) {
1663d37bab61SAlexey Samsonov   int32_t BranchOffset = (SignExtend32<16>(Offset) * 4) + 4;
1664e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(BranchOffset));
166571928e68SAkira Hatanaka   return MCDisassembler::Success;
166671928e68SAkira Hatanaka }
166771928e68SAkira Hatanaka 
166871928e68SAkira Hatanaka static DecodeStatus DecodeJumpTarget(MCInst &Inst,
166971928e68SAkira Hatanaka                                      unsigned Insn,
167071928e68SAkira Hatanaka                                      uint64_t Address,
167171928e68SAkira Hatanaka                                      const void *Decoder) {
167271928e68SAkira Hatanaka 
1673ecaef49fSJim Grosbach   unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 2;
1674e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(JumpOffset));
167571928e68SAkira Hatanaka   return MCDisassembler::Success;
167671928e68SAkira Hatanaka }
167771928e68SAkira Hatanaka 
16783c8869dcSZoran Jovanovic static DecodeStatus DecodeBranchTarget21(MCInst &Inst,
16793c8869dcSZoran Jovanovic                                          unsigned Offset,
16803c8869dcSZoran Jovanovic                                          uint64_t Address,
16813c8869dcSZoran Jovanovic                                          const void *Decoder) {
1682d37bab61SAlexey Samsonov   int32_t BranchOffset = SignExtend32<21>(Offset) * 4;
16833c8869dcSZoran Jovanovic 
1684e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(BranchOffset));
16853c8869dcSZoran Jovanovic   return MCDisassembler::Success;
16863c8869dcSZoran Jovanovic }
16873c8869dcSZoran Jovanovic 
16883c8869dcSZoran Jovanovic static DecodeStatus DecodeBranchTarget26(MCInst &Inst,
16893c8869dcSZoran Jovanovic                                          unsigned Offset,
16903c8869dcSZoran Jovanovic                                          uint64_t Address,
16913c8869dcSZoran Jovanovic                                          const void *Decoder) {
1692d37bab61SAlexey Samsonov   int32_t BranchOffset = SignExtend32<26>(Offset) * 4;
16933c8869dcSZoran Jovanovic 
1694e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(BranchOffset));
16953c8869dcSZoran Jovanovic   return MCDisassembler::Success;
16963c8869dcSZoran Jovanovic }
16973c8869dcSZoran Jovanovic 
16989761e96bSJozef Kolek static DecodeStatus DecodeBranchTarget7MM(MCInst &Inst,
16999761e96bSJozef Kolek                                           unsigned Offset,
17009761e96bSJozef Kolek                                           uint64_t Address,
17019761e96bSJozef Kolek                                           const void *Decoder) {
17029761e96bSJozef Kolek   int32_t BranchOffset = SignExtend32<7>(Offset) << 1;
1703e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(BranchOffset));
17049761e96bSJozef Kolek   return MCDisassembler::Success;
17059761e96bSJozef Kolek }
17069761e96bSJozef Kolek 
17075cfebddeSJozef Kolek static DecodeStatus DecodeBranchTarget10MM(MCInst &Inst,
17085cfebddeSJozef Kolek                                            unsigned Offset,
17095cfebddeSJozef Kolek                                            uint64_t Address,
17105cfebddeSJozef Kolek                                            const void *Decoder) {
17115cfebddeSJozef Kolek   int32_t BranchOffset = SignExtend32<10>(Offset) << 1;
1712e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(BranchOffset));
17135cfebddeSJozef Kolek   return MCDisassembler::Success;
17145cfebddeSJozef Kolek }
17155cfebddeSJozef Kolek 
17168a80aa76SZoran Jovanovic static DecodeStatus DecodeBranchTargetMM(MCInst &Inst,
17178a80aa76SZoran Jovanovic                                          unsigned Offset,
17188a80aa76SZoran Jovanovic                                          uint64_t Address,
17198a80aa76SZoran Jovanovic                                          const void *Decoder) {
1720d37bab61SAlexey Samsonov   int32_t BranchOffset = SignExtend32<16>(Offset) * 2;
1721e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(BranchOffset));
17228a80aa76SZoran Jovanovic   return MCDisassembler::Success;
17238a80aa76SZoran Jovanovic }
17248a80aa76SZoran Jovanovic 
1725507e084aSZoran Jovanovic static DecodeStatus DecodeJumpTargetMM(MCInst &Inst,
1726507e084aSZoran Jovanovic                                        unsigned Insn,
1727507e084aSZoran Jovanovic                                        uint64_t Address,
1728507e084aSZoran Jovanovic                                        const void *Decoder) {
1729507e084aSZoran Jovanovic   unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 1;
1730e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(JumpOffset));
1731507e084aSZoran Jovanovic   return MCDisassembler::Success;
1732507e084aSZoran Jovanovic }
173371928e68SAkira Hatanaka 
1734aa2b9278SJozef Kolek static DecodeStatus DecodeAddiur2Simm7(MCInst &Inst,
1735aa2b9278SJozef Kolek                                        unsigned Value,
1736aa2b9278SJozef Kolek                                        uint64_t Address,
1737aa2b9278SJozef Kolek                                        const void *Decoder) {
1738aa2b9278SJozef Kolek   if (Value == 0)
1739e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(1));
1740aa2b9278SJozef Kolek   else if (Value == 0x7)
1741e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(-1));
1742aa2b9278SJozef Kolek   else
1743e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(Value << 2));
1744aa2b9278SJozef Kolek   return MCDisassembler::Success;
1745aa2b9278SJozef Kolek }
1746aa2b9278SJozef Kolek 
1747aa2b9278SJozef Kolek static DecodeStatus DecodeUImm6Lsl2(MCInst &Inst,
1748aa2b9278SJozef Kolek                                     unsigned Value,
1749aa2b9278SJozef Kolek                                     uint64_t Address,
1750aa2b9278SJozef Kolek                                     const void *Decoder) {
1751e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Value << 2));
1752aa2b9278SJozef Kolek   return MCDisassembler::Success;
1753aa2b9278SJozef Kolek }
1754aa2b9278SJozef Kolek 
1755aa2b9278SJozef Kolek static DecodeStatus DecodeLiSimm7(MCInst &Inst,
1756aa2b9278SJozef Kolek                                   unsigned Value,
1757aa2b9278SJozef Kolek                                   uint64_t Address,
1758aa2b9278SJozef Kolek                                   const void *Decoder) {
1759aa2b9278SJozef Kolek   if (Value == 0x7F)
1760e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(-1));
1761aa2b9278SJozef Kolek   else
1762e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(Value));
1763aa2b9278SJozef Kolek   return MCDisassembler::Success;
1764aa2b9278SJozef Kolek }
1765aa2b9278SJozef Kolek 
1766aa2b9278SJozef Kolek static DecodeStatus DecodeSimm4(MCInst &Inst,
1767aa2b9278SJozef Kolek                                 unsigned Value,
1768aa2b9278SJozef Kolek                                 uint64_t Address,
1769aa2b9278SJozef Kolek                                 const void *Decoder) {
1770e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(SignExtend32<4>(Value)));
1771aa2b9278SJozef Kolek   return MCDisassembler::Success;
1772aa2b9278SJozef Kolek }
1773aa2b9278SJozef Kolek 
177471928e68SAkira Hatanaka static DecodeStatus DecodeSimm16(MCInst &Inst,
177571928e68SAkira Hatanaka                                  unsigned Insn,
177671928e68SAkira Hatanaka                                  uint64_t Address,
177771928e68SAkira Hatanaka                                  const void *Decoder) {
1778e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(SignExtend32<16>(Insn)));
177971928e68SAkira Hatanaka   return MCDisassembler::Success;
178071928e68SAkira Hatanaka }
178171928e68SAkira Hatanaka 
1782779c5937SMatheus Almeida static DecodeStatus DecodeLSAImm(MCInst &Inst,
1783779c5937SMatheus Almeida                                  unsigned Insn,
1784779c5937SMatheus Almeida                                  uint64_t Address,
1785779c5937SMatheus Almeida                                  const void *Decoder) {
1786779c5937SMatheus Almeida   // We add one to the immediate field as it was encoded as 'imm - 1'.
1787e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Insn + 1));
1788779c5937SMatheus Almeida   return MCDisassembler::Success;
1789779c5937SMatheus Almeida }
1790779c5937SMatheus Almeida 
179171928e68SAkira Hatanaka static DecodeStatus DecodeInsSize(MCInst &Inst,
179271928e68SAkira Hatanaka                                   unsigned Insn,
179371928e68SAkira Hatanaka                                   uint64_t Address,
179471928e68SAkira Hatanaka                                   const void *Decoder) {
179571928e68SAkira Hatanaka   // First we need to grab the pos(lsb) from MCInst.
179671928e68SAkira Hatanaka   int Pos = Inst.getOperand(2).getImm();
179771928e68SAkira Hatanaka   int Size = (int) Insn - Pos + 1;
1798e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(SignExtend32<16>(Size)));
179971928e68SAkira Hatanaka   return MCDisassembler::Success;
180071928e68SAkira Hatanaka }
180171928e68SAkira Hatanaka 
180271928e68SAkira Hatanaka static DecodeStatus DecodeExtSize(MCInst &Inst,
180371928e68SAkira Hatanaka                                   unsigned Insn,
180471928e68SAkira Hatanaka                                   uint64_t Address,
180571928e68SAkira Hatanaka                                   const void *Decoder) {
180671928e68SAkira Hatanaka   int Size = (int) Insn  + 1;
1807e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(SignExtend32<16>(Size)));
180871928e68SAkira Hatanaka   return MCDisassembler::Success;
180971928e68SAkira Hatanaka }
1810b59e1a41SDaniel Sanders 
1811b59e1a41SDaniel Sanders static DecodeStatus DecodeSimm19Lsl2(MCInst &Inst, unsigned Insn,
1812b59e1a41SDaniel Sanders                                      uint64_t Address, const void *Decoder) {
1813e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(SignExtend32<19>(Insn) * 4));
1814b59e1a41SDaniel Sanders   return MCDisassembler::Success;
1815b59e1a41SDaniel Sanders }
18162855142aSZoran Jovanovic 
18172855142aSZoran Jovanovic static DecodeStatus DecodeSimm18Lsl3(MCInst &Inst, unsigned Insn,
18182855142aSZoran Jovanovic                                      uint64_t Address, const void *Decoder) {
1819e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(SignExtend32<18>(Insn) * 8));
18202855142aSZoran Jovanovic   return MCDisassembler::Success;
18212855142aSZoran Jovanovic }
1822a4c4b5fcSZoran Jovanovic 
1823b682ddf3SVladimir Medic static DecodeStatus DecodeSimm9SP(MCInst &Inst, unsigned Insn,
1824b682ddf3SVladimir Medic                                   uint64_t Address, const void *Decoder) {
1825b682ddf3SVladimir Medic   int32_t DecodedValue;
1826b682ddf3SVladimir Medic   switch (Insn) {
1827b682ddf3SVladimir Medic   case 0: DecodedValue = 256; break;
1828b682ddf3SVladimir Medic   case 1: DecodedValue = 257; break;
1829b682ddf3SVladimir Medic   case 510: DecodedValue = -258; break;
1830b682ddf3SVladimir Medic   case 511: DecodedValue = -257; break;
1831b682ddf3SVladimir Medic   default: DecodedValue = SignExtend32<9>(Insn); break;
1832b682ddf3SVladimir Medic   }
1833e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(DecodedValue * 4));
1834b682ddf3SVladimir Medic   return MCDisassembler::Success;
1835b682ddf3SVladimir Medic }
1836b682ddf3SVladimir Medic 
1837b682ddf3SVladimir Medic static DecodeStatus DecodeANDI16Imm(MCInst &Inst, unsigned Insn,
1838b682ddf3SVladimir Medic                                     uint64_t Address, const void *Decoder) {
1839b682ddf3SVladimir Medic   // Insn must be >= 0, since it is unsigned that condition is always true.
1840b682ddf3SVladimir Medic   assert(Insn < 16);
1841b682ddf3SVladimir Medic   int32_t DecodedValues[] = {128, 1, 2, 3, 4, 7, 8, 15, 16, 31, 32, 63, 64,
1842b682ddf3SVladimir Medic                              255, 32768, 65535};
1843e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(DecodedValues[Insn]));
1844b682ddf3SVladimir Medic   return MCDisassembler::Success;
1845b682ddf3SVladimir Medic }
1846b682ddf3SVladimir Medic 
1847b682ddf3SVladimir Medic static DecodeStatus DecodeUImm5lsl2(MCInst &Inst, unsigned Insn,
1848b682ddf3SVladimir Medic                                     uint64_t Address, const void *Decoder) {
1849e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Insn << 2));
1850b682ddf3SVladimir Medic   return MCDisassembler::Success;
1851b682ddf3SVladimir Medic }
1852b682ddf3SVladimir Medic 
1853a4c4b5fcSZoran Jovanovic static DecodeStatus DecodeRegListOperand(MCInst &Inst,
1854a4c4b5fcSZoran Jovanovic                                          unsigned Insn,
1855a4c4b5fcSZoran Jovanovic                                          uint64_t Address,
1856a4c4b5fcSZoran Jovanovic                                          const void *Decoder) {
1857a4c4b5fcSZoran Jovanovic   unsigned Regs[] = {Mips::S0, Mips::S1, Mips::S2, Mips::S3, Mips::S4, Mips::S5,
1858a4c4b5fcSZoran Jovanovic                      Mips::S6, Mips::FP};
1859a4c4b5fcSZoran Jovanovic   unsigned RegNum;
1860a4c4b5fcSZoran Jovanovic 
1861a4c4b5fcSZoran Jovanovic   unsigned RegLst = fieldFromInstruction(Insn, 21, 5);
1862a4c4b5fcSZoran Jovanovic   // Empty register lists are not allowed.
1863a4c4b5fcSZoran Jovanovic   if (RegLst == 0)
1864a4c4b5fcSZoran Jovanovic     return MCDisassembler::Fail;
1865a4c4b5fcSZoran Jovanovic 
1866a4c4b5fcSZoran Jovanovic   RegNum = RegLst & 0xf;
1867a4c4b5fcSZoran Jovanovic   for (unsigned i = 0; i < RegNum; i++)
1868e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Regs[i]));
1869a4c4b5fcSZoran Jovanovic 
1870a4c4b5fcSZoran Jovanovic   if (RegLst & 0x10)
1871e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::RA));
1872a4c4b5fcSZoran Jovanovic 
1873a4c4b5fcSZoran Jovanovic   return MCDisassembler::Success;
1874a4c4b5fcSZoran Jovanovic }
1875f9a02500SZoran Jovanovic 
1876f9a02500SZoran Jovanovic static DecodeStatus DecodeRegListOperand16(MCInst &Inst, unsigned Insn,
1877f9a02500SZoran Jovanovic                                            uint64_t Address,
1878f9a02500SZoran Jovanovic                                            const void *Decoder) {
1879f9a02500SZoran Jovanovic   unsigned Regs[] = {Mips::S0, Mips::S1, Mips::S2, Mips::S3};
1880f9a02500SZoran Jovanovic   unsigned RegLst = fieldFromInstruction(Insn, 4, 2);
1881d68d424aSJozef Kolek   unsigned RegNum = RegLst & 0x3;
1882f9a02500SZoran Jovanovic 
1883d68d424aSJozef Kolek   for (unsigned i = 0; i <= RegNum; i++)
1884e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Regs[i]));
1885f9a02500SZoran Jovanovic 
1886e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Mips::RA));
1887f9a02500SZoran Jovanovic 
1888f9a02500SZoran Jovanovic   return MCDisassembler::Success;
1889f9a02500SZoran Jovanovic }
18902c6d7320SJozef Kolek 
189141688679SZoran Jovanovic static DecodeStatus DecodeMovePRegPair(MCInst &Inst, unsigned Insn,
189241688679SZoran Jovanovic                                        uint64_t Address, const void *Decoder) {
189341688679SZoran Jovanovic 
189441688679SZoran Jovanovic   unsigned RegPair = fieldFromInstruction(Insn, 7, 3);
189541688679SZoran Jovanovic 
189641688679SZoran Jovanovic   switch (RegPair) {
189741688679SZoran Jovanovic   default:
189841688679SZoran Jovanovic     return MCDisassembler::Fail;
189941688679SZoran Jovanovic   case 0:
1900e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A1));
1901e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A2));
190241688679SZoran Jovanovic     break;
190341688679SZoran Jovanovic   case 1:
1904e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A1));
1905e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A3));
190641688679SZoran Jovanovic     break;
190741688679SZoran Jovanovic   case 2:
1908e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A2));
1909e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A3));
191041688679SZoran Jovanovic     break;
191141688679SZoran Jovanovic   case 3:
1912e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A0));
1913e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::S5));
191441688679SZoran Jovanovic     break;
191541688679SZoran Jovanovic   case 4:
1916e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A0));
1917e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::S6));
191841688679SZoran Jovanovic     break;
191941688679SZoran Jovanovic   case 5:
1920e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A0));
1921e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A1));
192241688679SZoran Jovanovic     break;
192341688679SZoran Jovanovic   case 6:
1924e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A0));
1925e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A2));
192641688679SZoran Jovanovic     break;
192741688679SZoran Jovanovic   case 7:
1928e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A0));
1929e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A3));
193041688679SZoran Jovanovic     break;
193141688679SZoran Jovanovic   }
193241688679SZoran Jovanovic 
193341688679SZoran Jovanovic   return MCDisassembler::Success;
193441688679SZoran Jovanovic }
193541688679SZoran Jovanovic 
19362c6d7320SJozef Kolek static DecodeStatus DecodeSimm23Lsl2(MCInst &Inst, unsigned Insn,
19372c6d7320SJozef Kolek                                      uint64_t Address, const void *Decoder) {
19386499b5f0SJustin Bogner   Inst.addOperand(MCOperand::createImm(SignExtend32<25>(Insn << 2)));
19392c6d7320SJozef Kolek   return MCDisassembler::Success;
19402c6d7320SJozef Kolek }
1941