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 
244e4e83a7bSDaniel Sanders static DecodeStatus DecodeMemEVA(MCInst &Inst,
245e4e83a7bSDaniel Sanders                                  unsigned Insn,
246e4e83a7bSDaniel Sanders                                  uint64_t Address,
247e4e83a7bSDaniel Sanders                                  const void *Decoder);
248e4e83a7bSDaniel Sanders 
2493c88fbd3SHrvoje Varga static DecodeStatus DecodeLoadByte9(MCInst &Inst,
2503c88fbd3SHrvoje Varga                                     unsigned Insn,
2513c88fbd3SHrvoje Varga                                     uint64_t Address,
2523c88fbd3SHrvoje Varga                                     const void *Decoder);
2533c88fbd3SHrvoje Varga 
2543c88fbd3SHrvoje Varga static DecodeStatus DecodeLoadByte15(MCInst &Inst,
2553c88fbd3SHrvoje Varga                                      unsigned Insn,
2563c88fbd3SHrvoje Varga                                      uint64_t Address,
2573c88fbd3SHrvoje Varga                                      const void *Decoder);
2583c88fbd3SHrvoje Varga 
25992db6b78SDaniel Sanders static DecodeStatus DecodeCacheOp(MCInst &Inst,
26092db6b78SDaniel Sanders                               unsigned Insn,
26192db6b78SDaniel Sanders                               uint64_t Address,
26292db6b78SDaniel Sanders                               const void *Decoder);
26392db6b78SDaniel Sanders 
264e4e83a7bSDaniel Sanders static DecodeStatus DecodeCacheeOp_CacheOpR6(MCInst &Inst,
265df464ae2SVladimir Medic                                              unsigned Insn,
266df464ae2SVladimir Medic                                              uint64_t Address,
267df464ae2SVladimir Medic                                              const void *Decoder);
268df464ae2SVladimir Medic 
269ab6d1cceSJozef Kolek static DecodeStatus DecodeCacheOpMM(MCInst &Inst,
270ab6d1cceSJozef Kolek                                     unsigned Insn,
271ab6d1cceSJozef Kolek                                     uint64_t Address,
272ab6d1cceSJozef Kolek                                     const void *Decoder);
273ab6d1cceSJozef Kolek 
2749eaa30d2SZoran Jovanovic static DecodeStatus DecodeStoreEvaOpMM(MCInst &Inst,
2759eaa30d2SZoran Jovanovic                                        unsigned Insn,
2769eaa30d2SZoran Jovanovic                                        uint64_t Address,
2779eaa30d2SZoran Jovanovic                                        const void *Decoder);
2789eaa30d2SZoran Jovanovic 
279d9790793SZoran Jovanovic static DecodeStatus DecodePrefeOpMM(MCInst &Inst,
280d9790793SZoran Jovanovic                                     unsigned Insn,
281d9790793SZoran Jovanovic                                     uint64_t Address,
282d9790793SZoran Jovanovic                                     const void *Decoder);
283d9790793SZoran Jovanovic 
284b4484d62SDaniel Sanders static DecodeStatus DecodeSyncI(MCInst &Inst,
285b4484d62SDaniel Sanders                                 unsigned Insn,
286b4484d62SDaniel Sanders                                 uint64_t Address,
287b4484d62SDaniel Sanders                                 const void *Decoder);
288b4484d62SDaniel Sanders 
28918148671SHrvoje Varga static DecodeStatus DecodeSynciR6(MCInst &Inst,
29018148671SHrvoje Varga                                   unsigned Insn,
29118148671SHrvoje Varga                                   uint64_t Address,
29218148671SHrvoje Varga                                   const void *Decoder);
29318148671SHrvoje Varga 
294fe0bf9f6SMatheus Almeida static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn,
295fe0bf9f6SMatheus Almeida                                     uint64_t Address, const void *Decoder);
296fe0bf9f6SMatheus Almeida 
297315e7ecaSJozef Kolek static DecodeStatus DecodeMemMMImm4(MCInst &Inst,
298315e7ecaSJozef Kolek                                     unsigned Insn,
299315e7ecaSJozef Kolek                                     uint64_t Address,
300315e7ecaSJozef Kolek                                     const void *Decoder);
301315e7ecaSJozef Kolek 
30212c6982bSJozef Kolek static DecodeStatus DecodeMemMMSPImm5Lsl2(MCInst &Inst,
30312c6982bSJozef Kolek                                           unsigned Insn,
30412c6982bSJozef Kolek                                           uint64_t Address,
30512c6982bSJozef Kolek                                           const void *Decoder);
30612c6982bSJozef Kolek 
307e10a02ecSJozef Kolek static DecodeStatus DecodeMemMMGPImm7Lsl2(MCInst &Inst,
308e10a02ecSJozef Kolek                                           unsigned Insn,
309e10a02ecSJozef Kolek                                           uint64_t Address,
310e10a02ecSJozef Kolek                                           const void *Decoder);
311e10a02ecSJozef Kolek 
312d68d424aSJozef Kolek static DecodeStatus DecodeMemMMReglistImm4Lsl2(MCInst &Inst,
313d68d424aSJozef Kolek                                                unsigned Insn,
314d68d424aSJozef Kolek                                                uint64_t Address,
315d68d424aSJozef Kolek                                                const void *Decoder);
316d68d424aSJozef Kolek 
317a6593ff6SZoran Jovanovic static DecodeStatus DecodeMemMMImm9(MCInst &Inst,
318a6593ff6SZoran Jovanovic                                     unsigned Insn,
319a6593ff6SZoran Jovanovic                                     uint64_t Address,
320a6593ff6SZoran Jovanovic                                     const void *Decoder);
321a6593ff6SZoran Jovanovic 
322dde3d582SVladimir Medic static DecodeStatus DecodeMemMMImm12(MCInst &Inst,
323dde3d582SVladimir Medic                                      unsigned Insn,
324dde3d582SVladimir Medic                                      uint64_t Address,
325dde3d582SVladimir Medic                                      const void *Decoder);
326dde3d582SVladimir Medic 
327dde3d582SVladimir Medic static DecodeStatus DecodeMemMMImm16(MCInst &Inst,
328dde3d582SVladimir Medic                                      unsigned Insn,
329dde3d582SVladimir Medic                                      uint64_t Address,
330dde3d582SVladimir Medic                                      const void *Decoder);
331dde3d582SVladimir Medic 
33271928e68SAkira Hatanaka static DecodeStatus DecodeFMem(MCInst &Inst, unsigned Insn,
33371928e68SAkira Hatanaka                                uint64_t Address,
33471928e68SAkira Hatanaka                                const void *Decoder);
33571928e68SAkira Hatanaka 
33692db6b78SDaniel Sanders static DecodeStatus DecodeFMem2(MCInst &Inst, unsigned Insn,
33792db6b78SDaniel Sanders                                uint64_t Address,
33892db6b78SDaniel Sanders                                const void *Decoder);
33992db6b78SDaniel Sanders 
34092db6b78SDaniel Sanders static DecodeStatus DecodeFMem3(MCInst &Inst, unsigned Insn,
34192db6b78SDaniel Sanders                                uint64_t Address,
34292db6b78SDaniel Sanders                                const void *Decoder);
34392db6b78SDaniel Sanders 
344435cf8a4SVladimir Medic static DecodeStatus DecodeFMemCop2R6(MCInst &Inst, unsigned Insn,
345435cf8a4SVladimir Medic                                uint64_t Address,
346435cf8a4SVladimir Medic                                const void *Decoder);
347435cf8a4SVladimir Medic 
3486a803f61SDaniel Sanders static DecodeStatus DecodeSpecial3LlSc(MCInst &Inst,
3496a803f61SDaniel Sanders                                        unsigned Insn,
3506a803f61SDaniel Sanders                                        uint64_t Address,
3516a803f61SDaniel Sanders                                        const void *Decoder);
3526a803f61SDaniel Sanders 
353aa2b9278SJozef Kolek static DecodeStatus DecodeAddiur2Simm7(MCInst &Inst,
354aa2b9278SJozef Kolek                                        unsigned Value,
355aa2b9278SJozef Kolek                                        uint64_t Address,
356aa2b9278SJozef Kolek                                        const void *Decoder);
357aa2b9278SJozef Kolek 
358aa2b9278SJozef Kolek static DecodeStatus DecodeUImm6Lsl2(MCInst &Inst,
359aa2b9278SJozef Kolek                                     unsigned Value,
360aa2b9278SJozef Kolek                                     uint64_t Address,
361aa2b9278SJozef Kolek                                     const void *Decoder);
362aa2b9278SJozef Kolek 
363aa2b9278SJozef Kolek static DecodeStatus DecodeLiSimm7(MCInst &Inst,
364aa2b9278SJozef Kolek                                   unsigned Value,
365aa2b9278SJozef Kolek                                   uint64_t Address,
366aa2b9278SJozef Kolek                                   const void *Decoder);
367aa2b9278SJozef Kolek 
3686b28f09dSZoran Jovanovic static DecodeStatus DecodePOOL16BEncodedField(MCInst &Inst,
3696b28f09dSZoran Jovanovic                                               unsigned Value,
3706b28f09dSZoran Jovanovic                                               uint64_t Address,
3716b28f09dSZoran Jovanovic                                               const void *Decoder);
3726b28f09dSZoran Jovanovic 
373aa2b9278SJozef Kolek static DecodeStatus DecodeSimm4(MCInst &Inst,
374aa2b9278SJozef Kolek                                 unsigned Value,
375aa2b9278SJozef Kolek                                 uint64_t Address,
376aa2b9278SJozef Kolek                                 const void *Decoder);
377aa2b9278SJozef Kolek 
37871928e68SAkira Hatanaka static DecodeStatus DecodeSimm16(MCInst &Inst,
37971928e68SAkira Hatanaka                                  unsigned Insn,
38071928e68SAkira Hatanaka                                  uint64_t Address,
38171928e68SAkira Hatanaka                                  const void *Decoder);
38271928e68SAkira Hatanaka 
383ea4f653dSDaniel Sanders template <unsigned Bits, int Offset>
384ea4f653dSDaniel Sanders static DecodeStatus DecodeUImmWithOffset(MCInst &Inst, unsigned Value,
385ea4f653dSDaniel Sanders                                          uint64_t Address, const void *Decoder);
386779c5937SMatheus Almeida 
38771928e68SAkira Hatanaka static DecodeStatus DecodeInsSize(MCInst &Inst,
38871928e68SAkira Hatanaka                                   unsigned Insn,
38971928e68SAkira Hatanaka                                   uint64_t Address,
39071928e68SAkira Hatanaka                                   const void *Decoder);
39171928e68SAkira Hatanaka 
39271928e68SAkira Hatanaka static DecodeStatus DecodeExtSize(MCInst &Inst,
39371928e68SAkira Hatanaka                                   unsigned Insn,
39471928e68SAkira Hatanaka                                   uint64_t Address,
39571928e68SAkira Hatanaka                                   const void *Decoder);
39671928e68SAkira Hatanaka 
397b59e1a41SDaniel Sanders static DecodeStatus DecodeSimm19Lsl2(MCInst &Inst, unsigned Insn,
398b59e1a41SDaniel Sanders                                      uint64_t Address, const void *Decoder);
399b59e1a41SDaniel Sanders 
4002855142aSZoran Jovanovic static DecodeStatus DecodeSimm18Lsl3(MCInst &Inst, unsigned Insn,
4012855142aSZoran Jovanovic                                      uint64_t Address, const void *Decoder);
4022855142aSZoran Jovanovic 
403b682ddf3SVladimir Medic static DecodeStatus DecodeSimm9SP(MCInst &Inst, unsigned Insn,
404b682ddf3SVladimir Medic                                   uint64_t Address, const void *Decoder);
405b682ddf3SVladimir Medic 
406b682ddf3SVladimir Medic static DecodeStatus DecodeANDI16Imm(MCInst &Inst, unsigned Insn,
407b682ddf3SVladimir Medic                                     uint64_t Address, const void *Decoder);
408b682ddf3SVladimir Medic 
409b682ddf3SVladimir Medic static DecodeStatus DecodeUImm5lsl2(MCInst &Inst, unsigned Insn,
410b682ddf3SVladimir Medic                                    uint64_t Address, const void *Decoder);
411b682ddf3SVladimir Medic 
4122c6d7320SJozef Kolek static DecodeStatus DecodeSimm23Lsl2(MCInst &Inst, unsigned Insn,
4132c6d7320SJozef Kolek                                      uint64_t Address, const void *Decoder);
4142c6d7320SJozef Kolek 
415b50ccf8eSDaniel Sanders /// INSVE_[BHWD] have an implicit operand that the generated decoder doesn't
416b50ccf8eSDaniel Sanders /// handle.
417b50ccf8eSDaniel Sanders template <typename InsnType>
418b50ccf8eSDaniel Sanders static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address,
419b50ccf8eSDaniel Sanders                                    const void *Decoder);
4205c582b2fSDaniel Sanders 
4215c582b2fSDaniel Sanders template <typename InsnType>
4225c582b2fSDaniel Sanders static DecodeStatus
4235c582b2fSDaniel Sanders DecodeAddiGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
4245c582b2fSDaniel Sanders                       const void *Decoder);
4255c582b2fSDaniel Sanders 
4265c582b2fSDaniel Sanders template <typename InsnType>
4275c582b2fSDaniel Sanders static DecodeStatus
4285c582b2fSDaniel Sanders DecodeDaddiGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
4295c582b2fSDaniel Sanders                        const void *Decoder);
4305c582b2fSDaniel Sanders 
4315c582b2fSDaniel Sanders template <typename InsnType>
4325c582b2fSDaniel Sanders static DecodeStatus
4335c582b2fSDaniel Sanders DecodeBlezlGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
4345c582b2fSDaniel Sanders                        const void *Decoder);
4355c582b2fSDaniel Sanders 
4365c582b2fSDaniel Sanders template <typename InsnType>
4375c582b2fSDaniel Sanders static DecodeStatus
4385c582b2fSDaniel Sanders DecodeBgtzlGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
4395c582b2fSDaniel Sanders                        const void *Decoder);
4405c582b2fSDaniel Sanders 
4415c582b2fSDaniel Sanders template <typename InsnType>
4425c582b2fSDaniel Sanders static DecodeStatus
4435c582b2fSDaniel Sanders DecodeBgtzGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
4445c582b2fSDaniel Sanders                       const void *Decoder);
4455c582b2fSDaniel Sanders 
44628a0ca07SZoran Jovanovic template <typename InsnType>
44728a0ca07SZoran Jovanovic static DecodeStatus
44828a0ca07SZoran Jovanovic DecodeBlezGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
44928a0ca07SZoran Jovanovic                        const void *Decoder);
45028a0ca07SZoran Jovanovic 
451a4c4b5fcSZoran Jovanovic static DecodeStatus DecodeRegListOperand(MCInst &Inst, unsigned Insn,
452a4c4b5fcSZoran Jovanovic                                          uint64_t Address,
453a4c4b5fcSZoran Jovanovic                                          const void *Decoder);
454a4c4b5fcSZoran Jovanovic 
455f9a02500SZoran Jovanovic static DecodeStatus DecodeRegListOperand16(MCInst &Inst, unsigned Insn,
456f9a02500SZoran Jovanovic                                            uint64_t Address,
457f9a02500SZoran Jovanovic                                            const void *Decoder);
458f9a02500SZoran Jovanovic 
45941688679SZoran Jovanovic static DecodeStatus DecodeMovePRegPair(MCInst &Inst, unsigned Insn,
46041688679SZoran Jovanovic                                        uint64_t Address,
46141688679SZoran Jovanovic                                        const void *Decoder);
46241688679SZoran Jovanovic 
46371928e68SAkira Hatanaka namespace llvm {
46471928e68SAkira Hatanaka extern Target TheMipselTarget, TheMipsTarget, TheMips64Target,
46571928e68SAkira Hatanaka               TheMips64elTarget;
46671928e68SAkira Hatanaka }
46771928e68SAkira Hatanaka 
46871928e68SAkira Hatanaka static MCDisassembler *createMipsDisassembler(
46971928e68SAkira Hatanaka                        const Target &T,
470a1bc0f56SLang Hames                        const MCSubtargetInfo &STI,
471a1bc0f56SLang Hames                        MCContext &Ctx) {
472a1bc0f56SLang Hames   return new MipsDisassembler(STI, Ctx, true);
47371928e68SAkira Hatanaka }
47471928e68SAkira Hatanaka 
47571928e68SAkira Hatanaka static MCDisassembler *createMipselDisassembler(
47671928e68SAkira Hatanaka                        const Target &T,
477a1bc0f56SLang Hames                        const MCSubtargetInfo &STI,
478a1bc0f56SLang Hames                        MCContext &Ctx) {
479a1bc0f56SLang Hames   return new MipsDisassembler(STI, Ctx, false);
48071928e68SAkira Hatanaka }
48171928e68SAkira Hatanaka 
48271928e68SAkira Hatanaka extern "C" void LLVMInitializeMipsDisassembler() {
48371928e68SAkira Hatanaka   // Register the disassembler.
48471928e68SAkira Hatanaka   TargetRegistry::RegisterMCDisassembler(TheMipsTarget,
48571928e68SAkira Hatanaka                                          createMipsDisassembler);
48671928e68SAkira Hatanaka   TargetRegistry::RegisterMCDisassembler(TheMipselTarget,
48771928e68SAkira Hatanaka                                          createMipselDisassembler);
48871928e68SAkira Hatanaka   TargetRegistry::RegisterMCDisassembler(TheMips64Target,
489a19216c8SDaniel Sanders                                          createMipsDisassembler);
49071928e68SAkira Hatanaka   TargetRegistry::RegisterMCDisassembler(TheMips64elTarget,
491a19216c8SDaniel Sanders                                          createMipselDisassembler);
49271928e68SAkira Hatanaka }
49371928e68SAkira Hatanaka 
49471928e68SAkira Hatanaka #include "MipsGenDisassemblerTables.inc"
49571928e68SAkira Hatanaka 
4965c582b2fSDaniel Sanders static unsigned getReg(const void *D, unsigned RC, unsigned RegNo) {
497a19216c8SDaniel Sanders   const MipsDisassembler *Dis = static_cast<const MipsDisassembler*>(D);
4985c582b2fSDaniel Sanders   const MCRegisterInfo *RegInfo = Dis->getContext().getRegisterInfo();
4995c582b2fSDaniel Sanders   return *(RegInfo->getRegClass(RC).begin() + RegNo);
5005c582b2fSDaniel Sanders }
5015c582b2fSDaniel Sanders 
502b50ccf8eSDaniel Sanders template <typename InsnType>
503b50ccf8eSDaniel Sanders static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address,
504b50ccf8eSDaniel Sanders                                    const void *Decoder) {
505b50ccf8eSDaniel Sanders   typedef DecodeStatus (*DecodeFN)(MCInst &, unsigned, uint64_t, const void *);
506b50ccf8eSDaniel Sanders   // The size of the n field depends on the element size
507b50ccf8eSDaniel Sanders   // The register class also depends on this.
508b50ccf8eSDaniel Sanders   InsnType tmp = fieldFromInstruction(insn, 17, 5);
509b50ccf8eSDaniel Sanders   unsigned NSize = 0;
510b50ccf8eSDaniel Sanders   DecodeFN RegDecoder = nullptr;
511b50ccf8eSDaniel Sanders   if ((tmp & 0x18) == 0x00) { // INSVE_B
512b50ccf8eSDaniel Sanders     NSize = 4;
513b50ccf8eSDaniel Sanders     RegDecoder = DecodeMSA128BRegisterClass;
514b50ccf8eSDaniel Sanders   } else if ((tmp & 0x1c) == 0x10) { // INSVE_H
515b50ccf8eSDaniel Sanders     NSize = 3;
516b50ccf8eSDaniel Sanders     RegDecoder = DecodeMSA128HRegisterClass;
517b50ccf8eSDaniel Sanders   } else if ((tmp & 0x1e) == 0x18) { // INSVE_W
518b50ccf8eSDaniel Sanders     NSize = 2;
519b50ccf8eSDaniel Sanders     RegDecoder = DecodeMSA128WRegisterClass;
520b50ccf8eSDaniel Sanders   } else if ((tmp & 0x1f) == 0x1c) { // INSVE_D
521b50ccf8eSDaniel Sanders     NSize = 1;
522b50ccf8eSDaniel Sanders     RegDecoder = DecodeMSA128DRegisterClass;
523b50ccf8eSDaniel Sanders   } else
524b50ccf8eSDaniel Sanders     llvm_unreachable("Invalid encoding");
525b50ccf8eSDaniel Sanders 
526b50ccf8eSDaniel Sanders   assert(NSize != 0 && RegDecoder != nullptr);
527b50ccf8eSDaniel Sanders 
528b50ccf8eSDaniel Sanders   // $wd
529b50ccf8eSDaniel Sanders   tmp = fieldFromInstruction(insn, 6, 5);
530b50ccf8eSDaniel Sanders   if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
531b50ccf8eSDaniel Sanders     return MCDisassembler::Fail;
532b50ccf8eSDaniel Sanders   // $wd_in
533b50ccf8eSDaniel Sanders   if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
534b50ccf8eSDaniel Sanders     return MCDisassembler::Fail;
535b50ccf8eSDaniel Sanders   // $n
536b50ccf8eSDaniel Sanders   tmp = fieldFromInstruction(insn, 16, NSize);
537e9119e41SJim Grosbach   MI.addOperand(MCOperand::createImm(tmp));
538b50ccf8eSDaniel Sanders   // $ws
539b50ccf8eSDaniel Sanders   tmp = fieldFromInstruction(insn, 11, 5);
540b50ccf8eSDaniel Sanders   if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
541b50ccf8eSDaniel Sanders     return MCDisassembler::Fail;
542b50ccf8eSDaniel Sanders   // $n2
543e9119e41SJim Grosbach   MI.addOperand(MCOperand::createImm(0));
544b50ccf8eSDaniel Sanders 
545b50ccf8eSDaniel Sanders   return MCDisassembler::Success;
546b50ccf8eSDaniel Sanders }
547b50ccf8eSDaniel Sanders 
5485c582b2fSDaniel Sanders template <typename InsnType>
5495c582b2fSDaniel Sanders static DecodeStatus DecodeAddiGroupBranch(MCInst &MI, InsnType insn,
5505c582b2fSDaniel Sanders                                           uint64_t Address,
5515c582b2fSDaniel Sanders                                           const void *Decoder) {
5525c582b2fSDaniel Sanders   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
5535c582b2fSDaniel Sanders   // (otherwise we would have matched the ADDI instruction from the earlier
5545c582b2fSDaniel Sanders   // ISA's instead).
5555c582b2fSDaniel Sanders   //
5565c582b2fSDaniel Sanders   // We have:
5575c582b2fSDaniel Sanders   //    0b001000 sssss ttttt iiiiiiiiiiiiiiii
5585c582b2fSDaniel Sanders   //      BOVC if rs >= rt
5595c582b2fSDaniel Sanders   //      BEQZALC if rs == 0 && rt != 0
5605c582b2fSDaniel Sanders   //      BEQC if rs < rt && rs != 0
5615c582b2fSDaniel Sanders 
5625c582b2fSDaniel Sanders   InsnType Rs = fieldFromInstruction(insn, 21, 5);
5635c582b2fSDaniel Sanders   InsnType Rt = fieldFromInstruction(insn, 16, 5);
564d37bab61SAlexey Samsonov   InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4;
5655c582b2fSDaniel Sanders   bool HasRs = false;
5665c582b2fSDaniel Sanders 
5675c582b2fSDaniel Sanders   if (Rs >= Rt) {
5685c582b2fSDaniel Sanders     MI.setOpcode(Mips::BOVC);
5695c582b2fSDaniel Sanders     HasRs = true;
5705c582b2fSDaniel Sanders   } else if (Rs != 0 && Rs < Rt) {
5715c582b2fSDaniel Sanders     MI.setOpcode(Mips::BEQC);
5725c582b2fSDaniel Sanders     HasRs = true;
5735c582b2fSDaniel Sanders   } else
5745c582b2fSDaniel Sanders     MI.setOpcode(Mips::BEQZALC);
5755c582b2fSDaniel Sanders 
5765c582b2fSDaniel Sanders   if (HasRs)
577e9119e41SJim Grosbach     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
5785c582b2fSDaniel Sanders                                        Rs)));
5795c582b2fSDaniel Sanders 
580e9119e41SJim Grosbach   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
5815c582b2fSDaniel Sanders                                      Rt)));
582e9119e41SJim Grosbach   MI.addOperand(MCOperand::createImm(Imm));
5835c582b2fSDaniel Sanders 
5845c582b2fSDaniel Sanders   return MCDisassembler::Success;
5855c582b2fSDaniel Sanders }
5865c582b2fSDaniel Sanders 
5875c582b2fSDaniel Sanders template <typename InsnType>
5885c582b2fSDaniel Sanders static DecodeStatus DecodeDaddiGroupBranch(MCInst &MI, InsnType insn,
5895c582b2fSDaniel Sanders                                            uint64_t Address,
5905c582b2fSDaniel Sanders                                            const void *Decoder) {
5915c582b2fSDaniel Sanders   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
5925c582b2fSDaniel Sanders   // (otherwise we would have matched the ADDI instruction from the earlier
5935c582b2fSDaniel Sanders   // ISA's instead).
5945c582b2fSDaniel Sanders   //
5955c582b2fSDaniel Sanders   // We have:
5965c582b2fSDaniel Sanders   //    0b011000 sssss ttttt iiiiiiiiiiiiiiii
5975c582b2fSDaniel Sanders   //      BNVC if rs >= rt
5985c582b2fSDaniel Sanders   //      BNEZALC if rs == 0 && rt != 0
5995c582b2fSDaniel Sanders   //      BNEC if rs < rt && rs != 0
6005c582b2fSDaniel Sanders 
6015c582b2fSDaniel Sanders   InsnType Rs = fieldFromInstruction(insn, 21, 5);
6025c582b2fSDaniel Sanders   InsnType Rt = fieldFromInstruction(insn, 16, 5);
603d37bab61SAlexey Samsonov   InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4;
6045c582b2fSDaniel Sanders   bool HasRs = false;
6055c582b2fSDaniel Sanders 
6065c582b2fSDaniel Sanders   if (Rs >= Rt) {
6075c582b2fSDaniel Sanders     MI.setOpcode(Mips::BNVC);
6085c582b2fSDaniel Sanders     HasRs = true;
6095c582b2fSDaniel Sanders   } else if (Rs != 0 && Rs < Rt) {
6105c582b2fSDaniel Sanders     MI.setOpcode(Mips::BNEC);
6115c582b2fSDaniel Sanders     HasRs = true;
6125c582b2fSDaniel Sanders   } else
6135c582b2fSDaniel Sanders     MI.setOpcode(Mips::BNEZALC);
6145c582b2fSDaniel Sanders 
6155c582b2fSDaniel Sanders   if (HasRs)
616e9119e41SJim Grosbach     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
6175c582b2fSDaniel Sanders                                        Rs)));
6185c582b2fSDaniel Sanders 
619e9119e41SJim Grosbach   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
6205c582b2fSDaniel Sanders                                      Rt)));
621e9119e41SJim Grosbach   MI.addOperand(MCOperand::createImm(Imm));
6225c582b2fSDaniel Sanders 
6235c582b2fSDaniel Sanders   return MCDisassembler::Success;
6245c582b2fSDaniel Sanders }
6255c582b2fSDaniel Sanders 
6265c582b2fSDaniel Sanders template <typename InsnType>
6275c582b2fSDaniel Sanders static DecodeStatus DecodeBlezlGroupBranch(MCInst &MI, InsnType insn,
6285c582b2fSDaniel Sanders                                            uint64_t Address,
6295c582b2fSDaniel Sanders                                            const void *Decoder) {
6305c582b2fSDaniel Sanders   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
6315c582b2fSDaniel Sanders   // (otherwise we would have matched the BLEZL instruction from the earlier
6325c582b2fSDaniel Sanders   // ISA's instead).
6335c582b2fSDaniel Sanders   //
6345c582b2fSDaniel Sanders   // We have:
6355c582b2fSDaniel Sanders   //    0b010110 sssss ttttt iiiiiiiiiiiiiiii
6365c582b2fSDaniel Sanders   //      Invalid if rs == 0
6375c582b2fSDaniel Sanders   //      BLEZC   if rs == 0  && rt != 0
6385c582b2fSDaniel Sanders   //      BGEZC   if rs == rt && rt != 0
6395c582b2fSDaniel Sanders   //      BGEC    if rs != rt && rs != 0  && rt != 0
6405c582b2fSDaniel Sanders 
6415c582b2fSDaniel Sanders   InsnType Rs = fieldFromInstruction(insn, 21, 5);
6425c582b2fSDaniel Sanders   InsnType Rt = fieldFromInstruction(insn, 16, 5);
643d37bab61SAlexey Samsonov   InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4;
64428a0ca07SZoran Jovanovic   bool HasRs = false;
6455c582b2fSDaniel Sanders 
6465c582b2fSDaniel Sanders   if (Rt == 0)
6475c582b2fSDaniel Sanders     return MCDisassembler::Fail;
6485c582b2fSDaniel Sanders   else if (Rs == 0)
6495c582b2fSDaniel Sanders     MI.setOpcode(Mips::BLEZC);
6505c582b2fSDaniel Sanders   else if (Rs == Rt)
6515c582b2fSDaniel Sanders     MI.setOpcode(Mips::BGEZC);
65228a0ca07SZoran Jovanovic   else {
65328a0ca07SZoran Jovanovic     HasRs = true;
65428a0ca07SZoran Jovanovic     MI.setOpcode(Mips::BGEC);
65528a0ca07SZoran Jovanovic   }
65628a0ca07SZoran Jovanovic 
65728a0ca07SZoran Jovanovic   if (HasRs)
658e9119e41SJim Grosbach     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
65928a0ca07SZoran Jovanovic                                        Rs)));
6605c582b2fSDaniel Sanders 
661e9119e41SJim Grosbach   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
6625c582b2fSDaniel Sanders                                      Rt)));
6635c582b2fSDaniel Sanders 
664e9119e41SJim Grosbach   MI.addOperand(MCOperand::createImm(Imm));
6655c582b2fSDaniel Sanders 
6665c582b2fSDaniel Sanders   return MCDisassembler::Success;
6675c582b2fSDaniel Sanders }
6685c582b2fSDaniel Sanders 
6695c582b2fSDaniel Sanders template <typename InsnType>
6705c582b2fSDaniel Sanders static DecodeStatus DecodeBgtzlGroupBranch(MCInst &MI, InsnType insn,
6715c582b2fSDaniel Sanders                                            uint64_t Address,
6725c582b2fSDaniel Sanders                                            const void *Decoder) {
6735c582b2fSDaniel Sanders   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
6745c582b2fSDaniel Sanders   // (otherwise we would have matched the BGTZL instruction from the earlier
6755c582b2fSDaniel Sanders   // ISA's instead).
6765c582b2fSDaniel Sanders   //
6775c582b2fSDaniel Sanders   // We have:
6785c582b2fSDaniel Sanders   //    0b010111 sssss ttttt iiiiiiiiiiiiiiii
6795c582b2fSDaniel Sanders   //      Invalid if rs == 0
6805c582b2fSDaniel Sanders   //      BGTZC   if rs == 0  && rt != 0
6815c582b2fSDaniel Sanders   //      BLTZC   if rs == rt && rt != 0
6825c582b2fSDaniel Sanders   //      BLTC    if rs != rt && rs != 0  && rt != 0
6835c582b2fSDaniel Sanders 
6845c14b069SZoran Jovanovic   bool HasRs = false;
6855c14b069SZoran Jovanovic 
6865c582b2fSDaniel Sanders   InsnType Rs = fieldFromInstruction(insn, 21, 5);
6875c582b2fSDaniel Sanders   InsnType Rt = fieldFromInstruction(insn, 16, 5);
688d37bab61SAlexey Samsonov   InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4;
6895c582b2fSDaniel Sanders 
6905c582b2fSDaniel Sanders   if (Rt == 0)
6915c582b2fSDaniel Sanders     return MCDisassembler::Fail;
6925c582b2fSDaniel Sanders   else if (Rs == 0)
6935c582b2fSDaniel Sanders     MI.setOpcode(Mips::BGTZC);
6945c582b2fSDaniel Sanders   else if (Rs == Rt)
6955c582b2fSDaniel Sanders     MI.setOpcode(Mips::BLTZC);
6965c14b069SZoran Jovanovic   else {
6975c14b069SZoran Jovanovic     MI.setOpcode(Mips::BLTC);
6985c14b069SZoran Jovanovic     HasRs = true;
6995c14b069SZoran Jovanovic   }
7005c14b069SZoran Jovanovic 
7015c14b069SZoran Jovanovic   if (HasRs)
702e9119e41SJim Grosbach     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
7035c14b069SZoran Jovanovic                                               Rs)));
7045c582b2fSDaniel Sanders 
705e9119e41SJim Grosbach   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
7065c582b2fSDaniel Sanders                                      Rt)));
7075c582b2fSDaniel Sanders 
708e9119e41SJim Grosbach   MI.addOperand(MCOperand::createImm(Imm));
7095c582b2fSDaniel Sanders 
7105c582b2fSDaniel Sanders   return MCDisassembler::Success;
7115c582b2fSDaniel Sanders }
7125c582b2fSDaniel Sanders 
7135c582b2fSDaniel Sanders template <typename InsnType>
7145c582b2fSDaniel Sanders static DecodeStatus DecodeBgtzGroupBranch(MCInst &MI, InsnType insn,
7155c582b2fSDaniel Sanders                                           uint64_t Address,
7165c582b2fSDaniel Sanders                                           const void *Decoder) {
7175c582b2fSDaniel Sanders   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
7185c582b2fSDaniel Sanders   // (otherwise we would have matched the BGTZ instruction from the earlier
7195c582b2fSDaniel Sanders   // ISA's instead).
7205c582b2fSDaniel Sanders   //
7215c582b2fSDaniel Sanders   // We have:
7225c582b2fSDaniel Sanders   //    0b000111 sssss ttttt iiiiiiiiiiiiiiii
7235c582b2fSDaniel Sanders   //      BGTZ    if rt == 0
7245c582b2fSDaniel Sanders   //      BGTZALC if rs == 0 && rt != 0
7255c582b2fSDaniel Sanders   //      BLTZALC if rs != 0 && rs == rt
7265c582b2fSDaniel Sanders   //      BLTUC   if rs != 0 && rs != rt
7275c582b2fSDaniel Sanders 
7285c582b2fSDaniel Sanders   InsnType Rs = fieldFromInstruction(insn, 21, 5);
7295c582b2fSDaniel Sanders   InsnType Rt = fieldFromInstruction(insn, 16, 5);
730d37bab61SAlexey Samsonov   InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4;
7315c582b2fSDaniel Sanders   bool HasRs = false;
7325c582b2fSDaniel Sanders   bool HasRt = false;
7335c582b2fSDaniel Sanders 
7345c582b2fSDaniel Sanders   if (Rt == 0) {
7355c582b2fSDaniel Sanders     MI.setOpcode(Mips::BGTZ);
7365c582b2fSDaniel Sanders     HasRs = true;
7375c582b2fSDaniel Sanders   } else if (Rs == 0) {
7385c582b2fSDaniel Sanders     MI.setOpcode(Mips::BGTZALC);
7395c582b2fSDaniel Sanders     HasRt = true;
7405c582b2fSDaniel Sanders   } else if (Rs == Rt) {
7415c582b2fSDaniel Sanders     MI.setOpcode(Mips::BLTZALC);
7425c582b2fSDaniel Sanders     HasRs = true;
7435c14b069SZoran Jovanovic   } else {
7445c14b069SZoran Jovanovic     MI.setOpcode(Mips::BLTUC);
7455c14b069SZoran Jovanovic     HasRs = true;
7465c14b069SZoran Jovanovic     HasRt = true;
7475c14b069SZoran Jovanovic   }
7485c582b2fSDaniel Sanders 
7495c582b2fSDaniel Sanders   if (HasRs)
750e9119e41SJim Grosbach     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
7515c582b2fSDaniel Sanders                                        Rs)));
7525c582b2fSDaniel Sanders 
7535c582b2fSDaniel Sanders   if (HasRt)
754e9119e41SJim Grosbach     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
7555c582b2fSDaniel Sanders                                        Rt)));
7565c582b2fSDaniel Sanders 
757e9119e41SJim Grosbach   MI.addOperand(MCOperand::createImm(Imm));
7585c582b2fSDaniel Sanders 
7595c582b2fSDaniel Sanders   return MCDisassembler::Success;
7605c582b2fSDaniel Sanders }
7615c582b2fSDaniel Sanders 
76228a0ca07SZoran Jovanovic template <typename InsnType>
76328a0ca07SZoran Jovanovic static DecodeStatus DecodeBlezGroupBranch(MCInst &MI, InsnType insn,
76428a0ca07SZoran Jovanovic                                            uint64_t Address,
76528a0ca07SZoran Jovanovic                                            const void *Decoder) {
76628a0ca07SZoran Jovanovic   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
76728a0ca07SZoran Jovanovic   // (otherwise we would have matched the BLEZL instruction from the earlier
76828a0ca07SZoran Jovanovic   // ISA's instead).
76928a0ca07SZoran Jovanovic   //
77028a0ca07SZoran Jovanovic   // We have:
77128a0ca07SZoran Jovanovic   //    0b000110 sssss ttttt iiiiiiiiiiiiiiii
77228a0ca07SZoran Jovanovic   //      Invalid   if rs == 0
77328a0ca07SZoran Jovanovic   //      BLEZALC   if rs == 0  && rt != 0
77428a0ca07SZoran Jovanovic   //      BGEZALC   if rs == rt && rt != 0
77528a0ca07SZoran Jovanovic   //      BGEUC     if rs != rt && rs != 0  && rt != 0
77628a0ca07SZoran Jovanovic 
77728a0ca07SZoran Jovanovic   InsnType Rs = fieldFromInstruction(insn, 21, 5);
77828a0ca07SZoran Jovanovic   InsnType Rt = fieldFromInstruction(insn, 16, 5);
779d37bab61SAlexey Samsonov   InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4;
78028a0ca07SZoran Jovanovic   bool HasRs = false;
78128a0ca07SZoran Jovanovic 
78228a0ca07SZoran Jovanovic   if (Rt == 0)
78328a0ca07SZoran Jovanovic     return MCDisassembler::Fail;
78428a0ca07SZoran Jovanovic   else if (Rs == 0)
78528a0ca07SZoran Jovanovic     MI.setOpcode(Mips::BLEZALC);
78628a0ca07SZoran Jovanovic   else if (Rs == Rt)
78728a0ca07SZoran Jovanovic     MI.setOpcode(Mips::BGEZALC);
78828a0ca07SZoran Jovanovic   else {
78928a0ca07SZoran Jovanovic     HasRs = true;
79028a0ca07SZoran Jovanovic     MI.setOpcode(Mips::BGEUC);
79128a0ca07SZoran Jovanovic   }
79228a0ca07SZoran Jovanovic 
79328a0ca07SZoran Jovanovic   if (HasRs)
794e9119e41SJim Grosbach     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
79528a0ca07SZoran Jovanovic                                        Rs)));
796e9119e41SJim Grosbach   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
79728a0ca07SZoran Jovanovic                                      Rt)));
79828a0ca07SZoran Jovanovic 
799e9119e41SJim Grosbach   MI.addOperand(MCOperand::createImm(Imm));
80028a0ca07SZoran Jovanovic 
80128a0ca07SZoran Jovanovic   return MCDisassembler::Success;
80228a0ca07SZoran Jovanovic }
80328a0ca07SZoran Jovanovic 
804ea22c4cfSJozef Kolek /// Read two bytes from the ArrayRef and return 16 bit halfword sorted
805ea22c4cfSJozef Kolek /// according to the given endianess.
806ea22c4cfSJozef Kolek static DecodeStatus readInstruction16(ArrayRef<uint8_t> Bytes, uint64_t Address,
807ea22c4cfSJozef Kolek                                       uint64_t &Size, uint32_t &Insn,
808ea22c4cfSJozef Kolek                                       bool IsBigEndian) {
809ea22c4cfSJozef Kolek   // We want to read exactly 2 Bytes of data.
810ea22c4cfSJozef Kolek   if (Bytes.size() < 2) {
811ea22c4cfSJozef Kolek     Size = 0;
812ea22c4cfSJozef Kolek     return MCDisassembler::Fail;
813ea22c4cfSJozef Kolek   }
814ea22c4cfSJozef Kolek 
815ea22c4cfSJozef Kolek   if (IsBigEndian) {
816ea22c4cfSJozef Kolek     Insn = (Bytes[0] << 8) | Bytes[1];
817ea22c4cfSJozef Kolek   } else {
818ea22c4cfSJozef Kolek     Insn = (Bytes[1] << 8) | Bytes[0];
819ea22c4cfSJozef Kolek   }
820ea22c4cfSJozef Kolek 
821ea22c4cfSJozef Kolek   return MCDisassembler::Success;
822ea22c4cfSJozef Kolek }
823ea22c4cfSJozef Kolek 
8247fc5b874SRafael Espindola /// Read four bytes from the ArrayRef and return 32 bit word sorted
8254aa6bea7SRafael Espindola /// according to the given endianess
8267fc5b874SRafael Espindola static DecodeStatus readInstruction32(ArrayRef<uint8_t> Bytes, uint64_t Address,
8277fc5b874SRafael Espindola                                       uint64_t &Size, uint32_t &Insn,
8287fc5b874SRafael Espindola                                       bool IsBigEndian, bool IsMicroMips) {
82971928e68SAkira Hatanaka   // We want to read exactly 4 Bytes of data.
8307fc5b874SRafael Espindola   if (Bytes.size() < 4) {
8314aa6bea7SRafael Espindola     Size = 0;
83271928e68SAkira Hatanaka     return MCDisassembler::Fail;
83371928e68SAkira Hatanaka   }
83471928e68SAkira Hatanaka 
835ea22c4cfSJozef Kolek   // High 16 bits of a 32-bit microMIPS instruction (where the opcode is)
836ea22c4cfSJozef Kolek   // always precede the low 16 bits in the instruction stream (that is, they
837ea22c4cfSJozef Kolek   // are placed at lower addresses in the instruction stream).
838ea22c4cfSJozef Kolek   //
839ea22c4cfSJozef Kolek   // microMIPS byte ordering:
840ea22c4cfSJozef Kolek   //   Big-endian:    0 | 1 | 2 | 3
841ea22c4cfSJozef Kolek   //   Little-endian: 1 | 0 | 3 | 2
842ea22c4cfSJozef Kolek 
8434aa6bea7SRafael Espindola   if (IsBigEndian) {
84471928e68SAkira Hatanaka     // Encoded as a big-endian 32-bit word in the stream.
8454aa6bea7SRafael Espindola     Insn =
8464aa6bea7SRafael Espindola         (Bytes[3] << 0) | (Bytes[2] << 8) | (Bytes[1] << 16) | (Bytes[0] << 24);
8474aa6bea7SRafael Espindola   } else {
848dde3d582SVladimir Medic     if (IsMicroMips) {
8494aa6bea7SRafael Espindola       Insn = (Bytes[2] << 0) | (Bytes[3] << 8) | (Bytes[0] << 16) |
850dde3d582SVladimir Medic              (Bytes[1] << 24);
851dde3d582SVladimir Medic     } else {
8524aa6bea7SRafael Espindola       Insn = (Bytes[0] << 0) | (Bytes[1] << 8) | (Bytes[2] << 16) |
85371928e68SAkira Hatanaka              (Bytes[3] << 24);
85471928e68SAkira Hatanaka     }
855dde3d582SVladimir Medic   }
85671928e68SAkira Hatanaka 
85771928e68SAkira Hatanaka   return MCDisassembler::Success;
85871928e68SAkira Hatanaka }
85971928e68SAkira Hatanaka 
8604aa6bea7SRafael Espindola DecodeStatus MipsDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,
8617fc5b874SRafael Espindola                                               ArrayRef<uint8_t> Bytes,
86271928e68SAkira Hatanaka                                               uint64_t Address,
8634aa6bea7SRafael Espindola                                               raw_ostream &VStream,
8644aa6bea7SRafael Espindola                                               raw_ostream &CStream) const {
86571928e68SAkira Hatanaka   uint32_t Insn;
866ea22c4cfSJozef Kolek   DecodeStatus Result;
86771928e68SAkira Hatanaka 
868ea22c4cfSJozef Kolek   if (IsMicroMips) {
869ea22c4cfSJozef Kolek     Result = readInstruction16(Bytes, Address, Size, Insn, IsBigEndian);
870*ebee6129SReid Kleckner     if (Result == MCDisassembler::Fail)
871*ebee6129SReid Kleckner       return MCDisassembler::Fail;
872ea22c4cfSJozef Kolek 
873ada70918SZoran Jovanovic     if (hasMips32r6()) {
874ada70918SZoran Jovanovic       DEBUG(dbgs() << "Trying MicroMipsR616 table (16-bit instructions):\n");
875ada70918SZoran Jovanovic       // Calling the auto-generated decoder function for microMIPS32R6
876ada70918SZoran Jovanovic       // (and microMIPS64R6) 16-bit instructions.
877ada70918SZoran Jovanovic       Result = decodeInstruction(DecoderTableMicroMipsR616, Instr, Insn,
878ada70918SZoran Jovanovic                                  Address, this, STI);
879ada70918SZoran Jovanovic       if (Result != MCDisassembler::Fail) {
880ada70918SZoran Jovanovic         Size = 2;
881ada70918SZoran Jovanovic         return Result;
882ada70918SZoran Jovanovic       }
883ada70918SZoran Jovanovic     }
884ada70918SZoran Jovanovic 
885ea22c4cfSJozef Kolek     DEBUG(dbgs() << "Trying MicroMips16 table (16-bit instructions):\n");
886ada70918SZoran Jovanovic     // Calling the auto-generated decoder function for microMIPS 16-bit
887ada70918SZoran Jovanovic     // instructions.
888ea22c4cfSJozef Kolek     Result = decodeInstruction(DecoderTableMicroMips16, Instr, Insn, Address,
889ea22c4cfSJozef Kolek                                this, STI);
890ea22c4cfSJozef Kolek     if (Result != MCDisassembler::Fail) {
891ea22c4cfSJozef Kolek       Size = 2;
892ea22c4cfSJozef Kolek       return Result;
893ea22c4cfSJozef Kolek     }
894ea22c4cfSJozef Kolek 
895ea22c4cfSJozef Kolek     Result = readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, true);
89671928e68SAkira Hatanaka     if (Result == MCDisassembler::Fail)
89771928e68SAkira Hatanaka       return MCDisassembler::Fail;
89871928e68SAkira Hatanaka 
899676d6012SJozef Kolek     if (hasMips32r6()) {
900676d6012SJozef Kolek       DEBUG(dbgs() << "Trying MicroMips32r632 table (32-bit instructions):\n");
901676d6012SJozef Kolek       // Calling the auto-generated decoder function.
902366783e1SZoran Jovanovic       Result = decodeInstruction(DecoderTableMicroMipsR632, Instr, Insn, Address,
903676d6012SJozef Kolek                                  this, STI);
904ada70918SZoran Jovanovic       if (Result != MCDisassembler::Fail) {
905ada70918SZoran Jovanovic         Size = 4;
906ada70918SZoran Jovanovic         return Result;
907ada70918SZoran Jovanovic       }
908ada70918SZoran Jovanovic     }
909ada70918SZoran Jovanovic 
910ea22c4cfSJozef Kolek     DEBUG(dbgs() << "Trying MicroMips32 table (32-bit instructions):\n");
911dde3d582SVladimir Medic     // Calling the auto-generated decoder function.
9124aa6bea7SRafael Espindola     Result = decodeInstruction(DecoderTableMicroMips32, Instr, Insn, Address,
913dde3d582SVladimir Medic                                this, STI);
914dde3d582SVladimir Medic     if (Result != MCDisassembler::Fail) {
915dde3d582SVladimir Medic       Size = 4;
916dde3d582SVladimir Medic       return Result;
917dde3d582SVladimir Medic     }
918*ebee6129SReid Kleckner     // This is an invalid instruction. Let the disassembler move forward by the
919*ebee6129SReid Kleckner     // minimum instruction size.
920*ebee6129SReid Kleckner     Size = 2;
921dde3d582SVladimir Medic     return MCDisassembler::Fail;
922dde3d582SVladimir Medic   }
923dde3d582SVladimir Medic 
924ea22c4cfSJozef Kolek   Result = readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, false);
925*ebee6129SReid Kleckner   if (Result == MCDisassembler::Fail) {
926*ebee6129SReid Kleckner     Size = 4;
927ea22c4cfSJozef Kolek     return MCDisassembler::Fail;
928*ebee6129SReid Kleckner   }
929ea22c4cfSJozef Kolek 
930c171f65aSDaniel Sanders   if (hasCOP3()) {
931c171f65aSDaniel Sanders     DEBUG(dbgs() << "Trying COP3_ table (32-bit opcodes):\n");
932c171f65aSDaniel Sanders     Result =
9334aa6bea7SRafael Espindola         decodeInstruction(DecoderTableCOP3_32, Instr, Insn, Address, this, STI);
934c171f65aSDaniel Sanders     if (Result != MCDisassembler::Fail) {
935c171f65aSDaniel Sanders       Size = 4;
936c171f65aSDaniel Sanders       return Result;
937c171f65aSDaniel Sanders     }
938c171f65aSDaniel Sanders   }
939c171f65aSDaniel Sanders 
940c171f65aSDaniel Sanders   if (hasMips32r6() && isGP64()) {
9410fa60416SDaniel Sanders     DEBUG(dbgs() << "Trying Mips32r6_64r6 (GPR64) table (32-bit opcodes):\n");
9424aa6bea7SRafael Espindola     Result = decodeInstruction(DecoderTableMips32r6_64r6_GP6432, Instr, Insn,
9430fa60416SDaniel Sanders                                Address, this, STI);
9440fa60416SDaniel Sanders     if (Result != MCDisassembler::Fail) {
9450fa60416SDaniel Sanders       Size = 4;
9460fa60416SDaniel Sanders       return Result;
9470fa60416SDaniel Sanders     }
9480fa60416SDaniel Sanders   }
9490fa60416SDaniel Sanders 
950c171f65aSDaniel Sanders   if (hasMips32r6()) {
9510fa60416SDaniel Sanders     DEBUG(dbgs() << "Trying Mips32r6_64r6 table (32-bit opcodes):\n");
9524aa6bea7SRafael Espindola     Result = decodeInstruction(DecoderTableMips32r6_64r632, Instr, Insn,
9535c582b2fSDaniel Sanders                                Address, this, STI);
9545c582b2fSDaniel Sanders     if (Result != MCDisassembler::Fail) {
9555c582b2fSDaniel Sanders       Size = 4;
9565c582b2fSDaniel Sanders       return Result;
9575c582b2fSDaniel Sanders     }
9585c582b2fSDaniel Sanders   }
9595c582b2fSDaniel Sanders 
9603adf9b8dSKai Nacke   if (hasCnMips()) {
9613adf9b8dSKai Nacke     DEBUG(dbgs() << "Trying CnMips table (32-bit opcodes):\n");
9623adf9b8dSKai Nacke     Result = decodeInstruction(DecoderTableCnMips32, Instr, Insn,
9633adf9b8dSKai Nacke                                Address, this, STI);
9643adf9b8dSKai Nacke     if (Result != MCDisassembler::Fail) {
9653adf9b8dSKai Nacke       Size = 4;
9663adf9b8dSKai Nacke       return Result;
9673adf9b8dSKai Nacke     }
9683adf9b8dSKai Nacke   }
9693adf9b8dSKai Nacke 
970a19216c8SDaniel Sanders   if (isGP64()) {
971a19216c8SDaniel Sanders     DEBUG(dbgs() << "Trying Mips64 (GPR64) table (32-bit opcodes):\n");
972a19216c8SDaniel Sanders     Result = decodeInstruction(DecoderTableMips6432, Instr, Insn,
973a19216c8SDaniel Sanders                                Address, this, STI);
974a19216c8SDaniel Sanders     if (Result != MCDisassembler::Fail) {
975a19216c8SDaniel Sanders       Size = 4;
976a19216c8SDaniel Sanders       return Result;
977a19216c8SDaniel Sanders     }
978a19216c8SDaniel Sanders   }
979a19216c8SDaniel Sanders 
9800fa60416SDaniel Sanders   DEBUG(dbgs() << "Trying Mips table (32-bit opcodes):\n");
98171928e68SAkira Hatanaka   // Calling the auto-generated decoder function.
9824aa6bea7SRafael Espindola   Result =
9834aa6bea7SRafael Espindola       decodeInstruction(DecoderTableMips32, Instr, Insn, Address, this, STI);
98471928e68SAkira Hatanaka   if (Result != MCDisassembler::Fail) {
98571928e68SAkira Hatanaka     Size = 4;
98671928e68SAkira Hatanaka     return Result;
98771928e68SAkira Hatanaka   }
98871928e68SAkira Hatanaka 
989*ebee6129SReid Kleckner   Size = 4;
99071928e68SAkira Hatanaka   return MCDisassembler::Fail;
99171928e68SAkira Hatanaka }
99271928e68SAkira Hatanaka 
993ec8a5490SReed Kotler static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst,
994ec8a5490SReed Kotler                                                  unsigned RegNo,
995ec8a5490SReed Kotler                                                  uint64_t Address,
996ec8a5490SReed Kotler                                                  const void *Decoder) {
997ec8a5490SReed Kotler 
998ec8a5490SReed Kotler   return MCDisassembler::Fail;
999ec8a5490SReed Kotler 
1000ec8a5490SReed Kotler }
1001ec8a5490SReed Kotler 
100213e6ccf3SAkira Hatanaka static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst,
100371928e68SAkira Hatanaka                                              unsigned RegNo,
100471928e68SAkira Hatanaka                                              uint64_t Address,
100571928e68SAkira Hatanaka                                              const void *Decoder) {
100671928e68SAkira Hatanaka 
100771928e68SAkira Hatanaka   if (RegNo > 31)
100871928e68SAkira Hatanaka     return MCDisassembler::Fail;
100971928e68SAkira Hatanaka 
101013e6ccf3SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::GPR64RegClassID, RegNo);
1011e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
101271928e68SAkira Hatanaka   return MCDisassembler::Success;
101371928e68SAkira Hatanaka }
101471928e68SAkira Hatanaka 
1015b0852e54SZoran Jovanovic static DecodeStatus DecodeGPRMM16RegisterClass(MCInst &Inst,
1016b0852e54SZoran Jovanovic                                                unsigned RegNo,
1017b0852e54SZoran Jovanovic                                                uint64_t Address,
1018b0852e54SZoran Jovanovic                                                const void *Decoder) {
1019ea22c4cfSJozef Kolek   if (RegNo > 7)
1020b0852e54SZoran Jovanovic     return MCDisassembler::Fail;
1021ea22c4cfSJozef Kolek   unsigned Reg = getReg(Decoder, Mips::GPRMM16RegClassID, RegNo);
1022e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1023ea22c4cfSJozef Kolek   return MCDisassembler::Success;
1024b0852e54SZoran Jovanovic }
1025b0852e54SZoran Jovanovic 
10261904fa21SJozef Kolek static DecodeStatus DecodeGPRMM16ZeroRegisterClass(MCInst &Inst,
10271904fa21SJozef Kolek                                                    unsigned RegNo,
10281904fa21SJozef Kolek                                                    uint64_t Address,
10291904fa21SJozef Kolek                                                    const void *Decoder) {
1030315e7ecaSJozef Kolek   if (RegNo > 7)
10311904fa21SJozef Kolek     return MCDisassembler::Fail;
1032315e7ecaSJozef Kolek   unsigned Reg = getReg(Decoder, Mips::GPRMM16ZeroRegClassID, RegNo);
1033e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1034315e7ecaSJozef Kolek   return MCDisassembler::Success;
10351904fa21SJozef Kolek }
10361904fa21SJozef Kolek 
103741688679SZoran Jovanovic static DecodeStatus DecodeGPRMM16MovePRegisterClass(MCInst &Inst,
103841688679SZoran Jovanovic                                                     unsigned RegNo,
103941688679SZoran Jovanovic                                                     uint64_t Address,
104041688679SZoran Jovanovic                                                     const void *Decoder) {
104141688679SZoran Jovanovic   if (RegNo > 7)
104241688679SZoran Jovanovic     return MCDisassembler::Fail;
104341688679SZoran Jovanovic   unsigned Reg = getReg(Decoder, Mips::GPRMM16MovePRegClassID, RegNo);
1044e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
104541688679SZoran Jovanovic   return MCDisassembler::Success;
104641688679SZoran Jovanovic }
104741688679SZoran Jovanovic 
104813e6ccf3SAkira Hatanaka static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst,
104971928e68SAkira Hatanaka                                              unsigned RegNo,
105071928e68SAkira Hatanaka                                              uint64_t Address,
105171928e68SAkira Hatanaka                                              const void *Decoder) {
105271928e68SAkira Hatanaka   if (RegNo > 31)
105371928e68SAkira Hatanaka     return MCDisassembler::Fail;
105413e6ccf3SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::GPR32RegClassID, RegNo);
1055e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
105671928e68SAkira Hatanaka   return MCDisassembler::Success;
105771928e68SAkira Hatanaka }
105871928e68SAkira Hatanaka 
10599bfa2e2eSAkira Hatanaka static DecodeStatus DecodePtrRegisterClass(MCInst &Inst,
10609bfa2e2eSAkira Hatanaka                                            unsigned RegNo,
10619bfa2e2eSAkira Hatanaka                                            uint64_t Address,
10629bfa2e2eSAkira Hatanaka                                            const void *Decoder) {
1063a19216c8SDaniel Sanders   if (static_cast<const MipsDisassembler *>(Decoder)->isGP64())
10649bfa2e2eSAkira Hatanaka     return DecodeGPR64RegisterClass(Inst, RegNo, Address, Decoder);
10659bfa2e2eSAkira Hatanaka 
10669bfa2e2eSAkira Hatanaka   return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
10679bfa2e2eSAkira Hatanaka }
10689bfa2e2eSAkira Hatanaka 
1069654655f1SAkira Hatanaka static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst,
1070ecabd1a5SAkira Hatanaka                                             unsigned RegNo,
1071ecabd1a5SAkira Hatanaka                                             uint64_t Address,
1072ecabd1a5SAkira Hatanaka                                             const void *Decoder) {
107313e6ccf3SAkira Hatanaka   return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
1074ecabd1a5SAkira Hatanaka }
1075ecabd1a5SAkira Hatanaka 
107671928e68SAkira Hatanaka static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
107771928e68SAkira Hatanaka                                              unsigned RegNo,
107871928e68SAkira Hatanaka                                              uint64_t Address,
107971928e68SAkira Hatanaka                                              const void *Decoder) {
108071928e68SAkira Hatanaka   if (RegNo > 31)
108171928e68SAkira Hatanaka     return MCDisassembler::Fail;
108271928e68SAkira Hatanaka 
10839bf2b567SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::FGR64RegClassID, RegNo);
1084e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
108571928e68SAkira Hatanaka   return MCDisassembler::Success;
108671928e68SAkira Hatanaka }
108771928e68SAkira Hatanaka 
108871928e68SAkira Hatanaka static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
108971928e68SAkira Hatanaka                                              unsigned RegNo,
109071928e68SAkira Hatanaka                                              uint64_t Address,
109171928e68SAkira Hatanaka                                              const void *Decoder) {
109271928e68SAkira Hatanaka   if (RegNo > 31)
109371928e68SAkira Hatanaka     return MCDisassembler::Fail;
109471928e68SAkira Hatanaka 
10959bf2b567SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::FGR32RegClassID, RegNo);
1096e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
109771928e68SAkira Hatanaka   return MCDisassembler::Success;
109871928e68SAkira Hatanaka }
109971928e68SAkira Hatanaka 
110071928e68SAkira Hatanaka static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
110171928e68SAkira Hatanaka                                            unsigned RegNo,
110271928e68SAkira Hatanaka                                            uint64_t Address,
110371928e68SAkira Hatanaka                                            const void *Decoder) {
1104253777fdSChad Rosier   if (RegNo > 31)
1105253777fdSChad Rosier     return MCDisassembler::Fail;
1106253777fdSChad Rosier   unsigned Reg = getReg(Decoder, Mips::CCRRegClassID, RegNo);
1107e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
110871928e68SAkira Hatanaka   return MCDisassembler::Success;
110971928e68SAkira Hatanaka }
111071928e68SAkira Hatanaka 
11111fb1b8b8SAkira Hatanaka static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst,
11121fb1b8b8SAkira Hatanaka                                            unsigned RegNo,
11131fb1b8b8SAkira Hatanaka                                            uint64_t Address,
11141fb1b8b8SAkira Hatanaka                                            const void *Decoder) {
11151fb1b8b8SAkira Hatanaka   if (RegNo > 7)
11161fb1b8b8SAkira Hatanaka     return MCDisassembler::Fail;
11171fb1b8b8SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::FCCRegClassID, RegNo);
1118e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
11191fb1b8b8SAkira Hatanaka   return MCDisassembler::Success;
11201fb1b8b8SAkira Hatanaka }
11211fb1b8b8SAkira Hatanaka 
11220fa60416SDaniel Sanders static DecodeStatus DecodeFGRCCRegisterClass(MCInst &Inst, unsigned RegNo,
11230fa60416SDaniel Sanders                                              uint64_t Address,
11240fa60416SDaniel Sanders                                              const void *Decoder) {
11250fa60416SDaniel Sanders   if (RegNo > 31)
11260fa60416SDaniel Sanders     return MCDisassembler::Fail;
11270fa60416SDaniel Sanders 
11280fa60416SDaniel Sanders   unsigned Reg = getReg(Decoder, Mips::FGRCCRegClassID, RegNo);
1129e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
11300fa60416SDaniel Sanders   return MCDisassembler::Success;
11310fa60416SDaniel Sanders }
11320fa60416SDaniel Sanders 
113371928e68SAkira Hatanaka static DecodeStatus DecodeMem(MCInst &Inst,
113471928e68SAkira Hatanaka                               unsigned Insn,
113571928e68SAkira Hatanaka                               uint64_t Address,
113671928e68SAkira Hatanaka                               const void *Decoder) {
113771928e68SAkira Hatanaka   int Offset = SignExtend32<16>(Insn & 0xffff);
1138ecaef49fSJim Grosbach   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1139ecaef49fSJim Grosbach   unsigned Base = fieldFromInstruction(Insn, 21, 5);
11409bf2b567SAkira Hatanaka 
114113e6ccf3SAkira Hatanaka   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
114213e6ccf3SAkira Hatanaka   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
114371928e68SAkira Hatanaka 
1144d7ecf49eSVladimir Medic   if (Inst.getOpcode() == Mips::SC ||
1145e4e83a7bSDaniel Sanders       Inst.getOpcode() == Mips::SCD)
1146e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Reg));
1147e4e83a7bSDaniel Sanders 
1148e4e83a7bSDaniel Sanders   Inst.addOperand(MCOperand::createReg(Reg));
1149e4e83a7bSDaniel Sanders   Inst.addOperand(MCOperand::createReg(Base));
1150e4e83a7bSDaniel Sanders   Inst.addOperand(MCOperand::createImm(Offset));
1151e4e83a7bSDaniel Sanders 
1152e4e83a7bSDaniel Sanders   return MCDisassembler::Success;
115371928e68SAkira Hatanaka }
115471928e68SAkira Hatanaka 
1155e4e83a7bSDaniel Sanders static DecodeStatus DecodeMemEVA(MCInst &Inst,
1156e4e83a7bSDaniel Sanders                                  unsigned Insn,
1157e4e83a7bSDaniel Sanders                                  uint64_t Address,
1158e4e83a7bSDaniel Sanders                                  const void *Decoder) {
1159e4e83a7bSDaniel Sanders   int Offset = SignExtend32<9>(Insn >> 7);
1160e4e83a7bSDaniel Sanders   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1161e4e83a7bSDaniel Sanders   unsigned Base = fieldFromInstruction(Insn, 21, 5);
1162e4e83a7bSDaniel Sanders 
1163e4e83a7bSDaniel Sanders   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1164e4e83a7bSDaniel Sanders   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1165e4e83a7bSDaniel Sanders 
1166e4e83a7bSDaniel Sanders    if (Inst.getOpcode() == Mips::SCE)
1167e4e83a7bSDaniel Sanders      Inst.addOperand(MCOperand::createReg(Reg));
1168e4e83a7bSDaniel Sanders 
1169e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1170e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1171e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
117271928e68SAkira Hatanaka 
117371928e68SAkira Hatanaka   return MCDisassembler::Success;
117471928e68SAkira Hatanaka }
117571928e68SAkira Hatanaka 
11763c88fbd3SHrvoje Varga static DecodeStatus DecodeLoadByte9(MCInst &Inst,
11773c88fbd3SHrvoje Varga                                     unsigned Insn,
11783c88fbd3SHrvoje Varga                                     uint64_t Address,
11793c88fbd3SHrvoje Varga                                     const void *Decoder) {
11803c88fbd3SHrvoje Varga   int Offset = SignExtend32<9>(Insn & 0x1ff);
11813c88fbd3SHrvoje Varga   unsigned Base = fieldFromInstruction(Insn, 16, 5);
11823c88fbd3SHrvoje Varga   unsigned Reg = fieldFromInstruction(Insn, 21, 5);
11833c88fbd3SHrvoje Varga 
11843c88fbd3SHrvoje Varga   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
11853c88fbd3SHrvoje Varga   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
11863c88fbd3SHrvoje Varga 
11873c88fbd3SHrvoje Varga   Inst.addOperand(MCOperand::createReg(Reg));
11883c88fbd3SHrvoje Varga   Inst.addOperand(MCOperand::createReg(Base));
11893c88fbd3SHrvoje Varga   Inst.addOperand(MCOperand::createImm(Offset));
11903c88fbd3SHrvoje Varga 
11913c88fbd3SHrvoje Varga   return MCDisassembler::Success;
11923c88fbd3SHrvoje Varga }
11933c88fbd3SHrvoje Varga 
11943c88fbd3SHrvoje Varga static DecodeStatus DecodeLoadByte15(MCInst &Inst,
11953c88fbd3SHrvoje Varga                                      unsigned Insn,
11963c88fbd3SHrvoje Varga                                      uint64_t Address,
11973c88fbd3SHrvoje Varga                                      const void *Decoder) {
11983c88fbd3SHrvoje Varga   int Offset = SignExtend32<16>(Insn & 0xffff);
11993c88fbd3SHrvoje Varga   unsigned Base = fieldFromInstruction(Insn, 16, 5);
12003c88fbd3SHrvoje Varga   unsigned Reg = fieldFromInstruction(Insn, 21, 5);
12013c88fbd3SHrvoje Varga 
12023c88fbd3SHrvoje Varga   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
12033c88fbd3SHrvoje Varga   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
12043c88fbd3SHrvoje Varga 
12053c88fbd3SHrvoje Varga   Inst.addOperand(MCOperand::createReg(Reg));
12063c88fbd3SHrvoje Varga   Inst.addOperand(MCOperand::createReg(Base));
12073c88fbd3SHrvoje Varga   Inst.addOperand(MCOperand::createImm(Offset));
12083c88fbd3SHrvoje Varga 
12093c88fbd3SHrvoje Varga   return MCDisassembler::Success;
12103c88fbd3SHrvoje Varga }
12113c88fbd3SHrvoje Varga 
121292db6b78SDaniel Sanders static DecodeStatus DecodeCacheOp(MCInst &Inst,
121392db6b78SDaniel Sanders                               unsigned Insn,
121492db6b78SDaniel Sanders                               uint64_t Address,
121592db6b78SDaniel Sanders                               const void *Decoder) {
121692db6b78SDaniel Sanders   int Offset = SignExtend32<16>(Insn & 0xffff);
121792db6b78SDaniel Sanders   unsigned Hint = fieldFromInstruction(Insn, 16, 5);
121892db6b78SDaniel Sanders   unsigned Base = fieldFromInstruction(Insn, 21, 5);
121992db6b78SDaniel Sanders 
122092db6b78SDaniel Sanders   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
122192db6b78SDaniel Sanders 
1222e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1223e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
1224e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Hint));
122592db6b78SDaniel Sanders 
122692db6b78SDaniel Sanders   return MCDisassembler::Success;
122792db6b78SDaniel Sanders }
122892db6b78SDaniel Sanders 
1229ab6d1cceSJozef Kolek static DecodeStatus DecodeCacheOpMM(MCInst &Inst,
1230ab6d1cceSJozef Kolek                                     unsigned Insn,
1231ab6d1cceSJozef Kolek                                     uint64_t Address,
1232ab6d1cceSJozef Kolek                                     const void *Decoder) {
1233ab6d1cceSJozef Kolek   int Offset = SignExtend32<12>(Insn & 0xfff);
1234ab6d1cceSJozef Kolek   unsigned Base = fieldFromInstruction(Insn, 16, 5);
1235ab6d1cceSJozef Kolek   unsigned Hint = fieldFromInstruction(Insn, 21, 5);
1236ab6d1cceSJozef Kolek 
1237ab6d1cceSJozef Kolek   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1238ab6d1cceSJozef Kolek 
1239e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1240e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
1241e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Hint));
1242ab6d1cceSJozef Kolek 
1243ab6d1cceSJozef Kolek   return MCDisassembler::Success;
1244ab6d1cceSJozef Kolek }
1245ab6d1cceSJozef Kolek 
1246d9790793SZoran Jovanovic static DecodeStatus DecodePrefeOpMM(MCInst &Inst,
1247d9790793SZoran Jovanovic                                     unsigned Insn,
1248d9790793SZoran Jovanovic                                     uint64_t Address,
1249d9790793SZoran Jovanovic                                     const void *Decoder) {
1250d9790793SZoran Jovanovic   int Offset = SignExtend32<9>(Insn & 0x1ff);
1251d9790793SZoran Jovanovic   unsigned Base = fieldFromInstruction(Insn, 16, 5);
1252d9790793SZoran Jovanovic   unsigned Hint = fieldFromInstruction(Insn, 21, 5);
1253d9790793SZoran Jovanovic 
1254d9790793SZoran Jovanovic   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1255d9790793SZoran Jovanovic 
1256d9790793SZoran Jovanovic   Inst.addOperand(MCOperand::createReg(Base));
1257d9790793SZoran Jovanovic   Inst.addOperand(MCOperand::createImm(Offset));
1258d9790793SZoran Jovanovic   Inst.addOperand(MCOperand::createImm(Hint));
1259d9790793SZoran Jovanovic 
1260d9790793SZoran Jovanovic   return MCDisassembler::Success;
1261d9790793SZoran Jovanovic }
1262d9790793SZoran Jovanovic 
1263e4e83a7bSDaniel Sanders static DecodeStatus DecodeCacheeOp_CacheOpR6(MCInst &Inst,
1264df464ae2SVladimir Medic                                              unsigned Insn,
1265df464ae2SVladimir Medic                                              uint64_t Address,
1266df464ae2SVladimir Medic                                              const void *Decoder) {
1267e4e83a7bSDaniel Sanders   int Offset = SignExtend32<9>(Insn >> 7);
1268df464ae2SVladimir Medic   unsigned Hint = fieldFromInstruction(Insn, 16, 5);
1269df464ae2SVladimir Medic   unsigned Base = fieldFromInstruction(Insn, 21, 5);
1270df464ae2SVladimir Medic 
1271df464ae2SVladimir Medic   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1272df464ae2SVladimir Medic 
1273e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1274e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
1275e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Hint));
1276df464ae2SVladimir Medic 
1277df464ae2SVladimir Medic   return MCDisassembler::Success;
1278df464ae2SVladimir Medic }
1279df464ae2SVladimir Medic 
12809eaa30d2SZoran Jovanovic static DecodeStatus DecodeStoreEvaOpMM(MCInst &Inst,
12819eaa30d2SZoran Jovanovic                                        unsigned Insn,
12829eaa30d2SZoran Jovanovic                                        uint64_t Address,
12839eaa30d2SZoran Jovanovic                                        const void *Decoder) {
12849eaa30d2SZoran Jovanovic   int Offset = SignExtend32<9>(Insn & 0x1ff);
12859eaa30d2SZoran Jovanovic   unsigned Reg = fieldFromInstruction(Insn, 21, 5);
12869eaa30d2SZoran Jovanovic   unsigned Base = fieldFromInstruction(Insn, 16, 5);
12879eaa30d2SZoran Jovanovic 
12889eaa30d2SZoran Jovanovic   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
12899eaa30d2SZoran Jovanovic   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
12909eaa30d2SZoran Jovanovic 
12919eaa30d2SZoran Jovanovic   Inst.addOperand(MCOperand::createReg(Reg));
12929eaa30d2SZoran Jovanovic   Inst.addOperand(MCOperand::createReg(Base));
12939eaa30d2SZoran Jovanovic   Inst.addOperand(MCOperand::createImm(Offset));
12949eaa30d2SZoran Jovanovic 
12959eaa30d2SZoran Jovanovic   return MCDisassembler::Success;
12969eaa30d2SZoran Jovanovic }
12979eaa30d2SZoran Jovanovic 
1298b4484d62SDaniel Sanders static DecodeStatus DecodeSyncI(MCInst &Inst,
1299b4484d62SDaniel Sanders                               unsigned Insn,
1300b4484d62SDaniel Sanders                               uint64_t Address,
1301b4484d62SDaniel Sanders                               const void *Decoder) {
1302b4484d62SDaniel Sanders   int Offset = SignExtend32<16>(Insn & 0xffff);
1303b4484d62SDaniel Sanders   unsigned Base = fieldFromInstruction(Insn, 21, 5);
1304b4484d62SDaniel Sanders 
1305b4484d62SDaniel Sanders   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1306b4484d62SDaniel Sanders 
1307e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1308e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
1309b4484d62SDaniel Sanders 
1310b4484d62SDaniel Sanders   return MCDisassembler::Success;
1311b4484d62SDaniel Sanders }
1312b4484d62SDaniel Sanders 
131318148671SHrvoje Varga static DecodeStatus DecodeSynciR6(MCInst &Inst,
131418148671SHrvoje Varga                                   unsigned Insn,
131518148671SHrvoje Varga                                   uint64_t Address,
131618148671SHrvoje Varga                                   const void *Decoder) {
131718148671SHrvoje Varga   int Immediate = SignExtend32<16>(Insn & 0xffff);
131818148671SHrvoje Varga   unsigned Base = fieldFromInstruction(Insn, 16, 5);
131918148671SHrvoje Varga 
132018148671SHrvoje Varga   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
132118148671SHrvoje Varga 
132218148671SHrvoje Varga   Inst.addOperand(MCOperand::createReg(Base));
132318148671SHrvoje Varga   Inst.addOperand(MCOperand::createImm(Immediate));
132418148671SHrvoje Varga 
132518148671SHrvoje Varga   return MCDisassembler::Success;
132618148671SHrvoje Varga }
132718148671SHrvoje Varga 
1328fe0bf9f6SMatheus Almeida static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn,
1329fe0bf9f6SMatheus Almeida                                     uint64_t Address, const void *Decoder) {
1330fe0bf9f6SMatheus Almeida   int Offset = SignExtend32<10>(fieldFromInstruction(Insn, 16, 10));
1331fe0bf9f6SMatheus Almeida   unsigned Reg = fieldFromInstruction(Insn, 6, 5);
1332fe0bf9f6SMatheus Almeida   unsigned Base = fieldFromInstruction(Insn, 11, 5);
1333fe0bf9f6SMatheus Almeida 
1334fe0bf9f6SMatheus Almeida   Reg = getReg(Decoder, Mips::MSA128BRegClassID, Reg);
1335fe0bf9f6SMatheus Almeida   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1336fe0bf9f6SMatheus Almeida 
1337e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1338e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
13396b59c449SMatheus Almeida 
13406b59c449SMatheus Almeida   // The immediate field of an LD/ST instruction is scaled which means it must
13416b59c449SMatheus Almeida   // be multiplied (when decoding) by the size (in bytes) of the instructions'
13426b59c449SMatheus Almeida   // data format.
13436b59c449SMatheus Almeida   // .b - 1 byte
13446b59c449SMatheus Almeida   // .h - 2 bytes
13456b59c449SMatheus Almeida   // .w - 4 bytes
13466b59c449SMatheus Almeida   // .d - 8 bytes
13476b59c449SMatheus Almeida   switch(Inst.getOpcode())
13486b59c449SMatheus Almeida   {
13496b59c449SMatheus Almeida   default:
13506b59c449SMatheus Almeida     assert (0 && "Unexpected instruction");
13516b59c449SMatheus Almeida     return MCDisassembler::Fail;
13526b59c449SMatheus Almeida     break;
13536b59c449SMatheus Almeida   case Mips::LD_B:
13546b59c449SMatheus Almeida   case Mips::ST_B:
1355e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(Offset));
13566b59c449SMatheus Almeida     break;
13576b59c449SMatheus Almeida   case Mips::LD_H:
13586b59c449SMatheus Almeida   case Mips::ST_H:
1359e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(Offset * 2));
13606b59c449SMatheus Almeida     break;
13616b59c449SMatheus Almeida   case Mips::LD_W:
13626b59c449SMatheus Almeida   case Mips::ST_W:
1363e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(Offset * 4));
13646b59c449SMatheus Almeida     break;
13656b59c449SMatheus Almeida   case Mips::LD_D:
13666b59c449SMatheus Almeida   case Mips::ST_D:
1367e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(Offset * 8));
13686b59c449SMatheus Almeida     break;
13696b59c449SMatheus Almeida   }
1370fe0bf9f6SMatheus Almeida 
1371fe0bf9f6SMatheus Almeida   return MCDisassembler::Success;
1372fe0bf9f6SMatheus Almeida }
1373fe0bf9f6SMatheus Almeida 
1374315e7ecaSJozef Kolek static DecodeStatus DecodeMemMMImm4(MCInst &Inst,
1375315e7ecaSJozef Kolek                                     unsigned Insn,
1376315e7ecaSJozef Kolek                                     uint64_t Address,
1377315e7ecaSJozef Kolek                                     const void *Decoder) {
1378315e7ecaSJozef Kolek   unsigned Offset = Insn & 0xf;
1379315e7ecaSJozef Kolek   unsigned Reg = fieldFromInstruction(Insn, 7, 3);
1380315e7ecaSJozef Kolek   unsigned Base = fieldFromInstruction(Insn, 4, 3);
1381315e7ecaSJozef Kolek 
1382315e7ecaSJozef Kolek   switch (Inst.getOpcode()) {
1383315e7ecaSJozef Kolek     case Mips::LBU16_MM:
1384315e7ecaSJozef Kolek     case Mips::LHU16_MM:
1385315e7ecaSJozef Kolek     case Mips::LW16_MM:
1386315e7ecaSJozef Kolek       if (DecodeGPRMM16RegisterClass(Inst, Reg, Address, Decoder)
1387315e7ecaSJozef Kolek             == MCDisassembler::Fail)
1388315e7ecaSJozef Kolek         return MCDisassembler::Fail;
1389315e7ecaSJozef Kolek       break;
1390315e7ecaSJozef Kolek     case Mips::SB16_MM:
1391797c2aecSZlatko Buljan     case Mips::SB16_MMR6:
1392315e7ecaSJozef Kolek     case Mips::SH16_MM:
1393797c2aecSZlatko Buljan     case Mips::SH16_MMR6:
1394315e7ecaSJozef Kolek     case Mips::SW16_MM:
1395797c2aecSZlatko Buljan     case Mips::SW16_MMR6:
1396315e7ecaSJozef Kolek       if (DecodeGPRMM16ZeroRegisterClass(Inst, Reg, Address, Decoder)
1397315e7ecaSJozef Kolek             == MCDisassembler::Fail)
1398315e7ecaSJozef Kolek         return MCDisassembler::Fail;
1399315e7ecaSJozef Kolek       break;
1400315e7ecaSJozef Kolek   }
1401315e7ecaSJozef Kolek 
1402315e7ecaSJozef Kolek   if (DecodeGPRMM16RegisterClass(Inst, Base, Address, Decoder)
1403315e7ecaSJozef Kolek         == MCDisassembler::Fail)
1404315e7ecaSJozef Kolek     return MCDisassembler::Fail;
1405315e7ecaSJozef Kolek 
1406315e7ecaSJozef Kolek   switch (Inst.getOpcode()) {
1407315e7ecaSJozef Kolek     case Mips::LBU16_MM:
1408315e7ecaSJozef Kolek       if (Offset == 0xf)
1409e9119e41SJim Grosbach         Inst.addOperand(MCOperand::createImm(-1));
1410315e7ecaSJozef Kolek       else
1411e9119e41SJim Grosbach         Inst.addOperand(MCOperand::createImm(Offset));
1412315e7ecaSJozef Kolek       break;
1413315e7ecaSJozef Kolek     case Mips::SB16_MM:
1414797c2aecSZlatko Buljan     case Mips::SB16_MMR6:
1415e9119e41SJim Grosbach       Inst.addOperand(MCOperand::createImm(Offset));
1416315e7ecaSJozef Kolek       break;
1417315e7ecaSJozef Kolek     case Mips::LHU16_MM:
1418315e7ecaSJozef Kolek     case Mips::SH16_MM:
1419797c2aecSZlatko Buljan     case Mips::SH16_MMR6:
1420e9119e41SJim Grosbach       Inst.addOperand(MCOperand::createImm(Offset << 1));
1421315e7ecaSJozef Kolek       break;
1422315e7ecaSJozef Kolek     case Mips::LW16_MM:
1423315e7ecaSJozef Kolek     case Mips::SW16_MM:
1424797c2aecSZlatko Buljan     case Mips::SW16_MMR6:
1425e9119e41SJim Grosbach       Inst.addOperand(MCOperand::createImm(Offset << 2));
1426315e7ecaSJozef Kolek       break;
1427315e7ecaSJozef Kolek   }
1428315e7ecaSJozef Kolek 
1429315e7ecaSJozef Kolek   return MCDisassembler::Success;
1430315e7ecaSJozef Kolek }
1431315e7ecaSJozef Kolek 
143212c6982bSJozef Kolek static DecodeStatus DecodeMemMMSPImm5Lsl2(MCInst &Inst,
143312c6982bSJozef Kolek                                           unsigned Insn,
143412c6982bSJozef Kolek                                           uint64_t Address,
143512c6982bSJozef Kolek                                           const void *Decoder) {
143612c6982bSJozef Kolek   unsigned Offset = Insn & 0x1F;
143712c6982bSJozef Kolek   unsigned Reg = fieldFromInstruction(Insn, 5, 5);
143812c6982bSJozef Kolek 
143912c6982bSJozef Kolek   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
144012c6982bSJozef Kolek 
1441e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1442e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Mips::SP));
1443e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset << 2));
144412c6982bSJozef Kolek 
144512c6982bSJozef Kolek   return MCDisassembler::Success;
144612c6982bSJozef Kolek }
144712c6982bSJozef Kolek 
1448e10a02ecSJozef Kolek static DecodeStatus DecodeMemMMGPImm7Lsl2(MCInst &Inst,
1449e10a02ecSJozef Kolek                                           unsigned Insn,
1450e10a02ecSJozef Kolek                                           uint64_t Address,
1451e10a02ecSJozef Kolek                                           const void *Decoder) {
1452e10a02ecSJozef Kolek   unsigned Offset = Insn & 0x7F;
1453e10a02ecSJozef Kolek   unsigned Reg = fieldFromInstruction(Insn, 7, 3);
1454e10a02ecSJozef Kolek 
1455e10a02ecSJozef Kolek   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1456e10a02ecSJozef Kolek 
1457e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1458e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Mips::GP));
1459e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset << 2));
1460e10a02ecSJozef Kolek 
1461e10a02ecSJozef Kolek   return MCDisassembler::Success;
1462e10a02ecSJozef Kolek }
1463e10a02ecSJozef Kolek 
1464d68d424aSJozef Kolek static DecodeStatus DecodeMemMMReglistImm4Lsl2(MCInst &Inst,
1465d68d424aSJozef Kolek                                                unsigned Insn,
1466d68d424aSJozef Kolek                                                uint64_t Address,
1467d68d424aSJozef Kolek                                                const void *Decoder) {
1468797c2aecSZlatko Buljan   int Offset;
1469797c2aecSZlatko Buljan   switch (Inst.getOpcode()) {
1470797c2aecSZlatko Buljan   case Mips::LWM16_MMR6:
1471797c2aecSZlatko Buljan   case Mips::SWM16_MMR6:
1472797c2aecSZlatko Buljan     Offset = fieldFromInstruction(Insn, 4, 4);
1473797c2aecSZlatko Buljan     break;
1474797c2aecSZlatko Buljan   default:
1475797c2aecSZlatko Buljan     Offset = SignExtend32<4>(Insn & 0xf);
1476797c2aecSZlatko Buljan     break;
1477797c2aecSZlatko Buljan   }
1478d68d424aSJozef Kolek 
1479d68d424aSJozef Kolek   if (DecodeRegListOperand16(Inst, Insn, Address, Decoder)
1480d68d424aSJozef Kolek       == MCDisassembler::Fail)
1481d68d424aSJozef Kolek     return MCDisassembler::Fail;
1482d68d424aSJozef Kolek 
1483e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Mips::SP));
1484e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset << 2));
1485d68d424aSJozef Kolek 
1486d68d424aSJozef Kolek   return MCDisassembler::Success;
1487d68d424aSJozef Kolek }
1488d68d424aSJozef Kolek 
1489a6593ff6SZoran Jovanovic static DecodeStatus DecodeMemMMImm9(MCInst &Inst,
1490a6593ff6SZoran Jovanovic                                     unsigned Insn,
1491a6593ff6SZoran Jovanovic                                     uint64_t Address,
1492a6593ff6SZoran Jovanovic                                     const void *Decoder) {
1493a6593ff6SZoran Jovanovic   int Offset = SignExtend32<9>(Insn & 0x1ff);
1494a6593ff6SZoran Jovanovic   unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1495a6593ff6SZoran Jovanovic   unsigned Base = fieldFromInstruction(Insn, 16, 5);
1496a6593ff6SZoran Jovanovic 
1497a6593ff6SZoran Jovanovic   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1498a6593ff6SZoran Jovanovic   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1499a6593ff6SZoran Jovanovic 
15003ef4dd7bSHrvoje Varga   if (Inst.getOpcode() == Mips::SCE_MM)
15013ef4dd7bSHrvoje Varga     Inst.addOperand(MCOperand::createReg(Reg));
15023ef4dd7bSHrvoje Varga 
1503a6593ff6SZoran Jovanovic   Inst.addOperand(MCOperand::createReg(Reg));
1504a6593ff6SZoran Jovanovic   Inst.addOperand(MCOperand::createReg(Base));
1505a6593ff6SZoran Jovanovic   Inst.addOperand(MCOperand::createImm(Offset));
1506a6593ff6SZoran Jovanovic 
1507a6593ff6SZoran Jovanovic   return MCDisassembler::Success;
1508a6593ff6SZoran Jovanovic }
1509a6593ff6SZoran Jovanovic 
1510dde3d582SVladimir Medic static DecodeStatus DecodeMemMMImm12(MCInst &Inst,
1511dde3d582SVladimir Medic                                      unsigned Insn,
1512dde3d582SVladimir Medic                                      uint64_t Address,
1513dde3d582SVladimir Medic                                      const void *Decoder) {
1514dde3d582SVladimir Medic   int Offset = SignExtend32<12>(Insn & 0x0fff);
1515dde3d582SVladimir Medic   unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1516dde3d582SVladimir Medic   unsigned Base = fieldFromInstruction(Insn, 16, 5);
1517dde3d582SVladimir Medic 
1518dde3d582SVladimir Medic   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1519dde3d582SVladimir Medic   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1520dde3d582SVladimir Medic 
1521a4c4b5fcSZoran Jovanovic   switch (Inst.getOpcode()) {
1522a4c4b5fcSZoran Jovanovic   case Mips::SWM32_MM:
1523a4c4b5fcSZoran Jovanovic   case Mips::LWM32_MM:
1524a4c4b5fcSZoran Jovanovic     if (DecodeRegListOperand(Inst, Insn, Address, Decoder)
1525a4c4b5fcSZoran Jovanovic         == MCDisassembler::Fail)
1526a4c4b5fcSZoran Jovanovic       return MCDisassembler::Fail;
1527e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Base));
1528e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(Offset));
1529a4c4b5fcSZoran Jovanovic     break;
1530a4c4b5fcSZoran Jovanovic   case Mips::SC_MM:
1531e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Reg));
1532a4c4b5fcSZoran Jovanovic     // fallthrough
1533a4c4b5fcSZoran Jovanovic   default:
1534e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Reg));
15352deca348SZoran Jovanovic     if (Inst.getOpcode() == Mips::LWP_MM || Inst.getOpcode() == Mips::SWP_MM)
1536e9119e41SJim Grosbach       Inst.addOperand(MCOperand::createReg(Reg+1));
15372deca348SZoran Jovanovic 
1538e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Base));
1539e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(Offset));
1540a4c4b5fcSZoran Jovanovic   }
1541dde3d582SVladimir Medic 
1542dde3d582SVladimir Medic   return MCDisassembler::Success;
1543dde3d582SVladimir Medic }
1544dde3d582SVladimir Medic 
1545dde3d582SVladimir Medic static DecodeStatus DecodeMemMMImm16(MCInst &Inst,
1546dde3d582SVladimir Medic                                      unsigned Insn,
1547dde3d582SVladimir Medic                                      uint64_t Address,
1548dde3d582SVladimir Medic                                      const void *Decoder) {
1549dde3d582SVladimir Medic   int Offset = SignExtend32<16>(Insn & 0xffff);
1550dde3d582SVladimir Medic   unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1551dde3d582SVladimir Medic   unsigned Base = fieldFromInstruction(Insn, 16, 5);
1552dde3d582SVladimir Medic 
1553dde3d582SVladimir Medic   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1554dde3d582SVladimir Medic   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1555dde3d582SVladimir Medic 
1556e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1557e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1558e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
1559dde3d582SVladimir Medic 
1560dde3d582SVladimir Medic   return MCDisassembler::Success;
1561dde3d582SVladimir Medic }
1562dde3d582SVladimir Medic 
156371928e68SAkira Hatanaka static DecodeStatus DecodeFMem(MCInst &Inst,
156471928e68SAkira Hatanaka                                unsigned Insn,
156571928e68SAkira Hatanaka                                uint64_t Address,
156671928e68SAkira Hatanaka                                const void *Decoder) {
156771928e68SAkira Hatanaka   int Offset = SignExtend32<16>(Insn & 0xffff);
1568ecaef49fSJim Grosbach   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1569ecaef49fSJim Grosbach   unsigned Base = fieldFromInstruction(Insn, 21, 5);
157071928e68SAkira Hatanaka 
15719bf2b567SAkira Hatanaka   Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg);
157213e6ccf3SAkira Hatanaka   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
15739bf2b567SAkira Hatanaka 
1574e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1575e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1576e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
157771928e68SAkira Hatanaka 
157871928e68SAkira Hatanaka   return MCDisassembler::Success;
157971928e68SAkira Hatanaka }
158071928e68SAkira Hatanaka 
158192db6b78SDaniel Sanders static DecodeStatus DecodeFMem2(MCInst &Inst,
158292db6b78SDaniel Sanders                                unsigned Insn,
158392db6b78SDaniel Sanders                                uint64_t Address,
158492db6b78SDaniel Sanders                                const void *Decoder) {
158592db6b78SDaniel Sanders   int Offset = SignExtend32<16>(Insn & 0xffff);
158692db6b78SDaniel Sanders   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
158792db6b78SDaniel Sanders   unsigned Base = fieldFromInstruction(Insn, 21, 5);
158892db6b78SDaniel Sanders 
158992db6b78SDaniel Sanders   Reg = getReg(Decoder, Mips::COP2RegClassID, Reg);
159092db6b78SDaniel Sanders   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
159192db6b78SDaniel Sanders 
1592e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1593e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1594e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
159592db6b78SDaniel Sanders 
159692db6b78SDaniel Sanders   return MCDisassembler::Success;
159792db6b78SDaniel Sanders }
159892db6b78SDaniel Sanders 
159992db6b78SDaniel Sanders static DecodeStatus DecodeFMem3(MCInst &Inst,
160092db6b78SDaniel Sanders                                unsigned Insn,
160192db6b78SDaniel Sanders                                uint64_t Address,
160292db6b78SDaniel Sanders                                const void *Decoder) {
160392db6b78SDaniel Sanders   int Offset = SignExtend32<16>(Insn & 0xffff);
160492db6b78SDaniel Sanders   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
160592db6b78SDaniel Sanders   unsigned Base = fieldFromInstruction(Insn, 21, 5);
160692db6b78SDaniel Sanders 
160792db6b78SDaniel Sanders   Reg = getReg(Decoder, Mips::COP3RegClassID, Reg);
160892db6b78SDaniel Sanders   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
160992db6b78SDaniel Sanders 
1610e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1611e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1612e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
161392db6b78SDaniel Sanders 
161492db6b78SDaniel Sanders   return MCDisassembler::Success;
161592db6b78SDaniel Sanders }
161692db6b78SDaniel Sanders 
1617435cf8a4SVladimir Medic static DecodeStatus DecodeFMemCop2R6(MCInst &Inst,
1618435cf8a4SVladimir Medic                                     unsigned Insn,
1619435cf8a4SVladimir Medic                                     uint64_t Address,
1620435cf8a4SVladimir Medic                                     const void *Decoder) {
1621435cf8a4SVladimir Medic   int Offset = SignExtend32<11>(Insn & 0x07ff);
1622435cf8a4SVladimir Medic   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1623435cf8a4SVladimir Medic   unsigned Base = fieldFromInstruction(Insn, 11, 5);
1624435cf8a4SVladimir Medic 
1625435cf8a4SVladimir Medic   Reg = getReg(Decoder, Mips::COP2RegClassID, Reg);
1626435cf8a4SVladimir Medic   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1627435cf8a4SVladimir Medic 
1628e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1629e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1630e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
1631435cf8a4SVladimir Medic 
1632435cf8a4SVladimir Medic   return MCDisassembler::Success;
1633435cf8a4SVladimir Medic }
16346a803f61SDaniel Sanders static DecodeStatus DecodeSpecial3LlSc(MCInst &Inst,
16356a803f61SDaniel Sanders                                        unsigned Insn,
16366a803f61SDaniel Sanders                                        uint64_t Address,
16376a803f61SDaniel Sanders                                        const void *Decoder) {
16386a803f61SDaniel Sanders   int64_t Offset = SignExtend64<9>((Insn >> 7) & 0x1ff);
16396a803f61SDaniel Sanders   unsigned Rt = fieldFromInstruction(Insn, 16, 5);
16406a803f61SDaniel Sanders   unsigned Base = fieldFromInstruction(Insn, 21, 5);
16416a803f61SDaniel Sanders 
16426a803f61SDaniel Sanders   Rt = getReg(Decoder, Mips::GPR32RegClassID, Rt);
16436a803f61SDaniel Sanders   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
16446a803f61SDaniel Sanders 
16456a803f61SDaniel Sanders   if(Inst.getOpcode() == Mips::SC_R6 || Inst.getOpcode() == Mips::SCD_R6){
1646e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Rt));
16476a803f61SDaniel Sanders   }
16486a803f61SDaniel Sanders 
1649e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Rt));
1650e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1651e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
16526a803f61SDaniel Sanders 
16536a803f61SDaniel Sanders   return MCDisassembler::Success;
16546a803f61SDaniel Sanders }
165571928e68SAkira Hatanaka 
165671928e68SAkira Hatanaka static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
165771928e68SAkira Hatanaka                                               unsigned RegNo,
165871928e68SAkira Hatanaka                                               uint64_t Address,
165971928e68SAkira Hatanaka                                               const void *Decoder) {
166071928e68SAkira Hatanaka   // Currently only hardware register 29 is supported.
166171928e68SAkira Hatanaka   if (RegNo != 29)
166271928e68SAkira Hatanaka     return  MCDisassembler::Fail;
1663e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Mips::HWR29));
166471928e68SAkira Hatanaka   return MCDisassembler::Success;
166571928e68SAkira Hatanaka }
166671928e68SAkira Hatanaka 
166771928e68SAkira Hatanaka static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
166871928e68SAkira Hatanaka                                               unsigned RegNo,
166971928e68SAkira Hatanaka                                               uint64_t Address,
167071928e68SAkira Hatanaka                                               const void *Decoder) {
16719bf2b567SAkira Hatanaka   if (RegNo > 30 || RegNo %2)
167271928e68SAkira Hatanaka     return MCDisassembler::Fail;
167371928e68SAkira Hatanaka 
16749bf2b567SAkira Hatanaka   ;
16759bf2b567SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::AFGR64RegClassID, RegNo /2);
1676e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
167771928e68SAkira Hatanaka   return MCDisassembler::Success;
167871928e68SAkira Hatanaka }
167971928e68SAkira Hatanaka 
168000fcf2e1SAkira Hatanaka static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst,
1681ecabd1a5SAkira Hatanaka                                                 unsigned RegNo,
1682ecabd1a5SAkira Hatanaka                                                 uint64_t Address,
1683ecabd1a5SAkira Hatanaka                                                 const void *Decoder) {
1684ecabd1a5SAkira Hatanaka   if (RegNo >= 4)
1685ecabd1a5SAkira Hatanaka     return MCDisassembler::Fail;
1686ecabd1a5SAkira Hatanaka 
168700fcf2e1SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::ACC64DSPRegClassID, RegNo);
1688e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1689ecabd1a5SAkira Hatanaka   return MCDisassembler::Success;
1690ecabd1a5SAkira Hatanaka }
1691ecabd1a5SAkira Hatanaka 
16928002a3f6SAkira Hatanaka static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst,
169359bfaf77SAkira Hatanaka                                                unsigned RegNo,
169459bfaf77SAkira Hatanaka                                                uint64_t Address,
169559bfaf77SAkira Hatanaka                                                const void *Decoder) {
169659bfaf77SAkira Hatanaka   if (RegNo >= 4)
169759bfaf77SAkira Hatanaka     return MCDisassembler::Fail;
169859bfaf77SAkira Hatanaka 
16998002a3f6SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::HI32DSPRegClassID, RegNo);
1700e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
170159bfaf77SAkira Hatanaka   return MCDisassembler::Success;
170259bfaf77SAkira Hatanaka }
170359bfaf77SAkira Hatanaka 
17048002a3f6SAkira Hatanaka static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst,
170559bfaf77SAkira Hatanaka                                                unsigned RegNo,
170659bfaf77SAkira Hatanaka                                                uint64_t Address,
170759bfaf77SAkira Hatanaka                                                const void *Decoder) {
170859bfaf77SAkira Hatanaka   if (RegNo >= 4)
170959bfaf77SAkira Hatanaka     return MCDisassembler::Fail;
171059bfaf77SAkira Hatanaka 
17118002a3f6SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::LO32DSPRegClassID, RegNo);
1712e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
171359bfaf77SAkira Hatanaka   return MCDisassembler::Success;
171459bfaf77SAkira Hatanaka }
171559bfaf77SAkira Hatanaka 
17163eb663b0SJack Carter static DecodeStatus DecodeMSA128BRegisterClass(MCInst &Inst,
17173eb663b0SJack Carter                                                unsigned RegNo,
17183eb663b0SJack Carter                                                uint64_t Address,
17193eb663b0SJack Carter                                                const void *Decoder) {
17203eb663b0SJack Carter   if (RegNo > 31)
17213eb663b0SJack Carter     return MCDisassembler::Fail;
17223eb663b0SJack Carter 
17233eb663b0SJack Carter   unsigned Reg = getReg(Decoder, Mips::MSA128BRegClassID, RegNo);
1724e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
17253eb663b0SJack Carter   return MCDisassembler::Success;
17263eb663b0SJack Carter }
17273eb663b0SJack Carter 
17285dc8ac92SJack Carter static DecodeStatus DecodeMSA128HRegisterClass(MCInst &Inst,
17295dc8ac92SJack Carter                                                unsigned RegNo,
17305dc8ac92SJack Carter                                                uint64_t Address,
17315dc8ac92SJack Carter                                                const void *Decoder) {
17325dc8ac92SJack Carter   if (RegNo > 31)
17335dc8ac92SJack Carter     return MCDisassembler::Fail;
17345dc8ac92SJack Carter 
17355dc8ac92SJack Carter   unsigned Reg = getReg(Decoder, Mips::MSA128HRegClassID, RegNo);
1736e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
17375dc8ac92SJack Carter   return MCDisassembler::Success;
17385dc8ac92SJack Carter }
17395dc8ac92SJack Carter 
17405dc8ac92SJack Carter static DecodeStatus DecodeMSA128WRegisterClass(MCInst &Inst,
17415dc8ac92SJack Carter                                                unsigned RegNo,
17425dc8ac92SJack Carter                                                uint64_t Address,
17435dc8ac92SJack Carter                                                const void *Decoder) {
17445dc8ac92SJack Carter   if (RegNo > 31)
17455dc8ac92SJack Carter     return MCDisassembler::Fail;
17465dc8ac92SJack Carter 
17475dc8ac92SJack Carter   unsigned Reg = getReg(Decoder, Mips::MSA128WRegClassID, RegNo);
1748e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
17495dc8ac92SJack Carter   return MCDisassembler::Success;
17505dc8ac92SJack Carter }
17515dc8ac92SJack Carter 
17525dc8ac92SJack Carter static DecodeStatus DecodeMSA128DRegisterClass(MCInst &Inst,
17535dc8ac92SJack Carter                                                unsigned RegNo,
17545dc8ac92SJack Carter                                                uint64_t Address,
17555dc8ac92SJack Carter                                                const void *Decoder) {
17565dc8ac92SJack Carter   if (RegNo > 31)
17575dc8ac92SJack Carter     return MCDisassembler::Fail;
17585dc8ac92SJack Carter 
17595dc8ac92SJack Carter   unsigned Reg = getReg(Decoder, Mips::MSA128DRegClassID, RegNo);
1760e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
17615dc8ac92SJack Carter   return MCDisassembler::Success;
17625dc8ac92SJack Carter }
17635dc8ac92SJack Carter 
1764a591fdc6SMatheus Almeida static DecodeStatus DecodeMSACtrlRegisterClass(MCInst &Inst,
1765a591fdc6SMatheus Almeida                                                unsigned RegNo,
1766a591fdc6SMatheus Almeida                                                uint64_t Address,
1767a591fdc6SMatheus Almeida                                                const void *Decoder) {
1768a591fdc6SMatheus Almeida   if (RegNo > 7)
1769a591fdc6SMatheus Almeida     return MCDisassembler::Fail;
1770a591fdc6SMatheus Almeida 
1771a591fdc6SMatheus Almeida   unsigned Reg = getReg(Decoder, Mips::MSACtrlRegClassID, RegNo);
1772e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1773a591fdc6SMatheus Almeida   return MCDisassembler::Success;
1774a591fdc6SMatheus Almeida }
1775a591fdc6SMatheus Almeida 
1776a3134faeSDaniel Sanders static DecodeStatus DecodeCOP0RegisterClass(MCInst &Inst,
1777a3134faeSDaniel Sanders                                             unsigned RegNo,
1778a3134faeSDaniel Sanders                                             uint64_t Address,
1779a3134faeSDaniel Sanders                                             const void *Decoder) {
1780a3134faeSDaniel Sanders   if (RegNo > 31)
1781a3134faeSDaniel Sanders     return MCDisassembler::Fail;
1782a3134faeSDaniel Sanders 
1783a3134faeSDaniel Sanders   unsigned Reg = getReg(Decoder, Mips::COP0RegClassID, RegNo);
1784a3134faeSDaniel Sanders   Inst.addOperand(MCOperand::createReg(Reg));
1785a3134faeSDaniel Sanders   return MCDisassembler::Success;
1786a3134faeSDaniel Sanders }
1787a3134faeSDaniel Sanders 
17882a83d680SDaniel Sanders static DecodeStatus DecodeCOP2RegisterClass(MCInst &Inst,
17892a83d680SDaniel Sanders                                             unsigned RegNo,
17902a83d680SDaniel Sanders                                             uint64_t Address,
17912a83d680SDaniel Sanders                                             const void *Decoder) {
17922a83d680SDaniel Sanders   if (RegNo > 31)
17932a83d680SDaniel Sanders     return MCDisassembler::Fail;
17942a83d680SDaniel Sanders 
17952a83d680SDaniel Sanders   unsigned Reg = getReg(Decoder, Mips::COP2RegClassID, RegNo);
1796e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
17972a83d680SDaniel Sanders   return MCDisassembler::Success;
17982a83d680SDaniel Sanders }
17992a83d680SDaniel Sanders 
180071928e68SAkira Hatanaka static DecodeStatus DecodeBranchTarget(MCInst &Inst,
180171928e68SAkira Hatanaka                                        unsigned Offset,
180271928e68SAkira Hatanaka                                        uint64_t Address,
180371928e68SAkira Hatanaka                                        const void *Decoder) {
1804d37bab61SAlexey Samsonov   int32_t BranchOffset = (SignExtend32<16>(Offset) * 4) + 4;
1805e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(BranchOffset));
180671928e68SAkira Hatanaka   return MCDisassembler::Success;
180771928e68SAkira Hatanaka }
180871928e68SAkira Hatanaka 
180971928e68SAkira Hatanaka static DecodeStatus DecodeJumpTarget(MCInst &Inst,
181071928e68SAkira Hatanaka                                      unsigned Insn,
181171928e68SAkira Hatanaka                                      uint64_t Address,
181271928e68SAkira Hatanaka                                      const void *Decoder) {
181371928e68SAkira Hatanaka 
1814ecaef49fSJim Grosbach   unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 2;
1815e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(JumpOffset));
181671928e68SAkira Hatanaka   return MCDisassembler::Success;
181771928e68SAkira Hatanaka }
181871928e68SAkira Hatanaka 
18193c8869dcSZoran Jovanovic static DecodeStatus DecodeBranchTarget21(MCInst &Inst,
18203c8869dcSZoran Jovanovic                                          unsigned Offset,
18213c8869dcSZoran Jovanovic                                          uint64_t Address,
18223c8869dcSZoran Jovanovic                                          const void *Decoder) {
1823d37bab61SAlexey Samsonov   int32_t BranchOffset = SignExtend32<21>(Offset) * 4;
18243c8869dcSZoran Jovanovic 
1825e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(BranchOffset));
18263c8869dcSZoran Jovanovic   return MCDisassembler::Success;
18273c8869dcSZoran Jovanovic }
18283c8869dcSZoran Jovanovic 
18293c8869dcSZoran Jovanovic static DecodeStatus DecodeBranchTarget26(MCInst &Inst,
18303c8869dcSZoran Jovanovic                                          unsigned Offset,
18313c8869dcSZoran Jovanovic                                          uint64_t Address,
18323c8869dcSZoran Jovanovic                                          const void *Decoder) {
1833d37bab61SAlexey Samsonov   int32_t BranchOffset = SignExtend32<26>(Offset) * 4;
18343c8869dcSZoran Jovanovic 
1835e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(BranchOffset));
18363c8869dcSZoran Jovanovic   return MCDisassembler::Success;
18373c8869dcSZoran Jovanovic }
18383c8869dcSZoran Jovanovic 
18399761e96bSJozef Kolek static DecodeStatus DecodeBranchTarget7MM(MCInst &Inst,
18409761e96bSJozef Kolek                                           unsigned Offset,
18419761e96bSJozef Kolek                                           uint64_t Address,
18429761e96bSJozef Kolek                                           const void *Decoder) {
18439761e96bSJozef Kolek   int32_t BranchOffset = SignExtend32<7>(Offset) << 1;
1844e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(BranchOffset));
18459761e96bSJozef Kolek   return MCDisassembler::Success;
18469761e96bSJozef Kolek }
18479761e96bSJozef Kolek 
18485cfebddeSJozef Kolek static DecodeStatus DecodeBranchTarget10MM(MCInst &Inst,
18495cfebddeSJozef Kolek                                            unsigned Offset,
18505cfebddeSJozef Kolek                                            uint64_t Address,
18515cfebddeSJozef Kolek                                            const void *Decoder) {
18525cfebddeSJozef Kolek   int32_t BranchOffset = SignExtend32<10>(Offset) << 1;
1853e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(BranchOffset));
18545cfebddeSJozef Kolek   return MCDisassembler::Success;
18555cfebddeSJozef Kolek }
18565cfebddeSJozef Kolek 
18578a80aa76SZoran Jovanovic static DecodeStatus DecodeBranchTargetMM(MCInst &Inst,
18588a80aa76SZoran Jovanovic                                          unsigned Offset,
18598a80aa76SZoran Jovanovic                                          uint64_t Address,
18608a80aa76SZoran Jovanovic                                          const void *Decoder) {
1861d37bab61SAlexey Samsonov   int32_t BranchOffset = SignExtend32<16>(Offset) * 2;
1862e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(BranchOffset));
18638a80aa76SZoran Jovanovic   return MCDisassembler::Success;
18648a80aa76SZoran Jovanovic }
18658a80aa76SZoran Jovanovic 
1866507e084aSZoran Jovanovic static DecodeStatus DecodeJumpTargetMM(MCInst &Inst,
1867507e084aSZoran Jovanovic                                        unsigned Insn,
1868507e084aSZoran Jovanovic                                        uint64_t Address,
1869507e084aSZoran Jovanovic                                        const void *Decoder) {
1870507e084aSZoran Jovanovic   unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 1;
1871e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(JumpOffset));
1872507e084aSZoran Jovanovic   return MCDisassembler::Success;
1873507e084aSZoran Jovanovic }
187471928e68SAkira Hatanaka 
1875aa2b9278SJozef Kolek static DecodeStatus DecodeAddiur2Simm7(MCInst &Inst,
1876aa2b9278SJozef Kolek                                        unsigned Value,
1877aa2b9278SJozef Kolek                                        uint64_t Address,
1878aa2b9278SJozef Kolek                                        const void *Decoder) {
1879aa2b9278SJozef Kolek   if (Value == 0)
1880e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(1));
1881aa2b9278SJozef Kolek   else if (Value == 0x7)
1882e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(-1));
1883aa2b9278SJozef Kolek   else
1884e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(Value << 2));
1885aa2b9278SJozef Kolek   return MCDisassembler::Success;
1886aa2b9278SJozef Kolek }
1887aa2b9278SJozef Kolek 
1888aa2b9278SJozef Kolek static DecodeStatus DecodeUImm6Lsl2(MCInst &Inst,
1889aa2b9278SJozef Kolek                                     unsigned Value,
1890aa2b9278SJozef Kolek                                     uint64_t Address,
1891aa2b9278SJozef Kolek                                     const void *Decoder) {
1892e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Value << 2));
1893aa2b9278SJozef Kolek   return MCDisassembler::Success;
1894aa2b9278SJozef Kolek }
1895aa2b9278SJozef Kolek 
1896aa2b9278SJozef Kolek static DecodeStatus DecodeLiSimm7(MCInst &Inst,
1897aa2b9278SJozef Kolek                                   unsigned Value,
1898aa2b9278SJozef Kolek                                   uint64_t Address,
1899aa2b9278SJozef Kolek                                   const void *Decoder) {
1900aa2b9278SJozef Kolek   if (Value == 0x7F)
1901e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(-1));
1902aa2b9278SJozef Kolek   else
1903e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(Value));
1904aa2b9278SJozef Kolek   return MCDisassembler::Success;
1905aa2b9278SJozef Kolek }
1906aa2b9278SJozef Kolek 
19076b28f09dSZoran Jovanovic static DecodeStatus DecodePOOL16BEncodedField(MCInst &Inst,
19086b28f09dSZoran Jovanovic                                               unsigned Value,
19096b28f09dSZoran Jovanovic                                               uint64_t Address,
19106b28f09dSZoran Jovanovic                                               const void *Decoder) {
19116b28f09dSZoran Jovanovic   Inst.addOperand(MCOperand::createImm(Value == 0x0 ? 8 : Value));
19126b28f09dSZoran Jovanovic   return MCDisassembler::Success;
19136b28f09dSZoran Jovanovic }
19146b28f09dSZoran Jovanovic 
1915aa2b9278SJozef Kolek static DecodeStatus DecodeSimm4(MCInst &Inst,
1916aa2b9278SJozef Kolek                                 unsigned Value,
1917aa2b9278SJozef Kolek                                 uint64_t Address,
1918aa2b9278SJozef Kolek                                 const void *Decoder) {
1919e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(SignExtend32<4>(Value)));
1920aa2b9278SJozef Kolek   return MCDisassembler::Success;
1921aa2b9278SJozef Kolek }
1922aa2b9278SJozef Kolek 
192371928e68SAkira Hatanaka static DecodeStatus DecodeSimm16(MCInst &Inst,
192471928e68SAkira Hatanaka                                  unsigned Insn,
192571928e68SAkira Hatanaka                                  uint64_t Address,
192671928e68SAkira Hatanaka                                  const void *Decoder) {
1927e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(SignExtend32<16>(Insn)));
192871928e68SAkira Hatanaka   return MCDisassembler::Success;
192971928e68SAkira Hatanaka }
193071928e68SAkira Hatanaka 
1931ea4f653dSDaniel Sanders template <unsigned Bits, int Offset>
1932ea4f653dSDaniel Sanders static DecodeStatus DecodeUImmWithOffset(MCInst &Inst, unsigned Value,
1933779c5937SMatheus Almeida                                          uint64_t Address,
1934779c5937SMatheus Almeida                                          const void *Decoder) {
1935ea4f653dSDaniel Sanders   Value &= ((1 << Bits) - 1);
1936ea4f653dSDaniel Sanders   Inst.addOperand(MCOperand::createImm(Value + Offset));
1937779c5937SMatheus Almeida   return MCDisassembler::Success;
1938779c5937SMatheus Almeida }
1939779c5937SMatheus Almeida 
194071928e68SAkira Hatanaka static DecodeStatus DecodeInsSize(MCInst &Inst,
194171928e68SAkira Hatanaka                                   unsigned Insn,
194271928e68SAkira Hatanaka                                   uint64_t Address,
194371928e68SAkira Hatanaka                                   const void *Decoder) {
194471928e68SAkira Hatanaka   // First we need to grab the pos(lsb) from MCInst.
194571928e68SAkira Hatanaka   int Pos = Inst.getOperand(2).getImm();
194671928e68SAkira Hatanaka   int Size = (int) Insn - Pos + 1;
1947e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(SignExtend32<16>(Size)));
194871928e68SAkira Hatanaka   return MCDisassembler::Success;
194971928e68SAkira Hatanaka }
195071928e68SAkira Hatanaka 
195171928e68SAkira Hatanaka static DecodeStatus DecodeExtSize(MCInst &Inst,
195271928e68SAkira Hatanaka                                   unsigned Insn,
195371928e68SAkira Hatanaka                                   uint64_t Address,
195471928e68SAkira Hatanaka                                   const void *Decoder) {
195571928e68SAkira Hatanaka   int Size = (int) Insn  + 1;
1956e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(SignExtend32<16>(Size)));
195771928e68SAkira Hatanaka   return MCDisassembler::Success;
195871928e68SAkira Hatanaka }
1959b59e1a41SDaniel Sanders 
1960b59e1a41SDaniel Sanders static DecodeStatus DecodeSimm19Lsl2(MCInst &Inst, unsigned Insn,
1961b59e1a41SDaniel Sanders                                      uint64_t Address, const void *Decoder) {
1962e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(SignExtend32<19>(Insn) * 4));
1963b59e1a41SDaniel Sanders   return MCDisassembler::Success;
1964b59e1a41SDaniel Sanders }
19652855142aSZoran Jovanovic 
19662855142aSZoran Jovanovic static DecodeStatus DecodeSimm18Lsl3(MCInst &Inst, unsigned Insn,
19672855142aSZoran Jovanovic                                      uint64_t Address, const void *Decoder) {
1968e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(SignExtend32<18>(Insn) * 8));
19692855142aSZoran Jovanovic   return MCDisassembler::Success;
19702855142aSZoran Jovanovic }
1971a4c4b5fcSZoran Jovanovic 
1972b682ddf3SVladimir Medic static DecodeStatus DecodeSimm9SP(MCInst &Inst, unsigned Insn,
1973b682ddf3SVladimir Medic                                   uint64_t Address, const void *Decoder) {
1974b682ddf3SVladimir Medic   int32_t DecodedValue;
1975b682ddf3SVladimir Medic   switch (Insn) {
1976b682ddf3SVladimir Medic   case 0: DecodedValue = 256; break;
1977b682ddf3SVladimir Medic   case 1: DecodedValue = 257; break;
1978b682ddf3SVladimir Medic   case 510: DecodedValue = -258; break;
1979b682ddf3SVladimir Medic   case 511: DecodedValue = -257; break;
1980b682ddf3SVladimir Medic   default: DecodedValue = SignExtend32<9>(Insn); break;
1981b682ddf3SVladimir Medic   }
1982e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(DecodedValue * 4));
1983b682ddf3SVladimir Medic   return MCDisassembler::Success;
1984b682ddf3SVladimir Medic }
1985b682ddf3SVladimir Medic 
1986b682ddf3SVladimir Medic static DecodeStatus DecodeANDI16Imm(MCInst &Inst, unsigned Insn,
1987b682ddf3SVladimir Medic                                     uint64_t Address, const void *Decoder) {
1988b682ddf3SVladimir Medic   // Insn must be >= 0, since it is unsigned that condition is always true.
1989b682ddf3SVladimir Medic   assert(Insn < 16);
1990b682ddf3SVladimir Medic   int32_t DecodedValues[] = {128, 1, 2, 3, 4, 7, 8, 15, 16, 31, 32, 63, 64,
1991b682ddf3SVladimir Medic                              255, 32768, 65535};
1992e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(DecodedValues[Insn]));
1993b682ddf3SVladimir Medic   return MCDisassembler::Success;
1994b682ddf3SVladimir Medic }
1995b682ddf3SVladimir Medic 
1996b682ddf3SVladimir Medic static DecodeStatus DecodeUImm5lsl2(MCInst &Inst, unsigned Insn,
1997b682ddf3SVladimir Medic                                     uint64_t Address, const void *Decoder) {
1998e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Insn << 2));
1999b682ddf3SVladimir Medic   return MCDisassembler::Success;
2000b682ddf3SVladimir Medic }
2001b682ddf3SVladimir Medic 
2002a4c4b5fcSZoran Jovanovic static DecodeStatus DecodeRegListOperand(MCInst &Inst,
2003a4c4b5fcSZoran Jovanovic                                          unsigned Insn,
2004a4c4b5fcSZoran Jovanovic                                          uint64_t Address,
2005a4c4b5fcSZoran Jovanovic                                          const void *Decoder) {
2006a4c4b5fcSZoran Jovanovic   unsigned Regs[] = {Mips::S0, Mips::S1, Mips::S2, Mips::S3, Mips::S4, Mips::S5,
2007dc4b8c27SZoran Jovanovic                      Mips::S6, Mips::S7, Mips::FP};
2008a4c4b5fcSZoran Jovanovic   unsigned RegNum;
2009a4c4b5fcSZoran Jovanovic 
2010a4c4b5fcSZoran Jovanovic   unsigned RegLst = fieldFromInstruction(Insn, 21, 5);
2011df19a5e6SDaniel Sanders 
2012a4c4b5fcSZoran Jovanovic   // Empty register lists are not allowed.
2013a4c4b5fcSZoran Jovanovic   if (RegLst == 0)
2014a4c4b5fcSZoran Jovanovic     return MCDisassembler::Fail;
2015a4c4b5fcSZoran Jovanovic 
2016a4c4b5fcSZoran Jovanovic   RegNum = RegLst & 0xf;
2017df19a5e6SDaniel Sanders 
2018df19a5e6SDaniel Sanders   // RegLst values 10-15, and 26-31 are reserved.
2019df19a5e6SDaniel Sanders   if (RegNum > 9)
2020df19a5e6SDaniel Sanders     return MCDisassembler::Fail;
2021df19a5e6SDaniel Sanders 
2022a4c4b5fcSZoran Jovanovic   for (unsigned i = 0; i < RegNum; i++)
2023e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Regs[i]));
2024a4c4b5fcSZoran Jovanovic 
2025a4c4b5fcSZoran Jovanovic   if (RegLst & 0x10)
2026e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::RA));
2027a4c4b5fcSZoran Jovanovic 
2028a4c4b5fcSZoran Jovanovic   return MCDisassembler::Success;
2029a4c4b5fcSZoran Jovanovic }
2030f9a02500SZoran Jovanovic 
2031f9a02500SZoran Jovanovic static DecodeStatus DecodeRegListOperand16(MCInst &Inst, unsigned Insn,
2032f9a02500SZoran Jovanovic                                            uint64_t Address,
2033f9a02500SZoran Jovanovic                                            const void *Decoder) {
2034f9a02500SZoran Jovanovic   unsigned Regs[] = {Mips::S0, Mips::S1, Mips::S2, Mips::S3};
2035797c2aecSZlatko Buljan   unsigned RegLst;
2036797c2aecSZlatko Buljan   switch(Inst.getOpcode()) {
2037797c2aecSZlatko Buljan   default:
2038797c2aecSZlatko Buljan     RegLst = fieldFromInstruction(Insn, 4, 2);
2039797c2aecSZlatko Buljan     break;
2040797c2aecSZlatko Buljan   case Mips::LWM16_MMR6:
2041797c2aecSZlatko Buljan   case Mips::SWM16_MMR6:
2042797c2aecSZlatko Buljan     RegLst = fieldFromInstruction(Insn, 8, 2);
2043797c2aecSZlatko Buljan     break;
2044797c2aecSZlatko Buljan   }
2045d68d424aSJozef Kolek   unsigned RegNum = RegLst & 0x3;
2046f9a02500SZoran Jovanovic 
2047d68d424aSJozef Kolek   for (unsigned i = 0; i <= RegNum; i++)
2048e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Regs[i]));
2049f9a02500SZoran Jovanovic 
2050e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Mips::RA));
2051f9a02500SZoran Jovanovic 
2052f9a02500SZoran Jovanovic   return MCDisassembler::Success;
2053f9a02500SZoran Jovanovic }
20542c6d7320SJozef Kolek 
205541688679SZoran Jovanovic static DecodeStatus DecodeMovePRegPair(MCInst &Inst, unsigned Insn,
205641688679SZoran Jovanovic                                        uint64_t Address, const void *Decoder) {
205741688679SZoran Jovanovic 
205841688679SZoran Jovanovic   unsigned RegPair = fieldFromInstruction(Insn, 7, 3);
205941688679SZoran Jovanovic 
206041688679SZoran Jovanovic   switch (RegPair) {
206141688679SZoran Jovanovic   default:
206241688679SZoran Jovanovic     return MCDisassembler::Fail;
206341688679SZoran Jovanovic   case 0:
2064e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A1));
2065e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A2));
206641688679SZoran Jovanovic     break;
206741688679SZoran Jovanovic   case 1:
2068e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A1));
2069e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A3));
207041688679SZoran Jovanovic     break;
207141688679SZoran Jovanovic   case 2:
2072e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A2));
2073e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A3));
207441688679SZoran Jovanovic     break;
207541688679SZoran Jovanovic   case 3:
2076e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A0));
2077e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::S5));
207841688679SZoran Jovanovic     break;
207941688679SZoran Jovanovic   case 4:
2080e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A0));
2081e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::S6));
208241688679SZoran Jovanovic     break;
208341688679SZoran Jovanovic   case 5:
2084e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A0));
2085e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A1));
208641688679SZoran Jovanovic     break;
208741688679SZoran Jovanovic   case 6:
2088e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A0));
2089e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A2));
209041688679SZoran Jovanovic     break;
209141688679SZoran Jovanovic   case 7:
2092e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A0));
2093e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A3));
209441688679SZoran Jovanovic     break;
209541688679SZoran Jovanovic   }
209641688679SZoran Jovanovic 
209741688679SZoran Jovanovic   return MCDisassembler::Success;
209841688679SZoran Jovanovic }
209941688679SZoran Jovanovic 
21002c6d7320SJozef Kolek static DecodeStatus DecodeSimm23Lsl2(MCInst &Inst, unsigned Insn,
21012c6d7320SJozef Kolek                                      uint64_t Address, const void *Decoder) {
21026499b5f0SJustin Bogner   Inst.addOperand(MCOperand::createImm(SignExtend32<25>(Insn << 2)));
21032c6d7320SJozef Kolek   return MCDisassembler::Success;
21042c6d7320SJozef Kolek }
2105