1926883e1SEugene Zelenko //===- MipsDisassembler.cpp - Disassembler for Mips -----------------------===//
271928e68SAkira Hatanaka //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
671928e68SAkira Hatanaka //
771928e68SAkira Hatanaka //===----------------------------------------------------------------------===//
871928e68SAkira Hatanaka //
971928e68SAkira Hatanaka // This file is part of the Mips Disassembler.
1071928e68SAkira Hatanaka //
1171928e68SAkira Hatanaka //===----------------------------------------------------------------------===//
1271928e68SAkira Hatanaka 
1379220eaeSEugene Zelenko #include "MCTargetDesc/MipsMCTargetDesc.h"
1471928e68SAkira Hatanaka #include "Mips.h"
15313b7815SRichard Trieu #include "TargetInfo/MipsTargetInfo.h"
16926883e1SEugene Zelenko #include "llvm/ADT/ArrayRef.h"
17a1bc0f56SLang Hames #include "llvm/MC/MCContext.h"
18*c644488aSSheng #include "llvm/MC/MCDecoderOps.h"
19f57c1977SBenjamin Kramer #include "llvm/MC/MCDisassembler/MCDisassembler.h"
20ed0881b2SChandler Carruth #include "llvm/MC/MCInst.h"
21926883e1SEugene Zelenko #include "llvm/MC/MCRegisterInfo.h"
226bda14b3SChandler Carruth #include "llvm/MC/MCSubtargetInfo.h"
2389b57061SReid Kleckner #include "llvm/MC/TargetRegistry.h"
24926883e1SEugene Zelenko #include "llvm/Support/Compiler.h"
25926883e1SEugene Zelenko #include "llvm/Support/Debug.h"
26926883e1SEugene Zelenko #include "llvm/Support/ErrorHandling.h"
27ed0881b2SChandler Carruth #include "llvm/Support/MathExtras.h"
286bda14b3SChandler Carruth #include "llvm/Support/raw_ostream.h"
29926883e1SEugene Zelenko #include <cassert>
30926883e1SEugene Zelenko #include <cstdint>
3171928e68SAkira Hatanaka 
3271928e68SAkira Hatanaka using namespace llvm;
3371928e68SAkira Hatanaka 
34e96dd897SChandler Carruth #define DEBUG_TYPE "mips-disassembler"
35e96dd897SChandler Carruth 
3679220eaeSEugene Zelenko using DecodeStatus = MCDisassembler::DecodeStatus;
3771928e68SAkira Hatanaka 
38cb3e98cfSBenjamin Kramer namespace {
39cb3e98cfSBenjamin Kramer 
40a19216c8SDaniel Sanders class MipsDisassembler : public MCDisassembler {
41dde3d582SVladimir Medic   bool IsMicroMips;
42a19216c8SDaniel Sanders   bool IsBigEndian;
43926883e1SEugene Zelenko 
449bf2b567SAkira Hatanaka public:
MipsDisassembler(const MCSubtargetInfo & STI,MCContext & Ctx,bool IsBigEndian)45a19216c8SDaniel Sanders   MipsDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx, bool IsBigEndian)
46a19216c8SDaniel Sanders       : MCDisassembler(STI, Ctx),
47db0712f9SMichael Kuperstein         IsMicroMips(STI.getFeatureBits()[Mips::FeatureMicroMips]),
48a19216c8SDaniel Sanders         IsBigEndian(IsBigEndian) {}
4971928e68SAkira Hatanaka 
hasMips2() const504fbf76f7SSimon Dardis   bool hasMips2() const { return STI.getFeatureBits()[Mips::FeatureMips2]; }
hasMips3() const51db0712f9SMichael Kuperstein   bool hasMips3() const { return STI.getFeatureBits()[Mips::FeatureMips3]; }
hasMips32() const52db0712f9SMichael Kuperstein   bool hasMips32() const { return STI.getFeatureBits()[Mips::FeatureMips32]; }
53926883e1SEugene Zelenko 
hasMips32r6() const54c171f65aSDaniel Sanders   bool hasMips32r6() const {
55db0712f9SMichael Kuperstein     return STI.getFeatureBits()[Mips::FeatureMips32r6];
565c582b2fSDaniel Sanders   }
57926883e1SEugene Zelenko 
isFP64() const586221be8eSZlatko Buljan   bool isFP64() const { return STI.getFeatureBits()[Mips::FeatureFP64Bit]; }
595c582b2fSDaniel Sanders 
isGP64() const60db0712f9SMichael Kuperstein   bool isGP64() const { return STI.getFeatureBits()[Mips::FeatureGP64Bit]; }
610fa60416SDaniel Sanders 
isPTR64() const624fbf76f7SSimon Dardis   bool isPTR64() const { return STI.getFeatureBits()[Mips::FeaturePTR64Bit]; }
634fbf76f7SSimon Dardis 
hasCnMips() const643adf9b8dSKai Nacke   bool hasCnMips() const { return STI.getFeatureBits()[Mips::FeatureCnMips]; }
653adf9b8dSKai Nacke 
hasCnMipsP() const667bed381eSSimon Atanasyan   bool hasCnMipsP() const { return STI.getFeatureBits()[Mips::FeatureCnMipsP]; }
677bed381eSSimon Atanasyan 
hasCOP3() const68c171f65aSDaniel Sanders   bool hasCOP3() const {
69c171f65aSDaniel Sanders     // Only present in MIPS-I and MIPS-II
70c171f65aSDaniel Sanders     return !hasMips32() && !hasMips3();
71c171f65aSDaniel Sanders   }
72c171f65aSDaniel Sanders 
734aa6bea7SRafael Espindola   DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
747fc5b874SRafael Espindola                               ArrayRef<uint8_t> Bytes, uint64_t Address,
754aa6bea7SRafael Espindola                               raw_ostream &CStream) const override;
7671928e68SAkira Hatanaka };
7771928e68SAkira Hatanaka 
78cb3e98cfSBenjamin Kramer } // end anonymous namespace
79cb3e98cfSBenjamin Kramer 
8071928e68SAkira Hatanaka // Forward declare these because the autogenerated code will reference them.
8171928e68SAkira Hatanaka // Definitions are further down.
824ae9745aSMaksim Panchenko static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst, unsigned RegNo,
8371928e68SAkira Hatanaka                                              uint64_t Address,
844ae9745aSMaksim Panchenko                                              const MCDisassembler *Decoder);
8571928e68SAkira Hatanaka 
864ae9745aSMaksim Panchenko static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst, unsigned RegNo,
87ec8a5490SReed Kotler                                                  uint64_t Address,
884ae9745aSMaksim Panchenko                                                  const MCDisassembler *Decoder);
89ec8a5490SReed Kotler 
904ae9745aSMaksim Panchenko static DecodeStatus DecodeGPRMM16RegisterClass(MCInst &Inst, unsigned RegNo,
91b0852e54SZoran Jovanovic                                                uint64_t Address,
924ae9745aSMaksim Panchenko                                                const MCDisassembler *Decoder);
93b0852e54SZoran Jovanovic 
944ae9745aSMaksim Panchenko static DecodeStatus
954ae9745aSMaksim Panchenko DecodeGPRMM16ZeroRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address,
964ae9745aSMaksim Panchenko                                const MCDisassembler *Decoder);
971904fa21SJozef Kolek 
984ae9745aSMaksim Panchenko static DecodeStatus
994ae9745aSMaksim Panchenko DecodeGPRMM16MovePRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address,
1004ae9745aSMaksim Panchenko                                 const MCDisassembler *Decoder);
10141688679SZoran Jovanovic 
1024ae9745aSMaksim Panchenko static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst, unsigned RegNo,
10371928e68SAkira Hatanaka                                              uint64_t Address,
1044ae9745aSMaksim Panchenko                                              const MCDisassembler *Decoder);
10571928e68SAkira Hatanaka 
1064ae9745aSMaksim Panchenko static DecodeStatus DecodePtrRegisterClass(MCInst &Inst, unsigned Insn,
1079bfa2e2eSAkira Hatanaka                                            uint64_t Address,
1084ae9745aSMaksim Panchenko                                            const MCDisassembler *Decoder);
1099bfa2e2eSAkira Hatanaka 
1104ae9745aSMaksim Panchenko static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst, unsigned RegNo,
111ecabd1a5SAkira Hatanaka                                             uint64_t Address,
1124ae9745aSMaksim Panchenko                                             const MCDisassembler *Decoder);
113ecabd1a5SAkira Hatanaka 
1144ae9745aSMaksim Panchenko static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst, unsigned RegNo,
11571928e68SAkira Hatanaka                                              uint64_t Address,
1164ae9745aSMaksim Panchenko                                              const MCDisassembler *Decoder);
11771928e68SAkira Hatanaka 
1184ae9745aSMaksim Panchenko static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst, unsigned RegNo,
11971928e68SAkira Hatanaka                                              uint64_t Address,
1204ae9745aSMaksim Panchenko                                              const MCDisassembler *Decoder);
12171928e68SAkira Hatanaka 
1224ae9745aSMaksim Panchenko static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst, unsigned RegNo,
12371928e68SAkira Hatanaka                                            uint64_t Address,
1244ae9745aSMaksim Panchenko                                            const MCDisassembler *Decoder);
12571928e68SAkira Hatanaka 
1264ae9745aSMaksim Panchenko static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst, unsigned RegNo,
1271fb1b8b8SAkira Hatanaka                                            uint64_t Address,
1284ae9745aSMaksim Panchenko                                            const MCDisassembler *Decoder);
1291fb1b8b8SAkira Hatanaka 
13036901dd1SVasileios Kalintiris static DecodeStatus DecodeFGRCCRegisterClass(MCInst &Inst, unsigned RegNo,
1310fa60416SDaniel Sanders                                              uint64_t Address,
1324ae9745aSMaksim Panchenko                                              const MCDisassembler *Decoder);
1330fa60416SDaniel Sanders 
1344ae9745aSMaksim Panchenko static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst, unsigned Insn,
13571928e68SAkira Hatanaka                                               uint64_t Address,
1364ae9745aSMaksim Panchenko                                               const MCDisassembler *Decoder);
13771928e68SAkira Hatanaka 
1384ae9745aSMaksim Panchenko static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst, unsigned RegNo,
13971928e68SAkira Hatanaka                                               uint64_t Address,
1404ae9745aSMaksim Panchenko                                               const MCDisassembler *Decoder);
14171928e68SAkira Hatanaka 
1424ae9745aSMaksim Panchenko static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst, unsigned RegNo,
143ecabd1a5SAkira Hatanaka                                                 uint64_t Address,
1444ae9745aSMaksim Panchenko                                                 const MCDisassembler *Decoder);
145ecabd1a5SAkira Hatanaka 
1464ae9745aSMaksim Panchenko static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst, unsigned RegNo,
14759bfaf77SAkira Hatanaka                                                uint64_t Address,
1484ae9745aSMaksim Panchenko                                                const MCDisassembler *Decoder);
14959bfaf77SAkira Hatanaka 
1504ae9745aSMaksim Panchenko static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst, unsigned RegNo,
15159bfaf77SAkira Hatanaka                                                uint64_t Address,
1524ae9745aSMaksim Panchenko                                                const MCDisassembler *Decoder);
15359bfaf77SAkira Hatanaka 
1544ae9745aSMaksim Panchenko static DecodeStatus DecodeMSA128BRegisterClass(MCInst &Inst, unsigned RegNo,
1553eb663b0SJack Carter                                                uint64_t Address,
1564ae9745aSMaksim Panchenko                                                const MCDisassembler *Decoder);
1573eb663b0SJack Carter 
1584ae9745aSMaksim Panchenko static DecodeStatus DecodeMSA128HRegisterClass(MCInst &Inst, unsigned RegNo,
1595dc8ac92SJack Carter                                                uint64_t Address,
1604ae9745aSMaksim Panchenko                                                const MCDisassembler *Decoder);
1615dc8ac92SJack Carter 
1624ae9745aSMaksim Panchenko static DecodeStatus DecodeMSA128WRegisterClass(MCInst &Inst, unsigned RegNo,
1635dc8ac92SJack Carter                                                uint64_t Address,
1644ae9745aSMaksim Panchenko                                                const MCDisassembler *Decoder);
1655dc8ac92SJack Carter 
1664ae9745aSMaksim Panchenko static DecodeStatus DecodeMSA128DRegisterClass(MCInst &Inst, unsigned RegNo,
1675dc8ac92SJack Carter                                                uint64_t Address,
1684ae9745aSMaksim Panchenko                                                const MCDisassembler *Decoder);
1695dc8ac92SJack Carter 
1704ae9745aSMaksim Panchenko static DecodeStatus DecodeMSACtrlRegisterClass(MCInst &Inst, unsigned RegNo,
171a591fdc6SMatheus Almeida                                                uint64_t Address,
1724ae9745aSMaksim Panchenko                                                const MCDisassembler *Decoder);
173a591fdc6SMatheus Almeida 
1744ae9745aSMaksim Panchenko static DecodeStatus DecodeCOP0RegisterClass(MCInst &Inst, unsigned RegNo,
175a3134faeSDaniel Sanders                                             uint64_t Address,
1764ae9745aSMaksim Panchenko                                             const MCDisassembler *Decoder);
177a3134faeSDaniel Sanders 
1784ae9745aSMaksim Panchenko static DecodeStatus DecodeCOP2RegisterClass(MCInst &Inst, unsigned RegNo,
1792a83d680SDaniel Sanders                                             uint64_t Address,
1804ae9745aSMaksim Panchenko                                             const MCDisassembler *Decoder);
1812a83d680SDaniel Sanders 
1824ae9745aSMaksim Panchenko static DecodeStatus DecodeBranchTarget(MCInst &Inst, unsigned Offset,
18371928e68SAkira Hatanaka                                        uint64_t Address,
1844ae9745aSMaksim Panchenko                                        const MCDisassembler *Decoder);
18571928e68SAkira Hatanaka 
1864ae9745aSMaksim Panchenko static DecodeStatus DecodeBranchTarget1SImm16(MCInst &Inst, unsigned Offset,
1876f09cdfdSHrvoje Varga                                               uint64_t Address,
1884ae9745aSMaksim Panchenko                                               const MCDisassembler *Decoder);
1896f09cdfdSHrvoje Varga 
1904ae9745aSMaksim Panchenko static DecodeStatus DecodeJumpTarget(MCInst &Inst, unsigned Insn,
19171928e68SAkira Hatanaka                                      uint64_t Address,
1924ae9745aSMaksim Panchenko                                      const MCDisassembler *Decoder);
19371928e68SAkira Hatanaka 
1944ae9745aSMaksim Panchenko static DecodeStatus DecodeBranchTarget21(MCInst &Inst, unsigned Offset,
1953c8869dcSZoran Jovanovic                                          uint64_t Address,
1964ae9745aSMaksim Panchenko                                          const MCDisassembler *Decoder);
1973c8869dcSZoran Jovanovic 
1984ae9745aSMaksim Panchenko static DecodeStatus DecodeBranchTarget21MM(MCInst &Inst, unsigned Offset,
19984e4d59eSZoran Jovanovic                                            uint64_t Address,
2004ae9745aSMaksim Panchenko                                            const MCDisassembler *Decoder);
20184e4d59eSZoran Jovanovic 
2024ae9745aSMaksim Panchenko static DecodeStatus DecodeBranchTarget26(MCInst &Inst, unsigned Offset,
2033c8869dcSZoran Jovanovic                                          uint64_t Address,
2044ae9745aSMaksim Panchenko                                          const MCDisassembler *Decoder);
2053c8869dcSZoran Jovanovic 
2069761e96bSJozef Kolek // DecodeBranchTarget7MM - Decode microMIPS branch offset, which is
2079761e96bSJozef Kolek // shifted left by 1 bit.
2084ae9745aSMaksim Panchenko static DecodeStatus DecodeBranchTarget7MM(MCInst &Inst, unsigned Offset,
2099761e96bSJozef Kolek                                           uint64_t Address,
2104ae9745aSMaksim Panchenko                                           const MCDisassembler *Decoder);
2119761e96bSJozef Kolek 
2125cfebddeSJozef Kolek // DecodeBranchTarget10MM - Decode microMIPS branch offset, which is
2135cfebddeSJozef Kolek // shifted left by 1 bit.
2144ae9745aSMaksim Panchenko static DecodeStatus DecodeBranchTarget10MM(MCInst &Inst, unsigned Offset,
2155cfebddeSJozef Kolek                                            uint64_t Address,
2164ae9745aSMaksim Panchenko                                            const MCDisassembler *Decoder);
2175cfebddeSJozef Kolek 
2188a80aa76SZoran Jovanovic // DecodeBranchTargetMM - Decode microMIPS branch offset, which is
2198a80aa76SZoran Jovanovic // shifted left by 1 bit.
2204ae9745aSMaksim Panchenko static DecodeStatus DecodeBranchTargetMM(MCInst &Inst, unsigned Offset,
2218a80aa76SZoran Jovanovic                                          uint64_t Address,
2224ae9745aSMaksim Panchenko                                          const MCDisassembler *Decoder);
2238a80aa76SZoran Jovanovic 
224a887b361SZoran Jovanovic // DecodeBranchTarget26MM - Decode microMIPS branch offset, which is
225a887b361SZoran Jovanovic // shifted left by 1 bit.
2264ae9745aSMaksim Panchenko static DecodeStatus DecodeBranchTarget26MM(MCInst &Inst, unsigned Offset,
227a887b361SZoran Jovanovic                                            uint64_t Address,
2284ae9745aSMaksim Panchenko                                            const MCDisassembler *Decoder);
229a887b361SZoran Jovanovic 
230507e084aSZoran Jovanovic // DecodeJumpTargetMM - Decode microMIPS jump target, which is
231507e084aSZoran Jovanovic // shifted left by 1 bit.
2324ae9745aSMaksim Panchenko static DecodeStatus DecodeJumpTargetMM(MCInst &Inst, unsigned Insn,
233507e084aSZoran Jovanovic                                        uint64_t Address,
2344ae9745aSMaksim Panchenko                                        const MCDisassembler *Decoder);
235507e084aSZoran Jovanovic 
23656e4ea2bSSimon Atanasyan // DecodeJumpTargetXMM - Decode microMIPS jump and link exchange target,
23756e4ea2bSSimon Atanasyan // which is shifted left by 2 bit.
2384ae9745aSMaksim Panchenko static DecodeStatus DecodeJumpTargetXMM(MCInst &Inst, unsigned Insn,
23956e4ea2bSSimon Atanasyan                                         uint64_t Address,
2404ae9745aSMaksim Panchenko                                         const MCDisassembler *Decoder);
24156e4ea2bSSimon Atanasyan 
2424ae9745aSMaksim Panchenko static DecodeStatus DecodeMem(MCInst &Inst, unsigned Insn, uint64_t Address,
2434ae9745aSMaksim Panchenko                               const MCDisassembler *Decoder);
24471928e68SAkira Hatanaka 
2454ae9745aSMaksim Panchenko static DecodeStatus DecodeMemEVA(MCInst &Inst, unsigned Insn, uint64_t Address,
2464ae9745aSMaksim Panchenko                                  const MCDisassembler *Decoder);
247e4e83a7bSDaniel Sanders 
2484ae9745aSMaksim Panchenko static DecodeStatus DecodeLoadByte15(MCInst &Inst, unsigned Insn,
2493c88fbd3SHrvoje Varga                                      uint64_t Address,
2504ae9745aSMaksim Panchenko                                      const MCDisassembler *Decoder);
2513c88fbd3SHrvoje Varga 
25279220eaeSEugene Zelenko static DecodeStatus DecodeCacheOp(MCInst &Inst, unsigned Insn, uint64_t Address,
2534ae9745aSMaksim Panchenko                                   const MCDisassembler *Decoder);
25492db6b78SDaniel Sanders 
2554ae9745aSMaksim Panchenko static DecodeStatus DecodeCacheeOp_CacheOpR6(MCInst &Inst, unsigned Insn,
256df464ae2SVladimir Medic                                              uint64_t Address,
2574ae9745aSMaksim Panchenko                                              const MCDisassembler *Decoder);
258df464ae2SVladimir Medic 
2594ae9745aSMaksim Panchenko static DecodeStatus DecodeCacheOpMM(MCInst &Inst, unsigned Insn,
260ab6d1cceSJozef Kolek                                     uint64_t Address,
2614ae9745aSMaksim Panchenko                                     const MCDisassembler *Decoder);
262ab6d1cceSJozef Kolek 
2634ae9745aSMaksim Panchenko static DecodeStatus DecodePrefeOpMM(MCInst &Inst, unsigned Insn,
264d9790793SZoran Jovanovic                                     uint64_t Address,
2654ae9745aSMaksim Panchenko                                     const MCDisassembler *Decoder);
266d9790793SZoran Jovanovic 
2674ae9745aSMaksim Panchenko static DecodeStatus DecodeSyncI(MCInst &Inst, unsigned Insn, uint64_t Address,
2684ae9745aSMaksim Panchenko                                 const MCDisassembler *Decoder);
269b4484d62SDaniel Sanders 
2704ae9745aSMaksim Panchenko static DecodeStatus DecodeSyncI_MM(MCInst &Inst, unsigned Insn,
271eac9301cSSimon Dardis                                    uint64_t Address,
2724ae9745aSMaksim Panchenko                                    const MCDisassembler *Decoder);
273eac9301cSSimon Dardis 
2744ae9745aSMaksim Panchenko static DecodeStatus DecodeSynciR6(MCInst &Inst, unsigned Insn, uint64_t Address,
2754ae9745aSMaksim Panchenko                                   const MCDisassembler *Decoder);
27618148671SHrvoje Varga 
277fe0bf9f6SMatheus Almeida static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn,
278315e7ecaSJozef Kolek                                     uint64_t Address,
2794ae9745aSMaksim Panchenko                                     const MCDisassembler *Decoder);
280315e7ecaSJozef Kolek 
2814ae9745aSMaksim Panchenko static DecodeStatus DecodeMemMMImm4(MCInst &Inst, unsigned Insn,
28212c6982bSJozef Kolek                                     uint64_t Address,
2834ae9745aSMaksim Panchenko                                     const MCDisassembler *Decoder);
28412c6982bSJozef Kolek 
2854ae9745aSMaksim Panchenko static DecodeStatus DecodeMemMMSPImm5Lsl2(MCInst &Inst, unsigned Insn,
286e10a02ecSJozef Kolek                                           uint64_t Address,
2874ae9745aSMaksim Panchenko                                           const MCDisassembler *Decoder);
288e10a02ecSJozef Kolek 
2894ae9745aSMaksim Panchenko static DecodeStatus DecodeMemMMGPImm7Lsl2(MCInst &Inst, unsigned Insn,
290d68d424aSJozef Kolek                                           uint64_t Address,
2914ae9745aSMaksim Panchenko                                           const MCDisassembler *Decoder);
292d68d424aSJozef Kolek 
2934ae9745aSMaksim Panchenko static DecodeStatus DecodeMemMMReglistImm4Lsl2(MCInst &Inst, unsigned Insn,
294a6593ff6SZoran Jovanovic                                                uint64_t Address,
2954ae9745aSMaksim Panchenko                                                const MCDisassembler *Decoder);
296a6593ff6SZoran Jovanovic 
2974ae9745aSMaksim Panchenko static DecodeStatus DecodeMemMMImm9(MCInst &Inst, unsigned Insn,
298dde3d582SVladimir Medic                                     uint64_t Address,
2994ae9745aSMaksim Panchenko                                     const MCDisassembler *Decoder);
300dde3d582SVladimir Medic 
3014ae9745aSMaksim Panchenko static DecodeStatus DecodeMemMMImm12(MCInst &Inst, unsigned Insn,
302dde3d582SVladimir Medic                                      uint64_t Address,
3034ae9745aSMaksim Panchenko                                      const MCDisassembler *Decoder);
304dde3d582SVladimir Medic 
3054ae9745aSMaksim Panchenko static DecodeStatus DecodeMemMMImm16(MCInst &Inst, unsigned Insn,
30671928e68SAkira Hatanaka                                      uint64_t Address,
3074ae9745aSMaksim Panchenko                                      const MCDisassembler *Decoder);
3084ae9745aSMaksim Panchenko 
3094ae9745aSMaksim Panchenko static DecodeStatus DecodeFMem(MCInst &Inst, unsigned Insn, uint64_t Address,
3104ae9745aSMaksim Panchenko                                const MCDisassembler *Decoder);
31171928e68SAkira Hatanaka 
312cba9f80bSZlatko Buljan static DecodeStatus DecodeFMemMMR2(MCInst &Inst, unsigned Insn,
313cba9f80bSZlatko Buljan                                    uint64_t Address,
3144ae9745aSMaksim Panchenko                                    const MCDisassembler *Decoder);
315cba9f80bSZlatko Buljan 
31679220eaeSEugene Zelenko static DecodeStatus DecodeFMem2(MCInst &Inst, unsigned Insn, uint64_t Address,
3174ae9745aSMaksim Panchenko                                 const MCDisassembler *Decoder);
31892db6b78SDaniel Sanders 
31979220eaeSEugene Zelenko static DecodeStatus DecodeFMem3(MCInst &Inst, unsigned Insn, uint64_t Address,
3204ae9745aSMaksim Panchenko                                 const MCDisassembler *Decoder);
32192db6b78SDaniel Sanders 
322435cf8a4SVladimir Medic static DecodeStatus DecodeFMemCop2R6(MCInst &Inst, unsigned Insn,
3234ae9745aSMaksim Panchenko                                      uint64_t Address,
3244ae9745aSMaksim Panchenko                                      const MCDisassembler *Decoder);
325435cf8a4SVladimir Medic 
326cba9f80bSZlatko Buljan static DecodeStatus DecodeFMemCop2MMR6(MCInst &Inst, unsigned Insn,
327cba9f80bSZlatko Buljan                                        uint64_t Address,
3284ae9745aSMaksim Panchenko                                        const MCDisassembler *Decoder);
329cba9f80bSZlatko Buljan 
3304ae9745aSMaksim Panchenko static DecodeStatus DecodeSpecial3LlSc(MCInst &Inst, unsigned Insn,
3316a803f61SDaniel Sanders                                        uint64_t Address,
3324ae9745aSMaksim Panchenko                                        const MCDisassembler *Decoder);
3336a803f61SDaniel Sanders 
3344ae9745aSMaksim Panchenko static DecodeStatus DecodeAddiur2Simm7(MCInst &Inst, unsigned Value,
335aa2b9278SJozef Kolek                                        uint64_t Address,
3364ae9745aSMaksim Panchenko                                        const MCDisassembler *Decoder);
337aa2b9278SJozef Kolek 
3384ae9745aSMaksim Panchenko static DecodeStatus DecodeLi16Imm(MCInst &Inst, unsigned Value,
339aa2b9278SJozef Kolek                                   uint64_t Address,
3404ae9745aSMaksim Panchenko                                   const MCDisassembler *Decoder);
341aa2b9278SJozef Kolek 
3424ae9745aSMaksim Panchenko static DecodeStatus DecodePOOL16BEncodedField(MCInst &Inst, unsigned Value,
3436b28f09dSZoran Jovanovic                                               uint64_t Address,
3444ae9745aSMaksim Panchenko                                               const MCDisassembler *Decoder);
3456b28f09dSZoran Jovanovic 
34619b7f76aSDaniel Sanders template <unsigned Bits, int Offset, int Scale>
34719b7f76aSDaniel Sanders static DecodeStatus DecodeUImmWithOffsetAndScale(MCInst &Inst, unsigned Value,
34819b7f76aSDaniel Sanders                                                  uint64_t Address,
3494ae9745aSMaksim Panchenko                                                  const MCDisassembler *Decoder);
35019b7f76aSDaniel Sanders 
351ea4f653dSDaniel Sanders template <unsigned Bits, int Offset>
DecodeUImmWithOffset(MCInst & Inst,unsigned Value,uint64_t Address,const MCDisassembler * Decoder)352ea4f653dSDaniel Sanders static DecodeStatus DecodeUImmWithOffset(MCInst &Inst, unsigned Value,
35319b7f76aSDaniel Sanders                                          uint64_t Address,
3544ae9745aSMaksim Panchenko                                          const MCDisassembler *Decoder) {
35519b7f76aSDaniel Sanders   return DecodeUImmWithOffsetAndScale<Bits, Offset, 1>(Inst, Value, Address,
35619b7f76aSDaniel Sanders                                                        Decoder);
35719b7f76aSDaniel Sanders }
358779c5937SMatheus Almeida 
35997297770SDaniel Sanders template <unsigned Bits, int Offset = 0, int ScaleBy = 1>
36097297770SDaniel Sanders static DecodeStatus DecodeSImmWithOffsetAndScale(MCInst &Inst, unsigned Value,
36197297770SDaniel Sanders                                                  uint64_t Address,
3624ae9745aSMaksim Panchenko                                                  const MCDisassembler *Decoder);
36378e89020SDaniel Sanders 
3644ae9745aSMaksim Panchenko static DecodeStatus DecodeInsSize(MCInst &Inst, unsigned Insn, uint64_t Address,
3654ae9745aSMaksim Panchenko                                   const MCDisassembler *Decoder);
36671928e68SAkira Hatanaka 
367b59e1a41SDaniel Sanders static DecodeStatus DecodeSimm19Lsl2(MCInst &Inst, unsigned Insn,
3684ae9745aSMaksim Panchenko                                      uint64_t Address,
3694ae9745aSMaksim Panchenko                                      const MCDisassembler *Decoder);
370b59e1a41SDaniel Sanders 
3712855142aSZoran Jovanovic static DecodeStatus DecodeSimm18Lsl3(MCInst &Inst, unsigned Insn,
3724ae9745aSMaksim Panchenko                                      uint64_t Address,
3734ae9745aSMaksim Panchenko                                      const MCDisassembler *Decoder);
3742855142aSZoran Jovanovic 
3754ae9745aSMaksim Panchenko static DecodeStatus DecodeSimm9SP(MCInst &Inst, unsigned Insn, uint64_t Address,
3764ae9745aSMaksim Panchenko                                   const MCDisassembler *Decoder);
377b682ddf3SVladimir Medic 
378b682ddf3SVladimir Medic static DecodeStatus DecodeANDI16Imm(MCInst &Inst, unsigned Insn,
3794ae9745aSMaksim Panchenko                                     uint64_t Address,
3804ae9745aSMaksim Panchenko                                     const MCDisassembler *Decoder);
381b682ddf3SVladimir Medic 
3822c6d7320SJozef Kolek static DecodeStatus DecodeSimm23Lsl2(MCInst &Inst, unsigned Insn,
3834ae9745aSMaksim Panchenko                                      uint64_t Address,
3844ae9745aSMaksim Panchenko                                      const MCDisassembler *Decoder);
3852c6d7320SJozef Kolek 
386b50ccf8eSDaniel Sanders /// INSVE_[BHWD] have an implicit operand that the generated decoder doesn't
387b50ccf8eSDaniel Sanders /// handle.
388b50ccf8eSDaniel Sanders template <typename InsnType>
389b50ccf8eSDaniel Sanders static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address,
3904ae9745aSMaksim Panchenko                                    const MCDisassembler *Decoder);
3915c582b2fSDaniel Sanders 
3925c582b2fSDaniel Sanders template <typename InsnType>
3930bd82a96SSimon Atanasyan static DecodeStatus DecodeDAHIDATIMMR6(MCInst &MI, InsnType insn,
3944ae9745aSMaksim Panchenko                                        uint64_t Address,
3954ae9745aSMaksim Panchenko                                        const MCDisassembler *Decoder);
396cf060794SSimon Dardis 
397cf060794SSimon Dardis template <typename InsnType>
398cf060794SSimon Dardis static DecodeStatus DecodeDAHIDATI(MCInst &MI, InsnType insn, uint64_t Address,
3994ae9745aSMaksim Panchenko                                    const MCDisassembler *Decoder);
400cf060794SSimon Dardis 
401cf060794SSimon Dardis template <typename InsnType>
4024ae9745aSMaksim Panchenko static DecodeStatus DecodeAddiGroupBranch(MCInst &MI, InsnType insn,
4034ae9745aSMaksim Panchenko                                           uint64_t Address,
4044ae9745aSMaksim Panchenko                                           const MCDisassembler *Decoder);
4055c582b2fSDaniel Sanders 
4065c582b2fSDaniel Sanders template <typename InsnType>
4074ae9745aSMaksim Panchenko static DecodeStatus DecodePOP35GroupBranchMMR6(MCInst &MI, InsnType insn,
4084ae9745aSMaksim Panchenko                                                uint64_t Address,
4094ae9745aSMaksim Panchenko                                                const MCDisassembler *Decoder);
410c962c493SHrvoje Varga 
411c962c493SHrvoje Varga template <typename InsnType>
4124ae9745aSMaksim Panchenko static DecodeStatus DecodeDaddiGroupBranch(MCInst &MI, InsnType insn,
4134ae9745aSMaksim Panchenko                                            uint64_t Address,
4144ae9745aSMaksim Panchenko                                            const MCDisassembler *Decoder);
4155c582b2fSDaniel Sanders 
4165c582b2fSDaniel Sanders template <typename InsnType>
4174ae9745aSMaksim Panchenko static DecodeStatus DecodePOP37GroupBranchMMR6(MCInst &MI, InsnType insn,
4184ae9745aSMaksim Panchenko                                                uint64_t Address,
4194ae9745aSMaksim Panchenko                                                const MCDisassembler *Decoder);
420c962c493SHrvoje Varga 
421c962c493SHrvoje Varga template <typename InsnType>
4224ae9745aSMaksim Panchenko static DecodeStatus DecodePOP65GroupBranchMMR6(MCInst &MI, InsnType insn,
4234ae9745aSMaksim Panchenko                                                uint64_t Address,
4244ae9745aSMaksim Panchenko                                                const MCDisassembler *Decoder);
425f0ed16eaSHrvoje Varga 
426f0ed16eaSHrvoje Varga template <typename InsnType>
4274ae9745aSMaksim Panchenko static DecodeStatus DecodePOP75GroupBranchMMR6(MCInst &MI, InsnType insn,
4284ae9745aSMaksim Panchenko                                                uint64_t Address,
4294ae9745aSMaksim Panchenko                                                const MCDisassembler *Decoder);
430f0ed16eaSHrvoje Varga 
431f0ed16eaSHrvoje Varga template <typename InsnType>
4324ae9745aSMaksim Panchenko static DecodeStatus DecodeBlezlGroupBranch(MCInst &MI, InsnType insn,
4334ae9745aSMaksim Panchenko                                            uint64_t Address,
4344ae9745aSMaksim Panchenko                                            const MCDisassembler *Decoder);
4355c582b2fSDaniel Sanders 
4365c582b2fSDaniel Sanders template <typename InsnType>
4374ae9745aSMaksim Panchenko static DecodeStatus DecodeBgtzlGroupBranch(MCInst &MI, InsnType insn,
4384ae9745aSMaksim Panchenko                                            uint64_t Address,
4394ae9745aSMaksim Panchenko                                            const MCDisassembler *Decoder);
4405c582b2fSDaniel Sanders 
4415c582b2fSDaniel Sanders template <typename InsnType>
4424ae9745aSMaksim Panchenko static DecodeStatus DecodeBgtzGroupBranch(MCInst &MI, InsnType insn,
4434ae9745aSMaksim Panchenko                                           uint64_t Address,
4444ae9745aSMaksim Panchenko                                           const MCDisassembler *Decoder);
4455c582b2fSDaniel Sanders 
44628a0ca07SZoran Jovanovic template <typename InsnType>
4474ae9745aSMaksim Panchenko static DecodeStatus DecodeBlezGroupBranch(MCInst &MI, InsnType insn,
4484ae9745aSMaksim Panchenko                                           uint64_t Address,
4494ae9745aSMaksim Panchenko                                           const MCDisassembler *Decoder);
45028a0ca07SZoran Jovanovic 
451fdbd0a37SZoran Jovanovic template <typename InsnType>
4524ae9745aSMaksim Panchenko static DecodeStatus DecodeBgtzGroupBranchMMR6(MCInst &MI, InsnType insn,
4534ae9745aSMaksim Panchenko                                               uint64_t Address,
4544ae9745aSMaksim Panchenko                                               const MCDisassembler *Decoder);
455fdbd0a37SZoran Jovanovic 
456fdbd0a37SZoran Jovanovic template <typename InsnType>
4574ae9745aSMaksim Panchenko static DecodeStatus DecodeBlezGroupBranchMMR6(MCInst &MI, InsnType insn,
4584ae9745aSMaksim Panchenko                                               uint64_t Address,
4594ae9745aSMaksim Panchenko                                               const MCDisassembler *Decoder);
460fdbd0a37SZoran Jovanovic 
4616f83ae38SSimon Dardis template <typename InsnType>
4626f83ae38SSimon Dardis static DecodeStatus DecodeDINS(MCInst &MI, InsnType Insn, uint64_t Address,
4634ae9745aSMaksim Panchenko                                const MCDisassembler *Decoder);
4646f83ae38SSimon Dardis 
46555e44673SSimon Dardis template <typename InsnType>
46655e44673SSimon Dardis static DecodeStatus DecodeDEXT(MCInst &MI, InsnType Insn, uint64_t Address,
4674ae9745aSMaksim Panchenko                                const MCDisassembler *Decoder);
46855e44673SSimon Dardis 
4693408caf6SPetar Jovanovic template <typename InsnType>
4703408caf6SPetar Jovanovic static DecodeStatus DecodeCRC(MCInst &MI, InsnType Insn, uint64_t Address,
4714ae9745aSMaksim Panchenko                               const MCDisassembler *Decoder);
4723408caf6SPetar Jovanovic 
473a4c4b5fcSZoran Jovanovic static DecodeStatus DecodeRegListOperand(MCInst &Inst, unsigned Insn,
474a4c4b5fcSZoran Jovanovic                                          uint64_t Address,
4754ae9745aSMaksim Panchenko                                          const MCDisassembler *Decoder);
476a4c4b5fcSZoran Jovanovic 
477f9a02500SZoran Jovanovic static DecodeStatus DecodeRegListOperand16(MCInst &Inst, unsigned Insn,
478f9a02500SZoran Jovanovic                                            uint64_t Address,
4794ae9745aSMaksim Panchenko                                            const MCDisassembler *Decoder);
480f9a02500SZoran Jovanovic 
481169df4e2SSimon Dardis static DecodeStatus DecodeMovePRegPair(MCInst &Inst, unsigned RegPair,
48241688679SZoran Jovanovic                                        uint64_t Address,
4834ae9745aSMaksim Panchenko                                        const MCDisassembler *Decoder);
48441688679SZoran Jovanovic 
485852dd83bSSimon Atanasyan static DecodeStatus DecodeMovePOperands(MCInst &Inst, unsigned Insn,
4864ae9745aSMaksim Panchenko                                         uint64_t Address,
4874ae9745aSMaksim Panchenko                                         const MCDisassembler *Decoder);
488852dd83bSSimon Atanasyan 
createMipsDisassembler(const Target & T,const MCSubtargetInfo & STI,MCContext & Ctx)48971928e68SAkira Hatanaka static MCDisassembler *createMipsDisassembler(
49071928e68SAkira Hatanaka                        const Target &T,
491a1bc0f56SLang Hames                        const MCSubtargetInfo &STI,
492a1bc0f56SLang Hames                        MCContext &Ctx) {
493a1bc0f56SLang Hames   return new MipsDisassembler(STI, Ctx, true);
49471928e68SAkira Hatanaka }
49571928e68SAkira Hatanaka 
createMipselDisassembler(const Target & T,const MCSubtargetInfo & STI,MCContext & Ctx)49671928e68SAkira Hatanaka static MCDisassembler *createMipselDisassembler(
49771928e68SAkira Hatanaka                        const Target &T,
498a1bc0f56SLang Hames                        const MCSubtargetInfo &STI,
499a1bc0f56SLang Hames                        MCContext &Ctx) {
500a1bc0f56SLang Hames   return new MipsDisassembler(STI, Ctx, false);
50171928e68SAkira Hatanaka }
50271928e68SAkira Hatanaka 
LLVMInitializeMipsDisassembler()5030dbcb363STom Stellard extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeMipsDisassembler() {
50471928e68SAkira Hatanaka   // Register the disassembler.
505f42454b9SMehdi Amini   TargetRegistry::RegisterMCDisassembler(getTheMipsTarget(),
50671928e68SAkira Hatanaka                                          createMipsDisassembler);
507f42454b9SMehdi Amini   TargetRegistry::RegisterMCDisassembler(getTheMipselTarget(),
50871928e68SAkira Hatanaka                                          createMipselDisassembler);
509f42454b9SMehdi Amini   TargetRegistry::RegisterMCDisassembler(getTheMips64Target(),
510a19216c8SDaniel Sanders                                          createMipsDisassembler);
511f42454b9SMehdi Amini   TargetRegistry::RegisterMCDisassembler(getTheMips64elTarget(),
512a19216c8SDaniel Sanders                                          createMipselDisassembler);
51371928e68SAkira Hatanaka }
51471928e68SAkira Hatanaka 
51571928e68SAkira Hatanaka #include "MipsGenDisassemblerTables.inc"
51671928e68SAkira Hatanaka 
getReg(const MCDisassembler * D,unsigned RC,unsigned RegNo)5174ae9745aSMaksim Panchenko static unsigned getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo) {
5184ae9745aSMaksim Panchenko   const MCRegisterInfo *RegInfo = D->getContext().getRegisterInfo();
5195c582b2fSDaniel Sanders   return *(RegInfo->getRegClass(RC).begin() + RegNo);
5205c582b2fSDaniel Sanders }
5215c582b2fSDaniel Sanders 
522b50ccf8eSDaniel Sanders template <typename InsnType>
DecodeINSVE_DF(MCInst & MI,InsnType insn,uint64_t Address,const MCDisassembler * Decoder)523b50ccf8eSDaniel Sanders static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address,
5244ae9745aSMaksim Panchenko                                    const MCDisassembler *Decoder) {
5254ae9745aSMaksim Panchenko   using DecodeFN =
5264ae9745aSMaksim Panchenko       DecodeStatus (*)(MCInst &, unsigned, uint64_t, const MCDisassembler *);
52779220eaeSEugene Zelenko 
528b50ccf8eSDaniel Sanders   // The size of the n field depends on the element size
529b50ccf8eSDaniel Sanders   // The register class also depends on this.
530b50ccf8eSDaniel Sanders   InsnType tmp = fieldFromInstruction(insn, 17, 5);
531b50ccf8eSDaniel Sanders   unsigned NSize = 0;
532b50ccf8eSDaniel Sanders   DecodeFN RegDecoder = nullptr;
533b50ccf8eSDaniel Sanders   if ((tmp & 0x18) == 0x00) { // INSVE_B
534b50ccf8eSDaniel Sanders     NSize = 4;
535b50ccf8eSDaniel Sanders     RegDecoder = DecodeMSA128BRegisterClass;
536b50ccf8eSDaniel Sanders   } else if ((tmp & 0x1c) == 0x10) { // INSVE_H
537b50ccf8eSDaniel Sanders     NSize = 3;
538b50ccf8eSDaniel Sanders     RegDecoder = DecodeMSA128HRegisterClass;
539b50ccf8eSDaniel Sanders   } else if ((tmp & 0x1e) == 0x18) { // INSVE_W
540b50ccf8eSDaniel Sanders     NSize = 2;
541b50ccf8eSDaniel Sanders     RegDecoder = DecodeMSA128WRegisterClass;
542b50ccf8eSDaniel Sanders   } else if ((tmp & 0x1f) == 0x1c) { // INSVE_D
543b50ccf8eSDaniel Sanders     NSize = 1;
544b50ccf8eSDaniel Sanders     RegDecoder = DecodeMSA128DRegisterClass;
545b50ccf8eSDaniel Sanders   } else
546b50ccf8eSDaniel Sanders     llvm_unreachable("Invalid encoding");
547b50ccf8eSDaniel Sanders 
548b50ccf8eSDaniel Sanders   assert(NSize != 0 && RegDecoder != nullptr);
549b50ccf8eSDaniel Sanders 
550b50ccf8eSDaniel Sanders   // $wd
551b50ccf8eSDaniel Sanders   tmp = fieldFromInstruction(insn, 6, 5);
552b50ccf8eSDaniel Sanders   if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
553b50ccf8eSDaniel Sanders     return MCDisassembler::Fail;
554b50ccf8eSDaniel Sanders   // $wd_in
555b50ccf8eSDaniel Sanders   if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
556b50ccf8eSDaniel Sanders     return MCDisassembler::Fail;
557b50ccf8eSDaniel Sanders   // $n
558b50ccf8eSDaniel Sanders   tmp = fieldFromInstruction(insn, 16, NSize);
559e9119e41SJim Grosbach   MI.addOperand(MCOperand::createImm(tmp));
560b50ccf8eSDaniel Sanders   // $ws
561b50ccf8eSDaniel Sanders   tmp = fieldFromInstruction(insn, 11, 5);
562b50ccf8eSDaniel Sanders   if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
563b50ccf8eSDaniel Sanders     return MCDisassembler::Fail;
564b50ccf8eSDaniel Sanders   // $n2
565e9119e41SJim Grosbach   MI.addOperand(MCOperand::createImm(0));
566b50ccf8eSDaniel Sanders 
567b50ccf8eSDaniel Sanders   return MCDisassembler::Success;
568b50ccf8eSDaniel Sanders }
569b50ccf8eSDaniel Sanders 
5705c582b2fSDaniel Sanders template <typename InsnType>
DecodeDAHIDATIMMR6(MCInst & MI,InsnType insn,uint64_t Address,const MCDisassembler * Decoder)5710bd82a96SSimon Atanasyan static DecodeStatus DecodeDAHIDATIMMR6(MCInst &MI, InsnType insn,
5724ae9745aSMaksim Panchenko                                        uint64_t Address,
5734ae9745aSMaksim Panchenko                                        const MCDisassembler *Decoder) {
574b3fd189cSSimon Dardis   InsnType Rs = fieldFromInstruction(insn, 16, 5);
575cf060794SSimon Dardis   InsnType Imm = fieldFromInstruction(insn, 0, 16);
576cf060794SSimon Dardis   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID,
577b3fd189cSSimon Dardis                                        Rs)));
578cf060794SSimon Dardis   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID,
579b3fd189cSSimon Dardis                                        Rs)));
580cf060794SSimon Dardis   MI.addOperand(MCOperand::createImm(Imm));
581cf060794SSimon Dardis 
582cf060794SSimon Dardis   return MCDisassembler::Success;
583cf060794SSimon Dardis }
584cf060794SSimon Dardis 
585cf060794SSimon Dardis template <typename InsnType>
DecodeDAHIDATI(MCInst & MI,InsnType insn,uint64_t Address,const MCDisassembler * Decoder)586cf060794SSimon Dardis static DecodeStatus DecodeDAHIDATI(MCInst &MI, InsnType insn, uint64_t Address,
5874ae9745aSMaksim Panchenko                                    const MCDisassembler *Decoder) {
588b3fd189cSSimon Dardis   InsnType Rs = fieldFromInstruction(insn, 21, 5);
589cf060794SSimon Dardis   InsnType Imm = fieldFromInstruction(insn, 0, 16);
590cf060794SSimon Dardis   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID,
591b3fd189cSSimon Dardis                                        Rs)));
592cf060794SSimon Dardis   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID,
593b3fd189cSSimon Dardis                                        Rs)));
594cf060794SSimon Dardis   MI.addOperand(MCOperand::createImm(Imm));
595cf060794SSimon Dardis 
596cf060794SSimon Dardis   return MCDisassembler::Success;
597cf060794SSimon Dardis }
598cf060794SSimon Dardis 
599cf060794SSimon Dardis template <typename InsnType>
DecodeAddiGroupBranch(MCInst & MI,InsnType insn,uint64_t Address,const MCDisassembler * Decoder)6005c582b2fSDaniel Sanders static DecodeStatus DecodeAddiGroupBranch(MCInst &MI, InsnType insn,
6015c582b2fSDaniel Sanders                                           uint64_t Address,
6024ae9745aSMaksim Panchenko                                           const MCDisassembler *Decoder) {
6035c582b2fSDaniel Sanders   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
6045c582b2fSDaniel Sanders   // (otherwise we would have matched the ADDI instruction from the earlier
6055c582b2fSDaniel Sanders   // ISA's instead).
6065c582b2fSDaniel Sanders   //
6075c582b2fSDaniel Sanders   // We have:
6085c582b2fSDaniel Sanders   //    0b001000 sssss ttttt iiiiiiiiiiiiiiii
6095c582b2fSDaniel Sanders   //      BOVC if rs >= rt
6105c582b2fSDaniel Sanders   //      BEQZALC if rs == 0 && rt != 0
6115c582b2fSDaniel Sanders   //      BEQC if rs < rt && rs != 0
6125c582b2fSDaniel Sanders 
6135c582b2fSDaniel Sanders   InsnType Rs = fieldFromInstruction(insn, 21, 5);
6145c582b2fSDaniel Sanders   InsnType Rt = fieldFromInstruction(insn, 16, 5);
615672c710dSSagar Thakur   int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
6165c582b2fSDaniel Sanders   bool HasRs = false;
6175c582b2fSDaniel Sanders 
6185c582b2fSDaniel Sanders   if (Rs >= Rt) {
6195c582b2fSDaniel Sanders     MI.setOpcode(Mips::BOVC);
6205c582b2fSDaniel Sanders     HasRs = true;
6215c582b2fSDaniel Sanders   } else if (Rs != 0 && Rs < Rt) {
6225c582b2fSDaniel Sanders     MI.setOpcode(Mips::BEQC);
6235c582b2fSDaniel Sanders     HasRs = true;
6245c582b2fSDaniel Sanders   } else
6255c582b2fSDaniel Sanders     MI.setOpcode(Mips::BEQZALC);
6265c582b2fSDaniel Sanders 
6275c582b2fSDaniel Sanders   if (HasRs)
628e9119e41SJim Grosbach     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
6295c582b2fSDaniel Sanders                                        Rs)));
6305c582b2fSDaniel Sanders 
631e9119e41SJim Grosbach   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
6325c582b2fSDaniel Sanders                                      Rt)));
633e9119e41SJim Grosbach   MI.addOperand(MCOperand::createImm(Imm));
6345c582b2fSDaniel Sanders 
6355c582b2fSDaniel Sanders   return MCDisassembler::Success;
6365c582b2fSDaniel Sanders }
6375c582b2fSDaniel Sanders 
6385c582b2fSDaniel Sanders template <typename InsnType>
DecodePOP35GroupBranchMMR6(MCInst & MI,InsnType insn,uint64_t Address,const MCDisassembler * Decoder)639c962c493SHrvoje Varga static DecodeStatus DecodePOP35GroupBranchMMR6(MCInst &MI, InsnType insn,
640c962c493SHrvoje Varga                                                uint64_t Address,
6414ae9745aSMaksim Panchenko                                                const MCDisassembler *Decoder) {
642c962c493SHrvoje Varga   InsnType Rt = fieldFromInstruction(insn, 21, 5);
643c962c493SHrvoje Varga   InsnType Rs = fieldFromInstruction(insn, 16, 5);
644f0ed16eaSHrvoje Varga   int64_t Imm = 0;
645c962c493SHrvoje Varga 
646c962c493SHrvoje Varga   if (Rs >= Rt) {
647c962c493SHrvoje Varga     MI.setOpcode(Mips::BOVC_MMR6);
648c962c493SHrvoje Varga     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
649c962c493SHrvoje Varga                                        Rt)));
650c962c493SHrvoje Varga     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
651c962c493SHrvoje Varga                                        Rs)));
652f0ed16eaSHrvoje Varga     Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
653c962c493SHrvoje Varga   } else if (Rs != 0 && Rs < Rt) {
654c962c493SHrvoje Varga     MI.setOpcode(Mips::BEQC_MMR6);
655c962c493SHrvoje Varga     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
656c962c493SHrvoje Varga                                        Rs)));
657c962c493SHrvoje Varga     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
658c962c493SHrvoje Varga                                        Rt)));
659f0ed16eaSHrvoje Varga     Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
660c962c493SHrvoje Varga   } else {
661c962c493SHrvoje Varga     MI.setOpcode(Mips::BEQZALC_MMR6);
662c962c493SHrvoje Varga     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
663c962c493SHrvoje Varga                                        Rt)));
664f0ed16eaSHrvoje Varga     Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
665c962c493SHrvoje Varga   }
666c962c493SHrvoje Varga 
667c962c493SHrvoje Varga   MI.addOperand(MCOperand::createImm(Imm));
668c962c493SHrvoje Varga 
669c962c493SHrvoje Varga   return MCDisassembler::Success;
670c962c493SHrvoje Varga }
671c962c493SHrvoje Varga 
672c962c493SHrvoje Varga template <typename InsnType>
DecodeDaddiGroupBranch(MCInst & MI,InsnType insn,uint64_t Address,const MCDisassembler * Decoder)6735c582b2fSDaniel Sanders static DecodeStatus DecodeDaddiGroupBranch(MCInst &MI, InsnType insn,
6745c582b2fSDaniel Sanders                                            uint64_t Address,
6754ae9745aSMaksim Panchenko                                            const MCDisassembler *Decoder) {
6765c582b2fSDaniel Sanders   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
6775c582b2fSDaniel Sanders   // (otherwise we would have matched the ADDI instruction from the earlier
6785c582b2fSDaniel Sanders   // ISA's instead).
6795c582b2fSDaniel Sanders   //
6805c582b2fSDaniel Sanders   // We have:
6815c582b2fSDaniel Sanders   //    0b011000 sssss ttttt iiiiiiiiiiiiiiii
6825c582b2fSDaniel Sanders   //      BNVC if rs >= rt
6835c582b2fSDaniel Sanders   //      BNEZALC if rs == 0 && rt != 0
6845c582b2fSDaniel Sanders   //      BNEC if rs < rt && rs != 0
6855c582b2fSDaniel Sanders 
6865c582b2fSDaniel Sanders   InsnType Rs = fieldFromInstruction(insn, 21, 5);
6875c582b2fSDaniel Sanders   InsnType Rt = fieldFromInstruction(insn, 16, 5);
688672c710dSSagar Thakur   int64_t  Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
6895c582b2fSDaniel Sanders   bool HasRs = false;
6905c582b2fSDaniel Sanders 
6915c582b2fSDaniel Sanders   if (Rs >= Rt) {
6925c582b2fSDaniel Sanders     MI.setOpcode(Mips::BNVC);
6935c582b2fSDaniel Sanders     HasRs = true;
6945c582b2fSDaniel Sanders   } else if (Rs != 0 && Rs < Rt) {
6955c582b2fSDaniel Sanders     MI.setOpcode(Mips::BNEC);
6965c582b2fSDaniel Sanders     HasRs = true;
6975c582b2fSDaniel Sanders   } else
6985c582b2fSDaniel Sanders     MI.setOpcode(Mips::BNEZALC);
6995c582b2fSDaniel Sanders 
7005c582b2fSDaniel Sanders   if (HasRs)
701e9119e41SJim Grosbach     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
7025c582b2fSDaniel Sanders                                        Rs)));
7035c582b2fSDaniel Sanders 
704e9119e41SJim Grosbach   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
7055c582b2fSDaniel Sanders                                      Rt)));
706e9119e41SJim Grosbach   MI.addOperand(MCOperand::createImm(Imm));
7075c582b2fSDaniel Sanders 
7085c582b2fSDaniel Sanders   return MCDisassembler::Success;
7095c582b2fSDaniel Sanders }
7105c582b2fSDaniel Sanders 
7115c582b2fSDaniel Sanders template <typename InsnType>
DecodePOP37GroupBranchMMR6(MCInst & MI,InsnType insn,uint64_t Address,const MCDisassembler * Decoder)712c962c493SHrvoje Varga static DecodeStatus DecodePOP37GroupBranchMMR6(MCInst &MI, InsnType insn,
713c962c493SHrvoje Varga                                                uint64_t Address,
7144ae9745aSMaksim Panchenko                                                const MCDisassembler *Decoder) {
715c962c493SHrvoje Varga   InsnType Rt = fieldFromInstruction(insn, 21, 5);
716c962c493SHrvoje Varga   InsnType Rs = fieldFromInstruction(insn, 16, 5);
717f0ed16eaSHrvoje Varga   int64_t Imm = 0;
718c962c493SHrvoje Varga 
719c962c493SHrvoje Varga   if (Rs >= Rt) {
720c962c493SHrvoje Varga     MI.setOpcode(Mips::BNVC_MMR6);
721c962c493SHrvoje Varga     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
722c962c493SHrvoje Varga                                        Rt)));
723c962c493SHrvoje Varga     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
724c962c493SHrvoje Varga                                        Rs)));
725f0ed16eaSHrvoje Varga     Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
726c962c493SHrvoje Varga   } else if (Rs != 0 && Rs < Rt) {
727c962c493SHrvoje Varga     MI.setOpcode(Mips::BNEC_MMR6);
728c962c493SHrvoje Varga     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
729c962c493SHrvoje Varga                                        Rs)));
730c962c493SHrvoje Varga     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
731c962c493SHrvoje Varga                                        Rt)));
732f0ed16eaSHrvoje Varga     Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
733c962c493SHrvoje Varga   } else {
734c962c493SHrvoje Varga     MI.setOpcode(Mips::BNEZALC_MMR6);
735c962c493SHrvoje Varga     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
736c962c493SHrvoje Varga                                        Rt)));
737f0ed16eaSHrvoje Varga     Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
738c962c493SHrvoje Varga   }
739c962c493SHrvoje Varga 
740c962c493SHrvoje Varga   MI.addOperand(MCOperand::createImm(Imm));
741c962c493SHrvoje Varga 
742c962c493SHrvoje Varga   return MCDisassembler::Success;
743c962c493SHrvoje Varga }
744c962c493SHrvoje Varga 
745c962c493SHrvoje Varga template <typename InsnType>
DecodePOP65GroupBranchMMR6(MCInst & MI,InsnType insn,uint64_t Address,const MCDisassembler * Decoder)746f0ed16eaSHrvoje Varga static DecodeStatus DecodePOP65GroupBranchMMR6(MCInst &MI, InsnType insn,
747f0ed16eaSHrvoje Varga                                                uint64_t Address,
7484ae9745aSMaksim Panchenko                                                const MCDisassembler *Decoder) {
749f0ed16eaSHrvoje Varga   // We have:
750f0ed16eaSHrvoje Varga   //    0b110101 ttttt sssss iiiiiiiiiiiiiiii
751f0ed16eaSHrvoje Varga   //      Invalid if rt == 0
752f0ed16eaSHrvoje Varga   //      BGTZC_MMR6   if rs == 0  && rt != 0
753f0ed16eaSHrvoje Varga   //      BLTZC_MMR6   if rs == rt && rt != 0
754f0ed16eaSHrvoje Varga   //      BLTC_MMR6    if rs != rt && rs != 0  && rt != 0
755f0ed16eaSHrvoje Varga 
756f0ed16eaSHrvoje Varga   InsnType Rt = fieldFromInstruction(insn, 21, 5);
757f0ed16eaSHrvoje Varga   InsnType Rs = fieldFromInstruction(insn, 16, 5);
758f0ed16eaSHrvoje Varga   int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
759f0ed16eaSHrvoje Varga   bool HasRs = false;
760f0ed16eaSHrvoje Varga 
761f0ed16eaSHrvoje Varga   if (Rt == 0)
762f0ed16eaSHrvoje Varga     return MCDisassembler::Fail;
763f0ed16eaSHrvoje Varga   else if (Rs == 0)
764f0ed16eaSHrvoje Varga     MI.setOpcode(Mips::BGTZC_MMR6);
765f0ed16eaSHrvoje Varga   else if (Rs == Rt)
766f0ed16eaSHrvoje Varga     MI.setOpcode(Mips::BLTZC_MMR6);
767f0ed16eaSHrvoje Varga   else {
768f0ed16eaSHrvoje Varga     MI.setOpcode(Mips::BLTC_MMR6);
769f0ed16eaSHrvoje Varga     HasRs = true;
770f0ed16eaSHrvoje Varga   }
771f0ed16eaSHrvoje Varga 
772f0ed16eaSHrvoje Varga   if (HasRs)
773f0ed16eaSHrvoje Varga     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
774f0ed16eaSHrvoje Varga                                               Rs)));
775f0ed16eaSHrvoje Varga 
776f0ed16eaSHrvoje Varga   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
777f0ed16eaSHrvoje Varga                                      Rt)));
778f0ed16eaSHrvoje Varga 
779f0ed16eaSHrvoje Varga   MI.addOperand(MCOperand::createImm(Imm));
780f0ed16eaSHrvoje Varga 
781f0ed16eaSHrvoje Varga   return MCDisassembler::Success;
782f0ed16eaSHrvoje Varga }
783f0ed16eaSHrvoje Varga 
784f0ed16eaSHrvoje Varga template <typename InsnType>
DecodePOP75GroupBranchMMR6(MCInst & MI,InsnType insn,uint64_t Address,const MCDisassembler * Decoder)785f0ed16eaSHrvoje Varga static DecodeStatus DecodePOP75GroupBranchMMR6(MCInst &MI, InsnType insn,
786f0ed16eaSHrvoje Varga                                                uint64_t Address,
7874ae9745aSMaksim Panchenko                                                const MCDisassembler *Decoder) {
788f0ed16eaSHrvoje Varga   // We have:
789f0ed16eaSHrvoje Varga   //    0b111101 ttttt sssss iiiiiiiiiiiiiiii
790f0ed16eaSHrvoje Varga   //      Invalid if rt == 0
791f0ed16eaSHrvoje Varga   //      BLEZC_MMR6   if rs == 0  && rt != 0
792f0ed16eaSHrvoje Varga   //      BGEZC_MMR6   if rs == rt && rt != 0
793f0ed16eaSHrvoje Varga   //      BGEC_MMR6    if rs != rt && rs != 0  && rt != 0
794f0ed16eaSHrvoje Varga 
795f0ed16eaSHrvoje Varga   InsnType Rt = fieldFromInstruction(insn, 21, 5);
796f0ed16eaSHrvoje Varga   InsnType Rs = fieldFromInstruction(insn, 16, 5);
797f0ed16eaSHrvoje Varga   int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
798f0ed16eaSHrvoje Varga   bool HasRs = false;
799f0ed16eaSHrvoje Varga 
800f0ed16eaSHrvoje Varga   if (Rt == 0)
801f0ed16eaSHrvoje Varga     return MCDisassembler::Fail;
802f0ed16eaSHrvoje Varga   else if (Rs == 0)
803f0ed16eaSHrvoje Varga     MI.setOpcode(Mips::BLEZC_MMR6);
804f0ed16eaSHrvoje Varga   else if (Rs == Rt)
805f0ed16eaSHrvoje Varga     MI.setOpcode(Mips::BGEZC_MMR6);
806f0ed16eaSHrvoje Varga   else {
807f0ed16eaSHrvoje Varga     HasRs = true;
808f0ed16eaSHrvoje Varga     MI.setOpcode(Mips::BGEC_MMR6);
809f0ed16eaSHrvoje Varga   }
810f0ed16eaSHrvoje Varga 
811f0ed16eaSHrvoje Varga   if (HasRs)
812f0ed16eaSHrvoje Varga     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
813f0ed16eaSHrvoje Varga                                        Rs)));
814f0ed16eaSHrvoje Varga 
815f0ed16eaSHrvoje Varga   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
816f0ed16eaSHrvoje Varga                                      Rt)));
817f0ed16eaSHrvoje Varga 
818f0ed16eaSHrvoje Varga   MI.addOperand(MCOperand::createImm(Imm));
819f0ed16eaSHrvoje Varga 
820f0ed16eaSHrvoje Varga   return MCDisassembler::Success;
821f0ed16eaSHrvoje Varga }
822f0ed16eaSHrvoje Varga 
823f0ed16eaSHrvoje Varga template <typename InsnType>
DecodeBlezlGroupBranch(MCInst & MI,InsnType insn,uint64_t Address,const MCDisassembler * Decoder)8245c582b2fSDaniel Sanders static DecodeStatus DecodeBlezlGroupBranch(MCInst &MI, InsnType insn,
8255c582b2fSDaniel Sanders                                            uint64_t Address,
8264ae9745aSMaksim Panchenko                                            const MCDisassembler *Decoder) {
8275c582b2fSDaniel Sanders   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
8285c582b2fSDaniel Sanders   // (otherwise we would have matched the BLEZL instruction from the earlier
8295c582b2fSDaniel Sanders   // ISA's instead).
8305c582b2fSDaniel Sanders   //
8315c582b2fSDaniel Sanders   // We have:
8325c582b2fSDaniel Sanders   //    0b010110 sssss ttttt iiiiiiiiiiiiiiii
8335c582b2fSDaniel Sanders   //      Invalid if rs == 0
8345c582b2fSDaniel Sanders   //      BLEZC   if rs == 0  && rt != 0
8355c582b2fSDaniel Sanders   //      BGEZC   if rs == rt && rt != 0
8365c582b2fSDaniel Sanders   //      BGEC    if rs != rt && rs != 0  && rt != 0
8375c582b2fSDaniel Sanders 
8385c582b2fSDaniel Sanders   InsnType Rs = fieldFromInstruction(insn, 21, 5);
8395c582b2fSDaniel Sanders   InsnType Rt = fieldFromInstruction(insn, 16, 5);
840672c710dSSagar Thakur   int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
84128a0ca07SZoran Jovanovic   bool HasRs = false;
8425c582b2fSDaniel Sanders 
8435c582b2fSDaniel Sanders   if (Rt == 0)
8445c582b2fSDaniel Sanders     return MCDisassembler::Fail;
8455c582b2fSDaniel Sanders   else if (Rs == 0)
8465c582b2fSDaniel Sanders     MI.setOpcode(Mips::BLEZC);
8475c582b2fSDaniel Sanders   else if (Rs == Rt)
8485c582b2fSDaniel Sanders     MI.setOpcode(Mips::BGEZC);
84928a0ca07SZoran Jovanovic   else {
85028a0ca07SZoran Jovanovic     HasRs = true;
85128a0ca07SZoran Jovanovic     MI.setOpcode(Mips::BGEC);
85228a0ca07SZoran Jovanovic   }
85328a0ca07SZoran Jovanovic 
85428a0ca07SZoran Jovanovic   if (HasRs)
855e9119e41SJim Grosbach     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
85628a0ca07SZoran Jovanovic                                        Rs)));
8575c582b2fSDaniel Sanders 
858e9119e41SJim Grosbach   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
8595c582b2fSDaniel Sanders                                      Rt)));
8605c582b2fSDaniel Sanders 
861e9119e41SJim Grosbach   MI.addOperand(MCOperand::createImm(Imm));
8625c582b2fSDaniel Sanders 
8635c582b2fSDaniel Sanders   return MCDisassembler::Success;
8645c582b2fSDaniel Sanders }
8655c582b2fSDaniel Sanders 
8665c582b2fSDaniel Sanders template <typename InsnType>
DecodeBgtzlGroupBranch(MCInst & MI,InsnType insn,uint64_t Address,const MCDisassembler * Decoder)8675c582b2fSDaniel Sanders static DecodeStatus DecodeBgtzlGroupBranch(MCInst &MI, InsnType insn,
8685c582b2fSDaniel Sanders                                            uint64_t Address,
8694ae9745aSMaksim Panchenko                                            const MCDisassembler *Decoder) {
8705c582b2fSDaniel Sanders   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
8715c582b2fSDaniel Sanders   // (otherwise we would have matched the BGTZL instruction from the earlier
8725c582b2fSDaniel Sanders   // ISA's instead).
8735c582b2fSDaniel Sanders   //
8745c582b2fSDaniel Sanders   // We have:
8755c582b2fSDaniel Sanders   //    0b010111 sssss ttttt iiiiiiiiiiiiiiii
8765c582b2fSDaniel Sanders   //      Invalid if rs == 0
8775c582b2fSDaniel Sanders   //      BGTZC   if rs == 0  && rt != 0
8785c582b2fSDaniel Sanders   //      BLTZC   if rs == rt && rt != 0
8795c582b2fSDaniel Sanders   //      BLTC    if rs != rt && rs != 0  && rt != 0
8805c582b2fSDaniel Sanders 
8815c14b069SZoran Jovanovic   bool HasRs = false;
8825c14b069SZoran Jovanovic 
8835c582b2fSDaniel Sanders   InsnType Rs = fieldFromInstruction(insn, 21, 5);
8845c582b2fSDaniel Sanders   InsnType Rt = fieldFromInstruction(insn, 16, 5);
885672c710dSSagar Thakur   int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
8865c582b2fSDaniel Sanders 
8875c582b2fSDaniel Sanders   if (Rt == 0)
8885c582b2fSDaniel Sanders     return MCDisassembler::Fail;
8895c582b2fSDaniel Sanders   else if (Rs == 0)
8905c582b2fSDaniel Sanders     MI.setOpcode(Mips::BGTZC);
8915c582b2fSDaniel Sanders   else if (Rs == Rt)
8925c582b2fSDaniel Sanders     MI.setOpcode(Mips::BLTZC);
8935c14b069SZoran Jovanovic   else {
8945c14b069SZoran Jovanovic     MI.setOpcode(Mips::BLTC);
8955c14b069SZoran Jovanovic     HasRs = true;
8965c14b069SZoran Jovanovic   }
8975c14b069SZoran Jovanovic 
8985c14b069SZoran Jovanovic   if (HasRs)
899e9119e41SJim Grosbach     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
9005c14b069SZoran Jovanovic                                               Rs)));
9015c582b2fSDaniel Sanders 
902e9119e41SJim Grosbach   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
9035c582b2fSDaniel Sanders                                      Rt)));
9045c582b2fSDaniel Sanders 
905e9119e41SJim Grosbach   MI.addOperand(MCOperand::createImm(Imm));
9065c582b2fSDaniel Sanders 
9075c582b2fSDaniel Sanders   return MCDisassembler::Success;
9085c582b2fSDaniel Sanders }
9095c582b2fSDaniel Sanders 
9105c582b2fSDaniel Sanders template <typename InsnType>
DecodeBgtzGroupBranch(MCInst & MI,InsnType insn,uint64_t Address,const MCDisassembler * Decoder)9115c582b2fSDaniel Sanders static DecodeStatus DecodeBgtzGroupBranch(MCInst &MI, InsnType insn,
9125c582b2fSDaniel Sanders                                           uint64_t Address,
9134ae9745aSMaksim Panchenko                                           const MCDisassembler *Decoder) {
9145c582b2fSDaniel Sanders   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
9155c582b2fSDaniel Sanders   // (otherwise we would have matched the BGTZ instruction from the earlier
9165c582b2fSDaniel Sanders   // ISA's instead).
9175c582b2fSDaniel Sanders   //
9185c582b2fSDaniel Sanders   // We have:
9195c582b2fSDaniel Sanders   //    0b000111 sssss ttttt iiiiiiiiiiiiiiii
9205c582b2fSDaniel Sanders   //      BGTZ    if rt == 0
9215c582b2fSDaniel Sanders   //      BGTZALC if rs == 0 && rt != 0
9225c582b2fSDaniel Sanders   //      BLTZALC if rs != 0 && rs == rt
9235c582b2fSDaniel Sanders   //      BLTUC   if rs != 0 && rs != rt
9245c582b2fSDaniel Sanders 
9255c582b2fSDaniel Sanders   InsnType Rs = fieldFromInstruction(insn, 21, 5);
9265c582b2fSDaniel Sanders   InsnType Rt = fieldFromInstruction(insn, 16, 5);
927672c710dSSagar Thakur   int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
9285c582b2fSDaniel Sanders   bool HasRs = false;
9295c582b2fSDaniel Sanders   bool HasRt = false;
9305c582b2fSDaniel Sanders 
9315c582b2fSDaniel Sanders   if (Rt == 0) {
9325c582b2fSDaniel Sanders     MI.setOpcode(Mips::BGTZ);
9335c582b2fSDaniel Sanders     HasRs = true;
9345c582b2fSDaniel Sanders   } else if (Rs == 0) {
9355c582b2fSDaniel Sanders     MI.setOpcode(Mips::BGTZALC);
9365c582b2fSDaniel Sanders     HasRt = true;
9375c582b2fSDaniel Sanders   } else if (Rs == Rt) {
9385c582b2fSDaniel Sanders     MI.setOpcode(Mips::BLTZALC);
9395c582b2fSDaniel Sanders     HasRs = true;
9405c14b069SZoran Jovanovic   } else {
9415c14b069SZoran Jovanovic     MI.setOpcode(Mips::BLTUC);
9425c14b069SZoran Jovanovic     HasRs = true;
9435c14b069SZoran Jovanovic     HasRt = true;
9445c14b069SZoran Jovanovic   }
9455c582b2fSDaniel Sanders 
9465c582b2fSDaniel Sanders   if (HasRs)
947e9119e41SJim Grosbach     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
9485c582b2fSDaniel Sanders                                        Rs)));
9495c582b2fSDaniel Sanders 
9505c582b2fSDaniel Sanders   if (HasRt)
951e9119e41SJim Grosbach     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
9525c582b2fSDaniel Sanders                                        Rt)));
9535c582b2fSDaniel Sanders 
954e9119e41SJim Grosbach   MI.addOperand(MCOperand::createImm(Imm));
9555c582b2fSDaniel Sanders 
9565c582b2fSDaniel Sanders   return MCDisassembler::Success;
9575c582b2fSDaniel Sanders }
9585c582b2fSDaniel Sanders 
95928a0ca07SZoran Jovanovic template <typename InsnType>
DecodeBlezGroupBranch(MCInst & MI,InsnType insn,uint64_t Address,const MCDisassembler * Decoder)96028a0ca07SZoran Jovanovic static DecodeStatus DecodeBlezGroupBranch(MCInst &MI, InsnType insn,
96128a0ca07SZoran Jovanovic                                           uint64_t Address,
9624ae9745aSMaksim Panchenko                                           const MCDisassembler *Decoder) {
96328a0ca07SZoran Jovanovic   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
96428a0ca07SZoran Jovanovic   // (otherwise we would have matched the BLEZL instruction from the earlier
96528a0ca07SZoran Jovanovic   // ISA's instead).
96628a0ca07SZoran Jovanovic   //
96728a0ca07SZoran Jovanovic   // We have:
96828a0ca07SZoran Jovanovic   //    0b000110 sssss ttttt iiiiiiiiiiiiiiii
96928a0ca07SZoran Jovanovic   //      Invalid   if rs == 0
97028a0ca07SZoran Jovanovic   //      BLEZALC   if rs == 0  && rt != 0
97128a0ca07SZoran Jovanovic   //      BGEZALC   if rs == rt && rt != 0
97228a0ca07SZoran Jovanovic   //      BGEUC     if rs != rt && rs != 0  && rt != 0
97328a0ca07SZoran Jovanovic 
97428a0ca07SZoran Jovanovic   InsnType Rs = fieldFromInstruction(insn, 21, 5);
97528a0ca07SZoran Jovanovic   InsnType Rt = fieldFromInstruction(insn, 16, 5);
976672c710dSSagar Thakur   int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
97728a0ca07SZoran Jovanovic   bool HasRs = false;
97828a0ca07SZoran Jovanovic 
97928a0ca07SZoran Jovanovic   if (Rt == 0)
98028a0ca07SZoran Jovanovic     return MCDisassembler::Fail;
98128a0ca07SZoran Jovanovic   else if (Rs == 0)
98228a0ca07SZoran Jovanovic     MI.setOpcode(Mips::BLEZALC);
98328a0ca07SZoran Jovanovic   else if (Rs == Rt)
98428a0ca07SZoran Jovanovic     MI.setOpcode(Mips::BGEZALC);
98528a0ca07SZoran Jovanovic   else {
98628a0ca07SZoran Jovanovic     HasRs = true;
98728a0ca07SZoran Jovanovic     MI.setOpcode(Mips::BGEUC);
98828a0ca07SZoran Jovanovic   }
98928a0ca07SZoran Jovanovic 
99028a0ca07SZoran Jovanovic   if (HasRs)
991e9119e41SJim Grosbach     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
99228a0ca07SZoran Jovanovic                                        Rs)));
993e9119e41SJim Grosbach   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
99428a0ca07SZoran Jovanovic                                      Rt)));
99528a0ca07SZoran Jovanovic 
996e9119e41SJim Grosbach   MI.addOperand(MCOperand::createImm(Imm));
99728a0ca07SZoran Jovanovic 
99828a0ca07SZoran Jovanovic   return MCDisassembler::Success;
99928a0ca07SZoran Jovanovic }
100028a0ca07SZoran Jovanovic 
100155e44673SSimon Dardis // Override the generated disassembler to produce DEXT all the time. This is
100255e44673SSimon Dardis // for feature / behaviour parity with  binutils.
100355e44673SSimon Dardis template <typename InsnType>
DecodeDEXT(MCInst & MI,InsnType Insn,uint64_t Address,const MCDisassembler * Decoder)100455e44673SSimon Dardis static DecodeStatus DecodeDEXT(MCInst &MI, InsnType Insn, uint64_t Address,
10054ae9745aSMaksim Panchenko                                const MCDisassembler *Decoder) {
100655e44673SSimon Dardis   unsigned Msbd = fieldFromInstruction(Insn, 11, 5);
100755e44673SSimon Dardis   unsigned Lsb = fieldFromInstruction(Insn, 6, 5);
100855e44673SSimon Dardis   unsigned Size = 0;
100955e44673SSimon Dardis   unsigned Pos = 0;
101055e44673SSimon Dardis 
101155e44673SSimon Dardis   switch (MI.getOpcode()) {
101255e44673SSimon Dardis     case Mips::DEXT:
101355e44673SSimon Dardis       Pos = Lsb;
101455e44673SSimon Dardis       Size = Msbd + 1;
101555e44673SSimon Dardis       break;
101655e44673SSimon Dardis     case Mips::DEXTM:
101755e44673SSimon Dardis       Pos = Lsb;
101855e44673SSimon Dardis       Size = Msbd + 1 + 32;
101955e44673SSimon Dardis       break;
102055e44673SSimon Dardis     case Mips::DEXTU:
102155e44673SSimon Dardis       Pos = Lsb + 32;
102255e44673SSimon Dardis       Size = Msbd + 1;
102355e44673SSimon Dardis       break;
102455e44673SSimon Dardis     default:
102555e44673SSimon Dardis       llvm_unreachable("Unknown DEXT instruction!");
102655e44673SSimon Dardis   }
102755e44673SSimon Dardis 
1028d6dada17SAleksandar Beserminji   MI.setOpcode(Mips::DEXT);
102955e44673SSimon Dardis 
103055e44673SSimon Dardis   InsnType Rs = fieldFromInstruction(Insn, 21, 5);
103155e44673SSimon Dardis   InsnType Rt = fieldFromInstruction(Insn, 16, 5);
103255e44673SSimon Dardis 
10330bd82a96SSimon Atanasyan   MI.addOperand(
10340bd82a96SSimon Atanasyan       MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID, Rt)));
10350bd82a96SSimon Atanasyan   MI.addOperand(
10360bd82a96SSimon Atanasyan       MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID, Rs)));
103755e44673SSimon Dardis   MI.addOperand(MCOperand::createImm(Pos));
103855e44673SSimon Dardis   MI.addOperand(MCOperand::createImm(Size));
103955e44673SSimon Dardis 
104055e44673SSimon Dardis   return MCDisassembler::Success;
104155e44673SSimon Dardis }
104255e44673SSimon Dardis 
10436f83ae38SSimon Dardis // Override the generated disassembler to produce DINS all the time. This is
10446f83ae38SSimon Dardis // for feature / behaviour parity with binutils.
10456f83ae38SSimon Dardis template <typename InsnType>
DecodeDINS(MCInst & MI,InsnType Insn,uint64_t Address,const MCDisassembler * Decoder)10466f83ae38SSimon Dardis static DecodeStatus DecodeDINS(MCInst &MI, InsnType Insn, uint64_t Address,
10474ae9745aSMaksim Panchenko                                const MCDisassembler *Decoder) {
10486f83ae38SSimon Dardis   unsigned Msbd = fieldFromInstruction(Insn, 11, 5);
10496f83ae38SSimon Dardis   unsigned Lsb = fieldFromInstruction(Insn, 6, 5);
10506f83ae38SSimon Dardis   unsigned Size = 0;
10516f83ae38SSimon Dardis   unsigned Pos = 0;
10526f83ae38SSimon Dardis 
10536f83ae38SSimon Dardis   switch (MI.getOpcode()) {
10546f83ae38SSimon Dardis     case Mips::DINS:
10556f83ae38SSimon Dardis       Pos = Lsb;
10566f83ae38SSimon Dardis       Size = Msbd + 1 - Pos;
10576f83ae38SSimon Dardis       break;
10586f83ae38SSimon Dardis     case Mips::DINSM:
10596f83ae38SSimon Dardis       Pos = Lsb;
10606f83ae38SSimon Dardis       Size = Msbd + 33 - Pos;
10616f83ae38SSimon Dardis       break;
10626f83ae38SSimon Dardis     case Mips::DINSU:
10636f83ae38SSimon Dardis       Pos = Lsb + 32;
10646f83ae38SSimon Dardis       // mbsd = pos + size - 33
10656f83ae38SSimon Dardis       // mbsd - pos + 33 = size
10666f83ae38SSimon Dardis       Size = Msbd + 33 - Pos;
10676f83ae38SSimon Dardis       break;
10686f83ae38SSimon Dardis     default:
10696f83ae38SSimon Dardis       llvm_unreachable("Unknown DINS instruction!");
10706f83ae38SSimon Dardis   }
10716f83ae38SSimon Dardis 
10726f83ae38SSimon Dardis   InsnType Rs = fieldFromInstruction(Insn, 21, 5);
10736f83ae38SSimon Dardis   InsnType Rt = fieldFromInstruction(Insn, 16, 5);
10746f83ae38SSimon Dardis 
1075d6dada17SAleksandar Beserminji   MI.setOpcode(Mips::DINS);
10760bd82a96SSimon Atanasyan   MI.addOperand(
10770bd82a96SSimon Atanasyan       MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID, Rt)));
10780bd82a96SSimon Atanasyan   MI.addOperand(
10790bd82a96SSimon Atanasyan       MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID, Rs)));
10806f83ae38SSimon Dardis   MI.addOperand(MCOperand::createImm(Pos));
10816f83ae38SSimon Dardis   MI.addOperand(MCOperand::createImm(Size));
10826f83ae38SSimon Dardis 
10836f83ae38SSimon Dardis   return MCDisassembler::Success;
10846f83ae38SSimon Dardis }
10853408caf6SPetar Jovanovic 
10863408caf6SPetar Jovanovic // Auto-generated decoder wouldn't add the third operand for CRC32*.
10873408caf6SPetar Jovanovic template <typename InsnType>
DecodeCRC(MCInst & MI,InsnType Insn,uint64_t Address,const MCDisassembler * Decoder)10883408caf6SPetar Jovanovic static DecodeStatus DecodeCRC(MCInst &MI, InsnType Insn, uint64_t Address,
10894ae9745aSMaksim Panchenko                               const MCDisassembler *Decoder) {
10903408caf6SPetar Jovanovic   InsnType Rs = fieldFromInstruction(Insn, 21, 5);
10913408caf6SPetar Jovanovic   InsnType Rt = fieldFromInstruction(Insn, 16, 5);
10923408caf6SPetar Jovanovic   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
10933408caf6SPetar Jovanovic                                      Rt)));
10943408caf6SPetar Jovanovic   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
10953408caf6SPetar Jovanovic                                      Rs)));
10963408caf6SPetar Jovanovic   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
10973408caf6SPetar Jovanovic                                      Rt)));
10983408caf6SPetar Jovanovic   return MCDisassembler::Success;
10993408caf6SPetar Jovanovic }
11003408caf6SPetar Jovanovic 
1101ea22c4cfSJozef Kolek /// Read two bytes from the ArrayRef and return 16 bit halfword sorted
1102dcd84335SSimon Pilgrim /// according to the given endianness.
readInstruction16(ArrayRef<uint8_t> Bytes,uint64_t Address,uint64_t & Size,uint32_t & Insn,bool IsBigEndian)1103ea22c4cfSJozef Kolek static DecodeStatus readInstruction16(ArrayRef<uint8_t> Bytes, uint64_t Address,
1104ea22c4cfSJozef Kolek                                       uint64_t &Size, uint32_t &Insn,
1105ea22c4cfSJozef Kolek                                       bool IsBigEndian) {
1106ea22c4cfSJozef Kolek   // We want to read exactly 2 Bytes of data.
1107ea22c4cfSJozef Kolek   if (Bytes.size() < 2) {
1108ea22c4cfSJozef Kolek     Size = 0;
1109ea22c4cfSJozef Kolek     return MCDisassembler::Fail;
1110ea22c4cfSJozef Kolek   }
1111ea22c4cfSJozef Kolek 
1112ea22c4cfSJozef Kolek   if (IsBigEndian) {
1113ea22c4cfSJozef Kolek     Insn = (Bytes[0] << 8) | Bytes[1];
1114ea22c4cfSJozef Kolek   } else {
1115ea22c4cfSJozef Kolek     Insn = (Bytes[1] << 8) | Bytes[0];
1116ea22c4cfSJozef Kolek   }
1117ea22c4cfSJozef Kolek 
1118ea22c4cfSJozef Kolek   return MCDisassembler::Success;
1119ea22c4cfSJozef Kolek }
1120ea22c4cfSJozef Kolek 
11217fc5b874SRafael Espindola /// Read four bytes from the ArrayRef and return 32 bit word sorted
1122dcd84335SSimon Pilgrim /// according to the given endianness.
readInstruction32(ArrayRef<uint8_t> Bytes,uint64_t Address,uint64_t & Size,uint32_t & Insn,bool IsBigEndian,bool IsMicroMips)11237fc5b874SRafael Espindola static DecodeStatus readInstruction32(ArrayRef<uint8_t> Bytes, uint64_t Address,
11247fc5b874SRafael Espindola                                       uint64_t &Size, uint32_t &Insn,
11257fc5b874SRafael Espindola                                       bool IsBigEndian, bool IsMicroMips) {
112671928e68SAkira Hatanaka   // We want to read exactly 4 Bytes of data.
11277fc5b874SRafael Espindola   if (Bytes.size() < 4) {
11284aa6bea7SRafael Espindola     Size = 0;
112971928e68SAkira Hatanaka     return MCDisassembler::Fail;
113071928e68SAkira Hatanaka   }
113171928e68SAkira Hatanaka 
1132ea22c4cfSJozef Kolek   // High 16 bits of a 32-bit microMIPS instruction (where the opcode is)
1133ea22c4cfSJozef Kolek   // always precede the low 16 bits in the instruction stream (that is, they
1134ea22c4cfSJozef Kolek   // are placed at lower addresses in the instruction stream).
1135ea22c4cfSJozef Kolek   //
1136ea22c4cfSJozef Kolek   // microMIPS byte ordering:
1137ea22c4cfSJozef Kolek   //   Big-endian:    0 | 1 | 2 | 3
1138ea22c4cfSJozef Kolek   //   Little-endian: 1 | 0 | 3 | 2
1139ea22c4cfSJozef Kolek 
11404aa6bea7SRafael Espindola   if (IsBigEndian) {
114171928e68SAkira Hatanaka     // Encoded as a big-endian 32-bit word in the stream.
11424aa6bea7SRafael Espindola     Insn =
11434aa6bea7SRafael Espindola         (Bytes[3] << 0) | (Bytes[2] << 8) | (Bytes[1] << 16) | (Bytes[0] << 24);
11444aa6bea7SRafael Espindola   } else {
1145dde3d582SVladimir Medic     if (IsMicroMips) {
11464aa6bea7SRafael Espindola       Insn = (Bytes[2] << 0) | (Bytes[3] << 8) | (Bytes[0] << 16) |
1147dde3d582SVladimir Medic              (Bytes[1] << 24);
1148dde3d582SVladimir Medic     } else {
11494aa6bea7SRafael Espindola       Insn = (Bytes[0] << 0) | (Bytes[1] << 8) | (Bytes[2] << 16) |
115071928e68SAkira Hatanaka              (Bytes[3] << 24);
115171928e68SAkira Hatanaka     }
1152dde3d582SVladimir Medic   }
115371928e68SAkira Hatanaka 
115471928e68SAkira Hatanaka   return MCDisassembler::Success;
115571928e68SAkira Hatanaka }
115671928e68SAkira Hatanaka 
getInstruction(MCInst & Instr,uint64_t & Size,ArrayRef<uint8_t> Bytes,uint64_t Address,raw_ostream & CStream) const11574aa6bea7SRafael Espindola DecodeStatus MipsDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,
11587fc5b874SRafael Espindola                                               ArrayRef<uint8_t> Bytes,
115971928e68SAkira Hatanaka                                               uint64_t Address,
11604aa6bea7SRafael Espindola                                               raw_ostream &CStream) const {
116171928e68SAkira Hatanaka   uint32_t Insn;
1162ea22c4cfSJozef Kolek   DecodeStatus Result;
1163a5f52dc0SSimon Dardis   Size = 0;
116471928e68SAkira Hatanaka 
1165ea22c4cfSJozef Kolek   if (IsMicroMips) {
1166ea22c4cfSJozef Kolek     Result = readInstruction16(Bytes, Address, Size, Insn, IsBigEndian);
1167ebee6129SReid Kleckner     if (Result == MCDisassembler::Fail)
1168ebee6129SReid Kleckner       return MCDisassembler::Fail;
1169ea22c4cfSJozef Kolek 
1170ada70918SZoran Jovanovic     if (hasMips32r6()) {
1171d34e60caSNicola Zaghen       LLVM_DEBUG(
1172d34e60caSNicola Zaghen           dbgs() << "Trying MicroMipsR616 table (16-bit instructions):\n");
1173ada70918SZoran Jovanovic       // Calling the auto-generated decoder function for microMIPS32R6
1174d6dada17SAleksandar Beserminji       // 16-bit instructions.
1175ada70918SZoran Jovanovic       Result = decodeInstruction(DecoderTableMicroMipsR616, Instr, Insn,
1176ada70918SZoran Jovanovic                                  Address, this, STI);
1177ada70918SZoran Jovanovic       if (Result != MCDisassembler::Fail) {
1178ada70918SZoran Jovanovic         Size = 2;
1179ada70918SZoran Jovanovic         return Result;
1180ada70918SZoran Jovanovic       }
1181ada70918SZoran Jovanovic     }
1182ada70918SZoran Jovanovic 
1183d34e60caSNicola Zaghen     LLVM_DEBUG(dbgs() << "Trying MicroMips16 table (16-bit instructions):\n");
1184ada70918SZoran Jovanovic     // Calling the auto-generated decoder function for microMIPS 16-bit
1185ada70918SZoran Jovanovic     // instructions.
1186ea22c4cfSJozef Kolek     Result = decodeInstruction(DecoderTableMicroMips16, Instr, Insn, Address,
1187ea22c4cfSJozef Kolek                                this, STI);
1188ea22c4cfSJozef Kolek     if (Result != MCDisassembler::Fail) {
1189ea22c4cfSJozef Kolek       Size = 2;
1190ea22c4cfSJozef Kolek       return Result;
1191ea22c4cfSJozef Kolek     }
1192ea22c4cfSJozef Kolek 
1193ea22c4cfSJozef Kolek     Result = readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, true);
119471928e68SAkira Hatanaka     if (Result == MCDisassembler::Fail)
119571928e68SAkira Hatanaka       return MCDisassembler::Fail;
119671928e68SAkira Hatanaka 
1197676d6012SJozef Kolek     if (hasMips32r6()) {
1198d34e60caSNicola Zaghen       LLVM_DEBUG(
1199d34e60caSNicola Zaghen           dbgs() << "Trying MicroMips32r632 table (32-bit instructions):\n");
1200676d6012SJozef Kolek       // Calling the auto-generated decoder function.
12010bd82a96SSimon Atanasyan       Result = decodeInstruction(DecoderTableMicroMipsR632, Instr, Insn,
12020bd82a96SSimon Atanasyan                                  Address, this, STI);
1203ada70918SZoran Jovanovic       if (Result != MCDisassembler::Fail) {
1204ada70918SZoran Jovanovic         Size = 4;
1205ada70918SZoran Jovanovic         return Result;
1206ada70918SZoran Jovanovic       }
1207ada70918SZoran Jovanovic     }
1208ada70918SZoran Jovanovic 
1209d34e60caSNicola Zaghen     LLVM_DEBUG(dbgs() << "Trying MicroMips32 table (32-bit instructions):\n");
1210dde3d582SVladimir Medic     // Calling the auto-generated decoder function.
12114aa6bea7SRafael Espindola     Result = decodeInstruction(DecoderTableMicroMips32, Instr, Insn, Address,
1212dde3d582SVladimir Medic                                this, STI);
1213dde3d582SVladimir Medic     if (Result != MCDisassembler::Fail) {
1214dde3d582SVladimir Medic       Size = 4;
1215dde3d582SVladimir Medic       return Result;
1216dde3d582SVladimir Medic     }
12172cb74ac3SHrvoje Varga 
121851a7ae2aSSimon Dardis     if (isFP64()) {
1219d34e60caSNicola Zaghen       LLVM_DEBUG(dbgs() << "Trying MicroMipsFP64 table (32-bit opcodes):\n");
122051a7ae2aSSimon Dardis       Result = decodeInstruction(DecoderTableMicroMipsFP6432, Instr, Insn,
12212cb74ac3SHrvoje Varga                                  Address, this, STI);
12222cb74ac3SHrvoje Varga       if (Result != MCDisassembler::Fail) {
12232cb74ac3SHrvoje Varga         Size = 4;
12242cb74ac3SHrvoje Varga         return Result;
12252cb74ac3SHrvoje Varga       }
12262cb74ac3SHrvoje Varga     }
12272cb74ac3SHrvoje Varga 
1228a5f52dc0SSimon Dardis     // This is an invalid instruction. Claim that the Size is 2 bytes. Since
1229a5f52dc0SSimon Dardis     // microMIPS instructions have a minimum alignment of 2, the next 2 bytes
1230a5f52dc0SSimon Dardis     // could form a valid instruction. The two bytes we rejected as an
1231a5f52dc0SSimon Dardis     // instruction could have actually beeen an inline constant pool that is
1232a5f52dc0SSimon Dardis     // unconditionally branched over.
1233ebee6129SReid Kleckner     Size = 2;
1234dde3d582SVladimir Medic     return MCDisassembler::Fail;
1235dde3d582SVladimir Medic   }
1236dde3d582SVladimir Medic 
1237a5f52dc0SSimon Dardis   // Attempt to read the instruction so that we can attempt to decode it. If
1238a5f52dc0SSimon Dardis   // the buffer is not 4 bytes long, let the higher level logic figure out
1239a5f52dc0SSimon Dardis   // what to do with a size of zero and MCDisassembler::Fail.
1240ea22c4cfSJozef Kolek   Result = readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, false);
1241a5f52dc0SSimon Dardis   if (Result == MCDisassembler::Fail)
1242ea22c4cfSJozef Kolek     return MCDisassembler::Fail;
1243a5f52dc0SSimon Dardis 
1244a5f52dc0SSimon Dardis   // The only instruction size for standard encoded MIPS.
1245a5f52dc0SSimon Dardis   Size = 4;
1246ea22c4cfSJozef Kolek 
1247c171f65aSDaniel Sanders   if (hasCOP3()) {
1248d34e60caSNicola Zaghen     LLVM_DEBUG(dbgs() << "Trying COP3_ table (32-bit opcodes):\n");
1249c171f65aSDaniel Sanders     Result =
12504aa6bea7SRafael Espindola         decodeInstruction(DecoderTableCOP3_32, Instr, Insn, Address, this, STI);
1251a5f52dc0SSimon Dardis     if (Result != MCDisassembler::Fail)
1252c171f65aSDaniel Sanders       return Result;
1253c171f65aSDaniel Sanders   }
1254c171f65aSDaniel Sanders 
1255c171f65aSDaniel Sanders   if (hasMips32r6() && isGP64()) {
1256d34e60caSNicola Zaghen     LLVM_DEBUG(
1257d34e60caSNicola Zaghen         dbgs() << "Trying Mips32r6_64r6 (GPR64) table (32-bit opcodes):\n");
125836901dd1SVasileios Kalintiris     Result = decodeInstruction(DecoderTableMips32r6_64r6_GP6432, Instr, Insn,
125936901dd1SVasileios Kalintiris                                Address, this, STI);
1260a5f52dc0SSimon Dardis     if (Result != MCDisassembler::Fail)
12610fa60416SDaniel Sanders       return Result;
12620fa60416SDaniel Sanders   }
12630fa60416SDaniel Sanders 
12644fbf76f7SSimon Dardis   if (hasMips32r6() && isPTR64()) {
1265d34e60caSNicola Zaghen     LLVM_DEBUG(
1266d34e60caSNicola Zaghen         dbgs() << "Trying Mips32r6_64r6 (PTR64) table (32-bit opcodes):\n");
12674fbf76f7SSimon Dardis     Result = decodeInstruction(DecoderTableMips32r6_64r6_PTR6432, Instr, Insn,
12684fbf76f7SSimon Dardis                                Address, this, STI);
1269a5f52dc0SSimon Dardis     if (Result != MCDisassembler::Fail)
12704fbf76f7SSimon Dardis       return Result;
12714fbf76f7SSimon Dardis   }
12724fbf76f7SSimon Dardis 
1273c171f65aSDaniel Sanders   if (hasMips32r6()) {
1274d34e60caSNicola Zaghen     LLVM_DEBUG(dbgs() << "Trying Mips32r6_64r6 table (32-bit opcodes):\n");
12754aa6bea7SRafael Espindola     Result = decodeInstruction(DecoderTableMips32r6_64r632, Instr, Insn,
12765c582b2fSDaniel Sanders                                Address, this, STI);
1277a5f52dc0SSimon Dardis     if (Result != MCDisassembler::Fail)
12785c582b2fSDaniel Sanders       return Result;
12795c582b2fSDaniel Sanders   }
12805c582b2fSDaniel Sanders 
12814fbf76f7SSimon Dardis   if (hasMips2() && isPTR64()) {
1282d34e60caSNicola Zaghen     LLVM_DEBUG(
1283d34e60caSNicola Zaghen         dbgs() << "Trying Mips32r6_64r6 (PTR64) table (32-bit opcodes):\n");
12844fbf76f7SSimon Dardis     Result = decodeInstruction(DecoderTableMips32_64_PTR6432, Instr, Insn,
12854fbf76f7SSimon Dardis                                Address, this, STI);
1286a5f52dc0SSimon Dardis     if (Result != MCDisassembler::Fail)
12874fbf76f7SSimon Dardis       return Result;
12884fbf76f7SSimon Dardis   }
12894fbf76f7SSimon Dardis 
12903adf9b8dSKai Nacke   if (hasCnMips()) {
1291d34e60caSNicola Zaghen     LLVM_DEBUG(dbgs() << "Trying CnMips table (32-bit opcodes):\n");
12923adf9b8dSKai Nacke     Result = decodeInstruction(DecoderTableCnMips32, Instr, Insn,
12933adf9b8dSKai Nacke                                Address, this, STI);
1294a5f52dc0SSimon Dardis     if (Result != MCDisassembler::Fail)
12953adf9b8dSKai Nacke       return Result;
12963adf9b8dSKai Nacke   }
12973adf9b8dSKai Nacke 
12987bed381eSSimon Atanasyan   if (hasCnMipsP()) {
12997bed381eSSimon Atanasyan     LLVM_DEBUG(dbgs() << "Trying CnMipsP table (32-bit opcodes):\n");
13007bed381eSSimon Atanasyan     Result = decodeInstruction(DecoderTableCnMipsP32, Instr, Insn,
13017bed381eSSimon Atanasyan                                Address, this, STI);
13027bed381eSSimon Atanasyan     if (Result != MCDisassembler::Fail)
13037bed381eSSimon Atanasyan       return Result;
13047bed381eSSimon Atanasyan   }
13057bed381eSSimon Atanasyan 
1306a19216c8SDaniel Sanders   if (isGP64()) {
1307d34e60caSNicola Zaghen     LLVM_DEBUG(dbgs() << "Trying Mips64 (GPR64) table (32-bit opcodes):\n");
1308a19216c8SDaniel Sanders     Result = decodeInstruction(DecoderTableMips6432, Instr, Insn,
1309a19216c8SDaniel Sanders                                Address, this, STI);
1310a5f52dc0SSimon Dardis     if (Result != MCDisassembler::Fail)
1311a19216c8SDaniel Sanders       return Result;
1312a19216c8SDaniel Sanders   }
1313a19216c8SDaniel Sanders 
131451a7ae2aSSimon Dardis   if (isFP64()) {
1315d34e60caSNicola Zaghen     LLVM_DEBUG(
1316d34e60caSNicola Zaghen         dbgs() << "Trying MipsFP64 (64 bit FPU) table (32-bit opcodes):\n");
131751a7ae2aSSimon Dardis     Result = decodeInstruction(DecoderTableMipsFP6432, Instr, Insn,
131851a7ae2aSSimon Dardis                                Address, this, STI);
131951a7ae2aSSimon Dardis     if (Result != MCDisassembler::Fail)
132051a7ae2aSSimon Dardis       return Result;
132151a7ae2aSSimon Dardis   }
132251a7ae2aSSimon Dardis 
1323d34e60caSNicola Zaghen   LLVM_DEBUG(dbgs() << "Trying Mips table (32-bit opcodes):\n");
132471928e68SAkira Hatanaka   // Calling the auto-generated decoder function.
13254aa6bea7SRafael Espindola   Result =
13264aa6bea7SRafael Espindola       decodeInstruction(DecoderTableMips32, Instr, Insn, Address, this, STI);
1327a5f52dc0SSimon Dardis   if (Result != MCDisassembler::Fail)
132871928e68SAkira Hatanaka     return Result;
132971928e68SAkira Hatanaka 
133071928e68SAkira Hatanaka   return MCDisassembler::Fail;
133171928e68SAkira Hatanaka }
133271928e68SAkira Hatanaka 
13334ae9745aSMaksim Panchenko static DecodeStatus
DecodeCPU16RegsRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)13344ae9745aSMaksim Panchenko DecodeCPU16RegsRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address,
13354ae9745aSMaksim Panchenko                              const MCDisassembler *Decoder) {
1336ec8a5490SReed Kotler   return MCDisassembler::Fail;
1337ec8a5490SReed Kotler }
1338ec8a5490SReed Kotler 
DecodeGPR64RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)13394ae9745aSMaksim Panchenko static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst, unsigned RegNo,
134071928e68SAkira Hatanaka                                              uint64_t Address,
13414ae9745aSMaksim Panchenko                                              const MCDisassembler *Decoder) {
134271928e68SAkira Hatanaka   if (RegNo > 31)
134371928e68SAkira Hatanaka     return MCDisassembler::Fail;
134471928e68SAkira Hatanaka 
134513e6ccf3SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::GPR64RegClassID, RegNo);
1346e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
134771928e68SAkira Hatanaka   return MCDisassembler::Success;
134871928e68SAkira Hatanaka }
134971928e68SAkira Hatanaka 
DecodeGPRMM16RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)13504ae9745aSMaksim Panchenko static DecodeStatus DecodeGPRMM16RegisterClass(MCInst &Inst, unsigned RegNo,
1351b0852e54SZoran Jovanovic                                                uint64_t Address,
13524ae9745aSMaksim Panchenko                                                const MCDisassembler *Decoder) {
1353ea22c4cfSJozef Kolek   if (RegNo > 7)
1354b0852e54SZoran Jovanovic     return MCDisassembler::Fail;
1355ea22c4cfSJozef Kolek   unsigned Reg = getReg(Decoder, Mips::GPRMM16RegClassID, RegNo);
1356e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1357ea22c4cfSJozef Kolek   return MCDisassembler::Success;
1358b0852e54SZoran Jovanovic }
1359b0852e54SZoran Jovanovic 
13604ae9745aSMaksim Panchenko static DecodeStatus
DecodeGPRMM16ZeroRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)13614ae9745aSMaksim Panchenko DecodeGPRMM16ZeroRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address,
13624ae9745aSMaksim Panchenko                                const MCDisassembler *Decoder) {
1363315e7ecaSJozef Kolek   if (RegNo > 7)
13641904fa21SJozef Kolek     return MCDisassembler::Fail;
1365315e7ecaSJozef Kolek   unsigned Reg = getReg(Decoder, Mips::GPRMM16ZeroRegClassID, RegNo);
1366e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1367315e7ecaSJozef Kolek   return MCDisassembler::Success;
13681904fa21SJozef Kolek }
13691904fa21SJozef Kolek 
13704ae9745aSMaksim Panchenko static DecodeStatus
DecodeGPRMM16MovePRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)13714ae9745aSMaksim Panchenko DecodeGPRMM16MovePRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address,
13724ae9745aSMaksim Panchenko                                 const MCDisassembler *Decoder) {
137341688679SZoran Jovanovic   if (RegNo > 7)
137441688679SZoran Jovanovic     return MCDisassembler::Fail;
137541688679SZoran Jovanovic   unsigned Reg = getReg(Decoder, Mips::GPRMM16MovePRegClassID, RegNo);
1376e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
137741688679SZoran Jovanovic   return MCDisassembler::Success;
137841688679SZoran Jovanovic }
137941688679SZoran Jovanovic 
DecodeGPR32RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)13804ae9745aSMaksim Panchenko static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst, unsigned RegNo,
138171928e68SAkira Hatanaka                                              uint64_t Address,
13824ae9745aSMaksim Panchenko                                              const MCDisassembler *Decoder) {
138371928e68SAkira Hatanaka   if (RegNo > 31)
138471928e68SAkira Hatanaka     return MCDisassembler::Fail;
138513e6ccf3SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::GPR32RegClassID, RegNo);
1386e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
138771928e68SAkira Hatanaka   return MCDisassembler::Success;
138871928e68SAkira Hatanaka }
138971928e68SAkira Hatanaka 
DecodePtrRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)13904ae9745aSMaksim Panchenko static DecodeStatus DecodePtrRegisterClass(MCInst &Inst, unsigned RegNo,
13919bfa2e2eSAkira Hatanaka                                            uint64_t Address,
13924ae9745aSMaksim Panchenko                                            const MCDisassembler *Decoder) {
1393a19216c8SDaniel Sanders   if (static_cast<const MipsDisassembler *>(Decoder)->isGP64())
13949bfa2e2eSAkira Hatanaka     return DecodeGPR64RegisterClass(Inst, RegNo, Address, Decoder);
13959bfa2e2eSAkira Hatanaka 
13969bfa2e2eSAkira Hatanaka   return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
13979bfa2e2eSAkira Hatanaka }
13989bfa2e2eSAkira Hatanaka 
DecodeDSPRRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)13994ae9745aSMaksim Panchenko static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst, unsigned RegNo,
1400ecabd1a5SAkira Hatanaka                                             uint64_t Address,
14014ae9745aSMaksim Panchenko                                             const MCDisassembler *Decoder) {
140213e6ccf3SAkira Hatanaka   return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
1403ecabd1a5SAkira Hatanaka }
1404ecabd1a5SAkira Hatanaka 
DecodeFGR64RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)14054ae9745aSMaksim Panchenko static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst, unsigned RegNo,
140671928e68SAkira Hatanaka                                              uint64_t Address,
14074ae9745aSMaksim Panchenko                                              const MCDisassembler *Decoder) {
140871928e68SAkira Hatanaka   if (RegNo > 31)
140971928e68SAkira Hatanaka     return MCDisassembler::Fail;
141071928e68SAkira Hatanaka 
14119bf2b567SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::FGR64RegClassID, RegNo);
1412e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
141371928e68SAkira Hatanaka   return MCDisassembler::Success;
141471928e68SAkira Hatanaka }
141571928e68SAkira Hatanaka 
DecodeFGR32RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)14164ae9745aSMaksim Panchenko static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst, unsigned RegNo,
141771928e68SAkira Hatanaka                                              uint64_t Address,
14184ae9745aSMaksim Panchenko                                              const MCDisassembler *Decoder) {
141971928e68SAkira Hatanaka   if (RegNo > 31)
142071928e68SAkira Hatanaka     return MCDisassembler::Fail;
142171928e68SAkira Hatanaka 
14229bf2b567SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::FGR32RegClassID, RegNo);
1423e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
142471928e68SAkira Hatanaka   return MCDisassembler::Success;
142571928e68SAkira Hatanaka }
142671928e68SAkira Hatanaka 
DecodeCCRRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)14274ae9745aSMaksim Panchenko static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst, unsigned RegNo,
142871928e68SAkira Hatanaka                                            uint64_t Address,
14294ae9745aSMaksim Panchenko                                            const MCDisassembler *Decoder) {
1430253777fdSChad Rosier   if (RegNo > 31)
1431253777fdSChad Rosier     return MCDisassembler::Fail;
1432253777fdSChad Rosier   unsigned Reg = getReg(Decoder, Mips::CCRRegClassID, RegNo);
1433e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
143471928e68SAkira Hatanaka   return MCDisassembler::Success;
143571928e68SAkira Hatanaka }
143671928e68SAkira Hatanaka 
DecodeFCCRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)14374ae9745aSMaksim Panchenko static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst, unsigned RegNo,
14381fb1b8b8SAkira Hatanaka                                            uint64_t Address,
14394ae9745aSMaksim Panchenko                                            const MCDisassembler *Decoder) {
14401fb1b8b8SAkira Hatanaka   if (RegNo > 7)
14411fb1b8b8SAkira Hatanaka     return MCDisassembler::Fail;
14421fb1b8b8SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::FCCRegClassID, RegNo);
1443e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
14441fb1b8b8SAkira Hatanaka   return MCDisassembler::Success;
14451fb1b8b8SAkira Hatanaka }
14461fb1b8b8SAkira Hatanaka 
DecodeFGRCCRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)144736901dd1SVasileios Kalintiris static DecodeStatus DecodeFGRCCRegisterClass(MCInst &Inst, unsigned RegNo,
14480fa60416SDaniel Sanders                                              uint64_t Address,
14494ae9745aSMaksim Panchenko                                              const MCDisassembler *Decoder) {
14500fa60416SDaniel Sanders   if (RegNo > 31)
14510fa60416SDaniel Sanders     return MCDisassembler::Fail;
14520fa60416SDaniel Sanders 
145336901dd1SVasileios Kalintiris   unsigned Reg = getReg(Decoder, Mips::FGRCCRegClassID, RegNo);
1454e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
14550fa60416SDaniel Sanders   return MCDisassembler::Success;
14560fa60416SDaniel Sanders }
14570fa60416SDaniel Sanders 
DecodeMem(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)14584ae9745aSMaksim Panchenko static DecodeStatus DecodeMem(MCInst &Inst, unsigned Insn, uint64_t Address,
14594ae9745aSMaksim Panchenko                               const MCDisassembler *Decoder) {
146071928e68SAkira Hatanaka   int Offset = SignExtend32<16>(Insn & 0xffff);
1461ecaef49fSJim Grosbach   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1462ecaef49fSJim Grosbach   unsigned Base = fieldFromInstruction(Insn, 21, 5);
14639bf2b567SAkira Hatanaka 
146413e6ccf3SAkira Hatanaka   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
146513e6ccf3SAkira Hatanaka   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
146671928e68SAkira Hatanaka 
1467d7ecf49eSVladimir Medic   if (Inst.getOpcode() == Mips::SC ||
1468e4e83a7bSDaniel Sanders       Inst.getOpcode() == Mips::SCD)
1469e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Reg));
1470e4e83a7bSDaniel Sanders 
1471e4e83a7bSDaniel Sanders   Inst.addOperand(MCOperand::createReg(Reg));
1472e4e83a7bSDaniel Sanders   Inst.addOperand(MCOperand::createReg(Base));
1473e4e83a7bSDaniel Sanders   Inst.addOperand(MCOperand::createImm(Offset));
1474e4e83a7bSDaniel Sanders 
1475e4e83a7bSDaniel Sanders   return MCDisassembler::Success;
147671928e68SAkira Hatanaka }
147771928e68SAkira Hatanaka 
DecodeMemEVA(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)14784ae9745aSMaksim Panchenko static DecodeStatus DecodeMemEVA(MCInst &Inst, unsigned Insn, uint64_t Address,
14794ae9745aSMaksim Panchenko                                  const MCDisassembler *Decoder) {
1480e4e83a7bSDaniel Sanders   int Offset = SignExtend32<9>(Insn >> 7);
1481e4e83a7bSDaniel Sanders   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1482e4e83a7bSDaniel Sanders   unsigned Base = fieldFromInstruction(Insn, 21, 5);
1483e4e83a7bSDaniel Sanders 
1484e4e83a7bSDaniel Sanders   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1485e4e83a7bSDaniel Sanders   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1486e4e83a7bSDaniel Sanders 
1487e4e83a7bSDaniel Sanders    if (Inst.getOpcode() == Mips::SCE)
1488e4e83a7bSDaniel Sanders      Inst.addOperand(MCOperand::createReg(Reg));
1489e4e83a7bSDaniel Sanders 
1490e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1491e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1492e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
149371928e68SAkira Hatanaka 
149471928e68SAkira Hatanaka   return MCDisassembler::Success;
149571928e68SAkira Hatanaka }
149671928e68SAkira Hatanaka 
DecodeLoadByte15(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)14974ae9745aSMaksim Panchenko static DecodeStatus DecodeLoadByte15(MCInst &Inst, unsigned Insn,
14983c88fbd3SHrvoje Varga                                      uint64_t Address,
14994ae9745aSMaksim Panchenko                                      const MCDisassembler *Decoder) {
15003c88fbd3SHrvoje Varga   int Offset = SignExtend32<16>(Insn & 0xffff);
15013c88fbd3SHrvoje Varga   unsigned Base = fieldFromInstruction(Insn, 16, 5);
15023c88fbd3SHrvoje Varga   unsigned Reg = fieldFromInstruction(Insn, 21, 5);
15033c88fbd3SHrvoje Varga 
15043c88fbd3SHrvoje Varga   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
15053c88fbd3SHrvoje Varga   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
15063c88fbd3SHrvoje Varga 
15073c88fbd3SHrvoje Varga   Inst.addOperand(MCOperand::createReg(Reg));
15083c88fbd3SHrvoje Varga   Inst.addOperand(MCOperand::createReg(Base));
15093c88fbd3SHrvoje Varga   Inst.addOperand(MCOperand::createImm(Offset));
15103c88fbd3SHrvoje Varga 
15113c88fbd3SHrvoje Varga   return MCDisassembler::Success;
15123c88fbd3SHrvoje Varga }
15133c88fbd3SHrvoje Varga 
DecodeCacheOp(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)15144ae9745aSMaksim Panchenko static DecodeStatus DecodeCacheOp(MCInst &Inst, unsigned Insn, uint64_t Address,
15154ae9745aSMaksim Panchenko                                   const MCDisassembler *Decoder) {
151692db6b78SDaniel Sanders   int Offset = SignExtend32<16>(Insn & 0xffff);
151792db6b78SDaniel Sanders   unsigned Hint = fieldFromInstruction(Insn, 16, 5);
151892db6b78SDaniel Sanders   unsigned Base = fieldFromInstruction(Insn, 21, 5);
151992db6b78SDaniel Sanders 
152092db6b78SDaniel Sanders   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
152192db6b78SDaniel Sanders 
1522e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1523e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
1524e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Hint));
152592db6b78SDaniel Sanders 
152692db6b78SDaniel Sanders   return MCDisassembler::Success;
152792db6b78SDaniel Sanders }
152892db6b78SDaniel Sanders 
DecodeCacheOpMM(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)15294ae9745aSMaksim Panchenko static DecodeStatus DecodeCacheOpMM(MCInst &Inst, unsigned Insn,
1530ab6d1cceSJozef Kolek                                     uint64_t Address,
15314ae9745aSMaksim Panchenko                                     const MCDisassembler *Decoder) {
1532ab6d1cceSJozef Kolek   int Offset = SignExtend32<12>(Insn & 0xfff);
1533ab6d1cceSJozef Kolek   unsigned Base = fieldFromInstruction(Insn, 16, 5);
1534ab6d1cceSJozef Kolek   unsigned Hint = fieldFromInstruction(Insn, 21, 5);
1535ab6d1cceSJozef Kolek 
1536ab6d1cceSJozef Kolek   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1537ab6d1cceSJozef Kolek 
1538e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1539e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
1540e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Hint));
1541ab6d1cceSJozef Kolek 
1542ab6d1cceSJozef Kolek   return MCDisassembler::Success;
1543ab6d1cceSJozef Kolek }
1544ab6d1cceSJozef Kolek 
DecodePrefeOpMM(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)15454ae9745aSMaksim Panchenko static DecodeStatus DecodePrefeOpMM(MCInst &Inst, unsigned Insn,
1546d9790793SZoran Jovanovic                                     uint64_t Address,
15474ae9745aSMaksim Panchenko                                     const MCDisassembler *Decoder) {
1548d9790793SZoran Jovanovic   int Offset = SignExtend32<9>(Insn & 0x1ff);
1549d9790793SZoran Jovanovic   unsigned Base = fieldFromInstruction(Insn, 16, 5);
1550d9790793SZoran Jovanovic   unsigned Hint = fieldFromInstruction(Insn, 21, 5);
1551d9790793SZoran Jovanovic 
1552d9790793SZoran Jovanovic   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1553d9790793SZoran Jovanovic 
1554d9790793SZoran Jovanovic   Inst.addOperand(MCOperand::createReg(Base));
1555d9790793SZoran Jovanovic   Inst.addOperand(MCOperand::createImm(Offset));
1556d9790793SZoran Jovanovic   Inst.addOperand(MCOperand::createImm(Hint));
1557d9790793SZoran Jovanovic 
1558d9790793SZoran Jovanovic   return MCDisassembler::Success;
1559d9790793SZoran Jovanovic }
1560d9790793SZoran Jovanovic 
DecodeCacheeOp_CacheOpR6(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)15614ae9745aSMaksim Panchenko static DecodeStatus DecodeCacheeOp_CacheOpR6(MCInst &Inst, unsigned Insn,
1562df464ae2SVladimir Medic                                              uint64_t Address,
15634ae9745aSMaksim Panchenko                                              const MCDisassembler *Decoder) {
1564e4e83a7bSDaniel Sanders   int Offset = SignExtend32<9>(Insn >> 7);
1565df464ae2SVladimir Medic   unsigned Hint = fieldFromInstruction(Insn, 16, 5);
1566df464ae2SVladimir Medic   unsigned Base = fieldFromInstruction(Insn, 21, 5);
1567df464ae2SVladimir Medic 
1568df464ae2SVladimir Medic   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1569df464ae2SVladimir Medic 
1570e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1571e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
1572e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Hint));
1573df464ae2SVladimir Medic 
1574df464ae2SVladimir Medic   return MCDisassembler::Success;
1575df464ae2SVladimir Medic }
1576df464ae2SVladimir Medic 
DecodeSyncI(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)15774ae9745aSMaksim Panchenko static DecodeStatus DecodeSyncI(MCInst &Inst, unsigned Insn, uint64_t Address,
15784ae9745aSMaksim Panchenko                                 const MCDisassembler *Decoder) {
1579b4484d62SDaniel Sanders   int Offset = SignExtend32<16>(Insn & 0xffff);
1580b4484d62SDaniel Sanders   unsigned Base = fieldFromInstruction(Insn, 21, 5);
1581b4484d62SDaniel Sanders 
1582b4484d62SDaniel Sanders   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1583b4484d62SDaniel Sanders 
1584e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1585e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
1586b4484d62SDaniel Sanders 
1587b4484d62SDaniel Sanders   return MCDisassembler::Success;
1588b4484d62SDaniel Sanders }
1589b4484d62SDaniel Sanders 
DecodeSyncI_MM(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)1590eac9301cSSimon Dardis static DecodeStatus DecodeSyncI_MM(MCInst &Inst, unsigned Insn,
15914ae9745aSMaksim Panchenko                                    uint64_t Address,
15924ae9745aSMaksim Panchenko                                    const MCDisassembler *Decoder) {
1593eac9301cSSimon Dardis   int Offset = SignExtend32<16>(Insn & 0xffff);
1594eac9301cSSimon Dardis   unsigned Base = fieldFromInstruction(Insn, 16, 5);
1595eac9301cSSimon Dardis 
1596eac9301cSSimon Dardis   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1597eac9301cSSimon Dardis 
1598eac9301cSSimon Dardis   Inst.addOperand(MCOperand::createReg(Base));
1599eac9301cSSimon Dardis   Inst.addOperand(MCOperand::createImm(Offset));
1600eac9301cSSimon Dardis 
1601eac9301cSSimon Dardis   return MCDisassembler::Success;
1602eac9301cSSimon Dardis }
1603eac9301cSSimon Dardis 
DecodeSynciR6(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)16044ae9745aSMaksim Panchenko static DecodeStatus DecodeSynciR6(MCInst &Inst, unsigned Insn, uint64_t Address,
16054ae9745aSMaksim Panchenko                                   const MCDisassembler *Decoder) {
160618148671SHrvoje Varga   int Immediate = SignExtend32<16>(Insn & 0xffff);
160718148671SHrvoje Varga   unsigned Base = fieldFromInstruction(Insn, 16, 5);
160818148671SHrvoje Varga 
160918148671SHrvoje Varga   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
161018148671SHrvoje Varga 
161118148671SHrvoje Varga   Inst.addOperand(MCOperand::createReg(Base));
161218148671SHrvoje Varga   Inst.addOperand(MCOperand::createImm(Immediate));
161318148671SHrvoje Varga 
161418148671SHrvoje Varga   return MCDisassembler::Success;
161518148671SHrvoje Varga }
161618148671SHrvoje Varga 
DecodeMSA128Mem(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)1617fe0bf9f6SMatheus Almeida static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn,
16184ae9745aSMaksim Panchenko                                     uint64_t Address,
16194ae9745aSMaksim Panchenko                                     const MCDisassembler *Decoder) {
1620fe0bf9f6SMatheus Almeida   int Offset = SignExtend32<10>(fieldFromInstruction(Insn, 16, 10));
1621fe0bf9f6SMatheus Almeida   unsigned Reg = fieldFromInstruction(Insn, 6, 5);
1622fe0bf9f6SMatheus Almeida   unsigned Base = fieldFromInstruction(Insn, 11, 5);
1623fe0bf9f6SMatheus Almeida 
1624fe0bf9f6SMatheus Almeida   Reg = getReg(Decoder, Mips::MSA128BRegClassID, Reg);
1625fe0bf9f6SMatheus Almeida   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1626fe0bf9f6SMatheus Almeida 
1627e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1628e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
16296b59c449SMatheus Almeida 
16306b59c449SMatheus Almeida   // The immediate field of an LD/ST instruction is scaled which means it must
16316b59c449SMatheus Almeida   // be multiplied (when decoding) by the size (in bytes) of the instructions'
16326b59c449SMatheus Almeida   // data format.
16336b59c449SMatheus Almeida   // .b - 1 byte
16346b59c449SMatheus Almeida   // .h - 2 bytes
16356b59c449SMatheus Almeida   // .w - 4 bytes
16366b59c449SMatheus Almeida   // .d - 8 bytes
16376b59c449SMatheus Almeida   switch(Inst.getOpcode())
16386b59c449SMatheus Almeida   {
16396b59c449SMatheus Almeida   default:
1640926883e1SEugene Zelenko     assert(false && "Unexpected instruction");
16416b59c449SMatheus Almeida     return MCDisassembler::Fail;
16426b59c449SMatheus Almeida     break;
16436b59c449SMatheus Almeida   case Mips::LD_B:
16446b59c449SMatheus Almeida   case Mips::ST_B:
1645e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(Offset));
16466b59c449SMatheus Almeida     break;
16476b59c449SMatheus Almeida   case Mips::LD_H:
16486b59c449SMatheus Almeida   case Mips::ST_H:
1649e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(Offset * 2));
16506b59c449SMatheus Almeida     break;
16516b59c449SMatheus Almeida   case Mips::LD_W:
16526b59c449SMatheus Almeida   case Mips::ST_W:
1653e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(Offset * 4));
16546b59c449SMatheus Almeida     break;
16556b59c449SMatheus Almeida   case Mips::LD_D:
16566b59c449SMatheus Almeida   case Mips::ST_D:
1657e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(Offset * 8));
16586b59c449SMatheus Almeida     break;
16596b59c449SMatheus Almeida   }
1660fe0bf9f6SMatheus Almeida 
1661fe0bf9f6SMatheus Almeida   return MCDisassembler::Success;
1662fe0bf9f6SMatheus Almeida }
1663fe0bf9f6SMatheus Almeida 
DecodeMemMMImm4(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)16644ae9745aSMaksim Panchenko static DecodeStatus DecodeMemMMImm4(MCInst &Inst, unsigned Insn,
1665315e7ecaSJozef Kolek                                     uint64_t Address,
16664ae9745aSMaksim Panchenko                                     const MCDisassembler *Decoder) {
1667315e7ecaSJozef Kolek   unsigned Offset = Insn & 0xf;
1668315e7ecaSJozef Kolek   unsigned Reg = fieldFromInstruction(Insn, 7, 3);
1669315e7ecaSJozef Kolek   unsigned Base = fieldFromInstruction(Insn, 4, 3);
1670315e7ecaSJozef Kolek 
1671315e7ecaSJozef Kolek   switch (Inst.getOpcode()) {
1672315e7ecaSJozef Kolek     case Mips::LBU16_MM:
1673315e7ecaSJozef Kolek     case Mips::LHU16_MM:
1674315e7ecaSJozef Kolek     case Mips::LW16_MM:
1675315e7ecaSJozef Kolek       if (DecodeGPRMM16RegisterClass(Inst, Reg, Address, Decoder)
1676315e7ecaSJozef Kolek             == MCDisassembler::Fail)
1677315e7ecaSJozef Kolek         return MCDisassembler::Fail;
1678315e7ecaSJozef Kolek       break;
1679315e7ecaSJozef Kolek     case Mips::SB16_MM:
1680797c2aecSZlatko Buljan     case Mips::SB16_MMR6:
1681315e7ecaSJozef Kolek     case Mips::SH16_MM:
1682797c2aecSZlatko Buljan     case Mips::SH16_MMR6:
1683315e7ecaSJozef Kolek     case Mips::SW16_MM:
1684797c2aecSZlatko Buljan     case Mips::SW16_MMR6:
1685315e7ecaSJozef Kolek       if (DecodeGPRMM16ZeroRegisterClass(Inst, Reg, Address, Decoder)
1686315e7ecaSJozef Kolek             == MCDisassembler::Fail)
1687315e7ecaSJozef Kolek         return MCDisassembler::Fail;
1688315e7ecaSJozef Kolek       break;
1689315e7ecaSJozef Kolek   }
1690315e7ecaSJozef Kolek 
1691315e7ecaSJozef Kolek   if (DecodeGPRMM16RegisterClass(Inst, Base, Address, Decoder)
1692315e7ecaSJozef Kolek         == MCDisassembler::Fail)
1693315e7ecaSJozef Kolek     return MCDisassembler::Fail;
1694315e7ecaSJozef Kolek 
1695315e7ecaSJozef Kolek   switch (Inst.getOpcode()) {
1696315e7ecaSJozef Kolek     case Mips::LBU16_MM:
1697315e7ecaSJozef Kolek       if (Offset == 0xf)
1698e9119e41SJim Grosbach         Inst.addOperand(MCOperand::createImm(-1));
1699315e7ecaSJozef Kolek       else
1700e9119e41SJim Grosbach         Inst.addOperand(MCOperand::createImm(Offset));
1701315e7ecaSJozef Kolek       break;
1702315e7ecaSJozef Kolek     case Mips::SB16_MM:
1703797c2aecSZlatko Buljan     case Mips::SB16_MMR6:
1704e9119e41SJim Grosbach       Inst.addOperand(MCOperand::createImm(Offset));
1705315e7ecaSJozef Kolek       break;
1706315e7ecaSJozef Kolek     case Mips::LHU16_MM:
1707315e7ecaSJozef Kolek     case Mips::SH16_MM:
1708797c2aecSZlatko Buljan     case Mips::SH16_MMR6:
1709e9119e41SJim Grosbach       Inst.addOperand(MCOperand::createImm(Offset << 1));
1710315e7ecaSJozef Kolek       break;
1711315e7ecaSJozef Kolek     case Mips::LW16_MM:
1712315e7ecaSJozef Kolek     case Mips::SW16_MM:
1713797c2aecSZlatko Buljan     case Mips::SW16_MMR6:
1714e9119e41SJim Grosbach       Inst.addOperand(MCOperand::createImm(Offset << 2));
1715315e7ecaSJozef Kolek       break;
1716315e7ecaSJozef Kolek   }
1717315e7ecaSJozef Kolek 
1718315e7ecaSJozef Kolek   return MCDisassembler::Success;
1719315e7ecaSJozef Kolek }
1720315e7ecaSJozef Kolek 
DecodeMemMMSPImm5Lsl2(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)17214ae9745aSMaksim Panchenko static DecodeStatus DecodeMemMMSPImm5Lsl2(MCInst &Inst, unsigned Insn,
172212c6982bSJozef Kolek                                           uint64_t Address,
17234ae9745aSMaksim Panchenko                                           const MCDisassembler *Decoder) {
172412c6982bSJozef Kolek   unsigned Offset = Insn & 0x1F;
172512c6982bSJozef Kolek   unsigned Reg = fieldFromInstruction(Insn, 5, 5);
172612c6982bSJozef Kolek 
172712c6982bSJozef Kolek   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
172812c6982bSJozef Kolek 
1729e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1730e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Mips::SP));
1731e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset << 2));
173212c6982bSJozef Kolek 
173312c6982bSJozef Kolek   return MCDisassembler::Success;
173412c6982bSJozef Kolek }
173512c6982bSJozef Kolek 
DecodeMemMMGPImm7Lsl2(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)17364ae9745aSMaksim Panchenko static DecodeStatus DecodeMemMMGPImm7Lsl2(MCInst &Inst, unsigned Insn,
1737e10a02ecSJozef Kolek                                           uint64_t Address,
17384ae9745aSMaksim Panchenko                                           const MCDisassembler *Decoder) {
1739e10a02ecSJozef Kolek   unsigned Offset = Insn & 0x7F;
1740e10a02ecSJozef Kolek   unsigned Reg = fieldFromInstruction(Insn, 7, 3);
1741e10a02ecSJozef Kolek 
1742e10a02ecSJozef Kolek   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1743e10a02ecSJozef Kolek 
1744e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1745e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Mips::GP));
1746e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset << 2));
1747e10a02ecSJozef Kolek 
1748e10a02ecSJozef Kolek   return MCDisassembler::Success;
1749e10a02ecSJozef Kolek }
1750e10a02ecSJozef Kolek 
DecodeMemMMReglistImm4Lsl2(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)17514ae9745aSMaksim Panchenko static DecodeStatus DecodeMemMMReglistImm4Lsl2(MCInst &Inst, unsigned Insn,
1752d68d424aSJozef Kolek                                                uint64_t Address,
17534ae9745aSMaksim Panchenko                                                const MCDisassembler *Decoder) {
1754797c2aecSZlatko Buljan   int Offset;
1755797c2aecSZlatko Buljan   switch (Inst.getOpcode()) {
1756797c2aecSZlatko Buljan   case Mips::LWM16_MMR6:
1757797c2aecSZlatko Buljan   case Mips::SWM16_MMR6:
1758797c2aecSZlatko Buljan     Offset = fieldFromInstruction(Insn, 4, 4);
1759797c2aecSZlatko Buljan     break;
1760797c2aecSZlatko Buljan   default:
1761797c2aecSZlatko Buljan     Offset = SignExtend32<4>(Insn & 0xf);
1762797c2aecSZlatko Buljan     break;
1763797c2aecSZlatko Buljan   }
1764d68d424aSJozef Kolek 
1765d68d424aSJozef Kolek   if (DecodeRegListOperand16(Inst, Insn, Address, Decoder)
1766d68d424aSJozef Kolek       == MCDisassembler::Fail)
1767d68d424aSJozef Kolek     return MCDisassembler::Fail;
1768d68d424aSJozef Kolek 
1769e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Mips::SP));
1770e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset << 2));
1771d68d424aSJozef Kolek 
1772d68d424aSJozef Kolek   return MCDisassembler::Success;
1773d68d424aSJozef Kolek }
1774d68d424aSJozef Kolek 
DecodeMemMMImm9(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)17754ae9745aSMaksim Panchenko static DecodeStatus DecodeMemMMImm9(MCInst &Inst, unsigned Insn,
1776a6593ff6SZoran Jovanovic                                     uint64_t Address,
17774ae9745aSMaksim Panchenko                                     const MCDisassembler *Decoder) {
1778a6593ff6SZoran Jovanovic   int Offset = SignExtend32<9>(Insn & 0x1ff);
1779a6593ff6SZoran Jovanovic   unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1780a6593ff6SZoran Jovanovic   unsigned Base = fieldFromInstruction(Insn, 16, 5);
1781a6593ff6SZoran Jovanovic 
1782a6593ff6SZoran Jovanovic   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1783a6593ff6SZoran Jovanovic   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1784a6593ff6SZoran Jovanovic 
1785777afc7fSSimon Dardis   if (Inst.getOpcode() == Mips::SCE_MM || Inst.getOpcode() == Mips::SC_MMR6)
17863ef4dd7bSHrvoje Varga     Inst.addOperand(MCOperand::createReg(Reg));
17873ef4dd7bSHrvoje Varga 
1788a6593ff6SZoran Jovanovic   Inst.addOperand(MCOperand::createReg(Reg));
1789a6593ff6SZoran Jovanovic   Inst.addOperand(MCOperand::createReg(Base));
1790a6593ff6SZoran Jovanovic   Inst.addOperand(MCOperand::createImm(Offset));
1791a6593ff6SZoran Jovanovic 
1792a6593ff6SZoran Jovanovic   return MCDisassembler::Success;
1793a6593ff6SZoran Jovanovic }
1794a6593ff6SZoran Jovanovic 
DecodeMemMMImm12(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)17954ae9745aSMaksim Panchenko static DecodeStatus DecodeMemMMImm12(MCInst &Inst, unsigned Insn,
1796dde3d582SVladimir Medic                                      uint64_t Address,
17974ae9745aSMaksim Panchenko                                      const MCDisassembler *Decoder) {
1798dde3d582SVladimir Medic   int Offset = SignExtend32<12>(Insn & 0x0fff);
1799dde3d582SVladimir Medic   unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1800dde3d582SVladimir Medic   unsigned Base = fieldFromInstruction(Insn, 16, 5);
1801dde3d582SVladimir Medic 
1802dde3d582SVladimir Medic   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1803dde3d582SVladimir Medic   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1804dde3d582SVladimir Medic 
1805a4c4b5fcSZoran Jovanovic   switch (Inst.getOpcode()) {
1806a4c4b5fcSZoran Jovanovic   case Mips::SWM32_MM:
1807a4c4b5fcSZoran Jovanovic   case Mips::LWM32_MM:
1808a4c4b5fcSZoran Jovanovic     if (DecodeRegListOperand(Inst, Insn, Address, Decoder)
1809a4c4b5fcSZoran Jovanovic         == MCDisassembler::Fail)
1810a4c4b5fcSZoran Jovanovic       return MCDisassembler::Fail;
1811e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Base));
1812e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(Offset));
1813a4c4b5fcSZoran Jovanovic     break;
1814a4c4b5fcSZoran Jovanovic   case Mips::SC_MM:
1815e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Reg));
1816b03fd12cSJustin Bogner     LLVM_FALLTHROUGH;
1817a4c4b5fcSZoran Jovanovic   default:
1818e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Reg));
18196a319923SSimon Dardis     if (Inst.getOpcode() == Mips::LWP_MM || Inst.getOpcode() == Mips::SWP_MM)
1820e9119e41SJim Grosbach       Inst.addOperand(MCOperand::createReg(Reg+1));
18212deca348SZoran Jovanovic 
1822e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Base));
1823e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(Offset));
1824a4c4b5fcSZoran Jovanovic   }
1825dde3d582SVladimir Medic 
1826dde3d582SVladimir Medic   return MCDisassembler::Success;
1827dde3d582SVladimir Medic }
1828dde3d582SVladimir Medic 
DecodeMemMMImm16(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)18294ae9745aSMaksim Panchenko static DecodeStatus DecodeMemMMImm16(MCInst &Inst, unsigned Insn,
1830dde3d582SVladimir Medic                                      uint64_t Address,
18314ae9745aSMaksim Panchenko                                      const MCDisassembler *Decoder) {
1832dde3d582SVladimir Medic   int Offset = SignExtend32<16>(Insn & 0xffff);
1833dde3d582SVladimir Medic   unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1834dde3d582SVladimir Medic   unsigned Base = fieldFromInstruction(Insn, 16, 5);
1835dde3d582SVladimir Medic 
1836dde3d582SVladimir Medic   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1837dde3d582SVladimir Medic   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1838dde3d582SVladimir Medic 
1839e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1840e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1841e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
1842dde3d582SVladimir Medic 
1843dde3d582SVladimir Medic   return MCDisassembler::Success;
1844dde3d582SVladimir Medic }
1845dde3d582SVladimir Medic 
DecodeFMem(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)18464ae9745aSMaksim Panchenko static DecodeStatus DecodeFMem(MCInst &Inst, unsigned Insn, uint64_t Address,
18474ae9745aSMaksim Panchenko                                const MCDisassembler *Decoder) {
184871928e68SAkira Hatanaka   int Offset = SignExtend32<16>(Insn & 0xffff);
1849ecaef49fSJim Grosbach   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1850ecaef49fSJim Grosbach   unsigned Base = fieldFromInstruction(Insn, 21, 5);
185171928e68SAkira Hatanaka 
18529bf2b567SAkira Hatanaka   Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg);
185313e6ccf3SAkira Hatanaka   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
18549bf2b567SAkira Hatanaka 
1855e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1856e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1857e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
185871928e68SAkira Hatanaka 
185971928e68SAkira Hatanaka   return MCDisassembler::Success;
186071928e68SAkira Hatanaka }
186171928e68SAkira Hatanaka 
DecodeFMemMMR2(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)1862cba9f80bSZlatko Buljan static DecodeStatus DecodeFMemMMR2(MCInst &Inst, unsigned Insn,
18634ae9745aSMaksim Panchenko                                    uint64_t Address,
18644ae9745aSMaksim Panchenko                                    const MCDisassembler *Decoder) {
1865cba9f80bSZlatko Buljan   // This function is the same as DecodeFMem but with the Reg and Base fields
1866cba9f80bSZlatko Buljan   // swapped according to microMIPS spec.
1867cba9f80bSZlatko Buljan   int Offset = SignExtend32<16>(Insn & 0xffff);
1868cba9f80bSZlatko Buljan   unsigned Base = fieldFromInstruction(Insn, 16, 5);
1869cba9f80bSZlatko Buljan   unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1870cba9f80bSZlatko Buljan 
1871cba9f80bSZlatko Buljan   Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg);
1872cba9f80bSZlatko Buljan   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1873cba9f80bSZlatko Buljan 
1874cba9f80bSZlatko Buljan   Inst.addOperand(MCOperand::createReg(Reg));
1875cba9f80bSZlatko Buljan   Inst.addOperand(MCOperand::createReg(Base));
1876cba9f80bSZlatko Buljan   Inst.addOperand(MCOperand::createImm(Offset));
1877cba9f80bSZlatko Buljan 
1878cba9f80bSZlatko Buljan   return MCDisassembler::Success;
1879cba9f80bSZlatko Buljan }
1880cba9f80bSZlatko Buljan 
DecodeFMem2(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)18814ae9745aSMaksim Panchenko static DecodeStatus DecodeFMem2(MCInst &Inst, unsigned Insn, uint64_t Address,
18824ae9745aSMaksim Panchenko                                 const MCDisassembler *Decoder) {
188392db6b78SDaniel Sanders   int Offset = SignExtend32<16>(Insn & 0xffff);
188492db6b78SDaniel Sanders   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
188592db6b78SDaniel Sanders   unsigned Base = fieldFromInstruction(Insn, 21, 5);
188692db6b78SDaniel Sanders 
188792db6b78SDaniel Sanders   Reg = getReg(Decoder, Mips::COP2RegClassID, Reg);
188892db6b78SDaniel Sanders   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
188992db6b78SDaniel Sanders 
1890e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1891e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1892e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
189392db6b78SDaniel Sanders 
189492db6b78SDaniel Sanders   return MCDisassembler::Success;
189592db6b78SDaniel Sanders }
189692db6b78SDaniel Sanders 
DecodeFMem3(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)18974ae9745aSMaksim Panchenko static DecodeStatus DecodeFMem3(MCInst &Inst, unsigned Insn, uint64_t Address,
18984ae9745aSMaksim Panchenko                                 const MCDisassembler *Decoder) {
189992db6b78SDaniel Sanders   int Offset = SignExtend32<16>(Insn & 0xffff);
190092db6b78SDaniel Sanders   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
190192db6b78SDaniel Sanders   unsigned Base = fieldFromInstruction(Insn, 21, 5);
190292db6b78SDaniel Sanders 
190392db6b78SDaniel Sanders   Reg = getReg(Decoder, Mips::COP3RegClassID, Reg);
190492db6b78SDaniel Sanders   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
190592db6b78SDaniel Sanders 
1906e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1907e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1908e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
190992db6b78SDaniel Sanders 
191092db6b78SDaniel Sanders   return MCDisassembler::Success;
191192db6b78SDaniel Sanders }
191292db6b78SDaniel Sanders 
DecodeFMemCop2R6(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)19134ae9745aSMaksim Panchenko static DecodeStatus DecodeFMemCop2R6(MCInst &Inst, unsigned Insn,
1914435cf8a4SVladimir Medic                                      uint64_t Address,
19154ae9745aSMaksim Panchenko                                      const MCDisassembler *Decoder) {
1916435cf8a4SVladimir Medic   int Offset = SignExtend32<11>(Insn & 0x07ff);
1917435cf8a4SVladimir Medic   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1918435cf8a4SVladimir Medic   unsigned Base = fieldFromInstruction(Insn, 11, 5);
1919435cf8a4SVladimir Medic 
1920435cf8a4SVladimir Medic   Reg = getReg(Decoder, Mips::COP2RegClassID, Reg);
1921435cf8a4SVladimir Medic   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1922435cf8a4SVladimir Medic 
1923e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1924e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1925e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
1926435cf8a4SVladimir Medic 
1927435cf8a4SVladimir Medic   return MCDisassembler::Success;
1928435cf8a4SVladimir Medic }
1929cba9f80bSZlatko Buljan 
DecodeFMemCop2MMR6(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)1930cba9f80bSZlatko Buljan static DecodeStatus DecodeFMemCop2MMR6(MCInst &Inst, unsigned Insn,
19314ae9745aSMaksim Panchenko                                        uint64_t Address,
19324ae9745aSMaksim Panchenko                                        const MCDisassembler *Decoder) {
1933cba9f80bSZlatko Buljan   int Offset = SignExtend32<11>(Insn & 0x07ff);
1934cba9f80bSZlatko Buljan   unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1935cba9f80bSZlatko Buljan   unsigned Base = fieldFromInstruction(Insn, 16, 5);
1936cba9f80bSZlatko Buljan 
1937cba9f80bSZlatko Buljan   Reg = getReg(Decoder, Mips::COP2RegClassID, Reg);
1938cba9f80bSZlatko Buljan   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1939cba9f80bSZlatko Buljan 
1940cba9f80bSZlatko Buljan   Inst.addOperand(MCOperand::createReg(Reg));
1941cba9f80bSZlatko Buljan   Inst.addOperand(MCOperand::createReg(Base));
1942cba9f80bSZlatko Buljan   Inst.addOperand(MCOperand::createImm(Offset));
1943cba9f80bSZlatko Buljan 
1944cba9f80bSZlatko Buljan   return MCDisassembler::Success;
1945cba9f80bSZlatko Buljan }
1946cba9f80bSZlatko Buljan 
DecodeSpecial3LlSc(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)19474ae9745aSMaksim Panchenko static DecodeStatus DecodeSpecial3LlSc(MCInst &Inst, unsigned Insn,
19486a803f61SDaniel Sanders                                        uint64_t Address,
19494ae9745aSMaksim Panchenko                                        const MCDisassembler *Decoder) {
19506a803f61SDaniel Sanders   int64_t Offset = SignExtend64<9>((Insn >> 7) & 0x1ff);
19516a803f61SDaniel Sanders   unsigned Rt = fieldFromInstruction(Insn, 16, 5);
19526a803f61SDaniel Sanders   unsigned Base = fieldFromInstruction(Insn, 21, 5);
19536a803f61SDaniel Sanders 
19546a803f61SDaniel Sanders   Rt = getReg(Decoder, Mips::GPR32RegClassID, Rt);
19556a803f61SDaniel Sanders   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
19566a803f61SDaniel Sanders 
19576a803f61SDaniel Sanders   if(Inst.getOpcode() == Mips::SC_R6 || Inst.getOpcode() == Mips::SCD_R6){
1958e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Rt));
19596a803f61SDaniel Sanders   }
19606a803f61SDaniel Sanders 
1961e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Rt));
1962e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base));
1963e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Offset));
19646a803f61SDaniel Sanders 
19656a803f61SDaniel Sanders   return MCDisassembler::Success;
19666a803f61SDaniel Sanders }
196771928e68SAkira Hatanaka 
DecodeHWRegsRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)19684ae9745aSMaksim Panchenko static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst, unsigned RegNo,
196971928e68SAkira Hatanaka                                               uint64_t Address,
19704ae9745aSMaksim Panchenko                                               const MCDisassembler *Decoder) {
197171928e68SAkira Hatanaka   // Currently only hardware register 29 is supported.
197271928e68SAkira Hatanaka   if (RegNo != 29)
197371928e68SAkira Hatanaka     return  MCDisassembler::Fail;
1974e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Mips::HWR29));
197571928e68SAkira Hatanaka   return MCDisassembler::Success;
197671928e68SAkira Hatanaka }
197771928e68SAkira Hatanaka 
DecodeAFGR64RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)19784ae9745aSMaksim Panchenko static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst, unsigned RegNo,
197971928e68SAkira Hatanaka                                               uint64_t Address,
19804ae9745aSMaksim Panchenko                                               const MCDisassembler *Decoder) {
19819bf2b567SAkira Hatanaka   if (RegNo > 30 || RegNo %2)
198271928e68SAkira Hatanaka     return MCDisassembler::Fail;
198371928e68SAkira Hatanaka 
19849bf2b567SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::AFGR64RegClassID, RegNo /2);
1985e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
198671928e68SAkira Hatanaka   return MCDisassembler::Success;
198771928e68SAkira Hatanaka }
198871928e68SAkira Hatanaka 
DecodeACC64DSPRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)19894ae9745aSMaksim Panchenko static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst, unsigned RegNo,
1990ecabd1a5SAkira Hatanaka                                                 uint64_t Address,
19914ae9745aSMaksim Panchenko                                                 const MCDisassembler *Decoder) {
1992ecabd1a5SAkira Hatanaka   if (RegNo >= 4)
1993ecabd1a5SAkira Hatanaka     return MCDisassembler::Fail;
1994ecabd1a5SAkira Hatanaka 
199500fcf2e1SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::ACC64DSPRegClassID, RegNo);
1996e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
1997ecabd1a5SAkira Hatanaka   return MCDisassembler::Success;
1998ecabd1a5SAkira Hatanaka }
1999ecabd1a5SAkira Hatanaka 
DecodeHI32DSPRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)20004ae9745aSMaksim Panchenko static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst, unsigned RegNo,
200159bfaf77SAkira Hatanaka                                                uint64_t Address,
20024ae9745aSMaksim Panchenko                                                const MCDisassembler *Decoder) {
200359bfaf77SAkira Hatanaka   if (RegNo >= 4)
200459bfaf77SAkira Hatanaka     return MCDisassembler::Fail;
200559bfaf77SAkira Hatanaka 
20068002a3f6SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::HI32DSPRegClassID, RegNo);
2007e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
200859bfaf77SAkira Hatanaka   return MCDisassembler::Success;
200959bfaf77SAkira Hatanaka }
201059bfaf77SAkira Hatanaka 
DecodeLO32DSPRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)20114ae9745aSMaksim Panchenko static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst, unsigned RegNo,
201259bfaf77SAkira Hatanaka                                                uint64_t Address,
20134ae9745aSMaksim Panchenko                                                const MCDisassembler *Decoder) {
201459bfaf77SAkira Hatanaka   if (RegNo >= 4)
201559bfaf77SAkira Hatanaka     return MCDisassembler::Fail;
201659bfaf77SAkira Hatanaka 
20178002a3f6SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::LO32DSPRegClassID, RegNo);
2018e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
201959bfaf77SAkira Hatanaka   return MCDisassembler::Success;
202059bfaf77SAkira Hatanaka }
202159bfaf77SAkira Hatanaka 
DecodeMSA128BRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)20224ae9745aSMaksim Panchenko static DecodeStatus DecodeMSA128BRegisterClass(MCInst &Inst, unsigned RegNo,
20233eb663b0SJack Carter                                                uint64_t Address,
20244ae9745aSMaksim Panchenko                                                const MCDisassembler *Decoder) {
20253eb663b0SJack Carter   if (RegNo > 31)
20263eb663b0SJack Carter     return MCDisassembler::Fail;
20273eb663b0SJack Carter 
20283eb663b0SJack Carter   unsigned Reg = getReg(Decoder, Mips::MSA128BRegClassID, RegNo);
2029e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
20303eb663b0SJack Carter   return MCDisassembler::Success;
20313eb663b0SJack Carter }
20323eb663b0SJack Carter 
DecodeMSA128HRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)20334ae9745aSMaksim Panchenko static DecodeStatus DecodeMSA128HRegisterClass(MCInst &Inst, unsigned RegNo,
20345dc8ac92SJack Carter                                                uint64_t Address,
20354ae9745aSMaksim Panchenko                                                const MCDisassembler *Decoder) {
20365dc8ac92SJack Carter   if (RegNo > 31)
20375dc8ac92SJack Carter     return MCDisassembler::Fail;
20385dc8ac92SJack Carter 
20395dc8ac92SJack Carter   unsigned Reg = getReg(Decoder, Mips::MSA128HRegClassID, RegNo);
2040e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
20415dc8ac92SJack Carter   return MCDisassembler::Success;
20425dc8ac92SJack Carter }
20435dc8ac92SJack Carter 
DecodeMSA128WRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)20444ae9745aSMaksim Panchenko static DecodeStatus DecodeMSA128WRegisterClass(MCInst &Inst, unsigned RegNo,
20455dc8ac92SJack Carter                                                uint64_t Address,
20464ae9745aSMaksim Panchenko                                                const MCDisassembler *Decoder) {
20475dc8ac92SJack Carter   if (RegNo > 31)
20485dc8ac92SJack Carter     return MCDisassembler::Fail;
20495dc8ac92SJack Carter 
20505dc8ac92SJack Carter   unsigned Reg = getReg(Decoder, Mips::MSA128WRegClassID, RegNo);
2051e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
20525dc8ac92SJack Carter   return MCDisassembler::Success;
20535dc8ac92SJack Carter }
20545dc8ac92SJack Carter 
DecodeMSA128DRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)20554ae9745aSMaksim Panchenko static DecodeStatus DecodeMSA128DRegisterClass(MCInst &Inst, unsigned RegNo,
20565dc8ac92SJack Carter                                                uint64_t Address,
20574ae9745aSMaksim Panchenko                                                const MCDisassembler *Decoder) {
20585dc8ac92SJack Carter   if (RegNo > 31)
20595dc8ac92SJack Carter     return MCDisassembler::Fail;
20605dc8ac92SJack Carter 
20615dc8ac92SJack Carter   unsigned Reg = getReg(Decoder, Mips::MSA128DRegClassID, RegNo);
2062e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
20635dc8ac92SJack Carter   return MCDisassembler::Success;
20645dc8ac92SJack Carter }
20655dc8ac92SJack Carter 
DecodeMSACtrlRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)20664ae9745aSMaksim Panchenko static DecodeStatus DecodeMSACtrlRegisterClass(MCInst &Inst, unsigned RegNo,
2067a591fdc6SMatheus Almeida                                                uint64_t Address,
20684ae9745aSMaksim Panchenko                                                const MCDisassembler *Decoder) {
2069a591fdc6SMatheus Almeida   if (RegNo > 7)
2070a591fdc6SMatheus Almeida     return MCDisassembler::Fail;
2071a591fdc6SMatheus Almeida 
2072a591fdc6SMatheus Almeida   unsigned Reg = getReg(Decoder, Mips::MSACtrlRegClassID, RegNo);
2073e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
2074a591fdc6SMatheus Almeida   return MCDisassembler::Success;
2075a591fdc6SMatheus Almeida }
2076a591fdc6SMatheus Almeida 
DecodeCOP0RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)20774ae9745aSMaksim Panchenko static DecodeStatus DecodeCOP0RegisterClass(MCInst &Inst, unsigned RegNo,
2078a3134faeSDaniel Sanders                                             uint64_t Address,
20794ae9745aSMaksim Panchenko                                             const MCDisassembler *Decoder) {
2080a3134faeSDaniel Sanders   if (RegNo > 31)
2081a3134faeSDaniel Sanders     return MCDisassembler::Fail;
2082a3134faeSDaniel Sanders 
2083a3134faeSDaniel Sanders   unsigned Reg = getReg(Decoder, Mips::COP0RegClassID, RegNo);
2084a3134faeSDaniel Sanders   Inst.addOperand(MCOperand::createReg(Reg));
2085a3134faeSDaniel Sanders   return MCDisassembler::Success;
2086a3134faeSDaniel Sanders }
2087a3134faeSDaniel Sanders 
DecodeCOP2RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)20884ae9745aSMaksim Panchenko static DecodeStatus DecodeCOP2RegisterClass(MCInst &Inst, unsigned RegNo,
20892a83d680SDaniel Sanders                                             uint64_t Address,
20904ae9745aSMaksim Panchenko                                             const MCDisassembler *Decoder) {
20912a83d680SDaniel Sanders   if (RegNo > 31)
20922a83d680SDaniel Sanders     return MCDisassembler::Fail;
20932a83d680SDaniel Sanders 
20942a83d680SDaniel Sanders   unsigned Reg = getReg(Decoder, Mips::COP2RegClassID, RegNo);
2095e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Reg));
20962a83d680SDaniel Sanders   return MCDisassembler::Success;
20972a83d680SDaniel Sanders }
20982a83d680SDaniel Sanders 
DecodeBranchTarget(MCInst & Inst,unsigned Offset,uint64_t Address,const MCDisassembler * Decoder)20994ae9745aSMaksim Panchenko static DecodeStatus DecodeBranchTarget(MCInst &Inst, unsigned Offset,
210071928e68SAkira Hatanaka                                        uint64_t Address,
21014ae9745aSMaksim Panchenko                                        const MCDisassembler *Decoder) {
2102d37bab61SAlexey Samsonov   int32_t BranchOffset = (SignExtend32<16>(Offset) * 4) + 4;
2103e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(BranchOffset));
210471928e68SAkira Hatanaka   return MCDisassembler::Success;
210571928e68SAkira Hatanaka }
210671928e68SAkira Hatanaka 
DecodeBranchTarget1SImm16(MCInst & Inst,unsigned Offset,uint64_t Address,const MCDisassembler * Decoder)21074ae9745aSMaksim Panchenko static DecodeStatus DecodeBranchTarget1SImm16(MCInst &Inst, unsigned Offset,
21086f09cdfdSHrvoje Varga                                               uint64_t Address,
21094ae9745aSMaksim Panchenko                                               const MCDisassembler *Decoder) {
21106f09cdfdSHrvoje Varga   int32_t BranchOffset = (SignExtend32<16>(Offset) * 2);
21116f09cdfdSHrvoje Varga   Inst.addOperand(MCOperand::createImm(BranchOffset));
21126f09cdfdSHrvoje Varga   return MCDisassembler::Success;
21136f09cdfdSHrvoje Varga }
21146f09cdfdSHrvoje Varga 
DecodeJumpTarget(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)21154ae9745aSMaksim Panchenko static DecodeStatus DecodeJumpTarget(MCInst &Inst, unsigned Insn,
211671928e68SAkira Hatanaka                                      uint64_t Address,
21174ae9745aSMaksim Panchenko                                      const MCDisassembler *Decoder) {
2118ecaef49fSJim Grosbach   unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 2;
2119e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(JumpOffset));
212071928e68SAkira Hatanaka   return MCDisassembler::Success;
212171928e68SAkira Hatanaka }
212271928e68SAkira Hatanaka 
DecodeBranchTarget21(MCInst & Inst,unsigned Offset,uint64_t Address,const MCDisassembler * Decoder)21234ae9745aSMaksim Panchenko static DecodeStatus DecodeBranchTarget21(MCInst &Inst, unsigned Offset,
21243c8869dcSZoran Jovanovic                                          uint64_t Address,
21254ae9745aSMaksim Panchenko                                          const MCDisassembler *Decoder) {
2126672c710dSSagar Thakur   int32_t BranchOffset = SignExtend32<21>(Offset) * 4 + 4;
21273c8869dcSZoran Jovanovic 
2128e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(BranchOffset));
21293c8869dcSZoran Jovanovic   return MCDisassembler::Success;
21303c8869dcSZoran Jovanovic }
21313c8869dcSZoran Jovanovic 
DecodeBranchTarget21MM(MCInst & Inst,unsigned Offset,uint64_t Address,const MCDisassembler * Decoder)21324ae9745aSMaksim Panchenko static DecodeStatus DecodeBranchTarget21MM(MCInst &Inst, unsigned Offset,
213384e4d59eSZoran Jovanovic                                            uint64_t Address,
21344ae9745aSMaksim Panchenko                                            const MCDisassembler *Decoder) {
2135f0ed16eaSHrvoje Varga   int32_t BranchOffset = SignExtend32<21>(Offset) * 4 + 4;
213684e4d59eSZoran Jovanovic 
213784e4d59eSZoran Jovanovic   Inst.addOperand(MCOperand::createImm(BranchOffset));
213884e4d59eSZoran Jovanovic   return MCDisassembler::Success;
213984e4d59eSZoran Jovanovic }
214084e4d59eSZoran Jovanovic 
DecodeBranchTarget26(MCInst & Inst,unsigned Offset,uint64_t Address,const MCDisassembler * Decoder)21414ae9745aSMaksim Panchenko static DecodeStatus DecodeBranchTarget26(MCInst &Inst, unsigned Offset,
21423c8869dcSZoran Jovanovic                                          uint64_t Address,
21434ae9745aSMaksim Panchenko                                          const MCDisassembler *Decoder) {
2144672c710dSSagar Thakur   int32_t BranchOffset = SignExtend32<26>(Offset) * 4 + 4;
21453c8869dcSZoran Jovanovic 
2146e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(BranchOffset));
21473c8869dcSZoran Jovanovic   return MCDisassembler::Success;
21483c8869dcSZoran Jovanovic }
21493c8869dcSZoran Jovanovic 
DecodeBranchTarget7MM(MCInst & Inst,unsigned Offset,uint64_t Address,const MCDisassembler * Decoder)21504ae9745aSMaksim Panchenko static DecodeStatus DecodeBranchTarget7MM(MCInst &Inst, unsigned Offset,
21519761e96bSJozef Kolek                                           uint64_t Address,
21524ae9745aSMaksim Panchenko                                           const MCDisassembler *Decoder) {
215372982e69SSimon Atanasyan   int32_t BranchOffset = SignExtend32<8>(Offset << 1);
2154e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(BranchOffset));
21559761e96bSJozef Kolek   return MCDisassembler::Success;
21569761e96bSJozef Kolek }
21579761e96bSJozef Kolek 
DecodeBranchTarget10MM(MCInst & Inst,unsigned Offset,uint64_t Address,const MCDisassembler * Decoder)21584ae9745aSMaksim Panchenko static DecodeStatus DecodeBranchTarget10MM(MCInst &Inst, unsigned Offset,
21595cfebddeSJozef Kolek                                            uint64_t Address,
21604ae9745aSMaksim Panchenko                                            const MCDisassembler *Decoder) {
216172982e69SSimon Atanasyan   int32_t BranchOffset = SignExtend32<11>(Offset << 1);
2162e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(BranchOffset));
21635cfebddeSJozef Kolek   return MCDisassembler::Success;
21645cfebddeSJozef Kolek }
21655cfebddeSJozef Kolek 
DecodeBranchTargetMM(MCInst & Inst,unsigned Offset,uint64_t Address,const MCDisassembler * Decoder)21664ae9745aSMaksim Panchenko static DecodeStatus DecodeBranchTargetMM(MCInst &Inst, unsigned Offset,
21678a80aa76SZoran Jovanovic                                          uint64_t Address,
21684ae9745aSMaksim Panchenko                                          const MCDisassembler *Decoder) {
2169f0ed16eaSHrvoje Varga   int32_t BranchOffset = SignExtend32<16>(Offset) * 2 + 4;
2170e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(BranchOffset));
21718a80aa76SZoran Jovanovic   return MCDisassembler::Success;
21728a80aa76SZoran Jovanovic }
21738a80aa76SZoran Jovanovic 
DecodeBranchTarget26MM(MCInst & Inst,unsigned Offset,uint64_t Address,const MCDisassembler * Decoder)21744ae9745aSMaksim Panchenko static DecodeStatus DecodeBranchTarget26MM(MCInst &Inst, unsigned Offset,
2175a887b361SZoran Jovanovic                                            uint64_t Address,
21764ae9745aSMaksim Panchenko                                            const MCDisassembler *Decoder) {
217772982e69SSimon Atanasyan   int32_t BranchOffset = SignExtend32<27>(Offset << 1);
2178a887b361SZoran Jovanovic 
2179a887b361SZoran Jovanovic   Inst.addOperand(MCOperand::createImm(BranchOffset));
2180a887b361SZoran Jovanovic   return MCDisassembler::Success;
2181a887b361SZoran Jovanovic }
2182a887b361SZoran Jovanovic 
DecodeJumpTargetMM(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)21834ae9745aSMaksim Panchenko static DecodeStatus DecodeJumpTargetMM(MCInst &Inst, unsigned Insn,
2184507e084aSZoran Jovanovic                                        uint64_t Address,
21854ae9745aSMaksim Panchenko                                        const MCDisassembler *Decoder) {
2186507e084aSZoran Jovanovic   unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 1;
2187e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(JumpOffset));
2188507e084aSZoran Jovanovic   return MCDisassembler::Success;
2189507e084aSZoran Jovanovic }
219071928e68SAkira Hatanaka 
DecodeJumpTargetXMM(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)21914ae9745aSMaksim Panchenko static DecodeStatus DecodeJumpTargetXMM(MCInst &Inst, unsigned Insn,
219256e4ea2bSSimon Atanasyan                                         uint64_t Address,
21934ae9745aSMaksim Panchenko                                         const MCDisassembler *Decoder) {
219456e4ea2bSSimon Atanasyan   unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 2;
219556e4ea2bSSimon Atanasyan   Inst.addOperand(MCOperand::createImm(JumpOffset));
219656e4ea2bSSimon Atanasyan   return MCDisassembler::Success;
219756e4ea2bSSimon Atanasyan }
219856e4ea2bSSimon Atanasyan 
DecodeAddiur2Simm7(MCInst & Inst,unsigned Value,uint64_t Address,const MCDisassembler * Decoder)21994ae9745aSMaksim Panchenko static DecodeStatus DecodeAddiur2Simm7(MCInst &Inst, unsigned Value,
2200aa2b9278SJozef Kolek                                        uint64_t Address,
22014ae9745aSMaksim Panchenko                                        const MCDisassembler *Decoder) {
2202aa2b9278SJozef Kolek   if (Value == 0)
2203e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(1));
2204aa2b9278SJozef Kolek   else if (Value == 0x7)
2205e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(-1));
2206aa2b9278SJozef Kolek   else
2207e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(Value << 2));
2208aa2b9278SJozef Kolek   return MCDisassembler::Success;
2209aa2b9278SJozef Kolek }
2210aa2b9278SJozef Kolek 
DecodeLi16Imm(MCInst & Inst,unsigned Value,uint64_t Address,const MCDisassembler * Decoder)22114ae9745aSMaksim Panchenko static DecodeStatus DecodeLi16Imm(MCInst &Inst, unsigned Value,
2212aa2b9278SJozef Kolek                                   uint64_t Address,
22134ae9745aSMaksim Panchenko                                   const MCDisassembler *Decoder) {
2214aa2b9278SJozef Kolek   if (Value == 0x7F)
2215e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(-1));
2216aa2b9278SJozef Kolek   else
2217e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(Value));
2218aa2b9278SJozef Kolek   return MCDisassembler::Success;
2219aa2b9278SJozef Kolek }
2220aa2b9278SJozef Kolek 
DecodePOOL16BEncodedField(MCInst & Inst,unsigned Value,uint64_t Address,const MCDisassembler * Decoder)22214ae9745aSMaksim Panchenko static DecodeStatus DecodePOOL16BEncodedField(MCInst &Inst, unsigned Value,
22226b28f09dSZoran Jovanovic                                               uint64_t Address,
22234ae9745aSMaksim Panchenko                                               const MCDisassembler *Decoder) {
22246b28f09dSZoran Jovanovic   Inst.addOperand(MCOperand::createImm(Value == 0x0 ? 8 : Value));
22256b28f09dSZoran Jovanovic   return MCDisassembler::Success;
22266b28f09dSZoran Jovanovic }
22276b28f09dSZoran Jovanovic 
222819b7f76aSDaniel Sanders template <unsigned Bits, int Offset, int Scale>
22294ae9745aSMaksim Panchenko static DecodeStatus
DecodeUImmWithOffsetAndScale(MCInst & Inst,unsigned Value,uint64_t Address,const MCDisassembler * Decoder)22304ae9745aSMaksim Panchenko DecodeUImmWithOffsetAndScale(MCInst &Inst, unsigned Value, uint64_t Address,
22314ae9745aSMaksim Panchenko                              const MCDisassembler *Decoder) {
2232ea4f653dSDaniel Sanders   Value &= ((1 << Bits) - 1);
223319b7f76aSDaniel Sanders   Value *= Scale;
2234ea4f653dSDaniel Sanders   Inst.addOperand(MCOperand::createImm(Value + Offset));
2235779c5937SMatheus Almeida   return MCDisassembler::Success;
2236779c5937SMatheus Almeida }
2237779c5937SMatheus Almeida 
223897297770SDaniel Sanders template <unsigned Bits, int Offset, int ScaleBy>
22394ae9745aSMaksim Panchenko static DecodeStatus
DecodeSImmWithOffsetAndScale(MCInst & Inst,unsigned Value,uint64_t Address,const MCDisassembler * Decoder)22404ae9745aSMaksim Panchenko DecodeSImmWithOffsetAndScale(MCInst &Inst, unsigned Value, uint64_t Address,
22414ae9745aSMaksim Panchenko                              const MCDisassembler *Decoder) {
224297297770SDaniel Sanders   int32_t Imm = SignExtend32<Bits>(Value) * ScaleBy;
224378e89020SDaniel Sanders   Inst.addOperand(MCOperand::createImm(Imm + Offset));
224478e89020SDaniel Sanders   return MCDisassembler::Success;
224578e89020SDaniel Sanders }
224678e89020SDaniel Sanders 
DecodeInsSize(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)22474ae9745aSMaksim Panchenko static DecodeStatus DecodeInsSize(MCInst &Inst, unsigned Insn, uint64_t Address,
22484ae9745aSMaksim Panchenko                                   const MCDisassembler *Decoder) {
224971928e68SAkira Hatanaka   // First we need to grab the pos(lsb) from MCInst.
22506f83ae38SSimon Dardis   // This function only handles the 32 bit variants of ins, as dins
22516f83ae38SSimon Dardis   // variants are handled differently.
225271928e68SAkira Hatanaka   int Pos = Inst.getOperand(2).getImm();
22536f83ae38SSimon Dardis   int Size = (int) Insn - Pos + 1;
2254e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(SignExtend32<16>(Size)));
225571928e68SAkira Hatanaka   return MCDisassembler::Success;
225671928e68SAkira Hatanaka }
225771928e68SAkira Hatanaka 
DecodeSimm19Lsl2(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)2258b59e1a41SDaniel Sanders static DecodeStatus DecodeSimm19Lsl2(MCInst &Inst, unsigned Insn,
22594ae9745aSMaksim Panchenko                                      uint64_t Address,
22604ae9745aSMaksim Panchenko                                      const MCDisassembler *Decoder) {
2261e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(SignExtend32<19>(Insn) * 4));
2262b59e1a41SDaniel Sanders   return MCDisassembler::Success;
2263b59e1a41SDaniel Sanders }
22642855142aSZoran Jovanovic 
DecodeSimm18Lsl3(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)22652855142aSZoran Jovanovic static DecodeStatus DecodeSimm18Lsl3(MCInst &Inst, unsigned Insn,
22664ae9745aSMaksim Panchenko                                      uint64_t Address,
22674ae9745aSMaksim Panchenko                                      const MCDisassembler *Decoder) {
2268e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(SignExtend32<18>(Insn) * 8));
22692855142aSZoran Jovanovic   return MCDisassembler::Success;
22702855142aSZoran Jovanovic }
2271a4c4b5fcSZoran Jovanovic 
DecodeSimm9SP(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)22724ae9745aSMaksim Panchenko static DecodeStatus DecodeSimm9SP(MCInst &Inst, unsigned Insn, uint64_t Address,
22734ae9745aSMaksim Panchenko                                   const MCDisassembler *Decoder) {
2274b682ddf3SVladimir Medic   int32_t DecodedValue;
2275b682ddf3SVladimir Medic   switch (Insn) {
2276b682ddf3SVladimir Medic   case 0: DecodedValue = 256; break;
2277b682ddf3SVladimir Medic   case 1: DecodedValue = 257; break;
2278b682ddf3SVladimir Medic   case 510: DecodedValue = -258; break;
2279b682ddf3SVladimir Medic   case 511: DecodedValue = -257; break;
2280b682ddf3SVladimir Medic   default: DecodedValue = SignExtend32<9>(Insn); break;
2281b682ddf3SVladimir Medic   }
2282e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(DecodedValue * 4));
2283b682ddf3SVladimir Medic   return MCDisassembler::Success;
2284b682ddf3SVladimir Medic }
2285b682ddf3SVladimir Medic 
DecodeANDI16Imm(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)2286b682ddf3SVladimir Medic static DecodeStatus DecodeANDI16Imm(MCInst &Inst, unsigned Insn,
22874ae9745aSMaksim Panchenko                                     uint64_t Address,
22884ae9745aSMaksim Panchenko                                     const MCDisassembler *Decoder) {
2289b682ddf3SVladimir Medic   // Insn must be >= 0, since it is unsigned that condition is always true.
2290b682ddf3SVladimir Medic   assert(Insn < 16);
2291b682ddf3SVladimir Medic   int32_t DecodedValues[] = {128, 1, 2, 3, 4, 7, 8, 15, 16, 31, 32, 63, 64,
2292b682ddf3SVladimir Medic                              255, 32768, 65535};
2293e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(DecodedValues[Insn]));
2294b682ddf3SVladimir Medic   return MCDisassembler::Success;
2295b682ddf3SVladimir Medic }
2296b682ddf3SVladimir Medic 
DecodeRegListOperand(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)22974ae9745aSMaksim Panchenko static DecodeStatus DecodeRegListOperand(MCInst &Inst, unsigned Insn,
2298a4c4b5fcSZoran Jovanovic                                          uint64_t Address,
22994ae9745aSMaksim Panchenko                                          const MCDisassembler *Decoder) {
2300a4c4b5fcSZoran Jovanovic   unsigned Regs[] = {Mips::S0, Mips::S1, Mips::S2, Mips::S3, Mips::S4, Mips::S5,
2301dc4b8c27SZoran Jovanovic                      Mips::S6, Mips::S7, Mips::FP};
2302a4c4b5fcSZoran Jovanovic   unsigned RegNum;
2303a4c4b5fcSZoran Jovanovic 
2304a4c4b5fcSZoran Jovanovic   unsigned RegLst = fieldFromInstruction(Insn, 21, 5);
2305df19a5e6SDaniel Sanders 
2306a4c4b5fcSZoran Jovanovic   // Empty register lists are not allowed.
2307a4c4b5fcSZoran Jovanovic   if (RegLst == 0)
2308a4c4b5fcSZoran Jovanovic     return MCDisassembler::Fail;
2309a4c4b5fcSZoran Jovanovic 
2310a4c4b5fcSZoran Jovanovic   RegNum = RegLst & 0xf;
2311df19a5e6SDaniel Sanders 
2312df19a5e6SDaniel Sanders   // RegLst values 10-15, and 26-31 are reserved.
2313df19a5e6SDaniel Sanders   if (RegNum > 9)
2314df19a5e6SDaniel Sanders     return MCDisassembler::Fail;
2315df19a5e6SDaniel Sanders 
2316a4c4b5fcSZoran Jovanovic   for (unsigned i = 0; i < RegNum; i++)
2317e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Regs[i]));
2318a4c4b5fcSZoran Jovanovic 
2319a4c4b5fcSZoran Jovanovic   if (RegLst & 0x10)
2320e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::RA));
2321a4c4b5fcSZoran Jovanovic 
2322a4c4b5fcSZoran Jovanovic   return MCDisassembler::Success;
2323a4c4b5fcSZoran Jovanovic }
2324f9a02500SZoran Jovanovic 
DecodeRegListOperand16(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)2325f9a02500SZoran Jovanovic static DecodeStatus DecodeRegListOperand16(MCInst &Inst, unsigned Insn,
2326f9a02500SZoran Jovanovic                                            uint64_t Address,
23274ae9745aSMaksim Panchenko                                            const MCDisassembler *Decoder) {
2328f9a02500SZoran Jovanovic   unsigned Regs[] = {Mips::S0, Mips::S1, Mips::S2, Mips::S3};
2329797c2aecSZlatko Buljan   unsigned RegLst;
2330797c2aecSZlatko Buljan   switch(Inst.getOpcode()) {
2331797c2aecSZlatko Buljan   default:
2332797c2aecSZlatko Buljan     RegLst = fieldFromInstruction(Insn, 4, 2);
2333797c2aecSZlatko Buljan     break;
2334797c2aecSZlatko Buljan   case Mips::LWM16_MMR6:
2335797c2aecSZlatko Buljan   case Mips::SWM16_MMR6:
2336797c2aecSZlatko Buljan     RegLst = fieldFromInstruction(Insn, 8, 2);
2337797c2aecSZlatko Buljan     break;
2338797c2aecSZlatko Buljan   }
2339d68d424aSJozef Kolek   unsigned RegNum = RegLst & 0x3;
2340f9a02500SZoran Jovanovic 
2341d68d424aSJozef Kolek   for (unsigned i = 0; i <= RegNum; i++)
2342e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Regs[i]));
2343f9a02500SZoran Jovanovic 
2344e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Mips::RA));
2345f9a02500SZoran Jovanovic 
2346f9a02500SZoran Jovanovic   return MCDisassembler::Success;
2347f9a02500SZoran Jovanovic }
23482c6d7320SJozef Kolek 
DecodeMovePOperands(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)2349852dd83bSSimon Atanasyan static DecodeStatus DecodeMovePOperands(MCInst &Inst, unsigned Insn,
2350852dd83bSSimon Atanasyan                                         uint64_t Address,
23514ae9745aSMaksim Panchenko                                         const MCDisassembler *Decoder) {
2352852dd83bSSimon Atanasyan   unsigned RegPair = fieldFromInstruction(Insn, 7, 3);
2353852dd83bSSimon Atanasyan   if (DecodeMovePRegPair(Inst, RegPair, Address, Decoder) ==
2354852dd83bSSimon Atanasyan       MCDisassembler::Fail)
2355852dd83bSSimon Atanasyan     return MCDisassembler::Fail;
2356852dd83bSSimon Atanasyan 
2357852dd83bSSimon Atanasyan   unsigned RegRs;
2358852dd83bSSimon Atanasyan   if (static_cast<const MipsDisassembler*>(Decoder)->hasMips32r6())
2359852dd83bSSimon Atanasyan     RegRs = fieldFromInstruction(Insn, 0, 2) |
2360852dd83bSSimon Atanasyan             (fieldFromInstruction(Insn, 3, 1) << 2);
2361852dd83bSSimon Atanasyan   else
2362852dd83bSSimon Atanasyan     RegRs = fieldFromInstruction(Insn, 1, 3);
2363852dd83bSSimon Atanasyan   if (DecodeGPRMM16MovePRegisterClass(Inst, RegRs, Address, Decoder) ==
2364852dd83bSSimon Atanasyan       MCDisassembler::Fail)
2365852dd83bSSimon Atanasyan     return MCDisassembler::Fail;
2366852dd83bSSimon Atanasyan 
2367852dd83bSSimon Atanasyan   unsigned RegRt = fieldFromInstruction(Insn, 4, 3);
2368852dd83bSSimon Atanasyan   if (DecodeGPRMM16MovePRegisterClass(Inst, RegRt, Address, Decoder) ==
2369852dd83bSSimon Atanasyan       MCDisassembler::Fail)
2370852dd83bSSimon Atanasyan     return MCDisassembler::Fail;
2371852dd83bSSimon Atanasyan 
2372852dd83bSSimon Atanasyan   return MCDisassembler::Success;
2373852dd83bSSimon Atanasyan }
2374852dd83bSSimon Atanasyan 
DecodeMovePRegPair(MCInst & Inst,unsigned RegPair,uint64_t Address,const MCDisassembler * Decoder)2375169df4e2SSimon Dardis static DecodeStatus DecodeMovePRegPair(MCInst &Inst, unsigned RegPair,
23764ae9745aSMaksim Panchenko                                        uint64_t Address,
23774ae9745aSMaksim Panchenko                                        const MCDisassembler *Decoder) {
237841688679SZoran Jovanovic   switch (RegPair) {
237941688679SZoran Jovanovic   default:
238041688679SZoran Jovanovic     return MCDisassembler::Fail;
238141688679SZoran Jovanovic   case 0:
2382e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A1));
2383e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A2));
238441688679SZoran Jovanovic     break;
238541688679SZoran Jovanovic   case 1:
2386e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A1));
2387e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A3));
238841688679SZoran Jovanovic     break;
238941688679SZoran Jovanovic   case 2:
2390e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A2));
2391e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A3));
239241688679SZoran Jovanovic     break;
239341688679SZoran Jovanovic   case 3:
2394e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A0));
2395e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::S5));
239641688679SZoran Jovanovic     break;
239741688679SZoran Jovanovic   case 4:
2398e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A0));
2399e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::S6));
240041688679SZoran Jovanovic     break;
240141688679SZoran Jovanovic   case 5:
2402e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A0));
2403e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A1));
240441688679SZoran Jovanovic     break;
240541688679SZoran Jovanovic   case 6:
2406e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A0));
2407e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A2));
240841688679SZoran Jovanovic     break;
240941688679SZoran Jovanovic   case 7:
2410e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A0));
2411e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Mips::A3));
241241688679SZoran Jovanovic     break;
241341688679SZoran Jovanovic   }
241441688679SZoran Jovanovic 
241541688679SZoran Jovanovic   return MCDisassembler::Success;
241641688679SZoran Jovanovic }
241741688679SZoran Jovanovic 
DecodeSimm23Lsl2(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)24182c6d7320SJozef Kolek static DecodeStatus DecodeSimm23Lsl2(MCInst &Inst, unsigned Insn,
24194ae9745aSMaksim Panchenko                                      uint64_t Address,
24204ae9745aSMaksim Panchenko                                      const MCDisassembler *Decoder) {
24216499b5f0SJustin Bogner   Inst.addOperand(MCOperand::createImm(SignExtend32<25>(Insn << 2)));
24222c6d7320SJozef Kolek   return MCDisassembler::Success;
24232c6d7320SJozef Kolek }
2424fdbd0a37SZoran Jovanovic 
2425fdbd0a37SZoran Jovanovic template <typename InsnType>
DecodeBgtzGroupBranchMMR6(MCInst & MI,InsnType insn,uint64_t Address,const MCDisassembler * Decoder)2426fdbd0a37SZoran Jovanovic static DecodeStatus DecodeBgtzGroupBranchMMR6(MCInst &MI, InsnType insn,
2427fdbd0a37SZoran Jovanovic                                               uint64_t Address,
24284ae9745aSMaksim Panchenko                                               const MCDisassembler *Decoder) {
2429fdbd0a37SZoran Jovanovic   // We have:
2430fdbd0a37SZoran Jovanovic   //    0b000111 ttttt sssss iiiiiiiiiiiiiiii
2431fdbd0a37SZoran Jovanovic   //      Invalid      if rt == 0
2432fdbd0a37SZoran Jovanovic   //      BGTZALC_MMR6 if rs == 0 && rt != 0
2433fdbd0a37SZoran Jovanovic   //      BLTZALC_MMR6 if rs != 0 && rs == rt
2434fdbd0a37SZoran Jovanovic   //      BLTUC_MMR6   if rs != 0 && rs != rt
2435fdbd0a37SZoran Jovanovic 
2436fdbd0a37SZoran Jovanovic   InsnType Rt = fieldFromInstruction(insn, 21, 5);
2437fdbd0a37SZoran Jovanovic   InsnType Rs = fieldFromInstruction(insn, 16, 5);
2438f0ed16eaSHrvoje Varga   InsnType Imm = 0;
2439fdbd0a37SZoran Jovanovic   bool HasRs = false;
2440fdbd0a37SZoran Jovanovic   bool HasRt = false;
2441fdbd0a37SZoran Jovanovic 
2442fdbd0a37SZoran Jovanovic   if (Rt == 0)
2443fdbd0a37SZoran Jovanovic     return MCDisassembler::Fail;
2444fdbd0a37SZoran Jovanovic   else if (Rs == 0) {
2445fdbd0a37SZoran Jovanovic     MI.setOpcode(Mips::BGTZALC_MMR6);
2446fdbd0a37SZoran Jovanovic     HasRt = true;
2447f0ed16eaSHrvoje Varga     Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
2448fdbd0a37SZoran Jovanovic   }
2449fdbd0a37SZoran Jovanovic   else if (Rs == Rt) {
2450fdbd0a37SZoran Jovanovic     MI.setOpcode(Mips::BLTZALC_MMR6);
2451fdbd0a37SZoran Jovanovic     HasRs = true;
2452f0ed16eaSHrvoje Varga     Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
2453fdbd0a37SZoran Jovanovic   }
2454fdbd0a37SZoran Jovanovic   else {
2455fdbd0a37SZoran Jovanovic     MI.setOpcode(Mips::BLTUC_MMR6);
2456fdbd0a37SZoran Jovanovic     HasRs = true;
2457fdbd0a37SZoran Jovanovic     HasRt = true;
2458f0ed16eaSHrvoje Varga     Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
2459fdbd0a37SZoran Jovanovic   }
2460fdbd0a37SZoran Jovanovic 
2461fdbd0a37SZoran Jovanovic   if (HasRs)
2462fdbd0a37SZoran Jovanovic     MI.addOperand(
2463fdbd0a37SZoran Jovanovic     MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rs)));
2464fdbd0a37SZoran Jovanovic 
2465fdbd0a37SZoran Jovanovic   if (HasRt)
2466fdbd0a37SZoran Jovanovic     MI.addOperand(
2467fdbd0a37SZoran Jovanovic     MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rt)));
2468fdbd0a37SZoran Jovanovic 
2469fdbd0a37SZoran Jovanovic   MI.addOperand(MCOperand::createImm(Imm));
2470fdbd0a37SZoran Jovanovic 
2471fdbd0a37SZoran Jovanovic   return MCDisassembler::Success;
2472fdbd0a37SZoran Jovanovic }
2473fdbd0a37SZoran Jovanovic 
2474fdbd0a37SZoran Jovanovic template <typename InsnType>
DecodeBlezGroupBranchMMR6(MCInst & MI,InsnType insn,uint64_t Address,const MCDisassembler * Decoder)2475fdbd0a37SZoran Jovanovic static DecodeStatus DecodeBlezGroupBranchMMR6(MCInst &MI, InsnType insn,
2476fdbd0a37SZoran Jovanovic                                               uint64_t Address,
24774ae9745aSMaksim Panchenko                                               const MCDisassembler *Decoder) {
2478fdbd0a37SZoran Jovanovic   // We have:
2479fdbd0a37SZoran Jovanovic   //    0b000110 ttttt sssss iiiiiiiiiiiiiiii
2480f0ed16eaSHrvoje Varga   //      Invalid        if rt == 0
2481fdbd0a37SZoran Jovanovic   //      BLEZALC_MMR6   if rs == 0  && rt != 0
2482fdbd0a37SZoran Jovanovic   //      BGEZALC_MMR6   if rs == rt && rt != 0
2483fdbd0a37SZoran Jovanovic   //      BGEUC_MMR6     if rs != rt && rs != 0  && rt != 0
2484fdbd0a37SZoran Jovanovic 
2485fdbd0a37SZoran Jovanovic   InsnType Rt = fieldFromInstruction(insn, 21, 5);
2486fdbd0a37SZoran Jovanovic   InsnType Rs = fieldFromInstruction(insn, 16, 5);
2487f0ed16eaSHrvoje Varga   InsnType Imm = 0;
2488fdbd0a37SZoran Jovanovic   bool HasRs = false;
2489fdbd0a37SZoran Jovanovic 
2490fdbd0a37SZoran Jovanovic   if (Rt == 0)
2491fdbd0a37SZoran Jovanovic     return MCDisassembler::Fail;
2492f0ed16eaSHrvoje Varga   else if (Rs == 0) {
2493fdbd0a37SZoran Jovanovic     MI.setOpcode(Mips::BLEZALC_MMR6);
2494f0ed16eaSHrvoje Varga     Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
2495f0ed16eaSHrvoje Varga   }
2496f0ed16eaSHrvoje Varga   else if (Rs == Rt) {
2497fdbd0a37SZoran Jovanovic     MI.setOpcode(Mips::BGEZALC_MMR6);
2498f0ed16eaSHrvoje Varga     Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
2499f0ed16eaSHrvoje Varga   }
2500fdbd0a37SZoran Jovanovic   else {
2501fdbd0a37SZoran Jovanovic     HasRs = true;
2502fdbd0a37SZoran Jovanovic     MI.setOpcode(Mips::BGEUC_MMR6);
2503f0ed16eaSHrvoje Varga     Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
2504fdbd0a37SZoran Jovanovic   }
2505fdbd0a37SZoran Jovanovic 
2506fdbd0a37SZoran Jovanovic   if (HasRs)
2507fdbd0a37SZoran Jovanovic     MI.addOperand(
2508fdbd0a37SZoran Jovanovic     MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rs)));
2509fdbd0a37SZoran Jovanovic   MI.addOperand(
2510fdbd0a37SZoran Jovanovic     MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rt)));
2511fdbd0a37SZoran Jovanovic 
2512fdbd0a37SZoran Jovanovic   MI.addOperand(MCOperand::createImm(Imm));
2513fdbd0a37SZoran Jovanovic 
2514fdbd0a37SZoran Jovanovic   return MCDisassembler::Success;
2515fdbd0a37SZoran Jovanovic }
2516