109467b48Spatrick //===- MipsDisassembler.cpp - Disassembler for Mips -----------------------===//
209467b48Spatrick //
309467b48Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
409467b48Spatrick // See https://llvm.org/LICENSE.txt for license information.
509467b48Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
609467b48Spatrick //
709467b48Spatrick //===----------------------------------------------------------------------===//
809467b48Spatrick //
909467b48Spatrick // This file is part of the Mips Disassembler.
1009467b48Spatrick //
1109467b48Spatrick //===----------------------------------------------------------------------===//
1209467b48Spatrick
1309467b48Spatrick #include "MCTargetDesc/MipsMCTargetDesc.h"
1409467b48Spatrick #include "Mips.h"
1509467b48Spatrick #include "TargetInfo/MipsTargetInfo.h"
1609467b48Spatrick #include "llvm/ADT/ArrayRef.h"
1709467b48Spatrick #include "llvm/MC/MCContext.h"
18*d415bd75Srobert #include "llvm/MC/MCDecoderOps.h"
1909467b48Spatrick #include "llvm/MC/MCDisassembler/MCDisassembler.h"
2009467b48Spatrick #include "llvm/MC/MCInst.h"
2109467b48Spatrick #include "llvm/MC/MCRegisterInfo.h"
2209467b48Spatrick #include "llvm/MC/MCSubtargetInfo.h"
23*d415bd75Srobert #include "llvm/MC/TargetRegistry.h"
2409467b48Spatrick #include "llvm/Support/Compiler.h"
2509467b48Spatrick #include "llvm/Support/Debug.h"
2609467b48Spatrick #include "llvm/Support/ErrorHandling.h"
2709467b48Spatrick #include "llvm/Support/MathExtras.h"
2809467b48Spatrick #include "llvm/Support/raw_ostream.h"
2909467b48Spatrick #include <cassert>
3009467b48Spatrick #include <cstdint>
3109467b48Spatrick
3209467b48Spatrick using namespace llvm;
3309467b48Spatrick
3409467b48Spatrick #define DEBUG_TYPE "mips-disassembler"
3509467b48Spatrick
3609467b48Spatrick using DecodeStatus = MCDisassembler::DecodeStatus;
3709467b48Spatrick
3809467b48Spatrick namespace {
3909467b48Spatrick
4009467b48Spatrick class MipsDisassembler : public MCDisassembler {
4109467b48Spatrick bool IsMicroMips;
4209467b48Spatrick bool IsBigEndian;
4309467b48Spatrick
4409467b48Spatrick public:
MipsDisassembler(const MCSubtargetInfo & STI,MCContext & Ctx,bool IsBigEndian)4509467b48Spatrick MipsDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx, bool IsBigEndian)
4609467b48Spatrick : MCDisassembler(STI, Ctx),
4709467b48Spatrick IsMicroMips(STI.getFeatureBits()[Mips::FeatureMicroMips]),
4809467b48Spatrick IsBigEndian(IsBigEndian) {}
4909467b48Spatrick
hasMips2() const5009467b48Spatrick bool hasMips2() const { return STI.getFeatureBits()[Mips::FeatureMips2]; }
hasMips3() const5109467b48Spatrick bool hasMips3() const { return STI.getFeatureBits()[Mips::FeatureMips3]; }
hasMips32() const5209467b48Spatrick bool hasMips32() const { return STI.getFeatureBits()[Mips::FeatureMips32]; }
5309467b48Spatrick
hasMips32r6() const5409467b48Spatrick bool hasMips32r6() const {
5509467b48Spatrick return STI.getFeatureBits()[Mips::FeatureMips32r6];
5609467b48Spatrick }
5709467b48Spatrick
isFP64() const5809467b48Spatrick bool isFP64() const { return STI.getFeatureBits()[Mips::FeatureFP64Bit]; }
5909467b48Spatrick
isGP64() const6009467b48Spatrick bool isGP64() const { return STI.getFeatureBits()[Mips::FeatureGP64Bit]; }
6109467b48Spatrick
isPTR64() const6209467b48Spatrick bool isPTR64() const { return STI.getFeatureBits()[Mips::FeaturePTR64Bit]; }
6309467b48Spatrick
hasCnMips() const6409467b48Spatrick bool hasCnMips() const { return STI.getFeatureBits()[Mips::FeatureCnMips]; }
6509467b48Spatrick
hasCnMipsP() const6609467b48Spatrick bool hasCnMipsP() const { return STI.getFeatureBits()[Mips::FeatureCnMipsP]; }
6709467b48Spatrick
hasCOP3() const6809467b48Spatrick bool hasCOP3() const {
6909467b48Spatrick // Only present in MIPS-I and MIPS-II
7009467b48Spatrick return !hasMips32() && !hasMips3();
7109467b48Spatrick }
7209467b48Spatrick
7309467b48Spatrick DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
7409467b48Spatrick ArrayRef<uint8_t> Bytes, uint64_t Address,
7509467b48Spatrick raw_ostream &CStream) const override;
7609467b48Spatrick };
7709467b48Spatrick
7809467b48Spatrick } // end anonymous namespace
7909467b48Spatrick
8009467b48Spatrick // Forward declare these because the autogenerated code will reference them.
8109467b48Spatrick // Definitions are further down.
82*d415bd75Srobert static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst, unsigned RegNo,
8309467b48Spatrick uint64_t Address,
84*d415bd75Srobert const MCDisassembler *Decoder);
8509467b48Spatrick
86*d415bd75Srobert static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst, unsigned RegNo,
8709467b48Spatrick uint64_t Address,
88*d415bd75Srobert const MCDisassembler *Decoder);
8909467b48Spatrick
90*d415bd75Srobert static DecodeStatus DecodeGPRMM16RegisterClass(MCInst &Inst, unsigned RegNo,
9109467b48Spatrick uint64_t Address,
92*d415bd75Srobert const MCDisassembler *Decoder);
9309467b48Spatrick
94*d415bd75Srobert static DecodeStatus
95*d415bd75Srobert DecodeGPRMM16ZeroRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address,
96*d415bd75Srobert const MCDisassembler *Decoder);
9709467b48Spatrick
98*d415bd75Srobert static DecodeStatus
99*d415bd75Srobert DecodeGPRMM16MovePRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address,
100*d415bd75Srobert const MCDisassembler *Decoder);
10109467b48Spatrick
102*d415bd75Srobert static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst, unsigned RegNo,
10309467b48Spatrick uint64_t Address,
104*d415bd75Srobert const MCDisassembler *Decoder);
10509467b48Spatrick
106*d415bd75Srobert static DecodeStatus DecodePtrRegisterClass(MCInst &Inst, unsigned Insn,
10709467b48Spatrick uint64_t Address,
108*d415bd75Srobert const MCDisassembler *Decoder);
10909467b48Spatrick
110*d415bd75Srobert static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst, unsigned RegNo,
11109467b48Spatrick uint64_t Address,
112*d415bd75Srobert const MCDisassembler *Decoder);
11309467b48Spatrick
114*d415bd75Srobert static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst, unsigned RegNo,
11509467b48Spatrick uint64_t Address,
116*d415bd75Srobert const MCDisassembler *Decoder);
11709467b48Spatrick
118*d415bd75Srobert static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst, unsigned RegNo,
11909467b48Spatrick uint64_t Address,
120*d415bd75Srobert const MCDisassembler *Decoder);
12109467b48Spatrick
122*d415bd75Srobert static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst, unsigned RegNo,
12309467b48Spatrick uint64_t Address,
124*d415bd75Srobert const MCDisassembler *Decoder);
12509467b48Spatrick
126*d415bd75Srobert static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst, unsigned RegNo,
12709467b48Spatrick uint64_t Address,
128*d415bd75Srobert const MCDisassembler *Decoder);
12909467b48Spatrick
13009467b48Spatrick static DecodeStatus DecodeFGRCCRegisterClass(MCInst &Inst, unsigned RegNo,
13109467b48Spatrick uint64_t Address,
132*d415bd75Srobert const MCDisassembler *Decoder);
13309467b48Spatrick
134*d415bd75Srobert static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst, unsigned Insn,
13509467b48Spatrick uint64_t Address,
136*d415bd75Srobert const MCDisassembler *Decoder);
13709467b48Spatrick
138*d415bd75Srobert static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst, unsigned RegNo,
13909467b48Spatrick uint64_t Address,
140*d415bd75Srobert const MCDisassembler *Decoder);
14109467b48Spatrick
142*d415bd75Srobert static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst, unsigned RegNo,
14309467b48Spatrick uint64_t Address,
144*d415bd75Srobert const MCDisassembler *Decoder);
14509467b48Spatrick
146*d415bd75Srobert static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst, unsigned RegNo,
14709467b48Spatrick uint64_t Address,
148*d415bd75Srobert const MCDisassembler *Decoder);
14909467b48Spatrick
150*d415bd75Srobert static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst, unsigned RegNo,
15109467b48Spatrick uint64_t Address,
152*d415bd75Srobert const MCDisassembler *Decoder);
15309467b48Spatrick
154*d415bd75Srobert static DecodeStatus DecodeMSA128BRegisterClass(MCInst &Inst, unsigned RegNo,
15509467b48Spatrick uint64_t Address,
156*d415bd75Srobert const MCDisassembler *Decoder);
15709467b48Spatrick
158*d415bd75Srobert static DecodeStatus DecodeMSA128HRegisterClass(MCInst &Inst, unsigned RegNo,
15909467b48Spatrick uint64_t Address,
160*d415bd75Srobert const MCDisassembler *Decoder);
16109467b48Spatrick
162*d415bd75Srobert static DecodeStatus DecodeMSA128WRegisterClass(MCInst &Inst, unsigned RegNo,
16309467b48Spatrick uint64_t Address,
164*d415bd75Srobert const MCDisassembler *Decoder);
16509467b48Spatrick
166*d415bd75Srobert static DecodeStatus DecodeMSA128DRegisterClass(MCInst &Inst, unsigned RegNo,
16709467b48Spatrick uint64_t Address,
168*d415bd75Srobert const MCDisassembler *Decoder);
16909467b48Spatrick
170*d415bd75Srobert static DecodeStatus DecodeMSACtrlRegisterClass(MCInst &Inst, unsigned RegNo,
17109467b48Spatrick uint64_t Address,
172*d415bd75Srobert const MCDisassembler *Decoder);
17309467b48Spatrick
174*d415bd75Srobert static DecodeStatus DecodeCOP0RegisterClass(MCInst &Inst, unsigned RegNo,
17509467b48Spatrick uint64_t Address,
176*d415bd75Srobert const MCDisassembler *Decoder);
17709467b48Spatrick
178*d415bd75Srobert static DecodeStatus DecodeCOP2RegisterClass(MCInst &Inst, unsigned RegNo,
17909467b48Spatrick uint64_t Address,
180*d415bd75Srobert const MCDisassembler *Decoder);
18109467b48Spatrick
182*d415bd75Srobert static DecodeStatus DecodeBranchTarget(MCInst &Inst, unsigned Offset,
18309467b48Spatrick uint64_t Address,
184*d415bd75Srobert const MCDisassembler *Decoder);
18509467b48Spatrick
186*d415bd75Srobert static DecodeStatus DecodeBranchTarget1SImm16(MCInst &Inst, unsigned Offset,
18709467b48Spatrick uint64_t Address,
188*d415bd75Srobert const MCDisassembler *Decoder);
18909467b48Spatrick
190*d415bd75Srobert static DecodeStatus DecodeJumpTarget(MCInst &Inst, unsigned Insn,
19109467b48Spatrick uint64_t Address,
192*d415bd75Srobert const MCDisassembler *Decoder);
19309467b48Spatrick
194*d415bd75Srobert static DecodeStatus DecodeBranchTarget21(MCInst &Inst, unsigned Offset,
19509467b48Spatrick uint64_t Address,
196*d415bd75Srobert const MCDisassembler *Decoder);
19709467b48Spatrick
198*d415bd75Srobert static DecodeStatus DecodeBranchTarget21MM(MCInst &Inst, unsigned Offset,
19909467b48Spatrick uint64_t Address,
200*d415bd75Srobert const MCDisassembler *Decoder);
20109467b48Spatrick
202*d415bd75Srobert static DecodeStatus DecodeBranchTarget26(MCInst &Inst, unsigned Offset,
20309467b48Spatrick uint64_t Address,
204*d415bd75Srobert const MCDisassembler *Decoder);
20509467b48Spatrick
20609467b48Spatrick // DecodeBranchTarget7MM - Decode microMIPS branch offset, which is
20709467b48Spatrick // shifted left by 1 bit.
208*d415bd75Srobert static DecodeStatus DecodeBranchTarget7MM(MCInst &Inst, unsigned Offset,
20909467b48Spatrick uint64_t Address,
210*d415bd75Srobert const MCDisassembler *Decoder);
21109467b48Spatrick
21209467b48Spatrick // DecodeBranchTarget10MM - Decode microMIPS branch offset, which is
21309467b48Spatrick // shifted left by 1 bit.
214*d415bd75Srobert static DecodeStatus DecodeBranchTarget10MM(MCInst &Inst, unsigned Offset,
21509467b48Spatrick uint64_t Address,
216*d415bd75Srobert const MCDisassembler *Decoder);
21709467b48Spatrick
21809467b48Spatrick // DecodeBranchTargetMM - Decode microMIPS branch offset, which is
21909467b48Spatrick // shifted left by 1 bit.
220*d415bd75Srobert static DecodeStatus DecodeBranchTargetMM(MCInst &Inst, unsigned Offset,
22109467b48Spatrick uint64_t Address,
222*d415bd75Srobert const MCDisassembler *Decoder);
22309467b48Spatrick
22409467b48Spatrick // DecodeBranchTarget26MM - Decode microMIPS branch offset, which is
22509467b48Spatrick // shifted left by 1 bit.
226*d415bd75Srobert static DecodeStatus DecodeBranchTarget26MM(MCInst &Inst, unsigned Offset,
22709467b48Spatrick uint64_t Address,
228*d415bd75Srobert const MCDisassembler *Decoder);
22909467b48Spatrick
23009467b48Spatrick // DecodeJumpTargetMM - Decode microMIPS jump target, which is
23109467b48Spatrick // shifted left by 1 bit.
232*d415bd75Srobert static DecodeStatus DecodeJumpTargetMM(MCInst &Inst, unsigned Insn,
23309467b48Spatrick uint64_t Address,
234*d415bd75Srobert const MCDisassembler *Decoder);
23509467b48Spatrick
23609467b48Spatrick // DecodeJumpTargetXMM - Decode microMIPS jump and link exchange target,
23709467b48Spatrick // which is shifted left by 2 bit.
238*d415bd75Srobert static DecodeStatus DecodeJumpTargetXMM(MCInst &Inst, unsigned Insn,
23909467b48Spatrick uint64_t Address,
240*d415bd75Srobert const MCDisassembler *Decoder);
24109467b48Spatrick
242*d415bd75Srobert static DecodeStatus DecodeMem(MCInst &Inst, unsigned Insn, uint64_t Address,
243*d415bd75Srobert const MCDisassembler *Decoder);
24409467b48Spatrick
245*d415bd75Srobert static DecodeStatus DecodeMemEVA(MCInst &Inst, unsigned Insn, uint64_t Address,
246*d415bd75Srobert const MCDisassembler *Decoder);
24709467b48Spatrick
248*d415bd75Srobert static DecodeStatus DecodeLoadByte15(MCInst &Inst, unsigned Insn,
24909467b48Spatrick uint64_t Address,
250*d415bd75Srobert const MCDisassembler *Decoder);
25109467b48Spatrick
25209467b48Spatrick static DecodeStatus DecodeCacheOp(MCInst &Inst, unsigned Insn, uint64_t Address,
253*d415bd75Srobert const MCDisassembler *Decoder);
25409467b48Spatrick
255*d415bd75Srobert static DecodeStatus DecodeCacheeOp_CacheOpR6(MCInst &Inst, unsigned Insn,
25609467b48Spatrick uint64_t Address,
257*d415bd75Srobert const MCDisassembler *Decoder);
25809467b48Spatrick
259*d415bd75Srobert static DecodeStatus DecodeCacheOpMM(MCInst &Inst, unsigned Insn,
26009467b48Spatrick uint64_t Address,
261*d415bd75Srobert const MCDisassembler *Decoder);
26209467b48Spatrick
263*d415bd75Srobert static DecodeStatus DecodePrefeOpMM(MCInst &Inst, unsigned Insn,
26409467b48Spatrick uint64_t Address,
265*d415bd75Srobert const MCDisassembler *Decoder);
26609467b48Spatrick
267*d415bd75Srobert static DecodeStatus DecodeSyncI(MCInst &Inst, unsigned Insn, uint64_t Address,
268*d415bd75Srobert const MCDisassembler *Decoder);
26909467b48Spatrick
270*d415bd75Srobert static DecodeStatus DecodeSyncI_MM(MCInst &Inst, unsigned Insn,
27109467b48Spatrick uint64_t Address,
272*d415bd75Srobert const MCDisassembler *Decoder);
27309467b48Spatrick
274*d415bd75Srobert static DecodeStatus DecodeSynciR6(MCInst &Inst, unsigned Insn, uint64_t Address,
275*d415bd75Srobert const MCDisassembler *Decoder);
27609467b48Spatrick
27709467b48Spatrick static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn,
27809467b48Spatrick uint64_t Address,
279*d415bd75Srobert const MCDisassembler *Decoder);
28009467b48Spatrick
281*d415bd75Srobert static DecodeStatus DecodeMemMMImm4(MCInst &Inst, unsigned Insn,
28209467b48Spatrick uint64_t Address,
283*d415bd75Srobert const MCDisassembler *Decoder);
28409467b48Spatrick
285*d415bd75Srobert static DecodeStatus DecodeMemMMSPImm5Lsl2(MCInst &Inst, unsigned Insn,
28609467b48Spatrick uint64_t Address,
287*d415bd75Srobert const MCDisassembler *Decoder);
28809467b48Spatrick
289*d415bd75Srobert static DecodeStatus DecodeMemMMGPImm7Lsl2(MCInst &Inst, unsigned Insn,
29009467b48Spatrick uint64_t Address,
291*d415bd75Srobert const MCDisassembler *Decoder);
29209467b48Spatrick
293*d415bd75Srobert static DecodeStatus DecodeMemMMReglistImm4Lsl2(MCInst &Inst, unsigned Insn,
29409467b48Spatrick uint64_t Address,
295*d415bd75Srobert const MCDisassembler *Decoder);
29609467b48Spatrick
297*d415bd75Srobert static DecodeStatus DecodeMemMMImm9(MCInst &Inst, unsigned Insn,
29809467b48Spatrick uint64_t Address,
299*d415bd75Srobert const MCDisassembler *Decoder);
30009467b48Spatrick
301*d415bd75Srobert static DecodeStatus DecodeMemMMImm12(MCInst &Inst, unsigned Insn,
30209467b48Spatrick uint64_t Address,
303*d415bd75Srobert const MCDisassembler *Decoder);
30409467b48Spatrick
305*d415bd75Srobert static DecodeStatus DecodeMemMMImm16(MCInst &Inst, unsigned Insn,
30609467b48Spatrick uint64_t Address,
307*d415bd75Srobert const MCDisassembler *Decoder);
308*d415bd75Srobert
309*d415bd75Srobert static DecodeStatus DecodeFMem(MCInst &Inst, unsigned Insn, uint64_t Address,
310*d415bd75Srobert const MCDisassembler *Decoder);
31109467b48Spatrick
31209467b48Spatrick static DecodeStatus DecodeFMemMMR2(MCInst &Inst, unsigned Insn,
31309467b48Spatrick uint64_t Address,
314*d415bd75Srobert const MCDisassembler *Decoder);
31509467b48Spatrick
31609467b48Spatrick static DecodeStatus DecodeFMem2(MCInst &Inst, unsigned Insn, uint64_t Address,
317*d415bd75Srobert const MCDisassembler *Decoder);
31809467b48Spatrick
31909467b48Spatrick static DecodeStatus DecodeFMem3(MCInst &Inst, unsigned Insn, uint64_t Address,
320*d415bd75Srobert const MCDisassembler *Decoder);
32109467b48Spatrick
32209467b48Spatrick static DecodeStatus DecodeFMemCop2R6(MCInst &Inst, unsigned Insn,
323*d415bd75Srobert uint64_t Address,
324*d415bd75Srobert const MCDisassembler *Decoder);
32509467b48Spatrick
32609467b48Spatrick static DecodeStatus DecodeFMemCop2MMR6(MCInst &Inst, unsigned Insn,
32709467b48Spatrick uint64_t Address,
328*d415bd75Srobert const MCDisassembler *Decoder);
32909467b48Spatrick
330*d415bd75Srobert static DecodeStatus DecodeSpecial3LlSc(MCInst &Inst, unsigned Insn,
33109467b48Spatrick uint64_t Address,
332*d415bd75Srobert const MCDisassembler *Decoder);
33309467b48Spatrick
334*d415bd75Srobert static DecodeStatus DecodeAddiur2Simm7(MCInst &Inst, unsigned Value,
33509467b48Spatrick uint64_t Address,
336*d415bd75Srobert const MCDisassembler *Decoder);
33709467b48Spatrick
338*d415bd75Srobert static DecodeStatus DecodeLi16Imm(MCInst &Inst, unsigned Value,
33909467b48Spatrick uint64_t Address,
340*d415bd75Srobert const MCDisassembler *Decoder);
34109467b48Spatrick
342*d415bd75Srobert static DecodeStatus DecodePOOL16BEncodedField(MCInst &Inst, unsigned Value,
34309467b48Spatrick uint64_t Address,
344*d415bd75Srobert const MCDisassembler *Decoder);
34509467b48Spatrick
34609467b48Spatrick template <unsigned Bits, int Offset, int Scale>
34709467b48Spatrick static DecodeStatus DecodeUImmWithOffsetAndScale(MCInst &Inst, unsigned Value,
34809467b48Spatrick uint64_t Address,
349*d415bd75Srobert const MCDisassembler *Decoder);
35009467b48Spatrick
35109467b48Spatrick template <unsigned Bits, int Offset>
DecodeUImmWithOffset(MCInst & Inst,unsigned Value,uint64_t Address,const MCDisassembler * Decoder)35209467b48Spatrick static DecodeStatus DecodeUImmWithOffset(MCInst &Inst, unsigned Value,
35309467b48Spatrick uint64_t Address,
354*d415bd75Srobert const MCDisassembler *Decoder) {
35509467b48Spatrick return DecodeUImmWithOffsetAndScale<Bits, Offset, 1>(Inst, Value, Address,
35609467b48Spatrick Decoder);
35709467b48Spatrick }
35809467b48Spatrick
35909467b48Spatrick template <unsigned Bits, int Offset = 0, int ScaleBy = 1>
36009467b48Spatrick static DecodeStatus DecodeSImmWithOffsetAndScale(MCInst &Inst, unsigned Value,
36109467b48Spatrick uint64_t Address,
362*d415bd75Srobert const MCDisassembler *Decoder);
36309467b48Spatrick
364*d415bd75Srobert static DecodeStatus DecodeInsSize(MCInst &Inst, unsigned Insn, uint64_t Address,
365*d415bd75Srobert const MCDisassembler *Decoder);
36609467b48Spatrick
36709467b48Spatrick static DecodeStatus DecodeSimm19Lsl2(MCInst &Inst, unsigned Insn,
368*d415bd75Srobert uint64_t Address,
369*d415bd75Srobert const MCDisassembler *Decoder);
37009467b48Spatrick
37109467b48Spatrick static DecodeStatus DecodeSimm18Lsl3(MCInst &Inst, unsigned Insn,
372*d415bd75Srobert uint64_t Address,
373*d415bd75Srobert const MCDisassembler *Decoder);
37409467b48Spatrick
375*d415bd75Srobert static DecodeStatus DecodeSimm9SP(MCInst &Inst, unsigned Insn, uint64_t Address,
376*d415bd75Srobert const MCDisassembler *Decoder);
37709467b48Spatrick
37809467b48Spatrick static DecodeStatus DecodeANDI16Imm(MCInst &Inst, unsigned Insn,
379*d415bd75Srobert uint64_t Address,
380*d415bd75Srobert const MCDisassembler *Decoder);
38109467b48Spatrick
38209467b48Spatrick static DecodeStatus DecodeSimm23Lsl2(MCInst &Inst, unsigned Insn,
383*d415bd75Srobert uint64_t Address,
384*d415bd75Srobert const MCDisassembler *Decoder);
38509467b48Spatrick
38609467b48Spatrick /// INSVE_[BHWD] have an implicit operand that the generated decoder doesn't
38709467b48Spatrick /// handle.
38809467b48Spatrick template <typename InsnType>
38909467b48Spatrick static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address,
390*d415bd75Srobert const MCDisassembler *Decoder);
39109467b48Spatrick
39209467b48Spatrick template <typename InsnType>
39309467b48Spatrick static DecodeStatus DecodeDAHIDATIMMR6(MCInst &MI, InsnType insn,
394*d415bd75Srobert uint64_t Address,
395*d415bd75Srobert const MCDisassembler *Decoder);
39609467b48Spatrick
39709467b48Spatrick template <typename InsnType>
39809467b48Spatrick static DecodeStatus DecodeDAHIDATI(MCInst &MI, InsnType insn, uint64_t Address,
399*d415bd75Srobert const MCDisassembler *Decoder);
40009467b48Spatrick
40109467b48Spatrick template <typename InsnType>
402*d415bd75Srobert static DecodeStatus DecodeAddiGroupBranch(MCInst &MI, InsnType insn,
403*d415bd75Srobert uint64_t Address,
404*d415bd75Srobert const MCDisassembler *Decoder);
40509467b48Spatrick
40609467b48Spatrick template <typename InsnType>
407*d415bd75Srobert static DecodeStatus DecodePOP35GroupBranchMMR6(MCInst &MI, InsnType insn,
408*d415bd75Srobert uint64_t Address,
409*d415bd75Srobert const MCDisassembler *Decoder);
41009467b48Spatrick
41109467b48Spatrick template <typename InsnType>
412*d415bd75Srobert static DecodeStatus DecodeDaddiGroupBranch(MCInst &MI, InsnType insn,
413*d415bd75Srobert uint64_t Address,
414*d415bd75Srobert const MCDisassembler *Decoder);
41509467b48Spatrick
41609467b48Spatrick template <typename InsnType>
417*d415bd75Srobert static DecodeStatus DecodePOP37GroupBranchMMR6(MCInst &MI, InsnType insn,
418*d415bd75Srobert uint64_t Address,
419*d415bd75Srobert const MCDisassembler *Decoder);
42009467b48Spatrick
42109467b48Spatrick template <typename InsnType>
422*d415bd75Srobert static DecodeStatus DecodePOP65GroupBranchMMR6(MCInst &MI, InsnType insn,
423*d415bd75Srobert uint64_t Address,
424*d415bd75Srobert const MCDisassembler *Decoder);
42509467b48Spatrick
42609467b48Spatrick template <typename InsnType>
427*d415bd75Srobert static DecodeStatus DecodePOP75GroupBranchMMR6(MCInst &MI, InsnType insn,
428*d415bd75Srobert uint64_t Address,
429*d415bd75Srobert const MCDisassembler *Decoder);
43009467b48Spatrick
43109467b48Spatrick template <typename InsnType>
432*d415bd75Srobert static DecodeStatus DecodeBlezlGroupBranch(MCInst &MI, InsnType insn,
433*d415bd75Srobert uint64_t Address,
434*d415bd75Srobert const MCDisassembler *Decoder);
43509467b48Spatrick
43609467b48Spatrick template <typename InsnType>
437*d415bd75Srobert static DecodeStatus DecodeBgtzlGroupBranch(MCInst &MI, InsnType insn,
438*d415bd75Srobert uint64_t Address,
439*d415bd75Srobert const MCDisassembler *Decoder);
44009467b48Spatrick
44109467b48Spatrick template <typename InsnType>
442*d415bd75Srobert static DecodeStatus DecodeBgtzGroupBranch(MCInst &MI, InsnType insn,
443*d415bd75Srobert uint64_t Address,
444*d415bd75Srobert const MCDisassembler *Decoder);
44509467b48Spatrick
44609467b48Spatrick template <typename InsnType>
447*d415bd75Srobert static DecodeStatus DecodeBlezGroupBranch(MCInst &MI, InsnType insn,
448*d415bd75Srobert uint64_t Address,
449*d415bd75Srobert const MCDisassembler *Decoder);
45009467b48Spatrick
45109467b48Spatrick template <typename InsnType>
452*d415bd75Srobert static DecodeStatus DecodeBgtzGroupBranchMMR6(MCInst &MI, InsnType insn,
453*d415bd75Srobert uint64_t Address,
454*d415bd75Srobert const MCDisassembler *Decoder);
45509467b48Spatrick
45609467b48Spatrick template <typename InsnType>
457*d415bd75Srobert static DecodeStatus DecodeBlezGroupBranchMMR6(MCInst &MI, InsnType insn,
458*d415bd75Srobert uint64_t Address,
459*d415bd75Srobert const MCDisassembler *Decoder);
46009467b48Spatrick
46109467b48Spatrick template <typename InsnType>
46209467b48Spatrick static DecodeStatus DecodeDINS(MCInst &MI, InsnType Insn, uint64_t Address,
463*d415bd75Srobert const MCDisassembler *Decoder);
46409467b48Spatrick
46509467b48Spatrick template <typename InsnType>
46609467b48Spatrick static DecodeStatus DecodeDEXT(MCInst &MI, InsnType Insn, uint64_t Address,
467*d415bd75Srobert const MCDisassembler *Decoder);
46809467b48Spatrick
46909467b48Spatrick template <typename InsnType>
47009467b48Spatrick static DecodeStatus DecodeCRC(MCInst &MI, InsnType Insn, uint64_t Address,
471*d415bd75Srobert const MCDisassembler *Decoder);
47209467b48Spatrick
47309467b48Spatrick static DecodeStatus DecodeRegListOperand(MCInst &Inst, unsigned Insn,
47409467b48Spatrick uint64_t Address,
475*d415bd75Srobert const MCDisassembler *Decoder);
47609467b48Spatrick
47709467b48Spatrick static DecodeStatus DecodeRegListOperand16(MCInst &Inst, unsigned Insn,
47809467b48Spatrick uint64_t Address,
479*d415bd75Srobert const MCDisassembler *Decoder);
48009467b48Spatrick
48109467b48Spatrick static DecodeStatus DecodeMovePRegPair(MCInst &Inst, unsigned RegPair,
48209467b48Spatrick uint64_t Address,
483*d415bd75Srobert const MCDisassembler *Decoder);
48409467b48Spatrick
48509467b48Spatrick static DecodeStatus DecodeMovePOperands(MCInst &Inst, unsigned Insn,
486*d415bd75Srobert uint64_t Address,
487*d415bd75Srobert const MCDisassembler *Decoder);
488*d415bd75Srobert
489*d415bd75Srobert static DecodeStatus DecodeFIXMEInstruction(MCInst &Inst, unsigned Insn,
490*d415bd75Srobert uint64_t Address,
491*d415bd75Srobert const MCDisassembler *Decoder);
49209467b48Spatrick
createMipsDisassembler(const Target & T,const MCSubtargetInfo & STI,MCContext & Ctx)49309467b48Spatrick static MCDisassembler *createMipsDisassembler(
49409467b48Spatrick const Target &T,
49509467b48Spatrick const MCSubtargetInfo &STI,
49609467b48Spatrick MCContext &Ctx) {
49709467b48Spatrick return new MipsDisassembler(STI, Ctx, true);
49809467b48Spatrick }
49909467b48Spatrick
createMipselDisassembler(const Target & T,const MCSubtargetInfo & STI,MCContext & Ctx)50009467b48Spatrick static MCDisassembler *createMipselDisassembler(
50109467b48Spatrick const Target &T,
50209467b48Spatrick const MCSubtargetInfo &STI,
50309467b48Spatrick MCContext &Ctx) {
50409467b48Spatrick return new MipsDisassembler(STI, Ctx, false);
50509467b48Spatrick }
50609467b48Spatrick
LLVMInitializeMipsDisassembler()50709467b48Spatrick extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeMipsDisassembler() {
50809467b48Spatrick // Register the disassembler.
50909467b48Spatrick TargetRegistry::RegisterMCDisassembler(getTheMipsTarget(),
51009467b48Spatrick createMipsDisassembler);
51109467b48Spatrick TargetRegistry::RegisterMCDisassembler(getTheMipselTarget(),
51209467b48Spatrick createMipselDisassembler);
51309467b48Spatrick TargetRegistry::RegisterMCDisassembler(getTheMips64Target(),
51409467b48Spatrick createMipsDisassembler);
51509467b48Spatrick TargetRegistry::RegisterMCDisassembler(getTheMips64elTarget(),
51609467b48Spatrick createMipselDisassembler);
51709467b48Spatrick }
51809467b48Spatrick
51909467b48Spatrick #include "MipsGenDisassemblerTables.inc"
52009467b48Spatrick
getReg(const MCDisassembler * D,unsigned RC,unsigned RegNo)521*d415bd75Srobert static unsigned getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo) {
522*d415bd75Srobert const MCRegisterInfo *RegInfo = D->getContext().getRegisterInfo();
52309467b48Spatrick return *(RegInfo->getRegClass(RC).begin() + RegNo);
52409467b48Spatrick }
52509467b48Spatrick
52609467b48Spatrick template <typename InsnType>
DecodeINSVE_DF(MCInst & MI,InsnType insn,uint64_t Address,const MCDisassembler * Decoder)52709467b48Spatrick static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address,
528*d415bd75Srobert const MCDisassembler *Decoder) {
529*d415bd75Srobert using DecodeFN =
530*d415bd75Srobert DecodeStatus (*)(MCInst &, unsigned, uint64_t, const MCDisassembler *);
53109467b48Spatrick
53209467b48Spatrick // The size of the n field depends on the element size
53309467b48Spatrick // The register class also depends on this.
53409467b48Spatrick InsnType tmp = fieldFromInstruction(insn, 17, 5);
53509467b48Spatrick unsigned NSize = 0;
53609467b48Spatrick DecodeFN RegDecoder = nullptr;
53709467b48Spatrick if ((tmp & 0x18) == 0x00) { // INSVE_B
53809467b48Spatrick NSize = 4;
53909467b48Spatrick RegDecoder = DecodeMSA128BRegisterClass;
54009467b48Spatrick } else if ((tmp & 0x1c) == 0x10) { // INSVE_H
54109467b48Spatrick NSize = 3;
54209467b48Spatrick RegDecoder = DecodeMSA128HRegisterClass;
54309467b48Spatrick } else if ((tmp & 0x1e) == 0x18) { // INSVE_W
54409467b48Spatrick NSize = 2;
54509467b48Spatrick RegDecoder = DecodeMSA128WRegisterClass;
54609467b48Spatrick } else if ((tmp & 0x1f) == 0x1c) { // INSVE_D
54709467b48Spatrick NSize = 1;
54809467b48Spatrick RegDecoder = DecodeMSA128DRegisterClass;
54909467b48Spatrick } else
55009467b48Spatrick llvm_unreachable("Invalid encoding");
55109467b48Spatrick
55209467b48Spatrick assert(NSize != 0 && RegDecoder != nullptr);
55309467b48Spatrick
55409467b48Spatrick // $wd
55509467b48Spatrick tmp = fieldFromInstruction(insn, 6, 5);
55609467b48Spatrick if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
55709467b48Spatrick return MCDisassembler::Fail;
55809467b48Spatrick // $wd_in
55909467b48Spatrick if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
56009467b48Spatrick return MCDisassembler::Fail;
56109467b48Spatrick // $n
56209467b48Spatrick tmp = fieldFromInstruction(insn, 16, NSize);
56309467b48Spatrick MI.addOperand(MCOperand::createImm(tmp));
56409467b48Spatrick // $ws
56509467b48Spatrick tmp = fieldFromInstruction(insn, 11, 5);
56609467b48Spatrick if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
56709467b48Spatrick return MCDisassembler::Fail;
56809467b48Spatrick // $n2
56909467b48Spatrick MI.addOperand(MCOperand::createImm(0));
57009467b48Spatrick
57109467b48Spatrick return MCDisassembler::Success;
57209467b48Spatrick }
57309467b48Spatrick
57409467b48Spatrick template <typename InsnType>
DecodeDAHIDATIMMR6(MCInst & MI,InsnType insn,uint64_t Address,const MCDisassembler * Decoder)57509467b48Spatrick static DecodeStatus DecodeDAHIDATIMMR6(MCInst &MI, InsnType insn,
576*d415bd75Srobert uint64_t Address,
577*d415bd75Srobert const MCDisassembler *Decoder) {
57809467b48Spatrick InsnType Rs = fieldFromInstruction(insn, 16, 5);
57909467b48Spatrick InsnType Imm = fieldFromInstruction(insn, 0, 16);
58009467b48Spatrick MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID,
58109467b48Spatrick Rs)));
58209467b48Spatrick MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID,
58309467b48Spatrick Rs)));
58409467b48Spatrick MI.addOperand(MCOperand::createImm(Imm));
58509467b48Spatrick
58609467b48Spatrick return MCDisassembler::Success;
58709467b48Spatrick }
58809467b48Spatrick
58909467b48Spatrick template <typename InsnType>
DecodeDAHIDATI(MCInst & MI,InsnType insn,uint64_t Address,const MCDisassembler * Decoder)59009467b48Spatrick static DecodeStatus DecodeDAHIDATI(MCInst &MI, InsnType insn, uint64_t Address,
591*d415bd75Srobert const MCDisassembler *Decoder) {
59209467b48Spatrick InsnType Rs = fieldFromInstruction(insn, 21, 5);
59309467b48Spatrick InsnType Imm = fieldFromInstruction(insn, 0, 16);
59409467b48Spatrick MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID,
59509467b48Spatrick Rs)));
59609467b48Spatrick MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID,
59709467b48Spatrick Rs)));
59809467b48Spatrick MI.addOperand(MCOperand::createImm(Imm));
59909467b48Spatrick
60009467b48Spatrick return MCDisassembler::Success;
60109467b48Spatrick }
60209467b48Spatrick
60309467b48Spatrick template <typename InsnType>
DecodeAddiGroupBranch(MCInst & MI,InsnType insn,uint64_t Address,const MCDisassembler * Decoder)60409467b48Spatrick static DecodeStatus DecodeAddiGroupBranch(MCInst &MI, InsnType insn,
60509467b48Spatrick uint64_t Address,
606*d415bd75Srobert const MCDisassembler *Decoder) {
60709467b48Spatrick // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
60809467b48Spatrick // (otherwise we would have matched the ADDI instruction from the earlier
60909467b48Spatrick // ISA's instead).
61009467b48Spatrick //
61109467b48Spatrick // We have:
61209467b48Spatrick // 0b001000 sssss ttttt iiiiiiiiiiiiiiii
61309467b48Spatrick // BOVC if rs >= rt
61409467b48Spatrick // BEQZALC if rs == 0 && rt != 0
61509467b48Spatrick // BEQC if rs < rt && rs != 0
61609467b48Spatrick
61709467b48Spatrick InsnType Rs = fieldFromInstruction(insn, 21, 5);
61809467b48Spatrick InsnType Rt = fieldFromInstruction(insn, 16, 5);
61909467b48Spatrick int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
62009467b48Spatrick bool HasRs = false;
62109467b48Spatrick
62209467b48Spatrick if (Rs >= Rt) {
62309467b48Spatrick MI.setOpcode(Mips::BOVC);
62409467b48Spatrick HasRs = true;
62509467b48Spatrick } else if (Rs != 0 && Rs < Rt) {
62609467b48Spatrick MI.setOpcode(Mips::BEQC);
62709467b48Spatrick HasRs = true;
62809467b48Spatrick } else
62909467b48Spatrick MI.setOpcode(Mips::BEQZALC);
63009467b48Spatrick
63109467b48Spatrick if (HasRs)
63209467b48Spatrick MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
63309467b48Spatrick Rs)));
63409467b48Spatrick
63509467b48Spatrick MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
63609467b48Spatrick Rt)));
63709467b48Spatrick MI.addOperand(MCOperand::createImm(Imm));
63809467b48Spatrick
63909467b48Spatrick return MCDisassembler::Success;
64009467b48Spatrick }
64109467b48Spatrick
64209467b48Spatrick template <typename InsnType>
DecodePOP35GroupBranchMMR6(MCInst & MI,InsnType insn,uint64_t Address,const MCDisassembler * Decoder)64309467b48Spatrick static DecodeStatus DecodePOP35GroupBranchMMR6(MCInst &MI, InsnType insn,
64409467b48Spatrick uint64_t Address,
645*d415bd75Srobert const MCDisassembler *Decoder) {
64609467b48Spatrick InsnType Rt = fieldFromInstruction(insn, 21, 5);
64709467b48Spatrick InsnType Rs = fieldFromInstruction(insn, 16, 5);
64809467b48Spatrick int64_t Imm = 0;
64909467b48Spatrick
65009467b48Spatrick if (Rs >= Rt) {
65109467b48Spatrick MI.setOpcode(Mips::BOVC_MMR6);
65209467b48Spatrick MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
65309467b48Spatrick Rt)));
65409467b48Spatrick MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
65509467b48Spatrick Rs)));
65609467b48Spatrick Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
65709467b48Spatrick } else if (Rs != 0 && Rs < Rt) {
65809467b48Spatrick MI.setOpcode(Mips::BEQC_MMR6);
65909467b48Spatrick MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
66009467b48Spatrick Rs)));
66109467b48Spatrick MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
66209467b48Spatrick Rt)));
66309467b48Spatrick Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
66409467b48Spatrick } else {
66509467b48Spatrick MI.setOpcode(Mips::BEQZALC_MMR6);
66609467b48Spatrick MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
66709467b48Spatrick Rt)));
66809467b48Spatrick Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
66909467b48Spatrick }
67009467b48Spatrick
67109467b48Spatrick MI.addOperand(MCOperand::createImm(Imm));
67209467b48Spatrick
67309467b48Spatrick return MCDisassembler::Success;
67409467b48Spatrick }
67509467b48Spatrick
67609467b48Spatrick template <typename InsnType>
DecodeDaddiGroupBranch(MCInst & MI,InsnType insn,uint64_t Address,const MCDisassembler * Decoder)67709467b48Spatrick static DecodeStatus DecodeDaddiGroupBranch(MCInst &MI, InsnType insn,
67809467b48Spatrick uint64_t Address,
679*d415bd75Srobert const MCDisassembler *Decoder) {
68009467b48Spatrick // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
68109467b48Spatrick // (otherwise we would have matched the ADDI instruction from the earlier
68209467b48Spatrick // ISA's instead).
68309467b48Spatrick //
68409467b48Spatrick // We have:
68509467b48Spatrick // 0b011000 sssss ttttt iiiiiiiiiiiiiiii
68609467b48Spatrick // BNVC if rs >= rt
68709467b48Spatrick // BNEZALC if rs == 0 && rt != 0
68809467b48Spatrick // BNEC if rs < rt && rs != 0
68909467b48Spatrick
69009467b48Spatrick InsnType Rs = fieldFromInstruction(insn, 21, 5);
69109467b48Spatrick InsnType Rt = fieldFromInstruction(insn, 16, 5);
69209467b48Spatrick int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
69309467b48Spatrick bool HasRs = false;
69409467b48Spatrick
69509467b48Spatrick if (Rs >= Rt) {
69609467b48Spatrick MI.setOpcode(Mips::BNVC);
69709467b48Spatrick HasRs = true;
69809467b48Spatrick } else if (Rs != 0 && Rs < Rt) {
69909467b48Spatrick MI.setOpcode(Mips::BNEC);
70009467b48Spatrick HasRs = true;
70109467b48Spatrick } else
70209467b48Spatrick MI.setOpcode(Mips::BNEZALC);
70309467b48Spatrick
70409467b48Spatrick if (HasRs)
70509467b48Spatrick MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
70609467b48Spatrick Rs)));
70709467b48Spatrick
70809467b48Spatrick MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
70909467b48Spatrick Rt)));
71009467b48Spatrick MI.addOperand(MCOperand::createImm(Imm));
71109467b48Spatrick
71209467b48Spatrick return MCDisassembler::Success;
71309467b48Spatrick }
71409467b48Spatrick
71509467b48Spatrick template <typename InsnType>
DecodePOP37GroupBranchMMR6(MCInst & MI,InsnType insn,uint64_t Address,const MCDisassembler * Decoder)71609467b48Spatrick static DecodeStatus DecodePOP37GroupBranchMMR6(MCInst &MI, InsnType insn,
71709467b48Spatrick uint64_t Address,
718*d415bd75Srobert const MCDisassembler *Decoder) {
71909467b48Spatrick InsnType Rt = fieldFromInstruction(insn, 21, 5);
72009467b48Spatrick InsnType Rs = fieldFromInstruction(insn, 16, 5);
72109467b48Spatrick int64_t Imm = 0;
72209467b48Spatrick
72309467b48Spatrick if (Rs >= Rt) {
72409467b48Spatrick MI.setOpcode(Mips::BNVC_MMR6);
72509467b48Spatrick MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
72609467b48Spatrick Rt)));
72709467b48Spatrick MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
72809467b48Spatrick Rs)));
72909467b48Spatrick Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
73009467b48Spatrick } else if (Rs != 0 && Rs < Rt) {
73109467b48Spatrick MI.setOpcode(Mips::BNEC_MMR6);
73209467b48Spatrick MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
73309467b48Spatrick Rs)));
73409467b48Spatrick MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
73509467b48Spatrick Rt)));
73609467b48Spatrick Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
73709467b48Spatrick } else {
73809467b48Spatrick MI.setOpcode(Mips::BNEZALC_MMR6);
73909467b48Spatrick MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
74009467b48Spatrick Rt)));
74109467b48Spatrick Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
74209467b48Spatrick }
74309467b48Spatrick
74409467b48Spatrick MI.addOperand(MCOperand::createImm(Imm));
74509467b48Spatrick
74609467b48Spatrick return MCDisassembler::Success;
74709467b48Spatrick }
74809467b48Spatrick
74909467b48Spatrick template <typename InsnType>
DecodePOP65GroupBranchMMR6(MCInst & MI,InsnType insn,uint64_t Address,const MCDisassembler * Decoder)75009467b48Spatrick static DecodeStatus DecodePOP65GroupBranchMMR6(MCInst &MI, InsnType insn,
75109467b48Spatrick uint64_t Address,
752*d415bd75Srobert const MCDisassembler *Decoder) {
75309467b48Spatrick // We have:
75409467b48Spatrick // 0b110101 ttttt sssss iiiiiiiiiiiiiiii
75509467b48Spatrick // Invalid if rt == 0
75609467b48Spatrick // BGTZC_MMR6 if rs == 0 && rt != 0
75709467b48Spatrick // BLTZC_MMR6 if rs == rt && rt != 0
75809467b48Spatrick // BLTC_MMR6 if rs != rt && rs != 0 && rt != 0
75909467b48Spatrick
76009467b48Spatrick InsnType Rt = fieldFromInstruction(insn, 21, 5);
76109467b48Spatrick InsnType Rs = fieldFromInstruction(insn, 16, 5);
76209467b48Spatrick int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
76309467b48Spatrick bool HasRs = false;
76409467b48Spatrick
76509467b48Spatrick if (Rt == 0)
76609467b48Spatrick return MCDisassembler::Fail;
76709467b48Spatrick else if (Rs == 0)
76809467b48Spatrick MI.setOpcode(Mips::BGTZC_MMR6);
76909467b48Spatrick else if (Rs == Rt)
77009467b48Spatrick MI.setOpcode(Mips::BLTZC_MMR6);
77109467b48Spatrick else {
77209467b48Spatrick MI.setOpcode(Mips::BLTC_MMR6);
77309467b48Spatrick HasRs = true;
77409467b48Spatrick }
77509467b48Spatrick
77609467b48Spatrick if (HasRs)
77709467b48Spatrick MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
77809467b48Spatrick Rs)));
77909467b48Spatrick
78009467b48Spatrick MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
78109467b48Spatrick Rt)));
78209467b48Spatrick
78309467b48Spatrick MI.addOperand(MCOperand::createImm(Imm));
78409467b48Spatrick
78509467b48Spatrick return MCDisassembler::Success;
78609467b48Spatrick }
78709467b48Spatrick
78809467b48Spatrick template <typename InsnType>
DecodePOP75GroupBranchMMR6(MCInst & MI,InsnType insn,uint64_t Address,const MCDisassembler * Decoder)78909467b48Spatrick static DecodeStatus DecodePOP75GroupBranchMMR6(MCInst &MI, InsnType insn,
79009467b48Spatrick uint64_t Address,
791*d415bd75Srobert const MCDisassembler *Decoder) {
79209467b48Spatrick // We have:
79309467b48Spatrick // 0b111101 ttttt sssss iiiiiiiiiiiiiiii
79409467b48Spatrick // Invalid if rt == 0
79509467b48Spatrick // BLEZC_MMR6 if rs == 0 && rt != 0
79609467b48Spatrick // BGEZC_MMR6 if rs == rt && rt != 0
79709467b48Spatrick // BGEC_MMR6 if rs != rt && rs != 0 && rt != 0
79809467b48Spatrick
79909467b48Spatrick InsnType Rt = fieldFromInstruction(insn, 21, 5);
80009467b48Spatrick InsnType Rs = fieldFromInstruction(insn, 16, 5);
80109467b48Spatrick int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
80209467b48Spatrick bool HasRs = false;
80309467b48Spatrick
80409467b48Spatrick if (Rt == 0)
80509467b48Spatrick return MCDisassembler::Fail;
80609467b48Spatrick else if (Rs == 0)
80709467b48Spatrick MI.setOpcode(Mips::BLEZC_MMR6);
80809467b48Spatrick else if (Rs == Rt)
80909467b48Spatrick MI.setOpcode(Mips::BGEZC_MMR6);
81009467b48Spatrick else {
81109467b48Spatrick HasRs = true;
81209467b48Spatrick MI.setOpcode(Mips::BGEC_MMR6);
81309467b48Spatrick }
81409467b48Spatrick
81509467b48Spatrick if (HasRs)
81609467b48Spatrick MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
81709467b48Spatrick Rs)));
81809467b48Spatrick
81909467b48Spatrick MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
82009467b48Spatrick Rt)));
82109467b48Spatrick
82209467b48Spatrick MI.addOperand(MCOperand::createImm(Imm));
82309467b48Spatrick
82409467b48Spatrick return MCDisassembler::Success;
82509467b48Spatrick }
82609467b48Spatrick
82709467b48Spatrick template <typename InsnType>
DecodeBlezlGroupBranch(MCInst & MI,InsnType insn,uint64_t Address,const MCDisassembler * Decoder)82809467b48Spatrick static DecodeStatus DecodeBlezlGroupBranch(MCInst &MI, InsnType insn,
82909467b48Spatrick uint64_t Address,
830*d415bd75Srobert const MCDisassembler *Decoder) {
83109467b48Spatrick // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
83209467b48Spatrick // (otherwise we would have matched the BLEZL instruction from the earlier
83309467b48Spatrick // ISA's instead).
83409467b48Spatrick //
83509467b48Spatrick // We have:
83609467b48Spatrick // 0b010110 sssss ttttt iiiiiiiiiiiiiiii
83709467b48Spatrick // Invalid if rs == 0
83809467b48Spatrick // BLEZC if rs == 0 && rt != 0
83909467b48Spatrick // BGEZC if rs == rt && rt != 0
84009467b48Spatrick // BGEC if rs != rt && rs != 0 && rt != 0
84109467b48Spatrick
84209467b48Spatrick InsnType Rs = fieldFromInstruction(insn, 21, 5);
84309467b48Spatrick InsnType Rt = fieldFromInstruction(insn, 16, 5);
84409467b48Spatrick int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
84509467b48Spatrick bool HasRs = false;
84609467b48Spatrick
84709467b48Spatrick if (Rt == 0)
84809467b48Spatrick return MCDisassembler::Fail;
84909467b48Spatrick else if (Rs == 0)
85009467b48Spatrick MI.setOpcode(Mips::BLEZC);
85109467b48Spatrick else if (Rs == Rt)
85209467b48Spatrick MI.setOpcode(Mips::BGEZC);
85309467b48Spatrick else {
85409467b48Spatrick HasRs = true;
85509467b48Spatrick MI.setOpcode(Mips::BGEC);
85609467b48Spatrick }
85709467b48Spatrick
85809467b48Spatrick if (HasRs)
85909467b48Spatrick MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
86009467b48Spatrick Rs)));
86109467b48Spatrick
86209467b48Spatrick MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
86309467b48Spatrick Rt)));
86409467b48Spatrick
86509467b48Spatrick MI.addOperand(MCOperand::createImm(Imm));
86609467b48Spatrick
86709467b48Spatrick return MCDisassembler::Success;
86809467b48Spatrick }
86909467b48Spatrick
87009467b48Spatrick template <typename InsnType>
DecodeBgtzlGroupBranch(MCInst & MI,InsnType insn,uint64_t Address,const MCDisassembler * Decoder)87109467b48Spatrick static DecodeStatus DecodeBgtzlGroupBranch(MCInst &MI, InsnType insn,
87209467b48Spatrick uint64_t Address,
873*d415bd75Srobert const MCDisassembler *Decoder) {
87409467b48Spatrick // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
87509467b48Spatrick // (otherwise we would have matched the BGTZL instruction from the earlier
87609467b48Spatrick // ISA's instead).
87709467b48Spatrick //
87809467b48Spatrick // We have:
87909467b48Spatrick // 0b010111 sssss ttttt iiiiiiiiiiiiiiii
88009467b48Spatrick // Invalid if rs == 0
88109467b48Spatrick // BGTZC if rs == 0 && rt != 0
88209467b48Spatrick // BLTZC if rs == rt && rt != 0
88309467b48Spatrick // BLTC if rs != rt && rs != 0 && rt != 0
88409467b48Spatrick
88509467b48Spatrick bool HasRs = false;
88609467b48Spatrick
88709467b48Spatrick InsnType Rs = fieldFromInstruction(insn, 21, 5);
88809467b48Spatrick InsnType Rt = fieldFromInstruction(insn, 16, 5);
88909467b48Spatrick int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
89009467b48Spatrick
89109467b48Spatrick if (Rt == 0)
89209467b48Spatrick return MCDisassembler::Fail;
89309467b48Spatrick else if (Rs == 0)
89409467b48Spatrick MI.setOpcode(Mips::BGTZC);
89509467b48Spatrick else if (Rs == Rt)
89609467b48Spatrick MI.setOpcode(Mips::BLTZC);
89709467b48Spatrick else {
89809467b48Spatrick MI.setOpcode(Mips::BLTC);
89909467b48Spatrick HasRs = true;
90009467b48Spatrick }
90109467b48Spatrick
90209467b48Spatrick if (HasRs)
90309467b48Spatrick MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
90409467b48Spatrick Rs)));
90509467b48Spatrick
90609467b48Spatrick MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
90709467b48Spatrick Rt)));
90809467b48Spatrick
90909467b48Spatrick MI.addOperand(MCOperand::createImm(Imm));
91009467b48Spatrick
91109467b48Spatrick return MCDisassembler::Success;
91209467b48Spatrick }
91309467b48Spatrick
91409467b48Spatrick template <typename InsnType>
DecodeBgtzGroupBranch(MCInst & MI,InsnType insn,uint64_t Address,const MCDisassembler * Decoder)91509467b48Spatrick static DecodeStatus DecodeBgtzGroupBranch(MCInst &MI, InsnType insn,
91609467b48Spatrick uint64_t Address,
917*d415bd75Srobert const MCDisassembler *Decoder) {
91809467b48Spatrick // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
91909467b48Spatrick // (otherwise we would have matched the BGTZ instruction from the earlier
92009467b48Spatrick // ISA's instead).
92109467b48Spatrick //
92209467b48Spatrick // We have:
92309467b48Spatrick // 0b000111 sssss ttttt iiiiiiiiiiiiiiii
92409467b48Spatrick // BGTZ if rt == 0
92509467b48Spatrick // BGTZALC if rs == 0 && rt != 0
92609467b48Spatrick // BLTZALC if rs != 0 && rs == rt
92709467b48Spatrick // BLTUC if rs != 0 && rs != rt
92809467b48Spatrick
92909467b48Spatrick InsnType Rs = fieldFromInstruction(insn, 21, 5);
93009467b48Spatrick InsnType Rt = fieldFromInstruction(insn, 16, 5);
93109467b48Spatrick int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
93209467b48Spatrick bool HasRs = false;
93309467b48Spatrick bool HasRt = false;
93409467b48Spatrick
93509467b48Spatrick if (Rt == 0) {
93609467b48Spatrick MI.setOpcode(Mips::BGTZ);
93709467b48Spatrick HasRs = true;
93809467b48Spatrick } else if (Rs == 0) {
93909467b48Spatrick MI.setOpcode(Mips::BGTZALC);
94009467b48Spatrick HasRt = true;
94109467b48Spatrick } else if (Rs == Rt) {
94209467b48Spatrick MI.setOpcode(Mips::BLTZALC);
94309467b48Spatrick HasRs = true;
94409467b48Spatrick } else {
94509467b48Spatrick MI.setOpcode(Mips::BLTUC);
94609467b48Spatrick HasRs = true;
94709467b48Spatrick HasRt = true;
94809467b48Spatrick }
94909467b48Spatrick
95009467b48Spatrick if (HasRs)
95109467b48Spatrick MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
95209467b48Spatrick Rs)));
95309467b48Spatrick
95409467b48Spatrick if (HasRt)
95509467b48Spatrick MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
95609467b48Spatrick Rt)));
95709467b48Spatrick
95809467b48Spatrick MI.addOperand(MCOperand::createImm(Imm));
95909467b48Spatrick
96009467b48Spatrick return MCDisassembler::Success;
96109467b48Spatrick }
96209467b48Spatrick
96309467b48Spatrick template <typename InsnType>
DecodeBlezGroupBranch(MCInst & MI,InsnType insn,uint64_t Address,const MCDisassembler * Decoder)96409467b48Spatrick static DecodeStatus DecodeBlezGroupBranch(MCInst &MI, InsnType insn,
96509467b48Spatrick uint64_t Address,
966*d415bd75Srobert const MCDisassembler *Decoder) {
96709467b48Spatrick // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
96809467b48Spatrick // (otherwise we would have matched the BLEZL instruction from the earlier
96909467b48Spatrick // ISA's instead).
97009467b48Spatrick //
97109467b48Spatrick // We have:
97209467b48Spatrick // 0b000110 sssss ttttt iiiiiiiiiiiiiiii
97309467b48Spatrick // Invalid if rs == 0
97409467b48Spatrick // BLEZALC if rs == 0 && rt != 0
97509467b48Spatrick // BGEZALC if rs == rt && rt != 0
97609467b48Spatrick // BGEUC if rs != rt && rs != 0 && rt != 0
97709467b48Spatrick
97809467b48Spatrick InsnType Rs = fieldFromInstruction(insn, 21, 5);
97909467b48Spatrick InsnType Rt = fieldFromInstruction(insn, 16, 5);
98009467b48Spatrick int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
98109467b48Spatrick bool HasRs = false;
98209467b48Spatrick
98309467b48Spatrick if (Rt == 0)
98409467b48Spatrick return MCDisassembler::Fail;
98509467b48Spatrick else if (Rs == 0)
98609467b48Spatrick MI.setOpcode(Mips::BLEZALC);
98709467b48Spatrick else if (Rs == Rt)
98809467b48Spatrick MI.setOpcode(Mips::BGEZALC);
98909467b48Spatrick else {
99009467b48Spatrick HasRs = true;
99109467b48Spatrick MI.setOpcode(Mips::BGEUC);
99209467b48Spatrick }
99309467b48Spatrick
99409467b48Spatrick if (HasRs)
99509467b48Spatrick MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
99609467b48Spatrick Rs)));
99709467b48Spatrick MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
99809467b48Spatrick Rt)));
99909467b48Spatrick
100009467b48Spatrick MI.addOperand(MCOperand::createImm(Imm));
100109467b48Spatrick
100209467b48Spatrick return MCDisassembler::Success;
100309467b48Spatrick }
100409467b48Spatrick
100509467b48Spatrick // Override the generated disassembler to produce DEXT all the time. This is
100609467b48Spatrick // for feature / behaviour parity with binutils.
100709467b48Spatrick template <typename InsnType>
DecodeDEXT(MCInst & MI,InsnType Insn,uint64_t Address,const MCDisassembler * Decoder)100809467b48Spatrick static DecodeStatus DecodeDEXT(MCInst &MI, InsnType Insn, uint64_t Address,
1009*d415bd75Srobert const MCDisassembler *Decoder) {
101009467b48Spatrick unsigned Msbd = fieldFromInstruction(Insn, 11, 5);
101109467b48Spatrick unsigned Lsb = fieldFromInstruction(Insn, 6, 5);
101209467b48Spatrick unsigned Size = 0;
101309467b48Spatrick unsigned Pos = 0;
101409467b48Spatrick
101509467b48Spatrick switch (MI.getOpcode()) {
101609467b48Spatrick case Mips::DEXT:
101709467b48Spatrick Pos = Lsb;
101809467b48Spatrick Size = Msbd + 1;
101909467b48Spatrick break;
102009467b48Spatrick case Mips::DEXTM:
102109467b48Spatrick Pos = Lsb;
102209467b48Spatrick Size = Msbd + 1 + 32;
102309467b48Spatrick break;
102409467b48Spatrick case Mips::DEXTU:
102509467b48Spatrick Pos = Lsb + 32;
102609467b48Spatrick Size = Msbd + 1;
102709467b48Spatrick break;
102809467b48Spatrick default:
102909467b48Spatrick llvm_unreachable("Unknown DEXT instruction!");
103009467b48Spatrick }
103109467b48Spatrick
103209467b48Spatrick MI.setOpcode(Mips::DEXT);
103309467b48Spatrick
103409467b48Spatrick InsnType Rs = fieldFromInstruction(Insn, 21, 5);
103509467b48Spatrick InsnType Rt = fieldFromInstruction(Insn, 16, 5);
103609467b48Spatrick
103709467b48Spatrick MI.addOperand(
103809467b48Spatrick MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID, Rt)));
103909467b48Spatrick MI.addOperand(
104009467b48Spatrick MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID, Rs)));
104109467b48Spatrick MI.addOperand(MCOperand::createImm(Pos));
104209467b48Spatrick MI.addOperand(MCOperand::createImm(Size));
104309467b48Spatrick
104409467b48Spatrick return MCDisassembler::Success;
104509467b48Spatrick }
104609467b48Spatrick
104709467b48Spatrick // Override the generated disassembler to produce DINS all the time. This is
104809467b48Spatrick // for feature / behaviour parity with binutils.
104909467b48Spatrick template <typename InsnType>
DecodeDINS(MCInst & MI,InsnType Insn,uint64_t Address,const MCDisassembler * Decoder)105009467b48Spatrick static DecodeStatus DecodeDINS(MCInst &MI, InsnType Insn, uint64_t Address,
1051*d415bd75Srobert const MCDisassembler *Decoder) {
105209467b48Spatrick unsigned Msbd = fieldFromInstruction(Insn, 11, 5);
105309467b48Spatrick unsigned Lsb = fieldFromInstruction(Insn, 6, 5);
105409467b48Spatrick unsigned Size = 0;
105509467b48Spatrick unsigned Pos = 0;
105609467b48Spatrick
105709467b48Spatrick switch (MI.getOpcode()) {
105809467b48Spatrick case Mips::DINS:
105909467b48Spatrick Pos = Lsb;
106009467b48Spatrick Size = Msbd + 1 - Pos;
106109467b48Spatrick break;
106209467b48Spatrick case Mips::DINSM:
106309467b48Spatrick Pos = Lsb;
106409467b48Spatrick Size = Msbd + 33 - Pos;
106509467b48Spatrick break;
106609467b48Spatrick case Mips::DINSU:
106709467b48Spatrick Pos = Lsb + 32;
106809467b48Spatrick // mbsd = pos + size - 33
106909467b48Spatrick // mbsd - pos + 33 = size
107009467b48Spatrick Size = Msbd + 33 - Pos;
107109467b48Spatrick break;
107209467b48Spatrick default:
107309467b48Spatrick llvm_unreachable("Unknown DINS instruction!");
107409467b48Spatrick }
107509467b48Spatrick
107609467b48Spatrick InsnType Rs = fieldFromInstruction(Insn, 21, 5);
107709467b48Spatrick InsnType Rt = fieldFromInstruction(Insn, 16, 5);
107809467b48Spatrick
107909467b48Spatrick MI.setOpcode(Mips::DINS);
108009467b48Spatrick MI.addOperand(
108109467b48Spatrick MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID, Rt)));
108209467b48Spatrick MI.addOperand(
108309467b48Spatrick MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID, Rs)));
108409467b48Spatrick MI.addOperand(MCOperand::createImm(Pos));
108509467b48Spatrick MI.addOperand(MCOperand::createImm(Size));
108609467b48Spatrick
108709467b48Spatrick return MCDisassembler::Success;
108809467b48Spatrick }
108909467b48Spatrick
109009467b48Spatrick // Auto-generated decoder wouldn't add the third operand for CRC32*.
109109467b48Spatrick template <typename InsnType>
DecodeCRC(MCInst & MI,InsnType Insn,uint64_t Address,const MCDisassembler * Decoder)109209467b48Spatrick static DecodeStatus DecodeCRC(MCInst &MI, InsnType Insn, uint64_t Address,
1093*d415bd75Srobert const MCDisassembler *Decoder) {
109409467b48Spatrick InsnType Rs = fieldFromInstruction(Insn, 21, 5);
109509467b48Spatrick InsnType Rt = fieldFromInstruction(Insn, 16, 5);
109609467b48Spatrick MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
109709467b48Spatrick Rt)));
109809467b48Spatrick MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
109909467b48Spatrick Rs)));
110009467b48Spatrick MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
110109467b48Spatrick Rt)));
110209467b48Spatrick return MCDisassembler::Success;
110309467b48Spatrick }
110409467b48Spatrick
110509467b48Spatrick /// Read two bytes from the ArrayRef and return 16 bit halfword sorted
110609467b48Spatrick /// according to the given endianness.
readInstruction16(ArrayRef<uint8_t> Bytes,uint64_t Address,uint64_t & Size,uint32_t & Insn,bool IsBigEndian)110709467b48Spatrick static DecodeStatus readInstruction16(ArrayRef<uint8_t> Bytes, uint64_t Address,
110809467b48Spatrick uint64_t &Size, uint32_t &Insn,
110909467b48Spatrick bool IsBigEndian) {
111009467b48Spatrick // We want to read exactly 2 Bytes of data.
111109467b48Spatrick if (Bytes.size() < 2) {
111209467b48Spatrick Size = 0;
111309467b48Spatrick return MCDisassembler::Fail;
111409467b48Spatrick }
111509467b48Spatrick
111609467b48Spatrick if (IsBigEndian) {
111709467b48Spatrick Insn = (Bytes[0] << 8) | Bytes[1];
111809467b48Spatrick } else {
111909467b48Spatrick Insn = (Bytes[1] << 8) | Bytes[0];
112009467b48Spatrick }
112109467b48Spatrick
112209467b48Spatrick return MCDisassembler::Success;
112309467b48Spatrick }
112409467b48Spatrick
112509467b48Spatrick /// Read four bytes from the ArrayRef and return 32 bit word sorted
112609467b48Spatrick /// according to the given endianness.
readInstruction32(ArrayRef<uint8_t> Bytes,uint64_t Address,uint64_t & Size,uint32_t & Insn,bool IsBigEndian,bool IsMicroMips)112709467b48Spatrick static DecodeStatus readInstruction32(ArrayRef<uint8_t> Bytes, uint64_t Address,
112809467b48Spatrick uint64_t &Size, uint32_t &Insn,
112909467b48Spatrick bool IsBigEndian, bool IsMicroMips) {
113009467b48Spatrick // We want to read exactly 4 Bytes of data.
113109467b48Spatrick if (Bytes.size() < 4) {
113209467b48Spatrick Size = 0;
113309467b48Spatrick return MCDisassembler::Fail;
113409467b48Spatrick }
113509467b48Spatrick
113609467b48Spatrick // High 16 bits of a 32-bit microMIPS instruction (where the opcode is)
113709467b48Spatrick // always precede the low 16 bits in the instruction stream (that is, they
113809467b48Spatrick // are placed at lower addresses in the instruction stream).
113909467b48Spatrick //
114009467b48Spatrick // microMIPS byte ordering:
114109467b48Spatrick // Big-endian: 0 | 1 | 2 | 3
114209467b48Spatrick // Little-endian: 1 | 0 | 3 | 2
114309467b48Spatrick
114409467b48Spatrick if (IsBigEndian) {
114509467b48Spatrick // Encoded as a big-endian 32-bit word in the stream.
114609467b48Spatrick Insn =
114709467b48Spatrick (Bytes[3] << 0) | (Bytes[2] << 8) | (Bytes[1] << 16) | (Bytes[0] << 24);
114809467b48Spatrick } else {
114909467b48Spatrick if (IsMicroMips) {
115009467b48Spatrick Insn = (Bytes[2] << 0) | (Bytes[3] << 8) | (Bytes[0] << 16) |
115109467b48Spatrick (Bytes[1] << 24);
115209467b48Spatrick } else {
115309467b48Spatrick Insn = (Bytes[0] << 0) | (Bytes[1] << 8) | (Bytes[2] << 16) |
115409467b48Spatrick (Bytes[3] << 24);
115509467b48Spatrick }
115609467b48Spatrick }
115709467b48Spatrick
115809467b48Spatrick return MCDisassembler::Success;
115909467b48Spatrick }
116009467b48Spatrick
getInstruction(MCInst & Instr,uint64_t & Size,ArrayRef<uint8_t> Bytes,uint64_t Address,raw_ostream & CStream) const116109467b48Spatrick DecodeStatus MipsDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,
116209467b48Spatrick ArrayRef<uint8_t> Bytes,
116309467b48Spatrick uint64_t Address,
116409467b48Spatrick raw_ostream &CStream) const {
116509467b48Spatrick uint32_t Insn;
116609467b48Spatrick DecodeStatus Result;
116709467b48Spatrick Size = 0;
116809467b48Spatrick
116909467b48Spatrick if (IsMicroMips) {
117009467b48Spatrick Result = readInstruction16(Bytes, Address, Size, Insn, IsBigEndian);
117109467b48Spatrick if (Result == MCDisassembler::Fail)
117209467b48Spatrick return MCDisassembler::Fail;
117309467b48Spatrick
117409467b48Spatrick if (hasMips32r6()) {
117509467b48Spatrick LLVM_DEBUG(
117609467b48Spatrick dbgs() << "Trying MicroMipsR616 table (16-bit instructions):\n");
117709467b48Spatrick // Calling the auto-generated decoder function for microMIPS32R6
117809467b48Spatrick // 16-bit instructions.
117909467b48Spatrick Result = decodeInstruction(DecoderTableMicroMipsR616, Instr, Insn,
118009467b48Spatrick Address, this, STI);
118109467b48Spatrick if (Result != MCDisassembler::Fail) {
118209467b48Spatrick Size = 2;
118309467b48Spatrick return Result;
118409467b48Spatrick }
118509467b48Spatrick }
118609467b48Spatrick
118709467b48Spatrick LLVM_DEBUG(dbgs() << "Trying MicroMips16 table (16-bit instructions):\n");
118809467b48Spatrick // Calling the auto-generated decoder function for microMIPS 16-bit
118909467b48Spatrick // instructions.
119009467b48Spatrick Result = decodeInstruction(DecoderTableMicroMips16, Instr, Insn, Address,
119109467b48Spatrick this, STI);
119209467b48Spatrick if (Result != MCDisassembler::Fail) {
119309467b48Spatrick Size = 2;
119409467b48Spatrick return Result;
119509467b48Spatrick }
119609467b48Spatrick
119709467b48Spatrick Result = readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, true);
119809467b48Spatrick if (Result == MCDisassembler::Fail)
119909467b48Spatrick return MCDisassembler::Fail;
120009467b48Spatrick
120109467b48Spatrick if (hasMips32r6()) {
120209467b48Spatrick LLVM_DEBUG(
120309467b48Spatrick dbgs() << "Trying MicroMips32r632 table (32-bit instructions):\n");
120409467b48Spatrick // Calling the auto-generated decoder function.
120509467b48Spatrick Result = decodeInstruction(DecoderTableMicroMipsR632, Instr, Insn,
120609467b48Spatrick Address, this, STI);
120709467b48Spatrick if (Result != MCDisassembler::Fail) {
120809467b48Spatrick Size = 4;
120909467b48Spatrick return Result;
121009467b48Spatrick }
121109467b48Spatrick }
121209467b48Spatrick
121309467b48Spatrick LLVM_DEBUG(dbgs() << "Trying MicroMips32 table (32-bit instructions):\n");
121409467b48Spatrick // Calling the auto-generated decoder function.
121509467b48Spatrick Result = decodeInstruction(DecoderTableMicroMips32, Instr, Insn, Address,
121609467b48Spatrick this, STI);
121709467b48Spatrick if (Result != MCDisassembler::Fail) {
121809467b48Spatrick Size = 4;
121909467b48Spatrick return Result;
122009467b48Spatrick }
122109467b48Spatrick
122209467b48Spatrick if (isFP64()) {
122309467b48Spatrick LLVM_DEBUG(dbgs() << "Trying MicroMipsFP64 table (32-bit opcodes):\n");
122409467b48Spatrick Result = decodeInstruction(DecoderTableMicroMipsFP6432, Instr, Insn,
122509467b48Spatrick Address, this, STI);
122609467b48Spatrick if (Result != MCDisassembler::Fail) {
122709467b48Spatrick Size = 4;
122809467b48Spatrick return Result;
122909467b48Spatrick }
123009467b48Spatrick }
123109467b48Spatrick
123209467b48Spatrick // This is an invalid instruction. Claim that the Size is 2 bytes. Since
123309467b48Spatrick // microMIPS instructions have a minimum alignment of 2, the next 2 bytes
123409467b48Spatrick // could form a valid instruction. The two bytes we rejected as an
123509467b48Spatrick // instruction could have actually beeen an inline constant pool that is
123609467b48Spatrick // unconditionally branched over.
123709467b48Spatrick Size = 2;
123809467b48Spatrick return MCDisassembler::Fail;
123909467b48Spatrick }
124009467b48Spatrick
124109467b48Spatrick // Attempt to read the instruction so that we can attempt to decode it. If
124209467b48Spatrick // the buffer is not 4 bytes long, let the higher level logic figure out
124309467b48Spatrick // what to do with a size of zero and MCDisassembler::Fail.
124409467b48Spatrick Result = readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, false);
124509467b48Spatrick if (Result == MCDisassembler::Fail)
124609467b48Spatrick return MCDisassembler::Fail;
124709467b48Spatrick
124809467b48Spatrick // The only instruction size for standard encoded MIPS.
124909467b48Spatrick Size = 4;
125009467b48Spatrick
125109467b48Spatrick if (hasCOP3()) {
125209467b48Spatrick LLVM_DEBUG(dbgs() << "Trying COP3_ table (32-bit opcodes):\n");
125309467b48Spatrick Result =
125409467b48Spatrick decodeInstruction(DecoderTableCOP3_32, Instr, Insn, Address, this, STI);
125509467b48Spatrick if (Result != MCDisassembler::Fail)
125609467b48Spatrick return Result;
125709467b48Spatrick }
125809467b48Spatrick
125909467b48Spatrick if (hasMips32r6() && isGP64()) {
126009467b48Spatrick LLVM_DEBUG(
126109467b48Spatrick dbgs() << "Trying Mips32r6_64r6 (GPR64) table (32-bit opcodes):\n");
126209467b48Spatrick Result = decodeInstruction(DecoderTableMips32r6_64r6_GP6432, Instr, Insn,
126309467b48Spatrick Address, this, STI);
126409467b48Spatrick if (Result != MCDisassembler::Fail)
126509467b48Spatrick return Result;
126609467b48Spatrick }
126709467b48Spatrick
126809467b48Spatrick if (hasMips32r6() && isPTR64()) {
126909467b48Spatrick LLVM_DEBUG(
127009467b48Spatrick dbgs() << "Trying Mips32r6_64r6 (PTR64) table (32-bit opcodes):\n");
127109467b48Spatrick Result = decodeInstruction(DecoderTableMips32r6_64r6_PTR6432, Instr, Insn,
127209467b48Spatrick Address, this, STI);
127309467b48Spatrick if (Result != MCDisassembler::Fail)
127409467b48Spatrick return Result;
127509467b48Spatrick }
127609467b48Spatrick
127709467b48Spatrick if (hasMips32r6()) {
127809467b48Spatrick LLVM_DEBUG(dbgs() << "Trying Mips32r6_64r6 table (32-bit opcodes):\n");
127909467b48Spatrick Result = decodeInstruction(DecoderTableMips32r6_64r632, Instr, Insn,
128009467b48Spatrick Address, this, STI);
128109467b48Spatrick if (Result != MCDisassembler::Fail)
128209467b48Spatrick return Result;
128309467b48Spatrick }
128409467b48Spatrick
128509467b48Spatrick if (hasMips2() && isPTR64()) {
128609467b48Spatrick LLVM_DEBUG(
128709467b48Spatrick dbgs() << "Trying Mips32r6_64r6 (PTR64) table (32-bit opcodes):\n");
128809467b48Spatrick Result = decodeInstruction(DecoderTableMips32_64_PTR6432, Instr, Insn,
128909467b48Spatrick Address, this, STI);
129009467b48Spatrick if (Result != MCDisassembler::Fail)
129109467b48Spatrick return Result;
129209467b48Spatrick }
129309467b48Spatrick
129409467b48Spatrick if (hasCnMips()) {
129509467b48Spatrick LLVM_DEBUG(dbgs() << "Trying CnMips table (32-bit opcodes):\n");
129609467b48Spatrick Result = decodeInstruction(DecoderTableCnMips32, Instr, Insn,
129709467b48Spatrick Address, this, STI);
129809467b48Spatrick if (Result != MCDisassembler::Fail)
129909467b48Spatrick return Result;
130009467b48Spatrick }
130109467b48Spatrick
130209467b48Spatrick if (hasCnMipsP()) {
130309467b48Spatrick LLVM_DEBUG(dbgs() << "Trying CnMipsP table (32-bit opcodes):\n");
130409467b48Spatrick Result = decodeInstruction(DecoderTableCnMipsP32, Instr, Insn,
130509467b48Spatrick Address, this, STI);
130609467b48Spatrick if (Result != MCDisassembler::Fail)
130709467b48Spatrick return Result;
130809467b48Spatrick }
130909467b48Spatrick
131009467b48Spatrick if (isGP64()) {
131109467b48Spatrick LLVM_DEBUG(dbgs() << "Trying Mips64 (GPR64) table (32-bit opcodes):\n");
131209467b48Spatrick Result = decodeInstruction(DecoderTableMips6432, Instr, Insn,
131309467b48Spatrick Address, this, STI);
131409467b48Spatrick if (Result != MCDisassembler::Fail)
131509467b48Spatrick return Result;
131609467b48Spatrick }
131709467b48Spatrick
131809467b48Spatrick if (isFP64()) {
131909467b48Spatrick LLVM_DEBUG(
132009467b48Spatrick dbgs() << "Trying MipsFP64 (64 bit FPU) table (32-bit opcodes):\n");
132109467b48Spatrick Result = decodeInstruction(DecoderTableMipsFP6432, Instr, Insn,
132209467b48Spatrick Address, this, STI);
132309467b48Spatrick if (Result != MCDisassembler::Fail)
132409467b48Spatrick return Result;
132509467b48Spatrick }
132609467b48Spatrick
132709467b48Spatrick LLVM_DEBUG(dbgs() << "Trying Mips table (32-bit opcodes):\n");
132809467b48Spatrick // Calling the auto-generated decoder function.
132909467b48Spatrick Result =
133009467b48Spatrick decodeInstruction(DecoderTableMips32, Instr, Insn, Address, this, STI);
133109467b48Spatrick if (Result != MCDisassembler::Fail)
133209467b48Spatrick return Result;
133309467b48Spatrick
133409467b48Spatrick return MCDisassembler::Fail;
133509467b48Spatrick }
133609467b48Spatrick
1337*d415bd75Srobert static DecodeStatus
DecodeCPU16RegsRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)1338*d415bd75Srobert DecodeCPU16RegsRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address,
1339*d415bd75Srobert const MCDisassembler *Decoder) {
134009467b48Spatrick return MCDisassembler::Fail;
134109467b48Spatrick }
134209467b48Spatrick
DecodeGPR64RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)1343*d415bd75Srobert static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst, unsigned RegNo,
134409467b48Spatrick uint64_t Address,
1345*d415bd75Srobert const MCDisassembler *Decoder) {
134609467b48Spatrick if (RegNo > 31)
134709467b48Spatrick return MCDisassembler::Fail;
134809467b48Spatrick
134909467b48Spatrick unsigned Reg = getReg(Decoder, Mips::GPR64RegClassID, RegNo);
135009467b48Spatrick Inst.addOperand(MCOperand::createReg(Reg));
135109467b48Spatrick return MCDisassembler::Success;
135209467b48Spatrick }
135309467b48Spatrick
DecodeGPRMM16RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)1354*d415bd75Srobert static DecodeStatus DecodeGPRMM16RegisterClass(MCInst &Inst, unsigned RegNo,
135509467b48Spatrick uint64_t Address,
1356*d415bd75Srobert const MCDisassembler *Decoder) {
135709467b48Spatrick if (RegNo > 7)
135809467b48Spatrick return MCDisassembler::Fail;
135909467b48Spatrick unsigned Reg = getReg(Decoder, Mips::GPRMM16RegClassID, RegNo);
136009467b48Spatrick Inst.addOperand(MCOperand::createReg(Reg));
136109467b48Spatrick return MCDisassembler::Success;
136209467b48Spatrick }
136309467b48Spatrick
1364*d415bd75Srobert static DecodeStatus
DecodeGPRMM16ZeroRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)1365*d415bd75Srobert DecodeGPRMM16ZeroRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address,
1366*d415bd75Srobert const MCDisassembler *Decoder) {
136709467b48Spatrick if (RegNo > 7)
136809467b48Spatrick return MCDisassembler::Fail;
136909467b48Spatrick unsigned Reg = getReg(Decoder, Mips::GPRMM16ZeroRegClassID, RegNo);
137009467b48Spatrick Inst.addOperand(MCOperand::createReg(Reg));
137109467b48Spatrick return MCDisassembler::Success;
137209467b48Spatrick }
137309467b48Spatrick
1374*d415bd75Srobert static DecodeStatus
DecodeGPRMM16MovePRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)1375*d415bd75Srobert DecodeGPRMM16MovePRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address,
1376*d415bd75Srobert const MCDisassembler *Decoder) {
137709467b48Spatrick if (RegNo > 7)
137809467b48Spatrick return MCDisassembler::Fail;
137909467b48Spatrick unsigned Reg = getReg(Decoder, Mips::GPRMM16MovePRegClassID, RegNo);
138009467b48Spatrick Inst.addOperand(MCOperand::createReg(Reg));
138109467b48Spatrick return MCDisassembler::Success;
138209467b48Spatrick }
138309467b48Spatrick
DecodeGPR32RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)1384*d415bd75Srobert static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst, unsigned RegNo,
138509467b48Spatrick uint64_t Address,
1386*d415bd75Srobert const MCDisassembler *Decoder) {
138709467b48Spatrick if (RegNo > 31)
138809467b48Spatrick return MCDisassembler::Fail;
138909467b48Spatrick unsigned Reg = getReg(Decoder, Mips::GPR32RegClassID, RegNo);
139009467b48Spatrick Inst.addOperand(MCOperand::createReg(Reg));
139109467b48Spatrick return MCDisassembler::Success;
139209467b48Spatrick }
139309467b48Spatrick
DecodePtrRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)1394*d415bd75Srobert static DecodeStatus DecodePtrRegisterClass(MCInst &Inst, unsigned RegNo,
139509467b48Spatrick uint64_t Address,
1396*d415bd75Srobert const MCDisassembler *Decoder) {
139709467b48Spatrick if (static_cast<const MipsDisassembler *>(Decoder)->isGP64())
139809467b48Spatrick return DecodeGPR64RegisterClass(Inst, RegNo, Address, Decoder);
139909467b48Spatrick
140009467b48Spatrick return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
140109467b48Spatrick }
140209467b48Spatrick
DecodeDSPRRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)1403*d415bd75Srobert static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst, unsigned RegNo,
140409467b48Spatrick uint64_t Address,
1405*d415bd75Srobert const MCDisassembler *Decoder) {
140609467b48Spatrick return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
140709467b48Spatrick }
140809467b48Spatrick
DecodeFGR64RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)1409*d415bd75Srobert static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst, unsigned RegNo,
141009467b48Spatrick uint64_t Address,
1411*d415bd75Srobert const MCDisassembler *Decoder) {
141209467b48Spatrick if (RegNo > 31)
141309467b48Spatrick return MCDisassembler::Fail;
141409467b48Spatrick
141509467b48Spatrick unsigned Reg = getReg(Decoder, Mips::FGR64RegClassID, RegNo);
141609467b48Spatrick Inst.addOperand(MCOperand::createReg(Reg));
141709467b48Spatrick return MCDisassembler::Success;
141809467b48Spatrick }
141909467b48Spatrick
DecodeFGR32RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)1420*d415bd75Srobert static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst, unsigned RegNo,
142109467b48Spatrick uint64_t Address,
1422*d415bd75Srobert const MCDisassembler *Decoder) {
142309467b48Spatrick if (RegNo > 31)
142409467b48Spatrick return MCDisassembler::Fail;
142509467b48Spatrick
142609467b48Spatrick unsigned Reg = getReg(Decoder, Mips::FGR32RegClassID, RegNo);
142709467b48Spatrick Inst.addOperand(MCOperand::createReg(Reg));
142809467b48Spatrick return MCDisassembler::Success;
142909467b48Spatrick }
143009467b48Spatrick
DecodeCCRRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)1431*d415bd75Srobert static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst, unsigned RegNo,
143209467b48Spatrick uint64_t Address,
1433*d415bd75Srobert const MCDisassembler *Decoder) {
143409467b48Spatrick if (RegNo > 31)
143509467b48Spatrick return MCDisassembler::Fail;
143609467b48Spatrick unsigned Reg = getReg(Decoder, Mips::CCRRegClassID, RegNo);
143709467b48Spatrick Inst.addOperand(MCOperand::createReg(Reg));
143809467b48Spatrick return MCDisassembler::Success;
143909467b48Spatrick }
144009467b48Spatrick
DecodeFCCRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)1441*d415bd75Srobert static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst, unsigned RegNo,
144209467b48Spatrick uint64_t Address,
1443*d415bd75Srobert const MCDisassembler *Decoder) {
144409467b48Spatrick if (RegNo > 7)
144509467b48Spatrick return MCDisassembler::Fail;
144609467b48Spatrick unsigned Reg = getReg(Decoder, Mips::FCCRegClassID, RegNo);
144709467b48Spatrick Inst.addOperand(MCOperand::createReg(Reg));
144809467b48Spatrick return MCDisassembler::Success;
144909467b48Spatrick }
145009467b48Spatrick
DecodeFGRCCRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)145109467b48Spatrick static DecodeStatus DecodeFGRCCRegisterClass(MCInst &Inst, unsigned RegNo,
145209467b48Spatrick uint64_t Address,
1453*d415bd75Srobert const MCDisassembler *Decoder) {
145409467b48Spatrick if (RegNo > 31)
145509467b48Spatrick return MCDisassembler::Fail;
145609467b48Spatrick
145709467b48Spatrick unsigned Reg = getReg(Decoder, Mips::FGRCCRegClassID, RegNo);
145809467b48Spatrick Inst.addOperand(MCOperand::createReg(Reg));
145909467b48Spatrick return MCDisassembler::Success;
146009467b48Spatrick }
146109467b48Spatrick
DecodeMem(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)1462*d415bd75Srobert static DecodeStatus DecodeMem(MCInst &Inst, unsigned Insn, uint64_t Address,
1463*d415bd75Srobert const MCDisassembler *Decoder) {
146409467b48Spatrick int Offset = SignExtend32<16>(Insn & 0xffff);
146509467b48Spatrick unsigned Reg = fieldFromInstruction(Insn, 16, 5);
146609467b48Spatrick unsigned Base = fieldFromInstruction(Insn, 21, 5);
146709467b48Spatrick
146809467b48Spatrick Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
146909467b48Spatrick Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
147009467b48Spatrick
147109467b48Spatrick if (Inst.getOpcode() == Mips::SC ||
147209467b48Spatrick Inst.getOpcode() == Mips::SCD)
147309467b48Spatrick Inst.addOperand(MCOperand::createReg(Reg));
147409467b48Spatrick
147509467b48Spatrick Inst.addOperand(MCOperand::createReg(Reg));
147609467b48Spatrick Inst.addOperand(MCOperand::createReg(Base));
147709467b48Spatrick Inst.addOperand(MCOperand::createImm(Offset));
147809467b48Spatrick
147909467b48Spatrick return MCDisassembler::Success;
148009467b48Spatrick }
148109467b48Spatrick
DecodeMemEVA(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)1482*d415bd75Srobert static DecodeStatus DecodeMemEVA(MCInst &Inst, unsigned Insn, uint64_t Address,
1483*d415bd75Srobert const MCDisassembler *Decoder) {
148409467b48Spatrick int Offset = SignExtend32<9>(Insn >> 7);
148509467b48Spatrick unsigned Reg = fieldFromInstruction(Insn, 16, 5);
148609467b48Spatrick unsigned Base = fieldFromInstruction(Insn, 21, 5);
148709467b48Spatrick
148809467b48Spatrick Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
148909467b48Spatrick Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
149009467b48Spatrick
149109467b48Spatrick if (Inst.getOpcode() == Mips::SCE)
149209467b48Spatrick Inst.addOperand(MCOperand::createReg(Reg));
149309467b48Spatrick
149409467b48Spatrick Inst.addOperand(MCOperand::createReg(Reg));
149509467b48Spatrick Inst.addOperand(MCOperand::createReg(Base));
149609467b48Spatrick Inst.addOperand(MCOperand::createImm(Offset));
149709467b48Spatrick
149809467b48Spatrick return MCDisassembler::Success;
149909467b48Spatrick }
150009467b48Spatrick
DecodeLoadByte15(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)1501*d415bd75Srobert static DecodeStatus DecodeLoadByte15(MCInst &Inst, unsigned Insn,
150209467b48Spatrick uint64_t Address,
1503*d415bd75Srobert const MCDisassembler *Decoder) {
150409467b48Spatrick int Offset = SignExtend32<16>(Insn & 0xffff);
150509467b48Spatrick unsigned Base = fieldFromInstruction(Insn, 16, 5);
150609467b48Spatrick unsigned Reg = fieldFromInstruction(Insn, 21, 5);
150709467b48Spatrick
150809467b48Spatrick Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
150909467b48Spatrick Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
151009467b48Spatrick
151109467b48Spatrick Inst.addOperand(MCOperand::createReg(Reg));
151209467b48Spatrick Inst.addOperand(MCOperand::createReg(Base));
151309467b48Spatrick Inst.addOperand(MCOperand::createImm(Offset));
151409467b48Spatrick
151509467b48Spatrick return MCDisassembler::Success;
151609467b48Spatrick }
151709467b48Spatrick
DecodeCacheOp(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)1518*d415bd75Srobert static DecodeStatus DecodeCacheOp(MCInst &Inst, unsigned Insn, uint64_t Address,
1519*d415bd75Srobert const MCDisassembler *Decoder) {
152009467b48Spatrick int Offset = SignExtend32<16>(Insn & 0xffff);
152109467b48Spatrick unsigned Hint = fieldFromInstruction(Insn, 16, 5);
152209467b48Spatrick unsigned Base = fieldFromInstruction(Insn, 21, 5);
152309467b48Spatrick
152409467b48Spatrick Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
152509467b48Spatrick
152609467b48Spatrick Inst.addOperand(MCOperand::createReg(Base));
152709467b48Spatrick Inst.addOperand(MCOperand::createImm(Offset));
152809467b48Spatrick Inst.addOperand(MCOperand::createImm(Hint));
152909467b48Spatrick
153009467b48Spatrick return MCDisassembler::Success;
153109467b48Spatrick }
153209467b48Spatrick
DecodeCacheOpMM(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)1533*d415bd75Srobert static DecodeStatus DecodeCacheOpMM(MCInst &Inst, unsigned Insn,
153409467b48Spatrick uint64_t Address,
1535*d415bd75Srobert const MCDisassembler *Decoder) {
153609467b48Spatrick int Offset = SignExtend32<12>(Insn & 0xfff);
153709467b48Spatrick unsigned Base = fieldFromInstruction(Insn, 16, 5);
153809467b48Spatrick unsigned Hint = fieldFromInstruction(Insn, 21, 5);
153909467b48Spatrick
154009467b48Spatrick Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
154109467b48Spatrick
154209467b48Spatrick Inst.addOperand(MCOperand::createReg(Base));
154309467b48Spatrick Inst.addOperand(MCOperand::createImm(Offset));
154409467b48Spatrick Inst.addOperand(MCOperand::createImm(Hint));
154509467b48Spatrick
154609467b48Spatrick return MCDisassembler::Success;
154709467b48Spatrick }
154809467b48Spatrick
DecodePrefeOpMM(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)1549*d415bd75Srobert static DecodeStatus DecodePrefeOpMM(MCInst &Inst, unsigned Insn,
155009467b48Spatrick uint64_t Address,
1551*d415bd75Srobert const MCDisassembler *Decoder) {
155209467b48Spatrick int Offset = SignExtend32<9>(Insn & 0x1ff);
155309467b48Spatrick unsigned Base = fieldFromInstruction(Insn, 16, 5);
155409467b48Spatrick unsigned Hint = fieldFromInstruction(Insn, 21, 5);
155509467b48Spatrick
155609467b48Spatrick Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
155709467b48Spatrick
155809467b48Spatrick Inst.addOperand(MCOperand::createReg(Base));
155909467b48Spatrick Inst.addOperand(MCOperand::createImm(Offset));
156009467b48Spatrick Inst.addOperand(MCOperand::createImm(Hint));
156109467b48Spatrick
156209467b48Spatrick return MCDisassembler::Success;
156309467b48Spatrick }
156409467b48Spatrick
DecodeCacheeOp_CacheOpR6(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)1565*d415bd75Srobert static DecodeStatus DecodeCacheeOp_CacheOpR6(MCInst &Inst, unsigned Insn,
156609467b48Spatrick uint64_t Address,
1567*d415bd75Srobert const MCDisassembler *Decoder) {
156809467b48Spatrick int Offset = SignExtend32<9>(Insn >> 7);
156909467b48Spatrick unsigned Hint = fieldFromInstruction(Insn, 16, 5);
157009467b48Spatrick unsigned Base = fieldFromInstruction(Insn, 21, 5);
157109467b48Spatrick
157209467b48Spatrick Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
157309467b48Spatrick
157409467b48Spatrick Inst.addOperand(MCOperand::createReg(Base));
157509467b48Spatrick Inst.addOperand(MCOperand::createImm(Offset));
157609467b48Spatrick Inst.addOperand(MCOperand::createImm(Hint));
157709467b48Spatrick
157809467b48Spatrick return MCDisassembler::Success;
157909467b48Spatrick }
158009467b48Spatrick
DecodeSyncI(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)1581*d415bd75Srobert static DecodeStatus DecodeSyncI(MCInst &Inst, unsigned Insn, uint64_t Address,
1582*d415bd75Srobert const MCDisassembler *Decoder) {
158309467b48Spatrick int Offset = SignExtend32<16>(Insn & 0xffff);
158409467b48Spatrick unsigned Base = fieldFromInstruction(Insn, 21, 5);
158509467b48Spatrick
158609467b48Spatrick Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
158709467b48Spatrick
158809467b48Spatrick Inst.addOperand(MCOperand::createReg(Base));
158909467b48Spatrick Inst.addOperand(MCOperand::createImm(Offset));
159009467b48Spatrick
159109467b48Spatrick return MCDisassembler::Success;
159209467b48Spatrick }
159309467b48Spatrick
DecodeSyncI_MM(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)159409467b48Spatrick static DecodeStatus DecodeSyncI_MM(MCInst &Inst, unsigned Insn,
1595*d415bd75Srobert uint64_t Address,
1596*d415bd75Srobert const MCDisassembler *Decoder) {
159709467b48Spatrick int Offset = SignExtend32<16>(Insn & 0xffff);
159809467b48Spatrick unsigned Base = fieldFromInstruction(Insn, 16, 5);
159909467b48Spatrick
160009467b48Spatrick Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
160109467b48Spatrick
160209467b48Spatrick Inst.addOperand(MCOperand::createReg(Base));
160309467b48Spatrick Inst.addOperand(MCOperand::createImm(Offset));
160409467b48Spatrick
160509467b48Spatrick return MCDisassembler::Success;
160609467b48Spatrick }
160709467b48Spatrick
DecodeSynciR6(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)1608*d415bd75Srobert static DecodeStatus DecodeSynciR6(MCInst &Inst, unsigned Insn, uint64_t Address,
1609*d415bd75Srobert const MCDisassembler *Decoder) {
161009467b48Spatrick int Immediate = SignExtend32<16>(Insn & 0xffff);
161109467b48Spatrick unsigned Base = fieldFromInstruction(Insn, 16, 5);
161209467b48Spatrick
161309467b48Spatrick Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
161409467b48Spatrick
161509467b48Spatrick Inst.addOperand(MCOperand::createReg(Base));
161609467b48Spatrick Inst.addOperand(MCOperand::createImm(Immediate));
161709467b48Spatrick
161809467b48Spatrick return MCDisassembler::Success;
161909467b48Spatrick }
162009467b48Spatrick
DecodeMSA128Mem(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)162109467b48Spatrick static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn,
1622*d415bd75Srobert uint64_t Address,
1623*d415bd75Srobert const MCDisassembler *Decoder) {
162409467b48Spatrick int Offset = SignExtend32<10>(fieldFromInstruction(Insn, 16, 10));
162509467b48Spatrick unsigned Reg = fieldFromInstruction(Insn, 6, 5);
162609467b48Spatrick unsigned Base = fieldFromInstruction(Insn, 11, 5);
162709467b48Spatrick
162809467b48Spatrick Reg = getReg(Decoder, Mips::MSA128BRegClassID, Reg);
162909467b48Spatrick Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
163009467b48Spatrick
163109467b48Spatrick Inst.addOperand(MCOperand::createReg(Reg));
163209467b48Spatrick Inst.addOperand(MCOperand::createReg(Base));
163309467b48Spatrick
163409467b48Spatrick // The immediate field of an LD/ST instruction is scaled which means it must
163509467b48Spatrick // be multiplied (when decoding) by the size (in bytes) of the instructions'
163609467b48Spatrick // data format.
163709467b48Spatrick // .b - 1 byte
163809467b48Spatrick // .h - 2 bytes
163909467b48Spatrick // .w - 4 bytes
164009467b48Spatrick // .d - 8 bytes
164109467b48Spatrick switch(Inst.getOpcode())
164209467b48Spatrick {
164309467b48Spatrick default:
164409467b48Spatrick assert(false && "Unexpected instruction");
164509467b48Spatrick return MCDisassembler::Fail;
164609467b48Spatrick break;
164709467b48Spatrick case Mips::LD_B:
164809467b48Spatrick case Mips::ST_B:
164909467b48Spatrick Inst.addOperand(MCOperand::createImm(Offset));
165009467b48Spatrick break;
165109467b48Spatrick case Mips::LD_H:
165209467b48Spatrick case Mips::ST_H:
165309467b48Spatrick Inst.addOperand(MCOperand::createImm(Offset * 2));
165409467b48Spatrick break;
165509467b48Spatrick case Mips::LD_W:
165609467b48Spatrick case Mips::ST_W:
165709467b48Spatrick Inst.addOperand(MCOperand::createImm(Offset * 4));
165809467b48Spatrick break;
165909467b48Spatrick case Mips::LD_D:
166009467b48Spatrick case Mips::ST_D:
166109467b48Spatrick Inst.addOperand(MCOperand::createImm(Offset * 8));
166209467b48Spatrick break;
166309467b48Spatrick }
166409467b48Spatrick
166509467b48Spatrick return MCDisassembler::Success;
166609467b48Spatrick }
166709467b48Spatrick
DecodeMemMMImm4(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)1668*d415bd75Srobert static DecodeStatus DecodeMemMMImm4(MCInst &Inst, unsigned Insn,
166909467b48Spatrick uint64_t Address,
1670*d415bd75Srobert const MCDisassembler *Decoder) {
167109467b48Spatrick unsigned Offset = Insn & 0xf;
167209467b48Spatrick unsigned Reg = fieldFromInstruction(Insn, 7, 3);
167309467b48Spatrick unsigned Base = fieldFromInstruction(Insn, 4, 3);
167409467b48Spatrick
167509467b48Spatrick switch (Inst.getOpcode()) {
167609467b48Spatrick case Mips::LBU16_MM:
167709467b48Spatrick case Mips::LHU16_MM:
167809467b48Spatrick case Mips::LW16_MM:
167909467b48Spatrick if (DecodeGPRMM16RegisterClass(Inst, Reg, Address, Decoder)
168009467b48Spatrick == MCDisassembler::Fail)
168109467b48Spatrick return MCDisassembler::Fail;
168209467b48Spatrick break;
168309467b48Spatrick case Mips::SB16_MM:
168409467b48Spatrick case Mips::SB16_MMR6:
168509467b48Spatrick case Mips::SH16_MM:
168609467b48Spatrick case Mips::SH16_MMR6:
168709467b48Spatrick case Mips::SW16_MM:
168809467b48Spatrick case Mips::SW16_MMR6:
168909467b48Spatrick if (DecodeGPRMM16ZeroRegisterClass(Inst, Reg, Address, Decoder)
169009467b48Spatrick == MCDisassembler::Fail)
169109467b48Spatrick return MCDisassembler::Fail;
169209467b48Spatrick break;
169309467b48Spatrick }
169409467b48Spatrick
169509467b48Spatrick if (DecodeGPRMM16RegisterClass(Inst, Base, Address, Decoder)
169609467b48Spatrick == MCDisassembler::Fail)
169709467b48Spatrick return MCDisassembler::Fail;
169809467b48Spatrick
169909467b48Spatrick switch (Inst.getOpcode()) {
170009467b48Spatrick case Mips::LBU16_MM:
170109467b48Spatrick if (Offset == 0xf)
170209467b48Spatrick Inst.addOperand(MCOperand::createImm(-1));
170309467b48Spatrick else
170409467b48Spatrick Inst.addOperand(MCOperand::createImm(Offset));
170509467b48Spatrick break;
170609467b48Spatrick case Mips::SB16_MM:
170709467b48Spatrick case Mips::SB16_MMR6:
170809467b48Spatrick Inst.addOperand(MCOperand::createImm(Offset));
170909467b48Spatrick break;
171009467b48Spatrick case Mips::LHU16_MM:
171109467b48Spatrick case Mips::SH16_MM:
171209467b48Spatrick case Mips::SH16_MMR6:
171309467b48Spatrick Inst.addOperand(MCOperand::createImm(Offset << 1));
171409467b48Spatrick break;
171509467b48Spatrick case Mips::LW16_MM:
171609467b48Spatrick case Mips::SW16_MM:
171709467b48Spatrick case Mips::SW16_MMR6:
171809467b48Spatrick Inst.addOperand(MCOperand::createImm(Offset << 2));
171909467b48Spatrick break;
172009467b48Spatrick }
172109467b48Spatrick
172209467b48Spatrick return MCDisassembler::Success;
172309467b48Spatrick }
172409467b48Spatrick
DecodeMemMMSPImm5Lsl2(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)1725*d415bd75Srobert static DecodeStatus DecodeMemMMSPImm5Lsl2(MCInst &Inst, unsigned Insn,
172609467b48Spatrick uint64_t Address,
1727*d415bd75Srobert const MCDisassembler *Decoder) {
172809467b48Spatrick unsigned Offset = Insn & 0x1F;
172909467b48Spatrick unsigned Reg = fieldFromInstruction(Insn, 5, 5);
173009467b48Spatrick
173109467b48Spatrick Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
173209467b48Spatrick
173309467b48Spatrick Inst.addOperand(MCOperand::createReg(Reg));
173409467b48Spatrick Inst.addOperand(MCOperand::createReg(Mips::SP));
173509467b48Spatrick Inst.addOperand(MCOperand::createImm(Offset << 2));
173609467b48Spatrick
173709467b48Spatrick return MCDisassembler::Success;
173809467b48Spatrick }
173909467b48Spatrick
DecodeMemMMGPImm7Lsl2(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)1740*d415bd75Srobert static DecodeStatus DecodeMemMMGPImm7Lsl2(MCInst &Inst, unsigned Insn,
174109467b48Spatrick uint64_t Address,
1742*d415bd75Srobert const MCDisassembler *Decoder) {
174309467b48Spatrick unsigned Offset = Insn & 0x7F;
174409467b48Spatrick unsigned Reg = fieldFromInstruction(Insn, 7, 3);
174509467b48Spatrick
174609467b48Spatrick Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
174709467b48Spatrick
174809467b48Spatrick Inst.addOperand(MCOperand::createReg(Reg));
174909467b48Spatrick Inst.addOperand(MCOperand::createReg(Mips::GP));
175009467b48Spatrick Inst.addOperand(MCOperand::createImm(Offset << 2));
175109467b48Spatrick
175209467b48Spatrick return MCDisassembler::Success;
175309467b48Spatrick }
175409467b48Spatrick
DecodeMemMMReglistImm4Lsl2(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)1755*d415bd75Srobert static DecodeStatus DecodeMemMMReglistImm4Lsl2(MCInst &Inst, unsigned Insn,
175609467b48Spatrick uint64_t Address,
1757*d415bd75Srobert const MCDisassembler *Decoder) {
175809467b48Spatrick int Offset;
175909467b48Spatrick switch (Inst.getOpcode()) {
176009467b48Spatrick case Mips::LWM16_MMR6:
176109467b48Spatrick case Mips::SWM16_MMR6:
176209467b48Spatrick Offset = fieldFromInstruction(Insn, 4, 4);
176309467b48Spatrick break;
176409467b48Spatrick default:
176509467b48Spatrick Offset = SignExtend32<4>(Insn & 0xf);
176609467b48Spatrick break;
176709467b48Spatrick }
176809467b48Spatrick
176909467b48Spatrick if (DecodeRegListOperand16(Inst, Insn, Address, Decoder)
177009467b48Spatrick == MCDisassembler::Fail)
177109467b48Spatrick return MCDisassembler::Fail;
177209467b48Spatrick
177309467b48Spatrick Inst.addOperand(MCOperand::createReg(Mips::SP));
177409467b48Spatrick Inst.addOperand(MCOperand::createImm(Offset << 2));
177509467b48Spatrick
177609467b48Spatrick return MCDisassembler::Success;
177709467b48Spatrick }
177809467b48Spatrick
DecodeMemMMImm9(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)1779*d415bd75Srobert static DecodeStatus DecodeMemMMImm9(MCInst &Inst, unsigned Insn,
178009467b48Spatrick uint64_t Address,
1781*d415bd75Srobert const MCDisassembler *Decoder) {
178209467b48Spatrick int Offset = SignExtend32<9>(Insn & 0x1ff);
178309467b48Spatrick unsigned Reg = fieldFromInstruction(Insn, 21, 5);
178409467b48Spatrick unsigned Base = fieldFromInstruction(Insn, 16, 5);
178509467b48Spatrick
178609467b48Spatrick Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
178709467b48Spatrick Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
178809467b48Spatrick
178909467b48Spatrick if (Inst.getOpcode() == Mips::SCE_MM || Inst.getOpcode() == Mips::SC_MMR6)
179009467b48Spatrick Inst.addOperand(MCOperand::createReg(Reg));
179109467b48Spatrick
179209467b48Spatrick Inst.addOperand(MCOperand::createReg(Reg));
179309467b48Spatrick Inst.addOperand(MCOperand::createReg(Base));
179409467b48Spatrick Inst.addOperand(MCOperand::createImm(Offset));
179509467b48Spatrick
179609467b48Spatrick return MCDisassembler::Success;
179709467b48Spatrick }
179809467b48Spatrick
DecodeMemMMImm12(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)1799*d415bd75Srobert static DecodeStatus DecodeMemMMImm12(MCInst &Inst, unsigned Insn,
180009467b48Spatrick uint64_t Address,
1801*d415bd75Srobert const MCDisassembler *Decoder) {
180209467b48Spatrick int Offset = SignExtend32<12>(Insn & 0x0fff);
180309467b48Spatrick unsigned Reg = fieldFromInstruction(Insn, 21, 5);
180409467b48Spatrick unsigned Base = fieldFromInstruction(Insn, 16, 5);
180509467b48Spatrick
180609467b48Spatrick Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
180709467b48Spatrick Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
180809467b48Spatrick
180909467b48Spatrick switch (Inst.getOpcode()) {
181009467b48Spatrick case Mips::SWM32_MM:
181109467b48Spatrick case Mips::LWM32_MM:
181209467b48Spatrick if (DecodeRegListOperand(Inst, Insn, Address, Decoder)
181309467b48Spatrick == MCDisassembler::Fail)
181409467b48Spatrick return MCDisassembler::Fail;
181509467b48Spatrick Inst.addOperand(MCOperand::createReg(Base));
181609467b48Spatrick Inst.addOperand(MCOperand::createImm(Offset));
181709467b48Spatrick break;
181809467b48Spatrick case Mips::SC_MM:
181909467b48Spatrick Inst.addOperand(MCOperand::createReg(Reg));
1820*d415bd75Srobert [[fallthrough]];
182109467b48Spatrick default:
182209467b48Spatrick Inst.addOperand(MCOperand::createReg(Reg));
182309467b48Spatrick if (Inst.getOpcode() == Mips::LWP_MM || Inst.getOpcode() == Mips::SWP_MM)
182409467b48Spatrick Inst.addOperand(MCOperand::createReg(Reg+1));
182509467b48Spatrick
182609467b48Spatrick Inst.addOperand(MCOperand::createReg(Base));
182709467b48Spatrick Inst.addOperand(MCOperand::createImm(Offset));
182809467b48Spatrick }
182909467b48Spatrick
183009467b48Spatrick return MCDisassembler::Success;
183109467b48Spatrick }
183209467b48Spatrick
DecodeMemMMImm16(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)1833*d415bd75Srobert static DecodeStatus DecodeMemMMImm16(MCInst &Inst, unsigned Insn,
183409467b48Spatrick uint64_t Address,
1835*d415bd75Srobert const MCDisassembler *Decoder) {
183609467b48Spatrick int Offset = SignExtend32<16>(Insn & 0xffff);
183709467b48Spatrick unsigned Reg = fieldFromInstruction(Insn, 21, 5);
183809467b48Spatrick unsigned Base = fieldFromInstruction(Insn, 16, 5);
183909467b48Spatrick
184009467b48Spatrick Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
184109467b48Spatrick Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
184209467b48Spatrick
184309467b48Spatrick Inst.addOperand(MCOperand::createReg(Reg));
184409467b48Spatrick Inst.addOperand(MCOperand::createReg(Base));
184509467b48Spatrick Inst.addOperand(MCOperand::createImm(Offset));
184609467b48Spatrick
184709467b48Spatrick return MCDisassembler::Success;
184809467b48Spatrick }
184909467b48Spatrick
DecodeFMem(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)1850*d415bd75Srobert static DecodeStatus DecodeFMem(MCInst &Inst, unsigned Insn, uint64_t Address,
1851*d415bd75Srobert const MCDisassembler *Decoder) {
185209467b48Spatrick int Offset = SignExtend32<16>(Insn & 0xffff);
185309467b48Spatrick unsigned Reg = fieldFromInstruction(Insn, 16, 5);
185409467b48Spatrick unsigned Base = fieldFromInstruction(Insn, 21, 5);
185509467b48Spatrick
185609467b48Spatrick Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg);
185709467b48Spatrick Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
185809467b48Spatrick
185909467b48Spatrick Inst.addOperand(MCOperand::createReg(Reg));
186009467b48Spatrick Inst.addOperand(MCOperand::createReg(Base));
186109467b48Spatrick Inst.addOperand(MCOperand::createImm(Offset));
186209467b48Spatrick
186309467b48Spatrick return MCDisassembler::Success;
186409467b48Spatrick }
186509467b48Spatrick
DecodeFMemMMR2(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)186609467b48Spatrick static DecodeStatus DecodeFMemMMR2(MCInst &Inst, unsigned Insn,
1867*d415bd75Srobert uint64_t Address,
1868*d415bd75Srobert const MCDisassembler *Decoder) {
186909467b48Spatrick // This function is the same as DecodeFMem but with the Reg and Base fields
187009467b48Spatrick // swapped according to microMIPS spec.
187109467b48Spatrick int Offset = SignExtend32<16>(Insn & 0xffff);
187209467b48Spatrick unsigned Base = fieldFromInstruction(Insn, 16, 5);
187309467b48Spatrick unsigned Reg = fieldFromInstruction(Insn, 21, 5);
187409467b48Spatrick
187509467b48Spatrick Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg);
187609467b48Spatrick Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
187709467b48Spatrick
187809467b48Spatrick Inst.addOperand(MCOperand::createReg(Reg));
187909467b48Spatrick Inst.addOperand(MCOperand::createReg(Base));
188009467b48Spatrick Inst.addOperand(MCOperand::createImm(Offset));
188109467b48Spatrick
188209467b48Spatrick return MCDisassembler::Success;
188309467b48Spatrick }
188409467b48Spatrick
DecodeFMem2(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)1885*d415bd75Srobert static DecodeStatus DecodeFMem2(MCInst &Inst, unsigned Insn, uint64_t Address,
1886*d415bd75Srobert const MCDisassembler *Decoder) {
188709467b48Spatrick int Offset = SignExtend32<16>(Insn & 0xffff);
188809467b48Spatrick unsigned Reg = fieldFromInstruction(Insn, 16, 5);
188909467b48Spatrick unsigned Base = fieldFromInstruction(Insn, 21, 5);
189009467b48Spatrick
189109467b48Spatrick Reg = getReg(Decoder, Mips::COP2RegClassID, Reg);
189209467b48Spatrick Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
189309467b48Spatrick
189409467b48Spatrick Inst.addOperand(MCOperand::createReg(Reg));
189509467b48Spatrick Inst.addOperand(MCOperand::createReg(Base));
189609467b48Spatrick Inst.addOperand(MCOperand::createImm(Offset));
189709467b48Spatrick
189809467b48Spatrick return MCDisassembler::Success;
189909467b48Spatrick }
190009467b48Spatrick
DecodeFMem3(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)1901*d415bd75Srobert static DecodeStatus DecodeFMem3(MCInst &Inst, unsigned Insn, uint64_t Address,
1902*d415bd75Srobert const MCDisassembler *Decoder) {
190309467b48Spatrick int Offset = SignExtend32<16>(Insn & 0xffff);
190409467b48Spatrick unsigned Reg = fieldFromInstruction(Insn, 16, 5);
190509467b48Spatrick unsigned Base = fieldFromInstruction(Insn, 21, 5);
190609467b48Spatrick
190709467b48Spatrick Reg = getReg(Decoder, Mips::COP3RegClassID, Reg);
190809467b48Spatrick Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
190909467b48Spatrick
191009467b48Spatrick Inst.addOperand(MCOperand::createReg(Reg));
191109467b48Spatrick Inst.addOperand(MCOperand::createReg(Base));
191209467b48Spatrick Inst.addOperand(MCOperand::createImm(Offset));
191309467b48Spatrick
191409467b48Spatrick return MCDisassembler::Success;
191509467b48Spatrick }
191609467b48Spatrick
DecodeFMemCop2R6(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)1917*d415bd75Srobert static DecodeStatus DecodeFMemCop2R6(MCInst &Inst, unsigned Insn,
191809467b48Spatrick uint64_t Address,
1919*d415bd75Srobert const MCDisassembler *Decoder) {
192009467b48Spatrick int Offset = SignExtend32<11>(Insn & 0x07ff);
192109467b48Spatrick unsigned Reg = fieldFromInstruction(Insn, 16, 5);
192209467b48Spatrick unsigned Base = fieldFromInstruction(Insn, 11, 5);
192309467b48Spatrick
192409467b48Spatrick Reg = getReg(Decoder, Mips::COP2RegClassID, Reg);
192509467b48Spatrick Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
192609467b48Spatrick
192709467b48Spatrick Inst.addOperand(MCOperand::createReg(Reg));
192809467b48Spatrick Inst.addOperand(MCOperand::createReg(Base));
192909467b48Spatrick Inst.addOperand(MCOperand::createImm(Offset));
193009467b48Spatrick
193109467b48Spatrick return MCDisassembler::Success;
193209467b48Spatrick }
193309467b48Spatrick
DecodeFMemCop2MMR6(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)193409467b48Spatrick static DecodeStatus DecodeFMemCop2MMR6(MCInst &Inst, unsigned Insn,
1935*d415bd75Srobert uint64_t Address,
1936*d415bd75Srobert const MCDisassembler *Decoder) {
193709467b48Spatrick int Offset = SignExtend32<11>(Insn & 0x07ff);
193809467b48Spatrick unsigned Reg = fieldFromInstruction(Insn, 21, 5);
193909467b48Spatrick unsigned Base = fieldFromInstruction(Insn, 16, 5);
194009467b48Spatrick
194109467b48Spatrick Reg = getReg(Decoder, Mips::COP2RegClassID, Reg);
194209467b48Spatrick Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
194309467b48Spatrick
194409467b48Spatrick Inst.addOperand(MCOperand::createReg(Reg));
194509467b48Spatrick Inst.addOperand(MCOperand::createReg(Base));
194609467b48Spatrick Inst.addOperand(MCOperand::createImm(Offset));
194709467b48Spatrick
194809467b48Spatrick return MCDisassembler::Success;
194909467b48Spatrick }
195009467b48Spatrick
DecodeSpecial3LlSc(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)1951*d415bd75Srobert static DecodeStatus DecodeSpecial3LlSc(MCInst &Inst, unsigned Insn,
195209467b48Spatrick uint64_t Address,
1953*d415bd75Srobert const MCDisassembler *Decoder) {
195409467b48Spatrick int64_t Offset = SignExtend64<9>((Insn >> 7) & 0x1ff);
195509467b48Spatrick unsigned Rt = fieldFromInstruction(Insn, 16, 5);
195609467b48Spatrick unsigned Base = fieldFromInstruction(Insn, 21, 5);
195709467b48Spatrick
195809467b48Spatrick Rt = getReg(Decoder, Mips::GPR32RegClassID, Rt);
195909467b48Spatrick Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
196009467b48Spatrick
196109467b48Spatrick if(Inst.getOpcode() == Mips::SC_R6 || Inst.getOpcode() == Mips::SCD_R6){
196209467b48Spatrick Inst.addOperand(MCOperand::createReg(Rt));
196309467b48Spatrick }
196409467b48Spatrick
196509467b48Spatrick Inst.addOperand(MCOperand::createReg(Rt));
196609467b48Spatrick Inst.addOperand(MCOperand::createReg(Base));
196709467b48Spatrick Inst.addOperand(MCOperand::createImm(Offset));
196809467b48Spatrick
196909467b48Spatrick return MCDisassembler::Success;
197009467b48Spatrick }
197109467b48Spatrick
DecodeHWRegsRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)1972*d415bd75Srobert static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst, unsigned RegNo,
197309467b48Spatrick uint64_t Address,
1974*d415bd75Srobert const MCDisassembler *Decoder) {
197509467b48Spatrick // Currently only hardware register 29 is supported.
197609467b48Spatrick if (RegNo != 29)
197709467b48Spatrick return MCDisassembler::Fail;
197809467b48Spatrick Inst.addOperand(MCOperand::createReg(Mips::HWR29));
197909467b48Spatrick return MCDisassembler::Success;
198009467b48Spatrick }
198109467b48Spatrick
DecodeAFGR64RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)1982*d415bd75Srobert static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst, unsigned RegNo,
198309467b48Spatrick uint64_t Address,
1984*d415bd75Srobert const MCDisassembler *Decoder) {
198509467b48Spatrick if (RegNo > 30 || RegNo %2)
198609467b48Spatrick return MCDisassembler::Fail;
198709467b48Spatrick
198809467b48Spatrick unsigned Reg = getReg(Decoder, Mips::AFGR64RegClassID, RegNo /2);
198909467b48Spatrick Inst.addOperand(MCOperand::createReg(Reg));
199009467b48Spatrick return MCDisassembler::Success;
199109467b48Spatrick }
199209467b48Spatrick
DecodeACC64DSPRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)1993*d415bd75Srobert static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst, unsigned RegNo,
199409467b48Spatrick uint64_t Address,
1995*d415bd75Srobert const MCDisassembler *Decoder) {
199609467b48Spatrick if (RegNo >= 4)
199709467b48Spatrick return MCDisassembler::Fail;
199809467b48Spatrick
199909467b48Spatrick unsigned Reg = getReg(Decoder, Mips::ACC64DSPRegClassID, RegNo);
200009467b48Spatrick Inst.addOperand(MCOperand::createReg(Reg));
200109467b48Spatrick return MCDisassembler::Success;
200209467b48Spatrick }
200309467b48Spatrick
DecodeHI32DSPRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)2004*d415bd75Srobert static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst, unsigned RegNo,
200509467b48Spatrick uint64_t Address,
2006*d415bd75Srobert const MCDisassembler *Decoder) {
200709467b48Spatrick if (RegNo >= 4)
200809467b48Spatrick return MCDisassembler::Fail;
200909467b48Spatrick
201009467b48Spatrick unsigned Reg = getReg(Decoder, Mips::HI32DSPRegClassID, RegNo);
201109467b48Spatrick Inst.addOperand(MCOperand::createReg(Reg));
201209467b48Spatrick return MCDisassembler::Success;
201309467b48Spatrick }
201409467b48Spatrick
DecodeLO32DSPRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)2015*d415bd75Srobert static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst, unsigned RegNo,
201609467b48Spatrick uint64_t Address,
2017*d415bd75Srobert const MCDisassembler *Decoder) {
201809467b48Spatrick if (RegNo >= 4)
201909467b48Spatrick return MCDisassembler::Fail;
202009467b48Spatrick
202109467b48Spatrick unsigned Reg = getReg(Decoder, Mips::LO32DSPRegClassID, RegNo);
202209467b48Spatrick Inst.addOperand(MCOperand::createReg(Reg));
202309467b48Spatrick return MCDisassembler::Success;
202409467b48Spatrick }
202509467b48Spatrick
DecodeMSA128BRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)2026*d415bd75Srobert static DecodeStatus DecodeMSA128BRegisterClass(MCInst &Inst, unsigned RegNo,
202709467b48Spatrick uint64_t Address,
2028*d415bd75Srobert const MCDisassembler *Decoder) {
202909467b48Spatrick if (RegNo > 31)
203009467b48Spatrick return MCDisassembler::Fail;
203109467b48Spatrick
203209467b48Spatrick unsigned Reg = getReg(Decoder, Mips::MSA128BRegClassID, RegNo);
203309467b48Spatrick Inst.addOperand(MCOperand::createReg(Reg));
203409467b48Spatrick return MCDisassembler::Success;
203509467b48Spatrick }
203609467b48Spatrick
DecodeMSA128HRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)2037*d415bd75Srobert static DecodeStatus DecodeMSA128HRegisterClass(MCInst &Inst, unsigned RegNo,
203809467b48Spatrick uint64_t Address,
2039*d415bd75Srobert const MCDisassembler *Decoder) {
204009467b48Spatrick if (RegNo > 31)
204109467b48Spatrick return MCDisassembler::Fail;
204209467b48Spatrick
204309467b48Spatrick unsigned Reg = getReg(Decoder, Mips::MSA128HRegClassID, RegNo);
204409467b48Spatrick Inst.addOperand(MCOperand::createReg(Reg));
204509467b48Spatrick return MCDisassembler::Success;
204609467b48Spatrick }
204709467b48Spatrick
DecodeMSA128WRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)2048*d415bd75Srobert static DecodeStatus DecodeMSA128WRegisterClass(MCInst &Inst, unsigned RegNo,
204909467b48Spatrick uint64_t Address,
2050*d415bd75Srobert const MCDisassembler *Decoder) {
205109467b48Spatrick if (RegNo > 31)
205209467b48Spatrick return MCDisassembler::Fail;
205309467b48Spatrick
205409467b48Spatrick unsigned Reg = getReg(Decoder, Mips::MSA128WRegClassID, RegNo);
205509467b48Spatrick Inst.addOperand(MCOperand::createReg(Reg));
205609467b48Spatrick return MCDisassembler::Success;
205709467b48Spatrick }
205809467b48Spatrick
DecodeMSA128DRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)2059*d415bd75Srobert static DecodeStatus DecodeMSA128DRegisterClass(MCInst &Inst, unsigned RegNo,
206009467b48Spatrick uint64_t Address,
2061*d415bd75Srobert const MCDisassembler *Decoder) {
206209467b48Spatrick if (RegNo > 31)
206309467b48Spatrick return MCDisassembler::Fail;
206409467b48Spatrick
206509467b48Spatrick unsigned Reg = getReg(Decoder, Mips::MSA128DRegClassID, RegNo);
206609467b48Spatrick Inst.addOperand(MCOperand::createReg(Reg));
206709467b48Spatrick return MCDisassembler::Success;
206809467b48Spatrick }
206909467b48Spatrick
DecodeMSACtrlRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)2070*d415bd75Srobert static DecodeStatus DecodeMSACtrlRegisterClass(MCInst &Inst, unsigned RegNo,
207109467b48Spatrick uint64_t Address,
2072*d415bd75Srobert const MCDisassembler *Decoder) {
207309467b48Spatrick if (RegNo > 7)
207409467b48Spatrick return MCDisassembler::Fail;
207509467b48Spatrick
207609467b48Spatrick unsigned Reg = getReg(Decoder, Mips::MSACtrlRegClassID, RegNo);
207709467b48Spatrick Inst.addOperand(MCOperand::createReg(Reg));
207809467b48Spatrick return MCDisassembler::Success;
207909467b48Spatrick }
208009467b48Spatrick
DecodeCOP0RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)2081*d415bd75Srobert static DecodeStatus DecodeCOP0RegisterClass(MCInst &Inst, unsigned RegNo,
208209467b48Spatrick uint64_t Address,
2083*d415bd75Srobert const MCDisassembler *Decoder) {
208409467b48Spatrick if (RegNo > 31)
208509467b48Spatrick return MCDisassembler::Fail;
208609467b48Spatrick
208709467b48Spatrick unsigned Reg = getReg(Decoder, Mips::COP0RegClassID, RegNo);
208809467b48Spatrick Inst.addOperand(MCOperand::createReg(Reg));
208909467b48Spatrick return MCDisassembler::Success;
209009467b48Spatrick }
209109467b48Spatrick
DecodeCOP2RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)2092*d415bd75Srobert static DecodeStatus DecodeCOP2RegisterClass(MCInst &Inst, unsigned RegNo,
209309467b48Spatrick uint64_t Address,
2094*d415bd75Srobert const MCDisassembler *Decoder) {
209509467b48Spatrick if (RegNo > 31)
209609467b48Spatrick return MCDisassembler::Fail;
209709467b48Spatrick
209809467b48Spatrick unsigned Reg = getReg(Decoder, Mips::COP2RegClassID, RegNo);
209909467b48Spatrick Inst.addOperand(MCOperand::createReg(Reg));
210009467b48Spatrick return MCDisassembler::Success;
210109467b48Spatrick }
210209467b48Spatrick
DecodeBranchTarget(MCInst & Inst,unsigned Offset,uint64_t Address,const MCDisassembler * Decoder)2103*d415bd75Srobert static DecodeStatus DecodeBranchTarget(MCInst &Inst, unsigned Offset,
210409467b48Spatrick uint64_t Address,
2105*d415bd75Srobert const MCDisassembler *Decoder) {
210609467b48Spatrick int32_t BranchOffset = (SignExtend32<16>(Offset) * 4) + 4;
210709467b48Spatrick Inst.addOperand(MCOperand::createImm(BranchOffset));
210809467b48Spatrick return MCDisassembler::Success;
210909467b48Spatrick }
211009467b48Spatrick
DecodeBranchTarget1SImm16(MCInst & Inst,unsigned Offset,uint64_t Address,const MCDisassembler * Decoder)2111*d415bd75Srobert static DecodeStatus DecodeBranchTarget1SImm16(MCInst &Inst, unsigned Offset,
211209467b48Spatrick uint64_t Address,
2113*d415bd75Srobert const MCDisassembler *Decoder) {
211409467b48Spatrick int32_t BranchOffset = (SignExtend32<16>(Offset) * 2);
211509467b48Spatrick Inst.addOperand(MCOperand::createImm(BranchOffset));
211609467b48Spatrick return MCDisassembler::Success;
211709467b48Spatrick }
211809467b48Spatrick
DecodeJumpTarget(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)2119*d415bd75Srobert static DecodeStatus DecodeJumpTarget(MCInst &Inst, unsigned Insn,
212009467b48Spatrick uint64_t Address,
2121*d415bd75Srobert const MCDisassembler *Decoder) {
212209467b48Spatrick unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 2;
212309467b48Spatrick Inst.addOperand(MCOperand::createImm(JumpOffset));
212409467b48Spatrick return MCDisassembler::Success;
212509467b48Spatrick }
212609467b48Spatrick
DecodeBranchTarget21(MCInst & Inst,unsigned Offset,uint64_t Address,const MCDisassembler * Decoder)2127*d415bd75Srobert static DecodeStatus DecodeBranchTarget21(MCInst &Inst, unsigned Offset,
212809467b48Spatrick uint64_t Address,
2129*d415bd75Srobert const MCDisassembler *Decoder) {
213009467b48Spatrick int32_t BranchOffset = SignExtend32<21>(Offset) * 4 + 4;
213109467b48Spatrick
213209467b48Spatrick Inst.addOperand(MCOperand::createImm(BranchOffset));
213309467b48Spatrick return MCDisassembler::Success;
213409467b48Spatrick }
213509467b48Spatrick
DecodeBranchTarget21MM(MCInst & Inst,unsigned Offset,uint64_t Address,const MCDisassembler * Decoder)2136*d415bd75Srobert static DecodeStatus DecodeBranchTarget21MM(MCInst &Inst, unsigned Offset,
213709467b48Spatrick uint64_t Address,
2138*d415bd75Srobert const MCDisassembler *Decoder) {
213909467b48Spatrick int32_t BranchOffset = SignExtend32<21>(Offset) * 4 + 4;
214009467b48Spatrick
214109467b48Spatrick Inst.addOperand(MCOperand::createImm(BranchOffset));
214209467b48Spatrick return MCDisassembler::Success;
214309467b48Spatrick }
214409467b48Spatrick
DecodeBranchTarget26(MCInst & Inst,unsigned Offset,uint64_t Address,const MCDisassembler * Decoder)2145*d415bd75Srobert static DecodeStatus DecodeBranchTarget26(MCInst &Inst, unsigned Offset,
214609467b48Spatrick uint64_t Address,
2147*d415bd75Srobert const MCDisassembler *Decoder) {
214809467b48Spatrick int32_t BranchOffset = SignExtend32<26>(Offset) * 4 + 4;
214909467b48Spatrick
215009467b48Spatrick Inst.addOperand(MCOperand::createImm(BranchOffset));
215109467b48Spatrick return MCDisassembler::Success;
215209467b48Spatrick }
215309467b48Spatrick
DecodeBranchTarget7MM(MCInst & Inst,unsigned Offset,uint64_t Address,const MCDisassembler * Decoder)2154*d415bd75Srobert static DecodeStatus DecodeBranchTarget7MM(MCInst &Inst, unsigned Offset,
215509467b48Spatrick uint64_t Address,
2156*d415bd75Srobert const MCDisassembler *Decoder) {
215709467b48Spatrick int32_t BranchOffset = SignExtend32<8>(Offset << 1);
215809467b48Spatrick Inst.addOperand(MCOperand::createImm(BranchOffset));
215909467b48Spatrick return MCDisassembler::Success;
216009467b48Spatrick }
216109467b48Spatrick
DecodeBranchTarget10MM(MCInst & Inst,unsigned Offset,uint64_t Address,const MCDisassembler * Decoder)2162*d415bd75Srobert static DecodeStatus DecodeBranchTarget10MM(MCInst &Inst, unsigned Offset,
216309467b48Spatrick uint64_t Address,
2164*d415bd75Srobert const MCDisassembler *Decoder) {
216509467b48Spatrick int32_t BranchOffset = SignExtend32<11>(Offset << 1);
216609467b48Spatrick Inst.addOperand(MCOperand::createImm(BranchOffset));
216709467b48Spatrick return MCDisassembler::Success;
216809467b48Spatrick }
216909467b48Spatrick
DecodeBranchTargetMM(MCInst & Inst,unsigned Offset,uint64_t Address,const MCDisassembler * Decoder)2170*d415bd75Srobert static DecodeStatus DecodeBranchTargetMM(MCInst &Inst, unsigned Offset,
217109467b48Spatrick uint64_t Address,
2172*d415bd75Srobert const MCDisassembler *Decoder) {
217309467b48Spatrick int32_t BranchOffset = SignExtend32<16>(Offset) * 2 + 4;
217409467b48Spatrick Inst.addOperand(MCOperand::createImm(BranchOffset));
217509467b48Spatrick return MCDisassembler::Success;
217609467b48Spatrick }
217709467b48Spatrick
DecodeBranchTarget26MM(MCInst & Inst,unsigned Offset,uint64_t Address,const MCDisassembler * Decoder)2178*d415bd75Srobert static DecodeStatus DecodeBranchTarget26MM(MCInst &Inst, unsigned Offset,
217909467b48Spatrick uint64_t Address,
2180*d415bd75Srobert const MCDisassembler *Decoder) {
218109467b48Spatrick int32_t BranchOffset = SignExtend32<27>(Offset << 1);
218209467b48Spatrick
218309467b48Spatrick Inst.addOperand(MCOperand::createImm(BranchOffset));
218409467b48Spatrick return MCDisassembler::Success;
218509467b48Spatrick }
218609467b48Spatrick
DecodeJumpTargetMM(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)2187*d415bd75Srobert static DecodeStatus DecodeJumpTargetMM(MCInst &Inst, unsigned Insn,
218809467b48Spatrick uint64_t Address,
2189*d415bd75Srobert const MCDisassembler *Decoder) {
219009467b48Spatrick unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 1;
219109467b48Spatrick Inst.addOperand(MCOperand::createImm(JumpOffset));
219209467b48Spatrick return MCDisassembler::Success;
219309467b48Spatrick }
219409467b48Spatrick
DecodeJumpTargetXMM(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)2195*d415bd75Srobert static DecodeStatus DecodeJumpTargetXMM(MCInst &Inst, unsigned Insn,
219609467b48Spatrick uint64_t Address,
2197*d415bd75Srobert const MCDisassembler *Decoder) {
219809467b48Spatrick unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 2;
219909467b48Spatrick Inst.addOperand(MCOperand::createImm(JumpOffset));
220009467b48Spatrick return MCDisassembler::Success;
220109467b48Spatrick }
220209467b48Spatrick
DecodeAddiur2Simm7(MCInst & Inst,unsigned Value,uint64_t Address,const MCDisassembler * Decoder)2203*d415bd75Srobert static DecodeStatus DecodeAddiur2Simm7(MCInst &Inst, unsigned Value,
220409467b48Spatrick uint64_t Address,
2205*d415bd75Srobert const MCDisassembler *Decoder) {
220609467b48Spatrick if (Value == 0)
220709467b48Spatrick Inst.addOperand(MCOperand::createImm(1));
220809467b48Spatrick else if (Value == 0x7)
220909467b48Spatrick Inst.addOperand(MCOperand::createImm(-1));
221009467b48Spatrick else
221109467b48Spatrick Inst.addOperand(MCOperand::createImm(Value << 2));
221209467b48Spatrick return MCDisassembler::Success;
221309467b48Spatrick }
221409467b48Spatrick
DecodeLi16Imm(MCInst & Inst,unsigned Value,uint64_t Address,const MCDisassembler * Decoder)2215*d415bd75Srobert static DecodeStatus DecodeLi16Imm(MCInst &Inst, unsigned Value,
221609467b48Spatrick uint64_t Address,
2217*d415bd75Srobert const MCDisassembler *Decoder) {
221809467b48Spatrick if (Value == 0x7F)
221909467b48Spatrick Inst.addOperand(MCOperand::createImm(-1));
222009467b48Spatrick else
222109467b48Spatrick Inst.addOperand(MCOperand::createImm(Value));
222209467b48Spatrick return MCDisassembler::Success;
222309467b48Spatrick }
222409467b48Spatrick
DecodePOOL16BEncodedField(MCInst & Inst,unsigned Value,uint64_t Address,const MCDisassembler * Decoder)2225*d415bd75Srobert static DecodeStatus DecodePOOL16BEncodedField(MCInst &Inst, unsigned Value,
222609467b48Spatrick uint64_t Address,
2227*d415bd75Srobert const MCDisassembler *Decoder) {
222809467b48Spatrick Inst.addOperand(MCOperand::createImm(Value == 0x0 ? 8 : Value));
222909467b48Spatrick return MCDisassembler::Success;
223009467b48Spatrick }
223109467b48Spatrick
223209467b48Spatrick template <unsigned Bits, int Offset, int Scale>
2233*d415bd75Srobert static DecodeStatus
DecodeUImmWithOffsetAndScale(MCInst & Inst,unsigned Value,uint64_t Address,const MCDisassembler * Decoder)2234*d415bd75Srobert DecodeUImmWithOffsetAndScale(MCInst &Inst, unsigned Value, uint64_t Address,
2235*d415bd75Srobert const MCDisassembler *Decoder) {
223609467b48Spatrick Value &= ((1 << Bits) - 1);
223709467b48Spatrick Value *= Scale;
223809467b48Spatrick Inst.addOperand(MCOperand::createImm(Value + Offset));
223909467b48Spatrick return MCDisassembler::Success;
224009467b48Spatrick }
224109467b48Spatrick
224209467b48Spatrick template <unsigned Bits, int Offset, int ScaleBy>
2243*d415bd75Srobert static DecodeStatus
DecodeSImmWithOffsetAndScale(MCInst & Inst,unsigned Value,uint64_t Address,const MCDisassembler * Decoder)2244*d415bd75Srobert DecodeSImmWithOffsetAndScale(MCInst &Inst, unsigned Value, uint64_t Address,
2245*d415bd75Srobert const MCDisassembler *Decoder) {
224609467b48Spatrick int32_t Imm = SignExtend32<Bits>(Value) * ScaleBy;
224709467b48Spatrick Inst.addOperand(MCOperand::createImm(Imm + Offset));
224809467b48Spatrick return MCDisassembler::Success;
224909467b48Spatrick }
225009467b48Spatrick
DecodeInsSize(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)2251*d415bd75Srobert static DecodeStatus DecodeInsSize(MCInst &Inst, unsigned Insn, uint64_t Address,
2252*d415bd75Srobert const MCDisassembler *Decoder) {
225309467b48Spatrick // First we need to grab the pos(lsb) from MCInst.
225409467b48Spatrick // This function only handles the 32 bit variants of ins, as dins
225509467b48Spatrick // variants are handled differently.
225609467b48Spatrick int Pos = Inst.getOperand(2).getImm();
225709467b48Spatrick int Size = (int) Insn - Pos + 1;
225809467b48Spatrick Inst.addOperand(MCOperand::createImm(SignExtend32<16>(Size)));
225909467b48Spatrick return MCDisassembler::Success;
226009467b48Spatrick }
226109467b48Spatrick
DecodeSimm19Lsl2(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)226209467b48Spatrick static DecodeStatus DecodeSimm19Lsl2(MCInst &Inst, unsigned Insn,
2263*d415bd75Srobert uint64_t Address,
2264*d415bd75Srobert const MCDisassembler *Decoder) {
226509467b48Spatrick Inst.addOperand(MCOperand::createImm(SignExtend32<19>(Insn) * 4));
226609467b48Spatrick return MCDisassembler::Success;
226709467b48Spatrick }
226809467b48Spatrick
DecodeSimm18Lsl3(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)226909467b48Spatrick static DecodeStatus DecodeSimm18Lsl3(MCInst &Inst, unsigned Insn,
2270*d415bd75Srobert uint64_t Address,
2271*d415bd75Srobert const MCDisassembler *Decoder) {
227209467b48Spatrick Inst.addOperand(MCOperand::createImm(SignExtend32<18>(Insn) * 8));
227309467b48Spatrick return MCDisassembler::Success;
227409467b48Spatrick }
227509467b48Spatrick
DecodeSimm9SP(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)2276*d415bd75Srobert static DecodeStatus DecodeSimm9SP(MCInst &Inst, unsigned Insn, uint64_t Address,
2277*d415bd75Srobert const MCDisassembler *Decoder) {
227809467b48Spatrick int32_t DecodedValue;
227909467b48Spatrick switch (Insn) {
228009467b48Spatrick case 0: DecodedValue = 256; break;
228109467b48Spatrick case 1: DecodedValue = 257; break;
228209467b48Spatrick case 510: DecodedValue = -258; break;
228309467b48Spatrick case 511: DecodedValue = -257; break;
228409467b48Spatrick default: DecodedValue = SignExtend32<9>(Insn); break;
228509467b48Spatrick }
228609467b48Spatrick Inst.addOperand(MCOperand::createImm(DecodedValue * 4));
228709467b48Spatrick return MCDisassembler::Success;
228809467b48Spatrick }
228909467b48Spatrick
DecodeANDI16Imm(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)229009467b48Spatrick static DecodeStatus DecodeANDI16Imm(MCInst &Inst, unsigned Insn,
2291*d415bd75Srobert uint64_t Address,
2292*d415bd75Srobert const MCDisassembler *Decoder) {
229309467b48Spatrick // Insn must be >= 0, since it is unsigned that condition is always true.
229409467b48Spatrick assert(Insn < 16);
229509467b48Spatrick int32_t DecodedValues[] = {128, 1, 2, 3, 4, 7, 8, 15, 16, 31, 32, 63, 64,
229609467b48Spatrick 255, 32768, 65535};
229709467b48Spatrick Inst.addOperand(MCOperand::createImm(DecodedValues[Insn]));
229809467b48Spatrick return MCDisassembler::Success;
229909467b48Spatrick }
230009467b48Spatrick
DecodeRegListOperand(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)2301*d415bd75Srobert static DecodeStatus DecodeRegListOperand(MCInst &Inst, unsigned Insn,
230209467b48Spatrick uint64_t Address,
2303*d415bd75Srobert const MCDisassembler *Decoder) {
230409467b48Spatrick unsigned Regs[] = {Mips::S0, Mips::S1, Mips::S2, Mips::S3, Mips::S4, Mips::S5,
230509467b48Spatrick Mips::S6, Mips::S7, Mips::FP};
230609467b48Spatrick unsigned RegNum;
230709467b48Spatrick
230809467b48Spatrick unsigned RegLst = fieldFromInstruction(Insn, 21, 5);
230909467b48Spatrick
231009467b48Spatrick // Empty register lists are not allowed.
231109467b48Spatrick if (RegLst == 0)
231209467b48Spatrick return MCDisassembler::Fail;
231309467b48Spatrick
231409467b48Spatrick RegNum = RegLst & 0xf;
231509467b48Spatrick
231609467b48Spatrick // RegLst values 10-15, and 26-31 are reserved.
231709467b48Spatrick if (RegNum > 9)
231809467b48Spatrick return MCDisassembler::Fail;
231909467b48Spatrick
232009467b48Spatrick for (unsigned i = 0; i < RegNum; i++)
232109467b48Spatrick Inst.addOperand(MCOperand::createReg(Regs[i]));
232209467b48Spatrick
232309467b48Spatrick if (RegLst & 0x10)
232409467b48Spatrick Inst.addOperand(MCOperand::createReg(Mips::RA));
232509467b48Spatrick
232609467b48Spatrick return MCDisassembler::Success;
232709467b48Spatrick }
232809467b48Spatrick
DecodeRegListOperand16(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)232909467b48Spatrick static DecodeStatus DecodeRegListOperand16(MCInst &Inst, unsigned Insn,
233009467b48Spatrick uint64_t Address,
2331*d415bd75Srobert const MCDisassembler *Decoder) {
233209467b48Spatrick unsigned Regs[] = {Mips::S0, Mips::S1, Mips::S2, Mips::S3};
233309467b48Spatrick unsigned RegLst;
233409467b48Spatrick switch(Inst.getOpcode()) {
233509467b48Spatrick default:
233609467b48Spatrick RegLst = fieldFromInstruction(Insn, 4, 2);
233709467b48Spatrick break;
233809467b48Spatrick case Mips::LWM16_MMR6:
233909467b48Spatrick case Mips::SWM16_MMR6:
234009467b48Spatrick RegLst = fieldFromInstruction(Insn, 8, 2);
234109467b48Spatrick break;
234209467b48Spatrick }
234309467b48Spatrick unsigned RegNum = RegLst & 0x3;
234409467b48Spatrick
234509467b48Spatrick for (unsigned i = 0; i <= RegNum; i++)
234609467b48Spatrick Inst.addOperand(MCOperand::createReg(Regs[i]));
234709467b48Spatrick
234809467b48Spatrick Inst.addOperand(MCOperand::createReg(Mips::RA));
234909467b48Spatrick
235009467b48Spatrick return MCDisassembler::Success;
235109467b48Spatrick }
235209467b48Spatrick
DecodeMovePOperands(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)235309467b48Spatrick static DecodeStatus DecodeMovePOperands(MCInst &Inst, unsigned Insn,
235409467b48Spatrick uint64_t Address,
2355*d415bd75Srobert const MCDisassembler *Decoder) {
235609467b48Spatrick unsigned RegPair = fieldFromInstruction(Insn, 7, 3);
235709467b48Spatrick if (DecodeMovePRegPair(Inst, RegPair, Address, Decoder) ==
235809467b48Spatrick MCDisassembler::Fail)
235909467b48Spatrick return MCDisassembler::Fail;
236009467b48Spatrick
236109467b48Spatrick unsigned RegRs;
236209467b48Spatrick if (static_cast<const MipsDisassembler*>(Decoder)->hasMips32r6())
236309467b48Spatrick RegRs = fieldFromInstruction(Insn, 0, 2) |
236409467b48Spatrick (fieldFromInstruction(Insn, 3, 1) << 2);
236509467b48Spatrick else
236609467b48Spatrick RegRs = fieldFromInstruction(Insn, 1, 3);
236709467b48Spatrick if (DecodeGPRMM16MovePRegisterClass(Inst, RegRs, Address, Decoder) ==
236809467b48Spatrick MCDisassembler::Fail)
236909467b48Spatrick return MCDisassembler::Fail;
237009467b48Spatrick
237109467b48Spatrick unsigned RegRt = fieldFromInstruction(Insn, 4, 3);
237209467b48Spatrick if (DecodeGPRMM16MovePRegisterClass(Inst, RegRt, Address, Decoder) ==
237309467b48Spatrick MCDisassembler::Fail)
237409467b48Spatrick return MCDisassembler::Fail;
237509467b48Spatrick
237609467b48Spatrick return MCDisassembler::Success;
237709467b48Spatrick }
237809467b48Spatrick
DecodeMovePRegPair(MCInst & Inst,unsigned RegPair,uint64_t Address,const MCDisassembler * Decoder)237909467b48Spatrick static DecodeStatus DecodeMovePRegPair(MCInst &Inst, unsigned RegPair,
2380*d415bd75Srobert uint64_t Address,
2381*d415bd75Srobert const MCDisassembler *Decoder) {
238209467b48Spatrick switch (RegPair) {
238309467b48Spatrick default:
238409467b48Spatrick return MCDisassembler::Fail;
238509467b48Spatrick case 0:
238609467b48Spatrick Inst.addOperand(MCOperand::createReg(Mips::A1));
238709467b48Spatrick Inst.addOperand(MCOperand::createReg(Mips::A2));
238809467b48Spatrick break;
238909467b48Spatrick case 1:
239009467b48Spatrick Inst.addOperand(MCOperand::createReg(Mips::A1));
239109467b48Spatrick Inst.addOperand(MCOperand::createReg(Mips::A3));
239209467b48Spatrick break;
239309467b48Spatrick case 2:
239409467b48Spatrick Inst.addOperand(MCOperand::createReg(Mips::A2));
239509467b48Spatrick Inst.addOperand(MCOperand::createReg(Mips::A3));
239609467b48Spatrick break;
239709467b48Spatrick case 3:
239809467b48Spatrick Inst.addOperand(MCOperand::createReg(Mips::A0));
239909467b48Spatrick Inst.addOperand(MCOperand::createReg(Mips::S5));
240009467b48Spatrick break;
240109467b48Spatrick case 4:
240209467b48Spatrick Inst.addOperand(MCOperand::createReg(Mips::A0));
240309467b48Spatrick Inst.addOperand(MCOperand::createReg(Mips::S6));
240409467b48Spatrick break;
240509467b48Spatrick case 5:
240609467b48Spatrick Inst.addOperand(MCOperand::createReg(Mips::A0));
240709467b48Spatrick Inst.addOperand(MCOperand::createReg(Mips::A1));
240809467b48Spatrick break;
240909467b48Spatrick case 6:
241009467b48Spatrick Inst.addOperand(MCOperand::createReg(Mips::A0));
241109467b48Spatrick Inst.addOperand(MCOperand::createReg(Mips::A2));
241209467b48Spatrick break;
241309467b48Spatrick case 7:
241409467b48Spatrick Inst.addOperand(MCOperand::createReg(Mips::A0));
241509467b48Spatrick Inst.addOperand(MCOperand::createReg(Mips::A3));
241609467b48Spatrick break;
241709467b48Spatrick }
241809467b48Spatrick
241909467b48Spatrick return MCDisassembler::Success;
242009467b48Spatrick }
242109467b48Spatrick
DecodeSimm23Lsl2(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)242209467b48Spatrick static DecodeStatus DecodeSimm23Lsl2(MCInst &Inst, unsigned Insn,
2423*d415bd75Srobert uint64_t Address,
2424*d415bd75Srobert const MCDisassembler *Decoder) {
242509467b48Spatrick Inst.addOperand(MCOperand::createImm(SignExtend32<25>(Insn << 2)));
242609467b48Spatrick return MCDisassembler::Success;
242709467b48Spatrick }
242809467b48Spatrick
242909467b48Spatrick template <typename InsnType>
DecodeBgtzGroupBranchMMR6(MCInst & MI,InsnType insn,uint64_t Address,const MCDisassembler * Decoder)243009467b48Spatrick static DecodeStatus DecodeBgtzGroupBranchMMR6(MCInst &MI, InsnType insn,
243109467b48Spatrick uint64_t Address,
2432*d415bd75Srobert const MCDisassembler *Decoder) {
243309467b48Spatrick // We have:
243409467b48Spatrick // 0b000111 ttttt sssss iiiiiiiiiiiiiiii
243509467b48Spatrick // Invalid if rt == 0
243609467b48Spatrick // BGTZALC_MMR6 if rs == 0 && rt != 0
243709467b48Spatrick // BLTZALC_MMR6 if rs != 0 && rs == rt
243809467b48Spatrick // BLTUC_MMR6 if rs != 0 && rs != rt
243909467b48Spatrick
244009467b48Spatrick InsnType Rt = fieldFromInstruction(insn, 21, 5);
244109467b48Spatrick InsnType Rs = fieldFromInstruction(insn, 16, 5);
244209467b48Spatrick InsnType Imm = 0;
244309467b48Spatrick bool HasRs = false;
244409467b48Spatrick bool HasRt = false;
244509467b48Spatrick
244609467b48Spatrick if (Rt == 0)
244709467b48Spatrick return MCDisassembler::Fail;
244809467b48Spatrick else if (Rs == 0) {
244909467b48Spatrick MI.setOpcode(Mips::BGTZALC_MMR6);
245009467b48Spatrick HasRt = true;
245109467b48Spatrick Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
245209467b48Spatrick }
245309467b48Spatrick else if (Rs == Rt) {
245409467b48Spatrick MI.setOpcode(Mips::BLTZALC_MMR6);
245509467b48Spatrick HasRs = true;
245609467b48Spatrick Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
245709467b48Spatrick }
245809467b48Spatrick else {
245909467b48Spatrick MI.setOpcode(Mips::BLTUC_MMR6);
246009467b48Spatrick HasRs = true;
246109467b48Spatrick HasRt = true;
246209467b48Spatrick Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
246309467b48Spatrick }
246409467b48Spatrick
246509467b48Spatrick if (HasRs)
246609467b48Spatrick MI.addOperand(
246709467b48Spatrick MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rs)));
246809467b48Spatrick
246909467b48Spatrick if (HasRt)
247009467b48Spatrick MI.addOperand(
247109467b48Spatrick MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rt)));
247209467b48Spatrick
247309467b48Spatrick MI.addOperand(MCOperand::createImm(Imm));
247409467b48Spatrick
247509467b48Spatrick return MCDisassembler::Success;
247609467b48Spatrick }
247709467b48Spatrick
247809467b48Spatrick template <typename InsnType>
DecodeBlezGroupBranchMMR6(MCInst & MI,InsnType insn,uint64_t Address,const MCDisassembler * Decoder)247909467b48Spatrick static DecodeStatus DecodeBlezGroupBranchMMR6(MCInst &MI, InsnType insn,
248009467b48Spatrick uint64_t Address,
2481*d415bd75Srobert const MCDisassembler *Decoder) {
248209467b48Spatrick // We have:
248309467b48Spatrick // 0b000110 ttttt sssss iiiiiiiiiiiiiiii
248409467b48Spatrick // Invalid if rt == 0
248509467b48Spatrick // BLEZALC_MMR6 if rs == 0 && rt != 0
248609467b48Spatrick // BGEZALC_MMR6 if rs == rt && rt != 0
248709467b48Spatrick // BGEUC_MMR6 if rs != rt && rs != 0 && rt != 0
248809467b48Spatrick
248909467b48Spatrick InsnType Rt = fieldFromInstruction(insn, 21, 5);
249009467b48Spatrick InsnType Rs = fieldFromInstruction(insn, 16, 5);
249109467b48Spatrick InsnType Imm = 0;
249209467b48Spatrick bool HasRs = false;
249309467b48Spatrick
249409467b48Spatrick if (Rt == 0)
249509467b48Spatrick return MCDisassembler::Fail;
249609467b48Spatrick else if (Rs == 0) {
249709467b48Spatrick MI.setOpcode(Mips::BLEZALC_MMR6);
249809467b48Spatrick Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
249909467b48Spatrick }
250009467b48Spatrick else if (Rs == Rt) {
250109467b48Spatrick MI.setOpcode(Mips::BGEZALC_MMR6);
250209467b48Spatrick Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
250309467b48Spatrick }
250409467b48Spatrick else {
250509467b48Spatrick HasRs = true;
250609467b48Spatrick MI.setOpcode(Mips::BGEUC_MMR6);
250709467b48Spatrick Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
250809467b48Spatrick }
250909467b48Spatrick
251009467b48Spatrick if (HasRs)
251109467b48Spatrick MI.addOperand(
251209467b48Spatrick MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rs)));
251309467b48Spatrick MI.addOperand(
251409467b48Spatrick MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rt)));
251509467b48Spatrick
251609467b48Spatrick MI.addOperand(MCOperand::createImm(Imm));
251709467b48Spatrick
251809467b48Spatrick return MCDisassembler::Success;
251909467b48Spatrick }
2520*d415bd75Srobert
2521*d415bd75Srobert // This instruction does not have a working decoder, and needs to be
2522*d415bd75Srobert // fixed. This "fixme" function was introduced to keep the backend compiling,
2523*d415bd75Srobert // while making changes to tablegen code.
DecodeFIXMEInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)2524*d415bd75Srobert static DecodeStatus DecodeFIXMEInstruction(MCInst &Inst, unsigned Insn,
2525*d415bd75Srobert uint64_t Address,
2526*d415bd75Srobert const MCDisassembler *Decoder) {
2527*d415bd75Srobert return MCDisassembler::Fail;
2528*d415bd75Srobert }
2529