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"
18f57c1977SBenjamin Kramer #include "llvm/MC/MCDisassembler/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   }
476221be8eSZlatko Buljan   bool isFP64() const { return STI.getFeatureBits()[Mips::FeatureFP64Bit]; }
485c582b2fSDaniel Sanders 
49db0712f9SMichael Kuperstein   bool isGP64() const { return STI.getFeatureBits()[Mips::FeatureGP64Bit]; }
500fa60416SDaniel Sanders 
513adf9b8dSKai Nacke   bool hasCnMips() const { return STI.getFeatureBits()[Mips::FeatureCnMips]; }
523adf9b8dSKai Nacke 
53c171f65aSDaniel Sanders   bool hasCOP3() const {
54c171f65aSDaniel Sanders     // Only present in MIPS-I and MIPS-II
55c171f65aSDaniel Sanders     return !hasMips32() && !hasMips3();
56c171f65aSDaniel Sanders   }
57c171f65aSDaniel Sanders 
584aa6bea7SRafael Espindola   DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
597fc5b874SRafael Espindola                               ArrayRef<uint8_t> Bytes, uint64_t Address,
604aa6bea7SRafael Espindola                               raw_ostream &VStream,
614aa6bea7SRafael Espindola                               raw_ostream &CStream) const override;
6271928e68SAkira Hatanaka };
6371928e68SAkira Hatanaka 
64cb3e98cfSBenjamin Kramer } // end anonymous namespace
65cb3e98cfSBenjamin Kramer 
6671928e68SAkira Hatanaka // Forward declare these because the autogenerated code will reference them.
6771928e68SAkira Hatanaka // Definitions are further down.
6813e6ccf3SAkira Hatanaka static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst,
6971928e68SAkira Hatanaka                                              unsigned RegNo,
7071928e68SAkira Hatanaka                                              uint64_t Address,
7171928e68SAkira Hatanaka                                              const void *Decoder);
7271928e68SAkira Hatanaka 
73ec8a5490SReed Kotler static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst,
74ec8a5490SReed Kotler                                                  unsigned RegNo,
75ec8a5490SReed Kotler                                                  uint64_t Address,
76ec8a5490SReed Kotler                                                  const void *Decoder);
77ec8a5490SReed Kotler 
78b0852e54SZoran Jovanovic static DecodeStatus DecodeGPRMM16RegisterClass(MCInst &Inst,
79b0852e54SZoran Jovanovic                                                unsigned RegNo,
80b0852e54SZoran Jovanovic                                                uint64_t Address,
81b0852e54SZoran Jovanovic                                                const void *Decoder);
82b0852e54SZoran Jovanovic 
831904fa21SJozef Kolek static DecodeStatus DecodeGPRMM16ZeroRegisterClass(MCInst &Inst,
841904fa21SJozef Kolek                                                    unsigned RegNo,
851904fa21SJozef Kolek                                                    uint64_t Address,
861904fa21SJozef Kolek                                                    const void *Decoder);
871904fa21SJozef Kolek 
8841688679SZoran Jovanovic static DecodeStatus DecodeGPRMM16MovePRegisterClass(MCInst &Inst,
8941688679SZoran Jovanovic                                                     unsigned RegNo,
9041688679SZoran Jovanovic                                                     uint64_t Address,
9141688679SZoran Jovanovic                                                     const void *Decoder);
9241688679SZoran Jovanovic 
9313e6ccf3SAkira Hatanaka static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst,
9471928e68SAkira Hatanaka                                              unsigned RegNo,
9571928e68SAkira Hatanaka                                              uint64_t Address,
9671928e68SAkira Hatanaka                                              const void *Decoder);
9771928e68SAkira Hatanaka 
989bfa2e2eSAkira Hatanaka static DecodeStatus DecodePtrRegisterClass(MCInst &Inst,
999bfa2e2eSAkira Hatanaka                                            unsigned Insn,
1009bfa2e2eSAkira Hatanaka                                            uint64_t Address,
1019bfa2e2eSAkira Hatanaka                                            const void *Decoder);
1029bfa2e2eSAkira Hatanaka 
103654655f1SAkira Hatanaka static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst,
104ecabd1a5SAkira Hatanaka                                             unsigned RegNo,
105ecabd1a5SAkira Hatanaka                                             uint64_t Address,
106ecabd1a5SAkira Hatanaka                                             const void *Decoder);
107ecabd1a5SAkira Hatanaka 
10871928e68SAkira Hatanaka static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
10971928e68SAkira Hatanaka                                              unsigned RegNo,
11071928e68SAkira Hatanaka                                              uint64_t Address,
11171928e68SAkira Hatanaka                                              const void *Decoder);
11271928e68SAkira Hatanaka 
11371928e68SAkira Hatanaka static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
11471928e68SAkira Hatanaka                                              unsigned RegNo,
11571928e68SAkira Hatanaka                                              uint64_t Address,
11671928e68SAkira Hatanaka                                              const void *Decoder);
11771928e68SAkira Hatanaka 
11871928e68SAkira Hatanaka static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
11971928e68SAkira Hatanaka                                            unsigned RegNo,
12071928e68SAkira Hatanaka                                            uint64_t Address,
12171928e68SAkira Hatanaka                                            const void *Decoder);
12271928e68SAkira Hatanaka 
1231fb1b8b8SAkira Hatanaka static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst,
1241fb1b8b8SAkira Hatanaka                                            unsigned RegNo,
1251fb1b8b8SAkira Hatanaka                                            uint64_t Address,
1261fb1b8b8SAkira Hatanaka                                            const void *Decoder);
1271fb1b8b8SAkira Hatanaka 
12836901dd1SVasileios Kalintiris static DecodeStatus DecodeFGRCCRegisterClass(MCInst &Inst, unsigned RegNo,
1290fa60416SDaniel Sanders                                              uint64_t Address,
1300fa60416SDaniel Sanders                                              const void *Decoder);
1310fa60416SDaniel Sanders 
13271928e68SAkira Hatanaka static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
13371928e68SAkira Hatanaka                                               unsigned Insn,
13471928e68SAkira Hatanaka                                               uint64_t Address,
13571928e68SAkira Hatanaka                                               const void *Decoder);
13671928e68SAkira Hatanaka 
13771928e68SAkira Hatanaka static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
13871928e68SAkira Hatanaka                                               unsigned RegNo,
13971928e68SAkira Hatanaka                                               uint64_t Address,
14071928e68SAkira Hatanaka                                               const void *Decoder);
14171928e68SAkira Hatanaka 
14200fcf2e1SAkira Hatanaka static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst,
143ecabd1a5SAkira Hatanaka                                                 unsigned RegNo,
144ecabd1a5SAkira Hatanaka                                                 uint64_t Address,
145ecabd1a5SAkira Hatanaka                                                 const void *Decoder);
146ecabd1a5SAkira Hatanaka 
1478002a3f6SAkira Hatanaka static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst,
14859bfaf77SAkira Hatanaka                                                unsigned RegNo,
14959bfaf77SAkira Hatanaka                                                uint64_t Address,
15059bfaf77SAkira Hatanaka                                                const void *Decoder);
15159bfaf77SAkira Hatanaka 
1528002a3f6SAkira Hatanaka static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst,
15359bfaf77SAkira Hatanaka                                                unsigned RegNo,
15459bfaf77SAkira Hatanaka                                                uint64_t Address,
15559bfaf77SAkira Hatanaka                                                const void *Decoder);
15659bfaf77SAkira Hatanaka 
1573eb663b0SJack Carter static DecodeStatus DecodeMSA128BRegisterClass(MCInst &Inst,
1583eb663b0SJack Carter                                                unsigned RegNo,
1593eb663b0SJack Carter                                                uint64_t Address,
1603eb663b0SJack Carter                                                const void *Decoder);
1613eb663b0SJack Carter 
1625dc8ac92SJack Carter static DecodeStatus DecodeMSA128HRegisterClass(MCInst &Inst,
1635dc8ac92SJack Carter                                                unsigned RegNo,
1645dc8ac92SJack Carter                                                uint64_t Address,
1655dc8ac92SJack Carter                                                const void *Decoder);
1665dc8ac92SJack Carter 
1675dc8ac92SJack Carter static DecodeStatus DecodeMSA128WRegisterClass(MCInst &Inst,
1685dc8ac92SJack Carter                                                unsigned RegNo,
1695dc8ac92SJack Carter                                                uint64_t Address,
1705dc8ac92SJack Carter                                                const void *Decoder);
1715dc8ac92SJack Carter 
1725dc8ac92SJack Carter static DecodeStatus DecodeMSA128DRegisterClass(MCInst &Inst,
1735dc8ac92SJack Carter                                                unsigned RegNo,
1745dc8ac92SJack Carter                                                uint64_t Address,
1755dc8ac92SJack Carter                                                const void *Decoder);
1765dc8ac92SJack Carter 
177a591fdc6SMatheus Almeida static DecodeStatus DecodeMSACtrlRegisterClass(MCInst &Inst,
178a591fdc6SMatheus Almeida                                                unsigned RegNo,
179a591fdc6SMatheus Almeida                                                uint64_t Address,
180a591fdc6SMatheus Almeida                                                const void *Decoder);
181a591fdc6SMatheus Almeida 
182a3134faeSDaniel Sanders static DecodeStatus DecodeCOP0RegisterClass(MCInst &Inst,
183a3134faeSDaniel Sanders                                             unsigned RegNo,
184a3134faeSDaniel Sanders                                             uint64_t Address,
185a3134faeSDaniel Sanders                                             const void *Decoder);
186a3134faeSDaniel Sanders 
1872a83d680SDaniel Sanders static DecodeStatus DecodeCOP2RegisterClass(MCInst &Inst,
1882a83d680SDaniel Sanders                                             unsigned RegNo,
1892a83d680SDaniel Sanders                                             uint64_t Address,
1902a83d680SDaniel Sanders                                             const void *Decoder);
1912a83d680SDaniel Sanders 
19271928e68SAkira Hatanaka static DecodeStatus DecodeBranchTarget(MCInst &Inst,
19371928e68SAkira Hatanaka                                        unsigned Offset,
19471928e68SAkira Hatanaka                                        uint64_t Address,
19571928e68SAkira Hatanaka                                        const void *Decoder);
19671928e68SAkira Hatanaka 
197*6f09cdfdSHrvoje Varga static DecodeStatus DecodeBranchTarget1SImm16(MCInst &Inst,
198*6f09cdfdSHrvoje Varga                                               unsigned Offset,
199*6f09cdfdSHrvoje Varga                                               uint64_t Address,
200*6f09cdfdSHrvoje Varga                                               const void *Decoder);
201*6f09cdfdSHrvoje Varga 
20271928e68SAkira Hatanaka static DecodeStatus DecodeJumpTarget(MCInst &Inst,
20371928e68SAkira Hatanaka                                      unsigned Insn,
20471928e68SAkira Hatanaka                                      uint64_t Address,
20571928e68SAkira Hatanaka                                      const void *Decoder);
20671928e68SAkira Hatanaka 
2073c8869dcSZoran Jovanovic static DecodeStatus DecodeBranchTarget21(MCInst &Inst,
2083c8869dcSZoran Jovanovic                                          unsigned Offset,
2093c8869dcSZoran Jovanovic                                          uint64_t Address,
2103c8869dcSZoran Jovanovic                                          const void *Decoder);
2113c8869dcSZoran Jovanovic 
2123c8869dcSZoran Jovanovic static DecodeStatus DecodeBranchTarget26(MCInst &Inst,
2133c8869dcSZoran Jovanovic                                          unsigned Offset,
2143c8869dcSZoran Jovanovic                                          uint64_t Address,
2153c8869dcSZoran Jovanovic                                          const void *Decoder);
2163c8869dcSZoran Jovanovic 
2179761e96bSJozef Kolek // DecodeBranchTarget7MM - Decode microMIPS branch offset, which is
2189761e96bSJozef Kolek // shifted left by 1 bit.
2199761e96bSJozef Kolek static DecodeStatus DecodeBranchTarget7MM(MCInst &Inst,
2209761e96bSJozef Kolek                                           unsigned Offset,
2219761e96bSJozef Kolek                                           uint64_t Address,
2229761e96bSJozef Kolek                                           const void *Decoder);
2239761e96bSJozef Kolek 
2245cfebddeSJozef Kolek // DecodeBranchTarget10MM - Decode microMIPS branch offset, which is
2255cfebddeSJozef Kolek // shifted left by 1 bit.
2265cfebddeSJozef Kolek static DecodeStatus DecodeBranchTarget10MM(MCInst &Inst,
2275cfebddeSJozef Kolek                                            unsigned Offset,
2285cfebddeSJozef Kolek                                            uint64_t Address,
2295cfebddeSJozef Kolek                                            const void *Decoder);
2305cfebddeSJozef Kolek 
2318a80aa76SZoran Jovanovic // DecodeBranchTargetMM - Decode microMIPS branch offset, which is
2328a80aa76SZoran Jovanovic // shifted left by 1 bit.
2338a80aa76SZoran Jovanovic static DecodeStatus DecodeBranchTargetMM(MCInst &Inst,
2348a80aa76SZoran Jovanovic                                          unsigned Offset,
2358a80aa76SZoran Jovanovic                                          uint64_t Address,
2368a80aa76SZoran Jovanovic                                          const void *Decoder);
2378a80aa76SZoran Jovanovic 
238a887b361SZoran Jovanovic // DecodeBranchTarget26MM - Decode microMIPS branch offset, which is
239a887b361SZoran Jovanovic // shifted left by 1 bit.
240a887b361SZoran Jovanovic static DecodeStatus DecodeBranchTarget26MM(MCInst &Inst,
241a887b361SZoran Jovanovic                                            unsigned Offset,
242a887b361SZoran Jovanovic                                            uint64_t Address,
243a887b361SZoran Jovanovic                                            const void *Decoder);
244a887b361SZoran Jovanovic 
245507e084aSZoran Jovanovic // DecodeJumpTargetMM - Decode microMIPS jump target, which is
246507e084aSZoran Jovanovic // shifted left by 1 bit.
247507e084aSZoran Jovanovic static DecodeStatus DecodeJumpTargetMM(MCInst &Inst,
248507e084aSZoran Jovanovic                                        unsigned Insn,
249507e084aSZoran Jovanovic                                        uint64_t Address,
250507e084aSZoran Jovanovic                                        const void *Decoder);
251507e084aSZoran Jovanovic 
25271928e68SAkira Hatanaka static DecodeStatus DecodeMem(MCInst &Inst,
25371928e68SAkira Hatanaka                               unsigned Insn,
25471928e68SAkira Hatanaka                               uint64_t Address,
25571928e68SAkira Hatanaka                               const void *Decoder);
25671928e68SAkira Hatanaka 
257e4e83a7bSDaniel Sanders static DecodeStatus DecodeMemEVA(MCInst &Inst,
258e4e83a7bSDaniel Sanders                                  unsigned Insn,
259e4e83a7bSDaniel Sanders                                  uint64_t Address,
260e4e83a7bSDaniel Sanders                                  const void *Decoder);
261e4e83a7bSDaniel Sanders 
2623c88fbd3SHrvoje Varga static DecodeStatus DecodeLoadByte9(MCInst &Inst,
2633c88fbd3SHrvoje Varga                                     unsigned Insn,
2643c88fbd3SHrvoje Varga                                     uint64_t Address,
2653c88fbd3SHrvoje Varga                                     const void *Decoder);
2663c88fbd3SHrvoje Varga 
2673c88fbd3SHrvoje Varga static DecodeStatus DecodeLoadByte15(MCInst &Inst,
2683c88fbd3SHrvoje Varga                                      unsigned Insn,
2693c88fbd3SHrvoje Varga                                      uint64_t Address,
2703c88fbd3SHrvoje Varga                                      const void *Decoder);
2713c88fbd3SHrvoje Varga 
27292db6b78SDaniel Sanders static DecodeStatus DecodeCacheOp(MCInst &Inst,
27392db6b78SDaniel Sanders                               unsigned Insn,
27492db6b78SDaniel Sanders                               uint64_t Address,
27592db6b78SDaniel Sanders                               const void *Decoder);
27692db6b78SDaniel Sanders 
277e4e83a7bSDaniel Sanders static DecodeStatus DecodeCacheeOp_CacheOpR6(MCInst &Inst,
278df464ae2SVladimir Medic                                              unsigned Insn,
279df464ae2SVladimir Medic                                              uint64_t Address,
280df464ae2SVladimir Medic                                              const void *Decoder);
281df464ae2SVladimir Medic 
282ab6d1cceSJozef Kolek static DecodeStatus DecodeCacheOpMM(MCInst &Inst,
283ab6d1cceSJozef Kolek                                     unsigned Insn,
284ab6d1cceSJozef Kolek                                     uint64_t Address,
285ab6d1cceSJozef Kolek                                     const void *Decoder);
286ab6d1cceSJozef Kolek 
2879eaa30d2SZoran Jovanovic static DecodeStatus DecodeStoreEvaOpMM(MCInst &Inst,
2889eaa30d2SZoran Jovanovic                                        unsigned Insn,
2899eaa30d2SZoran Jovanovic                                        uint64_t Address,
2909eaa30d2SZoran Jovanovic                                        const void *Decoder);
2919eaa30d2SZoran Jovanovic 
292d9790793SZoran Jovanovic static DecodeStatus DecodePrefeOpMM(MCInst &Inst,
293d9790793SZoran Jovanovic                                     unsigned Insn,
294d9790793SZoran Jovanovic                                     uint64_t Address,
295d9790793SZoran Jovanovic                                     const void *Decoder);
296d9790793SZoran Jovanovic 
297b4484d62SDaniel Sanders static DecodeStatus DecodeSyncI(MCInst &Inst,
298b4484d62SDaniel Sanders                                 unsigned Insn,
299b4484d62SDaniel Sanders                                 uint64_t Address,
300b4484d62SDaniel Sanders                                 const void *Decoder);
301b4484d62SDaniel Sanders 
30218148671SHrvoje Varga static DecodeStatus DecodeSynciR6(MCInst &Inst,
30318148671SHrvoje Varga                                   unsigned Insn,
30418148671SHrvoje Varga                                   uint64_t Address,
30518148671SHrvoje Varga                                   const void *Decoder);
30618148671SHrvoje Varga 
307fe0bf9f6SMatheus Almeida static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn,
308fe0bf9f6SMatheus Almeida                                     uint64_t Address, const void *Decoder);
309fe0bf9f6SMatheus Almeida 
310315e7ecaSJozef Kolek static DecodeStatus DecodeMemMMImm4(MCInst &Inst,
311315e7ecaSJozef Kolek                                     unsigned Insn,
312315e7ecaSJozef Kolek                                     uint64_t Address,
313315e7ecaSJozef Kolek                                     const void *Decoder);
314315e7ecaSJozef Kolek 
31512c6982bSJozef Kolek static DecodeStatus DecodeMemMMSPImm5Lsl2(MCInst &Inst,
31612c6982bSJozef Kolek                                           unsigned Insn,
31712c6982bSJozef Kolek                                           uint64_t Address,
31812c6982bSJozef Kolek                                           const void *Decoder);
31912c6982bSJozef Kolek 
320e10a02ecSJozef Kolek static DecodeStatus DecodeMemMMGPImm7Lsl2(MCInst &Inst,
321e10a02ecSJozef Kolek                                           unsigned Insn,
322e10a02ecSJozef Kolek                                           uint64_t Address,
323e10a02ecSJozef Kolek                                           const void *Decoder);
324e10a02ecSJozef Kolek 
325d68d424aSJozef Kolek static DecodeStatus DecodeMemMMReglistImm4Lsl2(MCInst &Inst,
326d68d424aSJozef Kolek                                                unsigned Insn,
327d68d424aSJozef Kolek                                                uint64_t Address,
328d68d424aSJozef Kolek                                                const void *Decoder);
329d68d424aSJozef Kolek 
330a6593ff6SZoran Jovanovic static DecodeStatus DecodeMemMMImm9(MCInst &Inst,
331a6593ff6SZoran Jovanovic                                     unsigned Insn,
332a6593ff6SZoran Jovanovic                                     uint64_t Address,
333a6593ff6SZoran Jovanovic                                     const void *Decoder);
334a6593ff6SZoran Jovanovic 
335dde3d582SVladimir Medic static DecodeStatus DecodeMemMMImm12(MCInst &Inst,
336dde3d582SVladimir Medic                                      unsigned Insn,
337dde3d582SVladimir Medic                                      uint64_t Address,
338dde3d582SVladimir Medic                                      const void *Decoder);
339dde3d582SVladimir Medic 
340dde3d582SVladimir Medic static DecodeStatus DecodeMemMMImm16(MCInst &Inst,
341dde3d582SVladimir Medic                                      unsigned Insn,
342dde3d582SVladimir Medic                                      uint64_t Address,
343dde3d582SVladimir Medic                                      const void *Decoder);
344dde3d582SVladimir Medic 
34571928e68SAkira Hatanaka static DecodeStatus DecodeFMem(MCInst &Inst, unsigned Insn,
34671928e68SAkira Hatanaka                                uint64_t Address,
34771928e68SAkira Hatanaka                                const void *Decoder);
34871928e68SAkira Hatanaka 
34992db6b78SDaniel Sanders static DecodeStatus DecodeFMem2(MCInst &Inst, unsigned Insn,
35092db6b78SDaniel Sanders                                uint64_t Address,
35192db6b78SDaniel Sanders                                const void *Decoder);
35292db6b78SDaniel Sanders 
35392db6b78SDaniel Sanders static DecodeStatus DecodeFMem3(MCInst &Inst, unsigned Insn,
35492db6b78SDaniel Sanders                                uint64_t Address,
35592db6b78SDaniel Sanders                                const void *Decoder);
35692db6b78SDaniel Sanders 
357435cf8a4SVladimir Medic static DecodeStatus DecodeFMemCop2R6(MCInst &Inst, unsigned Insn,
358435cf8a4SVladimir Medic                                uint64_t Address,
359435cf8a4SVladimir Medic                                const void *Decoder);
360435cf8a4SVladimir Medic 
3616a803f61SDaniel Sanders static DecodeStatus DecodeSpecial3LlSc(MCInst &Inst,
3626a803f61SDaniel Sanders                                        unsigned Insn,
3636a803f61SDaniel Sanders                                        uint64_t Address,
3646a803f61SDaniel Sanders                                        const void *Decoder);
3656a803f61SDaniel Sanders 
366aa2b9278SJozef Kolek static DecodeStatus DecodeAddiur2Simm7(MCInst &Inst,
367aa2b9278SJozef Kolek                                        unsigned Value,
368aa2b9278SJozef Kolek                                        uint64_t Address,
369aa2b9278SJozef Kolek                                        const void *Decoder);
370aa2b9278SJozef Kolek 
37197297770SDaniel Sanders static DecodeStatus DecodeLi16Imm(MCInst &Inst,
372aa2b9278SJozef Kolek                                   unsigned Value,
373aa2b9278SJozef Kolek                                   uint64_t Address,
374aa2b9278SJozef Kolek                                   const void *Decoder);
375aa2b9278SJozef Kolek 
3766b28f09dSZoran Jovanovic static DecodeStatus DecodePOOL16BEncodedField(MCInst &Inst,
3776b28f09dSZoran Jovanovic                                               unsigned Value,
3786b28f09dSZoran Jovanovic                                               uint64_t Address,
3796b28f09dSZoran Jovanovic                                               const void *Decoder);
3806b28f09dSZoran Jovanovic 
38119b7f76aSDaniel Sanders template <unsigned Bits, int Offset, int Scale>
38219b7f76aSDaniel Sanders static DecodeStatus DecodeUImmWithOffsetAndScale(MCInst &Inst, unsigned Value,
38319b7f76aSDaniel Sanders                                                  uint64_t Address,
38419b7f76aSDaniel Sanders                                                  const void *Decoder);
38519b7f76aSDaniel Sanders 
386ea4f653dSDaniel Sanders template <unsigned Bits, int Offset>
387ea4f653dSDaniel Sanders static DecodeStatus DecodeUImmWithOffset(MCInst &Inst, unsigned Value,
38819b7f76aSDaniel Sanders                                          uint64_t Address,
38919b7f76aSDaniel Sanders                                          const void *Decoder) {
39019b7f76aSDaniel Sanders   return DecodeUImmWithOffsetAndScale<Bits, Offset, 1>(Inst, Value, Address,
39119b7f76aSDaniel Sanders                                                        Decoder);
39219b7f76aSDaniel Sanders }
393779c5937SMatheus Almeida 
39497297770SDaniel Sanders template <unsigned Bits, int Offset = 0, int ScaleBy = 1>
39597297770SDaniel Sanders static DecodeStatus DecodeSImmWithOffsetAndScale(MCInst &Inst, unsigned Value,
39697297770SDaniel Sanders                                                  uint64_t Address,
39797297770SDaniel Sanders                                                  const void *Decoder);
39878e89020SDaniel Sanders 
39971928e68SAkira Hatanaka static DecodeStatus DecodeInsSize(MCInst &Inst,
40071928e68SAkira Hatanaka                                   unsigned Insn,
40171928e68SAkira Hatanaka                                   uint64_t Address,
40271928e68SAkira Hatanaka                                   const void *Decoder);
40371928e68SAkira Hatanaka 
404b59e1a41SDaniel Sanders static DecodeStatus DecodeSimm19Lsl2(MCInst &Inst, unsigned Insn,
405b59e1a41SDaniel Sanders                                      uint64_t Address, const void *Decoder);
406b59e1a41SDaniel Sanders 
4072855142aSZoran Jovanovic static DecodeStatus DecodeSimm18Lsl3(MCInst &Inst, unsigned Insn,
4082855142aSZoran Jovanovic                                      uint64_t Address, const void *Decoder);
4092855142aSZoran Jovanovic 
410b682ddf3SVladimir Medic static DecodeStatus DecodeSimm9SP(MCInst &Inst, unsigned Insn,
411b682ddf3SVladimir Medic                                   uint64_t Address, const void *Decoder);
412b682ddf3SVladimir Medic 
413b682ddf3SVladimir Medic static DecodeStatus DecodeANDI16Imm(MCInst &Inst, unsigned Insn,
414b682ddf3SVladimir Medic                                     uint64_t Address, const void *Decoder);
415b682ddf3SVladimir Medic 
4162c6d7320SJozef Kolek static DecodeStatus DecodeSimm23Lsl2(MCInst &Inst, unsigned Insn,
4172c6d7320SJozef Kolek                                      uint64_t Address, const void *Decoder);
4182c6d7320SJozef Kolek 
419b50ccf8eSDaniel Sanders /// INSVE_[BHWD] have an implicit operand that the generated decoder doesn't
420b50ccf8eSDaniel Sanders /// handle.
421b50ccf8eSDaniel Sanders template <typename InsnType>
422b50ccf8eSDaniel Sanders static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address,
423b50ccf8eSDaniel Sanders                                    const void *Decoder);
4245c582b2fSDaniel Sanders 
4255c582b2fSDaniel Sanders template <typename InsnType>
4265c582b2fSDaniel Sanders static DecodeStatus
4275c582b2fSDaniel Sanders DecodeAddiGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
4285c582b2fSDaniel Sanders                       const void *Decoder);
4295c582b2fSDaniel Sanders 
4305c582b2fSDaniel Sanders template <typename InsnType>
4315c582b2fSDaniel Sanders static DecodeStatus
4325c582b2fSDaniel Sanders DecodeDaddiGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
4335c582b2fSDaniel Sanders                        const void *Decoder);
4345c582b2fSDaniel Sanders 
4355c582b2fSDaniel Sanders template <typename InsnType>
4365c582b2fSDaniel Sanders static DecodeStatus
4375c582b2fSDaniel Sanders DecodeBlezlGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
4385c582b2fSDaniel Sanders                        const void *Decoder);
4395c582b2fSDaniel Sanders 
4405c582b2fSDaniel Sanders template <typename InsnType>
4415c582b2fSDaniel Sanders static DecodeStatus
4425c582b2fSDaniel Sanders DecodeBgtzlGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
4435c582b2fSDaniel Sanders                        const void *Decoder);
4445c582b2fSDaniel Sanders 
4455c582b2fSDaniel Sanders template <typename InsnType>
4465c582b2fSDaniel Sanders static DecodeStatus
4475c582b2fSDaniel Sanders DecodeBgtzGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
4485c582b2fSDaniel Sanders                       const void *Decoder);
4495c582b2fSDaniel Sanders 
45028a0ca07SZoran Jovanovic template <typename InsnType>
45128a0ca07SZoran Jovanovic static DecodeStatus
45228a0ca07SZoran Jovanovic DecodeBlezGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
45328a0ca07SZoran Jovanovic                        const void *Decoder);
45428a0ca07SZoran Jovanovic 
455fdbd0a37SZoran Jovanovic template <typename InsnType>
456fdbd0a37SZoran Jovanovic static DecodeStatus
457fdbd0a37SZoran Jovanovic DecodeBgtzGroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address,
458fdbd0a37SZoran Jovanovic                           const void *Decoder);
459fdbd0a37SZoran Jovanovic 
460fdbd0a37SZoran Jovanovic template <typename InsnType>
461fdbd0a37SZoran Jovanovic static DecodeStatus
462fdbd0a37SZoran Jovanovic DecodeBlezGroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address,
463fdbd0a37SZoran Jovanovic                           const void *Decoder);
464fdbd0a37SZoran Jovanovic 
465a4c4b5fcSZoran Jovanovic static DecodeStatus DecodeRegListOperand(MCInst &Inst, unsigned Insn,
466a4c4b5fcSZoran Jovanovic                                          uint64_t Address,
467a4c4b5fcSZoran Jovanovic                                          const void *Decoder);
468a4c4b5fcSZoran Jovanovic 
469f9a02500SZoran Jovanovic static DecodeStatus DecodeRegListOperand16(MCInst &Inst, unsigned Insn,
470f9a02500SZoran Jovanovic                                            uint64_t Address,
471f9a02500SZoran Jovanovic                                            const void *Decoder);
472f9a02500SZoran Jovanovic 
47341688679SZoran Jovanovic static DecodeStatus DecodeMovePRegPair(MCInst &Inst, unsigned Insn,
47441688679SZoran Jovanovic                                        uint64_t Address,
47541688679SZoran Jovanovic                                        const void *Decoder);
47641688679SZoran Jovanovic 
47771928e68SAkira Hatanaka namespace llvm {
47871928e68SAkira Hatanaka extern Target TheMipselTarget, TheMipsTarget, TheMips64Target,
47971928e68SAkira Hatanaka               TheMips64elTarget;
48071928e68SAkira Hatanaka }
48171928e68SAkira Hatanaka 
48271928e68SAkira Hatanaka static MCDisassembler *createMipsDisassembler(
48371928e68SAkira Hatanaka                        const Target &T,
484a1bc0f56SLang Hames                        const MCSubtargetInfo &STI,
485a1bc0f56SLang Hames                        MCContext &Ctx) {
486a1bc0f56SLang Hames   return new MipsDisassembler(STI, Ctx, true);
48771928e68SAkira Hatanaka }
48871928e68SAkira Hatanaka 
48971928e68SAkira Hatanaka static MCDisassembler *createMipselDisassembler(
49071928e68SAkira Hatanaka                        const Target &T,
491a1bc0f56SLang Hames                        const MCSubtargetInfo &STI,
492a1bc0f56SLang Hames                        MCContext &Ctx) {
493a1bc0f56SLang Hames   return new MipsDisassembler(STI, Ctx, false);
49471928e68SAkira Hatanaka }
49571928e68SAkira Hatanaka 
49671928e68SAkira Hatanaka extern "C" void LLVMInitializeMipsDisassembler() {
49771928e68SAkira Hatanaka   // Register the disassembler.
49871928e68SAkira Hatanaka   TargetRegistry::RegisterMCDisassembler(TheMipsTarget,
49971928e68SAkira Hatanaka                                          createMipsDisassembler);
50071928e68SAkira Hatanaka   TargetRegistry::RegisterMCDisassembler(TheMipselTarget,
50171928e68SAkira Hatanaka                                          createMipselDisassembler);
50271928e68SAkira Hatanaka   TargetRegistry::RegisterMCDisassembler(TheMips64Target,
503a19216c8SDaniel Sanders                                          createMipsDisassembler);
50471928e68SAkira Hatanaka   TargetRegistry::RegisterMCDisassembler(TheMips64elTarget,
505a19216c8SDaniel Sanders                                          createMipselDisassembler);
50671928e68SAkira Hatanaka }
50771928e68SAkira Hatanaka 
50871928e68SAkira Hatanaka #include "MipsGenDisassemblerTables.inc"
50971928e68SAkira Hatanaka 
5105c582b2fSDaniel Sanders static unsigned getReg(const void *D, unsigned RC, unsigned RegNo) {
511a19216c8SDaniel Sanders   const MipsDisassembler *Dis = static_cast<const MipsDisassembler*>(D);
5125c582b2fSDaniel Sanders   const MCRegisterInfo *RegInfo = Dis->getContext().getRegisterInfo();
5135c582b2fSDaniel Sanders   return *(RegInfo->getRegClass(RC).begin() + RegNo);
5145c582b2fSDaniel Sanders }
5155c582b2fSDaniel Sanders 
516b50ccf8eSDaniel Sanders template <typename InsnType>
517b50ccf8eSDaniel Sanders static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address,
518b50ccf8eSDaniel Sanders                                    const void *Decoder) {
519b50ccf8eSDaniel Sanders   typedef DecodeStatus (*DecodeFN)(MCInst &, unsigned, uint64_t, const void *);
520b50ccf8eSDaniel Sanders   // The size of the n field depends on the element size
521b50ccf8eSDaniel Sanders   // The register class also depends on this.
522b50ccf8eSDaniel Sanders   InsnType tmp = fieldFromInstruction(insn, 17, 5);
523b50ccf8eSDaniel Sanders   unsigned NSize = 0;
524b50ccf8eSDaniel Sanders   DecodeFN RegDecoder = nullptr;
525b50ccf8eSDaniel Sanders   if ((tmp & 0x18) == 0x00) { // INSVE_B
526b50ccf8eSDaniel Sanders     NSize = 4;
527b50ccf8eSDaniel Sanders     RegDecoder = DecodeMSA128BRegisterClass;
528b50ccf8eSDaniel Sanders   } else if ((tmp & 0x1c) == 0x10) { // INSVE_H
529b50ccf8eSDaniel Sanders     NSize = 3;
530b50ccf8eSDaniel Sanders     RegDecoder = DecodeMSA128HRegisterClass;
531b50ccf8eSDaniel Sanders   } else if ((tmp & 0x1e) == 0x18) { // INSVE_W
532b50ccf8eSDaniel Sanders     NSize = 2;
533b50ccf8eSDaniel Sanders     RegDecoder = DecodeMSA128WRegisterClass;
534b50ccf8eSDaniel Sanders   } else if ((tmp & 0x1f) == 0x1c) { // INSVE_D
535b50ccf8eSDaniel Sanders     NSize = 1;
536b50ccf8eSDaniel Sanders     RegDecoder = DecodeMSA128DRegisterClass;
537b50ccf8eSDaniel Sanders   } else
538b50ccf8eSDaniel Sanders     llvm_unreachable("Invalid encoding");
539b50ccf8eSDaniel Sanders 
540b50ccf8eSDaniel Sanders   assert(NSize != 0 && RegDecoder != nullptr);
541b50ccf8eSDaniel Sanders 
542b50ccf8eSDaniel Sanders   // $wd
543b50ccf8eSDaniel Sanders   tmp = fieldFromInstruction(insn, 6, 5);
544b50ccf8eSDaniel Sanders   if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
545b50ccf8eSDaniel Sanders     return MCDisassembler::Fail;
546b50ccf8eSDaniel Sanders   // $wd_in
547b50ccf8eSDaniel Sanders   if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
548b50ccf8eSDaniel Sanders     return MCDisassembler::Fail;
549b50ccf8eSDaniel Sanders   // $n
550b50ccf8eSDaniel Sanders   tmp = fieldFromInstruction(insn, 16, NSize);
551e9119e41SJim Grosbach   MI.addOperand(MCOperand::createImm(tmp));
552b50ccf8eSDaniel Sanders   // $ws
553b50ccf8eSDaniel Sanders   tmp = fieldFromInstruction(insn, 11, 5);
554b50ccf8eSDaniel Sanders   if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
555b50ccf8eSDaniel Sanders     return MCDisassembler::Fail;
556b50ccf8eSDaniel Sanders   // $n2
557e9119e41SJim Grosbach   MI.addOperand(MCOperand::createImm(0));
558b50ccf8eSDaniel Sanders 
559b50ccf8eSDaniel Sanders   return MCDisassembler::Success;
560b50ccf8eSDaniel Sanders }
561b50ccf8eSDaniel Sanders 
5625c582b2fSDaniel Sanders template <typename InsnType>
5635c582b2fSDaniel Sanders static DecodeStatus DecodeAddiGroupBranch(MCInst &MI, InsnType insn,
5645c582b2fSDaniel Sanders                                           uint64_t Address,
5655c582b2fSDaniel Sanders                                           const void *Decoder) {
5665c582b2fSDaniel Sanders   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
5675c582b2fSDaniel Sanders   // (otherwise we would have matched the ADDI instruction from the earlier
5685c582b2fSDaniel Sanders   // ISA's instead).
5695c582b2fSDaniel Sanders   //
5705c582b2fSDaniel Sanders   // We have:
5715c582b2fSDaniel Sanders   //    0b001000 sssss ttttt iiiiiiiiiiiiiiii
5725c582b2fSDaniel Sanders   //      BOVC if rs >= rt
5735c582b2fSDaniel Sanders   //      BEQZALC if rs == 0 && rt != 0
5745c582b2fSDaniel Sanders   //      BEQC if rs < rt && rs != 0
5755c582b2fSDaniel Sanders 
5765c582b2fSDaniel Sanders   InsnType Rs = fieldFromInstruction(insn, 21, 5);
5775c582b2fSDaniel Sanders   InsnType Rt = fieldFromInstruction(insn, 16, 5);
578d37bab61SAlexey Samsonov   InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4;
5795c582b2fSDaniel Sanders   bool HasRs = false;
5805c582b2fSDaniel Sanders 
5815c582b2fSDaniel Sanders   if (Rs >= Rt) {
5825c582b2fSDaniel Sanders     MI.setOpcode(Mips::BOVC);
5835c582b2fSDaniel Sanders     HasRs = true;
5845c582b2fSDaniel Sanders   } else if (Rs != 0 && Rs < Rt) {
5855c582b2fSDaniel Sanders     MI.setOpcode(Mips::BEQC);
5865c582b2fSDaniel Sanders     HasRs = true;
5875c582b2fSDaniel Sanders   } else
5885c582b2fSDaniel Sanders     MI.setOpcode(Mips::BEQZALC);
5895c582b2fSDaniel Sanders 
5905c582b2fSDaniel Sanders   if (HasRs)
591e9119e41SJim Grosbach     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
5925c582b2fSDaniel Sanders                                        Rs)));
5935c582b2fSDaniel Sanders 
594e9119e41SJim Grosbach   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
5955c582b2fSDaniel Sanders                                      Rt)));
596e9119e41SJim Grosbach   MI.addOperand(MCOperand::createImm(Imm));
5975c582b2fSDaniel Sanders 
5985c582b2fSDaniel Sanders   return MCDisassembler::Success;
5995c582b2fSDaniel Sanders }
6005c582b2fSDaniel Sanders 
6015c582b2fSDaniel Sanders template <typename InsnType>
6025c582b2fSDaniel Sanders static DecodeStatus DecodeDaddiGroupBranch(MCInst &MI, InsnType insn,
6035c582b2fSDaniel Sanders                                            uint64_t Address,
6045c582b2fSDaniel Sanders                                            const void *Decoder) {
6055c582b2fSDaniel Sanders   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
6065c582b2fSDaniel Sanders   // (otherwise we would have matched the ADDI instruction from the earlier
6075c582b2fSDaniel Sanders   // ISA's instead).
6085c582b2fSDaniel Sanders   //
6095c582b2fSDaniel Sanders   // We have:
6105c582b2fSDaniel Sanders   //    0b011000 sssss ttttt iiiiiiiiiiiiiiii
6115c582b2fSDaniel Sanders   //      BNVC if rs >= rt
6125c582b2fSDaniel Sanders   //      BNEZALC if rs == 0 && rt != 0
6135c582b2fSDaniel Sanders   //      BNEC if rs < rt && rs != 0
6145c582b2fSDaniel Sanders 
6155c582b2fSDaniel Sanders   InsnType Rs = fieldFromInstruction(insn, 21, 5);
6165c582b2fSDaniel Sanders   InsnType Rt = fieldFromInstruction(insn, 16, 5);
617d37bab61SAlexey Samsonov   InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4;
6185c582b2fSDaniel Sanders   bool HasRs = false;
6195c582b2fSDaniel Sanders 
6205c582b2fSDaniel Sanders   if (Rs >= Rt) {
6215c582b2fSDaniel Sanders     MI.setOpcode(Mips::BNVC);
6225c582b2fSDaniel Sanders     HasRs = true;
6235c582b2fSDaniel Sanders   } else if (Rs != 0 && Rs < Rt) {
6245c582b2fSDaniel Sanders     MI.setOpcode(Mips::BNEC);
6255c582b2fSDaniel Sanders     HasRs = true;
6265c582b2fSDaniel Sanders   } else
6275c582b2fSDaniel Sanders     MI.setOpcode(Mips::BNEZALC);
6285c582b2fSDaniel Sanders 
6295c582b2fSDaniel Sanders   if (HasRs)
630e9119e41SJim Grosbach     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
6315c582b2fSDaniel Sanders                                        Rs)));
6325c582b2fSDaniel Sanders 
633e9119e41SJim Grosbach   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
6345c582b2fSDaniel Sanders                                      Rt)));
635e9119e41SJim Grosbach   MI.addOperand(MCOperand::createImm(Imm));
6365c582b2fSDaniel Sanders 
6375c582b2fSDaniel Sanders   return MCDisassembler::Success;
6385c582b2fSDaniel Sanders }
6395c582b2fSDaniel Sanders 
6405c582b2fSDaniel Sanders template <typename InsnType>
6415c582b2fSDaniel Sanders static DecodeStatus DecodeBlezlGroupBranch(MCInst &MI, InsnType insn,
6425c582b2fSDaniel Sanders                                            uint64_t Address,
6435c582b2fSDaniel Sanders                                            const void *Decoder) {
6445c582b2fSDaniel Sanders   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
6455c582b2fSDaniel Sanders   // (otherwise we would have matched the BLEZL instruction from the earlier
6465c582b2fSDaniel Sanders   // ISA's instead).
6475c582b2fSDaniel Sanders   //
6485c582b2fSDaniel Sanders   // We have:
6495c582b2fSDaniel Sanders   //    0b010110 sssss ttttt iiiiiiiiiiiiiiii
6505c582b2fSDaniel Sanders   //      Invalid if rs == 0
6515c582b2fSDaniel Sanders   //      BLEZC   if rs == 0  && rt != 0
6525c582b2fSDaniel Sanders   //      BGEZC   if rs == rt && rt != 0
6535c582b2fSDaniel Sanders   //      BGEC    if rs != rt && rs != 0  && rt != 0
6545c582b2fSDaniel Sanders 
6555c582b2fSDaniel Sanders   InsnType Rs = fieldFromInstruction(insn, 21, 5);
6565c582b2fSDaniel Sanders   InsnType Rt = fieldFromInstruction(insn, 16, 5);
657d37bab61SAlexey Samsonov   InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4;
65828a0ca07SZoran Jovanovic   bool HasRs = false;
6595c582b2fSDaniel Sanders 
6605c582b2fSDaniel Sanders   if (Rt == 0)
6615c582b2fSDaniel Sanders     return MCDisassembler::Fail;
6625c582b2fSDaniel Sanders   else if (Rs == 0)
6635c582b2fSDaniel Sanders     MI.setOpcode(Mips::BLEZC);
6645c582b2fSDaniel Sanders   else if (Rs == Rt)
6655c582b2fSDaniel Sanders     MI.setOpcode(Mips::BGEZC);
66628a0ca07SZoran Jovanovic   else {
66728a0ca07SZoran Jovanovic     HasRs = true;
66828a0ca07SZoran Jovanovic     MI.setOpcode(Mips::BGEC);
66928a0ca07SZoran Jovanovic   }
67028a0ca07SZoran Jovanovic 
67128a0ca07SZoran Jovanovic   if (HasRs)
672e9119e41SJim Grosbach     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
67328a0ca07SZoran Jovanovic                                        Rs)));
6745c582b2fSDaniel Sanders 
675e9119e41SJim Grosbach   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
6765c582b2fSDaniel Sanders                                      Rt)));
6775c582b2fSDaniel Sanders 
678e9119e41SJim Grosbach   MI.addOperand(MCOperand::createImm(Imm));
6795c582b2fSDaniel Sanders 
6805c582b2fSDaniel Sanders   return MCDisassembler::Success;
6815c582b2fSDaniel Sanders }
6825c582b2fSDaniel Sanders 
6835c582b2fSDaniel Sanders template <typename InsnType>
6845c582b2fSDaniel Sanders static DecodeStatus DecodeBgtzlGroupBranch(MCInst &MI, InsnType insn,
6855c582b2fSDaniel Sanders                                            uint64_t Address,
6865c582b2fSDaniel Sanders                                            const void *Decoder) {
6875c582b2fSDaniel Sanders   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
6885c582b2fSDaniel Sanders   // (otherwise we would have matched the BGTZL instruction from the earlier
6895c582b2fSDaniel Sanders   // ISA's instead).
6905c582b2fSDaniel Sanders   //
6915c582b2fSDaniel Sanders   // We have:
6925c582b2fSDaniel Sanders   //    0b010111 sssss ttttt iiiiiiiiiiiiiiii
6935c582b2fSDaniel Sanders   //      Invalid if rs == 0
6945c582b2fSDaniel Sanders   //      BGTZC   if rs == 0  && rt != 0
6955c582b2fSDaniel Sanders   //      BLTZC   if rs == rt && rt != 0
6965c582b2fSDaniel Sanders   //      BLTC    if rs != rt && rs != 0  && rt != 0
6975c582b2fSDaniel Sanders 
6985c14b069SZoran Jovanovic   bool HasRs = false;
6995c14b069SZoran Jovanovic 
7005c582b2fSDaniel Sanders   InsnType Rs = fieldFromInstruction(insn, 21, 5);
7015c582b2fSDaniel Sanders   InsnType Rt = fieldFromInstruction(insn, 16, 5);
702d37bab61SAlexey Samsonov   InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4;
7035c582b2fSDaniel Sanders 
7045c582b2fSDaniel Sanders   if (Rt == 0)
7055c582b2fSDaniel Sanders     return MCDisassembler::Fail;
7065c582b2fSDaniel Sanders   else if (Rs == 0)
7075c582b2fSDaniel Sanders     MI.setOpcode(Mips::BGTZC);
7085c582b2fSDaniel Sanders   else if (Rs == Rt)
7095c582b2fSDaniel Sanders     MI.setOpcode(Mips::BLTZC);
7105c14b069SZoran Jovanovic   else {
7115c14b069SZoran Jovanovic     MI.setOpcode(Mips::BLTC);
7125c14b069SZoran Jovanovic     HasRs = true;
7135c14b069SZoran Jovanovic   }
7145c14b069SZoran Jovanovic 
7155c14b069SZoran Jovanovic   if (HasRs)
716e9119e41SJim Grosbach     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
7175c14b069SZoran Jovanovic                                               Rs)));
7185c582b2fSDaniel Sanders 
719e9119e41SJim Grosbach   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
7205c582b2fSDaniel Sanders                                      Rt)));
7215c582b2fSDaniel Sanders 
722e9119e41SJim Grosbach   MI.addOperand(MCOperand::createImm(Imm));
7235c582b2fSDaniel Sanders 
7245c582b2fSDaniel Sanders   return MCDisassembler::Success;
7255c582b2fSDaniel Sanders }
7265c582b2fSDaniel Sanders 
7275c582b2fSDaniel Sanders template <typename InsnType>
7285c582b2fSDaniel Sanders static DecodeStatus DecodeBgtzGroupBranch(MCInst &MI, InsnType insn,
7295c582b2fSDaniel Sanders                                           uint64_t Address,
7305c582b2fSDaniel Sanders                                           const void *Decoder) {
7315c582b2fSDaniel Sanders   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
7325c582b2fSDaniel Sanders   // (otherwise we would have matched the BGTZ instruction from the earlier
7335c582b2fSDaniel Sanders   // ISA's instead).
7345c582b2fSDaniel Sanders   //
7355c582b2fSDaniel Sanders   // We have:
7365c582b2fSDaniel Sanders   //    0b000111 sssss ttttt iiiiiiiiiiiiiiii
7375c582b2fSDaniel Sanders   //      BGTZ    if rt == 0
7385c582b2fSDaniel Sanders   //      BGTZALC if rs == 0 && rt != 0
7395c582b2fSDaniel Sanders   //      BLTZALC if rs != 0 && rs == rt
7405c582b2fSDaniel Sanders   //      BLTUC   if rs != 0 && rs != rt
7415c582b2fSDaniel Sanders 
7425c582b2fSDaniel Sanders   InsnType Rs = fieldFromInstruction(insn, 21, 5);
7435c582b2fSDaniel Sanders   InsnType Rt = fieldFromInstruction(insn, 16, 5);
744d37bab61SAlexey Samsonov   InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4;
7455c582b2fSDaniel Sanders   bool HasRs = false;
7465c582b2fSDaniel Sanders   bool HasRt = false;
7475c582b2fSDaniel Sanders 
7485c582b2fSDaniel Sanders   if (Rt == 0) {
7495c582b2fSDaniel Sanders     MI.setOpcode(Mips::BGTZ);
7505c582b2fSDaniel Sanders     HasRs = true;
7515c582b2fSDaniel Sanders   } else if (Rs == 0) {
7525c582b2fSDaniel Sanders     MI.setOpcode(Mips::BGTZALC);
7535c582b2fSDaniel Sanders     HasRt = true;
7545c582b2fSDaniel Sanders   } else if (Rs == Rt) {
7555c582b2fSDaniel Sanders     MI.setOpcode(Mips::BLTZALC);
7565c582b2fSDaniel Sanders     HasRs = true;
7575c14b069SZoran Jovanovic   } else {
7585c14b069SZoran Jovanovic     MI.setOpcode(Mips::BLTUC);
7595c14b069SZoran Jovanovic     HasRs = true;
7605c14b069SZoran Jovanovic     HasRt = true;
7615c14b069SZoran Jovanovic   }
7625c582b2fSDaniel Sanders 
7635c582b2fSDaniel Sanders   if (HasRs)
764e9119e41SJim Grosbach     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
7655c582b2fSDaniel Sanders                                        Rs)));
7665c582b2fSDaniel Sanders 
7675c582b2fSDaniel Sanders   if (HasRt)
768e9119e41SJim Grosbach     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
7695c582b2fSDaniel Sanders                                        Rt)));
7705c582b2fSDaniel Sanders 
771e9119e41SJim Grosbach   MI.addOperand(MCOperand::createImm(Imm));
7725c582b2fSDaniel Sanders 
7735c582b2fSDaniel Sanders   return MCDisassembler::Success;
7745c582b2fSDaniel Sanders }
7755c582b2fSDaniel Sanders 
77628a0ca07SZoran Jovanovic template <typename InsnType>
77728a0ca07SZoran Jovanovic static DecodeStatus DecodeBlezGroupBranch(MCInst &MI, InsnType insn,
77828a0ca07SZoran Jovanovic                                            uint64_t Address,
77928a0ca07SZoran Jovanovic                                            const void *Decoder) {
78028a0ca07SZoran Jovanovic   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
78128a0ca07SZoran Jovanovic   // (otherwise we would have matched the BLEZL instruction from the earlier
78228a0ca07SZoran Jovanovic   // ISA's instead).
78328a0ca07SZoran Jovanovic   //
78428a0ca07SZoran Jovanovic   // We have:
78528a0ca07SZoran Jovanovic   //    0b000110 sssss ttttt iiiiiiiiiiiiiiii
78628a0ca07SZoran Jovanovic   //      Invalid   if rs == 0
78728a0ca07SZoran Jovanovic   //      BLEZALC   if rs == 0  && rt != 0
78828a0ca07SZoran Jovanovic   //      BGEZALC   if rs == rt && rt != 0
78928a0ca07SZoran Jovanovic   //      BGEUC     if rs != rt && rs != 0  && rt != 0
79028a0ca07SZoran Jovanovic 
79128a0ca07SZoran Jovanovic   InsnType Rs = fieldFromInstruction(insn, 21, 5);
79228a0ca07SZoran Jovanovic   InsnType Rt = fieldFromInstruction(insn, 16, 5);
793d37bab61SAlexey Samsonov   InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4;
79428a0ca07SZoran Jovanovic   bool HasRs = false;
79528a0ca07SZoran Jovanovic 
79628a0ca07SZoran Jovanovic   if (Rt == 0)
79728a0ca07SZoran Jovanovic     return MCDisassembler::Fail;
79828a0ca07SZoran Jovanovic   else if (Rs == 0)
79928a0ca07SZoran Jovanovic     MI.setOpcode(Mips::BLEZALC);
80028a0ca07SZoran Jovanovic   else if (Rs == Rt)
80128a0ca07SZoran Jovanovic     MI.setOpcode(Mips::BGEZALC);
80228a0ca07SZoran Jovanovic   else {
80328a0ca07SZoran Jovanovic     HasRs = true;
80428a0ca07SZoran Jovanovic     MI.setOpcode(Mips::BGEUC);
80528a0ca07SZoran Jovanovic   }
80628a0ca07SZoran Jovanovic 
80728a0ca07SZoran Jovanovic   if (HasRs)
808e9119e41SJim Grosbach     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
80928a0ca07SZoran Jovanovic                                        Rs)));
810e9119e41SJim Grosbach   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
81128a0ca07SZoran Jovanovic                                      Rt)));
81228a0ca07SZoran Jovanovic 
813e9119e41SJim Grosbach   MI.addOperand(MCOperand::createImm(Imm));
81428a0ca07SZoran Jovanovic 
81528a0ca07SZoran Jovanovic   return MCDisassembler::Success;
81628a0ca07SZoran Jovanovic }
81728a0ca07SZoran Jovanovic 
818ea22c4cfSJozef Kolek /// Read two bytes from the ArrayRef and return 16 bit halfword sorted
819ea22c4cfSJozef Kolek /// according to the given endianess.
820ea22c4cfSJozef Kolek static DecodeStatus readInstruction16(ArrayRef<uint8_t> Bytes, uint64_t Address,
821ea22c4cfSJozef Kolek                                       uint64_t &Size, uint32_t &Insn,
822ea22c4cfSJozef Kolek                                       bool IsBigEndian) {
823ea22c4cfSJozef Kolek   // We want to read exactly 2 Bytes of data.
824ea22c4cfSJozef Kolek   if (Bytes.size() < 2) {
825ea22c4cfSJozef Kolek     Size = 0;
826ea22c4cfSJozef Kolek     return MCDisassembler::Fail;
827ea22c4cfSJozef Kolek   }
828ea22c4cfSJozef Kolek 
829ea22c4cfSJozef Kolek   if (IsBigEndian) {
830ea22c4cfSJozef Kolek     Insn = (Bytes[0] << 8) | Bytes[1];
831ea22c4cfSJozef Kolek   } else {
832ea22c4cfSJozef Kolek     Insn = (Bytes[1] << 8) | Bytes[0];
833ea22c4cfSJozef Kolek   }
834ea22c4cfSJozef Kolek 
835ea22c4cfSJozef Kolek   return MCDisassembler::Success;
836ea22c4cfSJozef Kolek }
837ea22c4cfSJozef Kolek 
8387fc5b874SRafael Espindola /// Read four bytes from the ArrayRef and return 32 bit word sorted
8394aa6bea7SRafael Espindola /// according to the given endianess
8407fc5b874SRafael Espindola static DecodeStatus readInstruction32(ArrayRef<uint8_t> Bytes, uint64_t Address,
8417fc5b874SRafael Espindola                                       uint64_t &Size, uint32_t &Insn,
8427fc5b874SRafael Espindola                                       bool IsBigEndian, bool IsMicroMips) {
84371928e68SAkira Hatanaka   // We want to read exactly 4 Bytes of data.
8447fc5b874SRafael Espindola   if (Bytes.size() < 4) {
8454aa6bea7SRafael Espindola     Size = 0;
84671928e68SAkira Hatanaka     return MCDisassembler::Fail;
84771928e68SAkira Hatanaka   }
84871928e68SAkira Hatanaka 
849ea22c4cfSJozef Kolek   // High 16 bits of a 32-bit microMIPS instruction (where the opcode is)
850ea22c4cfSJozef Kolek   // always precede the low 16 bits in the instruction stream (that is, they
851ea22c4cfSJozef Kolek   // are placed at lower addresses in the instruction stream).
852ea22c4cfSJozef Kolek   //
853ea22c4cfSJozef Kolek   // microMIPS byte ordering:
854ea22c4cfSJozef Kolek   //   Big-endian:    0 | 1 | 2 | 3
855ea22c4cfSJozef Kolek   //   Little-endian: 1 | 0 | 3 | 2
856ea22c4cfSJozef Kolek 
8574aa6bea7SRafael Espindola   if (IsBigEndian) {
85871928e68SAkira Hatanaka     // Encoded as a big-endian 32-bit word in the stream.
8594aa6bea7SRafael Espindola     Insn =
8604aa6bea7SRafael Espindola         (Bytes[3] << 0) | (Bytes[2] << 8) | (Bytes[1] << 16) | (Bytes[0] << 24);
8614aa6bea7SRafael Espindola   } else {
862dde3d582SVladimir Medic     if (IsMicroMips) {
8634aa6bea7SRafael Espindola       Insn = (Bytes[2] << 0) | (Bytes[3] << 8) | (Bytes[0] << 16) |
864dde3d582SVladimir Medic              (Bytes[1] << 24);
865dde3d582SVladimir Medic     } else {
8664aa6bea7SRafael Espindola       Insn = (Bytes[0] << 0) | (Bytes[1] << 8) | (Bytes[2] << 16) |
86771928e68SAkira Hatanaka              (Bytes[3] << 24);
86871928e68SAkira Hatanaka     }
869dde3d582SVladimir Medic   }
87071928e68SAkira Hatanaka 
87171928e68SAkira Hatanaka   return MCDisassembler::Success;
87271928e68SAkira Hatanaka }
87371928e68SAkira Hatanaka 
8744aa6bea7SRafael Espindola DecodeStatus MipsDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,
8757fc5b874SRafael Espindola                                               ArrayRef<uint8_t> Bytes,
87671928e68SAkira Hatanaka                                               uint64_t Address,
8774aa6bea7SRafael Espindola                                               raw_ostream &VStream,
8784aa6bea7SRafael Espindola                                               raw_ostream &CStream) const {
87971928e68SAkira Hatanaka   uint32_t Insn;
880ea22c4cfSJozef Kolek   DecodeStatus Result;
88171928e68SAkira Hatanaka 
882ea22c4cfSJozef Kolek   if (IsMicroMips) {
883ea22c4cfSJozef Kolek     Result = readInstruction16(Bytes, Address, Size, Insn, IsBigEndian);
884ebee6129SReid Kleckner     if (Result == MCDisassembler::Fail)
885ebee6129SReid Kleckner       return MCDisassembler::Fail;
886ea22c4cfSJozef Kolek 
887ada70918SZoran Jovanovic     if (hasMips32r6()) {
888ada70918SZoran Jovanovic       DEBUG(dbgs() << "Trying MicroMipsR616 table (16-bit instructions):\n");
889ada70918SZoran Jovanovic       // Calling the auto-generated decoder function for microMIPS32R6
890ada70918SZoran Jovanovic       // (and microMIPS64R6) 16-bit instructions.
891ada70918SZoran Jovanovic       Result = decodeInstruction(DecoderTableMicroMipsR616, Instr, Insn,
892ada70918SZoran Jovanovic                                  Address, this, STI);
893ada70918SZoran Jovanovic       if (Result != MCDisassembler::Fail) {
894ada70918SZoran Jovanovic         Size = 2;
895ada70918SZoran Jovanovic         return Result;
896ada70918SZoran Jovanovic       }
897ada70918SZoran Jovanovic     }
898ada70918SZoran Jovanovic 
899ea22c4cfSJozef Kolek     DEBUG(dbgs() << "Trying MicroMips16 table (16-bit instructions):\n");
900ada70918SZoran Jovanovic     // Calling the auto-generated decoder function for microMIPS 16-bit
901ada70918SZoran Jovanovic     // instructions.
902ea22c4cfSJozef Kolek     Result = decodeInstruction(DecoderTableMicroMips16, Instr, Insn, Address,
903ea22c4cfSJozef Kolek                                this, STI);
904ea22c4cfSJozef Kolek     if (Result != MCDisassembler::Fail) {
905ea22c4cfSJozef Kolek       Size = 2;
906ea22c4cfSJozef Kolek       return Result;
907ea22c4cfSJozef Kolek     }
908ea22c4cfSJozef Kolek 
909ea22c4cfSJozef Kolek     Result = readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, true);
91071928e68SAkira Hatanaka     if (Result == MCDisassembler::Fail)
91171928e68SAkira Hatanaka       return MCDisassembler::Fail;
91271928e68SAkira Hatanaka 
913676d6012SJozef Kolek     if (hasMips32r6()) {
914676d6012SJozef Kolek       DEBUG(dbgs() << "Trying MicroMips32r632 table (32-bit instructions):\n");
915676d6012SJozef Kolek       // Calling the auto-generated decoder function.
916366783e1SZoran Jovanovic       Result = decodeInstruction(DecoderTableMicroMipsR632, Instr, Insn, Address,
917676d6012SJozef Kolek                                  this, STI);
918ada70918SZoran Jovanovic       if (Result != MCDisassembler::Fail) {
919ada70918SZoran Jovanovic         Size = 4;
920ada70918SZoran Jovanovic         return Result;
921ada70918SZoran Jovanovic       }
922ada70918SZoran Jovanovic     }
923ada70918SZoran Jovanovic 
924ea22c4cfSJozef Kolek     DEBUG(dbgs() << "Trying MicroMips32 table (32-bit instructions):\n");
925dde3d582SVladimir Medic     // Calling the auto-generated decoder function.
9264aa6bea7SRafael Espindola     Result = decodeInstruction(DecoderTableMicroMips32, Instr, Insn, Address,
927dde3d582SVladimir Medic                                this, STI);
928dde3d582SVladimir Medic     if (Result != MCDisassembler::Fail) {
929dde3d582SVladimir Medic       Size = 4;
930dde3d582SVladimir Medic       return Result;
931dde3d582SVladimir Medic     }
9322cb74ac3SHrvoje Varga 
9336221be8eSZlatko Buljan     if (hasMips32r6() && isFP64()) {
9346221be8eSZlatko Buljan       DEBUG(dbgs() << "Trying MicroMips32r6FP64 table (32-bit opcodes):\n");
9356221be8eSZlatko Buljan       Result = decodeInstruction(DecoderTableMicroMips32r6FP6432, Instr, Insn,
9362cb74ac3SHrvoje Varga                                  Address, this, STI);
9372cb74ac3SHrvoje Varga       if (Result != MCDisassembler::Fail) {
9382cb74ac3SHrvoje Varga         Size = 4;
9392cb74ac3SHrvoje Varga         return Result;
9402cb74ac3SHrvoje Varga       }
9412cb74ac3SHrvoje Varga     }
9422cb74ac3SHrvoje Varga 
943ebee6129SReid Kleckner     // This is an invalid instruction. Let the disassembler move forward by the
944ebee6129SReid Kleckner     // minimum instruction size.
945ebee6129SReid Kleckner     Size = 2;
946dde3d582SVladimir Medic     return MCDisassembler::Fail;
947dde3d582SVladimir Medic   }
948dde3d582SVladimir Medic 
949ea22c4cfSJozef Kolek   Result = readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, false);
950ebee6129SReid Kleckner   if (Result == MCDisassembler::Fail) {
951ebee6129SReid Kleckner     Size = 4;
952ea22c4cfSJozef Kolek     return MCDisassembler::Fail;
953ebee6129SReid Kleckner   }
954ea22c4cfSJozef Kolek 
955c171f65aSDaniel Sanders   if (hasCOP3()) {
956c171f65aSDaniel Sanders     DEBUG(dbgs() << "Trying COP3_ table (32-bit opcodes):\n");
957c171f65aSDaniel Sanders     Result =
9584aa6bea7SRafael Espindola         decodeInstruction(DecoderTableCOP3_32, Instr, Insn, Address, this, STI);
959c171f65aSDaniel Sanders     if (Result != MCDisassembler::Fail) {
960c171f65aSDaniel Sanders       Size = 4;
961c171f65aSDaniel Sanders       return Result;
962c171f65aSDaniel Sanders     }
963c171f65aSDaniel Sanders   }
964c171f65aSDaniel Sanders 
965c171f65aSDaniel Sanders   if (hasMips32r6() && isGP64()) {
96636901dd1SVasileios Kalintiris     DEBUG(dbgs() << "Trying Mips32r6_64r6 (GPR64) table (32-bit opcodes):\n");
96736901dd1SVasileios Kalintiris     Result = decodeInstruction(DecoderTableMips32r6_64r6_GP6432, Instr, Insn,
96836901dd1SVasileios Kalintiris                                Address, this, STI);
9690fa60416SDaniel Sanders     if (Result != MCDisassembler::Fail) {
9700fa60416SDaniel Sanders       Size = 4;
9710fa60416SDaniel Sanders       return Result;
9720fa60416SDaniel Sanders     }
9730fa60416SDaniel Sanders   }
9740fa60416SDaniel Sanders 
975c171f65aSDaniel Sanders   if (hasMips32r6()) {
9760fa60416SDaniel Sanders     DEBUG(dbgs() << "Trying Mips32r6_64r6 table (32-bit opcodes):\n");
9774aa6bea7SRafael Espindola     Result = decodeInstruction(DecoderTableMips32r6_64r632, Instr, Insn,
9785c582b2fSDaniel Sanders                                Address, this, STI);
9795c582b2fSDaniel Sanders     if (Result != MCDisassembler::Fail) {
9805c582b2fSDaniel Sanders       Size = 4;
9815c582b2fSDaniel Sanders       return Result;
9825c582b2fSDaniel Sanders     }
9835c582b2fSDaniel Sanders   }
9845c582b2fSDaniel Sanders 
9853adf9b8dSKai Nacke   if (hasCnMips()) {
9863adf9b8dSKai Nacke     DEBUG(dbgs() << "Trying CnMips table (32-bit opcodes):\n");
9873adf9b8dSKai Nacke     Result = decodeInstruction(DecoderTableCnMips32, Instr, Insn,
9883adf9b8dSKai Nacke                                Address, this, STI);
9893adf9b8dSKai Nacke     if (Result != MCDisassembler::Fail) {
9903adf9b8dSKai Nacke       Size = 4;
9913adf9b8dSKai Nacke       return Result;
9923adf9b8dSKai Nacke     }
9933adf9b8dSKai Nacke   }
9943adf9b8dSKai Nacke 
995a19216c8SDaniel Sanders   if (isGP64()) {
996a19216c8SDaniel Sanders     DEBUG(dbgs() << "Trying Mips64 (GPR64) table (32-bit opcodes):\n");
997a19216c8SDaniel Sanders     Result = decodeInstruction(DecoderTableMips6432, Instr, Insn,
998a19216c8SDaniel Sanders                                Address, this, STI);
999a19216c8SDaniel Sanders     if (Result != MCDisassembler::Fail) {
1000a19216c8SDaniel Sanders       Size = 4;
1001a19216c8SDaniel Sanders       return Result;
1002a19216c8SDaniel Sanders     }
1003a19216c8SDaniel Sanders   }
1004a19216c8SDaniel Sanders 
10050fa60416SDaniel Sanders   DEBUG(dbgs() << "Trying Mips table (32-bit opcodes):\n");
100671928e68SAkira Hatanaka   // Calling the auto-generated decoder function.
10074aa6bea7SRafael Espindola   Result =
10084aa6bea7SRafael Espindola       decodeInstruction(DecoderTableMips32, Instr, Insn, Address, this, STI);
100971928e68SAkira Hatanaka   if (Result != MCDisassembler::Fail) {
101071928e68SAkira Hatanaka     Size = 4;
101171928e68SAkira Hatanaka     return Result;
101271928e68SAkira Hatanaka   }
101371928e68SAkira Hatanaka 
1014ebee6129SReid Kleckner   Size = 4;
101571928e68SAkira Hatanaka   return MCDisassembler::Fail;
101671928e68SAkira Hatanaka }
101771928e68SAkira Hatanaka 
1018ec8a5490SReed Kotler static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst,
1019ec8a5490SReed Kotler                                                  unsigned RegNo,
1020ec8a5490SReed Kotler                                                  uint64_t Address,
1021ec8a5490SReed Kotler                                                  const void *Decoder) {
1022ec8a5490SReed Kotler 
1023ec8a5490SReed Kotler   return MCDisassembler::Fail;
1024ec8a5490SReed Kotler 
1025ec8a5490SReed Kotler }
1026ec8a5490SReed Kotler 
102713e6ccf3SAkira Hatanaka static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst,
102871928e68SAkira Hatanaka                                              unsigned RegNo,
102971928e68SAkira Hatanaka                                              uint64_t Address,
103071928e68SAkira Hatanaka                                              const void *Decoder) {
103171928e68SAkira Hatanaka 
103271928e68SAkira Hatanaka   if (RegNo > 31)
103371928e68SAkira Hatanaka     return MCDisassembler::Fail;
103471928e68SAkira Hatanaka 
103513e6ccf3SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::GPR64RegClassID, RegNo);
1036e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
103771928e68SAkira Hatanaka   return MCDisassembler::Success;
103871928e68SAkira Hatanaka }
103971928e68SAkira Hatanaka 
1040b0852e54SZoran Jovanovic static DecodeStatus DecodeGPRMM16RegisterClass(MCInst &Inst,
1041b0852e54SZoran Jovanovic                                                unsigned RegNo,
1042b0852e54SZoran Jovanovic                                                uint64_t Address,
1043b0852e54SZoran Jovanovic                                                const void *Decoder) {
1044ea22c4cfSJozef Kolek   if (RegNo > 7)
1045b0852e54SZoran Jovanovic     return MCDisassembler::Fail;
1046ea22c4cfSJozef Kolek   unsigned Reg = getReg(Decoder, Mips::GPRMM16RegClassID, RegNo);
1047e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1048ea22c4cfSJozef Kolek   return MCDisassembler::Success;
1049b0852e54SZoran Jovanovic }
1050b0852e54SZoran Jovanovic 
10511904fa21SJozef Kolek static DecodeStatus DecodeGPRMM16ZeroRegisterClass(MCInst &Inst,
10521904fa21SJozef Kolek                                                    unsigned RegNo,
10531904fa21SJozef Kolek                                                    uint64_t Address,
10541904fa21SJozef Kolek                                                    const void *Decoder) {
1055315e7ecaSJozef Kolek   if (RegNo > 7)
10561904fa21SJozef Kolek     return MCDisassembler::Fail;
1057315e7ecaSJozef Kolek   unsigned Reg = getReg(Decoder, Mips::GPRMM16ZeroRegClassID, RegNo);
1058e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1059315e7ecaSJozef Kolek   return MCDisassembler::Success;
10601904fa21SJozef Kolek }
10611904fa21SJozef Kolek 
106241688679SZoran Jovanovic static DecodeStatus DecodeGPRMM16MovePRegisterClass(MCInst &Inst,
106341688679SZoran Jovanovic                                                     unsigned RegNo,
106441688679SZoran Jovanovic                                                     uint64_t Address,
106541688679SZoran Jovanovic                                                     const void *Decoder) {
106641688679SZoran Jovanovic   if (RegNo > 7)
106741688679SZoran Jovanovic     return MCDisassembler::Fail;
106841688679SZoran Jovanovic   unsigned Reg = getReg(Decoder, Mips::GPRMM16MovePRegClassID, RegNo);
1069e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
107041688679SZoran Jovanovic   return MCDisassembler::Success;
107141688679SZoran Jovanovic }
107241688679SZoran Jovanovic 
107313e6ccf3SAkira Hatanaka static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst,
107471928e68SAkira Hatanaka                                              unsigned RegNo,
107571928e68SAkira Hatanaka                                              uint64_t Address,
107671928e68SAkira Hatanaka                                              const void *Decoder) {
107771928e68SAkira Hatanaka   if (RegNo > 31)
107871928e68SAkira Hatanaka     return MCDisassembler::Fail;
107913e6ccf3SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::GPR32RegClassID, RegNo);
1080e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
108171928e68SAkira Hatanaka   return MCDisassembler::Success;
108271928e68SAkira Hatanaka }
108371928e68SAkira Hatanaka 
10849bfa2e2eSAkira Hatanaka static DecodeStatus DecodePtrRegisterClass(MCInst &Inst,
10859bfa2e2eSAkira Hatanaka                                            unsigned RegNo,
10869bfa2e2eSAkira Hatanaka                                            uint64_t Address,
10879bfa2e2eSAkira Hatanaka                                            const void *Decoder) {
1088a19216c8SDaniel Sanders   if (static_cast<const MipsDisassembler *>(Decoder)->isGP64())
10899bfa2e2eSAkira Hatanaka     return DecodeGPR64RegisterClass(Inst, RegNo, Address, Decoder);
10909bfa2e2eSAkira Hatanaka 
10919bfa2e2eSAkira Hatanaka   return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
10929bfa2e2eSAkira Hatanaka }
10939bfa2e2eSAkira Hatanaka 
1094654655f1SAkira Hatanaka static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst,
1095ecabd1a5SAkira Hatanaka                                             unsigned RegNo,
1096ecabd1a5SAkira Hatanaka                                             uint64_t Address,
1097ecabd1a5SAkira Hatanaka                                             const void *Decoder) {
109813e6ccf3SAkira Hatanaka   return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
1099ecabd1a5SAkira Hatanaka }
1100ecabd1a5SAkira Hatanaka 
110171928e68SAkira Hatanaka static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
110271928e68SAkira Hatanaka                                              unsigned RegNo,
110371928e68SAkira Hatanaka                                              uint64_t Address,
110471928e68SAkira Hatanaka                                              const void *Decoder) {
110571928e68SAkira Hatanaka   if (RegNo > 31)
110671928e68SAkira Hatanaka     return MCDisassembler::Fail;
110771928e68SAkira Hatanaka 
11089bf2b567SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::FGR64RegClassID, RegNo);
1109e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
111071928e68SAkira Hatanaka   return MCDisassembler::Success;
111171928e68SAkira Hatanaka }
111271928e68SAkira Hatanaka 
111371928e68SAkira Hatanaka static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
111471928e68SAkira Hatanaka                                              unsigned RegNo,
111571928e68SAkira Hatanaka                                              uint64_t Address,
111671928e68SAkira Hatanaka                                              const void *Decoder) {
111771928e68SAkira Hatanaka   if (RegNo > 31)
111871928e68SAkira Hatanaka     return MCDisassembler::Fail;
111971928e68SAkira Hatanaka 
11209bf2b567SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::FGR32RegClassID, RegNo);
1121e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
112271928e68SAkira Hatanaka   return MCDisassembler::Success;
112371928e68SAkira Hatanaka }
112471928e68SAkira Hatanaka 
112571928e68SAkira Hatanaka static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
112671928e68SAkira Hatanaka                                            unsigned RegNo,
112771928e68SAkira Hatanaka                                            uint64_t Address,
112871928e68SAkira Hatanaka                                            const void *Decoder) {
1129253777fdSChad Rosier   if (RegNo > 31)
1130253777fdSChad Rosier     return MCDisassembler::Fail;
1131253777fdSChad Rosier   unsigned Reg = getReg(Decoder, Mips::CCRRegClassID, RegNo);
1132e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
113371928e68SAkira Hatanaka   return MCDisassembler::Success;
113471928e68SAkira Hatanaka }
113571928e68SAkira Hatanaka 
11361fb1b8b8SAkira Hatanaka static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst,
11371fb1b8b8SAkira Hatanaka                                            unsigned RegNo,
11381fb1b8b8SAkira Hatanaka                                            uint64_t Address,
11391fb1b8b8SAkira Hatanaka                                            const void *Decoder) {
11401fb1b8b8SAkira Hatanaka   if (RegNo > 7)
11411fb1b8b8SAkira Hatanaka     return MCDisassembler::Fail;
11421fb1b8b8SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::FCCRegClassID, RegNo);
1143e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
11441fb1b8b8SAkira Hatanaka   return MCDisassembler::Success;
11451fb1b8b8SAkira Hatanaka }
11461fb1b8b8SAkira Hatanaka 
114736901dd1SVasileios Kalintiris static DecodeStatus DecodeFGRCCRegisterClass(MCInst &Inst, unsigned RegNo,
11480fa60416SDaniel Sanders                                              uint64_t Address,
11490fa60416SDaniel Sanders                                              const void *Decoder) {
11500fa60416SDaniel Sanders   if (RegNo > 31)
11510fa60416SDaniel Sanders     return MCDisassembler::Fail;
11520fa60416SDaniel Sanders 
115336901dd1SVasileios Kalintiris   unsigned Reg = getReg(Decoder, Mips::FGRCCRegClassID, RegNo);
1154e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
11550fa60416SDaniel Sanders   return MCDisassembler::Success;
11560fa60416SDaniel Sanders }
11570fa60416SDaniel Sanders 
115871928e68SAkira Hatanaka static DecodeStatus DecodeMem(MCInst &Inst,
115971928e68SAkira Hatanaka                               unsigned Insn,
116071928e68SAkira Hatanaka                               uint64_t Address,
116171928e68SAkira Hatanaka                               const void *Decoder) {
116271928e68SAkira Hatanaka   int Offset = SignExtend32<16>(Insn & 0xffff);
1163ecaef49fSJim Grosbach   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1164ecaef49fSJim Grosbach   unsigned Base = fieldFromInstruction(Insn, 21, 5);
11659bf2b567SAkira Hatanaka 
116613e6ccf3SAkira Hatanaka   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
116713e6ccf3SAkira Hatanaka   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
116871928e68SAkira Hatanaka 
1169d7ecf49eSVladimir Medic   if (Inst.getOpcode() == Mips::SC ||
1170e4e83a7bSDaniel Sanders       Inst.getOpcode() == Mips::SCD)
1171e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Reg));
1172e4e83a7bSDaniel Sanders 
1173e4e83a7bSDaniel Sanders   Inst.addOperand(MCOperand::createReg(Reg));
1174e4e83a7bSDaniel Sanders   Inst.addOperand(MCOperand::createReg(Base));
1175e4e83a7bSDaniel Sanders   Inst.addOperand(MCOperand::createImm(Offset));
1176e4e83a7bSDaniel Sanders 
1177e4e83a7bSDaniel Sanders   return MCDisassembler::Success;
117871928e68SAkira Hatanaka }
117971928e68SAkira Hatanaka 
1180e4e83a7bSDaniel Sanders static DecodeStatus DecodeMemEVA(MCInst &Inst,
1181e4e83a7bSDaniel Sanders                                  unsigned Insn,
1182e4e83a7bSDaniel Sanders                                  uint64_t Address,
1183e4e83a7bSDaniel Sanders                                  const void *Decoder) {
1184e4e83a7bSDaniel Sanders   int Offset = SignExtend32<9>(Insn >> 7);
1185e4e83a7bSDaniel Sanders   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1186e4e83a7bSDaniel Sanders   unsigned Base = fieldFromInstruction(Insn, 21, 5);
1187e4e83a7bSDaniel Sanders 
1188e4e83a7bSDaniel Sanders   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1189e4e83a7bSDaniel Sanders   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1190e4e83a7bSDaniel Sanders 
1191e4e83a7bSDaniel Sanders    if (Inst.getOpcode() == Mips::SCE)
1192e4e83a7bSDaniel Sanders      Inst.addOperand(MCOperand::createReg(Reg));
1193e4e83a7bSDaniel Sanders 
1194e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1195e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1196e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
119771928e68SAkira Hatanaka 
119871928e68SAkira Hatanaka   return MCDisassembler::Success;
119971928e68SAkira Hatanaka }
120071928e68SAkira Hatanaka 
12013c88fbd3SHrvoje Varga static DecodeStatus DecodeLoadByte9(MCInst &Inst,
12023c88fbd3SHrvoje Varga                                     unsigned Insn,
12033c88fbd3SHrvoje Varga                                     uint64_t Address,
12043c88fbd3SHrvoje Varga                                     const void *Decoder) {
12053c88fbd3SHrvoje Varga   int Offset = SignExtend32<9>(Insn & 0x1ff);
12063c88fbd3SHrvoje Varga   unsigned Base = fieldFromInstruction(Insn, 16, 5);
12073c88fbd3SHrvoje Varga   unsigned Reg = fieldFromInstruction(Insn, 21, 5);
12083c88fbd3SHrvoje Varga 
12093c88fbd3SHrvoje Varga   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
12103c88fbd3SHrvoje Varga   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
12113c88fbd3SHrvoje Varga 
12123c88fbd3SHrvoje Varga   Inst.addOperand(MCOperand::createReg(Reg));
12133c88fbd3SHrvoje Varga   Inst.addOperand(MCOperand::createReg(Base));
12143c88fbd3SHrvoje Varga   Inst.addOperand(MCOperand::createImm(Offset));
12153c88fbd3SHrvoje Varga 
12163c88fbd3SHrvoje Varga   return MCDisassembler::Success;
12173c88fbd3SHrvoje Varga }
12183c88fbd3SHrvoje Varga 
12193c88fbd3SHrvoje Varga static DecodeStatus DecodeLoadByte15(MCInst &Inst,
12203c88fbd3SHrvoje Varga                                      unsigned Insn,
12213c88fbd3SHrvoje Varga                                      uint64_t Address,
12223c88fbd3SHrvoje Varga                                      const void *Decoder) {
12233c88fbd3SHrvoje Varga   int Offset = SignExtend32<16>(Insn & 0xffff);
12243c88fbd3SHrvoje Varga   unsigned Base = fieldFromInstruction(Insn, 16, 5);
12253c88fbd3SHrvoje Varga   unsigned Reg = fieldFromInstruction(Insn, 21, 5);
12263c88fbd3SHrvoje Varga 
12273c88fbd3SHrvoje Varga   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
12283c88fbd3SHrvoje Varga   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
12293c88fbd3SHrvoje Varga 
12303c88fbd3SHrvoje Varga   Inst.addOperand(MCOperand::createReg(Reg));
12313c88fbd3SHrvoje Varga   Inst.addOperand(MCOperand::createReg(Base));
12323c88fbd3SHrvoje Varga   Inst.addOperand(MCOperand::createImm(Offset));
12333c88fbd3SHrvoje Varga 
12343c88fbd3SHrvoje Varga   return MCDisassembler::Success;
12353c88fbd3SHrvoje Varga }
12363c88fbd3SHrvoje Varga 
123792db6b78SDaniel Sanders static DecodeStatus DecodeCacheOp(MCInst &Inst,
123892db6b78SDaniel Sanders                               unsigned Insn,
123992db6b78SDaniel Sanders                               uint64_t Address,
124092db6b78SDaniel Sanders                               const void *Decoder) {
124192db6b78SDaniel Sanders   int Offset = SignExtend32<16>(Insn & 0xffff);
124292db6b78SDaniel Sanders   unsigned Hint = fieldFromInstruction(Insn, 16, 5);
124392db6b78SDaniel Sanders   unsigned Base = fieldFromInstruction(Insn, 21, 5);
124492db6b78SDaniel Sanders 
124592db6b78SDaniel Sanders   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
124692db6b78SDaniel Sanders 
1247e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1248e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
1249e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Hint));
125092db6b78SDaniel Sanders 
125192db6b78SDaniel Sanders   return MCDisassembler::Success;
125292db6b78SDaniel Sanders }
125392db6b78SDaniel Sanders 
1254ab6d1cceSJozef Kolek static DecodeStatus DecodeCacheOpMM(MCInst &Inst,
1255ab6d1cceSJozef Kolek                                     unsigned Insn,
1256ab6d1cceSJozef Kolek                                     uint64_t Address,
1257ab6d1cceSJozef Kolek                                     const void *Decoder) {
1258ab6d1cceSJozef Kolek   int Offset = SignExtend32<12>(Insn & 0xfff);
1259ab6d1cceSJozef Kolek   unsigned Base = fieldFromInstruction(Insn, 16, 5);
1260ab6d1cceSJozef Kolek   unsigned Hint = fieldFromInstruction(Insn, 21, 5);
1261ab6d1cceSJozef Kolek 
1262ab6d1cceSJozef Kolek   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1263ab6d1cceSJozef Kolek 
1264e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1265e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
1266e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Hint));
1267ab6d1cceSJozef Kolek 
1268ab6d1cceSJozef Kolek   return MCDisassembler::Success;
1269ab6d1cceSJozef Kolek }
1270ab6d1cceSJozef Kolek 
1271d9790793SZoran Jovanovic static DecodeStatus DecodePrefeOpMM(MCInst &Inst,
1272d9790793SZoran Jovanovic                                     unsigned Insn,
1273d9790793SZoran Jovanovic                                     uint64_t Address,
1274d9790793SZoran Jovanovic                                     const void *Decoder) {
1275d9790793SZoran Jovanovic   int Offset = SignExtend32<9>(Insn & 0x1ff);
1276d9790793SZoran Jovanovic   unsigned Base = fieldFromInstruction(Insn, 16, 5);
1277d9790793SZoran Jovanovic   unsigned Hint = fieldFromInstruction(Insn, 21, 5);
1278d9790793SZoran Jovanovic 
1279d9790793SZoran Jovanovic   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1280d9790793SZoran Jovanovic 
1281d9790793SZoran Jovanovic   Inst.addOperand(MCOperand::createReg(Base));
1282d9790793SZoran Jovanovic   Inst.addOperand(MCOperand::createImm(Offset));
1283d9790793SZoran Jovanovic   Inst.addOperand(MCOperand::createImm(Hint));
1284d9790793SZoran Jovanovic 
1285d9790793SZoran Jovanovic   return MCDisassembler::Success;
1286d9790793SZoran Jovanovic }
1287d9790793SZoran Jovanovic 
1288e4e83a7bSDaniel Sanders static DecodeStatus DecodeCacheeOp_CacheOpR6(MCInst &Inst,
1289df464ae2SVladimir Medic                                              unsigned Insn,
1290df464ae2SVladimir Medic                                              uint64_t Address,
1291df464ae2SVladimir Medic                                              const void *Decoder) {
1292e4e83a7bSDaniel Sanders   int Offset = SignExtend32<9>(Insn >> 7);
1293df464ae2SVladimir Medic   unsigned Hint = fieldFromInstruction(Insn, 16, 5);
1294df464ae2SVladimir Medic   unsigned Base = fieldFromInstruction(Insn, 21, 5);
1295df464ae2SVladimir Medic 
1296df464ae2SVladimir Medic   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1297df464ae2SVladimir Medic 
1298e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1299e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
1300e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Hint));
1301df464ae2SVladimir Medic 
1302df464ae2SVladimir Medic   return MCDisassembler::Success;
1303df464ae2SVladimir Medic }
1304df464ae2SVladimir Medic 
13059eaa30d2SZoran Jovanovic static DecodeStatus DecodeStoreEvaOpMM(MCInst &Inst,
13069eaa30d2SZoran Jovanovic                                        unsigned Insn,
13079eaa30d2SZoran Jovanovic                                        uint64_t Address,
13089eaa30d2SZoran Jovanovic                                        const void *Decoder) {
13099eaa30d2SZoran Jovanovic   int Offset = SignExtend32<9>(Insn & 0x1ff);
13109eaa30d2SZoran Jovanovic   unsigned Reg = fieldFromInstruction(Insn, 21, 5);
13119eaa30d2SZoran Jovanovic   unsigned Base = fieldFromInstruction(Insn, 16, 5);
13129eaa30d2SZoran Jovanovic 
13139eaa30d2SZoran Jovanovic   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
13149eaa30d2SZoran Jovanovic   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
13159eaa30d2SZoran Jovanovic 
13169eaa30d2SZoran Jovanovic   Inst.addOperand(MCOperand::createReg(Reg));
13179eaa30d2SZoran Jovanovic   Inst.addOperand(MCOperand::createReg(Base));
13189eaa30d2SZoran Jovanovic   Inst.addOperand(MCOperand::createImm(Offset));
13199eaa30d2SZoran Jovanovic 
13209eaa30d2SZoran Jovanovic   return MCDisassembler::Success;
13219eaa30d2SZoran Jovanovic }
13229eaa30d2SZoran Jovanovic 
1323b4484d62SDaniel Sanders static DecodeStatus DecodeSyncI(MCInst &Inst,
1324b4484d62SDaniel Sanders                               unsigned Insn,
1325b4484d62SDaniel Sanders                               uint64_t Address,
1326b4484d62SDaniel Sanders                               const void *Decoder) {
1327b4484d62SDaniel Sanders   int Offset = SignExtend32<16>(Insn & 0xffff);
1328b4484d62SDaniel Sanders   unsigned Base = fieldFromInstruction(Insn, 21, 5);
1329b4484d62SDaniel Sanders 
1330b4484d62SDaniel Sanders   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1331b4484d62SDaniel Sanders 
1332e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1333e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
1334b4484d62SDaniel Sanders 
1335b4484d62SDaniel Sanders   return MCDisassembler::Success;
1336b4484d62SDaniel Sanders }
1337b4484d62SDaniel Sanders 
133818148671SHrvoje Varga static DecodeStatus DecodeSynciR6(MCInst &Inst,
133918148671SHrvoje Varga                                   unsigned Insn,
134018148671SHrvoje Varga                                   uint64_t Address,
134118148671SHrvoje Varga                                   const void *Decoder) {
134218148671SHrvoje Varga   int Immediate = SignExtend32<16>(Insn & 0xffff);
134318148671SHrvoje Varga   unsigned Base = fieldFromInstruction(Insn, 16, 5);
134418148671SHrvoje Varga 
134518148671SHrvoje Varga   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
134618148671SHrvoje Varga 
134718148671SHrvoje Varga   Inst.addOperand(MCOperand::createReg(Base));
134818148671SHrvoje Varga   Inst.addOperand(MCOperand::createImm(Immediate));
134918148671SHrvoje Varga 
135018148671SHrvoje Varga   return MCDisassembler::Success;
135118148671SHrvoje Varga }
135218148671SHrvoje Varga 
1353fe0bf9f6SMatheus Almeida static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn,
1354fe0bf9f6SMatheus Almeida                                     uint64_t Address, const void *Decoder) {
1355fe0bf9f6SMatheus Almeida   int Offset = SignExtend32<10>(fieldFromInstruction(Insn, 16, 10));
1356fe0bf9f6SMatheus Almeida   unsigned Reg = fieldFromInstruction(Insn, 6, 5);
1357fe0bf9f6SMatheus Almeida   unsigned Base = fieldFromInstruction(Insn, 11, 5);
1358fe0bf9f6SMatheus Almeida 
1359fe0bf9f6SMatheus Almeida   Reg = getReg(Decoder, Mips::MSA128BRegClassID, Reg);
1360fe0bf9f6SMatheus Almeida   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1361fe0bf9f6SMatheus Almeida 
1362e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1363e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
13646b59c449SMatheus Almeida 
13656b59c449SMatheus Almeida   // The immediate field of an LD/ST instruction is scaled which means it must
13666b59c449SMatheus Almeida   // be multiplied (when decoding) by the size (in bytes) of the instructions'
13676b59c449SMatheus Almeida   // data format.
13686b59c449SMatheus Almeida   // .b - 1 byte
13696b59c449SMatheus Almeida   // .h - 2 bytes
13706b59c449SMatheus Almeida   // .w - 4 bytes
13716b59c449SMatheus Almeida   // .d - 8 bytes
13726b59c449SMatheus Almeida   switch(Inst.getOpcode())
13736b59c449SMatheus Almeida   {
13746b59c449SMatheus Almeida   default:
13756b59c449SMatheus Almeida     assert (0 && "Unexpected instruction");
13766b59c449SMatheus Almeida     return MCDisassembler::Fail;
13776b59c449SMatheus Almeida     break;
13786b59c449SMatheus Almeida   case Mips::LD_B:
13796b59c449SMatheus Almeida   case Mips::ST_B:
1380e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(Offset));
13816b59c449SMatheus Almeida     break;
13826b59c449SMatheus Almeida   case Mips::LD_H:
13836b59c449SMatheus Almeida   case Mips::ST_H:
1384e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(Offset * 2));
13856b59c449SMatheus Almeida     break;
13866b59c449SMatheus Almeida   case Mips::LD_W:
13876b59c449SMatheus Almeida   case Mips::ST_W:
1388e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(Offset * 4));
13896b59c449SMatheus Almeida     break;
13906b59c449SMatheus Almeida   case Mips::LD_D:
13916b59c449SMatheus Almeida   case Mips::ST_D:
1392e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(Offset * 8));
13936b59c449SMatheus Almeida     break;
13946b59c449SMatheus Almeida   }
1395fe0bf9f6SMatheus Almeida 
1396fe0bf9f6SMatheus Almeida   return MCDisassembler::Success;
1397fe0bf9f6SMatheus Almeida }
1398fe0bf9f6SMatheus Almeida 
1399315e7ecaSJozef Kolek static DecodeStatus DecodeMemMMImm4(MCInst &Inst,
1400315e7ecaSJozef Kolek                                     unsigned Insn,
1401315e7ecaSJozef Kolek                                     uint64_t Address,
1402315e7ecaSJozef Kolek                                     const void *Decoder) {
1403315e7ecaSJozef Kolek   unsigned Offset = Insn & 0xf;
1404315e7ecaSJozef Kolek   unsigned Reg = fieldFromInstruction(Insn, 7, 3);
1405315e7ecaSJozef Kolek   unsigned Base = fieldFromInstruction(Insn, 4, 3);
1406315e7ecaSJozef Kolek 
1407315e7ecaSJozef Kolek   switch (Inst.getOpcode()) {
1408315e7ecaSJozef Kolek     case Mips::LBU16_MM:
1409315e7ecaSJozef Kolek     case Mips::LHU16_MM:
1410315e7ecaSJozef Kolek     case Mips::LW16_MM:
1411315e7ecaSJozef Kolek       if (DecodeGPRMM16RegisterClass(Inst, Reg, Address, Decoder)
1412315e7ecaSJozef Kolek             == MCDisassembler::Fail)
1413315e7ecaSJozef Kolek         return MCDisassembler::Fail;
1414315e7ecaSJozef Kolek       break;
1415315e7ecaSJozef Kolek     case Mips::SB16_MM:
1416797c2aecSZlatko Buljan     case Mips::SB16_MMR6:
1417315e7ecaSJozef Kolek     case Mips::SH16_MM:
1418797c2aecSZlatko Buljan     case Mips::SH16_MMR6:
1419315e7ecaSJozef Kolek     case Mips::SW16_MM:
1420797c2aecSZlatko Buljan     case Mips::SW16_MMR6:
1421315e7ecaSJozef Kolek       if (DecodeGPRMM16ZeroRegisterClass(Inst, Reg, Address, Decoder)
1422315e7ecaSJozef Kolek             == MCDisassembler::Fail)
1423315e7ecaSJozef Kolek         return MCDisassembler::Fail;
1424315e7ecaSJozef Kolek       break;
1425315e7ecaSJozef Kolek   }
1426315e7ecaSJozef Kolek 
1427315e7ecaSJozef Kolek   if (DecodeGPRMM16RegisterClass(Inst, Base, Address, Decoder)
1428315e7ecaSJozef Kolek         == MCDisassembler::Fail)
1429315e7ecaSJozef Kolek     return MCDisassembler::Fail;
1430315e7ecaSJozef Kolek 
1431315e7ecaSJozef Kolek   switch (Inst.getOpcode()) {
1432315e7ecaSJozef Kolek     case Mips::LBU16_MM:
1433315e7ecaSJozef Kolek       if (Offset == 0xf)
1434e9119e41SJim Grosbach         Inst.addOperand(MCOperand::createImm(-1));
1435315e7ecaSJozef Kolek       else
1436e9119e41SJim Grosbach         Inst.addOperand(MCOperand::createImm(Offset));
1437315e7ecaSJozef Kolek       break;
1438315e7ecaSJozef Kolek     case Mips::SB16_MM:
1439797c2aecSZlatko Buljan     case Mips::SB16_MMR6:
1440e9119e41SJim Grosbach       Inst.addOperand(MCOperand::createImm(Offset));
1441315e7ecaSJozef Kolek       break;
1442315e7ecaSJozef Kolek     case Mips::LHU16_MM:
1443315e7ecaSJozef Kolek     case Mips::SH16_MM:
1444797c2aecSZlatko Buljan     case Mips::SH16_MMR6:
1445e9119e41SJim Grosbach       Inst.addOperand(MCOperand::createImm(Offset << 1));
1446315e7ecaSJozef Kolek       break;
1447315e7ecaSJozef Kolek     case Mips::LW16_MM:
1448315e7ecaSJozef Kolek     case Mips::SW16_MM:
1449797c2aecSZlatko Buljan     case Mips::SW16_MMR6:
1450e9119e41SJim Grosbach       Inst.addOperand(MCOperand::createImm(Offset << 2));
1451315e7ecaSJozef Kolek       break;
1452315e7ecaSJozef Kolek   }
1453315e7ecaSJozef Kolek 
1454315e7ecaSJozef Kolek   return MCDisassembler::Success;
1455315e7ecaSJozef Kolek }
1456315e7ecaSJozef Kolek 
145712c6982bSJozef Kolek static DecodeStatus DecodeMemMMSPImm5Lsl2(MCInst &Inst,
145812c6982bSJozef Kolek                                           unsigned Insn,
145912c6982bSJozef Kolek                                           uint64_t Address,
146012c6982bSJozef Kolek                                           const void *Decoder) {
146112c6982bSJozef Kolek   unsigned Offset = Insn & 0x1F;
146212c6982bSJozef Kolek   unsigned Reg = fieldFromInstruction(Insn, 5, 5);
146312c6982bSJozef Kolek 
146412c6982bSJozef Kolek   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
146512c6982bSJozef Kolek 
1466e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1467e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Mips::SP));
1468e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset << 2));
146912c6982bSJozef Kolek 
147012c6982bSJozef Kolek   return MCDisassembler::Success;
147112c6982bSJozef Kolek }
147212c6982bSJozef Kolek 
1473e10a02ecSJozef Kolek static DecodeStatus DecodeMemMMGPImm7Lsl2(MCInst &Inst,
1474e10a02ecSJozef Kolek                                           unsigned Insn,
1475e10a02ecSJozef Kolek                                           uint64_t Address,
1476e10a02ecSJozef Kolek                                           const void *Decoder) {
1477e10a02ecSJozef Kolek   unsigned Offset = Insn & 0x7F;
1478e10a02ecSJozef Kolek   unsigned Reg = fieldFromInstruction(Insn, 7, 3);
1479e10a02ecSJozef Kolek 
1480e10a02ecSJozef Kolek   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1481e10a02ecSJozef Kolek 
1482e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1483e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Mips::GP));
1484e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset << 2));
1485e10a02ecSJozef Kolek 
1486e10a02ecSJozef Kolek   return MCDisassembler::Success;
1487e10a02ecSJozef Kolek }
1488e10a02ecSJozef Kolek 
1489d68d424aSJozef Kolek static DecodeStatus DecodeMemMMReglistImm4Lsl2(MCInst &Inst,
1490d68d424aSJozef Kolek                                                unsigned Insn,
1491d68d424aSJozef Kolek                                                uint64_t Address,
1492d68d424aSJozef Kolek                                                const void *Decoder) {
1493797c2aecSZlatko Buljan   int Offset;
1494797c2aecSZlatko Buljan   switch (Inst.getOpcode()) {
1495797c2aecSZlatko Buljan   case Mips::LWM16_MMR6:
1496797c2aecSZlatko Buljan   case Mips::SWM16_MMR6:
1497797c2aecSZlatko Buljan     Offset = fieldFromInstruction(Insn, 4, 4);
1498797c2aecSZlatko Buljan     break;
1499797c2aecSZlatko Buljan   default:
1500797c2aecSZlatko Buljan     Offset = SignExtend32<4>(Insn & 0xf);
1501797c2aecSZlatko Buljan     break;
1502797c2aecSZlatko Buljan   }
1503d68d424aSJozef Kolek 
1504d68d424aSJozef Kolek   if (DecodeRegListOperand16(Inst, Insn, Address, Decoder)
1505d68d424aSJozef Kolek       == MCDisassembler::Fail)
1506d68d424aSJozef Kolek     return MCDisassembler::Fail;
1507d68d424aSJozef Kolek 
1508e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Mips::SP));
1509e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset << 2));
1510d68d424aSJozef Kolek 
1511d68d424aSJozef Kolek   return MCDisassembler::Success;
1512d68d424aSJozef Kolek }
1513d68d424aSJozef Kolek 
1514a6593ff6SZoran Jovanovic static DecodeStatus DecodeMemMMImm9(MCInst &Inst,
1515a6593ff6SZoran Jovanovic                                     unsigned Insn,
1516a6593ff6SZoran Jovanovic                                     uint64_t Address,
1517a6593ff6SZoran Jovanovic                                     const void *Decoder) {
1518a6593ff6SZoran Jovanovic   int Offset = SignExtend32<9>(Insn & 0x1ff);
1519a6593ff6SZoran Jovanovic   unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1520a6593ff6SZoran Jovanovic   unsigned Base = fieldFromInstruction(Insn, 16, 5);
1521a6593ff6SZoran Jovanovic 
1522a6593ff6SZoran Jovanovic   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1523a6593ff6SZoran Jovanovic   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1524a6593ff6SZoran Jovanovic 
15253ef4dd7bSHrvoje Varga   if (Inst.getOpcode() == Mips::SCE_MM)
15263ef4dd7bSHrvoje Varga     Inst.addOperand(MCOperand::createReg(Reg));
15273ef4dd7bSHrvoje Varga 
1528a6593ff6SZoran Jovanovic   Inst.addOperand(MCOperand::createReg(Reg));
1529a6593ff6SZoran Jovanovic   Inst.addOperand(MCOperand::createReg(Base));
1530a6593ff6SZoran Jovanovic   Inst.addOperand(MCOperand::createImm(Offset));
1531a6593ff6SZoran Jovanovic 
1532a6593ff6SZoran Jovanovic   return MCDisassembler::Success;
1533a6593ff6SZoran Jovanovic }
1534a6593ff6SZoran Jovanovic 
1535dde3d582SVladimir Medic static DecodeStatus DecodeMemMMImm12(MCInst &Inst,
1536dde3d582SVladimir Medic                                      unsigned Insn,
1537dde3d582SVladimir Medic                                      uint64_t Address,
1538dde3d582SVladimir Medic                                      const void *Decoder) {
1539dde3d582SVladimir Medic   int Offset = SignExtend32<12>(Insn & 0x0fff);
1540dde3d582SVladimir Medic   unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1541dde3d582SVladimir Medic   unsigned Base = fieldFromInstruction(Insn, 16, 5);
1542dde3d582SVladimir Medic 
1543dde3d582SVladimir Medic   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1544dde3d582SVladimir Medic   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1545dde3d582SVladimir Medic 
1546a4c4b5fcSZoran Jovanovic   switch (Inst.getOpcode()) {
1547a4c4b5fcSZoran Jovanovic   case Mips::SWM32_MM:
1548a4c4b5fcSZoran Jovanovic   case Mips::LWM32_MM:
1549a4c4b5fcSZoran Jovanovic     if (DecodeRegListOperand(Inst, Insn, Address, Decoder)
1550a4c4b5fcSZoran Jovanovic         == MCDisassembler::Fail)
1551a4c4b5fcSZoran Jovanovic       return MCDisassembler::Fail;
1552e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Base));
1553e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(Offset));
1554a4c4b5fcSZoran Jovanovic     break;
1555a4c4b5fcSZoran Jovanovic   case Mips::SC_MM:
1556e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Reg));
1557a4c4b5fcSZoran Jovanovic     // fallthrough
1558a4c4b5fcSZoran Jovanovic   default:
1559e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Reg));
1560ba553a6eSZlatko Buljan     if (Inst.getOpcode() == Mips::LWP_MM || Inst.getOpcode() == Mips::SWP_MM ||
1561ba553a6eSZlatko Buljan         Inst.getOpcode() == Mips::LWP_MMR6 || Inst.getOpcode() == Mips::SWP_MMR6)
1562e9119e41SJim Grosbach       Inst.addOperand(MCOperand::createReg(Reg+1));
15632deca348SZoran Jovanovic 
1564e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Base));
1565e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(Offset));
1566a4c4b5fcSZoran Jovanovic   }
1567dde3d582SVladimir Medic 
1568dde3d582SVladimir Medic   return MCDisassembler::Success;
1569dde3d582SVladimir Medic }
1570dde3d582SVladimir Medic 
1571dde3d582SVladimir Medic static DecodeStatus DecodeMemMMImm16(MCInst &Inst,
1572dde3d582SVladimir Medic                                      unsigned Insn,
1573dde3d582SVladimir Medic                                      uint64_t Address,
1574dde3d582SVladimir Medic                                      const void *Decoder) {
1575dde3d582SVladimir Medic   int Offset = SignExtend32<16>(Insn & 0xffff);
1576dde3d582SVladimir Medic   unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1577dde3d582SVladimir Medic   unsigned Base = fieldFromInstruction(Insn, 16, 5);
1578dde3d582SVladimir Medic 
1579dde3d582SVladimir Medic   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1580dde3d582SVladimir Medic   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1581dde3d582SVladimir Medic 
1582e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1583e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1584e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
1585dde3d582SVladimir Medic 
1586dde3d582SVladimir Medic   return MCDisassembler::Success;
1587dde3d582SVladimir Medic }
1588dde3d582SVladimir Medic 
158971928e68SAkira Hatanaka static DecodeStatus DecodeFMem(MCInst &Inst,
159071928e68SAkira Hatanaka                                unsigned Insn,
159171928e68SAkira Hatanaka                                uint64_t Address,
159271928e68SAkira Hatanaka                                const void *Decoder) {
159371928e68SAkira Hatanaka   int Offset = SignExtend32<16>(Insn & 0xffff);
1594ecaef49fSJim Grosbach   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1595ecaef49fSJim Grosbach   unsigned Base = fieldFromInstruction(Insn, 21, 5);
159671928e68SAkira Hatanaka 
15979bf2b567SAkira Hatanaka   Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg);
159813e6ccf3SAkira Hatanaka   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
15999bf2b567SAkira Hatanaka 
1600e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1601e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1602e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
160371928e68SAkira Hatanaka 
160471928e68SAkira Hatanaka   return MCDisassembler::Success;
160571928e68SAkira Hatanaka }
160671928e68SAkira Hatanaka 
160792db6b78SDaniel Sanders static DecodeStatus DecodeFMem2(MCInst &Inst,
160892db6b78SDaniel Sanders                                unsigned Insn,
160992db6b78SDaniel Sanders                                uint64_t Address,
161092db6b78SDaniel Sanders                                const void *Decoder) {
161192db6b78SDaniel Sanders   int Offset = SignExtend32<16>(Insn & 0xffff);
161292db6b78SDaniel Sanders   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
161392db6b78SDaniel Sanders   unsigned Base = fieldFromInstruction(Insn, 21, 5);
161492db6b78SDaniel Sanders 
161592db6b78SDaniel Sanders   Reg = getReg(Decoder, Mips::COP2RegClassID, Reg);
161692db6b78SDaniel Sanders   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
161792db6b78SDaniel Sanders 
1618e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1619e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1620e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
162192db6b78SDaniel Sanders 
162292db6b78SDaniel Sanders   return MCDisassembler::Success;
162392db6b78SDaniel Sanders }
162492db6b78SDaniel Sanders 
162592db6b78SDaniel Sanders static DecodeStatus DecodeFMem3(MCInst &Inst,
162692db6b78SDaniel Sanders                                unsigned Insn,
162792db6b78SDaniel Sanders                                uint64_t Address,
162892db6b78SDaniel Sanders                                const void *Decoder) {
162992db6b78SDaniel Sanders   int Offset = SignExtend32<16>(Insn & 0xffff);
163092db6b78SDaniel Sanders   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
163192db6b78SDaniel Sanders   unsigned Base = fieldFromInstruction(Insn, 21, 5);
163292db6b78SDaniel Sanders 
163392db6b78SDaniel Sanders   Reg = getReg(Decoder, Mips::COP3RegClassID, Reg);
163492db6b78SDaniel Sanders   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
163592db6b78SDaniel Sanders 
1636e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1637e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1638e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
163992db6b78SDaniel Sanders 
164092db6b78SDaniel Sanders   return MCDisassembler::Success;
164192db6b78SDaniel Sanders }
164292db6b78SDaniel Sanders 
1643435cf8a4SVladimir Medic static DecodeStatus DecodeFMemCop2R6(MCInst &Inst,
1644435cf8a4SVladimir Medic                                     unsigned Insn,
1645435cf8a4SVladimir Medic                                     uint64_t Address,
1646435cf8a4SVladimir Medic                                     const void *Decoder) {
1647435cf8a4SVladimir Medic   int Offset = SignExtend32<11>(Insn & 0x07ff);
1648435cf8a4SVladimir Medic   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1649435cf8a4SVladimir Medic   unsigned Base = fieldFromInstruction(Insn, 11, 5);
1650435cf8a4SVladimir Medic 
1651435cf8a4SVladimir Medic   Reg = getReg(Decoder, Mips::COP2RegClassID, Reg);
1652435cf8a4SVladimir Medic   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1653435cf8a4SVladimir Medic 
1654e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1655e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1656e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
1657435cf8a4SVladimir Medic 
1658435cf8a4SVladimir Medic   return MCDisassembler::Success;
1659435cf8a4SVladimir Medic }
16606a803f61SDaniel Sanders static DecodeStatus DecodeSpecial3LlSc(MCInst &Inst,
16616a803f61SDaniel Sanders                                        unsigned Insn,
16626a803f61SDaniel Sanders                                        uint64_t Address,
16636a803f61SDaniel Sanders                                        const void *Decoder) {
16646a803f61SDaniel Sanders   int64_t Offset = SignExtend64<9>((Insn >> 7) & 0x1ff);
16656a803f61SDaniel Sanders   unsigned Rt = fieldFromInstruction(Insn, 16, 5);
16666a803f61SDaniel Sanders   unsigned Base = fieldFromInstruction(Insn, 21, 5);
16676a803f61SDaniel Sanders 
16686a803f61SDaniel Sanders   Rt = getReg(Decoder, Mips::GPR32RegClassID, Rt);
16696a803f61SDaniel Sanders   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
16706a803f61SDaniel Sanders 
16716a803f61SDaniel Sanders   if(Inst.getOpcode() == Mips::SC_R6 || Inst.getOpcode() == Mips::SCD_R6){
1672e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Rt));
16736a803f61SDaniel Sanders   }
16746a803f61SDaniel Sanders 
1675e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Rt));
1676e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1677e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
16786a803f61SDaniel Sanders 
16796a803f61SDaniel Sanders   return MCDisassembler::Success;
16806a803f61SDaniel Sanders }
168171928e68SAkira Hatanaka 
168271928e68SAkira Hatanaka static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
168371928e68SAkira Hatanaka                                               unsigned RegNo,
168471928e68SAkira Hatanaka                                               uint64_t Address,
168571928e68SAkira Hatanaka                                               const void *Decoder) {
168671928e68SAkira Hatanaka   // Currently only hardware register 29 is supported.
168771928e68SAkira Hatanaka   if (RegNo != 29)
168871928e68SAkira Hatanaka     return  MCDisassembler::Fail;
1689e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Mips::HWR29));
169071928e68SAkira Hatanaka   return MCDisassembler::Success;
169171928e68SAkira Hatanaka }
169271928e68SAkira Hatanaka 
169371928e68SAkira Hatanaka static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
169471928e68SAkira Hatanaka                                               unsigned RegNo,
169571928e68SAkira Hatanaka                                               uint64_t Address,
169671928e68SAkira Hatanaka                                               const void *Decoder) {
16979bf2b567SAkira Hatanaka   if (RegNo > 30 || RegNo %2)
169871928e68SAkira Hatanaka     return MCDisassembler::Fail;
169971928e68SAkira Hatanaka 
17009bf2b567SAkira Hatanaka   ;
17019bf2b567SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::AFGR64RegClassID, RegNo /2);
1702e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
170371928e68SAkira Hatanaka   return MCDisassembler::Success;
170471928e68SAkira Hatanaka }
170571928e68SAkira Hatanaka 
170600fcf2e1SAkira Hatanaka static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst,
1707ecabd1a5SAkira Hatanaka                                                 unsigned RegNo,
1708ecabd1a5SAkira Hatanaka                                                 uint64_t Address,
1709ecabd1a5SAkira Hatanaka                                                 const void *Decoder) {
1710ecabd1a5SAkira Hatanaka   if (RegNo >= 4)
1711ecabd1a5SAkira Hatanaka     return MCDisassembler::Fail;
1712ecabd1a5SAkira Hatanaka 
171300fcf2e1SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::ACC64DSPRegClassID, RegNo);
1714e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1715ecabd1a5SAkira Hatanaka   return MCDisassembler::Success;
1716ecabd1a5SAkira Hatanaka }
1717ecabd1a5SAkira Hatanaka 
17188002a3f6SAkira Hatanaka static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst,
171959bfaf77SAkira Hatanaka                                                unsigned RegNo,
172059bfaf77SAkira Hatanaka                                                uint64_t Address,
172159bfaf77SAkira Hatanaka                                                const void *Decoder) {
172259bfaf77SAkira Hatanaka   if (RegNo >= 4)
172359bfaf77SAkira Hatanaka     return MCDisassembler::Fail;
172459bfaf77SAkira Hatanaka 
17258002a3f6SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::HI32DSPRegClassID, RegNo);
1726e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
172759bfaf77SAkira Hatanaka   return MCDisassembler::Success;
172859bfaf77SAkira Hatanaka }
172959bfaf77SAkira Hatanaka 
17308002a3f6SAkira Hatanaka static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst,
173159bfaf77SAkira Hatanaka                                                unsigned RegNo,
173259bfaf77SAkira Hatanaka                                                uint64_t Address,
173359bfaf77SAkira Hatanaka                                                const void *Decoder) {
173459bfaf77SAkira Hatanaka   if (RegNo >= 4)
173559bfaf77SAkira Hatanaka     return MCDisassembler::Fail;
173659bfaf77SAkira Hatanaka 
17378002a3f6SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::LO32DSPRegClassID, RegNo);
1738e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
173959bfaf77SAkira Hatanaka   return MCDisassembler::Success;
174059bfaf77SAkira Hatanaka }
174159bfaf77SAkira Hatanaka 
17423eb663b0SJack Carter static DecodeStatus DecodeMSA128BRegisterClass(MCInst &Inst,
17433eb663b0SJack Carter                                                unsigned RegNo,
17443eb663b0SJack Carter                                                uint64_t Address,
17453eb663b0SJack Carter                                                const void *Decoder) {
17463eb663b0SJack Carter   if (RegNo > 31)
17473eb663b0SJack Carter     return MCDisassembler::Fail;
17483eb663b0SJack Carter 
17493eb663b0SJack Carter   unsigned Reg = getReg(Decoder, Mips::MSA128BRegClassID, RegNo);
1750e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
17513eb663b0SJack Carter   return MCDisassembler::Success;
17523eb663b0SJack Carter }
17533eb663b0SJack Carter 
17545dc8ac92SJack Carter static DecodeStatus DecodeMSA128HRegisterClass(MCInst &Inst,
17555dc8ac92SJack Carter                                                unsigned RegNo,
17565dc8ac92SJack Carter                                                uint64_t Address,
17575dc8ac92SJack Carter                                                const void *Decoder) {
17585dc8ac92SJack Carter   if (RegNo > 31)
17595dc8ac92SJack Carter     return MCDisassembler::Fail;
17605dc8ac92SJack Carter 
17615dc8ac92SJack Carter   unsigned Reg = getReg(Decoder, Mips::MSA128HRegClassID, RegNo);
1762e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
17635dc8ac92SJack Carter   return MCDisassembler::Success;
17645dc8ac92SJack Carter }
17655dc8ac92SJack Carter 
17665dc8ac92SJack Carter static DecodeStatus DecodeMSA128WRegisterClass(MCInst &Inst,
17675dc8ac92SJack Carter                                                unsigned RegNo,
17685dc8ac92SJack Carter                                                uint64_t Address,
17695dc8ac92SJack Carter                                                const void *Decoder) {
17705dc8ac92SJack Carter   if (RegNo > 31)
17715dc8ac92SJack Carter     return MCDisassembler::Fail;
17725dc8ac92SJack Carter 
17735dc8ac92SJack Carter   unsigned Reg = getReg(Decoder, Mips::MSA128WRegClassID, RegNo);
1774e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
17755dc8ac92SJack Carter   return MCDisassembler::Success;
17765dc8ac92SJack Carter }
17775dc8ac92SJack Carter 
17785dc8ac92SJack Carter static DecodeStatus DecodeMSA128DRegisterClass(MCInst &Inst,
17795dc8ac92SJack Carter                                                unsigned RegNo,
17805dc8ac92SJack Carter                                                uint64_t Address,
17815dc8ac92SJack Carter                                                const void *Decoder) {
17825dc8ac92SJack Carter   if (RegNo > 31)
17835dc8ac92SJack Carter     return MCDisassembler::Fail;
17845dc8ac92SJack Carter 
17855dc8ac92SJack Carter   unsigned Reg = getReg(Decoder, Mips::MSA128DRegClassID, RegNo);
1786e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
17875dc8ac92SJack Carter   return MCDisassembler::Success;
17885dc8ac92SJack Carter }
17895dc8ac92SJack Carter 
1790a591fdc6SMatheus Almeida static DecodeStatus DecodeMSACtrlRegisterClass(MCInst &Inst,
1791a591fdc6SMatheus Almeida                                                unsigned RegNo,
1792a591fdc6SMatheus Almeida                                                uint64_t Address,
1793a591fdc6SMatheus Almeida                                                const void *Decoder) {
1794a591fdc6SMatheus Almeida   if (RegNo > 7)
1795a591fdc6SMatheus Almeida     return MCDisassembler::Fail;
1796a591fdc6SMatheus Almeida 
1797a591fdc6SMatheus Almeida   unsigned Reg = getReg(Decoder, Mips::MSACtrlRegClassID, RegNo);
1798e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1799a591fdc6SMatheus Almeida   return MCDisassembler::Success;
1800a591fdc6SMatheus Almeida }
1801a591fdc6SMatheus Almeida 
1802a3134faeSDaniel Sanders static DecodeStatus DecodeCOP0RegisterClass(MCInst &Inst,
1803a3134faeSDaniel Sanders                                             unsigned RegNo,
1804a3134faeSDaniel Sanders                                             uint64_t Address,
1805a3134faeSDaniel Sanders                                             const void *Decoder) {
1806a3134faeSDaniel Sanders   if (RegNo > 31)
1807a3134faeSDaniel Sanders     return MCDisassembler::Fail;
1808a3134faeSDaniel Sanders 
1809a3134faeSDaniel Sanders   unsigned Reg = getReg(Decoder, Mips::COP0RegClassID, RegNo);
1810a3134faeSDaniel Sanders   Inst.addOperand(MCOperand::createReg(Reg));
1811a3134faeSDaniel Sanders   return MCDisassembler::Success;
1812a3134faeSDaniel Sanders }
1813a3134faeSDaniel Sanders 
18142a83d680SDaniel Sanders static DecodeStatus DecodeCOP2RegisterClass(MCInst &Inst,
18152a83d680SDaniel Sanders                                             unsigned RegNo,
18162a83d680SDaniel Sanders                                             uint64_t Address,
18172a83d680SDaniel Sanders                                             const void *Decoder) {
18182a83d680SDaniel Sanders   if (RegNo > 31)
18192a83d680SDaniel Sanders     return MCDisassembler::Fail;
18202a83d680SDaniel Sanders 
18212a83d680SDaniel Sanders   unsigned Reg = getReg(Decoder, Mips::COP2RegClassID, RegNo);
1822e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
18232a83d680SDaniel Sanders   return MCDisassembler::Success;
18242a83d680SDaniel Sanders }
18252a83d680SDaniel Sanders 
182671928e68SAkira Hatanaka static DecodeStatus DecodeBranchTarget(MCInst &Inst,
182771928e68SAkira Hatanaka                                        unsigned Offset,
182871928e68SAkira Hatanaka                                        uint64_t Address,
182971928e68SAkira Hatanaka                                        const void *Decoder) {
1830d37bab61SAlexey Samsonov   int32_t BranchOffset = (SignExtend32<16>(Offset) * 4) + 4;
1831e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(BranchOffset));
183271928e68SAkira Hatanaka   return MCDisassembler::Success;
183371928e68SAkira Hatanaka }
183471928e68SAkira Hatanaka 
1835*6f09cdfdSHrvoje Varga static DecodeStatus DecodeBranchTarget1SImm16(MCInst &Inst,
1836*6f09cdfdSHrvoje Varga                                               unsigned Offset,
1837*6f09cdfdSHrvoje Varga                                               uint64_t Address,
1838*6f09cdfdSHrvoje Varga                                               const void *Decoder) {
1839*6f09cdfdSHrvoje Varga   int32_t BranchOffset = (SignExtend32<16>(Offset) * 2);
1840*6f09cdfdSHrvoje Varga   Inst.addOperand(MCOperand::createImm(BranchOffset));
1841*6f09cdfdSHrvoje Varga   return MCDisassembler::Success;
1842*6f09cdfdSHrvoje Varga }
1843*6f09cdfdSHrvoje Varga 
184471928e68SAkira Hatanaka static DecodeStatus DecodeJumpTarget(MCInst &Inst,
184571928e68SAkira Hatanaka                                      unsigned Insn,
184671928e68SAkira Hatanaka                                      uint64_t Address,
184771928e68SAkira Hatanaka                                      const void *Decoder) {
184871928e68SAkira Hatanaka 
1849ecaef49fSJim Grosbach   unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 2;
1850e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(JumpOffset));
185171928e68SAkira Hatanaka   return MCDisassembler::Success;
185271928e68SAkira Hatanaka }
185371928e68SAkira Hatanaka 
18543c8869dcSZoran Jovanovic static DecodeStatus DecodeBranchTarget21(MCInst &Inst,
18553c8869dcSZoran Jovanovic                                          unsigned Offset,
18563c8869dcSZoran Jovanovic                                          uint64_t Address,
18573c8869dcSZoran Jovanovic                                          const void *Decoder) {
1858d37bab61SAlexey Samsonov   int32_t BranchOffset = SignExtend32<21>(Offset) * 4;
18593c8869dcSZoran Jovanovic 
1860e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(BranchOffset));
18613c8869dcSZoran Jovanovic   return MCDisassembler::Success;
18623c8869dcSZoran Jovanovic }
18633c8869dcSZoran Jovanovic 
18643c8869dcSZoran Jovanovic static DecodeStatus DecodeBranchTarget26(MCInst &Inst,
18653c8869dcSZoran Jovanovic                                          unsigned Offset,
18663c8869dcSZoran Jovanovic                                          uint64_t Address,
18673c8869dcSZoran Jovanovic                                          const void *Decoder) {
1868d37bab61SAlexey Samsonov   int32_t BranchOffset = SignExtend32<26>(Offset) * 4;
18693c8869dcSZoran Jovanovic 
1870e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(BranchOffset));
18713c8869dcSZoran Jovanovic   return MCDisassembler::Success;
18723c8869dcSZoran Jovanovic }
18733c8869dcSZoran Jovanovic 
18749761e96bSJozef Kolek static DecodeStatus DecodeBranchTarget7MM(MCInst &Inst,
18759761e96bSJozef Kolek                                           unsigned Offset,
18769761e96bSJozef Kolek                                           uint64_t Address,
18779761e96bSJozef Kolek                                           const void *Decoder) {
18789761e96bSJozef Kolek   int32_t BranchOffset = SignExtend32<7>(Offset) << 1;
1879e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(BranchOffset));
18809761e96bSJozef Kolek   return MCDisassembler::Success;
18819761e96bSJozef Kolek }
18829761e96bSJozef Kolek 
18835cfebddeSJozef Kolek static DecodeStatus DecodeBranchTarget10MM(MCInst &Inst,
18845cfebddeSJozef Kolek                                            unsigned Offset,
18855cfebddeSJozef Kolek                                            uint64_t Address,
18865cfebddeSJozef Kolek                                            const void *Decoder) {
18875cfebddeSJozef Kolek   int32_t BranchOffset = SignExtend32<10>(Offset) << 1;
1888e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(BranchOffset));
18895cfebddeSJozef Kolek   return MCDisassembler::Success;
18905cfebddeSJozef Kolek }
18915cfebddeSJozef Kolek 
18928a80aa76SZoran Jovanovic static DecodeStatus DecodeBranchTargetMM(MCInst &Inst,
18938a80aa76SZoran Jovanovic                                          unsigned Offset,
18948a80aa76SZoran Jovanovic                                          uint64_t Address,
18958a80aa76SZoran Jovanovic                                          const void *Decoder) {
1896d37bab61SAlexey Samsonov   int32_t BranchOffset = SignExtend32<16>(Offset) * 2;
1897e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(BranchOffset));
18988a80aa76SZoran Jovanovic   return MCDisassembler::Success;
18998a80aa76SZoran Jovanovic }
19008a80aa76SZoran Jovanovic 
1901a887b361SZoran Jovanovic static DecodeStatus DecodeBranchTarget26MM(MCInst &Inst,
1902a887b361SZoran Jovanovic   unsigned Offset,
1903a887b361SZoran Jovanovic   uint64_t Address,
1904a887b361SZoran Jovanovic   const void *Decoder) {
1905a887b361SZoran Jovanovic   int32_t BranchOffset = SignExtend32<26>(Offset) << 1;
1906a887b361SZoran Jovanovic 
1907a887b361SZoran Jovanovic   Inst.addOperand(MCOperand::createImm(BranchOffset));
1908a887b361SZoran Jovanovic   return MCDisassembler::Success;
1909a887b361SZoran Jovanovic }
1910a887b361SZoran Jovanovic 
1911507e084aSZoran Jovanovic static DecodeStatus DecodeJumpTargetMM(MCInst &Inst,
1912507e084aSZoran Jovanovic                                        unsigned Insn,
1913507e084aSZoran Jovanovic                                        uint64_t Address,
1914507e084aSZoran Jovanovic                                        const void *Decoder) {
1915507e084aSZoran Jovanovic   unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 1;
1916e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(JumpOffset));
1917507e084aSZoran Jovanovic   return MCDisassembler::Success;
1918507e084aSZoran Jovanovic }
191971928e68SAkira Hatanaka 
1920aa2b9278SJozef Kolek static DecodeStatus DecodeAddiur2Simm7(MCInst &Inst,
1921aa2b9278SJozef Kolek                                        unsigned Value,
1922aa2b9278SJozef Kolek                                        uint64_t Address,
1923aa2b9278SJozef Kolek                                        const void *Decoder) {
1924aa2b9278SJozef Kolek   if (Value == 0)
1925e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(1));
1926aa2b9278SJozef Kolek   else if (Value == 0x7)
1927e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(-1));
1928aa2b9278SJozef Kolek   else
1929e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(Value << 2));
1930aa2b9278SJozef Kolek   return MCDisassembler::Success;
1931aa2b9278SJozef Kolek }
1932aa2b9278SJozef Kolek 
193397297770SDaniel Sanders static DecodeStatus DecodeLi16Imm(MCInst &Inst,
1934aa2b9278SJozef Kolek                                   unsigned Value,
1935aa2b9278SJozef Kolek                                   uint64_t Address,
1936aa2b9278SJozef Kolek                                   const void *Decoder) {
1937aa2b9278SJozef Kolek   if (Value == 0x7F)
1938e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(-1));
1939aa2b9278SJozef Kolek   else
1940e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(Value));
1941aa2b9278SJozef Kolek   return MCDisassembler::Success;
1942aa2b9278SJozef Kolek }
1943aa2b9278SJozef Kolek 
19446b28f09dSZoran Jovanovic static DecodeStatus DecodePOOL16BEncodedField(MCInst &Inst,
19456b28f09dSZoran Jovanovic                                               unsigned Value,
19466b28f09dSZoran Jovanovic                                               uint64_t Address,
19476b28f09dSZoran Jovanovic                                               const void *Decoder) {
19486b28f09dSZoran Jovanovic   Inst.addOperand(MCOperand::createImm(Value == 0x0 ? 8 : Value));
19496b28f09dSZoran Jovanovic   return MCDisassembler::Success;
19506b28f09dSZoran Jovanovic }
19516b28f09dSZoran Jovanovic 
195219b7f76aSDaniel Sanders template <unsigned Bits, int Offset, int Scale>
195319b7f76aSDaniel Sanders static DecodeStatus DecodeUImmWithOffsetAndScale(MCInst &Inst, unsigned Value,
1954779c5937SMatheus Almeida                                                  uint64_t Address,
1955779c5937SMatheus Almeida                                                  const void *Decoder) {
1956ea4f653dSDaniel Sanders   Value &= ((1 << Bits) - 1);
195719b7f76aSDaniel Sanders   Value *= Scale;
1958ea4f653dSDaniel Sanders   Inst.addOperand(MCOperand::createImm(Value + Offset));
1959779c5937SMatheus Almeida   return MCDisassembler::Success;
1960779c5937SMatheus Almeida }
1961779c5937SMatheus Almeida 
196297297770SDaniel Sanders template <unsigned Bits, int Offset, int ScaleBy>
196397297770SDaniel Sanders static DecodeStatus DecodeSImmWithOffsetAndScale(MCInst &Inst, unsigned Value,
196478e89020SDaniel Sanders                                                  uint64_t Address,
196578e89020SDaniel Sanders                                                  const void *Decoder) {
196697297770SDaniel Sanders   int32_t Imm = SignExtend32<Bits>(Value) * ScaleBy;
196778e89020SDaniel Sanders   Inst.addOperand(MCOperand::createImm(Imm + Offset));
196878e89020SDaniel Sanders   return MCDisassembler::Success;
196978e89020SDaniel Sanders }
197078e89020SDaniel Sanders 
197171928e68SAkira Hatanaka static DecodeStatus DecodeInsSize(MCInst &Inst,
197271928e68SAkira Hatanaka                                   unsigned Insn,
197371928e68SAkira Hatanaka                                   uint64_t Address,
197471928e68SAkira Hatanaka                                   const void *Decoder) {
197571928e68SAkira Hatanaka   // First we need to grab the pos(lsb) from MCInst.
197671928e68SAkira Hatanaka   int Pos = Inst.getOperand(2).getImm();
197771928e68SAkira Hatanaka   int Size = (int) Insn - Pos + 1;
1978e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(SignExtend32<16>(Size)));
197971928e68SAkira Hatanaka   return MCDisassembler::Success;
198071928e68SAkira Hatanaka }
198171928e68SAkira Hatanaka 
1982b59e1a41SDaniel Sanders static DecodeStatus DecodeSimm19Lsl2(MCInst &Inst, unsigned Insn,
1983b59e1a41SDaniel Sanders                                      uint64_t Address, const void *Decoder) {
1984e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(SignExtend32<19>(Insn) * 4));
1985b59e1a41SDaniel Sanders   return MCDisassembler::Success;
1986b59e1a41SDaniel Sanders }
19872855142aSZoran Jovanovic 
19882855142aSZoran Jovanovic static DecodeStatus DecodeSimm18Lsl3(MCInst &Inst, unsigned Insn,
19892855142aSZoran Jovanovic                                      uint64_t Address, const void *Decoder) {
1990e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(SignExtend32<18>(Insn) * 8));
19912855142aSZoran Jovanovic   return MCDisassembler::Success;
19922855142aSZoran Jovanovic }
1993a4c4b5fcSZoran Jovanovic 
1994b682ddf3SVladimir Medic static DecodeStatus DecodeSimm9SP(MCInst &Inst, unsigned Insn,
1995b682ddf3SVladimir Medic                                   uint64_t Address, const void *Decoder) {
1996b682ddf3SVladimir Medic   int32_t DecodedValue;
1997b682ddf3SVladimir Medic   switch (Insn) {
1998b682ddf3SVladimir Medic   case 0: DecodedValue = 256; break;
1999b682ddf3SVladimir Medic   case 1: DecodedValue = 257; break;
2000b682ddf3SVladimir Medic   case 510: DecodedValue = -258; break;
2001b682ddf3SVladimir Medic   case 511: DecodedValue = -257; break;
2002b682ddf3SVladimir Medic   default: DecodedValue = SignExtend32<9>(Insn); break;
2003b682ddf3SVladimir Medic   }
2004e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(DecodedValue * 4));
2005b682ddf3SVladimir Medic   return MCDisassembler::Success;
2006b682ddf3SVladimir Medic }
2007b682ddf3SVladimir Medic 
2008b682ddf3SVladimir Medic static DecodeStatus DecodeANDI16Imm(MCInst &Inst, unsigned Insn,
2009b682ddf3SVladimir Medic                                     uint64_t Address, const void *Decoder) {
2010b682ddf3SVladimir Medic   // Insn must be >= 0, since it is unsigned that condition is always true.
2011b682ddf3SVladimir Medic   assert(Insn < 16);
2012b682ddf3SVladimir Medic   int32_t DecodedValues[] = {128, 1, 2, 3, 4, 7, 8, 15, 16, 31, 32, 63, 64,
2013b682ddf3SVladimir Medic                              255, 32768, 65535};
2014e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(DecodedValues[Insn]));
2015b682ddf3SVladimir Medic   return MCDisassembler::Success;
2016b682ddf3SVladimir Medic }
2017b682ddf3SVladimir Medic 
2018a4c4b5fcSZoran Jovanovic static DecodeStatus DecodeRegListOperand(MCInst &Inst,
2019a4c4b5fcSZoran Jovanovic                                          unsigned Insn,
2020a4c4b5fcSZoran Jovanovic                                          uint64_t Address,
2021a4c4b5fcSZoran Jovanovic                                          const void *Decoder) {
2022a4c4b5fcSZoran Jovanovic   unsigned Regs[] = {Mips::S0, Mips::S1, Mips::S2, Mips::S3, Mips::S4, Mips::S5,
2023dc4b8c27SZoran Jovanovic                      Mips::S6, Mips::S7, Mips::FP};
2024a4c4b5fcSZoran Jovanovic   unsigned RegNum;
2025a4c4b5fcSZoran Jovanovic 
2026a4c4b5fcSZoran Jovanovic   unsigned RegLst = fieldFromInstruction(Insn, 21, 5);
2027df19a5e6SDaniel Sanders 
2028a4c4b5fcSZoran Jovanovic   // Empty register lists are not allowed.
2029a4c4b5fcSZoran Jovanovic   if (RegLst == 0)
2030a4c4b5fcSZoran Jovanovic     return MCDisassembler::Fail;
2031a4c4b5fcSZoran Jovanovic 
2032a4c4b5fcSZoran Jovanovic   RegNum = RegLst & 0xf;
2033df19a5e6SDaniel Sanders 
2034df19a5e6SDaniel Sanders   // RegLst values 10-15, and 26-31 are reserved.
2035df19a5e6SDaniel Sanders   if (RegNum > 9)
2036df19a5e6SDaniel Sanders     return MCDisassembler::Fail;
2037df19a5e6SDaniel Sanders 
2038a4c4b5fcSZoran Jovanovic   for (unsigned i = 0; i < RegNum; i++)
2039e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Regs[i]));
2040a4c4b5fcSZoran Jovanovic 
2041a4c4b5fcSZoran Jovanovic   if (RegLst & 0x10)
2042e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::RA));
2043a4c4b5fcSZoran Jovanovic 
2044a4c4b5fcSZoran Jovanovic   return MCDisassembler::Success;
2045a4c4b5fcSZoran Jovanovic }
2046f9a02500SZoran Jovanovic 
2047f9a02500SZoran Jovanovic static DecodeStatus DecodeRegListOperand16(MCInst &Inst, unsigned Insn,
2048f9a02500SZoran Jovanovic                                            uint64_t Address,
2049f9a02500SZoran Jovanovic                                            const void *Decoder) {
2050f9a02500SZoran Jovanovic   unsigned Regs[] = {Mips::S0, Mips::S1, Mips::S2, Mips::S3};
2051797c2aecSZlatko Buljan   unsigned RegLst;
2052797c2aecSZlatko Buljan   switch(Inst.getOpcode()) {
2053797c2aecSZlatko Buljan   default:
2054797c2aecSZlatko Buljan     RegLst = fieldFromInstruction(Insn, 4, 2);
2055797c2aecSZlatko Buljan     break;
2056797c2aecSZlatko Buljan   case Mips::LWM16_MMR6:
2057797c2aecSZlatko Buljan   case Mips::SWM16_MMR6:
2058797c2aecSZlatko Buljan     RegLst = fieldFromInstruction(Insn, 8, 2);
2059797c2aecSZlatko Buljan     break;
2060797c2aecSZlatko Buljan   }
2061d68d424aSJozef Kolek   unsigned RegNum = RegLst & 0x3;
2062f9a02500SZoran Jovanovic 
2063d68d424aSJozef Kolek   for (unsigned i = 0; i <= RegNum; i++)
2064e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Regs[i]));
2065f9a02500SZoran Jovanovic 
2066e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Mips::RA));
2067f9a02500SZoran Jovanovic 
2068f9a02500SZoran Jovanovic   return MCDisassembler::Success;
2069f9a02500SZoran Jovanovic }
20702c6d7320SJozef Kolek 
207141688679SZoran Jovanovic static DecodeStatus DecodeMovePRegPair(MCInst &Inst, unsigned Insn,
207241688679SZoran Jovanovic                                        uint64_t Address, const void *Decoder) {
207341688679SZoran Jovanovic 
207441688679SZoran Jovanovic   unsigned RegPair = fieldFromInstruction(Insn, 7, 3);
207541688679SZoran Jovanovic 
207641688679SZoran Jovanovic   switch (RegPair) {
207741688679SZoran Jovanovic   default:
207841688679SZoran Jovanovic     return MCDisassembler::Fail;
207941688679SZoran Jovanovic   case 0:
2080e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A1));
2081e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A2));
208241688679SZoran Jovanovic     break;
208341688679SZoran Jovanovic   case 1:
2084e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A1));
2085e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A3));
208641688679SZoran Jovanovic     break;
208741688679SZoran Jovanovic   case 2:
2088e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A2));
2089e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A3));
209041688679SZoran Jovanovic     break;
209141688679SZoran Jovanovic   case 3:
2092e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A0));
2093e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::S5));
209441688679SZoran Jovanovic     break;
209541688679SZoran Jovanovic   case 4:
2096e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A0));
2097e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::S6));
209841688679SZoran Jovanovic     break;
209941688679SZoran Jovanovic   case 5:
2100e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A0));
2101e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A1));
210241688679SZoran Jovanovic     break;
210341688679SZoran Jovanovic   case 6:
2104e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A0));
2105e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A2));
210641688679SZoran Jovanovic     break;
210741688679SZoran Jovanovic   case 7:
2108e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A0));
2109e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A3));
211041688679SZoran Jovanovic     break;
211141688679SZoran Jovanovic   }
211241688679SZoran Jovanovic 
211341688679SZoran Jovanovic   return MCDisassembler::Success;
211441688679SZoran Jovanovic }
211541688679SZoran Jovanovic 
21162c6d7320SJozef Kolek static DecodeStatus DecodeSimm23Lsl2(MCInst &Inst, unsigned Insn,
21172c6d7320SJozef Kolek                                      uint64_t Address, const void *Decoder) {
21186499b5f0SJustin Bogner   Inst.addOperand(MCOperand::createImm(SignExtend32<25>(Insn << 2)));
21192c6d7320SJozef Kolek   return MCDisassembler::Success;
21202c6d7320SJozef Kolek }
2121fdbd0a37SZoran Jovanovic 
2122fdbd0a37SZoran Jovanovic template <typename InsnType>
2123fdbd0a37SZoran Jovanovic static DecodeStatus DecodeBgtzGroupBranchMMR6(MCInst &MI, InsnType insn,
2124fdbd0a37SZoran Jovanovic   uint64_t Address,
2125fdbd0a37SZoran Jovanovic   const void *Decoder) {
2126fdbd0a37SZoran Jovanovic   // We have:
2127fdbd0a37SZoran Jovanovic   //    0b000111 ttttt sssss iiiiiiiiiiiiiiii
2128fdbd0a37SZoran Jovanovic   //      Invalid      if rt == 0
2129fdbd0a37SZoran Jovanovic   //      BGTZALC_MMR6 if rs == 0 && rt != 0
2130fdbd0a37SZoran Jovanovic   //      BLTZALC_MMR6 if rs != 0 && rs == rt
2131fdbd0a37SZoran Jovanovic   //      BLTUC_MMR6   if rs != 0 && rs != rt
2132fdbd0a37SZoran Jovanovic 
2133fdbd0a37SZoran Jovanovic   InsnType Rt = fieldFromInstruction(insn, 21, 5);
2134fdbd0a37SZoran Jovanovic   InsnType Rs = fieldFromInstruction(insn, 16, 5);
2135fdbd0a37SZoran Jovanovic   InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2;
2136fdbd0a37SZoran Jovanovic   bool HasRs = false;
2137fdbd0a37SZoran Jovanovic   bool HasRt = false;
2138fdbd0a37SZoran Jovanovic 
2139fdbd0a37SZoran Jovanovic   if (Rt == 0)
2140fdbd0a37SZoran Jovanovic     return MCDisassembler::Fail;
2141fdbd0a37SZoran Jovanovic   else if (Rs == 0) {
2142fdbd0a37SZoran Jovanovic     MI.setOpcode(Mips::BGTZALC_MMR6);
2143fdbd0a37SZoran Jovanovic     HasRt = true;
2144fdbd0a37SZoran Jovanovic   }
2145fdbd0a37SZoran Jovanovic   else if (Rs == Rt) {
2146fdbd0a37SZoran Jovanovic     MI.setOpcode(Mips::BLTZALC_MMR6);
2147fdbd0a37SZoran Jovanovic     HasRs = true;
2148fdbd0a37SZoran Jovanovic   }
2149fdbd0a37SZoran Jovanovic   else {
2150fdbd0a37SZoran Jovanovic     MI.setOpcode(Mips::BLTUC_MMR6);
2151fdbd0a37SZoran Jovanovic     HasRs = true;
2152fdbd0a37SZoran Jovanovic     HasRt = true;
2153fdbd0a37SZoran Jovanovic   }
2154fdbd0a37SZoran Jovanovic 
2155fdbd0a37SZoran Jovanovic   if (HasRs)
2156fdbd0a37SZoran Jovanovic     MI.addOperand(
2157fdbd0a37SZoran Jovanovic     MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rs)));
2158fdbd0a37SZoran Jovanovic 
2159fdbd0a37SZoran Jovanovic   if (HasRt)
2160fdbd0a37SZoran Jovanovic     MI.addOperand(
2161fdbd0a37SZoran Jovanovic     MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rt)));
2162fdbd0a37SZoran Jovanovic 
2163fdbd0a37SZoran Jovanovic   MI.addOperand(MCOperand::createImm(Imm));
2164fdbd0a37SZoran Jovanovic 
2165fdbd0a37SZoran Jovanovic   return MCDisassembler::Success;
2166fdbd0a37SZoran Jovanovic }
2167fdbd0a37SZoran Jovanovic 
2168fdbd0a37SZoran Jovanovic template <typename InsnType>
2169fdbd0a37SZoran Jovanovic static DecodeStatus DecodeBlezGroupBranchMMR6(MCInst &MI, InsnType insn,
2170fdbd0a37SZoran Jovanovic   uint64_t Address,
2171fdbd0a37SZoran Jovanovic   const void *Decoder) {
2172fdbd0a37SZoran Jovanovic   // We have:
2173fdbd0a37SZoran Jovanovic   //    0b000110 ttttt sssss iiiiiiiiiiiiiiii
2174fdbd0a37SZoran Jovanovic   //      Invalid        if rs == 0
2175fdbd0a37SZoran Jovanovic   //      BLEZALC_MMR6   if rs == 0  && rt != 0
2176fdbd0a37SZoran Jovanovic   //      BGEZALC_MMR6   if rs == rt && rt != 0
2177fdbd0a37SZoran Jovanovic   //      BGEUC_MMR6     if rs != rt && rs != 0  && rt != 0
2178fdbd0a37SZoran Jovanovic 
2179fdbd0a37SZoran Jovanovic   InsnType Rt = fieldFromInstruction(insn, 21, 5);
2180fdbd0a37SZoran Jovanovic   InsnType Rs = fieldFromInstruction(insn, 16, 5);
2181fdbd0a37SZoran Jovanovic   InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2;
2182fdbd0a37SZoran Jovanovic   bool HasRs = false;
2183fdbd0a37SZoran Jovanovic 
2184fdbd0a37SZoran Jovanovic   if (Rt == 0)
2185fdbd0a37SZoran Jovanovic     return MCDisassembler::Fail;
2186fdbd0a37SZoran Jovanovic   else if (Rs == 0)
2187fdbd0a37SZoran Jovanovic     MI.setOpcode(Mips::BLEZALC_MMR6);
2188fdbd0a37SZoran Jovanovic   else if (Rs == Rt)
2189fdbd0a37SZoran Jovanovic     MI.setOpcode(Mips::BGEZALC_MMR6);
2190fdbd0a37SZoran Jovanovic   else {
2191fdbd0a37SZoran Jovanovic     HasRs = true;
2192fdbd0a37SZoran Jovanovic     MI.setOpcode(Mips::BGEUC_MMR6);
2193fdbd0a37SZoran Jovanovic   }
2194fdbd0a37SZoran Jovanovic 
2195fdbd0a37SZoran Jovanovic   if (HasRs)
2196fdbd0a37SZoran Jovanovic     MI.addOperand(
2197fdbd0a37SZoran Jovanovic     MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rs)));
2198fdbd0a37SZoran Jovanovic   MI.addOperand(
2199fdbd0a37SZoran Jovanovic     MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rt)));
2200fdbd0a37SZoran Jovanovic 
2201fdbd0a37SZoran Jovanovic   MI.addOperand(MCOperand::createImm(Imm));
2202fdbd0a37SZoran Jovanovic 
2203fdbd0a37SZoran Jovanovic   return MCDisassembler::Success;
2204fdbd0a37SZoran Jovanovic }
2205