17a7e6055SDimitry Andric //===- MipsDisassembler.cpp - Disassembler for Mips -----------------------===//
2cb4dff85SDimitry Andric //
3cb4dff85SDimitry Andric // The LLVM Compiler Infrastructure
4cb4dff85SDimitry Andric //
5cb4dff85SDimitry Andric // This file is distributed under the University of Illinois Open Source
6cb4dff85SDimitry Andric // License. See LICENSE.TXT for details.
7cb4dff85SDimitry Andric //
8cb4dff85SDimitry Andric //===----------------------------------------------------------------------===//
9cb4dff85SDimitry Andric //
10cb4dff85SDimitry Andric // This file is part of the Mips Disassembler.
11cb4dff85SDimitry Andric //
12cb4dff85SDimitry Andric //===----------------------------------------------------------------------===//
13cb4dff85SDimitry Andric
142cab237bSDimitry Andric #include "MCTargetDesc/MipsMCTargetDesc.h"
15cb4dff85SDimitry Andric #include "Mips.h"
167a7e6055SDimitry Andric #include "llvm/ADT/ArrayRef.h"
1791bc56edSDimitry Andric #include "llvm/MC/MCContext.h"
183ca95b02SDimitry Andric #include "llvm/MC/MCDisassembler/MCDisassembler.h"
197ae0e2c9SDimitry Andric #include "llvm/MC/MCFixedLenDisassembler.h"
20139f7f9bSDimitry Andric #include "llvm/MC/MCInst.h"
217a7e6055SDimitry Andric #include "llvm/MC/MCRegisterInfo.h"
22db17bf38SDimitry Andric #include "llvm/MC/MCSubtargetInfo.h"
237a7e6055SDimitry Andric #include "llvm/Support/Compiler.h"
247a7e6055SDimitry Andric #include "llvm/Support/Debug.h"
257a7e6055SDimitry Andric #include "llvm/Support/ErrorHandling.h"
26139f7f9bSDimitry Andric #include "llvm/Support/MathExtras.h"
27cb4dff85SDimitry Andric #include "llvm/Support/TargetRegistry.h"
28db17bf38SDimitry Andric #include "llvm/Support/raw_ostream.h"
297a7e6055SDimitry Andric #include <cassert>
307a7e6055SDimitry Andric #include <cstdint>
31cb4dff85SDimitry Andric
32cb4dff85SDimitry Andric using namespace llvm;
33cb4dff85SDimitry Andric
3491bc56edSDimitry Andric #define DEBUG_TYPE "mips-disassembler"
3591bc56edSDimitry Andric
362cab237bSDimitry Andric using DecodeStatus = MCDisassembler::DecodeStatus;
37cb4dff85SDimitry Andric
387ae0e2c9SDimitry Andric namespace {
397ae0e2c9SDimitry Andric
40ff0cc061SDimitry Andric class MipsDisassembler : public MCDisassembler {
41ff0cc061SDimitry Andric bool IsMicroMips;
42ff0cc061SDimitry Andric bool IsBigEndian;
437a7e6055SDimitry Andric
44cb4dff85SDimitry Andric public:
MipsDisassembler(const MCSubtargetInfo & STI,MCContext & Ctx,bool IsBigEndian)45ff0cc061SDimitry Andric MipsDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx, bool IsBigEndian)
4639d628a0SDimitry Andric : MCDisassembler(STI, Ctx),
47ff0cc061SDimitry Andric IsMicroMips(STI.getFeatureBits()[Mips::FeatureMicroMips]),
4839d628a0SDimitry Andric IsBigEndian(IsBigEndian) {}
49cb4dff85SDimitry Andric
hasMips2() const503ca95b02SDimitry Andric bool hasMips2() const { return STI.getFeatureBits()[Mips::FeatureMips2]; }
hasMips3() const51ff0cc061SDimitry Andric bool hasMips3() const { return STI.getFeatureBits()[Mips::FeatureMips3]; }
hasMips32() const52ff0cc061SDimitry Andric bool hasMips32() const { return STI.getFeatureBits()[Mips::FeatureMips32]; }
537a7e6055SDimitry Andric
hasMips32r6() const5491bc56edSDimitry Andric bool hasMips32r6() const {
55ff0cc061SDimitry Andric return STI.getFeatureBits()[Mips::FeatureMips32r6];
5691bc56edSDimitry Andric }
577a7e6055SDimitry Andric
isFP64() const583ca95b02SDimitry Andric bool isFP64() const { return STI.getFeatureBits()[Mips::FeatureFP64Bit]; }
5991bc56edSDimitry Andric
isGP64() const60ff0cc061SDimitry Andric bool isGP64() const { return STI.getFeatureBits()[Mips::FeatureGP64Bit]; }
6191bc56edSDimitry Andric
isPTR64() const623ca95b02SDimitry Andric bool isPTR64() const { return STI.getFeatureBits()[Mips::FeaturePTR64Bit]; }
633ca95b02SDimitry Andric
hasCnMips() const6497bc6c73SDimitry Andric bool hasCnMips() const { return STI.getFeatureBits()[Mips::FeatureCnMips]; }
6597bc6c73SDimitry Andric
hasCOP3() const6691bc56edSDimitry Andric bool hasCOP3() const {
6791bc56edSDimitry Andric // Only present in MIPS-I and MIPS-II
6891bc56edSDimitry Andric return !hasMips32() && !hasMips3();
6991bc56edSDimitry Andric }
7091bc56edSDimitry Andric
7139d628a0SDimitry Andric DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
7239d628a0SDimitry Andric ArrayRef<uint8_t> Bytes, uint64_t Address,
7339d628a0SDimitry Andric raw_ostream &VStream,
7439d628a0SDimitry Andric raw_ostream &CStream) const override;
75cb4dff85SDimitry Andric };
76cb4dff85SDimitry Andric
777ae0e2c9SDimitry Andric } // end anonymous namespace
787ae0e2c9SDimitry Andric
79cb4dff85SDimitry Andric // Forward declare these because the autogenerated code will reference them.
80cb4dff85SDimitry Andric // Definitions are further down.
81f785676fSDimitry Andric static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst,
82cb4dff85SDimitry Andric unsigned RegNo,
83cb4dff85SDimitry Andric uint64_t Address,
84cb4dff85SDimitry Andric const void *Decoder);
85cb4dff85SDimitry Andric
86139f7f9bSDimitry Andric static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst,
87139f7f9bSDimitry Andric unsigned RegNo,
88139f7f9bSDimitry Andric uint64_t Address,
89139f7f9bSDimitry Andric const void *Decoder);
90139f7f9bSDimitry Andric
9139d628a0SDimitry Andric static DecodeStatus DecodeGPRMM16RegisterClass(MCInst &Inst,
9239d628a0SDimitry Andric unsigned RegNo,
9339d628a0SDimitry Andric uint64_t Address,
9439d628a0SDimitry Andric const void *Decoder);
9539d628a0SDimitry Andric
9639d628a0SDimitry Andric static DecodeStatus DecodeGPRMM16ZeroRegisterClass(MCInst &Inst,
9739d628a0SDimitry Andric unsigned RegNo,
9839d628a0SDimitry Andric uint64_t Address,
9939d628a0SDimitry Andric const void *Decoder);
10039d628a0SDimitry Andric
101ff0cc061SDimitry Andric static DecodeStatus DecodeGPRMM16MovePRegisterClass(MCInst &Inst,
102ff0cc061SDimitry Andric unsigned RegNo,
103ff0cc061SDimitry Andric uint64_t Address,
104ff0cc061SDimitry Andric const void *Decoder);
105ff0cc061SDimitry Andric
106f785676fSDimitry Andric static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst,
107cb4dff85SDimitry Andric unsigned RegNo,
108cb4dff85SDimitry Andric uint64_t Address,
109cb4dff85SDimitry Andric const void *Decoder);
110cb4dff85SDimitry Andric
111f785676fSDimitry Andric static DecodeStatus DecodePtrRegisterClass(MCInst &Inst,
112f785676fSDimitry Andric unsigned Insn,
113f785676fSDimitry Andric uint64_t Address,
114f785676fSDimitry Andric const void *Decoder);
115f785676fSDimitry Andric
116f785676fSDimitry Andric static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst,
1173861d79fSDimitry Andric unsigned RegNo,
1183861d79fSDimitry Andric uint64_t Address,
1193861d79fSDimitry Andric const void *Decoder);
1203861d79fSDimitry Andric
121cb4dff85SDimitry Andric static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
122cb4dff85SDimitry Andric unsigned RegNo,
123cb4dff85SDimitry Andric uint64_t Address,
124cb4dff85SDimitry Andric const void *Decoder);
125cb4dff85SDimitry Andric
126cb4dff85SDimitry Andric static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
127cb4dff85SDimitry Andric unsigned RegNo,
128cb4dff85SDimitry Andric uint64_t Address,
129cb4dff85SDimitry Andric const void *Decoder);
130cb4dff85SDimitry Andric
131cb4dff85SDimitry Andric static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
132cb4dff85SDimitry Andric unsigned RegNo,
133cb4dff85SDimitry Andric uint64_t Address,
134cb4dff85SDimitry Andric const void *Decoder);
135cb4dff85SDimitry Andric
136f785676fSDimitry Andric static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst,
137f785676fSDimitry Andric unsigned RegNo,
138f785676fSDimitry Andric uint64_t Address,
139f785676fSDimitry Andric const void *Decoder);
140f785676fSDimitry Andric
14191bc56edSDimitry Andric static DecodeStatus DecodeFGRCCRegisterClass(MCInst &Inst, unsigned RegNo,
14291bc56edSDimitry Andric uint64_t Address,
14391bc56edSDimitry Andric const void *Decoder);
14491bc56edSDimitry Andric
145cb4dff85SDimitry Andric static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
146cb4dff85SDimitry Andric unsigned Insn,
147cb4dff85SDimitry Andric uint64_t Address,
148cb4dff85SDimitry Andric const void *Decoder);
149cb4dff85SDimitry Andric
150cb4dff85SDimitry Andric static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
151cb4dff85SDimitry Andric unsigned RegNo,
152cb4dff85SDimitry Andric uint64_t Address,
153cb4dff85SDimitry Andric const void *Decoder);
154cb4dff85SDimitry Andric
155f785676fSDimitry Andric static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst,
1563861d79fSDimitry Andric unsigned RegNo,
1573861d79fSDimitry Andric uint64_t Address,
1583861d79fSDimitry Andric const void *Decoder);
1593861d79fSDimitry Andric
160f785676fSDimitry Andric static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst,
161284c1978SDimitry Andric unsigned RegNo,
162284c1978SDimitry Andric uint64_t Address,
163284c1978SDimitry Andric const void *Decoder);
164284c1978SDimitry Andric
165f785676fSDimitry Andric static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst,
166f785676fSDimitry Andric unsigned RegNo,
167f785676fSDimitry Andric uint64_t Address,
168f785676fSDimitry Andric const void *Decoder);
169f785676fSDimitry Andric
170f785676fSDimitry Andric static DecodeStatus DecodeMSA128BRegisterClass(MCInst &Inst,
171f785676fSDimitry Andric unsigned RegNo,
172f785676fSDimitry Andric uint64_t Address,
173f785676fSDimitry Andric const void *Decoder);
174f785676fSDimitry Andric
175f785676fSDimitry Andric static DecodeStatus DecodeMSA128HRegisterClass(MCInst &Inst,
176f785676fSDimitry Andric unsigned RegNo,
177f785676fSDimitry Andric uint64_t Address,
178f785676fSDimitry Andric const void *Decoder);
179f785676fSDimitry Andric
180f785676fSDimitry Andric static DecodeStatus DecodeMSA128WRegisterClass(MCInst &Inst,
181f785676fSDimitry Andric unsigned RegNo,
182f785676fSDimitry Andric uint64_t Address,
183f785676fSDimitry Andric const void *Decoder);
184f785676fSDimitry Andric
185f785676fSDimitry Andric static DecodeStatus DecodeMSA128DRegisterClass(MCInst &Inst,
186f785676fSDimitry Andric unsigned RegNo,
187f785676fSDimitry Andric uint64_t Address,
188f785676fSDimitry Andric const void *Decoder);
189f785676fSDimitry Andric
190f785676fSDimitry Andric static DecodeStatus DecodeMSACtrlRegisterClass(MCInst &Inst,
191284c1978SDimitry Andric unsigned RegNo,
192284c1978SDimitry Andric uint64_t Address,
193284c1978SDimitry Andric const void *Decoder);
194284c1978SDimitry Andric
1953dac3a9bSDimitry Andric static DecodeStatus DecodeCOP0RegisterClass(MCInst &Inst,
1963dac3a9bSDimitry Andric unsigned RegNo,
1973dac3a9bSDimitry Andric uint64_t Address,
1983dac3a9bSDimitry Andric const void *Decoder);
1993dac3a9bSDimitry Andric
20091bc56edSDimitry Andric static DecodeStatus DecodeCOP2RegisterClass(MCInst &Inst,
20191bc56edSDimitry Andric unsigned RegNo,
20291bc56edSDimitry Andric uint64_t Address,
20391bc56edSDimitry Andric const void *Decoder);
20491bc56edSDimitry Andric
205cb4dff85SDimitry Andric static DecodeStatus DecodeBranchTarget(MCInst &Inst,
206cb4dff85SDimitry Andric unsigned Offset,
207cb4dff85SDimitry Andric uint64_t Address,
208cb4dff85SDimitry Andric const void *Decoder);
209cb4dff85SDimitry Andric
2103ca95b02SDimitry Andric static DecodeStatus DecodeBranchTarget1SImm16(MCInst &Inst,
2113ca95b02SDimitry Andric unsigned Offset,
2123ca95b02SDimitry Andric uint64_t Address,
2133ca95b02SDimitry Andric const void *Decoder);
2143ca95b02SDimitry Andric
215cb4dff85SDimitry Andric static DecodeStatus DecodeJumpTarget(MCInst &Inst,
216cb4dff85SDimitry Andric unsigned Insn,
217cb4dff85SDimitry Andric uint64_t Address,
218cb4dff85SDimitry Andric const void *Decoder);
219cb4dff85SDimitry Andric
22091bc56edSDimitry Andric static DecodeStatus DecodeBranchTarget21(MCInst &Inst,
22191bc56edSDimitry Andric unsigned Offset,
22291bc56edSDimitry Andric uint64_t Address,
22391bc56edSDimitry Andric const void *Decoder);
22491bc56edSDimitry Andric
2253ca95b02SDimitry Andric static DecodeStatus DecodeBranchTarget21MM(MCInst &Inst,
2263ca95b02SDimitry Andric unsigned Offset,
2273ca95b02SDimitry Andric uint64_t Address,
2283ca95b02SDimitry Andric const void *Decoder);
2293ca95b02SDimitry Andric
23091bc56edSDimitry Andric static DecodeStatus DecodeBranchTarget26(MCInst &Inst,
23191bc56edSDimitry Andric unsigned Offset,
23291bc56edSDimitry Andric uint64_t Address,
23391bc56edSDimitry Andric const void *Decoder);
23491bc56edSDimitry Andric
23539d628a0SDimitry Andric // DecodeBranchTarget7MM - Decode microMIPS branch offset, which is
23639d628a0SDimitry Andric // shifted left by 1 bit.
23739d628a0SDimitry Andric static DecodeStatus DecodeBranchTarget7MM(MCInst &Inst,
23839d628a0SDimitry Andric unsigned Offset,
23939d628a0SDimitry Andric uint64_t Address,
24039d628a0SDimitry Andric const void *Decoder);
24139d628a0SDimitry Andric
242ff0cc061SDimitry Andric // DecodeBranchTarget10MM - Decode microMIPS branch offset, which is
243ff0cc061SDimitry Andric // shifted left by 1 bit.
244ff0cc061SDimitry Andric static DecodeStatus DecodeBranchTarget10MM(MCInst &Inst,
245ff0cc061SDimitry Andric unsigned Offset,
246ff0cc061SDimitry Andric uint64_t Address,
247ff0cc061SDimitry Andric const void *Decoder);
248ff0cc061SDimitry Andric
249f785676fSDimitry Andric // DecodeBranchTargetMM - Decode microMIPS branch offset, which is
250f785676fSDimitry Andric // shifted left by 1 bit.
251f785676fSDimitry Andric static DecodeStatus DecodeBranchTargetMM(MCInst &Inst,
252f785676fSDimitry Andric unsigned Offset,
253f785676fSDimitry Andric uint64_t Address,
254f785676fSDimitry Andric const void *Decoder);
255f785676fSDimitry Andric
2567d523365SDimitry Andric // DecodeBranchTarget26MM - Decode microMIPS branch offset, which is
2577d523365SDimitry Andric // shifted left by 1 bit.
2587d523365SDimitry Andric static DecodeStatus DecodeBranchTarget26MM(MCInst &Inst,
2597d523365SDimitry Andric unsigned Offset,
2607d523365SDimitry Andric uint64_t Address,
2617d523365SDimitry Andric const void *Decoder);
2627d523365SDimitry Andric
263f785676fSDimitry Andric // DecodeJumpTargetMM - Decode microMIPS jump target, which is
264f785676fSDimitry Andric // shifted left by 1 bit.
265f785676fSDimitry Andric static DecodeStatus DecodeJumpTargetMM(MCInst &Inst,
266f785676fSDimitry Andric unsigned Insn,
267f785676fSDimitry Andric uint64_t Address,
268f785676fSDimitry Andric const void *Decoder);
269f785676fSDimitry Andric
270cb4dff85SDimitry Andric static DecodeStatus DecodeMem(MCInst &Inst,
271cb4dff85SDimitry Andric unsigned Insn,
272cb4dff85SDimitry Andric uint64_t Address,
273cb4dff85SDimitry Andric const void *Decoder);
274cb4dff85SDimitry Andric
2757d523365SDimitry Andric static DecodeStatus DecodeMemEVA(MCInst &Inst,
2767d523365SDimitry Andric unsigned Insn,
2777d523365SDimitry Andric uint64_t Address,
2787d523365SDimitry Andric const void *Decoder);
2797d523365SDimitry Andric
2807d523365SDimitry Andric static DecodeStatus DecodeLoadByte15(MCInst &Inst,
2817d523365SDimitry Andric unsigned Insn,
2827d523365SDimitry Andric uint64_t Address,
2837d523365SDimitry Andric const void *Decoder);
2847d523365SDimitry Andric
2852cab237bSDimitry Andric static DecodeStatus DecodeCacheOp(MCInst &Inst, unsigned Insn, uint64_t Address,
2869cac79b3SDimitry Andric const void *Decoder);
2879cac79b3SDimitry Andric
2887d523365SDimitry Andric static DecodeStatus DecodeCacheeOp_CacheOpR6(MCInst &Inst,
289ef6fa9e2SDimitry Andric unsigned Insn,
290ef6fa9e2SDimitry Andric uint64_t Address,
291ef6fa9e2SDimitry Andric const void *Decoder);
292ef6fa9e2SDimitry Andric
29339d628a0SDimitry Andric static DecodeStatus DecodeCacheOpMM(MCInst &Inst,
29439d628a0SDimitry Andric unsigned Insn,
29539d628a0SDimitry Andric uint64_t Address,
29639d628a0SDimitry Andric const void *Decoder);
29739d628a0SDimitry Andric
2987d523365SDimitry Andric static DecodeStatus DecodePrefeOpMM(MCInst &Inst,
2997d523365SDimitry Andric unsigned Insn,
3007d523365SDimitry Andric uint64_t Address,
3017d523365SDimitry Andric const void *Decoder);
3027d523365SDimitry Andric
30339d628a0SDimitry Andric static DecodeStatus DecodeSyncI(MCInst &Inst,
30439d628a0SDimitry Andric unsigned Insn,
30539d628a0SDimitry Andric uint64_t Address,
30639d628a0SDimitry Andric const void *Decoder);
30739d628a0SDimitry Andric
3084ba319b5SDimitry Andric static DecodeStatus DecodeSyncI_MM(MCInst &Inst,
3094ba319b5SDimitry Andric unsigned Insn,
3104ba319b5SDimitry Andric uint64_t Address,
3114ba319b5SDimitry Andric const void *Decoder);
3124ba319b5SDimitry Andric
3137d523365SDimitry Andric static DecodeStatus DecodeSynciR6(MCInst &Inst,
3147d523365SDimitry Andric unsigned Insn,
3157d523365SDimitry Andric uint64_t Address,
3167d523365SDimitry Andric const void *Decoder);
3177d523365SDimitry Andric
318f785676fSDimitry Andric static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn,
319f785676fSDimitry Andric uint64_t Address, const void *Decoder);
320f785676fSDimitry Andric
32139d628a0SDimitry Andric static DecodeStatus DecodeMemMMImm4(MCInst &Inst,
32239d628a0SDimitry Andric unsigned Insn,
32339d628a0SDimitry Andric uint64_t Address,
32439d628a0SDimitry Andric const void *Decoder);
32539d628a0SDimitry Andric
32639d628a0SDimitry Andric static DecodeStatus DecodeMemMMSPImm5Lsl2(MCInst &Inst,
32739d628a0SDimitry Andric unsigned Insn,
32839d628a0SDimitry Andric uint64_t Address,
32939d628a0SDimitry Andric const void *Decoder);
33039d628a0SDimitry Andric
331ff0cc061SDimitry Andric static DecodeStatus DecodeMemMMGPImm7Lsl2(MCInst &Inst,
332ff0cc061SDimitry Andric unsigned Insn,
333ff0cc061SDimitry Andric uint64_t Address,
334ff0cc061SDimitry Andric const void *Decoder);
335ff0cc061SDimitry Andric
336ff0cc061SDimitry Andric static DecodeStatus DecodeMemMMReglistImm4Lsl2(MCInst &Inst,
337ff0cc061SDimitry Andric unsigned Insn,
338ff0cc061SDimitry Andric uint64_t Address,
339ff0cc061SDimitry Andric const void *Decoder);
340ff0cc061SDimitry Andric
3417d523365SDimitry Andric static DecodeStatus DecodeMemMMImm9(MCInst &Inst,
3427d523365SDimitry Andric unsigned Insn,
3437d523365SDimitry Andric uint64_t Address,
3447d523365SDimitry Andric const void *Decoder);
3457d523365SDimitry Andric
346f785676fSDimitry Andric static DecodeStatus DecodeMemMMImm12(MCInst &Inst,
347f785676fSDimitry Andric unsigned Insn,
348f785676fSDimitry Andric uint64_t Address,
349f785676fSDimitry Andric const void *Decoder);
350f785676fSDimitry Andric
351f785676fSDimitry Andric static DecodeStatus DecodeMemMMImm16(MCInst &Inst,
352f785676fSDimitry Andric unsigned Insn,
353f785676fSDimitry Andric uint64_t Address,
354f785676fSDimitry Andric const void *Decoder);
355f785676fSDimitry Andric
356cb4dff85SDimitry Andric static DecodeStatus DecodeFMem(MCInst &Inst, unsigned Insn,
357cb4dff85SDimitry Andric uint64_t Address,
358cb4dff85SDimitry Andric const void *Decoder);
359cb4dff85SDimitry Andric
3603ca95b02SDimitry Andric static DecodeStatus DecodeFMemMMR2(MCInst &Inst, unsigned Insn,
3613ca95b02SDimitry Andric uint64_t Address,
3623ca95b02SDimitry Andric const void *Decoder);
3633ca95b02SDimitry Andric
3642cab237bSDimitry Andric static DecodeStatus DecodeFMem2(MCInst &Inst, unsigned Insn, uint64_t Address,
3659cac79b3SDimitry Andric const void *Decoder);
3669cac79b3SDimitry Andric
3672cab237bSDimitry Andric static DecodeStatus DecodeFMem3(MCInst &Inst, unsigned Insn, uint64_t Address,
3689cac79b3SDimitry Andric const void *Decoder);
3699cac79b3SDimitry Andric
370ef6fa9e2SDimitry Andric static DecodeStatus DecodeFMemCop2R6(MCInst &Inst, unsigned Insn,
3712cab237bSDimitry Andric uint64_t Address, const void *Decoder);
372ef6fa9e2SDimitry Andric
3733ca95b02SDimitry Andric static DecodeStatus DecodeFMemCop2MMR6(MCInst &Inst, unsigned Insn,
3743ca95b02SDimitry Andric uint64_t Address,
3753ca95b02SDimitry Andric const void *Decoder);
3763ca95b02SDimitry Andric
37791bc56edSDimitry Andric static DecodeStatus DecodeSpecial3LlSc(MCInst &Inst,
37891bc56edSDimitry Andric unsigned Insn,
37991bc56edSDimitry Andric uint64_t Address,
38091bc56edSDimitry Andric const void *Decoder);
38191bc56edSDimitry Andric
38239d628a0SDimitry Andric static DecodeStatus DecodeAddiur2Simm7(MCInst &Inst,
38339d628a0SDimitry Andric unsigned Value,
38439d628a0SDimitry Andric uint64_t Address,
38539d628a0SDimitry Andric const void *Decoder);
38639d628a0SDimitry Andric
3873ca95b02SDimitry Andric static DecodeStatus DecodeLi16Imm(MCInst &Inst,
38839d628a0SDimitry Andric unsigned Value,
38939d628a0SDimitry Andric uint64_t Address,
39039d628a0SDimitry Andric const void *Decoder);
39139d628a0SDimitry Andric
3927d523365SDimitry Andric static DecodeStatus DecodePOOL16BEncodedField(MCInst &Inst,
3937d523365SDimitry Andric unsigned Value,
3947d523365SDimitry Andric uint64_t Address,
3957d523365SDimitry Andric const void *Decoder);
3967d523365SDimitry Andric
3973ca95b02SDimitry Andric template <unsigned Bits, int Offset, int Scale>
3983ca95b02SDimitry Andric static DecodeStatus DecodeUImmWithOffsetAndScale(MCInst &Inst, unsigned Value,
399cb4dff85SDimitry Andric uint64_t Address,
400cb4dff85SDimitry Andric const void *Decoder);
401cb4dff85SDimitry Andric
4027d523365SDimitry Andric template <unsigned Bits, int Offset>
DecodeUImmWithOffset(MCInst & Inst,unsigned Value,uint64_t Address,const void * Decoder)4037d523365SDimitry Andric static DecodeStatus DecodeUImmWithOffset(MCInst &Inst, unsigned Value,
4043ca95b02SDimitry Andric uint64_t Address,
4053ca95b02SDimitry Andric const void *Decoder) {
4063ca95b02SDimitry Andric return DecodeUImmWithOffsetAndScale<Bits, Offset, 1>(Inst, Value, Address,
4073ca95b02SDimitry Andric Decoder);
4083ca95b02SDimitry Andric }
4093ca95b02SDimitry Andric
4103ca95b02SDimitry Andric template <unsigned Bits, int Offset = 0, int ScaleBy = 1>
4113ca95b02SDimitry Andric static DecodeStatus DecodeSImmWithOffsetAndScale(MCInst &Inst, unsigned Value,
4123ca95b02SDimitry Andric uint64_t Address,
4133ca95b02SDimitry Andric const void *Decoder);
414cb4dff85SDimitry Andric
415cb4dff85SDimitry Andric static DecodeStatus DecodeInsSize(MCInst &Inst,
416cb4dff85SDimitry Andric unsigned Insn,
417cb4dff85SDimitry Andric uint64_t Address,
418cb4dff85SDimitry Andric const void *Decoder);
419cb4dff85SDimitry Andric
42091bc56edSDimitry Andric static DecodeStatus DecodeSimm19Lsl2(MCInst &Inst, unsigned Insn,
42191bc56edSDimitry Andric uint64_t Address, const void *Decoder);
42291bc56edSDimitry Andric
42391bc56edSDimitry Andric static DecodeStatus DecodeSimm18Lsl3(MCInst &Inst, unsigned Insn,
42491bc56edSDimitry Andric uint64_t Address, const void *Decoder);
42591bc56edSDimitry Andric
42639d628a0SDimitry Andric static DecodeStatus DecodeSimm9SP(MCInst &Inst, unsigned Insn,
42739d628a0SDimitry Andric uint64_t Address, const void *Decoder);
42839d628a0SDimitry Andric
42939d628a0SDimitry Andric static DecodeStatus DecodeANDI16Imm(MCInst &Inst, unsigned Insn,
43039d628a0SDimitry Andric uint64_t Address, const void *Decoder);
43139d628a0SDimitry Andric
432ff0cc061SDimitry Andric static DecodeStatus DecodeSimm23Lsl2(MCInst &Inst, unsigned Insn,
433ff0cc061SDimitry Andric uint64_t Address, const void *Decoder);
434ff0cc061SDimitry Andric
43591bc56edSDimitry Andric /// INSVE_[BHWD] have an implicit operand that the generated decoder doesn't
43691bc56edSDimitry Andric /// handle.
43791bc56edSDimitry Andric template <typename InsnType>
43891bc56edSDimitry Andric static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address,
43991bc56edSDimitry Andric const void *Decoder);
44091bc56edSDimitry Andric
44191bc56edSDimitry Andric template <typename InsnType>
442d88c1a5aSDimitry Andric static DecodeStatus DecodeDAHIDATIMMR6(MCInst &MI, InsnType insn, uint64_t Address,
443d88c1a5aSDimitry Andric const void *Decoder);
444d88c1a5aSDimitry Andric
445d88c1a5aSDimitry Andric template <typename InsnType>
446d88c1a5aSDimitry Andric static DecodeStatus DecodeDAHIDATI(MCInst &MI, InsnType insn, uint64_t Address,
447d88c1a5aSDimitry Andric const void *Decoder);
448d88c1a5aSDimitry Andric
449d88c1a5aSDimitry Andric template <typename InsnType>
450d88c1a5aSDimitry Andric static DecodeStatus DecodeDAHIDATIMMR6(MCInst &MI, InsnType insn, uint64_t Address,
451d88c1a5aSDimitry Andric const void *Decoder);
452d88c1a5aSDimitry Andric
453d88c1a5aSDimitry Andric template <typename InsnType>
454d88c1a5aSDimitry Andric static DecodeStatus DecodeDAHIDATI(MCInst &MI, InsnType insn, uint64_t Address,
455d88c1a5aSDimitry Andric const void *Decoder);
456d88c1a5aSDimitry Andric
457d88c1a5aSDimitry Andric template <typename InsnType>
45891bc56edSDimitry Andric static DecodeStatus
45991bc56edSDimitry Andric DecodeAddiGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
46091bc56edSDimitry Andric const void *Decoder);
46191bc56edSDimitry Andric
46291bc56edSDimitry Andric template <typename InsnType>
46391bc56edSDimitry Andric static DecodeStatus
4643ca95b02SDimitry Andric DecodePOP35GroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address,
4653ca95b02SDimitry Andric const void *Decoder);
4663ca95b02SDimitry Andric
4673ca95b02SDimitry Andric template <typename InsnType>
4683ca95b02SDimitry Andric static DecodeStatus
46991bc56edSDimitry Andric DecodeDaddiGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
47091bc56edSDimitry Andric const void *Decoder);
47191bc56edSDimitry Andric
47291bc56edSDimitry Andric template <typename InsnType>
47391bc56edSDimitry Andric static DecodeStatus
4743ca95b02SDimitry Andric DecodePOP37GroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address,
4753ca95b02SDimitry Andric const void *Decoder);
4763ca95b02SDimitry Andric
4773ca95b02SDimitry Andric template <typename InsnType>
4783ca95b02SDimitry Andric static DecodeStatus
479d88c1a5aSDimitry Andric DecodePOP65GroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address,
480d88c1a5aSDimitry Andric const void *Decoder);
481d88c1a5aSDimitry Andric
482d88c1a5aSDimitry Andric template <typename InsnType>
483d88c1a5aSDimitry Andric static DecodeStatus
484d88c1a5aSDimitry Andric DecodePOP75GroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address,
485d88c1a5aSDimitry Andric const void *Decoder);
486d88c1a5aSDimitry Andric
487d88c1a5aSDimitry Andric template <typename InsnType>
488d88c1a5aSDimitry Andric static DecodeStatus
48991bc56edSDimitry Andric DecodeBlezlGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
49091bc56edSDimitry Andric const void *Decoder);
49191bc56edSDimitry Andric
49291bc56edSDimitry Andric template <typename InsnType>
49391bc56edSDimitry Andric static DecodeStatus
49491bc56edSDimitry Andric DecodeBgtzlGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
49591bc56edSDimitry Andric const void *Decoder);
49691bc56edSDimitry Andric
49791bc56edSDimitry Andric template <typename InsnType>
49891bc56edSDimitry Andric static DecodeStatus
49991bc56edSDimitry Andric DecodeBgtzGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
50091bc56edSDimitry Andric const void *Decoder);
50191bc56edSDimitry Andric
50291bc56edSDimitry Andric template <typename InsnType>
50391bc56edSDimitry Andric static DecodeStatus
50491bc56edSDimitry Andric DecodeBlezGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
50591bc56edSDimitry Andric const void *Decoder);
50691bc56edSDimitry Andric
5073ca95b02SDimitry Andric template <typename InsnType>
5083ca95b02SDimitry Andric static DecodeStatus
5093ca95b02SDimitry Andric DecodeBgtzGroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address,
5103ca95b02SDimitry Andric const void *Decoder);
5113ca95b02SDimitry Andric
5123ca95b02SDimitry Andric template <typename InsnType>
5133ca95b02SDimitry Andric static DecodeStatus
5143ca95b02SDimitry Andric DecodeBlezGroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address,
5153ca95b02SDimitry Andric const void *Decoder);
5163ca95b02SDimitry Andric
5172cab237bSDimitry Andric template <typename InsnType>
5182cab237bSDimitry Andric static DecodeStatus DecodeDINS(MCInst &MI, InsnType Insn, uint64_t Address,
5192cab237bSDimitry Andric const void *Decoder);
5202cab237bSDimitry Andric
5212cab237bSDimitry Andric template <typename InsnType>
5222cab237bSDimitry Andric static DecodeStatus DecodeDEXT(MCInst &MI, InsnType Insn, uint64_t Address,
5232cab237bSDimitry Andric const void *Decoder);
5242cab237bSDimitry Andric
5254ba319b5SDimitry Andric template <typename InsnType>
5264ba319b5SDimitry Andric static DecodeStatus DecodeCRC(MCInst &MI, InsnType Insn, uint64_t Address,
5274ba319b5SDimitry Andric const void *Decoder);
5284ba319b5SDimitry Andric
52939d628a0SDimitry Andric static DecodeStatus DecodeRegListOperand(MCInst &Inst, unsigned Insn,
53039d628a0SDimitry Andric uint64_t Address,
53139d628a0SDimitry Andric const void *Decoder);
53239d628a0SDimitry Andric
53339d628a0SDimitry Andric static DecodeStatus DecodeRegListOperand16(MCInst &Inst, unsigned Insn,
53439d628a0SDimitry Andric uint64_t Address,
53539d628a0SDimitry Andric const void *Decoder);
53639d628a0SDimitry Andric
5372cab237bSDimitry Andric static DecodeStatus DecodeMovePRegPair(MCInst &Inst, unsigned RegPair,
538ff0cc061SDimitry Andric uint64_t Address,
539ff0cc061SDimitry Andric const void *Decoder);
540ff0cc061SDimitry Andric
541*b5893f02SDimitry Andric static DecodeStatus DecodeMovePOperands(MCInst &Inst, unsigned Insn,
542*b5893f02SDimitry Andric uint64_t Address, const void *Decoder);
543*b5893f02SDimitry Andric
544cb4dff85SDimitry Andric namespace llvm {
5457a7e6055SDimitry Andric
546d88c1a5aSDimitry Andric Target &getTheMipselTarget();
547d88c1a5aSDimitry Andric Target &getTheMipsTarget();
548d88c1a5aSDimitry Andric Target &getTheMips64Target();
549d88c1a5aSDimitry Andric Target &getTheMips64elTarget();
5507a7e6055SDimitry Andric
5517a7e6055SDimitry Andric } // end namespace llvm
552cb4dff85SDimitry Andric
createMipsDisassembler(const Target & T,const MCSubtargetInfo & STI,MCContext & Ctx)553cb4dff85SDimitry Andric static MCDisassembler *createMipsDisassembler(
554cb4dff85SDimitry Andric const Target &T,
55591bc56edSDimitry Andric const MCSubtargetInfo &STI,
55691bc56edSDimitry Andric MCContext &Ctx) {
55791bc56edSDimitry Andric return new MipsDisassembler(STI, Ctx, true);
558cb4dff85SDimitry Andric }
559cb4dff85SDimitry Andric
createMipselDisassembler(const Target & T,const MCSubtargetInfo & STI,MCContext & Ctx)560cb4dff85SDimitry Andric static MCDisassembler *createMipselDisassembler(
561cb4dff85SDimitry Andric const Target &T,
56291bc56edSDimitry Andric const MCSubtargetInfo &STI,
56391bc56edSDimitry Andric MCContext &Ctx) {
56491bc56edSDimitry Andric return new MipsDisassembler(STI, Ctx, false);
565cb4dff85SDimitry Andric }
566cb4dff85SDimitry Andric
LLVMInitializeMipsDisassembler()567cb4dff85SDimitry Andric extern "C" void LLVMInitializeMipsDisassembler() {
568cb4dff85SDimitry Andric // Register the disassembler.
569d88c1a5aSDimitry Andric TargetRegistry::RegisterMCDisassembler(getTheMipsTarget(),
570cb4dff85SDimitry Andric createMipsDisassembler);
571d88c1a5aSDimitry Andric TargetRegistry::RegisterMCDisassembler(getTheMipselTarget(),
572cb4dff85SDimitry Andric createMipselDisassembler);
573d88c1a5aSDimitry Andric TargetRegistry::RegisterMCDisassembler(getTheMips64Target(),
574ff0cc061SDimitry Andric createMipsDisassembler);
575d88c1a5aSDimitry Andric TargetRegistry::RegisterMCDisassembler(getTheMips64elTarget(),
576ff0cc061SDimitry Andric createMipselDisassembler);
577cb4dff85SDimitry Andric }
578cb4dff85SDimitry Andric
579cb4dff85SDimitry Andric #include "MipsGenDisassemblerTables.inc"
580cb4dff85SDimitry Andric
getReg(const void * D,unsigned RC,unsigned RegNo)58191bc56edSDimitry Andric static unsigned getReg(const void *D, unsigned RC, unsigned RegNo) {
582ff0cc061SDimitry Andric const MipsDisassembler *Dis = static_cast<const MipsDisassembler*>(D);
58391bc56edSDimitry Andric const MCRegisterInfo *RegInfo = Dis->getContext().getRegisterInfo();
58491bc56edSDimitry Andric return *(RegInfo->getRegClass(RC).begin() + RegNo);
58591bc56edSDimitry Andric }
58691bc56edSDimitry Andric
58791bc56edSDimitry Andric template <typename InsnType>
DecodeINSVE_DF(MCInst & MI,InsnType insn,uint64_t Address,const void * Decoder)58891bc56edSDimitry Andric static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address,
58991bc56edSDimitry Andric const void *Decoder) {
5902cab237bSDimitry Andric using DecodeFN = DecodeStatus (*)(MCInst &, unsigned, uint64_t, const void *);
5912cab237bSDimitry Andric
59291bc56edSDimitry Andric // The size of the n field depends on the element size
59391bc56edSDimitry Andric // The register class also depends on this.
59491bc56edSDimitry Andric InsnType tmp = fieldFromInstruction(insn, 17, 5);
59591bc56edSDimitry Andric unsigned NSize = 0;
59691bc56edSDimitry Andric DecodeFN RegDecoder = nullptr;
59791bc56edSDimitry Andric if ((tmp & 0x18) == 0x00) { // INSVE_B
59891bc56edSDimitry Andric NSize = 4;
59991bc56edSDimitry Andric RegDecoder = DecodeMSA128BRegisterClass;
60091bc56edSDimitry Andric } else if ((tmp & 0x1c) == 0x10) { // INSVE_H
60191bc56edSDimitry Andric NSize = 3;
60291bc56edSDimitry Andric RegDecoder = DecodeMSA128HRegisterClass;
60391bc56edSDimitry Andric } else if ((tmp & 0x1e) == 0x18) { // INSVE_W
60491bc56edSDimitry Andric NSize = 2;
60591bc56edSDimitry Andric RegDecoder = DecodeMSA128WRegisterClass;
60691bc56edSDimitry Andric } else if ((tmp & 0x1f) == 0x1c) { // INSVE_D
60791bc56edSDimitry Andric NSize = 1;
60891bc56edSDimitry Andric RegDecoder = DecodeMSA128DRegisterClass;
60991bc56edSDimitry Andric } else
61091bc56edSDimitry Andric llvm_unreachable("Invalid encoding");
61191bc56edSDimitry Andric
61291bc56edSDimitry Andric assert(NSize != 0 && RegDecoder != nullptr);
61391bc56edSDimitry Andric
61491bc56edSDimitry Andric // $wd
61591bc56edSDimitry Andric tmp = fieldFromInstruction(insn, 6, 5);
61691bc56edSDimitry Andric if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
61791bc56edSDimitry Andric return MCDisassembler::Fail;
61891bc56edSDimitry Andric // $wd_in
61991bc56edSDimitry Andric if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
62091bc56edSDimitry Andric return MCDisassembler::Fail;
62191bc56edSDimitry Andric // $n
62291bc56edSDimitry Andric tmp = fieldFromInstruction(insn, 16, NSize);
623ff0cc061SDimitry Andric MI.addOperand(MCOperand::createImm(tmp));
62491bc56edSDimitry Andric // $ws
62591bc56edSDimitry Andric tmp = fieldFromInstruction(insn, 11, 5);
62691bc56edSDimitry Andric if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
62791bc56edSDimitry Andric return MCDisassembler::Fail;
62891bc56edSDimitry Andric // $n2
629ff0cc061SDimitry Andric MI.addOperand(MCOperand::createImm(0));
63091bc56edSDimitry Andric
63191bc56edSDimitry Andric return MCDisassembler::Success;
63291bc56edSDimitry Andric }
63391bc56edSDimitry Andric
63491bc56edSDimitry Andric template <typename InsnType>
DecodeDAHIDATIMMR6(MCInst & MI,InsnType insn,uint64_t Address,const void * Decoder)635d88c1a5aSDimitry Andric static DecodeStatus DecodeDAHIDATIMMR6(MCInst &MI, InsnType insn, uint64_t Address,
636d88c1a5aSDimitry Andric const void *Decoder) {
637d88c1a5aSDimitry Andric InsnType Rs = fieldFromInstruction(insn, 16, 5);
638d88c1a5aSDimitry Andric InsnType Imm = fieldFromInstruction(insn, 0, 16);
639d88c1a5aSDimitry Andric MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID,
640d88c1a5aSDimitry Andric Rs)));
641d88c1a5aSDimitry Andric MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID,
642d88c1a5aSDimitry Andric Rs)));
643d88c1a5aSDimitry Andric MI.addOperand(MCOperand::createImm(Imm));
644d88c1a5aSDimitry Andric
645d88c1a5aSDimitry Andric return MCDisassembler::Success;
646d88c1a5aSDimitry Andric }
647d88c1a5aSDimitry Andric
648d88c1a5aSDimitry Andric template <typename InsnType>
DecodeDAHIDATI(MCInst & MI,InsnType insn,uint64_t Address,const void * Decoder)649d88c1a5aSDimitry Andric static DecodeStatus DecodeDAHIDATI(MCInst &MI, InsnType insn, uint64_t Address,
650d88c1a5aSDimitry Andric const void *Decoder) {
651d88c1a5aSDimitry Andric InsnType Rs = fieldFromInstruction(insn, 21, 5);
652d88c1a5aSDimitry Andric InsnType Imm = fieldFromInstruction(insn, 0, 16);
653d88c1a5aSDimitry Andric MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID,
654d88c1a5aSDimitry Andric Rs)));
655d88c1a5aSDimitry Andric MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID,
656d88c1a5aSDimitry Andric Rs)));
657d88c1a5aSDimitry Andric MI.addOperand(MCOperand::createImm(Imm));
658d88c1a5aSDimitry Andric
659d88c1a5aSDimitry Andric return MCDisassembler::Success;
660d88c1a5aSDimitry Andric }
661d88c1a5aSDimitry Andric
662d88c1a5aSDimitry Andric template <typename InsnType>
DecodeAddiGroupBranch(MCInst & MI,InsnType insn,uint64_t Address,const void * Decoder)66391bc56edSDimitry Andric static DecodeStatus DecodeAddiGroupBranch(MCInst &MI, InsnType insn,
66491bc56edSDimitry Andric uint64_t Address,
66591bc56edSDimitry Andric const void *Decoder) {
66691bc56edSDimitry Andric // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
66791bc56edSDimitry Andric // (otherwise we would have matched the ADDI instruction from the earlier
66891bc56edSDimitry Andric // ISA's instead).
66991bc56edSDimitry Andric //
67091bc56edSDimitry Andric // We have:
67191bc56edSDimitry Andric // 0b001000 sssss ttttt iiiiiiiiiiiiiiii
67291bc56edSDimitry Andric // BOVC if rs >= rt
67391bc56edSDimitry Andric // BEQZALC if rs == 0 && rt != 0
67491bc56edSDimitry Andric // BEQC if rs < rt && rs != 0
67591bc56edSDimitry Andric
67691bc56edSDimitry Andric InsnType Rs = fieldFromInstruction(insn, 21, 5);
67791bc56edSDimitry Andric InsnType Rt = fieldFromInstruction(insn, 16, 5);
6783ca95b02SDimitry Andric int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
67991bc56edSDimitry Andric bool HasRs = false;
68091bc56edSDimitry Andric
68191bc56edSDimitry Andric if (Rs >= Rt) {
68291bc56edSDimitry Andric MI.setOpcode(Mips::BOVC);
68391bc56edSDimitry Andric HasRs = true;
68491bc56edSDimitry Andric } else if (Rs != 0 && Rs < Rt) {
68591bc56edSDimitry Andric MI.setOpcode(Mips::BEQC);
68691bc56edSDimitry Andric HasRs = true;
68791bc56edSDimitry Andric } else
68891bc56edSDimitry Andric MI.setOpcode(Mips::BEQZALC);
68991bc56edSDimitry Andric
69091bc56edSDimitry Andric if (HasRs)
691ff0cc061SDimitry Andric MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
69291bc56edSDimitry Andric Rs)));
69391bc56edSDimitry Andric
694ff0cc061SDimitry Andric MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
69591bc56edSDimitry Andric Rt)));
696ff0cc061SDimitry Andric MI.addOperand(MCOperand::createImm(Imm));
69791bc56edSDimitry Andric
69891bc56edSDimitry Andric return MCDisassembler::Success;
69991bc56edSDimitry Andric }
70091bc56edSDimitry Andric
70191bc56edSDimitry Andric template <typename InsnType>
DecodePOP35GroupBranchMMR6(MCInst & MI,InsnType insn,uint64_t Address,const void * Decoder)7023ca95b02SDimitry Andric static DecodeStatus DecodePOP35GroupBranchMMR6(MCInst &MI, InsnType insn,
7033ca95b02SDimitry Andric uint64_t Address,
7043ca95b02SDimitry Andric const void *Decoder) {
7053ca95b02SDimitry Andric InsnType Rt = fieldFromInstruction(insn, 21, 5);
7063ca95b02SDimitry Andric InsnType Rs = fieldFromInstruction(insn, 16, 5);
707d88c1a5aSDimitry Andric int64_t Imm = 0;
7083ca95b02SDimitry Andric
7093ca95b02SDimitry Andric if (Rs >= Rt) {
7103ca95b02SDimitry Andric MI.setOpcode(Mips::BOVC_MMR6);
7113ca95b02SDimitry Andric MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
7123ca95b02SDimitry Andric Rt)));
7133ca95b02SDimitry Andric MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
7143ca95b02SDimitry Andric Rs)));
715d88c1a5aSDimitry Andric Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
7163ca95b02SDimitry Andric } else if (Rs != 0 && Rs < Rt) {
7173ca95b02SDimitry Andric MI.setOpcode(Mips::BEQC_MMR6);
7183ca95b02SDimitry Andric MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
7193ca95b02SDimitry Andric Rs)));
7203ca95b02SDimitry Andric MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
7213ca95b02SDimitry Andric Rt)));
722d88c1a5aSDimitry Andric Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
7233ca95b02SDimitry Andric } else {
7243ca95b02SDimitry Andric MI.setOpcode(Mips::BEQZALC_MMR6);
7253ca95b02SDimitry Andric MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
7263ca95b02SDimitry Andric Rt)));
727d88c1a5aSDimitry Andric Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
7283ca95b02SDimitry Andric }
7293ca95b02SDimitry Andric
7303ca95b02SDimitry Andric MI.addOperand(MCOperand::createImm(Imm));
7313ca95b02SDimitry Andric
7323ca95b02SDimitry Andric return MCDisassembler::Success;
7333ca95b02SDimitry Andric }
7343ca95b02SDimitry Andric
7353ca95b02SDimitry Andric template <typename InsnType>
DecodeDaddiGroupBranch(MCInst & MI,InsnType insn,uint64_t Address,const void * Decoder)73691bc56edSDimitry Andric static DecodeStatus DecodeDaddiGroupBranch(MCInst &MI, InsnType insn,
73791bc56edSDimitry Andric uint64_t Address,
73891bc56edSDimitry Andric const void *Decoder) {
73991bc56edSDimitry Andric // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
74091bc56edSDimitry Andric // (otherwise we would have matched the ADDI instruction from the earlier
74191bc56edSDimitry Andric // ISA's instead).
74291bc56edSDimitry Andric //
74391bc56edSDimitry Andric // We have:
74491bc56edSDimitry Andric // 0b011000 sssss ttttt iiiiiiiiiiiiiiii
74591bc56edSDimitry Andric // BNVC if rs >= rt
74691bc56edSDimitry Andric // BNEZALC if rs == 0 && rt != 0
74791bc56edSDimitry Andric // BNEC if rs < rt && rs != 0
74891bc56edSDimitry Andric
74991bc56edSDimitry Andric InsnType Rs = fieldFromInstruction(insn, 21, 5);
75091bc56edSDimitry Andric InsnType Rt = fieldFromInstruction(insn, 16, 5);
7513ca95b02SDimitry Andric int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
75291bc56edSDimitry Andric bool HasRs = false;
75391bc56edSDimitry Andric
75491bc56edSDimitry Andric if (Rs >= Rt) {
75591bc56edSDimitry Andric MI.setOpcode(Mips::BNVC);
75691bc56edSDimitry Andric HasRs = true;
75791bc56edSDimitry Andric } else if (Rs != 0 && Rs < Rt) {
75891bc56edSDimitry Andric MI.setOpcode(Mips::BNEC);
75991bc56edSDimitry Andric HasRs = true;
76091bc56edSDimitry Andric } else
76191bc56edSDimitry Andric MI.setOpcode(Mips::BNEZALC);
76291bc56edSDimitry Andric
76391bc56edSDimitry Andric if (HasRs)
764ff0cc061SDimitry Andric MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
76591bc56edSDimitry Andric Rs)));
76691bc56edSDimitry Andric
767ff0cc061SDimitry Andric MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
76891bc56edSDimitry Andric Rt)));
769ff0cc061SDimitry Andric MI.addOperand(MCOperand::createImm(Imm));
77091bc56edSDimitry Andric
77191bc56edSDimitry Andric return MCDisassembler::Success;
77291bc56edSDimitry Andric }
77391bc56edSDimitry Andric
77491bc56edSDimitry Andric template <typename InsnType>
DecodePOP37GroupBranchMMR6(MCInst & MI,InsnType insn,uint64_t Address,const void * Decoder)7753ca95b02SDimitry Andric static DecodeStatus DecodePOP37GroupBranchMMR6(MCInst &MI, InsnType insn,
7763ca95b02SDimitry Andric uint64_t Address,
7773ca95b02SDimitry Andric const void *Decoder) {
7783ca95b02SDimitry Andric InsnType Rt = fieldFromInstruction(insn, 21, 5);
7793ca95b02SDimitry Andric InsnType Rs = fieldFromInstruction(insn, 16, 5);
780d88c1a5aSDimitry Andric int64_t Imm = 0;
7813ca95b02SDimitry Andric
7823ca95b02SDimitry Andric if (Rs >= Rt) {
7833ca95b02SDimitry Andric MI.setOpcode(Mips::BNVC_MMR6);
7843ca95b02SDimitry Andric MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
7853ca95b02SDimitry Andric Rt)));
7863ca95b02SDimitry Andric MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
7873ca95b02SDimitry Andric Rs)));
788d88c1a5aSDimitry Andric Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
7893ca95b02SDimitry Andric } else if (Rs != 0 && Rs < Rt) {
7903ca95b02SDimitry Andric MI.setOpcode(Mips::BNEC_MMR6);
7913ca95b02SDimitry Andric MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
7923ca95b02SDimitry Andric Rs)));
7933ca95b02SDimitry Andric MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
7943ca95b02SDimitry Andric Rt)));
795d88c1a5aSDimitry Andric Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
7963ca95b02SDimitry Andric } else {
7973ca95b02SDimitry Andric MI.setOpcode(Mips::BNEZALC_MMR6);
7983ca95b02SDimitry Andric MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
7993ca95b02SDimitry Andric Rt)));
800d88c1a5aSDimitry Andric Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
8013ca95b02SDimitry Andric }
8023ca95b02SDimitry Andric
8033ca95b02SDimitry Andric MI.addOperand(MCOperand::createImm(Imm));
8043ca95b02SDimitry Andric
8053ca95b02SDimitry Andric return MCDisassembler::Success;
8063ca95b02SDimitry Andric }
8073ca95b02SDimitry Andric
8083ca95b02SDimitry Andric template <typename InsnType>
DecodePOP65GroupBranchMMR6(MCInst & MI,InsnType insn,uint64_t Address,const void * Decoder)809d88c1a5aSDimitry Andric static DecodeStatus DecodePOP65GroupBranchMMR6(MCInst &MI, InsnType insn,
810d88c1a5aSDimitry Andric uint64_t Address,
811d88c1a5aSDimitry Andric const void *Decoder) {
812d88c1a5aSDimitry Andric // We have:
813d88c1a5aSDimitry Andric // 0b110101 ttttt sssss iiiiiiiiiiiiiiii
814d88c1a5aSDimitry Andric // Invalid if rt == 0
815d88c1a5aSDimitry Andric // BGTZC_MMR6 if rs == 0 && rt != 0
816d88c1a5aSDimitry Andric // BLTZC_MMR6 if rs == rt && rt != 0
817d88c1a5aSDimitry Andric // BLTC_MMR6 if rs != rt && rs != 0 && rt != 0
818d88c1a5aSDimitry Andric
819d88c1a5aSDimitry Andric InsnType Rt = fieldFromInstruction(insn, 21, 5);
820d88c1a5aSDimitry Andric InsnType Rs = fieldFromInstruction(insn, 16, 5);
821d88c1a5aSDimitry Andric int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
822d88c1a5aSDimitry Andric bool HasRs = false;
823d88c1a5aSDimitry Andric
824d88c1a5aSDimitry Andric if (Rt == 0)
825d88c1a5aSDimitry Andric return MCDisassembler::Fail;
826d88c1a5aSDimitry Andric else if (Rs == 0)
827d88c1a5aSDimitry Andric MI.setOpcode(Mips::BGTZC_MMR6);
828d88c1a5aSDimitry Andric else if (Rs == Rt)
829d88c1a5aSDimitry Andric MI.setOpcode(Mips::BLTZC_MMR6);
830d88c1a5aSDimitry Andric else {
831d88c1a5aSDimitry Andric MI.setOpcode(Mips::BLTC_MMR6);
832d88c1a5aSDimitry Andric HasRs = true;
833d88c1a5aSDimitry Andric }
834d88c1a5aSDimitry Andric
835d88c1a5aSDimitry Andric if (HasRs)
836d88c1a5aSDimitry Andric MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
837d88c1a5aSDimitry Andric Rs)));
838d88c1a5aSDimitry Andric
839d88c1a5aSDimitry Andric MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
840d88c1a5aSDimitry Andric Rt)));
841d88c1a5aSDimitry Andric
842d88c1a5aSDimitry Andric MI.addOperand(MCOperand::createImm(Imm));
843d88c1a5aSDimitry Andric
844d88c1a5aSDimitry Andric return MCDisassembler::Success;
845d88c1a5aSDimitry Andric }
846d88c1a5aSDimitry Andric
847d88c1a5aSDimitry Andric template <typename InsnType>
DecodePOP75GroupBranchMMR6(MCInst & MI,InsnType insn,uint64_t Address,const void * Decoder)848d88c1a5aSDimitry Andric static DecodeStatus DecodePOP75GroupBranchMMR6(MCInst &MI, InsnType insn,
849d88c1a5aSDimitry Andric uint64_t Address,
850d88c1a5aSDimitry Andric const void *Decoder) {
851d88c1a5aSDimitry Andric // We have:
852d88c1a5aSDimitry Andric // 0b111101 ttttt sssss iiiiiiiiiiiiiiii
853d88c1a5aSDimitry Andric // Invalid if rt == 0
854d88c1a5aSDimitry Andric // BLEZC_MMR6 if rs == 0 && rt != 0
855d88c1a5aSDimitry Andric // BGEZC_MMR6 if rs == rt && rt != 0
856d88c1a5aSDimitry Andric // BGEC_MMR6 if rs != rt && rs != 0 && rt != 0
857d88c1a5aSDimitry Andric
858d88c1a5aSDimitry Andric InsnType Rt = fieldFromInstruction(insn, 21, 5);
859d88c1a5aSDimitry Andric InsnType Rs = fieldFromInstruction(insn, 16, 5);
860d88c1a5aSDimitry Andric int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
861d88c1a5aSDimitry Andric bool HasRs = false;
862d88c1a5aSDimitry Andric
863d88c1a5aSDimitry Andric if (Rt == 0)
864d88c1a5aSDimitry Andric return MCDisassembler::Fail;
865d88c1a5aSDimitry Andric else if (Rs == 0)
866d88c1a5aSDimitry Andric MI.setOpcode(Mips::BLEZC_MMR6);
867d88c1a5aSDimitry Andric else if (Rs == Rt)
868d88c1a5aSDimitry Andric MI.setOpcode(Mips::BGEZC_MMR6);
869d88c1a5aSDimitry Andric else {
870d88c1a5aSDimitry Andric HasRs = true;
871d88c1a5aSDimitry Andric MI.setOpcode(Mips::BGEC_MMR6);
872d88c1a5aSDimitry Andric }
873d88c1a5aSDimitry Andric
874d88c1a5aSDimitry Andric if (HasRs)
875d88c1a5aSDimitry Andric MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
876d88c1a5aSDimitry Andric Rs)));
877d88c1a5aSDimitry Andric
878d88c1a5aSDimitry Andric MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
879d88c1a5aSDimitry Andric Rt)));
880d88c1a5aSDimitry Andric
881d88c1a5aSDimitry Andric MI.addOperand(MCOperand::createImm(Imm));
882d88c1a5aSDimitry Andric
883d88c1a5aSDimitry Andric return MCDisassembler::Success;
884d88c1a5aSDimitry Andric }
885d88c1a5aSDimitry Andric
886d88c1a5aSDimitry Andric template <typename InsnType>
DecodeBlezlGroupBranch(MCInst & MI,InsnType insn,uint64_t Address,const void * Decoder)88791bc56edSDimitry Andric static DecodeStatus DecodeBlezlGroupBranch(MCInst &MI, InsnType insn,
88891bc56edSDimitry Andric uint64_t Address,
88991bc56edSDimitry Andric const void *Decoder) {
89091bc56edSDimitry Andric // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
89191bc56edSDimitry Andric // (otherwise we would have matched the BLEZL instruction from the earlier
89291bc56edSDimitry Andric // ISA's instead).
89391bc56edSDimitry Andric //
89491bc56edSDimitry Andric // We have:
89591bc56edSDimitry Andric // 0b010110 sssss ttttt iiiiiiiiiiiiiiii
89691bc56edSDimitry Andric // Invalid if rs == 0
89791bc56edSDimitry Andric // BLEZC if rs == 0 && rt != 0
89891bc56edSDimitry Andric // BGEZC if rs == rt && rt != 0
89991bc56edSDimitry Andric // BGEC if rs != rt && rs != 0 && rt != 0
90091bc56edSDimitry Andric
90191bc56edSDimitry Andric InsnType Rs = fieldFromInstruction(insn, 21, 5);
90291bc56edSDimitry Andric InsnType Rt = fieldFromInstruction(insn, 16, 5);
9033ca95b02SDimitry Andric int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
90491bc56edSDimitry Andric bool HasRs = false;
90591bc56edSDimitry Andric
90691bc56edSDimitry Andric if (Rt == 0)
90791bc56edSDimitry Andric return MCDisassembler::Fail;
90891bc56edSDimitry Andric else if (Rs == 0)
90991bc56edSDimitry Andric MI.setOpcode(Mips::BLEZC);
91091bc56edSDimitry Andric else if (Rs == Rt)
91191bc56edSDimitry Andric MI.setOpcode(Mips::BGEZC);
91291bc56edSDimitry Andric else {
91391bc56edSDimitry Andric HasRs = true;
91491bc56edSDimitry Andric MI.setOpcode(Mips::BGEC);
91591bc56edSDimitry Andric }
91691bc56edSDimitry Andric
91791bc56edSDimitry Andric if (HasRs)
918ff0cc061SDimitry Andric MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
91991bc56edSDimitry Andric Rs)));
92091bc56edSDimitry Andric
921ff0cc061SDimitry Andric MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
92291bc56edSDimitry Andric Rt)));
92391bc56edSDimitry Andric
924ff0cc061SDimitry Andric MI.addOperand(MCOperand::createImm(Imm));
92591bc56edSDimitry Andric
92691bc56edSDimitry Andric return MCDisassembler::Success;
92791bc56edSDimitry Andric }
92891bc56edSDimitry Andric
92991bc56edSDimitry Andric template <typename InsnType>
DecodeBgtzlGroupBranch(MCInst & MI,InsnType insn,uint64_t Address,const void * Decoder)93091bc56edSDimitry Andric static DecodeStatus DecodeBgtzlGroupBranch(MCInst &MI, InsnType insn,
93191bc56edSDimitry Andric uint64_t Address,
93291bc56edSDimitry Andric const void *Decoder) {
93391bc56edSDimitry Andric // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
93491bc56edSDimitry Andric // (otherwise we would have matched the BGTZL instruction from the earlier
93591bc56edSDimitry Andric // ISA's instead).
93691bc56edSDimitry Andric //
93791bc56edSDimitry Andric // We have:
93891bc56edSDimitry Andric // 0b010111 sssss ttttt iiiiiiiiiiiiiiii
93991bc56edSDimitry Andric // Invalid if rs == 0
94091bc56edSDimitry Andric // BGTZC if rs == 0 && rt != 0
94191bc56edSDimitry Andric // BLTZC if rs == rt && rt != 0
94291bc56edSDimitry Andric // BLTC if rs != rt && rs != 0 && rt != 0
94391bc56edSDimitry Andric
94491bc56edSDimitry Andric bool HasRs = false;
94591bc56edSDimitry Andric
94691bc56edSDimitry Andric InsnType Rs = fieldFromInstruction(insn, 21, 5);
94791bc56edSDimitry Andric InsnType Rt = fieldFromInstruction(insn, 16, 5);
9483ca95b02SDimitry Andric int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
94991bc56edSDimitry Andric
95091bc56edSDimitry Andric if (Rt == 0)
95191bc56edSDimitry Andric return MCDisassembler::Fail;
95291bc56edSDimitry Andric else if (Rs == 0)
95391bc56edSDimitry Andric MI.setOpcode(Mips::BGTZC);
95491bc56edSDimitry Andric else if (Rs == Rt)
95591bc56edSDimitry Andric MI.setOpcode(Mips::BLTZC);
95691bc56edSDimitry Andric else {
95791bc56edSDimitry Andric MI.setOpcode(Mips::BLTC);
95891bc56edSDimitry Andric HasRs = true;
95991bc56edSDimitry Andric }
96091bc56edSDimitry Andric
96191bc56edSDimitry Andric if (HasRs)
962ff0cc061SDimitry Andric MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
96391bc56edSDimitry Andric Rs)));
96491bc56edSDimitry Andric
965ff0cc061SDimitry Andric MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
96691bc56edSDimitry Andric Rt)));
96791bc56edSDimitry Andric
968ff0cc061SDimitry Andric MI.addOperand(MCOperand::createImm(Imm));
96991bc56edSDimitry Andric
97091bc56edSDimitry Andric return MCDisassembler::Success;
97191bc56edSDimitry Andric }
97291bc56edSDimitry Andric
97391bc56edSDimitry Andric template <typename InsnType>
DecodeBgtzGroupBranch(MCInst & MI,InsnType insn,uint64_t Address,const void * Decoder)97491bc56edSDimitry Andric static DecodeStatus DecodeBgtzGroupBranch(MCInst &MI, InsnType insn,
97591bc56edSDimitry Andric uint64_t Address,
97691bc56edSDimitry Andric const void *Decoder) {
97791bc56edSDimitry Andric // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
97891bc56edSDimitry Andric // (otherwise we would have matched the BGTZ instruction from the earlier
97991bc56edSDimitry Andric // ISA's instead).
98091bc56edSDimitry Andric //
98191bc56edSDimitry Andric // We have:
98291bc56edSDimitry Andric // 0b000111 sssss ttttt iiiiiiiiiiiiiiii
98391bc56edSDimitry Andric // BGTZ if rt == 0
98491bc56edSDimitry Andric // BGTZALC if rs == 0 && rt != 0
98591bc56edSDimitry Andric // BLTZALC if rs != 0 && rs == rt
98691bc56edSDimitry Andric // BLTUC if rs != 0 && rs != rt
98791bc56edSDimitry Andric
98891bc56edSDimitry Andric InsnType Rs = fieldFromInstruction(insn, 21, 5);
98991bc56edSDimitry Andric InsnType Rt = fieldFromInstruction(insn, 16, 5);
9903ca95b02SDimitry Andric int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
99191bc56edSDimitry Andric bool HasRs = false;
99291bc56edSDimitry Andric bool HasRt = false;
99391bc56edSDimitry Andric
99491bc56edSDimitry Andric if (Rt == 0) {
99591bc56edSDimitry Andric MI.setOpcode(Mips::BGTZ);
99691bc56edSDimitry Andric HasRs = true;
99791bc56edSDimitry Andric } else if (Rs == 0) {
99891bc56edSDimitry Andric MI.setOpcode(Mips::BGTZALC);
99991bc56edSDimitry Andric HasRt = true;
100091bc56edSDimitry Andric } else if (Rs == Rt) {
100191bc56edSDimitry Andric MI.setOpcode(Mips::BLTZALC);
100291bc56edSDimitry Andric HasRs = true;
100391bc56edSDimitry Andric } else {
100491bc56edSDimitry Andric MI.setOpcode(Mips::BLTUC);
100591bc56edSDimitry Andric HasRs = true;
100691bc56edSDimitry Andric HasRt = true;
100791bc56edSDimitry Andric }
100891bc56edSDimitry Andric
100991bc56edSDimitry Andric if (HasRs)
1010ff0cc061SDimitry Andric MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
101191bc56edSDimitry Andric Rs)));
101291bc56edSDimitry Andric
101391bc56edSDimitry Andric if (HasRt)
1014ff0cc061SDimitry Andric MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
101591bc56edSDimitry Andric Rt)));
101691bc56edSDimitry Andric
1017ff0cc061SDimitry Andric MI.addOperand(MCOperand::createImm(Imm));
101891bc56edSDimitry Andric
101991bc56edSDimitry Andric return MCDisassembler::Success;
102091bc56edSDimitry Andric }
102191bc56edSDimitry Andric
102291bc56edSDimitry Andric template <typename InsnType>
DecodeBlezGroupBranch(MCInst & MI,InsnType insn,uint64_t Address,const void * Decoder)102391bc56edSDimitry Andric static DecodeStatus DecodeBlezGroupBranch(MCInst &MI, InsnType insn,
102491bc56edSDimitry Andric uint64_t Address,
102591bc56edSDimitry Andric const void *Decoder) {
102691bc56edSDimitry Andric // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
102791bc56edSDimitry Andric // (otherwise we would have matched the BLEZL instruction from the earlier
102891bc56edSDimitry Andric // ISA's instead).
102991bc56edSDimitry Andric //
103091bc56edSDimitry Andric // We have:
103191bc56edSDimitry Andric // 0b000110 sssss ttttt iiiiiiiiiiiiiiii
103291bc56edSDimitry Andric // Invalid if rs == 0
103391bc56edSDimitry Andric // BLEZALC if rs == 0 && rt != 0
103491bc56edSDimitry Andric // BGEZALC if rs == rt && rt != 0
103591bc56edSDimitry Andric // BGEUC if rs != rt && rs != 0 && rt != 0
103691bc56edSDimitry Andric
103791bc56edSDimitry Andric InsnType Rs = fieldFromInstruction(insn, 21, 5);
103891bc56edSDimitry Andric InsnType Rt = fieldFromInstruction(insn, 16, 5);
10393ca95b02SDimitry Andric int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
104091bc56edSDimitry Andric bool HasRs = false;
104191bc56edSDimitry Andric
104291bc56edSDimitry Andric if (Rt == 0)
104391bc56edSDimitry Andric return MCDisassembler::Fail;
104491bc56edSDimitry Andric else if (Rs == 0)
104591bc56edSDimitry Andric MI.setOpcode(Mips::BLEZALC);
104691bc56edSDimitry Andric else if (Rs == Rt)
104791bc56edSDimitry Andric MI.setOpcode(Mips::BGEZALC);
104891bc56edSDimitry Andric else {
104991bc56edSDimitry Andric HasRs = true;
105091bc56edSDimitry Andric MI.setOpcode(Mips::BGEUC);
105191bc56edSDimitry Andric }
105291bc56edSDimitry Andric
105391bc56edSDimitry Andric if (HasRs)
1054ff0cc061SDimitry Andric MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
105591bc56edSDimitry Andric Rs)));
1056ff0cc061SDimitry Andric MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
105791bc56edSDimitry Andric Rt)));
105891bc56edSDimitry Andric
1059ff0cc061SDimitry Andric MI.addOperand(MCOperand::createImm(Imm));
106091bc56edSDimitry Andric
106191bc56edSDimitry Andric return MCDisassembler::Success;
106291bc56edSDimitry Andric }
106391bc56edSDimitry Andric
10642cab237bSDimitry Andric // Override the generated disassembler to produce DEXT all the time. This is
10652cab237bSDimitry Andric // for feature / behaviour parity with binutils.
10662cab237bSDimitry Andric template <typename InsnType>
DecodeDEXT(MCInst & MI,InsnType Insn,uint64_t Address,const void * Decoder)10672cab237bSDimitry Andric static DecodeStatus DecodeDEXT(MCInst &MI, InsnType Insn, uint64_t Address,
10682cab237bSDimitry Andric const void *Decoder) {
10692cab237bSDimitry Andric unsigned Msbd = fieldFromInstruction(Insn, 11, 5);
10702cab237bSDimitry Andric unsigned Lsb = fieldFromInstruction(Insn, 6, 5);
10712cab237bSDimitry Andric unsigned Size = 0;
10722cab237bSDimitry Andric unsigned Pos = 0;
10732cab237bSDimitry Andric
10742cab237bSDimitry Andric switch (MI.getOpcode()) {
10752cab237bSDimitry Andric case Mips::DEXT:
10762cab237bSDimitry Andric Pos = Lsb;
10772cab237bSDimitry Andric Size = Msbd + 1;
10782cab237bSDimitry Andric break;
10792cab237bSDimitry Andric case Mips::DEXTM:
10802cab237bSDimitry Andric Pos = Lsb;
10812cab237bSDimitry Andric Size = Msbd + 1 + 32;
10822cab237bSDimitry Andric break;
10832cab237bSDimitry Andric case Mips::DEXTU:
10842cab237bSDimitry Andric Pos = Lsb + 32;
10852cab237bSDimitry Andric Size = Msbd + 1;
10862cab237bSDimitry Andric break;
10872cab237bSDimitry Andric default:
10882cab237bSDimitry Andric llvm_unreachable("Unknown DEXT instruction!");
10892cab237bSDimitry Andric }
10902cab237bSDimitry Andric
10912cab237bSDimitry Andric MI.setOpcode(Mips::DEXT);
10922cab237bSDimitry Andric
10932cab237bSDimitry Andric InsnType Rs = fieldFromInstruction(Insn, 21, 5);
10942cab237bSDimitry Andric InsnType Rt = fieldFromInstruction(Insn, 16, 5);
10952cab237bSDimitry Andric
10962cab237bSDimitry Andric MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID, Rt)));
10972cab237bSDimitry Andric MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID, Rs)));
10982cab237bSDimitry Andric MI.addOperand(MCOperand::createImm(Pos));
10992cab237bSDimitry Andric MI.addOperand(MCOperand::createImm(Size));
11002cab237bSDimitry Andric
11012cab237bSDimitry Andric return MCDisassembler::Success;
11022cab237bSDimitry Andric }
11032cab237bSDimitry Andric
11042cab237bSDimitry Andric // Override the generated disassembler to produce DINS all the time. This is
11052cab237bSDimitry Andric // for feature / behaviour parity with binutils.
11062cab237bSDimitry Andric template <typename InsnType>
DecodeDINS(MCInst & MI,InsnType Insn,uint64_t Address,const void * Decoder)11072cab237bSDimitry Andric static DecodeStatus DecodeDINS(MCInst &MI, InsnType Insn, uint64_t Address,
11082cab237bSDimitry Andric const void *Decoder) {
11092cab237bSDimitry Andric unsigned Msbd = fieldFromInstruction(Insn, 11, 5);
11102cab237bSDimitry Andric unsigned Lsb = fieldFromInstruction(Insn, 6, 5);
11112cab237bSDimitry Andric unsigned Size = 0;
11122cab237bSDimitry Andric unsigned Pos = 0;
11132cab237bSDimitry Andric
11142cab237bSDimitry Andric switch (MI.getOpcode()) {
11152cab237bSDimitry Andric case Mips::DINS:
11162cab237bSDimitry Andric Pos = Lsb;
11172cab237bSDimitry Andric Size = Msbd + 1 - Pos;
11182cab237bSDimitry Andric break;
11192cab237bSDimitry Andric case Mips::DINSM:
11202cab237bSDimitry Andric Pos = Lsb;
11212cab237bSDimitry Andric Size = Msbd + 33 - Pos;
11222cab237bSDimitry Andric break;
11232cab237bSDimitry Andric case Mips::DINSU:
11242cab237bSDimitry Andric Pos = Lsb + 32;
11252cab237bSDimitry Andric // mbsd = pos + size - 33
11262cab237bSDimitry Andric // mbsd - pos + 33 = size
11272cab237bSDimitry Andric Size = Msbd + 33 - Pos;
11282cab237bSDimitry Andric break;
11292cab237bSDimitry Andric default:
11302cab237bSDimitry Andric llvm_unreachable("Unknown DINS instruction!");
11312cab237bSDimitry Andric }
11322cab237bSDimitry Andric
11332cab237bSDimitry Andric InsnType Rs = fieldFromInstruction(Insn, 21, 5);
11342cab237bSDimitry Andric InsnType Rt = fieldFromInstruction(Insn, 16, 5);
11352cab237bSDimitry Andric
11362cab237bSDimitry Andric MI.setOpcode(Mips::DINS);
11372cab237bSDimitry Andric MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID, Rt)));
11382cab237bSDimitry Andric MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID, Rs)));
11392cab237bSDimitry Andric MI.addOperand(MCOperand::createImm(Pos));
11402cab237bSDimitry Andric MI.addOperand(MCOperand::createImm(Size));
11412cab237bSDimitry Andric
11422cab237bSDimitry Andric return MCDisassembler::Success;
11432cab237bSDimitry Andric }
11444ba319b5SDimitry Andric
11454ba319b5SDimitry Andric // Auto-generated decoder wouldn't add the third operand for CRC32*.
11464ba319b5SDimitry Andric template <typename InsnType>
DecodeCRC(MCInst & MI,InsnType Insn,uint64_t Address,const void * Decoder)11474ba319b5SDimitry Andric static DecodeStatus DecodeCRC(MCInst &MI, InsnType Insn, uint64_t Address,
11484ba319b5SDimitry Andric const void *Decoder) {
11494ba319b5SDimitry Andric InsnType Rs = fieldFromInstruction(Insn, 21, 5);
11504ba319b5SDimitry Andric InsnType Rt = fieldFromInstruction(Insn, 16, 5);
11514ba319b5SDimitry Andric MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
11524ba319b5SDimitry Andric Rt)));
11534ba319b5SDimitry Andric MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
11544ba319b5SDimitry Andric Rs)));
11554ba319b5SDimitry Andric MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
11564ba319b5SDimitry Andric Rt)));
11574ba319b5SDimitry Andric return MCDisassembler::Success;
11584ba319b5SDimitry Andric }
11594ba319b5SDimitry Andric
116039d628a0SDimitry Andric /// Read two bytes from the ArrayRef and return 16 bit halfword sorted
1161d88c1a5aSDimitry Andric /// according to the given endianness.
readInstruction16(ArrayRef<uint8_t> Bytes,uint64_t Address,uint64_t & Size,uint32_t & Insn,bool IsBigEndian)116239d628a0SDimitry Andric static DecodeStatus readInstruction16(ArrayRef<uint8_t> Bytes, uint64_t Address,
116339d628a0SDimitry Andric uint64_t &Size, uint32_t &Insn,
116439d628a0SDimitry Andric bool IsBigEndian) {
116539d628a0SDimitry Andric // We want to read exactly 2 Bytes of data.
116639d628a0SDimitry Andric if (Bytes.size() < 2) {
116739d628a0SDimitry Andric Size = 0;
1168cb4dff85SDimitry Andric return MCDisassembler::Fail;
1169cb4dff85SDimitry Andric }
1170cb4dff85SDimitry Andric
117139d628a0SDimitry Andric if (IsBigEndian) {
117239d628a0SDimitry Andric Insn = (Bytes[0] << 8) | Bytes[1];
117339d628a0SDimitry Andric } else {
117439d628a0SDimitry Andric Insn = (Bytes[1] << 8) | Bytes[0];
1175cb4dff85SDimitry Andric }
117639d628a0SDimitry Andric
117739d628a0SDimitry Andric return MCDisassembler::Success;
117839d628a0SDimitry Andric }
117939d628a0SDimitry Andric
118039d628a0SDimitry Andric /// Read four bytes from the ArrayRef and return 32 bit word sorted
1181d88c1a5aSDimitry Andric /// according to the given endianness.
readInstruction32(ArrayRef<uint8_t> Bytes,uint64_t Address,uint64_t & Size,uint32_t & Insn,bool IsBigEndian,bool IsMicroMips)118239d628a0SDimitry Andric static DecodeStatus readInstruction32(ArrayRef<uint8_t> Bytes, uint64_t Address,
118339d628a0SDimitry Andric uint64_t &Size, uint32_t &Insn,
118439d628a0SDimitry Andric bool IsBigEndian, bool IsMicroMips) {
118539d628a0SDimitry Andric // We want to read exactly 4 Bytes of data.
118639d628a0SDimitry Andric if (Bytes.size() < 4) {
118739d628a0SDimitry Andric Size = 0;
118839d628a0SDimitry Andric return MCDisassembler::Fail;
118939d628a0SDimitry Andric }
119039d628a0SDimitry Andric
119139d628a0SDimitry Andric // High 16 bits of a 32-bit microMIPS instruction (where the opcode is)
119239d628a0SDimitry Andric // always precede the low 16 bits in the instruction stream (that is, they
119339d628a0SDimitry Andric // are placed at lower addresses in the instruction stream).
119439d628a0SDimitry Andric //
119539d628a0SDimitry Andric // microMIPS byte ordering:
119639d628a0SDimitry Andric // Big-endian: 0 | 1 | 2 | 3
119739d628a0SDimitry Andric // Little-endian: 1 | 0 | 3 | 2
119839d628a0SDimitry Andric
119939d628a0SDimitry Andric if (IsBigEndian) {
120039d628a0SDimitry Andric // Encoded as a big-endian 32-bit word in the stream.
120139d628a0SDimitry Andric Insn =
120239d628a0SDimitry Andric (Bytes[3] << 0) | (Bytes[2] << 8) | (Bytes[1] << 16) | (Bytes[0] << 24);
120339d628a0SDimitry Andric } else {
1204f785676fSDimitry Andric if (IsMicroMips) {
120539d628a0SDimitry Andric Insn = (Bytes[2] << 0) | (Bytes[3] << 8) | (Bytes[0] << 16) |
1206f785676fSDimitry Andric (Bytes[1] << 24);
1207f785676fSDimitry Andric } else {
120839d628a0SDimitry Andric Insn = (Bytes[0] << 0) | (Bytes[1] << 8) | (Bytes[2] << 16) |
1209cb4dff85SDimitry Andric (Bytes[3] << 24);
1210cb4dff85SDimitry Andric }
1211f785676fSDimitry Andric }
1212cb4dff85SDimitry Andric
1213cb4dff85SDimitry Andric return MCDisassembler::Success;
1214cb4dff85SDimitry Andric }
1215cb4dff85SDimitry Andric
getInstruction(MCInst & Instr,uint64_t & Size,ArrayRef<uint8_t> Bytes,uint64_t Address,raw_ostream & VStream,raw_ostream & CStream) const121639d628a0SDimitry Andric DecodeStatus MipsDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,
121739d628a0SDimitry Andric ArrayRef<uint8_t> Bytes,
1218cb4dff85SDimitry Andric uint64_t Address,
121939d628a0SDimitry Andric raw_ostream &VStream,
122039d628a0SDimitry Andric raw_ostream &CStream) const {
1221cb4dff85SDimitry Andric uint32_t Insn;
122239d628a0SDimitry Andric DecodeStatus Result;
12237a7e6055SDimitry Andric Size = 0;
1224cb4dff85SDimitry Andric
122539d628a0SDimitry Andric if (IsMicroMips) {
122639d628a0SDimitry Andric Result = readInstruction16(Bytes, Address, Size, Insn, IsBigEndian);
12277d523365SDimitry Andric if (Result == MCDisassembler::Fail)
12287d523365SDimitry Andric return MCDisassembler::Fail;
12297d523365SDimitry Andric
12307d523365SDimitry Andric if (hasMips32r6()) {
12314ba319b5SDimitry Andric LLVM_DEBUG(
12324ba319b5SDimitry Andric dbgs() << "Trying MicroMipsR616 table (16-bit instructions):\n");
12337d523365SDimitry Andric // Calling the auto-generated decoder function for microMIPS32R6
12342cab237bSDimitry Andric // 16-bit instructions.
12357d523365SDimitry Andric Result = decodeInstruction(DecoderTableMicroMipsR616, Instr, Insn,
12367d523365SDimitry Andric Address, this, STI);
12377d523365SDimitry Andric if (Result != MCDisassembler::Fail) {
12387d523365SDimitry Andric Size = 2;
12397d523365SDimitry Andric return Result;
12407d523365SDimitry Andric }
12417d523365SDimitry Andric }
124239d628a0SDimitry Andric
12434ba319b5SDimitry Andric LLVM_DEBUG(dbgs() << "Trying MicroMips16 table (16-bit instructions):\n");
12447d523365SDimitry Andric // Calling the auto-generated decoder function for microMIPS 16-bit
12457d523365SDimitry Andric // instructions.
124639d628a0SDimitry Andric Result = decodeInstruction(DecoderTableMicroMips16, Instr, Insn, Address,
124739d628a0SDimitry Andric this, STI);
124839d628a0SDimitry Andric if (Result != MCDisassembler::Fail) {
124939d628a0SDimitry Andric Size = 2;
125039d628a0SDimitry Andric return Result;
125139d628a0SDimitry Andric }
125239d628a0SDimitry Andric
125339d628a0SDimitry Andric Result = readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, true);
1254cb4dff85SDimitry Andric if (Result == MCDisassembler::Fail)
1255cb4dff85SDimitry Andric return MCDisassembler::Fail;
1256cb4dff85SDimitry Andric
1257ff0cc061SDimitry Andric if (hasMips32r6()) {
12584ba319b5SDimitry Andric LLVM_DEBUG(
12594ba319b5SDimitry Andric dbgs() << "Trying MicroMips32r632 table (32-bit instructions):\n");
1260ff0cc061SDimitry Andric // Calling the auto-generated decoder function.
12617d523365SDimitry Andric Result = decodeInstruction(DecoderTableMicroMipsR632, Instr, Insn, Address,
1262ff0cc061SDimitry Andric this, STI);
1263f785676fSDimitry Andric if (Result != MCDisassembler::Fail) {
1264f785676fSDimitry Andric Size = 4;
1265f785676fSDimitry Andric return Result;
1266f785676fSDimitry Andric }
12677d523365SDimitry Andric }
12687d523365SDimitry Andric
12694ba319b5SDimitry Andric LLVM_DEBUG(dbgs() << "Trying MicroMips32 table (32-bit instructions):\n");
12707d523365SDimitry Andric // Calling the auto-generated decoder function.
12717d523365SDimitry Andric Result = decodeInstruction(DecoderTableMicroMips32, Instr, Insn, Address,
12727d523365SDimitry Andric this, STI);
12737d523365SDimitry Andric if (Result != MCDisassembler::Fail) {
12747d523365SDimitry Andric Size = 4;
12757d523365SDimitry Andric return Result;
12767d523365SDimitry Andric }
12773ca95b02SDimitry Andric
12782cab237bSDimitry Andric if (isFP64()) {
12794ba319b5SDimitry Andric LLVM_DEBUG(dbgs() << "Trying MicroMipsFP64 table (32-bit opcodes):\n");
12802cab237bSDimitry Andric Result = decodeInstruction(DecoderTableMicroMipsFP6432, Instr, Insn,
12813ca95b02SDimitry Andric Address, this, STI);
12823ca95b02SDimitry Andric if (Result != MCDisassembler::Fail) {
12833ca95b02SDimitry Andric Size = 4;
12843ca95b02SDimitry Andric return Result;
12853ca95b02SDimitry Andric }
12863ca95b02SDimitry Andric }
12873ca95b02SDimitry Andric
12887a7e6055SDimitry Andric // This is an invalid instruction. Claim that the Size is 2 bytes. Since
12897a7e6055SDimitry Andric // microMIPS instructions have a minimum alignment of 2, the next 2 bytes
12907a7e6055SDimitry Andric // could form a valid instruction. The two bytes we rejected as an
12917a7e6055SDimitry Andric // instruction could have actually beeen an inline constant pool that is
12927a7e6055SDimitry Andric // unconditionally branched over.
12937d523365SDimitry Andric Size = 2;
1294f785676fSDimitry Andric return MCDisassembler::Fail;
1295f785676fSDimitry Andric }
1296f785676fSDimitry Andric
12977a7e6055SDimitry Andric // Attempt to read the instruction so that we can attempt to decode it. If
12987a7e6055SDimitry Andric // the buffer is not 4 bytes long, let the higher level logic figure out
12997a7e6055SDimitry Andric // what to do with a size of zero and MCDisassembler::Fail.
130039d628a0SDimitry Andric Result = readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, false);
13017a7e6055SDimitry Andric if (Result == MCDisassembler::Fail)
130239d628a0SDimitry Andric return MCDisassembler::Fail;
13037a7e6055SDimitry Andric
13047a7e6055SDimitry Andric // The only instruction size for standard encoded MIPS.
13057a7e6055SDimitry Andric Size = 4;
130639d628a0SDimitry Andric
130791bc56edSDimitry Andric if (hasCOP3()) {
13084ba319b5SDimitry Andric LLVM_DEBUG(dbgs() << "Trying COP3_ table (32-bit opcodes):\n");
130991bc56edSDimitry Andric Result =
131039d628a0SDimitry Andric decodeInstruction(DecoderTableCOP3_32, Instr, Insn, Address, this, STI);
13117a7e6055SDimitry Andric if (Result != MCDisassembler::Fail)
131291bc56edSDimitry Andric return Result;
131391bc56edSDimitry Andric }
131491bc56edSDimitry Andric
131591bc56edSDimitry Andric if (hasMips32r6() && isGP64()) {
13164ba319b5SDimitry Andric LLVM_DEBUG(
13174ba319b5SDimitry Andric dbgs() << "Trying Mips32r6_64r6 (GPR64) table (32-bit opcodes):\n");
131839d628a0SDimitry Andric Result = decodeInstruction(DecoderTableMips32r6_64r6_GP6432, Instr, Insn,
131991bc56edSDimitry Andric Address, this, STI);
13207a7e6055SDimitry Andric if (Result != MCDisassembler::Fail)
132191bc56edSDimitry Andric return Result;
132291bc56edSDimitry Andric }
132391bc56edSDimitry Andric
13243ca95b02SDimitry Andric if (hasMips32r6() && isPTR64()) {
13254ba319b5SDimitry Andric LLVM_DEBUG(
13264ba319b5SDimitry Andric dbgs() << "Trying Mips32r6_64r6 (PTR64) table (32-bit opcodes):\n");
13273ca95b02SDimitry Andric Result = decodeInstruction(DecoderTableMips32r6_64r6_PTR6432, Instr, Insn,
13283ca95b02SDimitry Andric Address, this, STI);
13297a7e6055SDimitry Andric if (Result != MCDisassembler::Fail)
13303ca95b02SDimitry Andric return Result;
13313ca95b02SDimitry Andric }
13323ca95b02SDimitry Andric
133391bc56edSDimitry Andric if (hasMips32r6()) {
13344ba319b5SDimitry Andric LLVM_DEBUG(dbgs() << "Trying Mips32r6_64r6 table (32-bit opcodes):\n");
133539d628a0SDimitry Andric Result = decodeInstruction(DecoderTableMips32r6_64r632, Instr, Insn,
133691bc56edSDimitry Andric Address, this, STI);
13377a7e6055SDimitry Andric if (Result != MCDisassembler::Fail)
133891bc56edSDimitry Andric return Result;
133991bc56edSDimitry Andric }
134091bc56edSDimitry Andric
13413ca95b02SDimitry Andric if (hasMips2() && isPTR64()) {
13424ba319b5SDimitry Andric LLVM_DEBUG(
13434ba319b5SDimitry Andric dbgs() << "Trying Mips32r6_64r6 (PTR64) table (32-bit opcodes):\n");
13443ca95b02SDimitry Andric Result = decodeInstruction(DecoderTableMips32_64_PTR6432, Instr, Insn,
13453ca95b02SDimitry Andric Address, this, STI);
13467a7e6055SDimitry Andric if (Result != MCDisassembler::Fail)
13473ca95b02SDimitry Andric return Result;
13483ca95b02SDimitry Andric }
13493ca95b02SDimitry Andric
135097bc6c73SDimitry Andric if (hasCnMips()) {
13514ba319b5SDimitry Andric LLVM_DEBUG(dbgs() << "Trying CnMips table (32-bit opcodes):\n");
135297bc6c73SDimitry Andric Result = decodeInstruction(DecoderTableCnMips32, Instr, Insn,
135397bc6c73SDimitry Andric Address, this, STI);
13547a7e6055SDimitry Andric if (Result != MCDisassembler::Fail)
135597bc6c73SDimitry Andric return Result;
135697bc6c73SDimitry Andric }
135797bc6c73SDimitry Andric
1358ff0cc061SDimitry Andric if (isGP64()) {
13594ba319b5SDimitry Andric LLVM_DEBUG(dbgs() << "Trying Mips64 (GPR64) table (32-bit opcodes):\n");
1360ff0cc061SDimitry Andric Result = decodeInstruction(DecoderTableMips6432, Instr, Insn,
1361ff0cc061SDimitry Andric Address, this, STI);
13627a7e6055SDimitry Andric if (Result != MCDisassembler::Fail)
1363ff0cc061SDimitry Andric return Result;
1364ff0cc061SDimitry Andric }
1365ff0cc061SDimitry Andric
13662cab237bSDimitry Andric if (isFP64()) {
13674ba319b5SDimitry Andric LLVM_DEBUG(
13684ba319b5SDimitry Andric dbgs() << "Trying MipsFP64 (64 bit FPU) table (32-bit opcodes):\n");
13692cab237bSDimitry Andric Result = decodeInstruction(DecoderTableMipsFP6432, Instr, Insn,
13702cab237bSDimitry Andric Address, this, STI);
13712cab237bSDimitry Andric if (Result != MCDisassembler::Fail)
13722cab237bSDimitry Andric return Result;
13732cab237bSDimitry Andric }
13742cab237bSDimitry Andric
13754ba319b5SDimitry Andric LLVM_DEBUG(dbgs() << "Trying Mips table (32-bit opcodes):\n");
1376cb4dff85SDimitry Andric // Calling the auto-generated decoder function.
137739d628a0SDimitry Andric Result =
137839d628a0SDimitry Andric decodeInstruction(DecoderTableMips32, Instr, Insn, Address, this, STI);
13797a7e6055SDimitry Andric if (Result != MCDisassembler::Fail)
1380cb4dff85SDimitry Andric return Result;
1381cb4dff85SDimitry Andric
1382cb4dff85SDimitry Andric return MCDisassembler::Fail;
1383cb4dff85SDimitry Andric }
1384cb4dff85SDimitry Andric
DecodeCPU16RegsRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)1385139f7f9bSDimitry Andric static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst,
1386139f7f9bSDimitry Andric unsigned RegNo,
1387139f7f9bSDimitry Andric uint64_t Address,
1388139f7f9bSDimitry Andric const void *Decoder) {
1389139f7f9bSDimitry Andric return MCDisassembler::Fail;
1390139f7f9bSDimitry Andric }
1391139f7f9bSDimitry Andric
DecodeGPR64RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)1392f785676fSDimitry Andric static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst,
1393cb4dff85SDimitry Andric unsigned RegNo,
1394cb4dff85SDimitry Andric uint64_t Address,
1395cb4dff85SDimitry Andric const void *Decoder) {
1396cb4dff85SDimitry Andric if (RegNo > 31)
1397cb4dff85SDimitry Andric return MCDisassembler::Fail;
1398cb4dff85SDimitry Andric
1399f785676fSDimitry Andric unsigned Reg = getReg(Decoder, Mips::GPR64RegClassID, RegNo);
1400ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createReg(Reg));
1401cb4dff85SDimitry Andric return MCDisassembler::Success;
1402cb4dff85SDimitry Andric }
1403cb4dff85SDimitry Andric
DecodeGPRMM16RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)140439d628a0SDimitry Andric static DecodeStatus DecodeGPRMM16RegisterClass(MCInst &Inst,
140539d628a0SDimitry Andric unsigned RegNo,
140639d628a0SDimitry Andric uint64_t Address,
140739d628a0SDimitry Andric const void *Decoder) {
140839d628a0SDimitry Andric if (RegNo > 7)
140939d628a0SDimitry Andric return MCDisassembler::Fail;
141039d628a0SDimitry Andric unsigned Reg = getReg(Decoder, Mips::GPRMM16RegClassID, RegNo);
1411ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createReg(Reg));
141239d628a0SDimitry Andric return MCDisassembler::Success;
141339d628a0SDimitry Andric }
141439d628a0SDimitry Andric
DecodeGPRMM16ZeroRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)141539d628a0SDimitry Andric static DecodeStatus DecodeGPRMM16ZeroRegisterClass(MCInst &Inst,
141639d628a0SDimitry Andric unsigned RegNo,
141739d628a0SDimitry Andric uint64_t Address,
141839d628a0SDimitry Andric const void *Decoder) {
141939d628a0SDimitry Andric if (RegNo > 7)
142039d628a0SDimitry Andric return MCDisassembler::Fail;
142139d628a0SDimitry Andric unsigned Reg = getReg(Decoder, Mips::GPRMM16ZeroRegClassID, RegNo);
1422ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createReg(Reg));
1423ff0cc061SDimitry Andric return MCDisassembler::Success;
1424ff0cc061SDimitry Andric }
1425ff0cc061SDimitry Andric
DecodeGPRMM16MovePRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)1426ff0cc061SDimitry Andric static DecodeStatus DecodeGPRMM16MovePRegisterClass(MCInst &Inst,
1427ff0cc061SDimitry Andric unsigned RegNo,
1428ff0cc061SDimitry Andric uint64_t Address,
1429ff0cc061SDimitry Andric const void *Decoder) {
1430ff0cc061SDimitry Andric if (RegNo > 7)
1431ff0cc061SDimitry Andric return MCDisassembler::Fail;
1432ff0cc061SDimitry Andric unsigned Reg = getReg(Decoder, Mips::GPRMM16MovePRegClassID, RegNo);
1433ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createReg(Reg));
143439d628a0SDimitry Andric return MCDisassembler::Success;
143539d628a0SDimitry Andric }
143639d628a0SDimitry Andric
DecodeGPR32RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)1437f785676fSDimitry Andric static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst,
1438cb4dff85SDimitry Andric unsigned RegNo,
1439cb4dff85SDimitry Andric uint64_t Address,
1440cb4dff85SDimitry Andric const void *Decoder) {
1441cb4dff85SDimitry Andric if (RegNo > 31)
1442cb4dff85SDimitry Andric return MCDisassembler::Fail;
1443f785676fSDimitry Andric unsigned Reg = getReg(Decoder, Mips::GPR32RegClassID, RegNo);
1444ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createReg(Reg));
1445cb4dff85SDimitry Andric return MCDisassembler::Success;
1446cb4dff85SDimitry Andric }
1447cb4dff85SDimitry Andric
DecodePtrRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)1448f785676fSDimitry Andric static DecodeStatus DecodePtrRegisterClass(MCInst &Inst,
14493861d79fSDimitry Andric unsigned RegNo,
14503861d79fSDimitry Andric uint64_t Address,
14513861d79fSDimitry Andric const void *Decoder) {
1452ff0cc061SDimitry Andric if (static_cast<const MipsDisassembler *>(Decoder)->isGP64())
1453f785676fSDimitry Andric return DecodeGPR64RegisterClass(Inst, RegNo, Address, Decoder);
1454f785676fSDimitry Andric
1455f785676fSDimitry Andric return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
1456f785676fSDimitry Andric }
1457f785676fSDimitry Andric
DecodeDSPRRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)1458f785676fSDimitry Andric static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst,
1459f785676fSDimitry Andric unsigned RegNo,
1460f785676fSDimitry Andric uint64_t Address,
1461f785676fSDimitry Andric const void *Decoder) {
1462f785676fSDimitry Andric return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
14633861d79fSDimitry Andric }
14643861d79fSDimitry Andric
DecodeFGR64RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)1465cb4dff85SDimitry Andric static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
1466cb4dff85SDimitry Andric unsigned RegNo,
1467cb4dff85SDimitry Andric uint64_t Address,
1468cb4dff85SDimitry Andric const void *Decoder) {
1469cb4dff85SDimitry Andric if (RegNo > 31)
1470cb4dff85SDimitry Andric return MCDisassembler::Fail;
1471cb4dff85SDimitry Andric
14727ae0e2c9SDimitry Andric unsigned Reg = getReg(Decoder, Mips::FGR64RegClassID, RegNo);
1473ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createReg(Reg));
1474cb4dff85SDimitry Andric return MCDisassembler::Success;
1475cb4dff85SDimitry Andric }
1476cb4dff85SDimitry Andric
DecodeFGR32RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)1477cb4dff85SDimitry Andric static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
1478cb4dff85SDimitry Andric unsigned RegNo,
1479cb4dff85SDimitry Andric uint64_t Address,
1480cb4dff85SDimitry Andric const void *Decoder) {
1481cb4dff85SDimitry Andric if (RegNo > 31)
1482cb4dff85SDimitry Andric return MCDisassembler::Fail;
1483cb4dff85SDimitry Andric
14847ae0e2c9SDimitry Andric unsigned Reg = getReg(Decoder, Mips::FGR32RegClassID, RegNo);
1485ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createReg(Reg));
1486cb4dff85SDimitry Andric return MCDisassembler::Success;
1487cb4dff85SDimitry Andric }
1488cb4dff85SDimitry Andric
DecodeCCRRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)1489cb4dff85SDimitry Andric static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
1490cb4dff85SDimitry Andric unsigned RegNo,
1491cb4dff85SDimitry Andric uint64_t Address,
1492cb4dff85SDimitry Andric const void *Decoder) {
1493f785676fSDimitry Andric if (RegNo > 31)
1494f785676fSDimitry Andric return MCDisassembler::Fail;
1495f785676fSDimitry Andric unsigned Reg = getReg(Decoder, Mips::CCRRegClassID, RegNo);
1496ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createReg(Reg));
1497f785676fSDimitry Andric return MCDisassembler::Success;
1498f785676fSDimitry Andric }
1499f785676fSDimitry Andric
DecodeFCCRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)1500f785676fSDimitry Andric static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst,
1501f785676fSDimitry Andric unsigned RegNo,
1502f785676fSDimitry Andric uint64_t Address,
1503f785676fSDimitry Andric const void *Decoder) {
1504f785676fSDimitry Andric if (RegNo > 7)
1505f785676fSDimitry Andric return MCDisassembler::Fail;
1506f785676fSDimitry Andric unsigned Reg = getReg(Decoder, Mips::FCCRegClassID, RegNo);
1507ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createReg(Reg));
1508cb4dff85SDimitry Andric return MCDisassembler::Success;
1509cb4dff85SDimitry Andric }
1510cb4dff85SDimitry Andric
DecodeFGRCCRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)151191bc56edSDimitry Andric static DecodeStatus DecodeFGRCCRegisterClass(MCInst &Inst, unsigned RegNo,
151291bc56edSDimitry Andric uint64_t Address,
151391bc56edSDimitry Andric const void *Decoder) {
151491bc56edSDimitry Andric if (RegNo > 31)
151591bc56edSDimitry Andric return MCDisassembler::Fail;
151691bc56edSDimitry Andric
151791bc56edSDimitry Andric unsigned Reg = getReg(Decoder, Mips::FGRCCRegClassID, RegNo);
1518ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createReg(Reg));
151991bc56edSDimitry Andric return MCDisassembler::Success;
152091bc56edSDimitry Andric }
152191bc56edSDimitry Andric
DecodeMem(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)1522cb4dff85SDimitry Andric static DecodeStatus DecodeMem(MCInst &Inst,
1523cb4dff85SDimitry Andric unsigned Insn,
1524cb4dff85SDimitry Andric uint64_t Address,
1525cb4dff85SDimitry Andric const void *Decoder) {
1526cb4dff85SDimitry Andric int Offset = SignExtend32<16>(Insn & 0xffff);
15277ae0e2c9SDimitry Andric unsigned Reg = fieldFromInstruction(Insn, 16, 5);
15287ae0e2c9SDimitry Andric unsigned Base = fieldFromInstruction(Insn, 21, 5);
15297ae0e2c9SDimitry Andric
1530f785676fSDimitry Andric Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1531f785676fSDimitry Andric Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1532cb4dff85SDimitry Andric
153339d628a0SDimitry Andric if (Inst.getOpcode() == Mips::SC ||
15347d523365SDimitry Andric Inst.getOpcode() == Mips::SCD)
1535ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createReg(Reg));
15367d523365SDimitry Andric
15377d523365SDimitry Andric Inst.addOperand(MCOperand::createReg(Reg));
15387d523365SDimitry Andric Inst.addOperand(MCOperand::createReg(Base));
15397d523365SDimitry Andric Inst.addOperand(MCOperand::createImm(Offset));
15407d523365SDimitry Andric
15417d523365SDimitry Andric return MCDisassembler::Success;
1542cb4dff85SDimitry Andric }
1543cb4dff85SDimitry Andric
DecodeMemEVA(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)15447d523365SDimitry Andric static DecodeStatus DecodeMemEVA(MCInst &Inst,
15457d523365SDimitry Andric unsigned Insn,
15467d523365SDimitry Andric uint64_t Address,
15477d523365SDimitry Andric const void *Decoder) {
15487d523365SDimitry Andric int Offset = SignExtend32<9>(Insn >> 7);
15497d523365SDimitry Andric unsigned Reg = fieldFromInstruction(Insn, 16, 5);
15507d523365SDimitry Andric unsigned Base = fieldFromInstruction(Insn, 21, 5);
15517d523365SDimitry Andric
15527d523365SDimitry Andric Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
15537d523365SDimitry Andric Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
15547d523365SDimitry Andric
15557d523365SDimitry Andric if (Inst.getOpcode() == Mips::SCE)
15567d523365SDimitry Andric Inst.addOperand(MCOperand::createReg(Reg));
15577d523365SDimitry Andric
15587d523365SDimitry Andric Inst.addOperand(MCOperand::createReg(Reg));
15597d523365SDimitry Andric Inst.addOperand(MCOperand::createReg(Base));
15607d523365SDimitry Andric Inst.addOperand(MCOperand::createImm(Offset));
15617d523365SDimitry Andric
15627d523365SDimitry Andric return MCDisassembler::Success;
15637d523365SDimitry Andric }
15647d523365SDimitry Andric
DecodeLoadByte15(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)15657d523365SDimitry Andric static DecodeStatus DecodeLoadByte15(MCInst &Inst,
15667d523365SDimitry Andric unsigned Insn,
15677d523365SDimitry Andric uint64_t Address,
15687d523365SDimitry Andric const void *Decoder) {
15697d523365SDimitry Andric int Offset = SignExtend32<16>(Insn & 0xffff);
15707d523365SDimitry Andric unsigned Base = fieldFromInstruction(Insn, 16, 5);
15717d523365SDimitry Andric unsigned Reg = fieldFromInstruction(Insn, 21, 5);
15727d523365SDimitry Andric
15737d523365SDimitry Andric Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
15747d523365SDimitry Andric Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
15757d523365SDimitry Andric
1576ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createReg(Reg));
1577ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createReg(Base));
1578ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createImm(Offset));
1579cb4dff85SDimitry Andric
1580cb4dff85SDimitry Andric return MCDisassembler::Success;
1581cb4dff85SDimitry Andric }
1582cb4dff85SDimitry Andric
DecodeCacheOp(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)15839cac79b3SDimitry Andric static DecodeStatus DecodeCacheOp(MCInst &Inst,
15849cac79b3SDimitry Andric unsigned Insn,
15859cac79b3SDimitry Andric uint64_t Address,
15869cac79b3SDimitry Andric const void *Decoder) {
15879cac79b3SDimitry Andric int Offset = SignExtend32<16>(Insn & 0xffff);
15889cac79b3SDimitry Andric unsigned Hint = fieldFromInstruction(Insn, 16, 5);
15899cac79b3SDimitry Andric unsigned Base = fieldFromInstruction(Insn, 21, 5);
15909cac79b3SDimitry Andric
15919cac79b3SDimitry Andric Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
15929cac79b3SDimitry Andric
1593ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createReg(Base));
1594ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createImm(Offset));
1595ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createImm(Hint));
15969cac79b3SDimitry Andric
15979cac79b3SDimitry Andric return MCDisassembler::Success;
15989cac79b3SDimitry Andric }
15999cac79b3SDimitry Andric
DecodeCacheOpMM(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)160039d628a0SDimitry Andric static DecodeStatus DecodeCacheOpMM(MCInst &Inst,
160139d628a0SDimitry Andric unsigned Insn,
160239d628a0SDimitry Andric uint64_t Address,
160339d628a0SDimitry Andric const void *Decoder) {
160439d628a0SDimitry Andric int Offset = SignExtend32<12>(Insn & 0xfff);
160539d628a0SDimitry Andric unsigned Base = fieldFromInstruction(Insn, 16, 5);
160639d628a0SDimitry Andric unsigned Hint = fieldFromInstruction(Insn, 21, 5);
160739d628a0SDimitry Andric
160839d628a0SDimitry Andric Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
160939d628a0SDimitry Andric
1610ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createReg(Base));
1611ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createImm(Offset));
1612ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createImm(Hint));
161339d628a0SDimitry Andric
161439d628a0SDimitry Andric return MCDisassembler::Success;
161539d628a0SDimitry Andric }
161639d628a0SDimitry Andric
DecodePrefeOpMM(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)16177d523365SDimitry Andric static DecodeStatus DecodePrefeOpMM(MCInst &Inst,
1618ef6fa9e2SDimitry Andric unsigned Insn,
1619ef6fa9e2SDimitry Andric uint64_t Address,
1620ef6fa9e2SDimitry Andric const void *Decoder) {
16217d523365SDimitry Andric int Offset = SignExtend32<9>(Insn & 0x1ff);
16227d523365SDimitry Andric unsigned Base = fieldFromInstruction(Insn, 16, 5);
16237d523365SDimitry Andric unsigned Hint = fieldFromInstruction(Insn, 21, 5);
16247d523365SDimitry Andric
16257d523365SDimitry Andric Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
16267d523365SDimitry Andric
16277d523365SDimitry Andric Inst.addOperand(MCOperand::createReg(Base));
16287d523365SDimitry Andric Inst.addOperand(MCOperand::createImm(Offset));
16297d523365SDimitry Andric Inst.addOperand(MCOperand::createImm(Hint));
16307d523365SDimitry Andric
16317d523365SDimitry Andric return MCDisassembler::Success;
16327d523365SDimitry Andric }
16337d523365SDimitry Andric
DecodeCacheeOp_CacheOpR6(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)16347d523365SDimitry Andric static DecodeStatus DecodeCacheeOp_CacheOpR6(MCInst &Inst,
16357d523365SDimitry Andric unsigned Insn,
16367d523365SDimitry Andric uint64_t Address,
16377d523365SDimitry Andric const void *Decoder) {
16387d523365SDimitry Andric int Offset = SignExtend32<9>(Insn >> 7);
1639ef6fa9e2SDimitry Andric unsigned Hint = fieldFromInstruction(Insn, 16, 5);
1640ef6fa9e2SDimitry Andric unsigned Base = fieldFromInstruction(Insn, 21, 5);
1641ef6fa9e2SDimitry Andric
1642ef6fa9e2SDimitry Andric Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1643ef6fa9e2SDimitry Andric
1644ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createReg(Base));
1645ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createImm(Offset));
1646ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createImm(Hint));
1647ef6fa9e2SDimitry Andric
1648ef6fa9e2SDimitry Andric return MCDisassembler::Success;
1649ef6fa9e2SDimitry Andric }
1650ef6fa9e2SDimitry Andric
DecodeSyncI(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)165139d628a0SDimitry Andric static DecodeStatus DecodeSyncI(MCInst &Inst,
165239d628a0SDimitry Andric unsigned Insn,
165339d628a0SDimitry Andric uint64_t Address,
165439d628a0SDimitry Andric const void *Decoder) {
165539d628a0SDimitry Andric int Offset = SignExtend32<16>(Insn & 0xffff);
165639d628a0SDimitry Andric unsigned Base = fieldFromInstruction(Insn, 21, 5);
165739d628a0SDimitry Andric
165839d628a0SDimitry Andric Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
165939d628a0SDimitry Andric
1660ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createReg(Base));
1661ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createImm(Offset));
166239d628a0SDimitry Andric
166339d628a0SDimitry Andric return MCDisassembler::Success;
166439d628a0SDimitry Andric }
166539d628a0SDimitry Andric
DecodeSyncI_MM(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)16664ba319b5SDimitry Andric static DecodeStatus DecodeSyncI_MM(MCInst &Inst, unsigned Insn,
16674ba319b5SDimitry Andric uint64_t Address, const void *Decoder) {
16684ba319b5SDimitry Andric int Offset = SignExtend32<16>(Insn & 0xffff);
16694ba319b5SDimitry Andric unsigned Base = fieldFromInstruction(Insn, 16, 5);
16704ba319b5SDimitry Andric
16714ba319b5SDimitry Andric Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
16724ba319b5SDimitry Andric
16734ba319b5SDimitry Andric Inst.addOperand(MCOperand::createReg(Base));
16744ba319b5SDimitry Andric Inst.addOperand(MCOperand::createImm(Offset));
16754ba319b5SDimitry Andric
16764ba319b5SDimitry Andric return MCDisassembler::Success;
16774ba319b5SDimitry Andric }
16784ba319b5SDimitry Andric
DecodeSynciR6(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)16797d523365SDimitry Andric static DecodeStatus DecodeSynciR6(MCInst &Inst,
16807d523365SDimitry Andric unsigned Insn,
16817d523365SDimitry Andric uint64_t Address,
16827d523365SDimitry Andric const void *Decoder) {
16837d523365SDimitry Andric int Immediate = SignExtend32<16>(Insn & 0xffff);
16847d523365SDimitry Andric unsigned Base = fieldFromInstruction(Insn, 16, 5);
16857d523365SDimitry Andric
16867d523365SDimitry Andric Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
16877d523365SDimitry Andric
16887d523365SDimitry Andric Inst.addOperand(MCOperand::createReg(Base));
16897d523365SDimitry Andric Inst.addOperand(MCOperand::createImm(Immediate));
16907d523365SDimitry Andric
16917d523365SDimitry Andric return MCDisassembler::Success;
16927d523365SDimitry Andric }
16937d523365SDimitry Andric
DecodeMSA128Mem(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)1694f785676fSDimitry Andric static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn,
1695f785676fSDimitry Andric uint64_t Address, const void *Decoder) {
1696f785676fSDimitry Andric int Offset = SignExtend32<10>(fieldFromInstruction(Insn, 16, 10));
1697f785676fSDimitry Andric unsigned Reg = fieldFromInstruction(Insn, 6, 5);
1698f785676fSDimitry Andric unsigned Base = fieldFromInstruction(Insn, 11, 5);
1699f785676fSDimitry Andric
1700f785676fSDimitry Andric Reg = getReg(Decoder, Mips::MSA128BRegClassID, Reg);
1701f785676fSDimitry Andric Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1702f785676fSDimitry Andric
1703ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createReg(Reg));
1704ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createReg(Base));
170591bc56edSDimitry Andric
170691bc56edSDimitry Andric // The immediate field of an LD/ST instruction is scaled which means it must
170791bc56edSDimitry Andric // be multiplied (when decoding) by the size (in bytes) of the instructions'
170891bc56edSDimitry Andric // data format.
170991bc56edSDimitry Andric // .b - 1 byte
171091bc56edSDimitry Andric // .h - 2 bytes
171191bc56edSDimitry Andric // .w - 4 bytes
171291bc56edSDimitry Andric // .d - 8 bytes
171391bc56edSDimitry Andric switch(Inst.getOpcode())
171491bc56edSDimitry Andric {
171591bc56edSDimitry Andric default:
17167a7e6055SDimitry Andric assert(false && "Unexpected instruction");
171791bc56edSDimitry Andric return MCDisassembler::Fail;
171891bc56edSDimitry Andric break;
171991bc56edSDimitry Andric case Mips::LD_B:
172091bc56edSDimitry Andric case Mips::ST_B:
1721ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createImm(Offset));
172291bc56edSDimitry Andric break;
172391bc56edSDimitry Andric case Mips::LD_H:
172491bc56edSDimitry Andric case Mips::ST_H:
1725ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createImm(Offset * 2));
172691bc56edSDimitry Andric break;
172791bc56edSDimitry Andric case Mips::LD_W:
172891bc56edSDimitry Andric case Mips::ST_W:
1729ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createImm(Offset * 4));
173091bc56edSDimitry Andric break;
173191bc56edSDimitry Andric case Mips::LD_D:
173291bc56edSDimitry Andric case Mips::ST_D:
1733ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createImm(Offset * 8));
173491bc56edSDimitry Andric break;
173591bc56edSDimitry Andric }
1736f785676fSDimitry Andric
1737f785676fSDimitry Andric return MCDisassembler::Success;
1738f785676fSDimitry Andric }
1739f785676fSDimitry Andric
DecodeMemMMImm4(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)174039d628a0SDimitry Andric static DecodeStatus DecodeMemMMImm4(MCInst &Inst,
174139d628a0SDimitry Andric unsigned Insn,
174239d628a0SDimitry Andric uint64_t Address,
174339d628a0SDimitry Andric const void *Decoder) {
174439d628a0SDimitry Andric unsigned Offset = Insn & 0xf;
174539d628a0SDimitry Andric unsigned Reg = fieldFromInstruction(Insn, 7, 3);
174639d628a0SDimitry Andric unsigned Base = fieldFromInstruction(Insn, 4, 3);
174739d628a0SDimitry Andric
174839d628a0SDimitry Andric switch (Inst.getOpcode()) {
174939d628a0SDimitry Andric case Mips::LBU16_MM:
175039d628a0SDimitry Andric case Mips::LHU16_MM:
175139d628a0SDimitry Andric case Mips::LW16_MM:
175239d628a0SDimitry Andric if (DecodeGPRMM16RegisterClass(Inst, Reg, Address, Decoder)
175339d628a0SDimitry Andric == MCDisassembler::Fail)
175439d628a0SDimitry Andric return MCDisassembler::Fail;
175539d628a0SDimitry Andric break;
175639d628a0SDimitry Andric case Mips::SB16_MM:
17577d523365SDimitry Andric case Mips::SB16_MMR6:
175839d628a0SDimitry Andric case Mips::SH16_MM:
17597d523365SDimitry Andric case Mips::SH16_MMR6:
176039d628a0SDimitry Andric case Mips::SW16_MM:
17617d523365SDimitry Andric case Mips::SW16_MMR6:
176239d628a0SDimitry Andric if (DecodeGPRMM16ZeroRegisterClass(Inst, Reg, Address, Decoder)
176339d628a0SDimitry Andric == MCDisassembler::Fail)
176439d628a0SDimitry Andric return MCDisassembler::Fail;
176539d628a0SDimitry Andric break;
176639d628a0SDimitry Andric }
176739d628a0SDimitry Andric
176839d628a0SDimitry Andric if (DecodeGPRMM16RegisterClass(Inst, Base, Address, Decoder)
176939d628a0SDimitry Andric == MCDisassembler::Fail)
177039d628a0SDimitry Andric return MCDisassembler::Fail;
177139d628a0SDimitry Andric
177239d628a0SDimitry Andric switch (Inst.getOpcode()) {
177339d628a0SDimitry Andric case Mips::LBU16_MM:
177439d628a0SDimitry Andric if (Offset == 0xf)
1775ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createImm(-1));
177639d628a0SDimitry Andric else
1777ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createImm(Offset));
177839d628a0SDimitry Andric break;
177939d628a0SDimitry Andric case Mips::SB16_MM:
17807d523365SDimitry Andric case Mips::SB16_MMR6:
1781ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createImm(Offset));
178239d628a0SDimitry Andric break;
178339d628a0SDimitry Andric case Mips::LHU16_MM:
178439d628a0SDimitry Andric case Mips::SH16_MM:
17857d523365SDimitry Andric case Mips::SH16_MMR6:
1786ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createImm(Offset << 1));
178739d628a0SDimitry Andric break;
178839d628a0SDimitry Andric case Mips::LW16_MM:
178939d628a0SDimitry Andric case Mips::SW16_MM:
17907d523365SDimitry Andric case Mips::SW16_MMR6:
1791ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createImm(Offset << 2));
179239d628a0SDimitry Andric break;
179339d628a0SDimitry Andric }
179439d628a0SDimitry Andric
179539d628a0SDimitry Andric return MCDisassembler::Success;
179639d628a0SDimitry Andric }
179739d628a0SDimitry Andric
DecodeMemMMSPImm5Lsl2(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)179839d628a0SDimitry Andric static DecodeStatus DecodeMemMMSPImm5Lsl2(MCInst &Inst,
179939d628a0SDimitry Andric unsigned Insn,
180039d628a0SDimitry Andric uint64_t Address,
180139d628a0SDimitry Andric const void *Decoder) {
180239d628a0SDimitry Andric unsigned Offset = Insn & 0x1F;
180339d628a0SDimitry Andric unsigned Reg = fieldFromInstruction(Insn, 5, 5);
180439d628a0SDimitry Andric
180539d628a0SDimitry Andric Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
180639d628a0SDimitry Andric
1807ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createReg(Reg));
1808ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createReg(Mips::SP));
1809ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createImm(Offset << 2));
1810ff0cc061SDimitry Andric
1811ff0cc061SDimitry Andric return MCDisassembler::Success;
1812ff0cc061SDimitry Andric }
1813ff0cc061SDimitry Andric
DecodeMemMMGPImm7Lsl2(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)1814ff0cc061SDimitry Andric static DecodeStatus DecodeMemMMGPImm7Lsl2(MCInst &Inst,
1815ff0cc061SDimitry Andric unsigned Insn,
1816ff0cc061SDimitry Andric uint64_t Address,
1817ff0cc061SDimitry Andric const void *Decoder) {
1818ff0cc061SDimitry Andric unsigned Offset = Insn & 0x7F;
1819ff0cc061SDimitry Andric unsigned Reg = fieldFromInstruction(Insn, 7, 3);
1820ff0cc061SDimitry Andric
1821ff0cc061SDimitry Andric Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1822ff0cc061SDimitry Andric
1823ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createReg(Reg));
1824ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createReg(Mips::GP));
1825ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createImm(Offset << 2));
1826ff0cc061SDimitry Andric
1827ff0cc061SDimitry Andric return MCDisassembler::Success;
1828ff0cc061SDimitry Andric }
1829ff0cc061SDimitry Andric
DecodeMemMMReglistImm4Lsl2(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)1830ff0cc061SDimitry Andric static DecodeStatus DecodeMemMMReglistImm4Lsl2(MCInst &Inst,
1831ff0cc061SDimitry Andric unsigned Insn,
1832ff0cc061SDimitry Andric uint64_t Address,
1833ff0cc061SDimitry Andric const void *Decoder) {
18347d523365SDimitry Andric int Offset;
18357d523365SDimitry Andric switch (Inst.getOpcode()) {
18367d523365SDimitry Andric case Mips::LWM16_MMR6:
18377d523365SDimitry Andric case Mips::SWM16_MMR6:
18387d523365SDimitry Andric Offset = fieldFromInstruction(Insn, 4, 4);
18397d523365SDimitry Andric break;
18407d523365SDimitry Andric default:
18417d523365SDimitry Andric Offset = SignExtend32<4>(Insn & 0xf);
18427d523365SDimitry Andric break;
18437d523365SDimitry Andric }
1844ff0cc061SDimitry Andric
1845ff0cc061SDimitry Andric if (DecodeRegListOperand16(Inst, Insn, Address, Decoder)
1846ff0cc061SDimitry Andric == MCDisassembler::Fail)
1847ff0cc061SDimitry Andric return MCDisassembler::Fail;
1848ff0cc061SDimitry Andric
1849ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createReg(Mips::SP));
1850ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createImm(Offset << 2));
185139d628a0SDimitry Andric
185239d628a0SDimitry Andric return MCDisassembler::Success;
185339d628a0SDimitry Andric }
185439d628a0SDimitry Andric
DecodeMemMMImm9(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)18557d523365SDimitry Andric static DecodeStatus DecodeMemMMImm9(MCInst &Inst,
18567d523365SDimitry Andric unsigned Insn,
18577d523365SDimitry Andric uint64_t Address,
18587d523365SDimitry Andric const void *Decoder) {
18597d523365SDimitry Andric int Offset = SignExtend32<9>(Insn & 0x1ff);
18607d523365SDimitry Andric unsigned Reg = fieldFromInstruction(Insn, 21, 5);
18617d523365SDimitry Andric unsigned Base = fieldFromInstruction(Insn, 16, 5);
18627d523365SDimitry Andric
18637d523365SDimitry Andric Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
18647d523365SDimitry Andric Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
18657d523365SDimitry Andric
18664ba319b5SDimitry Andric if (Inst.getOpcode() == Mips::SCE_MM || Inst.getOpcode() == Mips::SC_MMR6)
18677d523365SDimitry Andric Inst.addOperand(MCOperand::createReg(Reg));
18687d523365SDimitry Andric
18697d523365SDimitry Andric Inst.addOperand(MCOperand::createReg(Reg));
18707d523365SDimitry Andric Inst.addOperand(MCOperand::createReg(Base));
18717d523365SDimitry Andric Inst.addOperand(MCOperand::createImm(Offset));
18727d523365SDimitry Andric
18737d523365SDimitry Andric return MCDisassembler::Success;
18747d523365SDimitry Andric }
18757d523365SDimitry Andric
DecodeMemMMImm12(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)1876f785676fSDimitry Andric static DecodeStatus DecodeMemMMImm12(MCInst &Inst,
1877f785676fSDimitry Andric unsigned Insn,
1878f785676fSDimitry Andric uint64_t Address,
1879f785676fSDimitry Andric const void *Decoder) {
1880f785676fSDimitry Andric int Offset = SignExtend32<12>(Insn & 0x0fff);
1881f785676fSDimitry Andric unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1882f785676fSDimitry Andric unsigned Base = fieldFromInstruction(Insn, 16, 5);
1883f785676fSDimitry Andric
1884f785676fSDimitry Andric Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1885f785676fSDimitry Andric Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1886f785676fSDimitry Andric
188739d628a0SDimitry Andric switch (Inst.getOpcode()) {
188839d628a0SDimitry Andric case Mips::SWM32_MM:
188939d628a0SDimitry Andric case Mips::LWM32_MM:
189039d628a0SDimitry Andric if (DecodeRegListOperand(Inst, Insn, Address, Decoder)
189139d628a0SDimitry Andric == MCDisassembler::Fail)
189239d628a0SDimitry Andric return MCDisassembler::Fail;
1893ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createReg(Base));
1894ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createImm(Offset));
189539d628a0SDimitry Andric break;
189639d628a0SDimitry Andric case Mips::SC_MM:
1897ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createReg(Reg));
1898d88c1a5aSDimitry Andric LLVM_FALLTHROUGH;
189939d628a0SDimitry Andric default:
1900ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createReg(Reg));
19014ba319b5SDimitry Andric if (Inst.getOpcode() == Mips::LWP_MM || Inst.getOpcode() == Mips::SWP_MM)
1902ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createReg(Reg+1));
190339d628a0SDimitry Andric
1904ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createReg(Base));
1905ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createImm(Offset));
190639d628a0SDimitry Andric }
1907f785676fSDimitry Andric
1908f785676fSDimitry Andric return MCDisassembler::Success;
1909f785676fSDimitry Andric }
1910f785676fSDimitry Andric
DecodeMemMMImm16(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)1911f785676fSDimitry Andric static DecodeStatus DecodeMemMMImm16(MCInst &Inst,
1912f785676fSDimitry Andric unsigned Insn,
1913f785676fSDimitry Andric uint64_t Address,
1914f785676fSDimitry Andric const void *Decoder) {
1915f785676fSDimitry Andric int Offset = SignExtend32<16>(Insn & 0xffff);
1916f785676fSDimitry Andric unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1917f785676fSDimitry Andric unsigned Base = fieldFromInstruction(Insn, 16, 5);
1918f785676fSDimitry Andric
1919f785676fSDimitry Andric Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1920f785676fSDimitry Andric Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1921f785676fSDimitry Andric
1922ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createReg(Reg));
1923ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createReg(Base));
1924ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createImm(Offset));
1925f785676fSDimitry Andric
1926f785676fSDimitry Andric return MCDisassembler::Success;
1927f785676fSDimitry Andric }
1928f785676fSDimitry Andric
DecodeFMem(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)1929cb4dff85SDimitry Andric static DecodeStatus DecodeFMem(MCInst &Inst,
1930cb4dff85SDimitry Andric unsigned Insn,
1931cb4dff85SDimitry Andric uint64_t Address,
1932cb4dff85SDimitry Andric const void *Decoder) {
1933cb4dff85SDimitry Andric int Offset = SignExtend32<16>(Insn & 0xffff);
19347ae0e2c9SDimitry Andric unsigned Reg = fieldFromInstruction(Insn, 16, 5);
19357ae0e2c9SDimitry Andric unsigned Base = fieldFromInstruction(Insn, 21, 5);
1936cb4dff85SDimitry Andric
19377ae0e2c9SDimitry Andric Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg);
1938f785676fSDimitry Andric Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
19397ae0e2c9SDimitry Andric
1940ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createReg(Reg));
1941ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createReg(Base));
1942ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createImm(Offset));
1943cb4dff85SDimitry Andric
1944cb4dff85SDimitry Andric return MCDisassembler::Success;
1945cb4dff85SDimitry Andric }
1946cb4dff85SDimitry Andric
DecodeFMemMMR2(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)19473ca95b02SDimitry Andric static DecodeStatus DecodeFMemMMR2(MCInst &Inst, unsigned Insn,
19483ca95b02SDimitry Andric uint64_t Address, const void *Decoder) {
19493ca95b02SDimitry Andric // This function is the same as DecodeFMem but with the Reg and Base fields
19503ca95b02SDimitry Andric // swapped according to microMIPS spec.
19513ca95b02SDimitry Andric int Offset = SignExtend32<16>(Insn & 0xffff);
19523ca95b02SDimitry Andric unsigned Base = fieldFromInstruction(Insn, 16, 5);
19533ca95b02SDimitry Andric unsigned Reg = fieldFromInstruction(Insn, 21, 5);
19543ca95b02SDimitry Andric
19553ca95b02SDimitry Andric Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg);
19563ca95b02SDimitry Andric Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
19573ca95b02SDimitry Andric
19583ca95b02SDimitry Andric Inst.addOperand(MCOperand::createReg(Reg));
19593ca95b02SDimitry Andric Inst.addOperand(MCOperand::createReg(Base));
19603ca95b02SDimitry Andric Inst.addOperand(MCOperand::createImm(Offset));
19613ca95b02SDimitry Andric
19623ca95b02SDimitry Andric return MCDisassembler::Success;
19633ca95b02SDimitry Andric }
19643ca95b02SDimitry Andric
DecodeFMem2(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)19659cac79b3SDimitry Andric static DecodeStatus DecodeFMem2(MCInst &Inst,
19669cac79b3SDimitry Andric unsigned Insn,
19679cac79b3SDimitry Andric uint64_t Address,
19689cac79b3SDimitry Andric const void *Decoder) {
19699cac79b3SDimitry Andric int Offset = SignExtend32<16>(Insn & 0xffff);
19709cac79b3SDimitry Andric unsigned Reg = fieldFromInstruction(Insn, 16, 5);
19719cac79b3SDimitry Andric unsigned Base = fieldFromInstruction(Insn, 21, 5);
19729cac79b3SDimitry Andric
19739cac79b3SDimitry Andric Reg = getReg(Decoder, Mips::COP2RegClassID, Reg);
19749cac79b3SDimitry Andric Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
19759cac79b3SDimitry Andric
1976ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createReg(Reg));
1977ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createReg(Base));
1978ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createImm(Offset));
19799cac79b3SDimitry Andric
19809cac79b3SDimitry Andric return MCDisassembler::Success;
19819cac79b3SDimitry Andric }
19829cac79b3SDimitry Andric
DecodeFMem3(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)19839cac79b3SDimitry Andric static DecodeStatus DecodeFMem3(MCInst &Inst,
19849cac79b3SDimitry Andric unsigned Insn,
19859cac79b3SDimitry Andric uint64_t Address,
19869cac79b3SDimitry Andric const void *Decoder) {
19879cac79b3SDimitry Andric int Offset = SignExtend32<16>(Insn & 0xffff);
19889cac79b3SDimitry Andric unsigned Reg = fieldFromInstruction(Insn, 16, 5);
19899cac79b3SDimitry Andric unsigned Base = fieldFromInstruction(Insn, 21, 5);
19909cac79b3SDimitry Andric
19919cac79b3SDimitry Andric Reg = getReg(Decoder, Mips::COP3RegClassID, Reg);
19929cac79b3SDimitry Andric Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
19939cac79b3SDimitry Andric
1994ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createReg(Reg));
1995ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createReg(Base));
1996ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createImm(Offset));
19979cac79b3SDimitry Andric
19989cac79b3SDimitry Andric return MCDisassembler::Success;
19999cac79b3SDimitry Andric }
20009cac79b3SDimitry Andric
DecodeFMemCop2R6(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)2001ef6fa9e2SDimitry Andric static DecodeStatus DecodeFMemCop2R6(MCInst &Inst,
2002ef6fa9e2SDimitry Andric unsigned Insn,
2003ef6fa9e2SDimitry Andric uint64_t Address,
2004ef6fa9e2SDimitry Andric const void *Decoder) {
2005ef6fa9e2SDimitry Andric int Offset = SignExtend32<11>(Insn & 0x07ff);
2006ef6fa9e2SDimitry Andric unsigned Reg = fieldFromInstruction(Insn, 16, 5);
2007ef6fa9e2SDimitry Andric unsigned Base = fieldFromInstruction(Insn, 11, 5);
2008ef6fa9e2SDimitry Andric
2009ef6fa9e2SDimitry Andric Reg = getReg(Decoder, Mips::COP2RegClassID, Reg);
2010ef6fa9e2SDimitry Andric Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
2011ef6fa9e2SDimitry Andric
2012ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createReg(Reg));
2013ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createReg(Base));
2014ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createImm(Offset));
2015ef6fa9e2SDimitry Andric
2016ef6fa9e2SDimitry Andric return MCDisassembler::Success;
2017ef6fa9e2SDimitry Andric }
20183ca95b02SDimitry Andric
DecodeFMemCop2MMR6(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)20193ca95b02SDimitry Andric static DecodeStatus DecodeFMemCop2MMR6(MCInst &Inst, unsigned Insn,
20203ca95b02SDimitry Andric uint64_t Address, const void *Decoder) {
20213ca95b02SDimitry Andric int Offset = SignExtend32<11>(Insn & 0x07ff);
20223ca95b02SDimitry Andric unsigned Reg = fieldFromInstruction(Insn, 21, 5);
20233ca95b02SDimitry Andric unsigned Base = fieldFromInstruction(Insn, 16, 5);
20243ca95b02SDimitry Andric
20253ca95b02SDimitry Andric Reg = getReg(Decoder, Mips::COP2RegClassID, Reg);
20263ca95b02SDimitry Andric Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
20273ca95b02SDimitry Andric
20283ca95b02SDimitry Andric Inst.addOperand(MCOperand::createReg(Reg));
20293ca95b02SDimitry Andric Inst.addOperand(MCOperand::createReg(Base));
20303ca95b02SDimitry Andric Inst.addOperand(MCOperand::createImm(Offset));
20313ca95b02SDimitry Andric
20323ca95b02SDimitry Andric return MCDisassembler::Success;
20333ca95b02SDimitry Andric }
20343ca95b02SDimitry Andric
DecodeSpecial3LlSc(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)203591bc56edSDimitry Andric static DecodeStatus DecodeSpecial3LlSc(MCInst &Inst,
203691bc56edSDimitry Andric unsigned Insn,
203791bc56edSDimitry Andric uint64_t Address,
203891bc56edSDimitry Andric const void *Decoder) {
203991bc56edSDimitry Andric int64_t Offset = SignExtend64<9>((Insn >> 7) & 0x1ff);
204091bc56edSDimitry Andric unsigned Rt = fieldFromInstruction(Insn, 16, 5);
204191bc56edSDimitry Andric unsigned Base = fieldFromInstruction(Insn, 21, 5);
204291bc56edSDimitry Andric
204391bc56edSDimitry Andric Rt = getReg(Decoder, Mips::GPR32RegClassID, Rt);
204491bc56edSDimitry Andric Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
204591bc56edSDimitry Andric
204691bc56edSDimitry Andric if(Inst.getOpcode() == Mips::SC_R6 || Inst.getOpcode() == Mips::SCD_R6){
2047ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createReg(Rt));
204891bc56edSDimitry Andric }
204991bc56edSDimitry Andric
2050ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createReg(Rt));
2051ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createReg(Base));
2052ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createImm(Offset));
205391bc56edSDimitry Andric
205491bc56edSDimitry Andric return MCDisassembler::Success;
205591bc56edSDimitry Andric }
2056cb4dff85SDimitry Andric
DecodeHWRegsRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)2057cb4dff85SDimitry Andric static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
2058cb4dff85SDimitry Andric unsigned RegNo,
2059cb4dff85SDimitry Andric uint64_t Address,
2060cb4dff85SDimitry Andric const void *Decoder) {
2061cb4dff85SDimitry Andric // Currently only hardware register 29 is supported.
2062cb4dff85SDimitry Andric if (RegNo != 29)
2063cb4dff85SDimitry Andric return MCDisassembler::Fail;
2064ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createReg(Mips::HWR29));
2065cb4dff85SDimitry Andric return MCDisassembler::Success;
2066cb4dff85SDimitry Andric }
2067cb4dff85SDimitry Andric
DecodeAFGR64RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)2068cb4dff85SDimitry Andric static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
2069cb4dff85SDimitry Andric unsigned RegNo,
2070cb4dff85SDimitry Andric uint64_t Address,
2071cb4dff85SDimitry Andric const void *Decoder) {
20727ae0e2c9SDimitry Andric if (RegNo > 30 || RegNo %2)
2073cb4dff85SDimitry Andric return MCDisassembler::Fail;
2074cb4dff85SDimitry Andric
20757ae0e2c9SDimitry Andric unsigned Reg = getReg(Decoder, Mips::AFGR64RegClassID, RegNo /2);
2076ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createReg(Reg));
2077cb4dff85SDimitry Andric return MCDisassembler::Success;
2078cb4dff85SDimitry Andric }
2079cb4dff85SDimitry Andric
DecodeACC64DSPRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)2080f785676fSDimitry Andric static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst,
20813861d79fSDimitry Andric unsigned RegNo,
20823861d79fSDimitry Andric uint64_t Address,
20833861d79fSDimitry Andric const void *Decoder) {
20843861d79fSDimitry Andric if (RegNo >= 4)
20853861d79fSDimitry Andric return MCDisassembler::Fail;
20863861d79fSDimitry Andric
2087f785676fSDimitry Andric unsigned Reg = getReg(Decoder, Mips::ACC64DSPRegClassID, RegNo);
2088ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createReg(Reg));
20893861d79fSDimitry Andric return MCDisassembler::Success;
20903861d79fSDimitry Andric }
20913861d79fSDimitry Andric
DecodeHI32DSPRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)2092f785676fSDimitry Andric static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst,
2093284c1978SDimitry Andric unsigned RegNo,
2094284c1978SDimitry Andric uint64_t Address,
2095284c1978SDimitry Andric const void *Decoder) {
2096284c1978SDimitry Andric if (RegNo >= 4)
2097284c1978SDimitry Andric return MCDisassembler::Fail;
2098284c1978SDimitry Andric
2099f785676fSDimitry Andric unsigned Reg = getReg(Decoder, Mips::HI32DSPRegClassID, RegNo);
2100ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createReg(Reg));
2101284c1978SDimitry Andric return MCDisassembler::Success;
2102284c1978SDimitry Andric }
2103284c1978SDimitry Andric
DecodeLO32DSPRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)2104f785676fSDimitry Andric static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst,
2105284c1978SDimitry Andric unsigned RegNo,
2106284c1978SDimitry Andric uint64_t Address,
2107284c1978SDimitry Andric const void *Decoder) {
2108284c1978SDimitry Andric if (RegNo >= 4)
2109284c1978SDimitry Andric return MCDisassembler::Fail;
2110284c1978SDimitry Andric
2111f785676fSDimitry Andric unsigned Reg = getReg(Decoder, Mips::LO32DSPRegClassID, RegNo);
2112ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createReg(Reg));
2113f785676fSDimitry Andric return MCDisassembler::Success;
2114f785676fSDimitry Andric }
2115f785676fSDimitry Andric
DecodeMSA128BRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)2116f785676fSDimitry Andric static DecodeStatus DecodeMSA128BRegisterClass(MCInst &Inst,
2117f785676fSDimitry Andric unsigned RegNo,
2118f785676fSDimitry Andric uint64_t Address,
2119f785676fSDimitry Andric const void *Decoder) {
2120f785676fSDimitry Andric if (RegNo > 31)
2121f785676fSDimitry Andric return MCDisassembler::Fail;
2122f785676fSDimitry Andric
2123f785676fSDimitry Andric unsigned Reg = getReg(Decoder, Mips::MSA128BRegClassID, RegNo);
2124ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createReg(Reg));
2125f785676fSDimitry Andric return MCDisassembler::Success;
2126f785676fSDimitry Andric }
2127f785676fSDimitry Andric
DecodeMSA128HRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)2128f785676fSDimitry Andric static DecodeStatus DecodeMSA128HRegisterClass(MCInst &Inst,
2129f785676fSDimitry Andric unsigned RegNo,
2130f785676fSDimitry Andric uint64_t Address,
2131f785676fSDimitry Andric const void *Decoder) {
2132f785676fSDimitry Andric if (RegNo > 31)
2133f785676fSDimitry Andric return MCDisassembler::Fail;
2134f785676fSDimitry Andric
2135f785676fSDimitry Andric unsigned Reg = getReg(Decoder, Mips::MSA128HRegClassID, RegNo);
2136ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createReg(Reg));
2137f785676fSDimitry Andric return MCDisassembler::Success;
2138f785676fSDimitry Andric }
2139f785676fSDimitry Andric
DecodeMSA128WRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)2140f785676fSDimitry Andric static DecodeStatus DecodeMSA128WRegisterClass(MCInst &Inst,
2141f785676fSDimitry Andric unsigned RegNo,
2142f785676fSDimitry Andric uint64_t Address,
2143f785676fSDimitry Andric const void *Decoder) {
2144f785676fSDimitry Andric if (RegNo > 31)
2145f785676fSDimitry Andric return MCDisassembler::Fail;
2146f785676fSDimitry Andric
2147f785676fSDimitry Andric unsigned Reg = getReg(Decoder, Mips::MSA128WRegClassID, RegNo);
2148ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createReg(Reg));
2149f785676fSDimitry Andric return MCDisassembler::Success;
2150f785676fSDimitry Andric }
2151f785676fSDimitry Andric
DecodeMSA128DRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)2152f785676fSDimitry Andric static DecodeStatus DecodeMSA128DRegisterClass(MCInst &Inst,
2153f785676fSDimitry Andric unsigned RegNo,
2154f785676fSDimitry Andric uint64_t Address,
2155f785676fSDimitry Andric const void *Decoder) {
2156f785676fSDimitry Andric if (RegNo > 31)
2157f785676fSDimitry Andric return MCDisassembler::Fail;
2158f785676fSDimitry Andric
2159f785676fSDimitry Andric unsigned Reg = getReg(Decoder, Mips::MSA128DRegClassID, RegNo);
2160ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createReg(Reg));
2161f785676fSDimitry Andric return MCDisassembler::Success;
2162f785676fSDimitry Andric }
2163f785676fSDimitry Andric
DecodeMSACtrlRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)2164f785676fSDimitry Andric static DecodeStatus DecodeMSACtrlRegisterClass(MCInst &Inst,
2165f785676fSDimitry Andric unsigned RegNo,
2166f785676fSDimitry Andric uint64_t Address,
2167f785676fSDimitry Andric const void *Decoder) {
2168f785676fSDimitry Andric if (RegNo > 7)
2169f785676fSDimitry Andric return MCDisassembler::Fail;
2170f785676fSDimitry Andric
2171f785676fSDimitry Andric unsigned Reg = getReg(Decoder, Mips::MSACtrlRegClassID, RegNo);
2172ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createReg(Reg));
2173284c1978SDimitry Andric return MCDisassembler::Success;
2174284c1978SDimitry Andric }
2175284c1978SDimitry Andric
DecodeCOP0RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)21763dac3a9bSDimitry Andric static DecodeStatus DecodeCOP0RegisterClass(MCInst &Inst,
21773dac3a9bSDimitry Andric unsigned RegNo,
21783dac3a9bSDimitry Andric uint64_t Address,
21793dac3a9bSDimitry Andric const void *Decoder) {
21803dac3a9bSDimitry Andric if (RegNo > 31)
21813dac3a9bSDimitry Andric return MCDisassembler::Fail;
21823dac3a9bSDimitry Andric
21833dac3a9bSDimitry Andric unsigned Reg = getReg(Decoder, Mips::COP0RegClassID, RegNo);
21843dac3a9bSDimitry Andric Inst.addOperand(MCOperand::createReg(Reg));
21853dac3a9bSDimitry Andric return MCDisassembler::Success;
21863dac3a9bSDimitry Andric }
21873dac3a9bSDimitry Andric
DecodeCOP2RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)218891bc56edSDimitry Andric static DecodeStatus DecodeCOP2RegisterClass(MCInst &Inst,
218991bc56edSDimitry Andric unsigned RegNo,
219091bc56edSDimitry Andric uint64_t Address,
219191bc56edSDimitry Andric const void *Decoder) {
219291bc56edSDimitry Andric if (RegNo > 31)
219391bc56edSDimitry Andric return MCDisassembler::Fail;
219491bc56edSDimitry Andric
219591bc56edSDimitry Andric unsigned Reg = getReg(Decoder, Mips::COP2RegClassID, RegNo);
2196ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createReg(Reg));
219791bc56edSDimitry Andric return MCDisassembler::Success;
219891bc56edSDimitry Andric }
219991bc56edSDimitry Andric
DecodeBranchTarget(MCInst & Inst,unsigned Offset,uint64_t Address,const void * Decoder)2200cb4dff85SDimitry Andric static DecodeStatus DecodeBranchTarget(MCInst &Inst,
2201cb4dff85SDimitry Andric unsigned Offset,
2202cb4dff85SDimitry Andric uint64_t Address,
2203cb4dff85SDimitry Andric const void *Decoder) {
22049cac79b3SDimitry Andric int32_t BranchOffset = (SignExtend32<16>(Offset) * 4) + 4;
2205ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createImm(BranchOffset));
2206cb4dff85SDimitry Andric return MCDisassembler::Success;
2207cb4dff85SDimitry Andric }
2208cb4dff85SDimitry Andric
DecodeBranchTarget1SImm16(MCInst & Inst,unsigned Offset,uint64_t Address,const void * Decoder)22093ca95b02SDimitry Andric static DecodeStatus DecodeBranchTarget1SImm16(MCInst &Inst,
22103ca95b02SDimitry Andric unsigned Offset,
22113ca95b02SDimitry Andric uint64_t Address,
22123ca95b02SDimitry Andric const void *Decoder) {
22133ca95b02SDimitry Andric int32_t BranchOffset = (SignExtend32<16>(Offset) * 2);
22143ca95b02SDimitry Andric Inst.addOperand(MCOperand::createImm(BranchOffset));
22153ca95b02SDimitry Andric return MCDisassembler::Success;
22163ca95b02SDimitry Andric }
22173ca95b02SDimitry Andric
DecodeJumpTarget(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)2218cb4dff85SDimitry Andric static DecodeStatus DecodeJumpTarget(MCInst &Inst,
2219cb4dff85SDimitry Andric unsigned Insn,
2220cb4dff85SDimitry Andric uint64_t Address,
2221cb4dff85SDimitry Andric const void *Decoder) {
22227ae0e2c9SDimitry Andric unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 2;
2223ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createImm(JumpOffset));
2224cb4dff85SDimitry Andric return MCDisassembler::Success;
2225cb4dff85SDimitry Andric }
2226cb4dff85SDimitry Andric
DecodeBranchTarget21(MCInst & Inst,unsigned Offset,uint64_t Address,const void * Decoder)222791bc56edSDimitry Andric static DecodeStatus DecodeBranchTarget21(MCInst &Inst,
222891bc56edSDimitry Andric unsigned Offset,
222991bc56edSDimitry Andric uint64_t Address,
223091bc56edSDimitry Andric const void *Decoder) {
22313ca95b02SDimitry Andric int32_t BranchOffset = SignExtend32<21>(Offset) * 4 + 4;
22323ca95b02SDimitry Andric
22333ca95b02SDimitry Andric Inst.addOperand(MCOperand::createImm(BranchOffset));
22343ca95b02SDimitry Andric return MCDisassembler::Success;
22353ca95b02SDimitry Andric }
22363ca95b02SDimitry Andric
DecodeBranchTarget21MM(MCInst & Inst,unsigned Offset,uint64_t Address,const void * Decoder)22373ca95b02SDimitry Andric static DecodeStatus DecodeBranchTarget21MM(MCInst &Inst,
22383ca95b02SDimitry Andric unsigned Offset,
22393ca95b02SDimitry Andric uint64_t Address,
22403ca95b02SDimitry Andric const void *Decoder) {
2241d88c1a5aSDimitry Andric int32_t BranchOffset = SignExtend32<21>(Offset) * 4 + 4;
224291bc56edSDimitry Andric
2243ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createImm(BranchOffset));
224491bc56edSDimitry Andric return MCDisassembler::Success;
224591bc56edSDimitry Andric }
224691bc56edSDimitry Andric
DecodeBranchTarget26(MCInst & Inst,unsigned Offset,uint64_t Address,const void * Decoder)224791bc56edSDimitry Andric static DecodeStatus DecodeBranchTarget26(MCInst &Inst,
224891bc56edSDimitry Andric unsigned Offset,
224991bc56edSDimitry Andric uint64_t Address,
225091bc56edSDimitry Andric const void *Decoder) {
22513ca95b02SDimitry Andric int32_t BranchOffset = SignExtend32<26>(Offset) * 4 + 4;
225291bc56edSDimitry Andric
2253ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createImm(BranchOffset));
225491bc56edSDimitry Andric return MCDisassembler::Success;
225591bc56edSDimitry Andric }
225691bc56edSDimitry Andric
DecodeBranchTarget7MM(MCInst & Inst,unsigned Offset,uint64_t Address,const void * Decoder)225739d628a0SDimitry Andric static DecodeStatus DecodeBranchTarget7MM(MCInst &Inst,
225839d628a0SDimitry Andric unsigned Offset,
225939d628a0SDimitry Andric uint64_t Address,
226039d628a0SDimitry Andric const void *Decoder) {
22612cab237bSDimitry Andric int32_t BranchOffset = SignExtend32<8>(Offset << 1);
2262ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createImm(BranchOffset));
2263ff0cc061SDimitry Andric return MCDisassembler::Success;
2264ff0cc061SDimitry Andric }
2265ff0cc061SDimitry Andric
DecodeBranchTarget10MM(MCInst & Inst,unsigned Offset,uint64_t Address,const void * Decoder)2266ff0cc061SDimitry Andric static DecodeStatus DecodeBranchTarget10MM(MCInst &Inst,
2267ff0cc061SDimitry Andric unsigned Offset,
2268ff0cc061SDimitry Andric uint64_t Address,
2269ff0cc061SDimitry Andric const void *Decoder) {
22702cab237bSDimitry Andric int32_t BranchOffset = SignExtend32<11>(Offset << 1);
2271ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createImm(BranchOffset));
227239d628a0SDimitry Andric return MCDisassembler::Success;
227339d628a0SDimitry Andric }
227439d628a0SDimitry Andric
DecodeBranchTargetMM(MCInst & Inst,unsigned Offset,uint64_t Address,const void * Decoder)2275f785676fSDimitry Andric static DecodeStatus DecodeBranchTargetMM(MCInst &Inst,
2276f785676fSDimitry Andric unsigned Offset,
2277f785676fSDimitry Andric uint64_t Address,
2278f785676fSDimitry Andric const void *Decoder) {
2279d88c1a5aSDimitry Andric int32_t BranchOffset = SignExtend32<16>(Offset) * 2 + 4;
2280ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createImm(BranchOffset));
2281f785676fSDimitry Andric return MCDisassembler::Success;
2282f785676fSDimitry Andric }
2283f785676fSDimitry Andric
DecodeBranchTarget26MM(MCInst & Inst,unsigned Offset,uint64_t Address,const void * Decoder)22847d523365SDimitry Andric static DecodeStatus DecodeBranchTarget26MM(MCInst &Inst,
22857d523365SDimitry Andric unsigned Offset,
22867d523365SDimitry Andric uint64_t Address,
22877d523365SDimitry Andric const void *Decoder) {
22882cab237bSDimitry Andric int32_t BranchOffset = SignExtend32<27>(Offset << 1);
22897d523365SDimitry Andric
22907d523365SDimitry Andric Inst.addOperand(MCOperand::createImm(BranchOffset));
22917d523365SDimitry Andric return MCDisassembler::Success;
22927d523365SDimitry Andric }
22937d523365SDimitry Andric
DecodeJumpTargetMM(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)2294f785676fSDimitry Andric static DecodeStatus DecodeJumpTargetMM(MCInst &Inst,
2295f785676fSDimitry Andric unsigned Insn,
2296f785676fSDimitry Andric uint64_t Address,
2297f785676fSDimitry Andric const void *Decoder) {
2298f785676fSDimitry Andric unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 1;
2299ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createImm(JumpOffset));
2300f785676fSDimitry Andric return MCDisassembler::Success;
2301f785676fSDimitry Andric }
2302cb4dff85SDimitry Andric
DecodeAddiur2Simm7(MCInst & Inst,unsigned Value,uint64_t Address,const void * Decoder)230339d628a0SDimitry Andric static DecodeStatus DecodeAddiur2Simm7(MCInst &Inst,
230439d628a0SDimitry Andric unsigned Value,
230539d628a0SDimitry Andric uint64_t Address,
230639d628a0SDimitry Andric const void *Decoder) {
230739d628a0SDimitry Andric if (Value == 0)
2308ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createImm(1));
230939d628a0SDimitry Andric else if (Value == 0x7)
2310ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createImm(-1));
231139d628a0SDimitry Andric else
2312ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createImm(Value << 2));
231339d628a0SDimitry Andric return MCDisassembler::Success;
231439d628a0SDimitry Andric }
231539d628a0SDimitry Andric
DecodeLi16Imm(MCInst & Inst,unsigned Value,uint64_t Address,const void * Decoder)23163ca95b02SDimitry Andric static DecodeStatus DecodeLi16Imm(MCInst &Inst,
231739d628a0SDimitry Andric unsigned Value,
231839d628a0SDimitry Andric uint64_t Address,
231939d628a0SDimitry Andric const void *Decoder) {
232039d628a0SDimitry Andric if (Value == 0x7F)
2321ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createImm(-1));
232239d628a0SDimitry Andric else
2323ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createImm(Value));
232439d628a0SDimitry Andric return MCDisassembler::Success;
232539d628a0SDimitry Andric }
232639d628a0SDimitry Andric
DecodePOOL16BEncodedField(MCInst & Inst,unsigned Value,uint64_t Address,const void * Decoder)23277d523365SDimitry Andric static DecodeStatus DecodePOOL16BEncodedField(MCInst &Inst,
23287d523365SDimitry Andric unsigned Value,
23297d523365SDimitry Andric uint64_t Address,
23307d523365SDimitry Andric const void *Decoder) {
23317d523365SDimitry Andric Inst.addOperand(MCOperand::createImm(Value == 0x0 ? 8 : Value));
23327d523365SDimitry Andric return MCDisassembler::Success;
23337d523365SDimitry Andric }
23347d523365SDimitry Andric
23353ca95b02SDimitry Andric template <unsigned Bits, int Offset, int Scale>
DecodeUImmWithOffsetAndScale(MCInst & Inst,unsigned Value,uint64_t Address,const void * Decoder)23363ca95b02SDimitry Andric static DecodeStatus DecodeUImmWithOffsetAndScale(MCInst &Inst, unsigned Value,
2337f785676fSDimitry Andric uint64_t Address,
2338f785676fSDimitry Andric const void *Decoder) {
23397d523365SDimitry Andric Value &= ((1 << Bits) - 1);
23403ca95b02SDimitry Andric Value *= Scale;
23417d523365SDimitry Andric Inst.addOperand(MCOperand::createImm(Value + Offset));
2342f785676fSDimitry Andric return MCDisassembler::Success;
2343f785676fSDimitry Andric }
2344f785676fSDimitry Andric
23453ca95b02SDimitry Andric template <unsigned Bits, int Offset, int ScaleBy>
DecodeSImmWithOffsetAndScale(MCInst & Inst,unsigned Value,uint64_t Address,const void * Decoder)23463ca95b02SDimitry Andric static DecodeStatus DecodeSImmWithOffsetAndScale(MCInst &Inst, unsigned Value,
23473ca95b02SDimitry Andric uint64_t Address,
23483ca95b02SDimitry Andric const void *Decoder) {
23493ca95b02SDimitry Andric int32_t Imm = SignExtend32<Bits>(Value) * ScaleBy;
23503ca95b02SDimitry Andric Inst.addOperand(MCOperand::createImm(Imm + Offset));
23513ca95b02SDimitry Andric return MCDisassembler::Success;
23523ca95b02SDimitry Andric }
23533ca95b02SDimitry Andric
DecodeInsSize(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)2354cb4dff85SDimitry Andric static DecodeStatus DecodeInsSize(MCInst &Inst,
2355cb4dff85SDimitry Andric unsigned Insn,
2356cb4dff85SDimitry Andric uint64_t Address,
2357cb4dff85SDimitry Andric const void *Decoder) {
2358cb4dff85SDimitry Andric // First we need to grab the pos(lsb) from MCInst.
23592cab237bSDimitry Andric // This function only handles the 32 bit variants of ins, as dins
23602cab237bSDimitry Andric // variants are handled differently.
2361cb4dff85SDimitry Andric int Pos = Inst.getOperand(2).getImm();
23622cab237bSDimitry Andric int Size = (int) Insn - Pos + 1;
2363ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createImm(SignExtend32<16>(Size)));
2364cb4dff85SDimitry Andric return MCDisassembler::Success;
2365cb4dff85SDimitry Andric }
2366cb4dff85SDimitry Andric
DecodeSimm19Lsl2(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)236791bc56edSDimitry Andric static DecodeStatus DecodeSimm19Lsl2(MCInst &Inst, unsigned Insn,
236891bc56edSDimitry Andric uint64_t Address, const void *Decoder) {
2369ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createImm(SignExtend32<19>(Insn) * 4));
237091bc56edSDimitry Andric return MCDisassembler::Success;
237191bc56edSDimitry Andric }
237291bc56edSDimitry Andric
DecodeSimm18Lsl3(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)237391bc56edSDimitry Andric static DecodeStatus DecodeSimm18Lsl3(MCInst &Inst, unsigned Insn,
237491bc56edSDimitry Andric uint64_t Address, const void *Decoder) {
2375ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createImm(SignExtend32<18>(Insn) * 8));
237691bc56edSDimitry Andric return MCDisassembler::Success;
237791bc56edSDimitry Andric }
237839d628a0SDimitry Andric
DecodeSimm9SP(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)237939d628a0SDimitry Andric static DecodeStatus DecodeSimm9SP(MCInst &Inst, unsigned Insn,
238039d628a0SDimitry Andric uint64_t Address, const void *Decoder) {
238139d628a0SDimitry Andric int32_t DecodedValue;
238239d628a0SDimitry Andric switch (Insn) {
238339d628a0SDimitry Andric case 0: DecodedValue = 256; break;
238439d628a0SDimitry Andric case 1: DecodedValue = 257; break;
238539d628a0SDimitry Andric case 510: DecodedValue = -258; break;
238639d628a0SDimitry Andric case 511: DecodedValue = -257; break;
238739d628a0SDimitry Andric default: DecodedValue = SignExtend32<9>(Insn); break;
238839d628a0SDimitry Andric }
2389ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createImm(DecodedValue * 4));
239039d628a0SDimitry Andric return MCDisassembler::Success;
239139d628a0SDimitry Andric }
239239d628a0SDimitry Andric
DecodeANDI16Imm(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)239339d628a0SDimitry Andric static DecodeStatus DecodeANDI16Imm(MCInst &Inst, unsigned Insn,
239439d628a0SDimitry Andric uint64_t Address, const void *Decoder) {
239539d628a0SDimitry Andric // Insn must be >= 0, since it is unsigned that condition is always true.
239639d628a0SDimitry Andric assert(Insn < 16);
239739d628a0SDimitry Andric int32_t DecodedValues[] = {128, 1, 2, 3, 4, 7, 8, 15, 16, 31, 32, 63, 64,
239839d628a0SDimitry Andric 255, 32768, 65535};
2399ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createImm(DecodedValues[Insn]));
240039d628a0SDimitry Andric return MCDisassembler::Success;
240139d628a0SDimitry Andric }
240239d628a0SDimitry Andric
DecodeRegListOperand(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)240339d628a0SDimitry Andric static DecodeStatus DecodeRegListOperand(MCInst &Inst,
240439d628a0SDimitry Andric unsigned Insn,
240539d628a0SDimitry Andric uint64_t Address,
240639d628a0SDimitry Andric const void *Decoder) {
240739d628a0SDimitry Andric unsigned Regs[] = {Mips::S0, Mips::S1, Mips::S2, Mips::S3, Mips::S4, Mips::S5,
24087d523365SDimitry Andric Mips::S6, Mips::S7, Mips::FP};
240939d628a0SDimitry Andric unsigned RegNum;
241039d628a0SDimitry Andric
241139d628a0SDimitry Andric unsigned RegLst = fieldFromInstruction(Insn, 21, 5);
24127d523365SDimitry Andric
241339d628a0SDimitry Andric // Empty register lists are not allowed.
241439d628a0SDimitry Andric if (RegLst == 0)
241539d628a0SDimitry Andric return MCDisassembler::Fail;
241639d628a0SDimitry Andric
241739d628a0SDimitry Andric RegNum = RegLst & 0xf;
24187d523365SDimitry Andric
24197d523365SDimitry Andric // RegLst values 10-15, and 26-31 are reserved.
24207d523365SDimitry Andric if (RegNum > 9)
24217d523365SDimitry Andric return MCDisassembler::Fail;
24227d523365SDimitry Andric
242339d628a0SDimitry Andric for (unsigned i = 0; i < RegNum; i++)
2424ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createReg(Regs[i]));
242539d628a0SDimitry Andric
242639d628a0SDimitry Andric if (RegLst & 0x10)
2427ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createReg(Mips::RA));
242839d628a0SDimitry Andric
242939d628a0SDimitry Andric return MCDisassembler::Success;
243039d628a0SDimitry Andric }
243139d628a0SDimitry Andric
DecodeRegListOperand16(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)243239d628a0SDimitry Andric static DecodeStatus DecodeRegListOperand16(MCInst &Inst, unsigned Insn,
243339d628a0SDimitry Andric uint64_t Address,
243439d628a0SDimitry Andric const void *Decoder) {
243539d628a0SDimitry Andric unsigned Regs[] = {Mips::S0, Mips::S1, Mips::S2, Mips::S3};
24367d523365SDimitry Andric unsigned RegLst;
24377d523365SDimitry Andric switch(Inst.getOpcode()) {
24387d523365SDimitry Andric default:
24397d523365SDimitry Andric RegLst = fieldFromInstruction(Insn, 4, 2);
24407d523365SDimitry Andric break;
24417d523365SDimitry Andric case Mips::LWM16_MMR6:
24427d523365SDimitry Andric case Mips::SWM16_MMR6:
24437d523365SDimitry Andric RegLst = fieldFromInstruction(Insn, 8, 2);
24447d523365SDimitry Andric break;
24457d523365SDimitry Andric }
2446ff0cc061SDimitry Andric unsigned RegNum = RegLst & 0x3;
2447ff0cc061SDimitry Andric
2448ff0cc061SDimitry Andric for (unsigned i = 0; i <= RegNum; i++)
2449ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createReg(Regs[i]));
2450ff0cc061SDimitry Andric
2451ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createReg(Mips::RA));
2452ff0cc061SDimitry Andric
2453ff0cc061SDimitry Andric return MCDisassembler::Success;
2454ff0cc061SDimitry Andric }
2455ff0cc061SDimitry Andric
DecodeMovePOperands(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)2456*b5893f02SDimitry Andric static DecodeStatus DecodeMovePOperands(MCInst &Inst, unsigned Insn,
2457*b5893f02SDimitry Andric uint64_t Address,
2458*b5893f02SDimitry Andric const void *Decoder) {
2459*b5893f02SDimitry Andric unsigned RegPair = fieldFromInstruction(Insn, 7, 3);
2460*b5893f02SDimitry Andric if (DecodeMovePRegPair(Inst, RegPair, Address, Decoder) ==
2461*b5893f02SDimitry Andric MCDisassembler::Fail)
2462*b5893f02SDimitry Andric return MCDisassembler::Fail;
2463*b5893f02SDimitry Andric
2464*b5893f02SDimitry Andric unsigned RegRs;
2465*b5893f02SDimitry Andric if (static_cast<const MipsDisassembler*>(Decoder)->hasMips32r6())
2466*b5893f02SDimitry Andric RegRs = fieldFromInstruction(Insn, 0, 2) |
2467*b5893f02SDimitry Andric (fieldFromInstruction(Insn, 3, 1) << 2);
2468*b5893f02SDimitry Andric else
2469*b5893f02SDimitry Andric RegRs = fieldFromInstruction(Insn, 1, 3);
2470*b5893f02SDimitry Andric if (DecodeGPRMM16MovePRegisterClass(Inst, RegRs, Address, Decoder) ==
2471*b5893f02SDimitry Andric MCDisassembler::Fail)
2472*b5893f02SDimitry Andric return MCDisassembler::Fail;
2473*b5893f02SDimitry Andric
2474*b5893f02SDimitry Andric unsigned RegRt = fieldFromInstruction(Insn, 4, 3);
2475*b5893f02SDimitry Andric if (DecodeGPRMM16MovePRegisterClass(Inst, RegRt, Address, Decoder) ==
2476*b5893f02SDimitry Andric MCDisassembler::Fail)
2477*b5893f02SDimitry Andric return MCDisassembler::Fail;
2478*b5893f02SDimitry Andric
2479*b5893f02SDimitry Andric return MCDisassembler::Success;
2480*b5893f02SDimitry Andric }
2481*b5893f02SDimitry Andric
DecodeMovePRegPair(MCInst & Inst,unsigned RegPair,uint64_t Address,const void * Decoder)24822cab237bSDimitry Andric static DecodeStatus DecodeMovePRegPair(MCInst &Inst, unsigned RegPair,
2483ff0cc061SDimitry Andric uint64_t Address, const void *Decoder) {
2484ff0cc061SDimitry Andric switch (RegPair) {
2485ff0cc061SDimitry Andric default:
248639d628a0SDimitry Andric return MCDisassembler::Fail;
2487ff0cc061SDimitry Andric case 0:
2488ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createReg(Mips::A1));
2489ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createReg(Mips::A2));
2490ff0cc061SDimitry Andric break;
2491ff0cc061SDimitry Andric case 1:
2492ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createReg(Mips::A1));
2493ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createReg(Mips::A3));
2494ff0cc061SDimitry Andric break;
2495ff0cc061SDimitry Andric case 2:
2496ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createReg(Mips::A2));
2497ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createReg(Mips::A3));
2498ff0cc061SDimitry Andric break;
2499ff0cc061SDimitry Andric case 3:
2500ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createReg(Mips::A0));
2501ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createReg(Mips::S5));
2502ff0cc061SDimitry Andric break;
2503ff0cc061SDimitry Andric case 4:
2504ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createReg(Mips::A0));
2505ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createReg(Mips::S6));
2506ff0cc061SDimitry Andric break;
2507ff0cc061SDimitry Andric case 5:
2508ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createReg(Mips::A0));
2509ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createReg(Mips::A1));
2510ff0cc061SDimitry Andric break;
2511ff0cc061SDimitry Andric case 6:
2512ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createReg(Mips::A0));
2513ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createReg(Mips::A2));
2514ff0cc061SDimitry Andric break;
2515ff0cc061SDimitry Andric case 7:
2516ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createReg(Mips::A0));
2517ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createReg(Mips::A3));
2518ff0cc061SDimitry Andric break;
2519ff0cc061SDimitry Andric }
252039d628a0SDimitry Andric
2521ff0cc061SDimitry Andric return MCDisassembler::Success;
2522ff0cc061SDimitry Andric }
252339d628a0SDimitry Andric
DecodeSimm23Lsl2(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)2524ff0cc061SDimitry Andric static DecodeStatus DecodeSimm23Lsl2(MCInst &Inst, unsigned Insn,
2525ff0cc061SDimitry Andric uint64_t Address, const void *Decoder) {
25263dac3a9bSDimitry Andric Inst.addOperand(MCOperand::createImm(SignExtend32<25>(Insn << 2)));
252739d628a0SDimitry Andric return MCDisassembler::Success;
252839d628a0SDimitry Andric }
25293ca95b02SDimitry Andric
25303ca95b02SDimitry Andric template <typename InsnType>
DecodeBgtzGroupBranchMMR6(MCInst & MI,InsnType insn,uint64_t Address,const void * Decoder)25313ca95b02SDimitry Andric static DecodeStatus DecodeBgtzGroupBranchMMR6(MCInst &MI, InsnType insn,
25323ca95b02SDimitry Andric uint64_t Address,
25333ca95b02SDimitry Andric const void *Decoder) {
25343ca95b02SDimitry Andric // We have:
25353ca95b02SDimitry Andric // 0b000111 ttttt sssss iiiiiiiiiiiiiiii
25363ca95b02SDimitry Andric // Invalid if rt == 0
25373ca95b02SDimitry Andric // BGTZALC_MMR6 if rs == 0 && rt != 0
25383ca95b02SDimitry Andric // BLTZALC_MMR6 if rs != 0 && rs == rt
25393ca95b02SDimitry Andric // BLTUC_MMR6 if rs != 0 && rs != rt
25403ca95b02SDimitry Andric
25413ca95b02SDimitry Andric InsnType Rt = fieldFromInstruction(insn, 21, 5);
25423ca95b02SDimitry Andric InsnType Rs = fieldFromInstruction(insn, 16, 5);
2543d88c1a5aSDimitry Andric InsnType Imm = 0;
25443ca95b02SDimitry Andric bool HasRs = false;
25453ca95b02SDimitry Andric bool HasRt = false;
25463ca95b02SDimitry Andric
25473ca95b02SDimitry Andric if (Rt == 0)
25483ca95b02SDimitry Andric return MCDisassembler::Fail;
25493ca95b02SDimitry Andric else if (Rs == 0) {
25503ca95b02SDimitry Andric MI.setOpcode(Mips::BGTZALC_MMR6);
25513ca95b02SDimitry Andric HasRt = true;
2552d88c1a5aSDimitry Andric Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
25533ca95b02SDimitry Andric }
25543ca95b02SDimitry Andric else if (Rs == Rt) {
25553ca95b02SDimitry Andric MI.setOpcode(Mips::BLTZALC_MMR6);
25563ca95b02SDimitry Andric HasRs = true;
2557d88c1a5aSDimitry Andric Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
25583ca95b02SDimitry Andric }
25593ca95b02SDimitry Andric else {
25603ca95b02SDimitry Andric MI.setOpcode(Mips::BLTUC_MMR6);
25613ca95b02SDimitry Andric HasRs = true;
25623ca95b02SDimitry Andric HasRt = true;
2563d88c1a5aSDimitry Andric Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
25643ca95b02SDimitry Andric }
25653ca95b02SDimitry Andric
25663ca95b02SDimitry Andric if (HasRs)
25673ca95b02SDimitry Andric MI.addOperand(
25683ca95b02SDimitry Andric MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rs)));
25693ca95b02SDimitry Andric
25703ca95b02SDimitry Andric if (HasRt)
25713ca95b02SDimitry Andric MI.addOperand(
25723ca95b02SDimitry Andric MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rt)));
25733ca95b02SDimitry Andric
25743ca95b02SDimitry Andric MI.addOperand(MCOperand::createImm(Imm));
25753ca95b02SDimitry Andric
25763ca95b02SDimitry Andric return MCDisassembler::Success;
25773ca95b02SDimitry Andric }
25783ca95b02SDimitry Andric
25793ca95b02SDimitry Andric template <typename InsnType>
DecodeBlezGroupBranchMMR6(MCInst & MI,InsnType insn,uint64_t Address,const void * Decoder)25803ca95b02SDimitry Andric static DecodeStatus DecodeBlezGroupBranchMMR6(MCInst &MI, InsnType insn,
25813ca95b02SDimitry Andric uint64_t Address,
25823ca95b02SDimitry Andric const void *Decoder) {
25833ca95b02SDimitry Andric // We have:
25843ca95b02SDimitry Andric // 0b000110 ttttt sssss iiiiiiiiiiiiiiii
2585d88c1a5aSDimitry Andric // Invalid if rt == 0
25863ca95b02SDimitry Andric // BLEZALC_MMR6 if rs == 0 && rt != 0
25873ca95b02SDimitry Andric // BGEZALC_MMR6 if rs == rt && rt != 0
25883ca95b02SDimitry Andric // BGEUC_MMR6 if rs != rt && rs != 0 && rt != 0
25893ca95b02SDimitry Andric
25903ca95b02SDimitry Andric InsnType Rt = fieldFromInstruction(insn, 21, 5);
25913ca95b02SDimitry Andric InsnType Rs = fieldFromInstruction(insn, 16, 5);
2592d88c1a5aSDimitry Andric InsnType Imm = 0;
25933ca95b02SDimitry Andric bool HasRs = false;
25943ca95b02SDimitry Andric
25953ca95b02SDimitry Andric if (Rt == 0)
25963ca95b02SDimitry Andric return MCDisassembler::Fail;
2597d88c1a5aSDimitry Andric else if (Rs == 0) {
25983ca95b02SDimitry Andric MI.setOpcode(Mips::BLEZALC_MMR6);
2599d88c1a5aSDimitry Andric Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
2600d88c1a5aSDimitry Andric }
2601d88c1a5aSDimitry Andric else if (Rs == Rt) {
26023ca95b02SDimitry Andric MI.setOpcode(Mips::BGEZALC_MMR6);
2603d88c1a5aSDimitry Andric Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
2604d88c1a5aSDimitry Andric }
26053ca95b02SDimitry Andric else {
26063ca95b02SDimitry Andric HasRs = true;
26073ca95b02SDimitry Andric MI.setOpcode(Mips::BGEUC_MMR6);
2608d88c1a5aSDimitry Andric Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
26093ca95b02SDimitry Andric }
26103ca95b02SDimitry Andric
26113ca95b02SDimitry Andric if (HasRs)
26123ca95b02SDimitry Andric MI.addOperand(
26133ca95b02SDimitry Andric MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rs)));
26143ca95b02SDimitry Andric MI.addOperand(
26153ca95b02SDimitry Andric MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rt)));
26163ca95b02SDimitry Andric
26173ca95b02SDimitry Andric MI.addOperand(MCOperand::createImm(Imm));
26183ca95b02SDimitry Andric
26193ca95b02SDimitry Andric return MCDisassembler::Success;
26203ca95b02SDimitry Andric }
2621