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