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 
383*ea4f653dSDaniel Sanders template <unsigned Bits, int Offset>
384*ea4f653dSDaniel Sanders static DecodeStatus DecodeUImmWithOffset(MCInst &Inst, unsigned Value,
385*ea4f653dSDaniel 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);
870ea22c4cfSJozef Kolek 
871ada70918SZoran Jovanovic     if (hasMips32r6()) {
872ada70918SZoran Jovanovic       DEBUG(dbgs() << "Trying MicroMipsR616 table (16-bit instructions):\n");
873ada70918SZoran Jovanovic       // Calling the auto-generated decoder function for microMIPS32R6
874ada70918SZoran Jovanovic       // (and microMIPS64R6) 16-bit instructions.
875ada70918SZoran Jovanovic       Result = decodeInstruction(DecoderTableMicroMipsR616, Instr, Insn,
876ada70918SZoran Jovanovic                                  Address, this, STI);
877ada70918SZoran Jovanovic       if (Result != MCDisassembler::Fail) {
878ada70918SZoran Jovanovic         Size = 2;
879ada70918SZoran Jovanovic         return Result;
880ada70918SZoran Jovanovic       }
881ada70918SZoran Jovanovic     }
882ada70918SZoran Jovanovic 
883ea22c4cfSJozef Kolek     DEBUG(dbgs() << "Trying MicroMips16 table (16-bit instructions):\n");
884ada70918SZoran Jovanovic     // Calling the auto-generated decoder function for microMIPS 16-bit
885ada70918SZoran Jovanovic     // instructions.
886ea22c4cfSJozef Kolek     Result = decodeInstruction(DecoderTableMicroMips16, Instr, Insn, Address,
887ea22c4cfSJozef Kolek                                this, STI);
888ea22c4cfSJozef Kolek     if (Result != MCDisassembler::Fail) {
889ea22c4cfSJozef Kolek       Size = 2;
890ea22c4cfSJozef Kolek       return Result;
891ea22c4cfSJozef Kolek     }
892ea22c4cfSJozef Kolek 
893ea22c4cfSJozef Kolek     Result = readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, true);
89471928e68SAkira Hatanaka     if (Result == MCDisassembler::Fail)
89571928e68SAkira Hatanaka       return MCDisassembler::Fail;
89671928e68SAkira Hatanaka 
897676d6012SJozef Kolek     if (hasMips32r6()) {
898676d6012SJozef Kolek       DEBUG(dbgs() << "Trying MicroMips32r632 table (32-bit instructions):\n");
899676d6012SJozef Kolek       // Calling the auto-generated decoder function.
900366783e1SZoran Jovanovic       Result = decodeInstruction(DecoderTableMicroMipsR632, Instr, Insn, Address,
901676d6012SJozef Kolek                                  this, STI);
902ada70918SZoran Jovanovic       if (Result != MCDisassembler::Fail) {
903ada70918SZoran Jovanovic         Size = 4;
904ada70918SZoran Jovanovic         return Result;
905ada70918SZoran Jovanovic       }
906ada70918SZoran Jovanovic     }
907ada70918SZoran Jovanovic 
908ea22c4cfSJozef Kolek     DEBUG(dbgs() << "Trying MicroMips32 table (32-bit instructions):\n");
909dde3d582SVladimir Medic     // Calling the auto-generated decoder function.
9104aa6bea7SRafael Espindola     Result = decodeInstruction(DecoderTableMicroMips32, Instr, Insn, Address,
911dde3d582SVladimir Medic                                this, STI);
912dde3d582SVladimir Medic     if (Result != MCDisassembler::Fail) {
913dde3d582SVladimir Medic       Size = 4;
914dde3d582SVladimir Medic       return Result;
915dde3d582SVladimir Medic     }
916dde3d582SVladimir Medic     return MCDisassembler::Fail;
917dde3d582SVladimir Medic   }
918dde3d582SVladimir Medic 
919ea22c4cfSJozef Kolek   Result = readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, false);
920ea22c4cfSJozef Kolek   if (Result == MCDisassembler::Fail)
921ea22c4cfSJozef Kolek     return MCDisassembler::Fail;
922ea22c4cfSJozef Kolek 
923c171f65aSDaniel Sanders   if (hasCOP3()) {
924c171f65aSDaniel Sanders     DEBUG(dbgs() << "Trying COP3_ table (32-bit opcodes):\n");
925c171f65aSDaniel Sanders     Result =
9264aa6bea7SRafael Espindola         decodeInstruction(DecoderTableCOP3_32, Instr, Insn, Address, this, STI);
927c171f65aSDaniel Sanders     if (Result != MCDisassembler::Fail) {
928c171f65aSDaniel Sanders       Size = 4;
929c171f65aSDaniel Sanders       return Result;
930c171f65aSDaniel Sanders     }
931c171f65aSDaniel Sanders   }
932c171f65aSDaniel Sanders 
933c171f65aSDaniel Sanders   if (hasMips32r6() && isGP64()) {
9340fa60416SDaniel Sanders     DEBUG(dbgs() << "Trying Mips32r6_64r6 (GPR64) table (32-bit opcodes):\n");
9354aa6bea7SRafael Espindola     Result = decodeInstruction(DecoderTableMips32r6_64r6_GP6432, Instr, Insn,
9360fa60416SDaniel Sanders                                Address, this, STI);
9370fa60416SDaniel Sanders     if (Result != MCDisassembler::Fail) {
9380fa60416SDaniel Sanders       Size = 4;
9390fa60416SDaniel Sanders       return Result;
9400fa60416SDaniel Sanders     }
9410fa60416SDaniel Sanders   }
9420fa60416SDaniel Sanders 
943c171f65aSDaniel Sanders   if (hasMips32r6()) {
9440fa60416SDaniel Sanders     DEBUG(dbgs() << "Trying Mips32r6_64r6 table (32-bit opcodes):\n");
9454aa6bea7SRafael Espindola     Result = decodeInstruction(DecoderTableMips32r6_64r632, Instr, Insn,
9465c582b2fSDaniel Sanders                                Address, this, STI);
9475c582b2fSDaniel Sanders     if (Result != MCDisassembler::Fail) {
9485c582b2fSDaniel Sanders       Size = 4;
9495c582b2fSDaniel Sanders       return Result;
9505c582b2fSDaniel Sanders     }
9515c582b2fSDaniel Sanders   }
9525c582b2fSDaniel Sanders 
9533adf9b8dSKai Nacke   if (hasCnMips()) {
9543adf9b8dSKai Nacke     DEBUG(dbgs() << "Trying CnMips table (32-bit opcodes):\n");
9553adf9b8dSKai Nacke     Result = decodeInstruction(DecoderTableCnMips32, Instr, Insn,
9563adf9b8dSKai Nacke                                Address, this, STI);
9573adf9b8dSKai Nacke     if (Result != MCDisassembler::Fail) {
9583adf9b8dSKai Nacke       Size = 4;
9593adf9b8dSKai Nacke       return Result;
9603adf9b8dSKai Nacke     }
9613adf9b8dSKai Nacke   }
9623adf9b8dSKai Nacke 
963a19216c8SDaniel Sanders   if (isGP64()) {
964a19216c8SDaniel Sanders     DEBUG(dbgs() << "Trying Mips64 (GPR64) table (32-bit opcodes):\n");
965a19216c8SDaniel Sanders     Result = decodeInstruction(DecoderTableMips6432, Instr, Insn,
966a19216c8SDaniel Sanders                                Address, this, STI);
967a19216c8SDaniel Sanders     if (Result != MCDisassembler::Fail) {
968a19216c8SDaniel Sanders       Size = 4;
969a19216c8SDaniel Sanders       return Result;
970a19216c8SDaniel Sanders     }
971a19216c8SDaniel Sanders   }
972a19216c8SDaniel Sanders 
9730fa60416SDaniel Sanders   DEBUG(dbgs() << "Trying Mips table (32-bit opcodes):\n");
97471928e68SAkira Hatanaka   // Calling the auto-generated decoder function.
9754aa6bea7SRafael Espindola   Result =
9764aa6bea7SRafael Espindola       decodeInstruction(DecoderTableMips32, Instr, Insn, Address, this, STI);
97771928e68SAkira Hatanaka   if (Result != MCDisassembler::Fail) {
97871928e68SAkira Hatanaka     Size = 4;
97971928e68SAkira Hatanaka     return Result;
98071928e68SAkira Hatanaka   }
98171928e68SAkira Hatanaka 
98271928e68SAkira Hatanaka   return MCDisassembler::Fail;
98371928e68SAkira Hatanaka }
98471928e68SAkira Hatanaka 
985ec8a5490SReed Kotler static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst,
986ec8a5490SReed Kotler                                                  unsigned RegNo,
987ec8a5490SReed Kotler                                                  uint64_t Address,
988ec8a5490SReed Kotler                                                  const void *Decoder) {
989ec8a5490SReed Kotler 
990ec8a5490SReed Kotler   return MCDisassembler::Fail;
991ec8a5490SReed Kotler 
992ec8a5490SReed Kotler }
993ec8a5490SReed Kotler 
99413e6ccf3SAkira Hatanaka static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst,
99571928e68SAkira Hatanaka                                              unsigned RegNo,
99671928e68SAkira Hatanaka                                              uint64_t Address,
99771928e68SAkira Hatanaka                                              const void *Decoder) {
99871928e68SAkira Hatanaka 
99971928e68SAkira Hatanaka   if (RegNo > 31)
100071928e68SAkira Hatanaka     return MCDisassembler::Fail;
100171928e68SAkira Hatanaka 
100213e6ccf3SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::GPR64RegClassID, RegNo);
1003e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
100471928e68SAkira Hatanaka   return MCDisassembler::Success;
100571928e68SAkira Hatanaka }
100671928e68SAkira Hatanaka 
1007b0852e54SZoran Jovanovic static DecodeStatus DecodeGPRMM16RegisterClass(MCInst &Inst,
1008b0852e54SZoran Jovanovic                                                unsigned RegNo,
1009b0852e54SZoran Jovanovic                                                uint64_t Address,
1010b0852e54SZoran Jovanovic                                                const void *Decoder) {
1011ea22c4cfSJozef Kolek   if (RegNo > 7)
1012b0852e54SZoran Jovanovic     return MCDisassembler::Fail;
1013ea22c4cfSJozef Kolek   unsigned Reg = getReg(Decoder, Mips::GPRMM16RegClassID, RegNo);
1014e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1015ea22c4cfSJozef Kolek   return MCDisassembler::Success;
1016b0852e54SZoran Jovanovic }
1017b0852e54SZoran Jovanovic 
10181904fa21SJozef Kolek static DecodeStatus DecodeGPRMM16ZeroRegisterClass(MCInst &Inst,
10191904fa21SJozef Kolek                                                    unsigned RegNo,
10201904fa21SJozef Kolek                                                    uint64_t Address,
10211904fa21SJozef Kolek                                                    const void *Decoder) {
1022315e7ecaSJozef Kolek   if (RegNo > 7)
10231904fa21SJozef Kolek     return MCDisassembler::Fail;
1024315e7ecaSJozef Kolek   unsigned Reg = getReg(Decoder, Mips::GPRMM16ZeroRegClassID, RegNo);
1025e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1026315e7ecaSJozef Kolek   return MCDisassembler::Success;
10271904fa21SJozef Kolek }
10281904fa21SJozef Kolek 
102941688679SZoran Jovanovic static DecodeStatus DecodeGPRMM16MovePRegisterClass(MCInst &Inst,
103041688679SZoran Jovanovic                                                     unsigned RegNo,
103141688679SZoran Jovanovic                                                     uint64_t Address,
103241688679SZoran Jovanovic                                                     const void *Decoder) {
103341688679SZoran Jovanovic   if (RegNo > 7)
103441688679SZoran Jovanovic     return MCDisassembler::Fail;
103541688679SZoran Jovanovic   unsigned Reg = getReg(Decoder, Mips::GPRMM16MovePRegClassID, RegNo);
1036e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
103741688679SZoran Jovanovic   return MCDisassembler::Success;
103841688679SZoran Jovanovic }
103941688679SZoran Jovanovic 
104013e6ccf3SAkira Hatanaka static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst,
104171928e68SAkira Hatanaka                                              unsigned RegNo,
104271928e68SAkira Hatanaka                                              uint64_t Address,
104371928e68SAkira Hatanaka                                              const void *Decoder) {
104471928e68SAkira Hatanaka   if (RegNo > 31)
104571928e68SAkira Hatanaka     return MCDisassembler::Fail;
104613e6ccf3SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::GPR32RegClassID, RegNo);
1047e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
104871928e68SAkira Hatanaka   return MCDisassembler::Success;
104971928e68SAkira Hatanaka }
105071928e68SAkira Hatanaka 
10519bfa2e2eSAkira Hatanaka static DecodeStatus DecodePtrRegisterClass(MCInst &Inst,
10529bfa2e2eSAkira Hatanaka                                            unsigned RegNo,
10539bfa2e2eSAkira Hatanaka                                            uint64_t Address,
10549bfa2e2eSAkira Hatanaka                                            const void *Decoder) {
1055a19216c8SDaniel Sanders   if (static_cast<const MipsDisassembler *>(Decoder)->isGP64())
10569bfa2e2eSAkira Hatanaka     return DecodeGPR64RegisterClass(Inst, RegNo, Address, Decoder);
10579bfa2e2eSAkira Hatanaka 
10589bfa2e2eSAkira Hatanaka   return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
10599bfa2e2eSAkira Hatanaka }
10609bfa2e2eSAkira Hatanaka 
1061654655f1SAkira Hatanaka static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst,
1062ecabd1a5SAkira Hatanaka                                             unsigned RegNo,
1063ecabd1a5SAkira Hatanaka                                             uint64_t Address,
1064ecabd1a5SAkira Hatanaka                                             const void *Decoder) {
106513e6ccf3SAkira Hatanaka   return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
1066ecabd1a5SAkira Hatanaka }
1067ecabd1a5SAkira Hatanaka 
106871928e68SAkira Hatanaka static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
106971928e68SAkira Hatanaka                                              unsigned RegNo,
107071928e68SAkira Hatanaka                                              uint64_t Address,
107171928e68SAkira Hatanaka                                              const void *Decoder) {
107271928e68SAkira Hatanaka   if (RegNo > 31)
107371928e68SAkira Hatanaka     return MCDisassembler::Fail;
107471928e68SAkira Hatanaka 
10759bf2b567SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::FGR64RegClassID, RegNo);
1076e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
107771928e68SAkira Hatanaka   return MCDisassembler::Success;
107871928e68SAkira Hatanaka }
107971928e68SAkira Hatanaka 
108071928e68SAkira Hatanaka static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
108171928e68SAkira Hatanaka                                              unsigned RegNo,
108271928e68SAkira Hatanaka                                              uint64_t Address,
108371928e68SAkira Hatanaka                                              const void *Decoder) {
108471928e68SAkira Hatanaka   if (RegNo > 31)
108571928e68SAkira Hatanaka     return MCDisassembler::Fail;
108671928e68SAkira Hatanaka 
10879bf2b567SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::FGR32RegClassID, RegNo);
1088e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
108971928e68SAkira Hatanaka   return MCDisassembler::Success;
109071928e68SAkira Hatanaka }
109171928e68SAkira Hatanaka 
109271928e68SAkira Hatanaka static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
109371928e68SAkira Hatanaka                                            unsigned RegNo,
109471928e68SAkira Hatanaka                                            uint64_t Address,
109571928e68SAkira Hatanaka                                            const void *Decoder) {
1096253777fdSChad Rosier   if (RegNo > 31)
1097253777fdSChad Rosier     return MCDisassembler::Fail;
1098253777fdSChad Rosier   unsigned Reg = getReg(Decoder, Mips::CCRRegClassID, RegNo);
1099e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
110071928e68SAkira Hatanaka   return MCDisassembler::Success;
110171928e68SAkira Hatanaka }
110271928e68SAkira Hatanaka 
11031fb1b8b8SAkira Hatanaka static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst,
11041fb1b8b8SAkira Hatanaka                                            unsigned RegNo,
11051fb1b8b8SAkira Hatanaka                                            uint64_t Address,
11061fb1b8b8SAkira Hatanaka                                            const void *Decoder) {
11071fb1b8b8SAkira Hatanaka   if (RegNo > 7)
11081fb1b8b8SAkira Hatanaka     return MCDisassembler::Fail;
11091fb1b8b8SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::FCCRegClassID, RegNo);
1110e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
11111fb1b8b8SAkira Hatanaka   return MCDisassembler::Success;
11121fb1b8b8SAkira Hatanaka }
11131fb1b8b8SAkira Hatanaka 
11140fa60416SDaniel Sanders static DecodeStatus DecodeFGRCCRegisterClass(MCInst &Inst, unsigned RegNo,
11150fa60416SDaniel Sanders                                              uint64_t Address,
11160fa60416SDaniel Sanders                                              const void *Decoder) {
11170fa60416SDaniel Sanders   if (RegNo > 31)
11180fa60416SDaniel Sanders     return MCDisassembler::Fail;
11190fa60416SDaniel Sanders 
11200fa60416SDaniel Sanders   unsigned Reg = getReg(Decoder, Mips::FGRCCRegClassID, RegNo);
1121e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
11220fa60416SDaniel Sanders   return MCDisassembler::Success;
11230fa60416SDaniel Sanders }
11240fa60416SDaniel Sanders 
112571928e68SAkira Hatanaka static DecodeStatus DecodeMem(MCInst &Inst,
112671928e68SAkira Hatanaka                               unsigned Insn,
112771928e68SAkira Hatanaka                               uint64_t Address,
112871928e68SAkira Hatanaka                               const void *Decoder) {
112971928e68SAkira Hatanaka   int Offset = SignExtend32<16>(Insn & 0xffff);
1130ecaef49fSJim Grosbach   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1131ecaef49fSJim Grosbach   unsigned Base = fieldFromInstruction(Insn, 21, 5);
11329bf2b567SAkira Hatanaka 
113313e6ccf3SAkira Hatanaka   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
113413e6ccf3SAkira Hatanaka   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
113571928e68SAkira Hatanaka 
1136d7ecf49eSVladimir Medic   if (Inst.getOpcode() == Mips::SC ||
1137e4e83a7bSDaniel Sanders       Inst.getOpcode() == Mips::SCD)
1138e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Reg));
1139e4e83a7bSDaniel Sanders 
1140e4e83a7bSDaniel Sanders   Inst.addOperand(MCOperand::createReg(Reg));
1141e4e83a7bSDaniel Sanders   Inst.addOperand(MCOperand::createReg(Base));
1142e4e83a7bSDaniel Sanders   Inst.addOperand(MCOperand::createImm(Offset));
1143e4e83a7bSDaniel Sanders 
1144e4e83a7bSDaniel Sanders   return MCDisassembler::Success;
114571928e68SAkira Hatanaka }
114671928e68SAkira Hatanaka 
1147e4e83a7bSDaniel Sanders static DecodeStatus DecodeMemEVA(MCInst &Inst,
1148e4e83a7bSDaniel Sanders                                  unsigned Insn,
1149e4e83a7bSDaniel Sanders                                  uint64_t Address,
1150e4e83a7bSDaniel Sanders                                  const void *Decoder) {
1151e4e83a7bSDaniel Sanders   int Offset = SignExtend32<9>(Insn >> 7);
1152e4e83a7bSDaniel Sanders   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1153e4e83a7bSDaniel Sanders   unsigned Base = fieldFromInstruction(Insn, 21, 5);
1154e4e83a7bSDaniel Sanders 
1155e4e83a7bSDaniel Sanders   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1156e4e83a7bSDaniel Sanders   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1157e4e83a7bSDaniel Sanders 
1158e4e83a7bSDaniel Sanders    if (Inst.getOpcode() == Mips::SCE)
1159e4e83a7bSDaniel Sanders      Inst.addOperand(MCOperand::createReg(Reg));
1160e4e83a7bSDaniel Sanders 
1161e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1162e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1163e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
116471928e68SAkira Hatanaka 
116571928e68SAkira Hatanaka   return MCDisassembler::Success;
116671928e68SAkira Hatanaka }
116771928e68SAkira Hatanaka 
11683c88fbd3SHrvoje Varga static DecodeStatus DecodeLoadByte9(MCInst &Inst,
11693c88fbd3SHrvoje Varga                                     unsigned Insn,
11703c88fbd3SHrvoje Varga                                     uint64_t Address,
11713c88fbd3SHrvoje Varga                                     const void *Decoder) {
11723c88fbd3SHrvoje Varga   int Offset = SignExtend32<9>(Insn & 0x1ff);
11733c88fbd3SHrvoje Varga   unsigned Base = fieldFromInstruction(Insn, 16, 5);
11743c88fbd3SHrvoje Varga   unsigned Reg = fieldFromInstruction(Insn, 21, 5);
11753c88fbd3SHrvoje Varga 
11763c88fbd3SHrvoje Varga   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
11773c88fbd3SHrvoje Varga   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
11783c88fbd3SHrvoje Varga 
11793c88fbd3SHrvoje Varga   Inst.addOperand(MCOperand::createReg(Reg));
11803c88fbd3SHrvoje Varga   Inst.addOperand(MCOperand::createReg(Base));
11813c88fbd3SHrvoje Varga   Inst.addOperand(MCOperand::createImm(Offset));
11823c88fbd3SHrvoje Varga 
11833c88fbd3SHrvoje Varga   return MCDisassembler::Success;
11843c88fbd3SHrvoje Varga }
11853c88fbd3SHrvoje Varga 
11863c88fbd3SHrvoje Varga static DecodeStatus DecodeLoadByte15(MCInst &Inst,
11873c88fbd3SHrvoje Varga                                      unsigned Insn,
11883c88fbd3SHrvoje Varga                                      uint64_t Address,
11893c88fbd3SHrvoje Varga                                      const void *Decoder) {
11903c88fbd3SHrvoje Varga   int Offset = SignExtend32<16>(Insn & 0xffff);
11913c88fbd3SHrvoje Varga   unsigned Base = fieldFromInstruction(Insn, 16, 5);
11923c88fbd3SHrvoje Varga   unsigned Reg = fieldFromInstruction(Insn, 21, 5);
11933c88fbd3SHrvoje Varga 
11943c88fbd3SHrvoje Varga   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
11953c88fbd3SHrvoje Varga   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
11963c88fbd3SHrvoje Varga 
11973c88fbd3SHrvoje Varga   Inst.addOperand(MCOperand::createReg(Reg));
11983c88fbd3SHrvoje Varga   Inst.addOperand(MCOperand::createReg(Base));
11993c88fbd3SHrvoje Varga   Inst.addOperand(MCOperand::createImm(Offset));
12003c88fbd3SHrvoje Varga 
12013c88fbd3SHrvoje Varga   return MCDisassembler::Success;
12023c88fbd3SHrvoje Varga }
12033c88fbd3SHrvoje Varga 
120492db6b78SDaniel Sanders static DecodeStatus DecodeCacheOp(MCInst &Inst,
120592db6b78SDaniel Sanders                               unsigned Insn,
120692db6b78SDaniel Sanders                               uint64_t Address,
120792db6b78SDaniel Sanders                               const void *Decoder) {
120892db6b78SDaniel Sanders   int Offset = SignExtend32<16>(Insn & 0xffff);
120992db6b78SDaniel Sanders   unsigned Hint = fieldFromInstruction(Insn, 16, 5);
121092db6b78SDaniel Sanders   unsigned Base = fieldFromInstruction(Insn, 21, 5);
121192db6b78SDaniel Sanders 
121292db6b78SDaniel Sanders   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
121392db6b78SDaniel Sanders 
1214e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1215e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
1216e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Hint));
121792db6b78SDaniel Sanders 
121892db6b78SDaniel Sanders   return MCDisassembler::Success;
121992db6b78SDaniel Sanders }
122092db6b78SDaniel Sanders 
1221ab6d1cceSJozef Kolek static DecodeStatus DecodeCacheOpMM(MCInst &Inst,
1222ab6d1cceSJozef Kolek                                     unsigned Insn,
1223ab6d1cceSJozef Kolek                                     uint64_t Address,
1224ab6d1cceSJozef Kolek                                     const void *Decoder) {
1225ab6d1cceSJozef Kolek   int Offset = SignExtend32<12>(Insn & 0xfff);
1226ab6d1cceSJozef Kolek   unsigned Base = fieldFromInstruction(Insn, 16, 5);
1227ab6d1cceSJozef Kolek   unsigned Hint = fieldFromInstruction(Insn, 21, 5);
1228ab6d1cceSJozef Kolek 
1229ab6d1cceSJozef Kolek   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1230ab6d1cceSJozef Kolek 
1231e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1232e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
1233e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Hint));
1234ab6d1cceSJozef Kolek 
1235ab6d1cceSJozef Kolek   return MCDisassembler::Success;
1236ab6d1cceSJozef Kolek }
1237ab6d1cceSJozef Kolek 
1238d9790793SZoran Jovanovic static DecodeStatus DecodePrefeOpMM(MCInst &Inst,
1239d9790793SZoran Jovanovic                                     unsigned Insn,
1240d9790793SZoran Jovanovic                                     uint64_t Address,
1241d9790793SZoran Jovanovic                                     const void *Decoder) {
1242d9790793SZoran Jovanovic   int Offset = SignExtend32<9>(Insn & 0x1ff);
1243d9790793SZoran Jovanovic   unsigned Base = fieldFromInstruction(Insn, 16, 5);
1244d9790793SZoran Jovanovic   unsigned Hint = fieldFromInstruction(Insn, 21, 5);
1245d9790793SZoran Jovanovic 
1246d9790793SZoran Jovanovic   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1247d9790793SZoran Jovanovic 
1248d9790793SZoran Jovanovic   Inst.addOperand(MCOperand::createReg(Base));
1249d9790793SZoran Jovanovic   Inst.addOperand(MCOperand::createImm(Offset));
1250d9790793SZoran Jovanovic   Inst.addOperand(MCOperand::createImm(Hint));
1251d9790793SZoran Jovanovic 
1252d9790793SZoran Jovanovic   return MCDisassembler::Success;
1253d9790793SZoran Jovanovic }
1254d9790793SZoran Jovanovic 
1255e4e83a7bSDaniel Sanders static DecodeStatus DecodeCacheeOp_CacheOpR6(MCInst &Inst,
1256df464ae2SVladimir Medic                                              unsigned Insn,
1257df464ae2SVladimir Medic                                              uint64_t Address,
1258df464ae2SVladimir Medic                                              const void *Decoder) {
1259e4e83a7bSDaniel Sanders   int Offset = SignExtend32<9>(Insn >> 7);
1260df464ae2SVladimir Medic   unsigned Hint = fieldFromInstruction(Insn, 16, 5);
1261df464ae2SVladimir Medic   unsigned Base = fieldFromInstruction(Insn, 21, 5);
1262df464ae2SVladimir Medic 
1263df464ae2SVladimir Medic   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1264df464ae2SVladimir Medic 
1265e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1266e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
1267e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Hint));
1268df464ae2SVladimir Medic 
1269df464ae2SVladimir Medic   return MCDisassembler::Success;
1270df464ae2SVladimir Medic }
1271df464ae2SVladimir Medic 
12729eaa30d2SZoran Jovanovic static DecodeStatus DecodeStoreEvaOpMM(MCInst &Inst,
12739eaa30d2SZoran Jovanovic                                        unsigned Insn,
12749eaa30d2SZoran Jovanovic                                        uint64_t Address,
12759eaa30d2SZoran Jovanovic                                        const void *Decoder) {
12769eaa30d2SZoran Jovanovic   int Offset = SignExtend32<9>(Insn & 0x1ff);
12779eaa30d2SZoran Jovanovic   unsigned Reg = fieldFromInstruction(Insn, 21, 5);
12789eaa30d2SZoran Jovanovic   unsigned Base = fieldFromInstruction(Insn, 16, 5);
12799eaa30d2SZoran Jovanovic 
12809eaa30d2SZoran Jovanovic   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
12819eaa30d2SZoran Jovanovic   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
12829eaa30d2SZoran Jovanovic 
12839eaa30d2SZoran Jovanovic   Inst.addOperand(MCOperand::createReg(Reg));
12849eaa30d2SZoran Jovanovic   Inst.addOperand(MCOperand::createReg(Base));
12859eaa30d2SZoran Jovanovic   Inst.addOperand(MCOperand::createImm(Offset));
12869eaa30d2SZoran Jovanovic 
12879eaa30d2SZoran Jovanovic   return MCDisassembler::Success;
12889eaa30d2SZoran Jovanovic }
12899eaa30d2SZoran Jovanovic 
1290b4484d62SDaniel Sanders static DecodeStatus DecodeSyncI(MCInst &Inst,
1291b4484d62SDaniel Sanders                               unsigned Insn,
1292b4484d62SDaniel Sanders                               uint64_t Address,
1293b4484d62SDaniel Sanders                               const void *Decoder) {
1294b4484d62SDaniel Sanders   int Offset = SignExtend32<16>(Insn & 0xffff);
1295b4484d62SDaniel Sanders   unsigned Base = fieldFromInstruction(Insn, 21, 5);
1296b4484d62SDaniel Sanders 
1297b4484d62SDaniel Sanders   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1298b4484d62SDaniel Sanders 
1299e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1300e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
1301b4484d62SDaniel Sanders 
1302b4484d62SDaniel Sanders   return MCDisassembler::Success;
1303b4484d62SDaniel Sanders }
1304b4484d62SDaniel Sanders 
130518148671SHrvoje Varga static DecodeStatus DecodeSynciR6(MCInst &Inst,
130618148671SHrvoje Varga                                   unsigned Insn,
130718148671SHrvoje Varga                                   uint64_t Address,
130818148671SHrvoje Varga                                   const void *Decoder) {
130918148671SHrvoje Varga   int Immediate = SignExtend32<16>(Insn & 0xffff);
131018148671SHrvoje Varga   unsigned Base = fieldFromInstruction(Insn, 16, 5);
131118148671SHrvoje Varga 
131218148671SHrvoje Varga   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
131318148671SHrvoje Varga 
131418148671SHrvoje Varga   Inst.addOperand(MCOperand::createReg(Base));
131518148671SHrvoje Varga   Inst.addOperand(MCOperand::createImm(Immediate));
131618148671SHrvoje Varga 
131718148671SHrvoje Varga   return MCDisassembler::Success;
131818148671SHrvoje Varga }
131918148671SHrvoje Varga 
1320fe0bf9f6SMatheus Almeida static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn,
1321fe0bf9f6SMatheus Almeida                                     uint64_t Address, const void *Decoder) {
1322fe0bf9f6SMatheus Almeida   int Offset = SignExtend32<10>(fieldFromInstruction(Insn, 16, 10));
1323fe0bf9f6SMatheus Almeida   unsigned Reg = fieldFromInstruction(Insn, 6, 5);
1324fe0bf9f6SMatheus Almeida   unsigned Base = fieldFromInstruction(Insn, 11, 5);
1325fe0bf9f6SMatheus Almeida 
1326fe0bf9f6SMatheus Almeida   Reg = getReg(Decoder, Mips::MSA128BRegClassID, Reg);
1327fe0bf9f6SMatheus Almeida   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1328fe0bf9f6SMatheus Almeida 
1329e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1330e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
13316b59c449SMatheus Almeida 
13326b59c449SMatheus Almeida   // The immediate field of an LD/ST instruction is scaled which means it must
13336b59c449SMatheus Almeida   // be multiplied (when decoding) by the size (in bytes) of the instructions'
13346b59c449SMatheus Almeida   // data format.
13356b59c449SMatheus Almeida   // .b - 1 byte
13366b59c449SMatheus Almeida   // .h - 2 bytes
13376b59c449SMatheus Almeida   // .w - 4 bytes
13386b59c449SMatheus Almeida   // .d - 8 bytes
13396b59c449SMatheus Almeida   switch(Inst.getOpcode())
13406b59c449SMatheus Almeida   {
13416b59c449SMatheus Almeida   default:
13426b59c449SMatheus Almeida     assert (0 && "Unexpected instruction");
13436b59c449SMatheus Almeida     return MCDisassembler::Fail;
13446b59c449SMatheus Almeida     break;
13456b59c449SMatheus Almeida   case Mips::LD_B:
13466b59c449SMatheus Almeida   case Mips::ST_B:
1347e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(Offset));
13486b59c449SMatheus Almeida     break;
13496b59c449SMatheus Almeida   case Mips::LD_H:
13506b59c449SMatheus Almeida   case Mips::ST_H:
1351e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(Offset * 2));
13526b59c449SMatheus Almeida     break;
13536b59c449SMatheus Almeida   case Mips::LD_W:
13546b59c449SMatheus Almeida   case Mips::ST_W:
1355e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(Offset * 4));
13566b59c449SMatheus Almeida     break;
13576b59c449SMatheus Almeida   case Mips::LD_D:
13586b59c449SMatheus Almeida   case Mips::ST_D:
1359e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(Offset * 8));
13606b59c449SMatheus Almeida     break;
13616b59c449SMatheus Almeida   }
1362fe0bf9f6SMatheus Almeida 
1363fe0bf9f6SMatheus Almeida   return MCDisassembler::Success;
1364fe0bf9f6SMatheus Almeida }
1365fe0bf9f6SMatheus Almeida 
1366315e7ecaSJozef Kolek static DecodeStatus DecodeMemMMImm4(MCInst &Inst,
1367315e7ecaSJozef Kolek                                     unsigned Insn,
1368315e7ecaSJozef Kolek                                     uint64_t Address,
1369315e7ecaSJozef Kolek                                     const void *Decoder) {
1370315e7ecaSJozef Kolek   unsigned Offset = Insn & 0xf;
1371315e7ecaSJozef Kolek   unsigned Reg = fieldFromInstruction(Insn, 7, 3);
1372315e7ecaSJozef Kolek   unsigned Base = fieldFromInstruction(Insn, 4, 3);
1373315e7ecaSJozef Kolek 
1374315e7ecaSJozef Kolek   switch (Inst.getOpcode()) {
1375315e7ecaSJozef Kolek     case Mips::LBU16_MM:
1376315e7ecaSJozef Kolek     case Mips::LHU16_MM:
1377315e7ecaSJozef Kolek     case Mips::LW16_MM:
1378315e7ecaSJozef Kolek       if (DecodeGPRMM16RegisterClass(Inst, Reg, Address, Decoder)
1379315e7ecaSJozef Kolek             == MCDisassembler::Fail)
1380315e7ecaSJozef Kolek         return MCDisassembler::Fail;
1381315e7ecaSJozef Kolek       break;
1382315e7ecaSJozef Kolek     case Mips::SB16_MM:
1383315e7ecaSJozef Kolek     case Mips::SH16_MM:
1384315e7ecaSJozef Kolek     case Mips::SW16_MM:
1385315e7ecaSJozef Kolek       if (DecodeGPRMM16ZeroRegisterClass(Inst, Reg, Address, Decoder)
1386315e7ecaSJozef Kolek             == MCDisassembler::Fail)
1387315e7ecaSJozef Kolek         return MCDisassembler::Fail;
1388315e7ecaSJozef Kolek       break;
1389315e7ecaSJozef Kolek   }
1390315e7ecaSJozef Kolek 
1391315e7ecaSJozef Kolek   if (DecodeGPRMM16RegisterClass(Inst, Base, Address, Decoder)
1392315e7ecaSJozef Kolek         == MCDisassembler::Fail)
1393315e7ecaSJozef Kolek     return MCDisassembler::Fail;
1394315e7ecaSJozef Kolek 
1395315e7ecaSJozef Kolek   switch (Inst.getOpcode()) {
1396315e7ecaSJozef Kolek     case Mips::LBU16_MM:
1397315e7ecaSJozef Kolek       if (Offset == 0xf)
1398e9119e41SJim Grosbach         Inst.addOperand(MCOperand::createImm(-1));
1399315e7ecaSJozef Kolek       else
1400e9119e41SJim Grosbach         Inst.addOperand(MCOperand::createImm(Offset));
1401315e7ecaSJozef Kolek       break;
1402315e7ecaSJozef Kolek     case Mips::SB16_MM:
1403e9119e41SJim Grosbach       Inst.addOperand(MCOperand::createImm(Offset));
1404315e7ecaSJozef Kolek       break;
1405315e7ecaSJozef Kolek     case Mips::LHU16_MM:
1406315e7ecaSJozef Kolek     case Mips::SH16_MM:
1407e9119e41SJim Grosbach       Inst.addOperand(MCOperand::createImm(Offset << 1));
1408315e7ecaSJozef Kolek       break;
1409315e7ecaSJozef Kolek     case Mips::LW16_MM:
1410315e7ecaSJozef Kolek     case Mips::SW16_MM:
1411e9119e41SJim Grosbach       Inst.addOperand(MCOperand::createImm(Offset << 2));
1412315e7ecaSJozef Kolek       break;
1413315e7ecaSJozef Kolek   }
1414315e7ecaSJozef Kolek 
1415315e7ecaSJozef Kolek   return MCDisassembler::Success;
1416315e7ecaSJozef Kolek }
1417315e7ecaSJozef Kolek 
141812c6982bSJozef Kolek static DecodeStatus DecodeMemMMSPImm5Lsl2(MCInst &Inst,
141912c6982bSJozef Kolek                                           unsigned Insn,
142012c6982bSJozef Kolek                                           uint64_t Address,
142112c6982bSJozef Kolek                                           const void *Decoder) {
142212c6982bSJozef Kolek   unsigned Offset = Insn & 0x1F;
142312c6982bSJozef Kolek   unsigned Reg = fieldFromInstruction(Insn, 5, 5);
142412c6982bSJozef Kolek 
142512c6982bSJozef Kolek   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
142612c6982bSJozef Kolek 
1427e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1428e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Mips::SP));
1429e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset << 2));
143012c6982bSJozef Kolek 
143112c6982bSJozef Kolek   return MCDisassembler::Success;
143212c6982bSJozef Kolek }
143312c6982bSJozef Kolek 
1434e10a02ecSJozef Kolek static DecodeStatus DecodeMemMMGPImm7Lsl2(MCInst &Inst,
1435e10a02ecSJozef Kolek                                           unsigned Insn,
1436e10a02ecSJozef Kolek                                           uint64_t Address,
1437e10a02ecSJozef Kolek                                           const void *Decoder) {
1438e10a02ecSJozef Kolek   unsigned Offset = Insn & 0x7F;
1439e10a02ecSJozef Kolek   unsigned Reg = fieldFromInstruction(Insn, 7, 3);
1440e10a02ecSJozef Kolek 
1441e10a02ecSJozef Kolek   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1442e10a02ecSJozef Kolek 
1443e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1444e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Mips::GP));
1445e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset << 2));
1446e10a02ecSJozef Kolek 
1447e10a02ecSJozef Kolek   return MCDisassembler::Success;
1448e10a02ecSJozef Kolek }
1449e10a02ecSJozef Kolek 
1450d68d424aSJozef Kolek static DecodeStatus DecodeMemMMReglistImm4Lsl2(MCInst &Inst,
1451d68d424aSJozef Kolek                                                unsigned Insn,
1452d68d424aSJozef Kolek                                                uint64_t Address,
1453d68d424aSJozef Kolek                                                const void *Decoder) {
1454d68d424aSJozef Kolek   int Offset = SignExtend32<4>(Insn & 0xf);
1455d68d424aSJozef Kolek 
1456d68d424aSJozef Kolek   if (DecodeRegListOperand16(Inst, Insn, Address, Decoder)
1457d68d424aSJozef Kolek       == MCDisassembler::Fail)
1458d68d424aSJozef Kolek     return MCDisassembler::Fail;
1459d68d424aSJozef Kolek 
1460e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Mips::SP));
1461e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset << 2));
1462d68d424aSJozef Kolek 
1463d68d424aSJozef Kolek   return MCDisassembler::Success;
1464d68d424aSJozef Kolek }
1465d68d424aSJozef Kolek 
1466a6593ff6SZoran Jovanovic static DecodeStatus DecodeMemMMImm9(MCInst &Inst,
1467a6593ff6SZoran Jovanovic                                     unsigned Insn,
1468a6593ff6SZoran Jovanovic                                     uint64_t Address,
1469a6593ff6SZoran Jovanovic                                     const void *Decoder) {
1470a6593ff6SZoran Jovanovic   int Offset = SignExtend32<9>(Insn & 0x1ff);
1471a6593ff6SZoran Jovanovic   unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1472a6593ff6SZoran Jovanovic   unsigned Base = fieldFromInstruction(Insn, 16, 5);
1473a6593ff6SZoran Jovanovic 
1474a6593ff6SZoran Jovanovic   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1475a6593ff6SZoran Jovanovic   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1476a6593ff6SZoran Jovanovic 
14773ef4dd7bSHrvoje Varga   if (Inst.getOpcode() == Mips::SCE_MM)
14783ef4dd7bSHrvoje Varga     Inst.addOperand(MCOperand::createReg(Reg));
14793ef4dd7bSHrvoje Varga 
1480a6593ff6SZoran Jovanovic   Inst.addOperand(MCOperand::createReg(Reg));
1481a6593ff6SZoran Jovanovic   Inst.addOperand(MCOperand::createReg(Base));
1482a6593ff6SZoran Jovanovic   Inst.addOperand(MCOperand::createImm(Offset));
1483a6593ff6SZoran Jovanovic 
1484a6593ff6SZoran Jovanovic   return MCDisassembler::Success;
1485a6593ff6SZoran Jovanovic }
1486a6593ff6SZoran Jovanovic 
1487dde3d582SVladimir Medic static DecodeStatus DecodeMemMMImm12(MCInst &Inst,
1488dde3d582SVladimir Medic                                      unsigned Insn,
1489dde3d582SVladimir Medic                                      uint64_t Address,
1490dde3d582SVladimir Medic                                      const void *Decoder) {
1491dde3d582SVladimir Medic   int Offset = SignExtend32<12>(Insn & 0x0fff);
1492dde3d582SVladimir Medic   unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1493dde3d582SVladimir Medic   unsigned Base = fieldFromInstruction(Insn, 16, 5);
1494dde3d582SVladimir Medic 
1495dde3d582SVladimir Medic   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1496dde3d582SVladimir Medic   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1497dde3d582SVladimir Medic 
1498a4c4b5fcSZoran Jovanovic   switch (Inst.getOpcode()) {
1499a4c4b5fcSZoran Jovanovic   case Mips::SWM32_MM:
1500a4c4b5fcSZoran Jovanovic   case Mips::LWM32_MM:
1501a4c4b5fcSZoran Jovanovic     if (DecodeRegListOperand(Inst, Insn, Address, Decoder)
1502a4c4b5fcSZoran Jovanovic         == MCDisassembler::Fail)
1503a4c4b5fcSZoran Jovanovic       return MCDisassembler::Fail;
1504e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Base));
1505e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(Offset));
1506a4c4b5fcSZoran Jovanovic     break;
1507a4c4b5fcSZoran Jovanovic   case Mips::SC_MM:
1508e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Reg));
1509a4c4b5fcSZoran Jovanovic     // fallthrough
1510a4c4b5fcSZoran Jovanovic   default:
1511e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Reg));
15122deca348SZoran Jovanovic     if (Inst.getOpcode() == Mips::LWP_MM || Inst.getOpcode() == Mips::SWP_MM)
1513e9119e41SJim Grosbach       Inst.addOperand(MCOperand::createReg(Reg+1));
15142deca348SZoran Jovanovic 
1515e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Base));
1516e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(Offset));
1517a4c4b5fcSZoran Jovanovic   }
1518dde3d582SVladimir Medic 
1519dde3d582SVladimir Medic   return MCDisassembler::Success;
1520dde3d582SVladimir Medic }
1521dde3d582SVladimir Medic 
1522dde3d582SVladimir Medic static DecodeStatus DecodeMemMMImm16(MCInst &Inst,
1523dde3d582SVladimir Medic                                      unsigned Insn,
1524dde3d582SVladimir Medic                                      uint64_t Address,
1525dde3d582SVladimir Medic                                      const void *Decoder) {
1526dde3d582SVladimir Medic   int Offset = SignExtend32<16>(Insn & 0xffff);
1527dde3d582SVladimir Medic   unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1528dde3d582SVladimir Medic   unsigned Base = fieldFromInstruction(Insn, 16, 5);
1529dde3d582SVladimir Medic 
1530dde3d582SVladimir Medic   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1531dde3d582SVladimir Medic   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1532dde3d582SVladimir Medic 
1533e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1534e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1535e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
1536dde3d582SVladimir Medic 
1537dde3d582SVladimir Medic   return MCDisassembler::Success;
1538dde3d582SVladimir Medic }
1539dde3d582SVladimir Medic 
154071928e68SAkira Hatanaka static DecodeStatus DecodeFMem(MCInst &Inst,
154171928e68SAkira Hatanaka                                unsigned Insn,
154271928e68SAkira Hatanaka                                uint64_t Address,
154371928e68SAkira Hatanaka                                const void *Decoder) {
154471928e68SAkira Hatanaka   int Offset = SignExtend32<16>(Insn & 0xffff);
1545ecaef49fSJim Grosbach   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1546ecaef49fSJim Grosbach   unsigned Base = fieldFromInstruction(Insn, 21, 5);
154771928e68SAkira Hatanaka 
15489bf2b567SAkira Hatanaka   Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg);
154913e6ccf3SAkira Hatanaka   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
15509bf2b567SAkira Hatanaka 
1551e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1552e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1553e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
155471928e68SAkira Hatanaka 
155571928e68SAkira Hatanaka   return MCDisassembler::Success;
155671928e68SAkira Hatanaka }
155771928e68SAkira Hatanaka 
155892db6b78SDaniel Sanders static DecodeStatus DecodeFMem2(MCInst &Inst,
155992db6b78SDaniel Sanders                                unsigned Insn,
156092db6b78SDaniel Sanders                                uint64_t Address,
156192db6b78SDaniel Sanders                                const void *Decoder) {
156292db6b78SDaniel Sanders   int Offset = SignExtend32<16>(Insn & 0xffff);
156392db6b78SDaniel Sanders   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
156492db6b78SDaniel Sanders   unsigned Base = fieldFromInstruction(Insn, 21, 5);
156592db6b78SDaniel Sanders 
156692db6b78SDaniel Sanders   Reg = getReg(Decoder, Mips::COP2RegClassID, Reg);
156792db6b78SDaniel Sanders   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
156892db6b78SDaniel Sanders 
1569e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1570e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1571e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
157292db6b78SDaniel Sanders 
157392db6b78SDaniel Sanders   return MCDisassembler::Success;
157492db6b78SDaniel Sanders }
157592db6b78SDaniel Sanders 
157692db6b78SDaniel Sanders static DecodeStatus DecodeFMem3(MCInst &Inst,
157792db6b78SDaniel Sanders                                unsigned Insn,
157892db6b78SDaniel Sanders                                uint64_t Address,
157992db6b78SDaniel Sanders                                const void *Decoder) {
158092db6b78SDaniel Sanders   int Offset = SignExtend32<16>(Insn & 0xffff);
158192db6b78SDaniel Sanders   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
158292db6b78SDaniel Sanders   unsigned Base = fieldFromInstruction(Insn, 21, 5);
158392db6b78SDaniel Sanders 
158492db6b78SDaniel Sanders   Reg = getReg(Decoder, Mips::COP3RegClassID, Reg);
158592db6b78SDaniel Sanders   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
158692db6b78SDaniel Sanders 
1587e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1588e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1589e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
159092db6b78SDaniel Sanders 
159192db6b78SDaniel Sanders   return MCDisassembler::Success;
159292db6b78SDaniel Sanders }
159392db6b78SDaniel Sanders 
1594435cf8a4SVladimir Medic static DecodeStatus DecodeFMemCop2R6(MCInst &Inst,
1595435cf8a4SVladimir Medic                                     unsigned Insn,
1596435cf8a4SVladimir Medic                                     uint64_t Address,
1597435cf8a4SVladimir Medic                                     const void *Decoder) {
1598435cf8a4SVladimir Medic   int Offset = SignExtend32<11>(Insn & 0x07ff);
1599435cf8a4SVladimir Medic   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1600435cf8a4SVladimir Medic   unsigned Base = fieldFromInstruction(Insn, 11, 5);
1601435cf8a4SVladimir Medic 
1602435cf8a4SVladimir Medic   Reg = getReg(Decoder, Mips::COP2RegClassID, Reg);
1603435cf8a4SVladimir Medic   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1604435cf8a4SVladimir Medic 
1605e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1606e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1607e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
1608435cf8a4SVladimir Medic 
1609435cf8a4SVladimir Medic   return MCDisassembler::Success;
1610435cf8a4SVladimir Medic }
16116a803f61SDaniel Sanders static DecodeStatus DecodeSpecial3LlSc(MCInst &Inst,
16126a803f61SDaniel Sanders                                        unsigned Insn,
16136a803f61SDaniel Sanders                                        uint64_t Address,
16146a803f61SDaniel Sanders                                        const void *Decoder) {
16156a803f61SDaniel Sanders   int64_t Offset = SignExtend64<9>((Insn >> 7) & 0x1ff);
16166a803f61SDaniel Sanders   unsigned Rt = fieldFromInstruction(Insn, 16, 5);
16176a803f61SDaniel Sanders   unsigned Base = fieldFromInstruction(Insn, 21, 5);
16186a803f61SDaniel Sanders 
16196a803f61SDaniel Sanders   Rt = getReg(Decoder, Mips::GPR32RegClassID, Rt);
16206a803f61SDaniel Sanders   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
16216a803f61SDaniel Sanders 
16226a803f61SDaniel Sanders   if(Inst.getOpcode() == Mips::SC_R6 || Inst.getOpcode() == Mips::SCD_R6){
1623e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Rt));
16246a803f61SDaniel Sanders   }
16256a803f61SDaniel Sanders 
1626e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Rt));
1627e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1628e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
16296a803f61SDaniel Sanders 
16306a803f61SDaniel Sanders   return MCDisassembler::Success;
16316a803f61SDaniel Sanders }
163271928e68SAkira Hatanaka 
163371928e68SAkira Hatanaka static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
163471928e68SAkira Hatanaka                                               unsigned RegNo,
163571928e68SAkira Hatanaka                                               uint64_t Address,
163671928e68SAkira Hatanaka                                               const void *Decoder) {
163771928e68SAkira Hatanaka   // Currently only hardware register 29 is supported.
163871928e68SAkira Hatanaka   if (RegNo != 29)
163971928e68SAkira Hatanaka     return  MCDisassembler::Fail;
1640e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Mips::HWR29));
164171928e68SAkira Hatanaka   return MCDisassembler::Success;
164271928e68SAkira Hatanaka }
164371928e68SAkira Hatanaka 
164471928e68SAkira Hatanaka static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
164571928e68SAkira Hatanaka                                               unsigned RegNo,
164671928e68SAkira Hatanaka                                               uint64_t Address,
164771928e68SAkira Hatanaka                                               const void *Decoder) {
16489bf2b567SAkira Hatanaka   if (RegNo > 30 || RegNo %2)
164971928e68SAkira Hatanaka     return MCDisassembler::Fail;
165071928e68SAkira Hatanaka 
16519bf2b567SAkira Hatanaka   ;
16529bf2b567SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::AFGR64RegClassID, RegNo /2);
1653e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
165471928e68SAkira Hatanaka   return MCDisassembler::Success;
165571928e68SAkira Hatanaka }
165671928e68SAkira Hatanaka 
165700fcf2e1SAkira Hatanaka static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst,
1658ecabd1a5SAkira Hatanaka                                                 unsigned RegNo,
1659ecabd1a5SAkira Hatanaka                                                 uint64_t Address,
1660ecabd1a5SAkira Hatanaka                                                 const void *Decoder) {
1661ecabd1a5SAkira Hatanaka   if (RegNo >= 4)
1662ecabd1a5SAkira Hatanaka     return MCDisassembler::Fail;
1663ecabd1a5SAkira Hatanaka 
166400fcf2e1SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::ACC64DSPRegClassID, RegNo);
1665e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1666ecabd1a5SAkira Hatanaka   return MCDisassembler::Success;
1667ecabd1a5SAkira Hatanaka }
1668ecabd1a5SAkira Hatanaka 
16698002a3f6SAkira Hatanaka static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst,
167059bfaf77SAkira Hatanaka                                                unsigned RegNo,
167159bfaf77SAkira Hatanaka                                                uint64_t Address,
167259bfaf77SAkira Hatanaka                                                const void *Decoder) {
167359bfaf77SAkira Hatanaka   if (RegNo >= 4)
167459bfaf77SAkira Hatanaka     return MCDisassembler::Fail;
167559bfaf77SAkira Hatanaka 
16768002a3f6SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::HI32DSPRegClassID, RegNo);
1677e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
167859bfaf77SAkira Hatanaka   return MCDisassembler::Success;
167959bfaf77SAkira Hatanaka }
168059bfaf77SAkira Hatanaka 
16818002a3f6SAkira Hatanaka static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst,
168259bfaf77SAkira Hatanaka                                                unsigned RegNo,
168359bfaf77SAkira Hatanaka                                                uint64_t Address,
168459bfaf77SAkira Hatanaka                                                const void *Decoder) {
168559bfaf77SAkira Hatanaka   if (RegNo >= 4)
168659bfaf77SAkira Hatanaka     return MCDisassembler::Fail;
168759bfaf77SAkira Hatanaka 
16888002a3f6SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::LO32DSPRegClassID, RegNo);
1689e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
169059bfaf77SAkira Hatanaka   return MCDisassembler::Success;
169159bfaf77SAkira Hatanaka }
169259bfaf77SAkira Hatanaka 
16933eb663b0SJack Carter static DecodeStatus DecodeMSA128BRegisterClass(MCInst &Inst,
16943eb663b0SJack Carter                                                unsigned RegNo,
16953eb663b0SJack Carter                                                uint64_t Address,
16963eb663b0SJack Carter                                                const void *Decoder) {
16973eb663b0SJack Carter   if (RegNo > 31)
16983eb663b0SJack Carter     return MCDisassembler::Fail;
16993eb663b0SJack Carter 
17003eb663b0SJack Carter   unsigned Reg = getReg(Decoder, Mips::MSA128BRegClassID, RegNo);
1701e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
17023eb663b0SJack Carter   return MCDisassembler::Success;
17033eb663b0SJack Carter }
17043eb663b0SJack Carter 
17055dc8ac92SJack Carter static DecodeStatus DecodeMSA128HRegisterClass(MCInst &Inst,
17065dc8ac92SJack Carter                                                unsigned RegNo,
17075dc8ac92SJack Carter                                                uint64_t Address,
17085dc8ac92SJack Carter                                                const void *Decoder) {
17095dc8ac92SJack Carter   if (RegNo > 31)
17105dc8ac92SJack Carter     return MCDisassembler::Fail;
17115dc8ac92SJack Carter 
17125dc8ac92SJack Carter   unsigned Reg = getReg(Decoder, Mips::MSA128HRegClassID, RegNo);
1713e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
17145dc8ac92SJack Carter   return MCDisassembler::Success;
17155dc8ac92SJack Carter }
17165dc8ac92SJack Carter 
17175dc8ac92SJack Carter static DecodeStatus DecodeMSA128WRegisterClass(MCInst &Inst,
17185dc8ac92SJack Carter                                                unsigned RegNo,
17195dc8ac92SJack Carter                                                uint64_t Address,
17205dc8ac92SJack Carter                                                const void *Decoder) {
17215dc8ac92SJack Carter   if (RegNo > 31)
17225dc8ac92SJack Carter     return MCDisassembler::Fail;
17235dc8ac92SJack Carter 
17245dc8ac92SJack Carter   unsigned Reg = getReg(Decoder, Mips::MSA128WRegClassID, RegNo);
1725e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
17265dc8ac92SJack Carter   return MCDisassembler::Success;
17275dc8ac92SJack Carter }
17285dc8ac92SJack Carter 
17295dc8ac92SJack Carter static DecodeStatus DecodeMSA128DRegisterClass(MCInst &Inst,
17305dc8ac92SJack Carter                                                unsigned RegNo,
17315dc8ac92SJack Carter                                                uint64_t Address,
17325dc8ac92SJack Carter                                                const void *Decoder) {
17335dc8ac92SJack Carter   if (RegNo > 31)
17345dc8ac92SJack Carter     return MCDisassembler::Fail;
17355dc8ac92SJack Carter 
17365dc8ac92SJack Carter   unsigned Reg = getReg(Decoder, Mips::MSA128DRegClassID, RegNo);
1737e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
17385dc8ac92SJack Carter   return MCDisassembler::Success;
17395dc8ac92SJack Carter }
17405dc8ac92SJack Carter 
1741a591fdc6SMatheus Almeida static DecodeStatus DecodeMSACtrlRegisterClass(MCInst &Inst,
1742a591fdc6SMatheus Almeida                                                unsigned RegNo,
1743a591fdc6SMatheus Almeida                                                uint64_t Address,
1744a591fdc6SMatheus Almeida                                                const void *Decoder) {
1745a591fdc6SMatheus Almeida   if (RegNo > 7)
1746a591fdc6SMatheus Almeida     return MCDisassembler::Fail;
1747a591fdc6SMatheus Almeida 
1748a591fdc6SMatheus Almeida   unsigned Reg = getReg(Decoder, Mips::MSACtrlRegClassID, RegNo);
1749e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1750a591fdc6SMatheus Almeida   return MCDisassembler::Success;
1751a591fdc6SMatheus Almeida }
1752a591fdc6SMatheus Almeida 
1753a3134faeSDaniel Sanders static DecodeStatus DecodeCOP0RegisterClass(MCInst &Inst,
1754a3134faeSDaniel Sanders                                             unsigned RegNo,
1755a3134faeSDaniel Sanders                                             uint64_t Address,
1756a3134faeSDaniel Sanders                                             const void *Decoder) {
1757a3134faeSDaniel Sanders   if (RegNo > 31)
1758a3134faeSDaniel Sanders     return MCDisassembler::Fail;
1759a3134faeSDaniel Sanders 
1760a3134faeSDaniel Sanders   unsigned Reg = getReg(Decoder, Mips::COP0RegClassID, RegNo);
1761a3134faeSDaniel Sanders   Inst.addOperand(MCOperand::createReg(Reg));
1762a3134faeSDaniel Sanders   return MCDisassembler::Success;
1763a3134faeSDaniel Sanders }
1764a3134faeSDaniel Sanders 
17652a83d680SDaniel Sanders static DecodeStatus DecodeCOP2RegisterClass(MCInst &Inst,
17662a83d680SDaniel Sanders                                             unsigned RegNo,
17672a83d680SDaniel Sanders                                             uint64_t Address,
17682a83d680SDaniel Sanders                                             const void *Decoder) {
17692a83d680SDaniel Sanders   if (RegNo > 31)
17702a83d680SDaniel Sanders     return MCDisassembler::Fail;
17712a83d680SDaniel Sanders 
17722a83d680SDaniel Sanders   unsigned Reg = getReg(Decoder, Mips::COP2RegClassID, RegNo);
1773e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
17742a83d680SDaniel Sanders   return MCDisassembler::Success;
17752a83d680SDaniel Sanders }
17762a83d680SDaniel Sanders 
177771928e68SAkira Hatanaka static DecodeStatus DecodeBranchTarget(MCInst &Inst,
177871928e68SAkira Hatanaka                                        unsigned Offset,
177971928e68SAkira Hatanaka                                        uint64_t Address,
178071928e68SAkira Hatanaka                                        const void *Decoder) {
1781d37bab61SAlexey Samsonov   int32_t BranchOffset = (SignExtend32<16>(Offset) * 4) + 4;
1782e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(BranchOffset));
178371928e68SAkira Hatanaka   return MCDisassembler::Success;
178471928e68SAkira Hatanaka }
178571928e68SAkira Hatanaka 
178671928e68SAkira Hatanaka static DecodeStatus DecodeJumpTarget(MCInst &Inst,
178771928e68SAkira Hatanaka                                      unsigned Insn,
178871928e68SAkira Hatanaka                                      uint64_t Address,
178971928e68SAkira Hatanaka                                      const void *Decoder) {
179071928e68SAkira Hatanaka 
1791ecaef49fSJim Grosbach   unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 2;
1792e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(JumpOffset));
179371928e68SAkira Hatanaka   return MCDisassembler::Success;
179471928e68SAkira Hatanaka }
179571928e68SAkira Hatanaka 
17963c8869dcSZoran Jovanovic static DecodeStatus DecodeBranchTarget21(MCInst &Inst,
17973c8869dcSZoran Jovanovic                                          unsigned Offset,
17983c8869dcSZoran Jovanovic                                          uint64_t Address,
17993c8869dcSZoran Jovanovic                                          const void *Decoder) {
1800d37bab61SAlexey Samsonov   int32_t BranchOffset = SignExtend32<21>(Offset) * 4;
18013c8869dcSZoran Jovanovic 
1802e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(BranchOffset));
18033c8869dcSZoran Jovanovic   return MCDisassembler::Success;
18043c8869dcSZoran Jovanovic }
18053c8869dcSZoran Jovanovic 
18063c8869dcSZoran Jovanovic static DecodeStatus DecodeBranchTarget26(MCInst &Inst,
18073c8869dcSZoran Jovanovic                                          unsigned Offset,
18083c8869dcSZoran Jovanovic                                          uint64_t Address,
18093c8869dcSZoran Jovanovic                                          const void *Decoder) {
1810d37bab61SAlexey Samsonov   int32_t BranchOffset = SignExtend32<26>(Offset) * 4;
18113c8869dcSZoran Jovanovic 
1812e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(BranchOffset));
18133c8869dcSZoran Jovanovic   return MCDisassembler::Success;
18143c8869dcSZoran Jovanovic }
18153c8869dcSZoran Jovanovic 
18169761e96bSJozef Kolek static DecodeStatus DecodeBranchTarget7MM(MCInst &Inst,
18179761e96bSJozef Kolek                                           unsigned Offset,
18189761e96bSJozef Kolek                                           uint64_t Address,
18199761e96bSJozef Kolek                                           const void *Decoder) {
18209761e96bSJozef Kolek   int32_t BranchOffset = SignExtend32<7>(Offset) << 1;
1821e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(BranchOffset));
18229761e96bSJozef Kolek   return MCDisassembler::Success;
18239761e96bSJozef Kolek }
18249761e96bSJozef Kolek 
18255cfebddeSJozef Kolek static DecodeStatus DecodeBranchTarget10MM(MCInst &Inst,
18265cfebddeSJozef Kolek                                            unsigned Offset,
18275cfebddeSJozef Kolek                                            uint64_t Address,
18285cfebddeSJozef Kolek                                            const void *Decoder) {
18295cfebddeSJozef Kolek   int32_t BranchOffset = SignExtend32<10>(Offset) << 1;
1830e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(BranchOffset));
18315cfebddeSJozef Kolek   return MCDisassembler::Success;
18325cfebddeSJozef Kolek }
18335cfebddeSJozef Kolek 
18348a80aa76SZoran Jovanovic static DecodeStatus DecodeBranchTargetMM(MCInst &Inst,
18358a80aa76SZoran Jovanovic                                          unsigned Offset,
18368a80aa76SZoran Jovanovic                                          uint64_t Address,
18378a80aa76SZoran Jovanovic                                          const void *Decoder) {
1838d37bab61SAlexey Samsonov   int32_t BranchOffset = SignExtend32<16>(Offset) * 2;
1839e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(BranchOffset));
18408a80aa76SZoran Jovanovic   return MCDisassembler::Success;
18418a80aa76SZoran Jovanovic }
18428a80aa76SZoran Jovanovic 
1843507e084aSZoran Jovanovic static DecodeStatus DecodeJumpTargetMM(MCInst &Inst,
1844507e084aSZoran Jovanovic                                        unsigned Insn,
1845507e084aSZoran Jovanovic                                        uint64_t Address,
1846507e084aSZoran Jovanovic                                        const void *Decoder) {
1847507e084aSZoran Jovanovic   unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 1;
1848e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(JumpOffset));
1849507e084aSZoran Jovanovic   return MCDisassembler::Success;
1850507e084aSZoran Jovanovic }
185171928e68SAkira Hatanaka 
1852aa2b9278SJozef Kolek static DecodeStatus DecodeAddiur2Simm7(MCInst &Inst,
1853aa2b9278SJozef Kolek                                        unsigned Value,
1854aa2b9278SJozef Kolek                                        uint64_t Address,
1855aa2b9278SJozef Kolek                                        const void *Decoder) {
1856aa2b9278SJozef Kolek   if (Value == 0)
1857e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(1));
1858aa2b9278SJozef Kolek   else if (Value == 0x7)
1859e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(-1));
1860aa2b9278SJozef Kolek   else
1861e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(Value << 2));
1862aa2b9278SJozef Kolek   return MCDisassembler::Success;
1863aa2b9278SJozef Kolek }
1864aa2b9278SJozef Kolek 
1865aa2b9278SJozef Kolek static DecodeStatus DecodeUImm6Lsl2(MCInst &Inst,
1866aa2b9278SJozef Kolek                                     unsigned Value,
1867aa2b9278SJozef Kolek                                     uint64_t Address,
1868aa2b9278SJozef Kolek                                     const void *Decoder) {
1869e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Value << 2));
1870aa2b9278SJozef Kolek   return MCDisassembler::Success;
1871aa2b9278SJozef Kolek }
1872aa2b9278SJozef Kolek 
1873aa2b9278SJozef Kolek static DecodeStatus DecodeLiSimm7(MCInst &Inst,
1874aa2b9278SJozef Kolek                                   unsigned Value,
1875aa2b9278SJozef Kolek                                   uint64_t Address,
1876aa2b9278SJozef Kolek                                   const void *Decoder) {
1877aa2b9278SJozef Kolek   if (Value == 0x7F)
1878e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(-1));
1879aa2b9278SJozef Kolek   else
1880e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(Value));
1881aa2b9278SJozef Kolek   return MCDisassembler::Success;
1882aa2b9278SJozef Kolek }
1883aa2b9278SJozef Kolek 
18846b28f09dSZoran Jovanovic static DecodeStatus DecodePOOL16BEncodedField(MCInst &Inst,
18856b28f09dSZoran Jovanovic                                               unsigned Value,
18866b28f09dSZoran Jovanovic                                               uint64_t Address,
18876b28f09dSZoran Jovanovic                                               const void *Decoder) {
18886b28f09dSZoran Jovanovic   Inst.addOperand(MCOperand::createImm(Value == 0x0 ? 8 : Value));
18896b28f09dSZoran Jovanovic   return MCDisassembler::Success;
18906b28f09dSZoran Jovanovic }
18916b28f09dSZoran Jovanovic 
1892aa2b9278SJozef Kolek static DecodeStatus DecodeSimm4(MCInst &Inst,
1893aa2b9278SJozef Kolek                                 unsigned Value,
1894aa2b9278SJozef Kolek                                 uint64_t Address,
1895aa2b9278SJozef Kolek                                 const void *Decoder) {
1896e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(SignExtend32<4>(Value)));
1897aa2b9278SJozef Kolek   return MCDisassembler::Success;
1898aa2b9278SJozef Kolek }
1899aa2b9278SJozef Kolek 
190071928e68SAkira Hatanaka static DecodeStatus DecodeSimm16(MCInst &Inst,
190171928e68SAkira Hatanaka                                  unsigned Insn,
190271928e68SAkira Hatanaka                                  uint64_t Address,
190371928e68SAkira Hatanaka                                  const void *Decoder) {
1904e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(SignExtend32<16>(Insn)));
190571928e68SAkira Hatanaka   return MCDisassembler::Success;
190671928e68SAkira Hatanaka }
190771928e68SAkira Hatanaka 
1908*ea4f653dSDaniel Sanders template <unsigned Bits, int Offset>
1909*ea4f653dSDaniel Sanders static DecodeStatus DecodeUImmWithOffset(MCInst &Inst, unsigned Value,
1910779c5937SMatheus Almeida                                          uint64_t Address,
1911779c5937SMatheus Almeida                                          const void *Decoder) {
1912*ea4f653dSDaniel Sanders   Value &= ((1 << Bits) - 1);
1913*ea4f653dSDaniel Sanders   Inst.addOperand(MCOperand::createImm(Value + Offset));
1914779c5937SMatheus Almeida   return MCDisassembler::Success;
1915779c5937SMatheus Almeida }
1916779c5937SMatheus Almeida 
191771928e68SAkira Hatanaka static DecodeStatus DecodeInsSize(MCInst &Inst,
191871928e68SAkira Hatanaka                                   unsigned Insn,
191971928e68SAkira Hatanaka                                   uint64_t Address,
192071928e68SAkira Hatanaka                                   const void *Decoder) {
192171928e68SAkira Hatanaka   // First we need to grab the pos(lsb) from MCInst.
192271928e68SAkira Hatanaka   int Pos = Inst.getOperand(2).getImm();
192371928e68SAkira Hatanaka   int Size = (int) Insn - Pos + 1;
1924e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(SignExtend32<16>(Size)));
192571928e68SAkira Hatanaka   return MCDisassembler::Success;
192671928e68SAkira Hatanaka }
192771928e68SAkira Hatanaka 
192871928e68SAkira Hatanaka static DecodeStatus DecodeExtSize(MCInst &Inst,
192971928e68SAkira Hatanaka                                   unsigned Insn,
193071928e68SAkira Hatanaka                                   uint64_t Address,
193171928e68SAkira Hatanaka                                   const void *Decoder) {
193271928e68SAkira Hatanaka   int Size = (int) Insn  + 1;
1933e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(SignExtend32<16>(Size)));
193471928e68SAkira Hatanaka   return MCDisassembler::Success;
193571928e68SAkira Hatanaka }
1936b59e1a41SDaniel Sanders 
1937b59e1a41SDaniel Sanders static DecodeStatus DecodeSimm19Lsl2(MCInst &Inst, unsigned Insn,
1938b59e1a41SDaniel Sanders                                      uint64_t Address, const void *Decoder) {
1939e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(SignExtend32<19>(Insn) * 4));
1940b59e1a41SDaniel Sanders   return MCDisassembler::Success;
1941b59e1a41SDaniel Sanders }
19422855142aSZoran Jovanovic 
19432855142aSZoran Jovanovic static DecodeStatus DecodeSimm18Lsl3(MCInst &Inst, unsigned Insn,
19442855142aSZoran Jovanovic                                      uint64_t Address, const void *Decoder) {
1945e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(SignExtend32<18>(Insn) * 8));
19462855142aSZoran Jovanovic   return MCDisassembler::Success;
19472855142aSZoran Jovanovic }
1948a4c4b5fcSZoran Jovanovic 
1949b682ddf3SVladimir Medic static DecodeStatus DecodeSimm9SP(MCInst &Inst, unsigned Insn,
1950b682ddf3SVladimir Medic                                   uint64_t Address, const void *Decoder) {
1951b682ddf3SVladimir Medic   int32_t DecodedValue;
1952b682ddf3SVladimir Medic   switch (Insn) {
1953b682ddf3SVladimir Medic   case 0: DecodedValue = 256; break;
1954b682ddf3SVladimir Medic   case 1: DecodedValue = 257; break;
1955b682ddf3SVladimir Medic   case 510: DecodedValue = -258; break;
1956b682ddf3SVladimir Medic   case 511: DecodedValue = -257; break;
1957b682ddf3SVladimir Medic   default: DecodedValue = SignExtend32<9>(Insn); break;
1958b682ddf3SVladimir Medic   }
1959e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(DecodedValue * 4));
1960b682ddf3SVladimir Medic   return MCDisassembler::Success;
1961b682ddf3SVladimir Medic }
1962b682ddf3SVladimir Medic 
1963b682ddf3SVladimir Medic static DecodeStatus DecodeANDI16Imm(MCInst &Inst, unsigned Insn,
1964b682ddf3SVladimir Medic                                     uint64_t Address, const void *Decoder) {
1965b682ddf3SVladimir Medic   // Insn must be >= 0, since it is unsigned that condition is always true.
1966b682ddf3SVladimir Medic   assert(Insn < 16);
1967b682ddf3SVladimir Medic   int32_t DecodedValues[] = {128, 1, 2, 3, 4, 7, 8, 15, 16, 31, 32, 63, 64,
1968b682ddf3SVladimir Medic                              255, 32768, 65535};
1969e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(DecodedValues[Insn]));
1970b682ddf3SVladimir Medic   return MCDisassembler::Success;
1971b682ddf3SVladimir Medic }
1972b682ddf3SVladimir Medic 
1973b682ddf3SVladimir Medic static DecodeStatus DecodeUImm5lsl2(MCInst &Inst, unsigned Insn,
1974b682ddf3SVladimir Medic                                     uint64_t Address, const void *Decoder) {
1975e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Insn << 2));
1976b682ddf3SVladimir Medic   return MCDisassembler::Success;
1977b682ddf3SVladimir Medic }
1978b682ddf3SVladimir Medic 
1979a4c4b5fcSZoran Jovanovic static DecodeStatus DecodeRegListOperand(MCInst &Inst,
1980a4c4b5fcSZoran Jovanovic                                          unsigned Insn,
1981a4c4b5fcSZoran Jovanovic                                          uint64_t Address,
1982a4c4b5fcSZoran Jovanovic                                          const void *Decoder) {
1983a4c4b5fcSZoran Jovanovic   unsigned Regs[] = {Mips::S0, Mips::S1, Mips::S2, Mips::S3, Mips::S4, Mips::S5,
1984dc4b8c27SZoran Jovanovic                      Mips::S6, Mips::S7, Mips::FP};
1985a4c4b5fcSZoran Jovanovic   unsigned RegNum;
1986a4c4b5fcSZoran Jovanovic 
1987a4c4b5fcSZoran Jovanovic   unsigned RegLst = fieldFromInstruction(Insn, 21, 5);
1988df19a5e6SDaniel Sanders 
1989a4c4b5fcSZoran Jovanovic   // Empty register lists are not allowed.
1990a4c4b5fcSZoran Jovanovic   if (RegLst == 0)
1991a4c4b5fcSZoran Jovanovic     return MCDisassembler::Fail;
1992a4c4b5fcSZoran Jovanovic 
1993a4c4b5fcSZoran Jovanovic   RegNum = RegLst & 0xf;
1994df19a5e6SDaniel Sanders 
1995df19a5e6SDaniel Sanders   // RegLst values 10-15, and 26-31 are reserved.
1996df19a5e6SDaniel Sanders   if (RegNum > 9)
1997df19a5e6SDaniel Sanders     return MCDisassembler::Fail;
1998df19a5e6SDaniel Sanders 
1999a4c4b5fcSZoran Jovanovic   for (unsigned i = 0; i < RegNum; i++)
2000e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Regs[i]));
2001a4c4b5fcSZoran Jovanovic 
2002a4c4b5fcSZoran Jovanovic   if (RegLst & 0x10)
2003e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::RA));
2004a4c4b5fcSZoran Jovanovic 
2005a4c4b5fcSZoran Jovanovic   return MCDisassembler::Success;
2006a4c4b5fcSZoran Jovanovic }
2007f9a02500SZoran Jovanovic 
2008f9a02500SZoran Jovanovic static DecodeStatus DecodeRegListOperand16(MCInst &Inst, unsigned Insn,
2009f9a02500SZoran Jovanovic                                            uint64_t Address,
2010f9a02500SZoran Jovanovic                                            const void *Decoder) {
2011f9a02500SZoran Jovanovic   unsigned Regs[] = {Mips::S0, Mips::S1, Mips::S2, Mips::S3};
2012f9a02500SZoran Jovanovic   unsigned RegLst = fieldFromInstruction(Insn, 4, 2);
2013d68d424aSJozef Kolek   unsigned RegNum = RegLst & 0x3;
2014f9a02500SZoran Jovanovic 
2015d68d424aSJozef Kolek   for (unsigned i = 0; i <= RegNum; i++)
2016e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Regs[i]));
2017f9a02500SZoran Jovanovic 
2018e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Mips::RA));
2019f9a02500SZoran Jovanovic 
2020f9a02500SZoran Jovanovic   return MCDisassembler::Success;
2021f9a02500SZoran Jovanovic }
20222c6d7320SJozef Kolek 
202341688679SZoran Jovanovic static DecodeStatus DecodeMovePRegPair(MCInst &Inst, unsigned Insn,
202441688679SZoran Jovanovic                                        uint64_t Address, const void *Decoder) {
202541688679SZoran Jovanovic 
202641688679SZoran Jovanovic   unsigned RegPair = fieldFromInstruction(Insn, 7, 3);
202741688679SZoran Jovanovic 
202841688679SZoran Jovanovic   switch (RegPair) {
202941688679SZoran Jovanovic   default:
203041688679SZoran Jovanovic     return MCDisassembler::Fail;
203141688679SZoran Jovanovic   case 0:
2032e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A1));
2033e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A2));
203441688679SZoran Jovanovic     break;
203541688679SZoran Jovanovic   case 1:
2036e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A1));
2037e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A3));
203841688679SZoran Jovanovic     break;
203941688679SZoran Jovanovic   case 2:
2040e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A2));
2041e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A3));
204241688679SZoran Jovanovic     break;
204341688679SZoran Jovanovic   case 3:
2044e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A0));
2045e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::S5));
204641688679SZoran Jovanovic     break;
204741688679SZoran Jovanovic   case 4:
2048e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A0));
2049e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::S6));
205041688679SZoran Jovanovic     break;
205141688679SZoran Jovanovic   case 5:
2052e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A0));
2053e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A1));
205441688679SZoran Jovanovic     break;
205541688679SZoran Jovanovic   case 6:
2056e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A0));
2057e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A2));
205841688679SZoran Jovanovic     break;
205941688679SZoran Jovanovic   case 7:
2060e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A0));
2061e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A3));
206241688679SZoran Jovanovic     break;
206341688679SZoran Jovanovic   }
206441688679SZoran Jovanovic 
206541688679SZoran Jovanovic   return MCDisassembler::Success;
206641688679SZoran Jovanovic }
206741688679SZoran Jovanovic 
20682c6d7320SJozef Kolek static DecodeStatus DecodeSimm23Lsl2(MCInst &Inst, unsigned Insn,
20692c6d7320SJozef Kolek                                      uint64_t Address, const void *Decoder) {
20706499b5f0SJustin Bogner   Inst.addOperand(MCOperand::createImm(SignExtend32<25>(Insn << 2)));
20712c6d7320SJozef Kolek   return MCDisassembler::Success;
20722c6d7320SJozef Kolek }
2073