171d5a254SDimitry Andric //===- MipsDisassembler.cpp - Disassembler for Mips -----------------------===//
2b61ab53cSDimitry Andric //
3e6d15924SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e6d15924SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5e6d15924SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6b61ab53cSDimitry Andric //
7b61ab53cSDimitry Andric //===----------------------------------------------------------------------===//
8b61ab53cSDimitry Andric //
9b61ab53cSDimitry Andric // This file is part of the Mips Disassembler.
10b61ab53cSDimitry Andric //
11b61ab53cSDimitry Andric //===----------------------------------------------------------------------===//
12b61ab53cSDimitry Andric
13044eb2f6SDimitry Andric #include "MCTargetDesc/MipsMCTargetDesc.h"
14b61ab53cSDimitry Andric #include "Mips.h"
15e6d15924SDimitry Andric #include "TargetInfo/MipsTargetInfo.h"
1671d5a254SDimitry Andric #include "llvm/ADT/ArrayRef.h"
175ca98fd9SDimitry Andric #include "llvm/MC/MCContext.h"
18145449b1SDimitry Andric #include "llvm/MC/MCDecoderOps.h"
1901095a5dSDimitry Andric #include "llvm/MC/MCDisassembler/MCDisassembler.h"
204a16efa3SDimitry Andric #include "llvm/MC/MCInst.h"
2171d5a254SDimitry Andric #include "llvm/MC/MCRegisterInfo.h"
227ab83427SDimitry Andric #include "llvm/MC/MCSubtargetInfo.h"
23c0981da4SDimitry Andric #include "llvm/MC/TargetRegistry.h"
2471d5a254SDimitry Andric #include "llvm/Support/Compiler.h"
2571d5a254SDimitry Andric #include "llvm/Support/Debug.h"
2671d5a254SDimitry Andric #include "llvm/Support/ErrorHandling.h"
274a16efa3SDimitry Andric #include "llvm/Support/MathExtras.h"
287ab83427SDimitry Andric #include "llvm/Support/raw_ostream.h"
2971d5a254SDimitry Andric #include <cassert>
3071d5a254SDimitry Andric #include <cstdint>
31b61ab53cSDimitry Andric
32b61ab53cSDimitry Andric using namespace llvm;
33b61ab53cSDimitry Andric
345ca98fd9SDimitry Andric #define DEBUG_TYPE "mips-disassembler"
355ca98fd9SDimitry Andric
36044eb2f6SDimitry Andric using DecodeStatus = MCDisassembler::DecodeStatus;
37b61ab53cSDimitry Andric
3858b69754SDimitry Andric namespace {
3958b69754SDimitry Andric
405a5ac124SDimitry Andric class MipsDisassembler : public MCDisassembler {
415a5ac124SDimitry Andric bool IsMicroMips;
425a5ac124SDimitry Andric bool IsBigEndian;
4371d5a254SDimitry Andric
44b61ab53cSDimitry Andric public:
MipsDisassembler(const MCSubtargetInfo & STI,MCContext & Ctx,bool IsBigEndian)455a5ac124SDimitry Andric MipsDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx, bool IsBigEndian)
4667c32a98SDimitry Andric : MCDisassembler(STI, Ctx),
477fa27ce4SDimitry Andric IsMicroMips(STI.hasFeature(Mips::FeatureMicroMips)),
4867c32a98SDimitry Andric IsBigEndian(IsBigEndian) {}
49b61ab53cSDimitry Andric
hasMips2() const507fa27ce4SDimitry Andric bool hasMips2() const { return STI.hasFeature(Mips::FeatureMips2); }
hasMips3() const517fa27ce4SDimitry Andric bool hasMips3() const { return STI.hasFeature(Mips::FeatureMips3); }
hasMips32() const527fa27ce4SDimitry Andric bool hasMips32() const { return STI.hasFeature(Mips::FeatureMips32); }
5371d5a254SDimitry Andric
hasMips32r6() const545ca98fd9SDimitry Andric bool hasMips32r6() const {
557fa27ce4SDimitry Andric return STI.hasFeature(Mips::FeatureMips32r6);
565ca98fd9SDimitry Andric }
5771d5a254SDimitry Andric
isFP64() const587fa27ce4SDimitry Andric bool isFP64() const { return STI.hasFeature(Mips::FeatureFP64Bit); }
595ca98fd9SDimitry Andric
isGP64() const607fa27ce4SDimitry Andric bool isGP64() const { return STI.hasFeature(Mips::FeatureGP64Bit); }
615ca98fd9SDimitry Andric
isPTR64() const627fa27ce4SDimitry Andric bool isPTR64() const { return STI.hasFeature(Mips::FeaturePTR64Bit); }
6301095a5dSDimitry Andric
hasCnMips() const647fa27ce4SDimitry Andric bool hasCnMips() const { return STI.hasFeature(Mips::FeatureCnMips); }
6585d8b2bbSDimitry Andric
hasCnMipsP() const667fa27ce4SDimitry Andric bool hasCnMipsP() const { return STI.hasFeature(Mips::FeatureCnMipsP); }
67706b4fc4SDimitry Andric
hasCOP3() const685ca98fd9SDimitry Andric bool hasCOP3() const {
695ca98fd9SDimitry Andric // Only present in MIPS-I and MIPS-II
705ca98fd9SDimitry Andric return !hasMips32() && !hasMips3();
715ca98fd9SDimitry Andric }
725ca98fd9SDimitry Andric
7367c32a98SDimitry Andric DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
7467c32a98SDimitry Andric ArrayRef<uint8_t> Bytes, uint64_t Address,
7567c32a98SDimitry Andric raw_ostream &CStream) const override;
76b61ab53cSDimitry Andric };
77b61ab53cSDimitry Andric
7858b69754SDimitry Andric } // end anonymous namespace
7958b69754SDimitry Andric
80b61ab53cSDimitry Andric // Forward declare these because the autogenerated code will reference them.
81b61ab53cSDimitry Andric // Definitions are further down.
82145449b1SDimitry Andric static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst, unsigned RegNo,
83b61ab53cSDimitry Andric uint64_t Address,
84145449b1SDimitry Andric const MCDisassembler *Decoder);
85b61ab53cSDimitry Andric
86145449b1SDimitry Andric static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst, unsigned RegNo,
874a16efa3SDimitry Andric uint64_t Address,
88145449b1SDimitry Andric const MCDisassembler *Decoder);
894a16efa3SDimitry Andric
90145449b1SDimitry Andric static DecodeStatus DecodeGPRMM16RegisterClass(MCInst &Inst, unsigned RegNo,
9167c32a98SDimitry Andric uint64_t Address,
92145449b1SDimitry Andric const MCDisassembler *Decoder);
9367c32a98SDimitry Andric
94145449b1SDimitry Andric static DecodeStatus
95145449b1SDimitry Andric DecodeGPRMM16ZeroRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address,
96145449b1SDimitry Andric const MCDisassembler *Decoder);
9767c32a98SDimitry Andric
98145449b1SDimitry Andric static DecodeStatus
99145449b1SDimitry Andric DecodeGPRMM16MovePRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address,
100145449b1SDimitry Andric const MCDisassembler *Decoder);
1015a5ac124SDimitry Andric
102145449b1SDimitry Andric static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst, unsigned RegNo,
103b61ab53cSDimitry Andric uint64_t Address,
104145449b1SDimitry Andric const MCDisassembler *Decoder);
105b61ab53cSDimitry Andric
106145449b1SDimitry Andric static DecodeStatus DecodePtrRegisterClass(MCInst &Inst, unsigned Insn,
107f8af5cf6SDimitry Andric uint64_t Address,
108145449b1SDimitry Andric const MCDisassembler *Decoder);
109f8af5cf6SDimitry Andric
110145449b1SDimitry Andric static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst, unsigned RegNo,
111522600a2SDimitry Andric uint64_t Address,
112145449b1SDimitry Andric const MCDisassembler *Decoder);
113522600a2SDimitry Andric
114145449b1SDimitry Andric static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst, unsigned RegNo,
115b61ab53cSDimitry Andric uint64_t Address,
116145449b1SDimitry Andric const MCDisassembler *Decoder);
117b61ab53cSDimitry Andric
118145449b1SDimitry Andric static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst, unsigned RegNo,
119b61ab53cSDimitry Andric uint64_t Address,
120145449b1SDimitry Andric const MCDisassembler *Decoder);
121b61ab53cSDimitry Andric
122145449b1SDimitry Andric static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst, unsigned RegNo,
123b61ab53cSDimitry Andric uint64_t Address,
124145449b1SDimitry Andric const MCDisassembler *Decoder);
125b61ab53cSDimitry Andric
126145449b1SDimitry Andric static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst, unsigned RegNo,
127f8af5cf6SDimitry Andric uint64_t Address,
128145449b1SDimitry Andric const MCDisassembler *Decoder);
129f8af5cf6SDimitry Andric
1305ca98fd9SDimitry Andric static DecodeStatus DecodeFGRCCRegisterClass(MCInst &Inst, unsigned RegNo,
1315ca98fd9SDimitry Andric uint64_t Address,
132145449b1SDimitry Andric const MCDisassembler *Decoder);
1335ca98fd9SDimitry Andric
134145449b1SDimitry Andric static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst, unsigned Insn,
135b61ab53cSDimitry Andric uint64_t Address,
136145449b1SDimitry Andric const MCDisassembler *Decoder);
137b61ab53cSDimitry Andric
138145449b1SDimitry Andric static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst, unsigned RegNo,
139b61ab53cSDimitry Andric uint64_t Address,
140145449b1SDimitry Andric const MCDisassembler *Decoder);
141b61ab53cSDimitry Andric
142145449b1SDimitry Andric static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst, unsigned RegNo,
143522600a2SDimitry Andric uint64_t Address,
144145449b1SDimitry Andric const MCDisassembler *Decoder);
145522600a2SDimitry Andric
146145449b1SDimitry Andric static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst, unsigned RegNo,
14759d6cff9SDimitry Andric uint64_t Address,
148145449b1SDimitry Andric const MCDisassembler *Decoder);
14959d6cff9SDimitry Andric
150145449b1SDimitry Andric static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst, unsigned RegNo,
151f8af5cf6SDimitry Andric uint64_t Address,
152145449b1SDimitry Andric const MCDisassembler *Decoder);
153f8af5cf6SDimitry Andric
154145449b1SDimitry Andric static DecodeStatus DecodeMSA128BRegisterClass(MCInst &Inst, unsigned RegNo,
155f8af5cf6SDimitry Andric uint64_t Address,
156145449b1SDimitry Andric const MCDisassembler *Decoder);
157f8af5cf6SDimitry Andric
158145449b1SDimitry Andric static DecodeStatus DecodeMSA128HRegisterClass(MCInst &Inst, unsigned RegNo,
159f8af5cf6SDimitry Andric uint64_t Address,
160145449b1SDimitry Andric const MCDisassembler *Decoder);
161f8af5cf6SDimitry Andric
162145449b1SDimitry Andric static DecodeStatus DecodeMSA128WRegisterClass(MCInst &Inst, unsigned RegNo,
163f8af5cf6SDimitry Andric uint64_t Address,
164145449b1SDimitry Andric const MCDisassembler *Decoder);
165f8af5cf6SDimitry Andric
166145449b1SDimitry Andric static DecodeStatus DecodeMSA128DRegisterClass(MCInst &Inst, unsigned RegNo,
167f8af5cf6SDimitry Andric uint64_t Address,
168145449b1SDimitry Andric const MCDisassembler *Decoder);
169f8af5cf6SDimitry Andric
170145449b1SDimitry Andric static DecodeStatus DecodeMSACtrlRegisterClass(MCInst &Inst, unsigned RegNo,
17159d6cff9SDimitry Andric uint64_t Address,
172145449b1SDimitry Andric const MCDisassembler *Decoder);
17359d6cff9SDimitry Andric
174145449b1SDimitry Andric static DecodeStatus DecodeCOP0RegisterClass(MCInst &Inst, unsigned RegNo,
1751a82d4c0SDimitry Andric uint64_t Address,
176145449b1SDimitry Andric const MCDisassembler *Decoder);
1771a82d4c0SDimitry Andric
178145449b1SDimitry Andric static DecodeStatus DecodeCOP2RegisterClass(MCInst &Inst, unsigned RegNo,
1795ca98fd9SDimitry Andric uint64_t Address,
180145449b1SDimitry Andric const MCDisassembler *Decoder);
1815ca98fd9SDimitry Andric
182145449b1SDimitry Andric static DecodeStatus DecodeBranchTarget(MCInst &Inst, unsigned Offset,
183b61ab53cSDimitry Andric uint64_t Address,
184145449b1SDimitry Andric const MCDisassembler *Decoder);
185b61ab53cSDimitry Andric
186145449b1SDimitry Andric static DecodeStatus DecodeBranchTarget1SImm16(MCInst &Inst, unsigned Offset,
18701095a5dSDimitry Andric uint64_t Address,
188145449b1SDimitry Andric const MCDisassembler *Decoder);
18901095a5dSDimitry Andric
190145449b1SDimitry Andric static DecodeStatus DecodeJumpTarget(MCInst &Inst, unsigned Insn,
191b61ab53cSDimitry Andric uint64_t Address,
192145449b1SDimitry Andric const MCDisassembler *Decoder);
193b61ab53cSDimitry Andric
194145449b1SDimitry Andric static DecodeStatus DecodeBranchTarget21(MCInst &Inst, unsigned Offset,
1955ca98fd9SDimitry Andric uint64_t Address,
196145449b1SDimitry Andric const MCDisassembler *Decoder);
1975ca98fd9SDimitry Andric
198145449b1SDimitry Andric static DecodeStatus DecodeBranchTarget21MM(MCInst &Inst, unsigned Offset,
19901095a5dSDimitry Andric uint64_t Address,
200145449b1SDimitry Andric const MCDisassembler *Decoder);
20101095a5dSDimitry Andric
202145449b1SDimitry Andric static DecodeStatus DecodeBranchTarget26(MCInst &Inst, unsigned Offset,
2035ca98fd9SDimitry Andric uint64_t Address,
204145449b1SDimitry Andric const MCDisassembler *Decoder);
2055ca98fd9SDimitry Andric
20667c32a98SDimitry Andric // DecodeBranchTarget7MM - Decode microMIPS branch offset, which is
20767c32a98SDimitry Andric // shifted left by 1 bit.
208145449b1SDimitry Andric static DecodeStatus DecodeBranchTarget7MM(MCInst &Inst, unsigned Offset,
20967c32a98SDimitry Andric uint64_t Address,
210145449b1SDimitry Andric const MCDisassembler *Decoder);
21167c32a98SDimitry Andric
2125a5ac124SDimitry Andric // DecodeBranchTarget10MM - Decode microMIPS branch offset, which is
2135a5ac124SDimitry Andric // shifted left by 1 bit.
214145449b1SDimitry Andric static DecodeStatus DecodeBranchTarget10MM(MCInst &Inst, unsigned Offset,
2155a5ac124SDimitry Andric uint64_t Address,
216145449b1SDimitry Andric const MCDisassembler *Decoder);
2175a5ac124SDimitry Andric
218f8af5cf6SDimitry Andric // DecodeBranchTargetMM - Decode microMIPS branch offset, which is
219f8af5cf6SDimitry Andric // shifted left by 1 bit.
220145449b1SDimitry Andric static DecodeStatus DecodeBranchTargetMM(MCInst &Inst, unsigned Offset,
221f8af5cf6SDimitry Andric uint64_t Address,
222145449b1SDimitry Andric const MCDisassembler *Decoder);
223f8af5cf6SDimitry Andric
224dd58ef01SDimitry Andric // DecodeBranchTarget26MM - Decode microMIPS branch offset, which is
225dd58ef01SDimitry Andric // shifted left by 1 bit.
226145449b1SDimitry Andric static DecodeStatus DecodeBranchTarget26MM(MCInst &Inst, unsigned Offset,
227dd58ef01SDimitry Andric uint64_t Address,
228145449b1SDimitry Andric const MCDisassembler *Decoder);
229dd58ef01SDimitry Andric
230f8af5cf6SDimitry Andric // DecodeJumpTargetMM - Decode microMIPS jump target, which is
231f8af5cf6SDimitry Andric // shifted left by 1 bit.
232145449b1SDimitry Andric static DecodeStatus DecodeJumpTargetMM(MCInst &Inst, unsigned Insn,
233f8af5cf6SDimitry Andric uint64_t Address,
234145449b1SDimitry Andric const MCDisassembler *Decoder);
235f8af5cf6SDimitry Andric
2361d5ae102SDimitry Andric // DecodeJumpTargetXMM - Decode microMIPS jump and link exchange target,
2371d5ae102SDimitry Andric // which is shifted left by 2 bit.
238145449b1SDimitry Andric static DecodeStatus DecodeJumpTargetXMM(MCInst &Inst, unsigned Insn,
2391d5ae102SDimitry Andric uint64_t Address,
240145449b1SDimitry Andric const MCDisassembler *Decoder);
2411d5ae102SDimitry Andric
242145449b1SDimitry Andric static DecodeStatus DecodeMem(MCInst &Inst, unsigned Insn, uint64_t Address,
243145449b1SDimitry Andric const MCDisassembler *Decoder);
244b61ab53cSDimitry Andric
245145449b1SDimitry Andric static DecodeStatus DecodeMemEVA(MCInst &Inst, unsigned Insn, uint64_t Address,
246145449b1SDimitry Andric const MCDisassembler *Decoder);
247dd58ef01SDimitry Andric
248145449b1SDimitry Andric static DecodeStatus DecodeLoadByte15(MCInst &Inst, unsigned Insn,
249dd58ef01SDimitry Andric uint64_t Address,
250145449b1SDimitry Andric const MCDisassembler *Decoder);
251dd58ef01SDimitry Andric
252044eb2f6SDimitry Andric static DecodeStatus DecodeCacheOp(MCInst &Inst, unsigned Insn, uint64_t Address,
253145449b1SDimitry Andric const MCDisassembler *Decoder);
2549f619479SDimitry Andric
255145449b1SDimitry Andric static DecodeStatus DecodeCacheeOp_CacheOpR6(MCInst &Inst, unsigned Insn,
256f03b5bedSDimitry Andric uint64_t Address,
257145449b1SDimitry Andric const MCDisassembler *Decoder);
258f03b5bedSDimitry Andric
259145449b1SDimitry Andric static DecodeStatus DecodeCacheOpMM(MCInst &Inst, unsigned Insn,
26067c32a98SDimitry Andric uint64_t Address,
261145449b1SDimitry Andric const MCDisassembler *Decoder);
26267c32a98SDimitry Andric
263145449b1SDimitry Andric static DecodeStatus DecodePrefeOpMM(MCInst &Inst, unsigned Insn,
264dd58ef01SDimitry Andric uint64_t Address,
265145449b1SDimitry Andric const MCDisassembler *Decoder);
266dd58ef01SDimitry Andric
267145449b1SDimitry Andric static DecodeStatus DecodeSyncI(MCInst &Inst, unsigned Insn, uint64_t Address,
268145449b1SDimitry Andric const MCDisassembler *Decoder);
26967c32a98SDimitry Andric
270145449b1SDimitry Andric static DecodeStatus DecodeSyncI_MM(MCInst &Inst, unsigned Insn,
271eb11fae6SDimitry Andric uint64_t Address,
272145449b1SDimitry Andric const MCDisassembler *Decoder);
273eb11fae6SDimitry Andric
274145449b1SDimitry Andric static DecodeStatus DecodeSynciR6(MCInst &Inst, unsigned Insn, uint64_t Address,
275145449b1SDimitry Andric const MCDisassembler *Decoder);
276dd58ef01SDimitry Andric
277f8af5cf6SDimitry Andric static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn,
27867c32a98SDimitry Andric uint64_t Address,
279145449b1SDimitry Andric const MCDisassembler *Decoder);
28067c32a98SDimitry Andric
281145449b1SDimitry Andric static DecodeStatus DecodeMemMMImm4(MCInst &Inst, unsigned Insn,
28267c32a98SDimitry Andric uint64_t Address,
283145449b1SDimitry Andric const MCDisassembler *Decoder);
28467c32a98SDimitry Andric
285145449b1SDimitry Andric static DecodeStatus DecodeMemMMSPImm5Lsl2(MCInst &Inst, unsigned Insn,
2865a5ac124SDimitry Andric uint64_t Address,
287145449b1SDimitry Andric const MCDisassembler *Decoder);
2885a5ac124SDimitry Andric
289145449b1SDimitry Andric static DecodeStatus DecodeMemMMGPImm7Lsl2(MCInst &Inst, unsigned Insn,
2905a5ac124SDimitry Andric uint64_t Address,
291145449b1SDimitry Andric const MCDisassembler *Decoder);
2925a5ac124SDimitry Andric
293145449b1SDimitry Andric static DecodeStatus DecodeMemMMReglistImm4Lsl2(MCInst &Inst, unsigned Insn,
294dd58ef01SDimitry Andric uint64_t Address,
295145449b1SDimitry Andric const MCDisassembler *Decoder);
296dd58ef01SDimitry Andric
297145449b1SDimitry Andric static DecodeStatus DecodeMemMMImm9(MCInst &Inst, unsigned Insn,
298f8af5cf6SDimitry Andric uint64_t Address,
299145449b1SDimitry Andric const MCDisassembler *Decoder);
300f8af5cf6SDimitry Andric
301145449b1SDimitry Andric static DecodeStatus DecodeMemMMImm12(MCInst &Inst, unsigned Insn,
302f8af5cf6SDimitry Andric uint64_t Address,
303145449b1SDimitry Andric const MCDisassembler *Decoder);
304f8af5cf6SDimitry Andric
305145449b1SDimitry Andric static DecodeStatus DecodeMemMMImm16(MCInst &Inst, unsigned Insn,
306b61ab53cSDimitry Andric uint64_t Address,
307145449b1SDimitry Andric const MCDisassembler *Decoder);
308145449b1SDimitry Andric
309145449b1SDimitry Andric static DecodeStatus DecodeFMem(MCInst &Inst, unsigned Insn, uint64_t Address,
310145449b1SDimitry Andric const MCDisassembler *Decoder);
311b61ab53cSDimitry Andric
31201095a5dSDimitry Andric static DecodeStatus DecodeFMemMMR2(MCInst &Inst, unsigned Insn,
31301095a5dSDimitry Andric uint64_t Address,
314145449b1SDimitry Andric const MCDisassembler *Decoder);
31501095a5dSDimitry Andric
316044eb2f6SDimitry Andric static DecodeStatus DecodeFMem2(MCInst &Inst, unsigned Insn, uint64_t Address,
317145449b1SDimitry Andric const MCDisassembler *Decoder);
3189f619479SDimitry Andric
319044eb2f6SDimitry Andric static DecodeStatus DecodeFMem3(MCInst &Inst, unsigned Insn, uint64_t Address,
320145449b1SDimitry Andric const MCDisassembler *Decoder);
3219f619479SDimitry Andric
322f03b5bedSDimitry Andric static DecodeStatus DecodeFMemCop2R6(MCInst &Inst, unsigned Insn,
323145449b1SDimitry Andric uint64_t Address,
324145449b1SDimitry Andric const MCDisassembler *Decoder);
325f03b5bedSDimitry Andric
32601095a5dSDimitry Andric static DecodeStatus DecodeFMemCop2MMR6(MCInst &Inst, unsigned Insn,
32701095a5dSDimitry Andric uint64_t Address,
328145449b1SDimitry Andric const MCDisassembler *Decoder);
32901095a5dSDimitry Andric
330145449b1SDimitry Andric static DecodeStatus DecodeSpecial3LlSc(MCInst &Inst, unsigned Insn,
3315ca98fd9SDimitry Andric uint64_t Address,
332145449b1SDimitry Andric const MCDisassembler *Decoder);
3335ca98fd9SDimitry Andric
334145449b1SDimitry Andric static DecodeStatus DecodeAddiur2Simm7(MCInst &Inst, unsigned Value,
33567c32a98SDimitry Andric uint64_t Address,
336145449b1SDimitry Andric const MCDisassembler *Decoder);
33767c32a98SDimitry Andric
338145449b1SDimitry Andric static DecodeStatus DecodeLi16Imm(MCInst &Inst, unsigned Value,
33967c32a98SDimitry Andric uint64_t Address,
340145449b1SDimitry Andric const MCDisassembler *Decoder);
34167c32a98SDimitry Andric
342145449b1SDimitry Andric static DecodeStatus DecodePOOL16BEncodedField(MCInst &Inst, unsigned Value,
343dd58ef01SDimitry Andric uint64_t Address,
344145449b1SDimitry Andric const MCDisassembler *Decoder);
345dd58ef01SDimitry Andric
34601095a5dSDimitry Andric template <unsigned Bits, int Offset, int Scale>
34701095a5dSDimitry Andric static DecodeStatus DecodeUImmWithOffsetAndScale(MCInst &Inst, unsigned Value,
348b61ab53cSDimitry Andric uint64_t Address,
349145449b1SDimitry Andric const MCDisassembler *Decoder);
350b61ab53cSDimitry Andric
351dd58ef01SDimitry Andric template <unsigned Bits, int Offset>
DecodeUImmWithOffset(MCInst & Inst,unsigned Value,uint64_t Address,const MCDisassembler * Decoder)352dd58ef01SDimitry Andric static DecodeStatus DecodeUImmWithOffset(MCInst &Inst, unsigned Value,
35301095a5dSDimitry Andric uint64_t Address,
354145449b1SDimitry Andric const MCDisassembler *Decoder) {
35501095a5dSDimitry Andric return DecodeUImmWithOffsetAndScale<Bits, Offset, 1>(Inst, Value, Address,
35601095a5dSDimitry Andric Decoder);
35701095a5dSDimitry Andric }
35801095a5dSDimitry Andric
35901095a5dSDimitry Andric template <unsigned Bits, int Offset = 0, int ScaleBy = 1>
36001095a5dSDimitry Andric static DecodeStatus DecodeSImmWithOffsetAndScale(MCInst &Inst, unsigned Value,
36101095a5dSDimitry Andric uint64_t Address,
362145449b1SDimitry Andric const MCDisassembler *Decoder);
363b61ab53cSDimitry Andric
364145449b1SDimitry Andric static DecodeStatus DecodeInsSize(MCInst &Inst, unsigned Insn, uint64_t Address,
365145449b1SDimitry Andric const MCDisassembler *Decoder);
366b61ab53cSDimitry Andric
3675ca98fd9SDimitry Andric static DecodeStatus DecodeSimm19Lsl2(MCInst &Inst, unsigned Insn,
368145449b1SDimitry Andric uint64_t Address,
369145449b1SDimitry Andric const MCDisassembler *Decoder);
3705ca98fd9SDimitry Andric
3715ca98fd9SDimitry Andric static DecodeStatus DecodeSimm18Lsl3(MCInst &Inst, unsigned Insn,
372145449b1SDimitry Andric uint64_t Address,
373145449b1SDimitry Andric const MCDisassembler *Decoder);
3745ca98fd9SDimitry Andric
375145449b1SDimitry Andric static DecodeStatus DecodeSimm9SP(MCInst &Inst, unsigned Insn, uint64_t Address,
376145449b1SDimitry Andric const MCDisassembler *Decoder);
37767c32a98SDimitry Andric
37867c32a98SDimitry Andric static DecodeStatus DecodeANDI16Imm(MCInst &Inst, unsigned Insn,
379145449b1SDimitry Andric uint64_t Address,
380145449b1SDimitry Andric const MCDisassembler *Decoder);
38167c32a98SDimitry Andric
3825a5ac124SDimitry Andric static DecodeStatus DecodeSimm23Lsl2(MCInst &Inst, unsigned Insn,
383145449b1SDimitry Andric uint64_t Address,
384145449b1SDimitry Andric const MCDisassembler *Decoder);
3855a5ac124SDimitry Andric
3865ca98fd9SDimitry Andric /// INSVE_[BHWD] have an implicit operand that the generated decoder doesn't
3875ca98fd9SDimitry Andric /// handle.
3885ca98fd9SDimitry Andric template <typename InsnType>
3895ca98fd9SDimitry Andric static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address,
390145449b1SDimitry Andric const MCDisassembler *Decoder);
3915ca98fd9SDimitry Andric
3925ca98fd9SDimitry Andric template <typename InsnType>
393706b4fc4SDimitry Andric static DecodeStatus DecodeDAHIDATIMMR6(MCInst &MI, InsnType insn,
394145449b1SDimitry Andric uint64_t Address,
395145449b1SDimitry Andric const MCDisassembler *Decoder);
396b915e9e0SDimitry Andric
397b915e9e0SDimitry Andric template <typename InsnType>
398b915e9e0SDimitry Andric static DecodeStatus DecodeDAHIDATI(MCInst &MI, InsnType insn, uint64_t Address,
399145449b1SDimitry Andric const MCDisassembler *Decoder);
400b915e9e0SDimitry Andric
401b915e9e0SDimitry Andric template <typename InsnType>
402145449b1SDimitry Andric static DecodeStatus DecodeAddiGroupBranch(MCInst &MI, InsnType insn,
403145449b1SDimitry Andric uint64_t Address,
404145449b1SDimitry Andric const MCDisassembler *Decoder);
4055ca98fd9SDimitry Andric
4065ca98fd9SDimitry Andric template <typename InsnType>
407145449b1SDimitry Andric static DecodeStatus DecodePOP35GroupBranchMMR6(MCInst &MI, InsnType insn,
408145449b1SDimitry Andric uint64_t Address,
409145449b1SDimitry Andric const MCDisassembler *Decoder);
41001095a5dSDimitry Andric
41101095a5dSDimitry Andric template <typename InsnType>
412145449b1SDimitry Andric static DecodeStatus DecodeDaddiGroupBranch(MCInst &MI, InsnType insn,
413145449b1SDimitry Andric uint64_t Address,
414145449b1SDimitry Andric const MCDisassembler *Decoder);
4155ca98fd9SDimitry Andric
4165ca98fd9SDimitry Andric template <typename InsnType>
417145449b1SDimitry Andric static DecodeStatus DecodePOP37GroupBranchMMR6(MCInst &MI, InsnType insn,
418145449b1SDimitry Andric uint64_t Address,
419145449b1SDimitry Andric const MCDisassembler *Decoder);
42001095a5dSDimitry Andric
42101095a5dSDimitry Andric template <typename InsnType>
422145449b1SDimitry Andric static DecodeStatus DecodePOP65GroupBranchMMR6(MCInst &MI, InsnType insn,
423145449b1SDimitry Andric uint64_t Address,
424145449b1SDimitry Andric const MCDisassembler *Decoder);
425b915e9e0SDimitry Andric
426b915e9e0SDimitry Andric template <typename InsnType>
427145449b1SDimitry Andric static DecodeStatus DecodePOP75GroupBranchMMR6(MCInst &MI, InsnType insn,
428145449b1SDimitry Andric uint64_t Address,
429145449b1SDimitry Andric const MCDisassembler *Decoder);
430b915e9e0SDimitry Andric
431b915e9e0SDimitry Andric template <typename InsnType>
432145449b1SDimitry Andric static DecodeStatus DecodeBlezlGroupBranch(MCInst &MI, InsnType insn,
433145449b1SDimitry Andric uint64_t Address,
434145449b1SDimitry Andric const MCDisassembler *Decoder);
4355ca98fd9SDimitry Andric
4365ca98fd9SDimitry Andric template <typename InsnType>
437145449b1SDimitry Andric static DecodeStatus DecodeBgtzlGroupBranch(MCInst &MI, InsnType insn,
438145449b1SDimitry Andric uint64_t Address,
439145449b1SDimitry Andric const MCDisassembler *Decoder);
4405ca98fd9SDimitry Andric
4415ca98fd9SDimitry Andric template <typename InsnType>
442145449b1SDimitry Andric static DecodeStatus DecodeBgtzGroupBranch(MCInst &MI, InsnType insn,
443145449b1SDimitry Andric uint64_t Address,
444145449b1SDimitry Andric const MCDisassembler *Decoder);
4455ca98fd9SDimitry Andric
4465ca98fd9SDimitry Andric template <typename InsnType>
447145449b1SDimitry Andric static DecodeStatus DecodeBlezGroupBranch(MCInst &MI, InsnType insn,
448145449b1SDimitry Andric uint64_t Address,
449145449b1SDimitry Andric const MCDisassembler *Decoder);
4505ca98fd9SDimitry Andric
45101095a5dSDimitry Andric template <typename InsnType>
452145449b1SDimitry Andric static DecodeStatus DecodeBgtzGroupBranchMMR6(MCInst &MI, InsnType insn,
453145449b1SDimitry Andric uint64_t Address,
454145449b1SDimitry Andric const MCDisassembler *Decoder);
45501095a5dSDimitry Andric
45601095a5dSDimitry Andric template <typename InsnType>
457145449b1SDimitry Andric static DecodeStatus DecodeBlezGroupBranchMMR6(MCInst &MI, InsnType insn,
458145449b1SDimitry Andric uint64_t Address,
459145449b1SDimitry Andric const MCDisassembler *Decoder);
46001095a5dSDimitry Andric
461044eb2f6SDimitry Andric template <typename InsnType>
462044eb2f6SDimitry Andric static DecodeStatus DecodeDINS(MCInst &MI, InsnType Insn, uint64_t Address,
463145449b1SDimitry Andric const MCDisassembler *Decoder);
464044eb2f6SDimitry Andric
465044eb2f6SDimitry Andric template <typename InsnType>
466044eb2f6SDimitry Andric static DecodeStatus DecodeDEXT(MCInst &MI, InsnType Insn, uint64_t Address,
467145449b1SDimitry Andric const MCDisassembler *Decoder);
468044eb2f6SDimitry Andric
469eb11fae6SDimitry Andric template <typename InsnType>
470eb11fae6SDimitry Andric static DecodeStatus DecodeCRC(MCInst &MI, InsnType Insn, uint64_t Address,
471145449b1SDimitry Andric const MCDisassembler *Decoder);
472eb11fae6SDimitry Andric
47367c32a98SDimitry Andric static DecodeStatus DecodeRegListOperand(MCInst &Inst, unsigned Insn,
47467c32a98SDimitry Andric uint64_t Address,
475145449b1SDimitry Andric const MCDisassembler *Decoder);
47667c32a98SDimitry Andric
47767c32a98SDimitry Andric static DecodeStatus DecodeRegListOperand16(MCInst &Inst, unsigned Insn,
47867c32a98SDimitry Andric uint64_t Address,
479145449b1SDimitry Andric const MCDisassembler *Decoder);
48067c32a98SDimitry Andric
481044eb2f6SDimitry Andric static DecodeStatus DecodeMovePRegPair(MCInst &Inst, unsigned RegPair,
4825a5ac124SDimitry Andric uint64_t Address,
483145449b1SDimitry Andric const MCDisassembler *Decoder);
4845a5ac124SDimitry Andric
485d8e91e46SDimitry Andric static DecodeStatus DecodeMovePOperands(MCInst &Inst, unsigned Insn,
486145449b1SDimitry Andric uint64_t Address,
487145449b1SDimitry Andric const MCDisassembler *Decoder);
488d8e91e46SDimitry Andric
489e3b55780SDimitry Andric static DecodeStatus DecodeFIXMEInstruction(MCInst &Inst, unsigned Insn,
490e3b55780SDimitry Andric uint64_t Address,
491e3b55780SDimitry Andric const MCDisassembler *Decoder);
492e3b55780SDimitry Andric
createMipsDisassembler(const Target & T,const MCSubtargetInfo & STI,MCContext & Ctx)493b61ab53cSDimitry Andric static MCDisassembler *createMipsDisassembler(
494b61ab53cSDimitry Andric const Target &T,
4955ca98fd9SDimitry Andric const MCSubtargetInfo &STI,
4965ca98fd9SDimitry Andric MCContext &Ctx) {
4975ca98fd9SDimitry Andric return new MipsDisassembler(STI, Ctx, true);
498b61ab53cSDimitry Andric }
499b61ab53cSDimitry Andric
createMipselDisassembler(const Target & T,const MCSubtargetInfo & STI,MCContext & Ctx)500b61ab53cSDimitry Andric static MCDisassembler *createMipselDisassembler(
501b61ab53cSDimitry Andric const Target &T,
5025ca98fd9SDimitry Andric const MCSubtargetInfo &STI,
5035ca98fd9SDimitry Andric MCContext &Ctx) {
5045ca98fd9SDimitry Andric return new MipsDisassembler(STI, Ctx, false);
505b61ab53cSDimitry Andric }
506b61ab53cSDimitry Andric
LLVMInitializeMipsDisassembler()507706b4fc4SDimitry Andric extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeMipsDisassembler() {
508b61ab53cSDimitry Andric // Register the disassembler.
509b915e9e0SDimitry Andric TargetRegistry::RegisterMCDisassembler(getTheMipsTarget(),
510b61ab53cSDimitry Andric createMipsDisassembler);
511b915e9e0SDimitry Andric TargetRegistry::RegisterMCDisassembler(getTheMipselTarget(),
512b61ab53cSDimitry Andric createMipselDisassembler);
513b915e9e0SDimitry Andric TargetRegistry::RegisterMCDisassembler(getTheMips64Target(),
5145a5ac124SDimitry Andric createMipsDisassembler);
515b915e9e0SDimitry Andric TargetRegistry::RegisterMCDisassembler(getTheMips64elTarget(),
5165a5ac124SDimitry Andric createMipselDisassembler);
517b61ab53cSDimitry Andric }
518b61ab53cSDimitry Andric
519b61ab53cSDimitry Andric #include "MipsGenDisassemblerTables.inc"
520b61ab53cSDimitry Andric
getReg(const MCDisassembler * D,unsigned RC,unsigned RegNo)521145449b1SDimitry Andric static unsigned getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo) {
522145449b1SDimitry Andric const MCRegisterInfo *RegInfo = D->getContext().getRegisterInfo();
5235ca98fd9SDimitry Andric return *(RegInfo->getRegClass(RC).begin() + RegNo);
5245ca98fd9SDimitry Andric }
5255ca98fd9SDimitry Andric
5265ca98fd9SDimitry Andric template <typename InsnType>
DecodeINSVE_DF(MCInst & MI,InsnType insn,uint64_t Address,const MCDisassembler * Decoder)5275ca98fd9SDimitry Andric static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address,
528145449b1SDimitry Andric const MCDisassembler *Decoder) {
529145449b1SDimitry Andric using DecodeFN =
530145449b1SDimitry Andric DecodeStatus (*)(MCInst &, unsigned, uint64_t, const MCDisassembler *);
531044eb2f6SDimitry Andric
5325ca98fd9SDimitry Andric // The size of the n field depends on the element size
5335ca98fd9SDimitry Andric // The register class also depends on this.
5345ca98fd9SDimitry Andric InsnType tmp = fieldFromInstruction(insn, 17, 5);
5355ca98fd9SDimitry Andric unsigned NSize = 0;
5365ca98fd9SDimitry Andric DecodeFN RegDecoder = nullptr;
5375ca98fd9SDimitry Andric if ((tmp & 0x18) == 0x00) { // INSVE_B
5385ca98fd9SDimitry Andric NSize = 4;
5395ca98fd9SDimitry Andric RegDecoder = DecodeMSA128BRegisterClass;
5405ca98fd9SDimitry Andric } else if ((tmp & 0x1c) == 0x10) { // INSVE_H
5415ca98fd9SDimitry Andric NSize = 3;
5425ca98fd9SDimitry Andric RegDecoder = DecodeMSA128HRegisterClass;
5435ca98fd9SDimitry Andric } else if ((tmp & 0x1e) == 0x18) { // INSVE_W
5445ca98fd9SDimitry Andric NSize = 2;
5455ca98fd9SDimitry Andric RegDecoder = DecodeMSA128WRegisterClass;
5465ca98fd9SDimitry Andric } else if ((tmp & 0x1f) == 0x1c) { // INSVE_D
5475ca98fd9SDimitry Andric NSize = 1;
5485ca98fd9SDimitry Andric RegDecoder = DecodeMSA128DRegisterClass;
5495ca98fd9SDimitry Andric } else
5505ca98fd9SDimitry Andric llvm_unreachable("Invalid encoding");
5515ca98fd9SDimitry Andric
5525ca98fd9SDimitry Andric assert(NSize != 0 && RegDecoder != nullptr);
5535ca98fd9SDimitry Andric
5545ca98fd9SDimitry Andric // $wd
5555ca98fd9SDimitry Andric tmp = fieldFromInstruction(insn, 6, 5);
5565ca98fd9SDimitry Andric if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
5575ca98fd9SDimitry Andric return MCDisassembler::Fail;
5585ca98fd9SDimitry Andric // $wd_in
5595ca98fd9SDimitry Andric if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
5605ca98fd9SDimitry Andric return MCDisassembler::Fail;
5615ca98fd9SDimitry Andric // $n
5625ca98fd9SDimitry Andric tmp = fieldFromInstruction(insn, 16, NSize);
5635a5ac124SDimitry Andric MI.addOperand(MCOperand::createImm(tmp));
5645ca98fd9SDimitry Andric // $ws
5655ca98fd9SDimitry Andric tmp = fieldFromInstruction(insn, 11, 5);
5665ca98fd9SDimitry Andric if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
5675ca98fd9SDimitry Andric return MCDisassembler::Fail;
5685ca98fd9SDimitry Andric // $n2
5695a5ac124SDimitry Andric MI.addOperand(MCOperand::createImm(0));
5705ca98fd9SDimitry Andric
5715ca98fd9SDimitry Andric return MCDisassembler::Success;
5725ca98fd9SDimitry Andric }
5735ca98fd9SDimitry Andric
5745ca98fd9SDimitry Andric template <typename InsnType>
DecodeDAHIDATIMMR6(MCInst & MI,InsnType insn,uint64_t Address,const MCDisassembler * Decoder)575706b4fc4SDimitry Andric static DecodeStatus DecodeDAHIDATIMMR6(MCInst &MI, InsnType insn,
576145449b1SDimitry Andric uint64_t Address,
577145449b1SDimitry Andric const MCDisassembler *Decoder) {
578b915e9e0SDimitry Andric InsnType Rs = fieldFromInstruction(insn, 16, 5);
579b915e9e0SDimitry Andric InsnType Imm = fieldFromInstruction(insn, 0, 16);
580b915e9e0SDimitry Andric MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID,
581b915e9e0SDimitry Andric Rs)));
582b915e9e0SDimitry Andric MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID,
583b915e9e0SDimitry Andric Rs)));
584b915e9e0SDimitry Andric MI.addOperand(MCOperand::createImm(Imm));
585b915e9e0SDimitry Andric
586b915e9e0SDimitry Andric return MCDisassembler::Success;
587b915e9e0SDimitry Andric }
588b915e9e0SDimitry Andric
589b915e9e0SDimitry Andric template <typename InsnType>
DecodeDAHIDATI(MCInst & MI,InsnType insn,uint64_t Address,const MCDisassembler * Decoder)590b915e9e0SDimitry Andric static DecodeStatus DecodeDAHIDATI(MCInst &MI, InsnType insn, uint64_t Address,
591145449b1SDimitry Andric const MCDisassembler *Decoder) {
592b915e9e0SDimitry Andric InsnType Rs = fieldFromInstruction(insn, 21, 5);
593b915e9e0SDimitry Andric InsnType Imm = fieldFromInstruction(insn, 0, 16);
594b915e9e0SDimitry Andric MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID,
595b915e9e0SDimitry Andric Rs)));
596b915e9e0SDimitry Andric MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID,
597b915e9e0SDimitry Andric Rs)));
598b915e9e0SDimitry Andric MI.addOperand(MCOperand::createImm(Imm));
599b915e9e0SDimitry Andric
600b915e9e0SDimitry Andric return MCDisassembler::Success;
601b915e9e0SDimitry Andric }
602b915e9e0SDimitry Andric
603b915e9e0SDimitry Andric template <typename InsnType>
DecodeAddiGroupBranch(MCInst & MI,InsnType insn,uint64_t Address,const MCDisassembler * Decoder)6045ca98fd9SDimitry Andric static DecodeStatus DecodeAddiGroupBranch(MCInst &MI, InsnType insn,
6055ca98fd9SDimitry Andric uint64_t Address,
606145449b1SDimitry Andric const MCDisassembler *Decoder) {
6075ca98fd9SDimitry Andric // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
6085ca98fd9SDimitry Andric // (otherwise we would have matched the ADDI instruction from the earlier
6095ca98fd9SDimitry Andric // ISA's instead).
6105ca98fd9SDimitry Andric //
6115ca98fd9SDimitry Andric // We have:
6125ca98fd9SDimitry Andric // 0b001000 sssss ttttt iiiiiiiiiiiiiiii
6135ca98fd9SDimitry Andric // BOVC if rs >= rt
6145ca98fd9SDimitry Andric // BEQZALC if rs == 0 && rt != 0
6155ca98fd9SDimitry Andric // BEQC if rs < rt && rs != 0
6165ca98fd9SDimitry Andric
6175ca98fd9SDimitry Andric InsnType Rs = fieldFromInstruction(insn, 21, 5);
6185ca98fd9SDimitry Andric InsnType Rt = fieldFromInstruction(insn, 16, 5);
61901095a5dSDimitry Andric int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
6205ca98fd9SDimitry Andric bool HasRs = false;
6215ca98fd9SDimitry Andric
6225ca98fd9SDimitry Andric if (Rs >= Rt) {
6235ca98fd9SDimitry Andric MI.setOpcode(Mips::BOVC);
6245ca98fd9SDimitry Andric HasRs = true;
6255ca98fd9SDimitry Andric } else if (Rs != 0 && Rs < Rt) {
6265ca98fd9SDimitry Andric MI.setOpcode(Mips::BEQC);
6275ca98fd9SDimitry Andric HasRs = true;
6285ca98fd9SDimitry Andric } else
6295ca98fd9SDimitry Andric MI.setOpcode(Mips::BEQZALC);
6305ca98fd9SDimitry Andric
6315ca98fd9SDimitry Andric if (HasRs)
6325a5ac124SDimitry Andric MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
6335ca98fd9SDimitry Andric Rs)));
6345ca98fd9SDimitry Andric
6355a5ac124SDimitry Andric MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
6365ca98fd9SDimitry Andric Rt)));
6375a5ac124SDimitry Andric MI.addOperand(MCOperand::createImm(Imm));
6385ca98fd9SDimitry Andric
6395ca98fd9SDimitry Andric return MCDisassembler::Success;
6405ca98fd9SDimitry Andric }
6415ca98fd9SDimitry Andric
6425ca98fd9SDimitry Andric template <typename InsnType>
DecodePOP35GroupBranchMMR6(MCInst & MI,InsnType insn,uint64_t Address,const MCDisassembler * Decoder)64301095a5dSDimitry Andric static DecodeStatus DecodePOP35GroupBranchMMR6(MCInst &MI, InsnType insn,
64401095a5dSDimitry Andric uint64_t Address,
645145449b1SDimitry Andric const MCDisassembler *Decoder) {
64601095a5dSDimitry Andric InsnType Rt = fieldFromInstruction(insn, 21, 5);
64701095a5dSDimitry Andric InsnType Rs = fieldFromInstruction(insn, 16, 5);
648b915e9e0SDimitry Andric int64_t Imm = 0;
64901095a5dSDimitry Andric
65001095a5dSDimitry Andric if (Rs >= Rt) {
65101095a5dSDimitry Andric MI.setOpcode(Mips::BOVC_MMR6);
65201095a5dSDimitry Andric MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
65301095a5dSDimitry Andric Rt)));
65401095a5dSDimitry Andric MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
65501095a5dSDimitry Andric Rs)));
656b915e9e0SDimitry Andric Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
65701095a5dSDimitry Andric } else if (Rs != 0 && Rs < Rt) {
65801095a5dSDimitry Andric MI.setOpcode(Mips::BEQC_MMR6);
65901095a5dSDimitry Andric MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
66001095a5dSDimitry Andric Rs)));
66101095a5dSDimitry Andric MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
66201095a5dSDimitry Andric Rt)));
663b915e9e0SDimitry Andric Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
66401095a5dSDimitry Andric } else {
66501095a5dSDimitry Andric MI.setOpcode(Mips::BEQZALC_MMR6);
66601095a5dSDimitry Andric MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
66701095a5dSDimitry Andric Rt)));
668b915e9e0SDimitry Andric Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
66901095a5dSDimitry Andric }
67001095a5dSDimitry Andric
67101095a5dSDimitry Andric MI.addOperand(MCOperand::createImm(Imm));
67201095a5dSDimitry Andric
67301095a5dSDimitry Andric return MCDisassembler::Success;
67401095a5dSDimitry Andric }
67501095a5dSDimitry Andric
67601095a5dSDimitry Andric template <typename InsnType>
DecodeDaddiGroupBranch(MCInst & MI,InsnType insn,uint64_t Address,const MCDisassembler * Decoder)6775ca98fd9SDimitry Andric static DecodeStatus DecodeDaddiGroupBranch(MCInst &MI, InsnType insn,
6785ca98fd9SDimitry Andric uint64_t Address,
679145449b1SDimitry Andric const MCDisassembler *Decoder) {
6805ca98fd9SDimitry Andric // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
6815ca98fd9SDimitry Andric // (otherwise we would have matched the ADDI instruction from the earlier
6825ca98fd9SDimitry Andric // ISA's instead).
6835ca98fd9SDimitry Andric //
6845ca98fd9SDimitry Andric // We have:
6855ca98fd9SDimitry Andric // 0b011000 sssss ttttt iiiiiiiiiiiiiiii
6865ca98fd9SDimitry Andric // BNVC if rs >= rt
6875ca98fd9SDimitry Andric // BNEZALC if rs == 0 && rt != 0
6885ca98fd9SDimitry Andric // BNEC if rs < rt && rs != 0
6895ca98fd9SDimitry Andric
6905ca98fd9SDimitry Andric InsnType Rs = fieldFromInstruction(insn, 21, 5);
6915ca98fd9SDimitry Andric InsnType Rt = fieldFromInstruction(insn, 16, 5);
69201095a5dSDimitry Andric int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
6935ca98fd9SDimitry Andric bool HasRs = false;
6945ca98fd9SDimitry Andric
6955ca98fd9SDimitry Andric if (Rs >= Rt) {
6965ca98fd9SDimitry Andric MI.setOpcode(Mips::BNVC);
6975ca98fd9SDimitry Andric HasRs = true;
6985ca98fd9SDimitry Andric } else if (Rs != 0 && Rs < Rt) {
6995ca98fd9SDimitry Andric MI.setOpcode(Mips::BNEC);
7005ca98fd9SDimitry Andric HasRs = true;
7015ca98fd9SDimitry Andric } else
7025ca98fd9SDimitry Andric MI.setOpcode(Mips::BNEZALC);
7035ca98fd9SDimitry Andric
7045ca98fd9SDimitry Andric if (HasRs)
7055a5ac124SDimitry Andric MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
7065ca98fd9SDimitry Andric Rs)));
7075ca98fd9SDimitry Andric
7085a5ac124SDimitry Andric MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
7095ca98fd9SDimitry Andric Rt)));
7105a5ac124SDimitry Andric MI.addOperand(MCOperand::createImm(Imm));
7115ca98fd9SDimitry Andric
7125ca98fd9SDimitry Andric return MCDisassembler::Success;
7135ca98fd9SDimitry Andric }
7145ca98fd9SDimitry Andric
7155ca98fd9SDimitry Andric template <typename InsnType>
DecodePOP37GroupBranchMMR6(MCInst & MI,InsnType insn,uint64_t Address,const MCDisassembler * Decoder)71601095a5dSDimitry Andric static DecodeStatus DecodePOP37GroupBranchMMR6(MCInst &MI, InsnType insn,
71701095a5dSDimitry Andric uint64_t Address,
718145449b1SDimitry Andric const MCDisassembler *Decoder) {
71901095a5dSDimitry Andric InsnType Rt = fieldFromInstruction(insn, 21, 5);
72001095a5dSDimitry Andric InsnType Rs = fieldFromInstruction(insn, 16, 5);
721b915e9e0SDimitry Andric int64_t Imm = 0;
72201095a5dSDimitry Andric
72301095a5dSDimitry Andric if (Rs >= Rt) {
72401095a5dSDimitry Andric MI.setOpcode(Mips::BNVC_MMR6);
72501095a5dSDimitry Andric MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
72601095a5dSDimitry Andric Rt)));
72701095a5dSDimitry Andric MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
72801095a5dSDimitry Andric Rs)));
729b915e9e0SDimitry Andric Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
73001095a5dSDimitry Andric } else if (Rs != 0 && Rs < Rt) {
73101095a5dSDimitry Andric MI.setOpcode(Mips::BNEC_MMR6);
73201095a5dSDimitry Andric MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
73301095a5dSDimitry Andric Rs)));
73401095a5dSDimitry Andric MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
73501095a5dSDimitry Andric Rt)));
736b915e9e0SDimitry Andric Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
73701095a5dSDimitry Andric } else {
73801095a5dSDimitry Andric MI.setOpcode(Mips::BNEZALC_MMR6);
73901095a5dSDimitry Andric MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
74001095a5dSDimitry Andric Rt)));
741b915e9e0SDimitry Andric Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
74201095a5dSDimitry Andric }
74301095a5dSDimitry Andric
74401095a5dSDimitry Andric MI.addOperand(MCOperand::createImm(Imm));
74501095a5dSDimitry Andric
74601095a5dSDimitry Andric return MCDisassembler::Success;
74701095a5dSDimitry Andric }
74801095a5dSDimitry Andric
74901095a5dSDimitry Andric template <typename InsnType>
DecodePOP65GroupBranchMMR6(MCInst & MI,InsnType insn,uint64_t Address,const MCDisassembler * Decoder)750b915e9e0SDimitry Andric static DecodeStatus DecodePOP65GroupBranchMMR6(MCInst &MI, InsnType insn,
751b915e9e0SDimitry Andric uint64_t Address,
752145449b1SDimitry Andric const MCDisassembler *Decoder) {
753b915e9e0SDimitry Andric // We have:
754b915e9e0SDimitry Andric // 0b110101 ttttt sssss iiiiiiiiiiiiiiii
755b915e9e0SDimitry Andric // Invalid if rt == 0
756b915e9e0SDimitry Andric // BGTZC_MMR6 if rs == 0 && rt != 0
757b915e9e0SDimitry Andric // BLTZC_MMR6 if rs == rt && rt != 0
758b915e9e0SDimitry Andric // BLTC_MMR6 if rs != rt && rs != 0 && rt != 0
759b915e9e0SDimitry Andric
760b915e9e0SDimitry Andric InsnType Rt = fieldFromInstruction(insn, 21, 5);
761b915e9e0SDimitry Andric InsnType Rs = fieldFromInstruction(insn, 16, 5);
762b915e9e0SDimitry Andric int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
763b915e9e0SDimitry Andric bool HasRs = false;
764b915e9e0SDimitry Andric
765b915e9e0SDimitry Andric if (Rt == 0)
766b915e9e0SDimitry Andric return MCDisassembler::Fail;
767b915e9e0SDimitry Andric else if (Rs == 0)
768b915e9e0SDimitry Andric MI.setOpcode(Mips::BGTZC_MMR6);
769b915e9e0SDimitry Andric else if (Rs == Rt)
770b915e9e0SDimitry Andric MI.setOpcode(Mips::BLTZC_MMR6);
771b915e9e0SDimitry Andric else {
772b915e9e0SDimitry Andric MI.setOpcode(Mips::BLTC_MMR6);
773b915e9e0SDimitry Andric HasRs = true;
774b915e9e0SDimitry Andric }
775b915e9e0SDimitry Andric
776b915e9e0SDimitry Andric if (HasRs)
777b915e9e0SDimitry Andric MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
778b915e9e0SDimitry Andric Rs)));
779b915e9e0SDimitry Andric
780b915e9e0SDimitry Andric MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
781b915e9e0SDimitry Andric Rt)));
782b915e9e0SDimitry Andric
783b915e9e0SDimitry Andric MI.addOperand(MCOperand::createImm(Imm));
784b915e9e0SDimitry Andric
785b915e9e0SDimitry Andric return MCDisassembler::Success;
786b915e9e0SDimitry Andric }
787b915e9e0SDimitry Andric
788b915e9e0SDimitry Andric template <typename InsnType>
DecodePOP75GroupBranchMMR6(MCInst & MI,InsnType insn,uint64_t Address,const MCDisassembler * Decoder)789b915e9e0SDimitry Andric static DecodeStatus DecodePOP75GroupBranchMMR6(MCInst &MI, InsnType insn,
790b915e9e0SDimitry Andric uint64_t Address,
791145449b1SDimitry Andric const MCDisassembler *Decoder) {
792b915e9e0SDimitry Andric // We have:
793b915e9e0SDimitry Andric // 0b111101 ttttt sssss iiiiiiiiiiiiiiii
794b915e9e0SDimitry Andric // Invalid if rt == 0
795b915e9e0SDimitry Andric // BLEZC_MMR6 if rs == 0 && rt != 0
796b915e9e0SDimitry Andric // BGEZC_MMR6 if rs == rt && rt != 0
797b915e9e0SDimitry Andric // BGEC_MMR6 if rs != rt && rs != 0 && rt != 0
798b915e9e0SDimitry Andric
799b915e9e0SDimitry Andric InsnType Rt = fieldFromInstruction(insn, 21, 5);
800b915e9e0SDimitry Andric InsnType Rs = fieldFromInstruction(insn, 16, 5);
801b915e9e0SDimitry Andric int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
802b915e9e0SDimitry Andric bool HasRs = false;
803b915e9e0SDimitry Andric
804b915e9e0SDimitry Andric if (Rt == 0)
805b915e9e0SDimitry Andric return MCDisassembler::Fail;
806b915e9e0SDimitry Andric else if (Rs == 0)
807b915e9e0SDimitry Andric MI.setOpcode(Mips::BLEZC_MMR6);
808b915e9e0SDimitry Andric else if (Rs == Rt)
809b915e9e0SDimitry Andric MI.setOpcode(Mips::BGEZC_MMR6);
810b915e9e0SDimitry Andric else {
811b915e9e0SDimitry Andric HasRs = true;
812b915e9e0SDimitry Andric MI.setOpcode(Mips::BGEC_MMR6);
813b915e9e0SDimitry Andric }
814b915e9e0SDimitry Andric
815b915e9e0SDimitry Andric if (HasRs)
816b915e9e0SDimitry Andric MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
817b915e9e0SDimitry Andric Rs)));
818b915e9e0SDimitry Andric
819b915e9e0SDimitry Andric MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
820b915e9e0SDimitry Andric Rt)));
821b915e9e0SDimitry Andric
822b915e9e0SDimitry Andric MI.addOperand(MCOperand::createImm(Imm));
823b915e9e0SDimitry Andric
824b915e9e0SDimitry Andric return MCDisassembler::Success;
825b915e9e0SDimitry Andric }
826b915e9e0SDimitry Andric
827b915e9e0SDimitry Andric template <typename InsnType>
DecodeBlezlGroupBranch(MCInst & MI,InsnType insn,uint64_t Address,const MCDisassembler * Decoder)8285ca98fd9SDimitry Andric static DecodeStatus DecodeBlezlGroupBranch(MCInst &MI, InsnType insn,
8295ca98fd9SDimitry Andric uint64_t Address,
830145449b1SDimitry Andric const MCDisassembler *Decoder) {
8315ca98fd9SDimitry Andric // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
8325ca98fd9SDimitry Andric // (otherwise we would have matched the BLEZL instruction from the earlier
8335ca98fd9SDimitry Andric // ISA's instead).
8345ca98fd9SDimitry Andric //
8355ca98fd9SDimitry Andric // We have:
8365ca98fd9SDimitry Andric // 0b010110 sssss ttttt iiiiiiiiiiiiiiii
8375ca98fd9SDimitry Andric // Invalid if rs == 0
8385ca98fd9SDimitry Andric // BLEZC if rs == 0 && rt != 0
8395ca98fd9SDimitry Andric // BGEZC if rs == rt && rt != 0
8405ca98fd9SDimitry Andric // BGEC if rs != rt && rs != 0 && rt != 0
8415ca98fd9SDimitry Andric
8425ca98fd9SDimitry Andric InsnType Rs = fieldFromInstruction(insn, 21, 5);
8435ca98fd9SDimitry Andric InsnType Rt = fieldFromInstruction(insn, 16, 5);
84401095a5dSDimitry Andric int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
8455ca98fd9SDimitry Andric bool HasRs = false;
8465ca98fd9SDimitry Andric
8475ca98fd9SDimitry Andric if (Rt == 0)
8485ca98fd9SDimitry Andric return MCDisassembler::Fail;
8495ca98fd9SDimitry Andric else if (Rs == 0)
8505ca98fd9SDimitry Andric MI.setOpcode(Mips::BLEZC);
8515ca98fd9SDimitry Andric else if (Rs == Rt)
8525ca98fd9SDimitry Andric MI.setOpcode(Mips::BGEZC);
8535ca98fd9SDimitry Andric else {
8545ca98fd9SDimitry Andric HasRs = true;
8555ca98fd9SDimitry Andric MI.setOpcode(Mips::BGEC);
8565ca98fd9SDimitry Andric }
8575ca98fd9SDimitry Andric
8585ca98fd9SDimitry Andric if (HasRs)
8595a5ac124SDimitry Andric MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
8605ca98fd9SDimitry Andric Rs)));
8615ca98fd9SDimitry Andric
8625a5ac124SDimitry Andric MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
8635ca98fd9SDimitry Andric Rt)));
8645ca98fd9SDimitry Andric
8655a5ac124SDimitry Andric MI.addOperand(MCOperand::createImm(Imm));
8665ca98fd9SDimitry Andric
8675ca98fd9SDimitry Andric return MCDisassembler::Success;
8685ca98fd9SDimitry Andric }
8695ca98fd9SDimitry Andric
8705ca98fd9SDimitry Andric template <typename InsnType>
DecodeBgtzlGroupBranch(MCInst & MI,InsnType insn,uint64_t Address,const MCDisassembler * Decoder)8715ca98fd9SDimitry Andric static DecodeStatus DecodeBgtzlGroupBranch(MCInst &MI, InsnType insn,
8725ca98fd9SDimitry Andric uint64_t Address,
873145449b1SDimitry Andric const MCDisassembler *Decoder) {
8745ca98fd9SDimitry Andric // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
8755ca98fd9SDimitry Andric // (otherwise we would have matched the BGTZL instruction from the earlier
8765ca98fd9SDimitry Andric // ISA's instead).
8775ca98fd9SDimitry Andric //
8785ca98fd9SDimitry Andric // We have:
8795ca98fd9SDimitry Andric // 0b010111 sssss ttttt iiiiiiiiiiiiiiii
8805ca98fd9SDimitry Andric // Invalid if rs == 0
8815ca98fd9SDimitry Andric // BGTZC if rs == 0 && rt != 0
8825ca98fd9SDimitry Andric // BLTZC if rs == rt && rt != 0
8835ca98fd9SDimitry Andric // BLTC if rs != rt && rs != 0 && rt != 0
8845ca98fd9SDimitry Andric
8855ca98fd9SDimitry Andric bool HasRs = false;
8865ca98fd9SDimitry Andric
8875ca98fd9SDimitry Andric InsnType Rs = fieldFromInstruction(insn, 21, 5);
8885ca98fd9SDimitry Andric InsnType Rt = fieldFromInstruction(insn, 16, 5);
88901095a5dSDimitry Andric int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
8905ca98fd9SDimitry Andric
8915ca98fd9SDimitry Andric if (Rt == 0)
8925ca98fd9SDimitry Andric return MCDisassembler::Fail;
8935ca98fd9SDimitry Andric else if (Rs == 0)
8945ca98fd9SDimitry Andric MI.setOpcode(Mips::BGTZC);
8955ca98fd9SDimitry Andric else if (Rs == Rt)
8965ca98fd9SDimitry Andric MI.setOpcode(Mips::BLTZC);
8975ca98fd9SDimitry Andric else {
8985ca98fd9SDimitry Andric MI.setOpcode(Mips::BLTC);
8995ca98fd9SDimitry Andric HasRs = true;
9005ca98fd9SDimitry Andric }
9015ca98fd9SDimitry Andric
9025ca98fd9SDimitry Andric if (HasRs)
9035a5ac124SDimitry Andric MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
9045ca98fd9SDimitry Andric Rs)));
9055ca98fd9SDimitry Andric
9065a5ac124SDimitry Andric MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
9075ca98fd9SDimitry Andric Rt)));
9085ca98fd9SDimitry Andric
9095a5ac124SDimitry Andric MI.addOperand(MCOperand::createImm(Imm));
9105ca98fd9SDimitry Andric
9115ca98fd9SDimitry Andric return MCDisassembler::Success;
9125ca98fd9SDimitry Andric }
9135ca98fd9SDimitry Andric
9145ca98fd9SDimitry Andric template <typename InsnType>
DecodeBgtzGroupBranch(MCInst & MI,InsnType insn,uint64_t Address,const MCDisassembler * Decoder)9155ca98fd9SDimitry Andric static DecodeStatus DecodeBgtzGroupBranch(MCInst &MI, InsnType insn,
9165ca98fd9SDimitry Andric uint64_t Address,
917145449b1SDimitry Andric const MCDisassembler *Decoder) {
9185ca98fd9SDimitry Andric // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
9195ca98fd9SDimitry Andric // (otherwise we would have matched the BGTZ instruction from the earlier
9205ca98fd9SDimitry Andric // ISA's instead).
9215ca98fd9SDimitry Andric //
9225ca98fd9SDimitry Andric // We have:
9235ca98fd9SDimitry Andric // 0b000111 sssss ttttt iiiiiiiiiiiiiiii
9245ca98fd9SDimitry Andric // BGTZ if rt == 0
9255ca98fd9SDimitry Andric // BGTZALC if rs == 0 && rt != 0
9265ca98fd9SDimitry Andric // BLTZALC if rs != 0 && rs == rt
9275ca98fd9SDimitry Andric // BLTUC if rs != 0 && rs != rt
9285ca98fd9SDimitry Andric
9295ca98fd9SDimitry Andric InsnType Rs = fieldFromInstruction(insn, 21, 5);
9305ca98fd9SDimitry Andric InsnType Rt = fieldFromInstruction(insn, 16, 5);
93101095a5dSDimitry Andric int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
9325ca98fd9SDimitry Andric bool HasRs = false;
9335ca98fd9SDimitry Andric bool HasRt = false;
9345ca98fd9SDimitry Andric
9355ca98fd9SDimitry Andric if (Rt == 0) {
9365ca98fd9SDimitry Andric MI.setOpcode(Mips::BGTZ);
9375ca98fd9SDimitry Andric HasRs = true;
9385ca98fd9SDimitry Andric } else if (Rs == 0) {
9395ca98fd9SDimitry Andric MI.setOpcode(Mips::BGTZALC);
9405ca98fd9SDimitry Andric HasRt = true;
9415ca98fd9SDimitry Andric } else if (Rs == Rt) {
9425ca98fd9SDimitry Andric MI.setOpcode(Mips::BLTZALC);
9435ca98fd9SDimitry Andric HasRs = true;
9445ca98fd9SDimitry Andric } else {
9455ca98fd9SDimitry Andric MI.setOpcode(Mips::BLTUC);
9465ca98fd9SDimitry Andric HasRs = true;
9475ca98fd9SDimitry Andric HasRt = true;
9485ca98fd9SDimitry Andric }
9495ca98fd9SDimitry Andric
9505ca98fd9SDimitry Andric if (HasRs)
9515a5ac124SDimitry Andric MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
9525ca98fd9SDimitry Andric Rs)));
9535ca98fd9SDimitry Andric
9545ca98fd9SDimitry Andric if (HasRt)
9555a5ac124SDimitry Andric MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
9565ca98fd9SDimitry Andric Rt)));
9575ca98fd9SDimitry Andric
9585a5ac124SDimitry Andric MI.addOperand(MCOperand::createImm(Imm));
9595ca98fd9SDimitry Andric
9605ca98fd9SDimitry Andric return MCDisassembler::Success;
9615ca98fd9SDimitry Andric }
9625ca98fd9SDimitry Andric
9635ca98fd9SDimitry Andric template <typename InsnType>
DecodeBlezGroupBranch(MCInst & MI,InsnType insn,uint64_t Address,const MCDisassembler * Decoder)9645ca98fd9SDimitry Andric static DecodeStatus DecodeBlezGroupBranch(MCInst &MI, InsnType insn,
9655ca98fd9SDimitry Andric uint64_t Address,
966145449b1SDimitry Andric const MCDisassembler *Decoder) {
9675ca98fd9SDimitry Andric // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
9685ca98fd9SDimitry Andric // (otherwise we would have matched the BLEZL instruction from the earlier
9695ca98fd9SDimitry Andric // ISA's instead).
9705ca98fd9SDimitry Andric //
9715ca98fd9SDimitry Andric // We have:
9725ca98fd9SDimitry Andric // 0b000110 sssss ttttt iiiiiiiiiiiiiiii
9735ca98fd9SDimitry Andric // Invalid if rs == 0
9745ca98fd9SDimitry Andric // BLEZALC if rs == 0 && rt != 0
9755ca98fd9SDimitry Andric // BGEZALC if rs == rt && rt != 0
9765ca98fd9SDimitry Andric // BGEUC if rs != rt && rs != 0 && rt != 0
9775ca98fd9SDimitry Andric
9785ca98fd9SDimitry Andric InsnType Rs = fieldFromInstruction(insn, 21, 5);
9795ca98fd9SDimitry Andric InsnType Rt = fieldFromInstruction(insn, 16, 5);
98001095a5dSDimitry Andric int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
9815ca98fd9SDimitry Andric bool HasRs = false;
9825ca98fd9SDimitry Andric
9835ca98fd9SDimitry Andric if (Rt == 0)
9845ca98fd9SDimitry Andric return MCDisassembler::Fail;
9855ca98fd9SDimitry Andric else if (Rs == 0)
9865ca98fd9SDimitry Andric MI.setOpcode(Mips::BLEZALC);
9875ca98fd9SDimitry Andric else if (Rs == Rt)
9885ca98fd9SDimitry Andric MI.setOpcode(Mips::BGEZALC);
9895ca98fd9SDimitry Andric else {
9905ca98fd9SDimitry Andric HasRs = true;
9915ca98fd9SDimitry Andric MI.setOpcode(Mips::BGEUC);
9925ca98fd9SDimitry Andric }
9935ca98fd9SDimitry Andric
9945ca98fd9SDimitry Andric if (HasRs)
9955a5ac124SDimitry Andric MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
9965ca98fd9SDimitry Andric Rs)));
9975a5ac124SDimitry Andric MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
9985ca98fd9SDimitry Andric Rt)));
9995ca98fd9SDimitry Andric
10005a5ac124SDimitry Andric MI.addOperand(MCOperand::createImm(Imm));
10015ca98fd9SDimitry Andric
10025ca98fd9SDimitry Andric return MCDisassembler::Success;
10035ca98fd9SDimitry Andric }
10045ca98fd9SDimitry Andric
1005044eb2f6SDimitry Andric // Override the generated disassembler to produce DEXT all the time. This is
1006044eb2f6SDimitry Andric // for feature / behaviour parity with binutils.
1007044eb2f6SDimitry Andric template <typename InsnType>
DecodeDEXT(MCInst & MI,InsnType Insn,uint64_t Address,const MCDisassembler * Decoder)1008044eb2f6SDimitry Andric static DecodeStatus DecodeDEXT(MCInst &MI, InsnType Insn, uint64_t Address,
1009145449b1SDimitry Andric const MCDisassembler *Decoder) {
1010044eb2f6SDimitry Andric unsigned Msbd = fieldFromInstruction(Insn, 11, 5);
1011044eb2f6SDimitry Andric unsigned Lsb = fieldFromInstruction(Insn, 6, 5);
1012044eb2f6SDimitry Andric unsigned Size = 0;
1013044eb2f6SDimitry Andric unsigned Pos = 0;
1014044eb2f6SDimitry Andric
1015044eb2f6SDimitry Andric switch (MI.getOpcode()) {
1016044eb2f6SDimitry Andric case Mips::DEXT:
1017044eb2f6SDimitry Andric Pos = Lsb;
1018044eb2f6SDimitry Andric Size = Msbd + 1;
1019044eb2f6SDimitry Andric break;
1020044eb2f6SDimitry Andric case Mips::DEXTM:
1021044eb2f6SDimitry Andric Pos = Lsb;
1022044eb2f6SDimitry Andric Size = Msbd + 1 + 32;
1023044eb2f6SDimitry Andric break;
1024044eb2f6SDimitry Andric case Mips::DEXTU:
1025044eb2f6SDimitry Andric Pos = Lsb + 32;
1026044eb2f6SDimitry Andric Size = Msbd + 1;
1027044eb2f6SDimitry Andric break;
1028044eb2f6SDimitry Andric default:
1029044eb2f6SDimitry Andric llvm_unreachable("Unknown DEXT instruction!");
1030044eb2f6SDimitry Andric }
1031044eb2f6SDimitry Andric
1032044eb2f6SDimitry Andric MI.setOpcode(Mips::DEXT);
1033044eb2f6SDimitry Andric
1034044eb2f6SDimitry Andric InsnType Rs = fieldFromInstruction(Insn, 21, 5);
1035044eb2f6SDimitry Andric InsnType Rt = fieldFromInstruction(Insn, 16, 5);
1036044eb2f6SDimitry Andric
1037706b4fc4SDimitry Andric MI.addOperand(
1038706b4fc4SDimitry Andric MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID, Rt)));
1039706b4fc4SDimitry Andric MI.addOperand(
1040706b4fc4SDimitry Andric MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID, Rs)));
1041044eb2f6SDimitry Andric MI.addOperand(MCOperand::createImm(Pos));
1042044eb2f6SDimitry Andric MI.addOperand(MCOperand::createImm(Size));
1043044eb2f6SDimitry Andric
1044044eb2f6SDimitry Andric return MCDisassembler::Success;
1045044eb2f6SDimitry Andric }
1046044eb2f6SDimitry Andric
1047044eb2f6SDimitry Andric // Override the generated disassembler to produce DINS all the time. This is
1048044eb2f6SDimitry Andric // for feature / behaviour parity with binutils.
1049044eb2f6SDimitry Andric template <typename InsnType>
DecodeDINS(MCInst & MI,InsnType Insn,uint64_t Address,const MCDisassembler * Decoder)1050044eb2f6SDimitry Andric static DecodeStatus DecodeDINS(MCInst &MI, InsnType Insn, uint64_t Address,
1051145449b1SDimitry Andric const MCDisassembler *Decoder) {
1052044eb2f6SDimitry Andric unsigned Msbd = fieldFromInstruction(Insn, 11, 5);
1053044eb2f6SDimitry Andric unsigned Lsb = fieldFromInstruction(Insn, 6, 5);
1054044eb2f6SDimitry Andric unsigned Size = 0;
1055044eb2f6SDimitry Andric unsigned Pos = 0;
1056044eb2f6SDimitry Andric
1057044eb2f6SDimitry Andric switch (MI.getOpcode()) {
1058044eb2f6SDimitry Andric case Mips::DINS:
1059044eb2f6SDimitry Andric Pos = Lsb;
1060044eb2f6SDimitry Andric Size = Msbd + 1 - Pos;
1061044eb2f6SDimitry Andric break;
1062044eb2f6SDimitry Andric case Mips::DINSM:
1063044eb2f6SDimitry Andric Pos = Lsb;
1064044eb2f6SDimitry Andric Size = Msbd + 33 - Pos;
1065044eb2f6SDimitry Andric break;
1066044eb2f6SDimitry Andric case Mips::DINSU:
1067044eb2f6SDimitry Andric Pos = Lsb + 32;
1068044eb2f6SDimitry Andric // mbsd = pos + size - 33
1069044eb2f6SDimitry Andric // mbsd - pos + 33 = size
1070044eb2f6SDimitry Andric Size = Msbd + 33 - Pos;
1071044eb2f6SDimitry Andric break;
1072044eb2f6SDimitry Andric default:
1073044eb2f6SDimitry Andric llvm_unreachable("Unknown DINS instruction!");
1074044eb2f6SDimitry Andric }
1075044eb2f6SDimitry Andric
1076044eb2f6SDimitry Andric InsnType Rs = fieldFromInstruction(Insn, 21, 5);
1077044eb2f6SDimitry Andric InsnType Rt = fieldFromInstruction(Insn, 16, 5);
1078044eb2f6SDimitry Andric
1079044eb2f6SDimitry Andric MI.setOpcode(Mips::DINS);
1080706b4fc4SDimitry Andric MI.addOperand(
1081706b4fc4SDimitry Andric MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID, Rt)));
1082706b4fc4SDimitry Andric MI.addOperand(
1083706b4fc4SDimitry Andric MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID, Rs)));
1084044eb2f6SDimitry Andric MI.addOperand(MCOperand::createImm(Pos));
1085044eb2f6SDimitry Andric MI.addOperand(MCOperand::createImm(Size));
1086044eb2f6SDimitry Andric
1087044eb2f6SDimitry Andric return MCDisassembler::Success;
1088044eb2f6SDimitry Andric }
1089eb11fae6SDimitry Andric
1090eb11fae6SDimitry Andric // Auto-generated decoder wouldn't add the third operand for CRC32*.
1091eb11fae6SDimitry Andric template <typename InsnType>
DecodeCRC(MCInst & MI,InsnType Insn,uint64_t Address,const MCDisassembler * Decoder)1092eb11fae6SDimitry Andric static DecodeStatus DecodeCRC(MCInst &MI, InsnType Insn, uint64_t Address,
1093145449b1SDimitry Andric const MCDisassembler *Decoder) {
1094eb11fae6SDimitry Andric InsnType Rs = fieldFromInstruction(Insn, 21, 5);
1095eb11fae6SDimitry Andric InsnType Rt = fieldFromInstruction(Insn, 16, 5);
1096eb11fae6SDimitry Andric MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
1097eb11fae6SDimitry Andric Rt)));
1098eb11fae6SDimitry Andric MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
1099eb11fae6SDimitry Andric Rs)));
1100eb11fae6SDimitry Andric MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
1101eb11fae6SDimitry Andric Rt)));
1102eb11fae6SDimitry Andric return MCDisassembler::Success;
1103eb11fae6SDimitry Andric }
1104eb11fae6SDimitry Andric
110567c32a98SDimitry Andric /// Read two bytes from the ArrayRef and return 16 bit halfword sorted
1106b915e9e0SDimitry Andric /// according to the given endianness.
readInstruction16(ArrayRef<uint8_t> Bytes,uint64_t Address,uint64_t & Size,uint32_t & Insn,bool IsBigEndian)110767c32a98SDimitry Andric static DecodeStatus readInstruction16(ArrayRef<uint8_t> Bytes, uint64_t Address,
110867c32a98SDimitry Andric uint64_t &Size, uint32_t &Insn,
110967c32a98SDimitry Andric bool IsBigEndian) {
111067c32a98SDimitry Andric // We want to read exactly 2 Bytes of data.
111167c32a98SDimitry Andric if (Bytes.size() < 2) {
111267c32a98SDimitry Andric Size = 0;
1113b61ab53cSDimitry Andric return MCDisassembler::Fail;
1114b61ab53cSDimitry Andric }
1115b61ab53cSDimitry Andric
111667c32a98SDimitry Andric if (IsBigEndian) {
111767c32a98SDimitry Andric Insn = (Bytes[0] << 8) | Bytes[1];
111867c32a98SDimitry Andric } else {
111967c32a98SDimitry Andric Insn = (Bytes[1] << 8) | Bytes[0];
1120b61ab53cSDimitry Andric }
112167c32a98SDimitry Andric
112267c32a98SDimitry Andric return MCDisassembler::Success;
112367c32a98SDimitry Andric }
112467c32a98SDimitry Andric
112567c32a98SDimitry Andric /// Read four bytes from the ArrayRef and return 32 bit word sorted
1126b915e9e0SDimitry Andric /// according to the given endianness.
readInstruction32(ArrayRef<uint8_t> Bytes,uint64_t Address,uint64_t & Size,uint32_t & Insn,bool IsBigEndian,bool IsMicroMips)112767c32a98SDimitry Andric static DecodeStatus readInstruction32(ArrayRef<uint8_t> Bytes, uint64_t Address,
112867c32a98SDimitry Andric uint64_t &Size, uint32_t &Insn,
112967c32a98SDimitry Andric bool IsBigEndian, bool IsMicroMips) {
113067c32a98SDimitry Andric // We want to read exactly 4 Bytes of data.
113167c32a98SDimitry Andric if (Bytes.size() < 4) {
113267c32a98SDimitry Andric Size = 0;
113367c32a98SDimitry Andric return MCDisassembler::Fail;
113467c32a98SDimitry Andric }
113567c32a98SDimitry Andric
113667c32a98SDimitry Andric // High 16 bits of a 32-bit microMIPS instruction (where the opcode is)
113767c32a98SDimitry Andric // always precede the low 16 bits in the instruction stream (that is, they
113867c32a98SDimitry Andric // are placed at lower addresses in the instruction stream).
113967c32a98SDimitry Andric //
114067c32a98SDimitry Andric // microMIPS byte ordering:
114167c32a98SDimitry Andric // Big-endian: 0 | 1 | 2 | 3
114267c32a98SDimitry Andric // Little-endian: 1 | 0 | 3 | 2
114367c32a98SDimitry Andric
114467c32a98SDimitry Andric if (IsBigEndian) {
114567c32a98SDimitry Andric // Encoded as a big-endian 32-bit word in the stream.
114667c32a98SDimitry Andric Insn =
114767c32a98SDimitry Andric (Bytes[3] << 0) | (Bytes[2] << 8) | (Bytes[1] << 16) | (Bytes[0] << 24);
114867c32a98SDimitry Andric } else {
1149f8af5cf6SDimitry Andric if (IsMicroMips) {
115067c32a98SDimitry Andric Insn = (Bytes[2] << 0) | (Bytes[3] << 8) | (Bytes[0] << 16) |
1151f8af5cf6SDimitry Andric (Bytes[1] << 24);
1152f8af5cf6SDimitry Andric } else {
115367c32a98SDimitry Andric Insn = (Bytes[0] << 0) | (Bytes[1] << 8) | (Bytes[2] << 16) |
1154b61ab53cSDimitry Andric (Bytes[3] << 24);
1155b61ab53cSDimitry Andric }
1156f8af5cf6SDimitry Andric }
1157b61ab53cSDimitry Andric
1158b61ab53cSDimitry Andric return MCDisassembler::Success;
1159b61ab53cSDimitry Andric }
1160b61ab53cSDimitry Andric
getInstruction(MCInst & Instr,uint64_t & Size,ArrayRef<uint8_t> Bytes,uint64_t Address,raw_ostream & CStream) const116167c32a98SDimitry Andric DecodeStatus MipsDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,
116267c32a98SDimitry Andric ArrayRef<uint8_t> Bytes,
1163b61ab53cSDimitry Andric uint64_t Address,
116467c32a98SDimitry Andric raw_ostream &CStream) const {
1165b61ab53cSDimitry Andric uint32_t Insn;
116667c32a98SDimitry Andric DecodeStatus Result;
116771d5a254SDimitry Andric Size = 0;
1168b61ab53cSDimitry Andric
116967c32a98SDimitry Andric if (IsMicroMips) {
117067c32a98SDimitry Andric Result = readInstruction16(Bytes, Address, Size, Insn, IsBigEndian);
1171dd58ef01SDimitry Andric if (Result == MCDisassembler::Fail)
1172dd58ef01SDimitry Andric return MCDisassembler::Fail;
1173dd58ef01SDimitry Andric
1174dd58ef01SDimitry Andric if (hasMips32r6()) {
1175eb11fae6SDimitry Andric LLVM_DEBUG(
1176eb11fae6SDimitry Andric dbgs() << "Trying MicroMipsR616 table (16-bit instructions):\n");
1177dd58ef01SDimitry Andric // Calling the auto-generated decoder function for microMIPS32R6
1178044eb2f6SDimitry Andric // 16-bit instructions.
1179dd58ef01SDimitry Andric Result = decodeInstruction(DecoderTableMicroMipsR616, Instr, Insn,
1180dd58ef01SDimitry Andric Address, this, STI);
1181dd58ef01SDimitry Andric if (Result != MCDisassembler::Fail) {
1182dd58ef01SDimitry Andric Size = 2;
1183dd58ef01SDimitry Andric return Result;
1184dd58ef01SDimitry Andric }
1185dd58ef01SDimitry Andric }
118667c32a98SDimitry Andric
1187eb11fae6SDimitry Andric LLVM_DEBUG(dbgs() << "Trying MicroMips16 table (16-bit instructions):\n");
1188dd58ef01SDimitry Andric // Calling the auto-generated decoder function for microMIPS 16-bit
1189dd58ef01SDimitry Andric // instructions.
119067c32a98SDimitry Andric Result = decodeInstruction(DecoderTableMicroMips16, Instr, Insn, Address,
119167c32a98SDimitry Andric this, STI);
119267c32a98SDimitry Andric if (Result != MCDisassembler::Fail) {
119367c32a98SDimitry Andric Size = 2;
119467c32a98SDimitry Andric return Result;
119567c32a98SDimitry Andric }
119667c32a98SDimitry Andric
119767c32a98SDimitry Andric Result = readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, true);
1198b61ab53cSDimitry Andric if (Result == MCDisassembler::Fail)
1199b61ab53cSDimitry Andric return MCDisassembler::Fail;
1200b61ab53cSDimitry Andric
12015a5ac124SDimitry Andric if (hasMips32r6()) {
1202eb11fae6SDimitry Andric LLVM_DEBUG(
1203eb11fae6SDimitry Andric dbgs() << "Trying MicroMips32r632 table (32-bit instructions):\n");
12045a5ac124SDimitry Andric // Calling the auto-generated decoder function.
1205706b4fc4SDimitry Andric Result = decodeInstruction(DecoderTableMicroMipsR632, Instr, Insn,
1206706b4fc4SDimitry Andric Address, this, STI);
1207f8af5cf6SDimitry Andric if (Result != MCDisassembler::Fail) {
1208f8af5cf6SDimitry Andric Size = 4;
1209f8af5cf6SDimitry Andric return Result;
1210f8af5cf6SDimitry Andric }
1211dd58ef01SDimitry Andric }
1212dd58ef01SDimitry Andric
1213eb11fae6SDimitry Andric LLVM_DEBUG(dbgs() << "Trying MicroMips32 table (32-bit instructions):\n");
1214dd58ef01SDimitry Andric // Calling the auto-generated decoder function.
1215dd58ef01SDimitry Andric Result = decodeInstruction(DecoderTableMicroMips32, Instr, Insn, Address,
1216dd58ef01SDimitry Andric this, STI);
1217dd58ef01SDimitry Andric if (Result != MCDisassembler::Fail) {
1218dd58ef01SDimitry Andric Size = 4;
1219dd58ef01SDimitry Andric return Result;
1220dd58ef01SDimitry Andric }
122101095a5dSDimitry Andric
1222044eb2f6SDimitry Andric if (isFP64()) {
1223eb11fae6SDimitry Andric LLVM_DEBUG(dbgs() << "Trying MicroMipsFP64 table (32-bit opcodes):\n");
1224044eb2f6SDimitry Andric Result = decodeInstruction(DecoderTableMicroMipsFP6432, Instr, Insn,
122501095a5dSDimitry Andric Address, this, STI);
122601095a5dSDimitry Andric if (Result != MCDisassembler::Fail) {
122701095a5dSDimitry Andric Size = 4;
122801095a5dSDimitry Andric return Result;
122901095a5dSDimitry Andric }
123001095a5dSDimitry Andric }
123101095a5dSDimitry Andric
123271d5a254SDimitry Andric // This is an invalid instruction. Claim that the Size is 2 bytes. Since
123371d5a254SDimitry Andric // microMIPS instructions have a minimum alignment of 2, the next 2 bytes
123471d5a254SDimitry Andric // could form a valid instruction. The two bytes we rejected as an
123571d5a254SDimitry Andric // instruction could have actually beeen an inline constant pool that is
123671d5a254SDimitry Andric // unconditionally branched over.
1237dd58ef01SDimitry Andric Size = 2;
1238f8af5cf6SDimitry Andric return MCDisassembler::Fail;
1239f8af5cf6SDimitry Andric }
1240f8af5cf6SDimitry Andric
124171d5a254SDimitry Andric // Attempt to read the instruction so that we can attempt to decode it. If
124271d5a254SDimitry Andric // the buffer is not 4 bytes long, let the higher level logic figure out
124371d5a254SDimitry Andric // what to do with a size of zero and MCDisassembler::Fail.
124467c32a98SDimitry Andric Result = readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, false);
124571d5a254SDimitry Andric if (Result == MCDisassembler::Fail)
124667c32a98SDimitry Andric return MCDisassembler::Fail;
124771d5a254SDimitry Andric
124871d5a254SDimitry Andric // The only instruction size for standard encoded MIPS.
124971d5a254SDimitry Andric Size = 4;
125067c32a98SDimitry Andric
12515ca98fd9SDimitry Andric if (hasCOP3()) {
1252eb11fae6SDimitry Andric LLVM_DEBUG(dbgs() << "Trying COP3_ table (32-bit opcodes):\n");
12535ca98fd9SDimitry Andric Result =
125467c32a98SDimitry Andric decodeInstruction(DecoderTableCOP3_32, Instr, Insn, Address, this, STI);
125571d5a254SDimitry Andric if (Result != MCDisassembler::Fail)
12565ca98fd9SDimitry Andric return Result;
12575ca98fd9SDimitry Andric }
12585ca98fd9SDimitry Andric
12595ca98fd9SDimitry Andric if (hasMips32r6() && isGP64()) {
1260eb11fae6SDimitry Andric LLVM_DEBUG(
1261eb11fae6SDimitry Andric dbgs() << "Trying Mips32r6_64r6 (GPR64) table (32-bit opcodes):\n");
126267c32a98SDimitry Andric Result = decodeInstruction(DecoderTableMips32r6_64r6_GP6432, Instr, Insn,
12635ca98fd9SDimitry Andric Address, this, STI);
126471d5a254SDimitry Andric if (Result != MCDisassembler::Fail)
12655ca98fd9SDimitry Andric return Result;
12665ca98fd9SDimitry Andric }
12675ca98fd9SDimitry Andric
126801095a5dSDimitry Andric if (hasMips32r6() && isPTR64()) {
1269eb11fae6SDimitry Andric LLVM_DEBUG(
1270eb11fae6SDimitry Andric dbgs() << "Trying Mips32r6_64r6 (PTR64) table (32-bit opcodes):\n");
127101095a5dSDimitry Andric Result = decodeInstruction(DecoderTableMips32r6_64r6_PTR6432, Instr, Insn,
127201095a5dSDimitry Andric Address, this, STI);
127371d5a254SDimitry Andric if (Result != MCDisassembler::Fail)
127401095a5dSDimitry Andric return Result;
127501095a5dSDimitry Andric }
127601095a5dSDimitry Andric
12775ca98fd9SDimitry Andric if (hasMips32r6()) {
1278eb11fae6SDimitry Andric LLVM_DEBUG(dbgs() << "Trying Mips32r6_64r6 table (32-bit opcodes):\n");
127967c32a98SDimitry Andric Result = decodeInstruction(DecoderTableMips32r6_64r632, Instr, Insn,
12805ca98fd9SDimitry Andric Address, this, STI);
128171d5a254SDimitry Andric if (Result != MCDisassembler::Fail)
12825ca98fd9SDimitry Andric return Result;
12835ca98fd9SDimitry Andric }
12845ca98fd9SDimitry Andric
128501095a5dSDimitry Andric if (hasMips2() && isPTR64()) {
1286eb11fae6SDimitry Andric LLVM_DEBUG(
1287eb11fae6SDimitry Andric dbgs() << "Trying Mips32r6_64r6 (PTR64) table (32-bit opcodes):\n");
128801095a5dSDimitry Andric Result = decodeInstruction(DecoderTableMips32_64_PTR6432, Instr, Insn,
128901095a5dSDimitry Andric Address, this, STI);
129071d5a254SDimitry Andric if (Result != MCDisassembler::Fail)
129101095a5dSDimitry Andric return Result;
129201095a5dSDimitry Andric }
129301095a5dSDimitry Andric
129485d8b2bbSDimitry Andric if (hasCnMips()) {
1295eb11fae6SDimitry Andric LLVM_DEBUG(dbgs() << "Trying CnMips table (32-bit opcodes):\n");
129685d8b2bbSDimitry Andric Result = decodeInstruction(DecoderTableCnMips32, Instr, Insn,
129785d8b2bbSDimitry Andric Address, this, STI);
129871d5a254SDimitry Andric if (Result != MCDisassembler::Fail)
129985d8b2bbSDimitry Andric return Result;
130085d8b2bbSDimitry Andric }
130185d8b2bbSDimitry Andric
1302706b4fc4SDimitry Andric if (hasCnMipsP()) {
1303706b4fc4SDimitry Andric LLVM_DEBUG(dbgs() << "Trying CnMipsP table (32-bit opcodes):\n");
1304706b4fc4SDimitry Andric Result = decodeInstruction(DecoderTableCnMipsP32, Instr, Insn,
1305706b4fc4SDimitry Andric Address, this, STI);
1306706b4fc4SDimitry Andric if (Result != MCDisassembler::Fail)
1307706b4fc4SDimitry Andric return Result;
1308706b4fc4SDimitry Andric }
1309706b4fc4SDimitry Andric
13105a5ac124SDimitry Andric if (isGP64()) {
1311eb11fae6SDimitry Andric LLVM_DEBUG(dbgs() << "Trying Mips64 (GPR64) table (32-bit opcodes):\n");
13125a5ac124SDimitry Andric Result = decodeInstruction(DecoderTableMips6432, Instr, Insn,
13135a5ac124SDimitry Andric Address, this, STI);
131471d5a254SDimitry Andric if (Result != MCDisassembler::Fail)
13155a5ac124SDimitry Andric return Result;
13165a5ac124SDimitry Andric }
13175a5ac124SDimitry Andric
1318044eb2f6SDimitry Andric if (isFP64()) {
1319eb11fae6SDimitry Andric LLVM_DEBUG(
1320eb11fae6SDimitry Andric dbgs() << "Trying MipsFP64 (64 bit FPU) table (32-bit opcodes):\n");
1321044eb2f6SDimitry Andric Result = decodeInstruction(DecoderTableMipsFP6432, Instr, Insn,
1322044eb2f6SDimitry Andric Address, this, STI);
1323044eb2f6SDimitry Andric if (Result != MCDisassembler::Fail)
1324044eb2f6SDimitry Andric return Result;
1325044eb2f6SDimitry Andric }
1326044eb2f6SDimitry Andric
1327eb11fae6SDimitry Andric LLVM_DEBUG(dbgs() << "Trying Mips table (32-bit opcodes):\n");
1328b61ab53cSDimitry Andric // Calling the auto-generated decoder function.
132967c32a98SDimitry Andric Result =
133067c32a98SDimitry Andric decodeInstruction(DecoderTableMips32, Instr, Insn, Address, this, STI);
133171d5a254SDimitry Andric if (Result != MCDisassembler::Fail)
1332b61ab53cSDimitry Andric return Result;
1333b61ab53cSDimitry Andric
1334b61ab53cSDimitry Andric return MCDisassembler::Fail;
1335b61ab53cSDimitry Andric }
1336b61ab53cSDimitry Andric
1337145449b1SDimitry Andric static DecodeStatus
DecodeCPU16RegsRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)1338145449b1SDimitry Andric DecodeCPU16RegsRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address,
1339145449b1SDimitry Andric const MCDisassembler *Decoder) {
13404a16efa3SDimitry Andric return MCDisassembler::Fail;
13414a16efa3SDimitry Andric }
13424a16efa3SDimitry Andric
DecodeGPR64RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)1343145449b1SDimitry Andric static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst, unsigned RegNo,
1344b61ab53cSDimitry Andric uint64_t Address,
1345145449b1SDimitry Andric const MCDisassembler *Decoder) {
1346b61ab53cSDimitry Andric if (RegNo > 31)
1347b61ab53cSDimitry Andric return MCDisassembler::Fail;
1348b61ab53cSDimitry Andric
1349f8af5cf6SDimitry Andric unsigned Reg = getReg(Decoder, Mips::GPR64RegClassID, RegNo);
13505a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(Reg));
1351b61ab53cSDimitry Andric return MCDisassembler::Success;
1352b61ab53cSDimitry Andric }
1353b61ab53cSDimitry Andric
DecodeGPRMM16RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)1354145449b1SDimitry Andric static DecodeStatus DecodeGPRMM16RegisterClass(MCInst &Inst, unsigned RegNo,
135567c32a98SDimitry Andric uint64_t Address,
1356145449b1SDimitry Andric const MCDisassembler *Decoder) {
135767c32a98SDimitry Andric if (RegNo > 7)
135867c32a98SDimitry Andric return MCDisassembler::Fail;
135967c32a98SDimitry Andric unsigned Reg = getReg(Decoder, Mips::GPRMM16RegClassID, RegNo);
13605a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(Reg));
136167c32a98SDimitry Andric return MCDisassembler::Success;
136267c32a98SDimitry Andric }
136367c32a98SDimitry Andric
1364145449b1SDimitry Andric static DecodeStatus
DecodeGPRMM16ZeroRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)1365145449b1SDimitry Andric DecodeGPRMM16ZeroRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address,
1366145449b1SDimitry Andric const MCDisassembler *Decoder) {
136767c32a98SDimitry Andric if (RegNo > 7)
136867c32a98SDimitry Andric return MCDisassembler::Fail;
136967c32a98SDimitry Andric unsigned Reg = getReg(Decoder, Mips::GPRMM16ZeroRegClassID, RegNo);
13705a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(Reg));
13715a5ac124SDimitry Andric return MCDisassembler::Success;
13725a5ac124SDimitry Andric }
13735a5ac124SDimitry Andric
1374145449b1SDimitry Andric static DecodeStatus
DecodeGPRMM16MovePRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)1375145449b1SDimitry Andric DecodeGPRMM16MovePRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address,
1376145449b1SDimitry Andric const MCDisassembler *Decoder) {
13775a5ac124SDimitry Andric if (RegNo > 7)
13785a5ac124SDimitry Andric return MCDisassembler::Fail;
13795a5ac124SDimitry Andric unsigned Reg = getReg(Decoder, Mips::GPRMM16MovePRegClassID, RegNo);
13805a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(Reg));
138167c32a98SDimitry Andric return MCDisassembler::Success;
138267c32a98SDimitry Andric }
138367c32a98SDimitry Andric
DecodeGPR32RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)1384145449b1SDimitry Andric static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst, unsigned RegNo,
1385b61ab53cSDimitry Andric uint64_t Address,
1386145449b1SDimitry Andric const MCDisassembler *Decoder) {
1387b61ab53cSDimitry Andric if (RegNo > 31)
1388b61ab53cSDimitry Andric return MCDisassembler::Fail;
1389f8af5cf6SDimitry Andric unsigned Reg = getReg(Decoder, Mips::GPR32RegClassID, RegNo);
13905a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(Reg));
1391b61ab53cSDimitry Andric return MCDisassembler::Success;
1392b61ab53cSDimitry Andric }
1393b61ab53cSDimitry Andric
DecodePtrRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)1394145449b1SDimitry Andric static DecodeStatus DecodePtrRegisterClass(MCInst &Inst, unsigned RegNo,
1395522600a2SDimitry Andric uint64_t Address,
1396145449b1SDimitry Andric const MCDisassembler *Decoder) {
13975a5ac124SDimitry Andric if (static_cast<const MipsDisassembler *>(Decoder)->isGP64())
1398f8af5cf6SDimitry Andric return DecodeGPR64RegisterClass(Inst, RegNo, Address, Decoder);
1399f8af5cf6SDimitry Andric
1400f8af5cf6SDimitry Andric return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
1401f8af5cf6SDimitry Andric }
1402f8af5cf6SDimitry Andric
DecodeDSPRRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)1403145449b1SDimitry Andric static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst, unsigned RegNo,
1404f8af5cf6SDimitry Andric uint64_t Address,
1405145449b1SDimitry Andric const MCDisassembler *Decoder) {
1406f8af5cf6SDimitry Andric return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
1407522600a2SDimitry Andric }
1408522600a2SDimitry Andric
DecodeFGR64RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)1409145449b1SDimitry Andric static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst, unsigned RegNo,
1410b61ab53cSDimitry Andric uint64_t Address,
1411145449b1SDimitry Andric const MCDisassembler *Decoder) {
1412b61ab53cSDimitry Andric if (RegNo > 31)
1413b61ab53cSDimitry Andric return MCDisassembler::Fail;
1414b61ab53cSDimitry Andric
141558b69754SDimitry Andric unsigned Reg = getReg(Decoder, Mips::FGR64RegClassID, RegNo);
14165a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(Reg));
1417b61ab53cSDimitry Andric return MCDisassembler::Success;
1418b61ab53cSDimitry Andric }
1419b61ab53cSDimitry Andric
DecodeFGR32RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)1420145449b1SDimitry Andric static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst, unsigned RegNo,
1421b61ab53cSDimitry Andric uint64_t Address,
1422145449b1SDimitry Andric const MCDisassembler *Decoder) {
1423b61ab53cSDimitry Andric if (RegNo > 31)
1424b61ab53cSDimitry Andric return MCDisassembler::Fail;
1425b61ab53cSDimitry Andric
142658b69754SDimitry Andric unsigned Reg = getReg(Decoder, Mips::FGR32RegClassID, RegNo);
14275a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(Reg));
1428b61ab53cSDimitry Andric return MCDisassembler::Success;
1429b61ab53cSDimitry Andric }
1430b61ab53cSDimitry Andric
DecodeCCRRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)1431145449b1SDimitry Andric static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst, unsigned RegNo,
1432b61ab53cSDimitry Andric uint64_t Address,
1433145449b1SDimitry Andric const MCDisassembler *Decoder) {
1434f8af5cf6SDimitry Andric if (RegNo > 31)
1435f8af5cf6SDimitry Andric return MCDisassembler::Fail;
1436f8af5cf6SDimitry Andric unsigned Reg = getReg(Decoder, Mips::CCRRegClassID, RegNo);
14375a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(Reg));
1438f8af5cf6SDimitry Andric return MCDisassembler::Success;
1439f8af5cf6SDimitry Andric }
1440f8af5cf6SDimitry Andric
DecodeFCCRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)1441145449b1SDimitry Andric static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst, unsigned RegNo,
1442f8af5cf6SDimitry Andric uint64_t Address,
1443145449b1SDimitry Andric const MCDisassembler *Decoder) {
1444f8af5cf6SDimitry Andric if (RegNo > 7)
1445f8af5cf6SDimitry Andric return MCDisassembler::Fail;
1446f8af5cf6SDimitry Andric unsigned Reg = getReg(Decoder, Mips::FCCRegClassID, RegNo);
14475a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(Reg));
1448b61ab53cSDimitry Andric return MCDisassembler::Success;
1449b61ab53cSDimitry Andric }
1450b61ab53cSDimitry Andric
DecodeFGRCCRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)14515ca98fd9SDimitry Andric static DecodeStatus DecodeFGRCCRegisterClass(MCInst &Inst, unsigned RegNo,
14525ca98fd9SDimitry Andric uint64_t Address,
1453145449b1SDimitry Andric const MCDisassembler *Decoder) {
14545ca98fd9SDimitry Andric if (RegNo > 31)
14555ca98fd9SDimitry Andric return MCDisassembler::Fail;
14565ca98fd9SDimitry Andric
14575ca98fd9SDimitry Andric unsigned Reg = getReg(Decoder, Mips::FGRCCRegClassID, RegNo);
14585a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(Reg));
14595ca98fd9SDimitry Andric return MCDisassembler::Success;
14605ca98fd9SDimitry Andric }
14615ca98fd9SDimitry Andric
DecodeMem(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)1462145449b1SDimitry Andric static DecodeStatus DecodeMem(MCInst &Inst, unsigned Insn, uint64_t Address,
1463145449b1SDimitry Andric const MCDisassembler *Decoder) {
1464b61ab53cSDimitry Andric int Offset = SignExtend32<16>(Insn & 0xffff);
1465902a7b52SDimitry Andric unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1466902a7b52SDimitry Andric unsigned Base = fieldFromInstruction(Insn, 21, 5);
146758b69754SDimitry Andric
1468f8af5cf6SDimitry Andric Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1469f8af5cf6SDimitry Andric Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1470b61ab53cSDimitry Andric
147167c32a98SDimitry Andric if (Inst.getOpcode() == Mips::SC ||
1472dd58ef01SDimitry Andric Inst.getOpcode() == Mips::SCD)
14735a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(Reg));
1474dd58ef01SDimitry Andric
1475dd58ef01SDimitry Andric Inst.addOperand(MCOperand::createReg(Reg));
1476dd58ef01SDimitry Andric Inst.addOperand(MCOperand::createReg(Base));
1477dd58ef01SDimitry Andric Inst.addOperand(MCOperand::createImm(Offset));
1478dd58ef01SDimitry Andric
1479dd58ef01SDimitry Andric return MCDisassembler::Success;
1480b61ab53cSDimitry Andric }
1481b61ab53cSDimitry Andric
DecodeMemEVA(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)1482145449b1SDimitry Andric static DecodeStatus DecodeMemEVA(MCInst &Inst, unsigned Insn, uint64_t Address,
1483145449b1SDimitry Andric const MCDisassembler *Decoder) {
1484dd58ef01SDimitry Andric int Offset = SignExtend32<9>(Insn >> 7);
1485dd58ef01SDimitry Andric unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1486dd58ef01SDimitry Andric unsigned Base = fieldFromInstruction(Insn, 21, 5);
1487dd58ef01SDimitry Andric
1488dd58ef01SDimitry Andric Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1489dd58ef01SDimitry Andric Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1490dd58ef01SDimitry Andric
1491dd58ef01SDimitry Andric if (Inst.getOpcode() == Mips::SCE)
1492dd58ef01SDimitry Andric Inst.addOperand(MCOperand::createReg(Reg));
1493dd58ef01SDimitry Andric
1494dd58ef01SDimitry Andric Inst.addOperand(MCOperand::createReg(Reg));
1495dd58ef01SDimitry Andric Inst.addOperand(MCOperand::createReg(Base));
1496dd58ef01SDimitry Andric Inst.addOperand(MCOperand::createImm(Offset));
1497dd58ef01SDimitry Andric
1498dd58ef01SDimitry Andric return MCDisassembler::Success;
1499dd58ef01SDimitry Andric }
1500dd58ef01SDimitry Andric
DecodeLoadByte15(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)1501145449b1SDimitry Andric static DecodeStatus DecodeLoadByte15(MCInst &Inst, unsigned Insn,
1502dd58ef01SDimitry Andric uint64_t Address,
1503145449b1SDimitry Andric const MCDisassembler *Decoder) {
1504dd58ef01SDimitry Andric int Offset = SignExtend32<16>(Insn & 0xffff);
1505dd58ef01SDimitry Andric unsigned Base = fieldFromInstruction(Insn, 16, 5);
1506dd58ef01SDimitry Andric unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1507dd58ef01SDimitry Andric
1508dd58ef01SDimitry Andric Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1509dd58ef01SDimitry Andric Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1510dd58ef01SDimitry Andric
15115a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(Reg));
15125a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(Base));
15135a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(Offset));
1514b61ab53cSDimitry Andric
1515b61ab53cSDimitry Andric return MCDisassembler::Success;
1516b61ab53cSDimitry Andric }
1517b61ab53cSDimitry Andric
DecodeCacheOp(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)1518145449b1SDimitry Andric static DecodeStatus DecodeCacheOp(MCInst &Inst, unsigned Insn, uint64_t Address,
1519145449b1SDimitry Andric const MCDisassembler *Decoder) {
15209f619479SDimitry Andric int Offset = SignExtend32<16>(Insn & 0xffff);
15219f619479SDimitry Andric unsigned Hint = fieldFromInstruction(Insn, 16, 5);
15229f619479SDimitry Andric unsigned Base = fieldFromInstruction(Insn, 21, 5);
15239f619479SDimitry Andric
15249f619479SDimitry Andric Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
15259f619479SDimitry Andric
15265a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(Base));
15275a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(Offset));
15285a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(Hint));
15299f619479SDimitry Andric
15309f619479SDimitry Andric return MCDisassembler::Success;
15319f619479SDimitry Andric }
15329f619479SDimitry Andric
DecodeCacheOpMM(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)1533145449b1SDimitry Andric static DecodeStatus DecodeCacheOpMM(MCInst &Inst, unsigned Insn,
153467c32a98SDimitry Andric uint64_t Address,
1535145449b1SDimitry Andric const MCDisassembler *Decoder) {
153667c32a98SDimitry Andric int Offset = SignExtend32<12>(Insn & 0xfff);
153767c32a98SDimitry Andric unsigned Base = fieldFromInstruction(Insn, 16, 5);
153867c32a98SDimitry Andric unsigned Hint = fieldFromInstruction(Insn, 21, 5);
153967c32a98SDimitry Andric
154067c32a98SDimitry Andric Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
154167c32a98SDimitry Andric
15425a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(Base));
15435a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(Offset));
15445a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(Hint));
154567c32a98SDimitry Andric
154667c32a98SDimitry Andric return MCDisassembler::Success;
154767c32a98SDimitry Andric }
154867c32a98SDimitry Andric
DecodePrefeOpMM(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)1549145449b1SDimitry Andric static DecodeStatus DecodePrefeOpMM(MCInst &Inst, unsigned Insn,
1550f03b5bedSDimitry Andric uint64_t Address,
1551145449b1SDimitry Andric const MCDisassembler *Decoder) {
1552dd58ef01SDimitry Andric int Offset = SignExtend32<9>(Insn & 0x1ff);
1553dd58ef01SDimitry Andric unsigned Base = fieldFromInstruction(Insn, 16, 5);
1554dd58ef01SDimitry Andric unsigned Hint = fieldFromInstruction(Insn, 21, 5);
1555dd58ef01SDimitry Andric
1556dd58ef01SDimitry Andric Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1557dd58ef01SDimitry Andric
1558dd58ef01SDimitry Andric Inst.addOperand(MCOperand::createReg(Base));
1559dd58ef01SDimitry Andric Inst.addOperand(MCOperand::createImm(Offset));
1560dd58ef01SDimitry Andric Inst.addOperand(MCOperand::createImm(Hint));
1561dd58ef01SDimitry Andric
1562dd58ef01SDimitry Andric return MCDisassembler::Success;
1563dd58ef01SDimitry Andric }
1564dd58ef01SDimitry Andric
DecodeCacheeOp_CacheOpR6(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)1565145449b1SDimitry Andric static DecodeStatus DecodeCacheeOp_CacheOpR6(MCInst &Inst, unsigned Insn,
1566dd58ef01SDimitry Andric uint64_t Address,
1567145449b1SDimitry Andric const MCDisassembler *Decoder) {
1568dd58ef01SDimitry Andric int Offset = SignExtend32<9>(Insn >> 7);
1569f03b5bedSDimitry Andric unsigned Hint = fieldFromInstruction(Insn, 16, 5);
1570f03b5bedSDimitry Andric unsigned Base = fieldFromInstruction(Insn, 21, 5);
1571f03b5bedSDimitry Andric
1572f03b5bedSDimitry Andric Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1573f03b5bedSDimitry Andric
15745a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(Base));
15755a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(Offset));
15765a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(Hint));
1577f03b5bedSDimitry Andric
1578f03b5bedSDimitry Andric return MCDisassembler::Success;
1579f03b5bedSDimitry Andric }
1580f03b5bedSDimitry Andric
DecodeSyncI(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)1581145449b1SDimitry Andric static DecodeStatus DecodeSyncI(MCInst &Inst, unsigned Insn, uint64_t Address,
1582145449b1SDimitry Andric const MCDisassembler *Decoder) {
158367c32a98SDimitry Andric int Offset = SignExtend32<16>(Insn & 0xffff);
158467c32a98SDimitry Andric unsigned Base = fieldFromInstruction(Insn, 21, 5);
158567c32a98SDimitry Andric
158667c32a98SDimitry Andric Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
158767c32a98SDimitry Andric
15885a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(Base));
15895a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(Offset));
159067c32a98SDimitry Andric
159167c32a98SDimitry Andric return MCDisassembler::Success;
159267c32a98SDimitry Andric }
159367c32a98SDimitry Andric
DecodeSyncI_MM(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)1594eb11fae6SDimitry Andric static DecodeStatus DecodeSyncI_MM(MCInst &Inst, unsigned Insn,
1595145449b1SDimitry Andric uint64_t Address,
1596145449b1SDimitry Andric const MCDisassembler *Decoder) {
1597eb11fae6SDimitry Andric int Offset = SignExtend32<16>(Insn & 0xffff);
1598eb11fae6SDimitry Andric unsigned Base = fieldFromInstruction(Insn, 16, 5);
1599eb11fae6SDimitry Andric
1600eb11fae6SDimitry Andric Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1601eb11fae6SDimitry Andric
1602eb11fae6SDimitry Andric Inst.addOperand(MCOperand::createReg(Base));
1603eb11fae6SDimitry Andric Inst.addOperand(MCOperand::createImm(Offset));
1604eb11fae6SDimitry Andric
1605eb11fae6SDimitry Andric return MCDisassembler::Success;
1606eb11fae6SDimitry Andric }
1607eb11fae6SDimitry Andric
DecodeSynciR6(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)1608145449b1SDimitry Andric static DecodeStatus DecodeSynciR6(MCInst &Inst, unsigned Insn, uint64_t Address,
1609145449b1SDimitry Andric const MCDisassembler *Decoder) {
1610dd58ef01SDimitry Andric int Immediate = SignExtend32<16>(Insn & 0xffff);
1611dd58ef01SDimitry Andric unsigned Base = fieldFromInstruction(Insn, 16, 5);
1612dd58ef01SDimitry Andric
1613dd58ef01SDimitry Andric Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1614dd58ef01SDimitry Andric
1615dd58ef01SDimitry Andric Inst.addOperand(MCOperand::createReg(Base));
1616dd58ef01SDimitry Andric Inst.addOperand(MCOperand::createImm(Immediate));
1617dd58ef01SDimitry Andric
1618dd58ef01SDimitry Andric return MCDisassembler::Success;
1619dd58ef01SDimitry Andric }
1620dd58ef01SDimitry Andric
DecodeMSA128Mem(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)1621f8af5cf6SDimitry Andric static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn,
1622145449b1SDimitry Andric uint64_t Address,
1623145449b1SDimitry Andric const MCDisassembler *Decoder) {
1624f8af5cf6SDimitry Andric int Offset = SignExtend32<10>(fieldFromInstruction(Insn, 16, 10));
1625f8af5cf6SDimitry Andric unsigned Reg = fieldFromInstruction(Insn, 6, 5);
1626f8af5cf6SDimitry Andric unsigned Base = fieldFromInstruction(Insn, 11, 5);
1627f8af5cf6SDimitry Andric
1628f8af5cf6SDimitry Andric Reg = getReg(Decoder, Mips::MSA128BRegClassID, Reg);
1629f8af5cf6SDimitry Andric Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1630f8af5cf6SDimitry Andric
16315a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(Reg));
16325a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(Base));
16335ca98fd9SDimitry Andric
16345ca98fd9SDimitry Andric // The immediate field of an LD/ST instruction is scaled which means it must
16355ca98fd9SDimitry Andric // be multiplied (when decoding) by the size (in bytes) of the instructions'
16365ca98fd9SDimitry Andric // data format.
16375ca98fd9SDimitry Andric // .b - 1 byte
16385ca98fd9SDimitry Andric // .h - 2 bytes
16395ca98fd9SDimitry Andric // .w - 4 bytes
16405ca98fd9SDimitry Andric // .d - 8 bytes
16415ca98fd9SDimitry Andric switch(Inst.getOpcode())
16425ca98fd9SDimitry Andric {
16435ca98fd9SDimitry Andric default:
164471d5a254SDimitry Andric assert(false && "Unexpected instruction");
16455ca98fd9SDimitry Andric return MCDisassembler::Fail;
16465ca98fd9SDimitry Andric break;
16475ca98fd9SDimitry Andric case Mips::LD_B:
16485ca98fd9SDimitry Andric case Mips::ST_B:
16495a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(Offset));
16505ca98fd9SDimitry Andric break;
16515ca98fd9SDimitry Andric case Mips::LD_H:
16525ca98fd9SDimitry Andric case Mips::ST_H:
16535a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(Offset * 2));
16545ca98fd9SDimitry Andric break;
16555ca98fd9SDimitry Andric case Mips::LD_W:
16565ca98fd9SDimitry Andric case Mips::ST_W:
16575a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(Offset * 4));
16585ca98fd9SDimitry Andric break;
16595ca98fd9SDimitry Andric case Mips::LD_D:
16605ca98fd9SDimitry Andric case Mips::ST_D:
16615a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(Offset * 8));
16625ca98fd9SDimitry Andric break;
16635ca98fd9SDimitry Andric }
1664f8af5cf6SDimitry Andric
1665f8af5cf6SDimitry Andric return MCDisassembler::Success;
1666f8af5cf6SDimitry Andric }
1667f8af5cf6SDimitry Andric
DecodeMemMMImm4(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)1668145449b1SDimitry Andric static DecodeStatus DecodeMemMMImm4(MCInst &Inst, unsigned Insn,
166967c32a98SDimitry Andric uint64_t Address,
1670145449b1SDimitry Andric const MCDisassembler *Decoder) {
167167c32a98SDimitry Andric unsigned Offset = Insn & 0xf;
167267c32a98SDimitry Andric unsigned Reg = fieldFromInstruction(Insn, 7, 3);
167367c32a98SDimitry Andric unsigned Base = fieldFromInstruction(Insn, 4, 3);
167467c32a98SDimitry Andric
167567c32a98SDimitry Andric switch (Inst.getOpcode()) {
167667c32a98SDimitry Andric case Mips::LBU16_MM:
167767c32a98SDimitry Andric case Mips::LHU16_MM:
167867c32a98SDimitry Andric case Mips::LW16_MM:
167967c32a98SDimitry Andric if (DecodeGPRMM16RegisterClass(Inst, Reg, Address, Decoder)
168067c32a98SDimitry Andric == MCDisassembler::Fail)
168167c32a98SDimitry Andric return MCDisassembler::Fail;
168267c32a98SDimitry Andric break;
168367c32a98SDimitry Andric case Mips::SB16_MM:
1684dd58ef01SDimitry Andric case Mips::SB16_MMR6:
168567c32a98SDimitry Andric case Mips::SH16_MM:
1686dd58ef01SDimitry Andric case Mips::SH16_MMR6:
168767c32a98SDimitry Andric case Mips::SW16_MM:
1688dd58ef01SDimitry Andric case Mips::SW16_MMR6:
168967c32a98SDimitry Andric if (DecodeGPRMM16ZeroRegisterClass(Inst, Reg, Address, Decoder)
169067c32a98SDimitry Andric == MCDisassembler::Fail)
169167c32a98SDimitry Andric return MCDisassembler::Fail;
169267c32a98SDimitry Andric break;
169367c32a98SDimitry Andric }
169467c32a98SDimitry Andric
169567c32a98SDimitry Andric if (DecodeGPRMM16RegisterClass(Inst, Base, Address, Decoder)
169667c32a98SDimitry Andric == MCDisassembler::Fail)
169767c32a98SDimitry Andric return MCDisassembler::Fail;
169867c32a98SDimitry Andric
169967c32a98SDimitry Andric switch (Inst.getOpcode()) {
170067c32a98SDimitry Andric case Mips::LBU16_MM:
170167c32a98SDimitry Andric if (Offset == 0xf)
17025a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(-1));
170367c32a98SDimitry Andric else
17045a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(Offset));
170567c32a98SDimitry Andric break;
170667c32a98SDimitry Andric case Mips::SB16_MM:
1707dd58ef01SDimitry Andric case Mips::SB16_MMR6:
17085a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(Offset));
170967c32a98SDimitry Andric break;
171067c32a98SDimitry Andric case Mips::LHU16_MM:
171167c32a98SDimitry Andric case Mips::SH16_MM:
1712dd58ef01SDimitry Andric case Mips::SH16_MMR6:
17135a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(Offset << 1));
171467c32a98SDimitry Andric break;
171567c32a98SDimitry Andric case Mips::LW16_MM:
171667c32a98SDimitry Andric case Mips::SW16_MM:
1717dd58ef01SDimitry Andric case Mips::SW16_MMR6:
17185a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(Offset << 2));
171967c32a98SDimitry Andric break;
172067c32a98SDimitry Andric }
172167c32a98SDimitry Andric
172267c32a98SDimitry Andric return MCDisassembler::Success;
172367c32a98SDimitry Andric }
172467c32a98SDimitry Andric
DecodeMemMMSPImm5Lsl2(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)1725145449b1SDimitry Andric static DecodeStatus DecodeMemMMSPImm5Lsl2(MCInst &Inst, unsigned Insn,
172667c32a98SDimitry Andric uint64_t Address,
1727145449b1SDimitry Andric const MCDisassembler *Decoder) {
172867c32a98SDimitry Andric unsigned Offset = Insn & 0x1F;
172967c32a98SDimitry Andric unsigned Reg = fieldFromInstruction(Insn, 5, 5);
173067c32a98SDimitry Andric
173167c32a98SDimitry Andric Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
173267c32a98SDimitry Andric
17335a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(Reg));
17345a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(Mips::SP));
17355a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(Offset << 2));
17365a5ac124SDimitry Andric
17375a5ac124SDimitry Andric return MCDisassembler::Success;
17385a5ac124SDimitry Andric }
17395a5ac124SDimitry Andric
DecodeMemMMGPImm7Lsl2(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)1740145449b1SDimitry Andric static DecodeStatus DecodeMemMMGPImm7Lsl2(MCInst &Inst, unsigned Insn,
17415a5ac124SDimitry Andric uint64_t Address,
1742145449b1SDimitry Andric const MCDisassembler *Decoder) {
17435a5ac124SDimitry Andric unsigned Offset = Insn & 0x7F;
17445a5ac124SDimitry Andric unsigned Reg = fieldFromInstruction(Insn, 7, 3);
17455a5ac124SDimitry Andric
17465a5ac124SDimitry Andric Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
17475a5ac124SDimitry Andric
17485a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(Reg));
17495a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(Mips::GP));
17505a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(Offset << 2));
17515a5ac124SDimitry Andric
17525a5ac124SDimitry Andric return MCDisassembler::Success;
17535a5ac124SDimitry Andric }
17545a5ac124SDimitry Andric
DecodeMemMMReglistImm4Lsl2(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)1755145449b1SDimitry Andric static DecodeStatus DecodeMemMMReglistImm4Lsl2(MCInst &Inst, unsigned Insn,
17565a5ac124SDimitry Andric uint64_t Address,
1757145449b1SDimitry Andric const MCDisassembler *Decoder) {
1758dd58ef01SDimitry Andric int Offset;
1759dd58ef01SDimitry Andric switch (Inst.getOpcode()) {
1760dd58ef01SDimitry Andric case Mips::LWM16_MMR6:
1761dd58ef01SDimitry Andric case Mips::SWM16_MMR6:
1762dd58ef01SDimitry Andric Offset = fieldFromInstruction(Insn, 4, 4);
1763dd58ef01SDimitry Andric break;
1764dd58ef01SDimitry Andric default:
1765dd58ef01SDimitry Andric Offset = SignExtend32<4>(Insn & 0xf);
1766dd58ef01SDimitry Andric break;
1767dd58ef01SDimitry Andric }
17685a5ac124SDimitry Andric
17695a5ac124SDimitry Andric if (DecodeRegListOperand16(Inst, Insn, Address, Decoder)
17705a5ac124SDimitry Andric == MCDisassembler::Fail)
17715a5ac124SDimitry Andric return MCDisassembler::Fail;
17725a5ac124SDimitry Andric
17735a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(Mips::SP));
17745a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(Offset << 2));
177567c32a98SDimitry Andric
177667c32a98SDimitry Andric return MCDisassembler::Success;
177767c32a98SDimitry Andric }
177867c32a98SDimitry Andric
DecodeMemMMImm9(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)1779145449b1SDimitry Andric static DecodeStatus DecodeMemMMImm9(MCInst &Inst, unsigned Insn,
1780dd58ef01SDimitry Andric uint64_t Address,
1781145449b1SDimitry Andric const MCDisassembler *Decoder) {
1782dd58ef01SDimitry Andric int Offset = SignExtend32<9>(Insn & 0x1ff);
1783dd58ef01SDimitry Andric unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1784dd58ef01SDimitry Andric unsigned Base = fieldFromInstruction(Insn, 16, 5);
1785dd58ef01SDimitry Andric
1786dd58ef01SDimitry Andric Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1787dd58ef01SDimitry Andric Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1788dd58ef01SDimitry Andric
1789eb11fae6SDimitry Andric if (Inst.getOpcode() == Mips::SCE_MM || Inst.getOpcode() == Mips::SC_MMR6)
1790dd58ef01SDimitry Andric Inst.addOperand(MCOperand::createReg(Reg));
1791dd58ef01SDimitry Andric
1792dd58ef01SDimitry Andric Inst.addOperand(MCOperand::createReg(Reg));
1793dd58ef01SDimitry Andric Inst.addOperand(MCOperand::createReg(Base));
1794dd58ef01SDimitry Andric Inst.addOperand(MCOperand::createImm(Offset));
1795dd58ef01SDimitry Andric
1796dd58ef01SDimitry Andric return MCDisassembler::Success;
1797dd58ef01SDimitry Andric }
1798dd58ef01SDimitry Andric
DecodeMemMMImm12(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)1799145449b1SDimitry Andric static DecodeStatus DecodeMemMMImm12(MCInst &Inst, unsigned Insn,
1800f8af5cf6SDimitry Andric uint64_t Address,
1801145449b1SDimitry Andric const MCDisassembler *Decoder) {
1802f8af5cf6SDimitry Andric int Offset = SignExtend32<12>(Insn & 0x0fff);
1803f8af5cf6SDimitry Andric unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1804f8af5cf6SDimitry Andric unsigned Base = fieldFromInstruction(Insn, 16, 5);
1805f8af5cf6SDimitry Andric
1806f8af5cf6SDimitry Andric Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1807f8af5cf6SDimitry Andric Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1808f8af5cf6SDimitry Andric
180967c32a98SDimitry Andric switch (Inst.getOpcode()) {
181067c32a98SDimitry Andric case Mips::SWM32_MM:
181167c32a98SDimitry Andric case Mips::LWM32_MM:
181267c32a98SDimitry Andric if (DecodeRegListOperand(Inst, Insn, Address, Decoder)
181367c32a98SDimitry Andric == MCDisassembler::Fail)
181467c32a98SDimitry Andric return MCDisassembler::Fail;
18155a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(Base));
18165a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(Offset));
181767c32a98SDimitry Andric break;
181867c32a98SDimitry Andric case Mips::SC_MM:
18195a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(Reg));
1820e3b55780SDimitry Andric [[fallthrough]];
182167c32a98SDimitry Andric default:
18225a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(Reg));
1823eb11fae6SDimitry Andric if (Inst.getOpcode() == Mips::LWP_MM || Inst.getOpcode() == Mips::SWP_MM)
18245a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(Reg+1));
182567c32a98SDimitry Andric
18265a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(Base));
18275a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(Offset));
182867c32a98SDimitry Andric }
1829f8af5cf6SDimitry Andric
1830f8af5cf6SDimitry Andric return MCDisassembler::Success;
1831f8af5cf6SDimitry Andric }
1832f8af5cf6SDimitry Andric
DecodeMemMMImm16(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)1833145449b1SDimitry Andric static DecodeStatus DecodeMemMMImm16(MCInst &Inst, unsigned Insn,
1834f8af5cf6SDimitry Andric uint64_t Address,
1835145449b1SDimitry Andric const MCDisassembler *Decoder) {
1836f8af5cf6SDimitry Andric int Offset = SignExtend32<16>(Insn & 0xffff);
1837f8af5cf6SDimitry Andric unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1838f8af5cf6SDimitry Andric unsigned Base = fieldFromInstruction(Insn, 16, 5);
1839f8af5cf6SDimitry Andric
1840f8af5cf6SDimitry Andric Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1841f8af5cf6SDimitry Andric Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1842f8af5cf6SDimitry Andric
18435a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(Reg));
18445a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(Base));
18455a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(Offset));
1846f8af5cf6SDimitry Andric
1847f8af5cf6SDimitry Andric return MCDisassembler::Success;
1848f8af5cf6SDimitry Andric }
1849f8af5cf6SDimitry Andric
DecodeFMem(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)1850145449b1SDimitry Andric static DecodeStatus DecodeFMem(MCInst &Inst, unsigned Insn, uint64_t Address,
1851145449b1SDimitry Andric const MCDisassembler *Decoder) {
1852b61ab53cSDimitry Andric int Offset = SignExtend32<16>(Insn & 0xffff);
1853902a7b52SDimitry Andric unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1854902a7b52SDimitry Andric unsigned Base = fieldFromInstruction(Insn, 21, 5);
1855b61ab53cSDimitry Andric
185658b69754SDimitry Andric Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg);
1857f8af5cf6SDimitry Andric Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
185858b69754SDimitry Andric
18595a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(Reg));
18605a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(Base));
18615a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(Offset));
1862b61ab53cSDimitry Andric
1863b61ab53cSDimitry Andric return MCDisassembler::Success;
1864b61ab53cSDimitry Andric }
1865b61ab53cSDimitry Andric
DecodeFMemMMR2(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)186601095a5dSDimitry Andric static DecodeStatus DecodeFMemMMR2(MCInst &Inst, unsigned Insn,
1867145449b1SDimitry Andric uint64_t Address,
1868145449b1SDimitry Andric const MCDisassembler *Decoder) {
186901095a5dSDimitry Andric // This function is the same as DecodeFMem but with the Reg and Base fields
187001095a5dSDimitry Andric // swapped according to microMIPS spec.
187101095a5dSDimitry Andric int Offset = SignExtend32<16>(Insn & 0xffff);
187201095a5dSDimitry Andric unsigned Base = fieldFromInstruction(Insn, 16, 5);
187301095a5dSDimitry Andric unsigned Reg = fieldFromInstruction(Insn, 21, 5);
187401095a5dSDimitry Andric
187501095a5dSDimitry Andric Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg);
187601095a5dSDimitry Andric Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
187701095a5dSDimitry Andric
187801095a5dSDimitry Andric Inst.addOperand(MCOperand::createReg(Reg));
187901095a5dSDimitry Andric Inst.addOperand(MCOperand::createReg(Base));
188001095a5dSDimitry Andric Inst.addOperand(MCOperand::createImm(Offset));
188101095a5dSDimitry Andric
188201095a5dSDimitry Andric return MCDisassembler::Success;
188301095a5dSDimitry Andric }
188401095a5dSDimitry Andric
DecodeFMem2(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)1885145449b1SDimitry Andric static DecodeStatus DecodeFMem2(MCInst &Inst, unsigned Insn, uint64_t Address,
1886145449b1SDimitry Andric const MCDisassembler *Decoder) {
18879f619479SDimitry Andric int Offset = SignExtend32<16>(Insn & 0xffff);
18889f619479SDimitry Andric unsigned Reg = fieldFromInstruction(Insn, 16, 5);
18899f619479SDimitry Andric unsigned Base = fieldFromInstruction(Insn, 21, 5);
18909f619479SDimitry Andric
18919f619479SDimitry Andric Reg = getReg(Decoder, Mips::COP2RegClassID, Reg);
18929f619479SDimitry Andric Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
18939f619479SDimitry Andric
18945a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(Reg));
18955a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(Base));
18965a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(Offset));
18979f619479SDimitry Andric
18989f619479SDimitry Andric return MCDisassembler::Success;
18999f619479SDimitry Andric }
19009f619479SDimitry Andric
DecodeFMem3(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)1901145449b1SDimitry Andric static DecodeStatus DecodeFMem3(MCInst &Inst, unsigned Insn, uint64_t Address,
1902145449b1SDimitry Andric const MCDisassembler *Decoder) {
19039f619479SDimitry Andric int Offset = SignExtend32<16>(Insn & 0xffff);
19049f619479SDimitry Andric unsigned Reg = fieldFromInstruction(Insn, 16, 5);
19059f619479SDimitry Andric unsigned Base = fieldFromInstruction(Insn, 21, 5);
19069f619479SDimitry Andric
19079f619479SDimitry Andric Reg = getReg(Decoder, Mips::COP3RegClassID, Reg);
19089f619479SDimitry Andric Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
19099f619479SDimitry Andric
19105a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(Reg));
19115a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(Base));
19125a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(Offset));
19139f619479SDimitry Andric
19149f619479SDimitry Andric return MCDisassembler::Success;
19159f619479SDimitry Andric }
19169f619479SDimitry Andric
DecodeFMemCop2R6(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)1917145449b1SDimitry Andric static DecodeStatus DecodeFMemCop2R6(MCInst &Inst, unsigned Insn,
1918f03b5bedSDimitry Andric uint64_t Address,
1919145449b1SDimitry Andric const MCDisassembler *Decoder) {
1920f03b5bedSDimitry Andric int Offset = SignExtend32<11>(Insn & 0x07ff);
1921f03b5bedSDimitry Andric unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1922f03b5bedSDimitry Andric unsigned Base = fieldFromInstruction(Insn, 11, 5);
1923f03b5bedSDimitry Andric
1924f03b5bedSDimitry Andric Reg = getReg(Decoder, Mips::COP2RegClassID, Reg);
1925f03b5bedSDimitry Andric Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1926f03b5bedSDimitry Andric
19275a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(Reg));
19285a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(Base));
19295a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(Offset));
1930f03b5bedSDimitry Andric
1931f03b5bedSDimitry Andric return MCDisassembler::Success;
1932f03b5bedSDimitry Andric }
193301095a5dSDimitry Andric
DecodeFMemCop2MMR6(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)193401095a5dSDimitry Andric static DecodeStatus DecodeFMemCop2MMR6(MCInst &Inst, unsigned Insn,
1935145449b1SDimitry Andric uint64_t Address,
1936145449b1SDimitry Andric const MCDisassembler *Decoder) {
193701095a5dSDimitry Andric int Offset = SignExtend32<11>(Insn & 0x07ff);
193801095a5dSDimitry Andric unsigned Reg = fieldFromInstruction(Insn, 21, 5);
193901095a5dSDimitry Andric unsigned Base = fieldFromInstruction(Insn, 16, 5);
194001095a5dSDimitry Andric
194101095a5dSDimitry Andric Reg = getReg(Decoder, Mips::COP2RegClassID, Reg);
194201095a5dSDimitry Andric Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
194301095a5dSDimitry Andric
194401095a5dSDimitry Andric Inst.addOperand(MCOperand::createReg(Reg));
194501095a5dSDimitry Andric Inst.addOperand(MCOperand::createReg(Base));
194601095a5dSDimitry Andric Inst.addOperand(MCOperand::createImm(Offset));
194701095a5dSDimitry Andric
194801095a5dSDimitry Andric return MCDisassembler::Success;
194901095a5dSDimitry Andric }
195001095a5dSDimitry Andric
DecodeSpecial3LlSc(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)1951145449b1SDimitry Andric static DecodeStatus DecodeSpecial3LlSc(MCInst &Inst, unsigned Insn,
19525ca98fd9SDimitry Andric uint64_t Address,
1953145449b1SDimitry Andric const MCDisassembler *Decoder) {
19545ca98fd9SDimitry Andric int64_t Offset = SignExtend64<9>((Insn >> 7) & 0x1ff);
19555ca98fd9SDimitry Andric unsigned Rt = fieldFromInstruction(Insn, 16, 5);
19565ca98fd9SDimitry Andric unsigned Base = fieldFromInstruction(Insn, 21, 5);
19575ca98fd9SDimitry Andric
19585ca98fd9SDimitry Andric Rt = getReg(Decoder, Mips::GPR32RegClassID, Rt);
19595ca98fd9SDimitry Andric Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
19605ca98fd9SDimitry Andric
19615ca98fd9SDimitry Andric if(Inst.getOpcode() == Mips::SC_R6 || Inst.getOpcode() == Mips::SCD_R6){
19625a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(Rt));
19635ca98fd9SDimitry Andric }
19645ca98fd9SDimitry Andric
19655a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(Rt));
19665a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(Base));
19675a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(Offset));
19685ca98fd9SDimitry Andric
19695ca98fd9SDimitry Andric return MCDisassembler::Success;
19705ca98fd9SDimitry Andric }
1971b61ab53cSDimitry Andric
DecodeHWRegsRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)1972145449b1SDimitry Andric static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst, unsigned RegNo,
1973b61ab53cSDimitry Andric uint64_t Address,
1974145449b1SDimitry Andric const MCDisassembler *Decoder) {
1975b61ab53cSDimitry Andric // Currently only hardware register 29 is supported.
1976b61ab53cSDimitry Andric if (RegNo != 29)
1977b61ab53cSDimitry Andric return MCDisassembler::Fail;
19785a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(Mips::HWR29));
1979b61ab53cSDimitry Andric return MCDisassembler::Success;
1980b61ab53cSDimitry Andric }
1981b61ab53cSDimitry Andric
DecodeAFGR64RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)1982145449b1SDimitry Andric static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst, unsigned RegNo,
1983b61ab53cSDimitry Andric uint64_t Address,
1984145449b1SDimitry Andric const MCDisassembler *Decoder) {
198558b69754SDimitry Andric if (RegNo > 30 || RegNo %2)
1986b61ab53cSDimitry Andric return MCDisassembler::Fail;
1987b61ab53cSDimitry Andric
198858b69754SDimitry Andric unsigned Reg = getReg(Decoder, Mips::AFGR64RegClassID, RegNo /2);
19895a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(Reg));
1990b61ab53cSDimitry Andric return MCDisassembler::Success;
1991b61ab53cSDimitry Andric }
1992b61ab53cSDimitry Andric
DecodeACC64DSPRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)1993145449b1SDimitry Andric static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst, unsigned RegNo,
1994522600a2SDimitry Andric uint64_t Address,
1995145449b1SDimitry Andric const MCDisassembler *Decoder) {
1996522600a2SDimitry Andric if (RegNo >= 4)
1997522600a2SDimitry Andric return MCDisassembler::Fail;
1998522600a2SDimitry Andric
1999f8af5cf6SDimitry Andric unsigned Reg = getReg(Decoder, Mips::ACC64DSPRegClassID, RegNo);
20005a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(Reg));
2001522600a2SDimitry Andric return MCDisassembler::Success;
2002522600a2SDimitry Andric }
2003522600a2SDimitry Andric
DecodeHI32DSPRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)2004145449b1SDimitry Andric static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst, unsigned RegNo,
200559d6cff9SDimitry Andric uint64_t Address,
2006145449b1SDimitry Andric const MCDisassembler *Decoder) {
200759d6cff9SDimitry Andric if (RegNo >= 4)
200859d6cff9SDimitry Andric return MCDisassembler::Fail;
200959d6cff9SDimitry Andric
2010f8af5cf6SDimitry Andric unsigned Reg = getReg(Decoder, Mips::HI32DSPRegClassID, RegNo);
20115a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(Reg));
201259d6cff9SDimitry Andric return MCDisassembler::Success;
201359d6cff9SDimitry Andric }
201459d6cff9SDimitry Andric
DecodeLO32DSPRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)2015145449b1SDimitry Andric static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst, unsigned RegNo,
201659d6cff9SDimitry Andric uint64_t Address,
2017145449b1SDimitry Andric const MCDisassembler *Decoder) {
201859d6cff9SDimitry Andric if (RegNo >= 4)
201959d6cff9SDimitry Andric return MCDisassembler::Fail;
202059d6cff9SDimitry Andric
2021f8af5cf6SDimitry Andric unsigned Reg = getReg(Decoder, Mips::LO32DSPRegClassID, RegNo);
20225a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(Reg));
2023f8af5cf6SDimitry Andric return MCDisassembler::Success;
2024f8af5cf6SDimitry Andric }
2025f8af5cf6SDimitry Andric
DecodeMSA128BRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)2026145449b1SDimitry Andric static DecodeStatus DecodeMSA128BRegisterClass(MCInst &Inst, unsigned RegNo,
2027f8af5cf6SDimitry Andric uint64_t Address,
2028145449b1SDimitry Andric const MCDisassembler *Decoder) {
2029f8af5cf6SDimitry Andric if (RegNo > 31)
2030f8af5cf6SDimitry Andric return MCDisassembler::Fail;
2031f8af5cf6SDimitry Andric
2032f8af5cf6SDimitry Andric unsigned Reg = getReg(Decoder, Mips::MSA128BRegClassID, RegNo);
20335a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(Reg));
2034f8af5cf6SDimitry Andric return MCDisassembler::Success;
2035f8af5cf6SDimitry Andric }
2036f8af5cf6SDimitry Andric
DecodeMSA128HRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)2037145449b1SDimitry Andric static DecodeStatus DecodeMSA128HRegisterClass(MCInst &Inst, unsigned RegNo,
2038f8af5cf6SDimitry Andric uint64_t Address,
2039145449b1SDimitry Andric const MCDisassembler *Decoder) {
2040f8af5cf6SDimitry Andric if (RegNo > 31)
2041f8af5cf6SDimitry Andric return MCDisassembler::Fail;
2042f8af5cf6SDimitry Andric
2043f8af5cf6SDimitry Andric unsigned Reg = getReg(Decoder, Mips::MSA128HRegClassID, RegNo);
20445a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(Reg));
2045f8af5cf6SDimitry Andric return MCDisassembler::Success;
2046f8af5cf6SDimitry Andric }
2047f8af5cf6SDimitry Andric
DecodeMSA128WRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)2048145449b1SDimitry Andric static DecodeStatus DecodeMSA128WRegisterClass(MCInst &Inst, unsigned RegNo,
2049f8af5cf6SDimitry Andric uint64_t Address,
2050145449b1SDimitry Andric const MCDisassembler *Decoder) {
2051f8af5cf6SDimitry Andric if (RegNo > 31)
2052f8af5cf6SDimitry Andric return MCDisassembler::Fail;
2053f8af5cf6SDimitry Andric
2054f8af5cf6SDimitry Andric unsigned Reg = getReg(Decoder, Mips::MSA128WRegClassID, RegNo);
20555a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(Reg));
2056f8af5cf6SDimitry Andric return MCDisassembler::Success;
2057f8af5cf6SDimitry Andric }
2058f8af5cf6SDimitry Andric
DecodeMSA128DRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)2059145449b1SDimitry Andric static DecodeStatus DecodeMSA128DRegisterClass(MCInst &Inst, unsigned RegNo,
2060f8af5cf6SDimitry Andric uint64_t Address,
2061145449b1SDimitry Andric const MCDisassembler *Decoder) {
2062f8af5cf6SDimitry Andric if (RegNo > 31)
2063f8af5cf6SDimitry Andric return MCDisassembler::Fail;
2064f8af5cf6SDimitry Andric
2065f8af5cf6SDimitry Andric unsigned Reg = getReg(Decoder, Mips::MSA128DRegClassID, RegNo);
20665a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(Reg));
2067f8af5cf6SDimitry Andric return MCDisassembler::Success;
2068f8af5cf6SDimitry Andric }
2069f8af5cf6SDimitry Andric
DecodeMSACtrlRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)2070145449b1SDimitry Andric static DecodeStatus DecodeMSACtrlRegisterClass(MCInst &Inst, unsigned RegNo,
2071f8af5cf6SDimitry Andric uint64_t Address,
2072145449b1SDimitry Andric const MCDisassembler *Decoder) {
2073f8af5cf6SDimitry Andric if (RegNo > 7)
2074f8af5cf6SDimitry Andric return MCDisassembler::Fail;
2075f8af5cf6SDimitry Andric
2076f8af5cf6SDimitry Andric unsigned Reg = getReg(Decoder, Mips::MSACtrlRegClassID, RegNo);
20775a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(Reg));
207859d6cff9SDimitry Andric return MCDisassembler::Success;
207959d6cff9SDimitry Andric }
208059d6cff9SDimitry Andric
DecodeCOP0RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)2081145449b1SDimitry Andric static DecodeStatus DecodeCOP0RegisterClass(MCInst &Inst, unsigned RegNo,
20821a82d4c0SDimitry Andric uint64_t Address,
2083145449b1SDimitry Andric const MCDisassembler *Decoder) {
20841a82d4c0SDimitry Andric if (RegNo > 31)
20851a82d4c0SDimitry Andric return MCDisassembler::Fail;
20861a82d4c0SDimitry Andric
20871a82d4c0SDimitry Andric unsigned Reg = getReg(Decoder, Mips::COP0RegClassID, RegNo);
20881a82d4c0SDimitry Andric Inst.addOperand(MCOperand::createReg(Reg));
20891a82d4c0SDimitry Andric return MCDisassembler::Success;
20901a82d4c0SDimitry Andric }
20911a82d4c0SDimitry Andric
DecodeCOP2RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)2092145449b1SDimitry Andric static DecodeStatus DecodeCOP2RegisterClass(MCInst &Inst, unsigned RegNo,
20935ca98fd9SDimitry Andric uint64_t Address,
2094145449b1SDimitry Andric const MCDisassembler *Decoder) {
20955ca98fd9SDimitry Andric if (RegNo > 31)
20965ca98fd9SDimitry Andric return MCDisassembler::Fail;
20975ca98fd9SDimitry Andric
20985ca98fd9SDimitry Andric unsigned Reg = getReg(Decoder, Mips::COP2RegClassID, RegNo);
20995a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(Reg));
21005ca98fd9SDimitry Andric return MCDisassembler::Success;
21015ca98fd9SDimitry Andric }
21025ca98fd9SDimitry Andric
DecodeBranchTarget(MCInst & Inst,unsigned Offset,uint64_t Address,const MCDisassembler * Decoder)2103145449b1SDimitry Andric static DecodeStatus DecodeBranchTarget(MCInst &Inst, unsigned Offset,
2104b61ab53cSDimitry Andric uint64_t Address,
2105145449b1SDimitry Andric const MCDisassembler *Decoder) {
21069f619479SDimitry Andric int32_t BranchOffset = (SignExtend32<16>(Offset) * 4) + 4;
21075a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(BranchOffset));
2108b61ab53cSDimitry Andric return MCDisassembler::Success;
2109b61ab53cSDimitry Andric }
2110b61ab53cSDimitry Andric
DecodeBranchTarget1SImm16(MCInst & Inst,unsigned Offset,uint64_t Address,const MCDisassembler * Decoder)2111145449b1SDimitry Andric static DecodeStatus DecodeBranchTarget1SImm16(MCInst &Inst, unsigned Offset,
211201095a5dSDimitry Andric uint64_t Address,
2113145449b1SDimitry Andric const MCDisassembler *Decoder) {
211401095a5dSDimitry Andric int32_t BranchOffset = (SignExtend32<16>(Offset) * 2);
211501095a5dSDimitry Andric Inst.addOperand(MCOperand::createImm(BranchOffset));
211601095a5dSDimitry Andric return MCDisassembler::Success;
211701095a5dSDimitry Andric }
211801095a5dSDimitry Andric
DecodeJumpTarget(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)2119145449b1SDimitry Andric static DecodeStatus DecodeJumpTarget(MCInst &Inst, unsigned Insn,
2120b61ab53cSDimitry Andric uint64_t Address,
2121145449b1SDimitry Andric const MCDisassembler *Decoder) {
2122902a7b52SDimitry Andric unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 2;
21235a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(JumpOffset));
2124b61ab53cSDimitry Andric return MCDisassembler::Success;
2125b61ab53cSDimitry Andric }
2126b61ab53cSDimitry Andric
DecodeBranchTarget21(MCInst & Inst,unsigned Offset,uint64_t Address,const MCDisassembler * Decoder)2127145449b1SDimitry Andric static DecodeStatus DecodeBranchTarget21(MCInst &Inst, unsigned Offset,
21285ca98fd9SDimitry Andric uint64_t Address,
2129145449b1SDimitry Andric const MCDisassembler *Decoder) {
213001095a5dSDimitry Andric int32_t BranchOffset = SignExtend32<21>(Offset) * 4 + 4;
213101095a5dSDimitry Andric
213201095a5dSDimitry Andric Inst.addOperand(MCOperand::createImm(BranchOffset));
213301095a5dSDimitry Andric return MCDisassembler::Success;
213401095a5dSDimitry Andric }
213501095a5dSDimitry Andric
DecodeBranchTarget21MM(MCInst & Inst,unsigned Offset,uint64_t Address,const MCDisassembler * Decoder)2136145449b1SDimitry Andric static DecodeStatus DecodeBranchTarget21MM(MCInst &Inst, unsigned Offset,
213701095a5dSDimitry Andric uint64_t Address,
2138145449b1SDimitry Andric const MCDisassembler *Decoder) {
2139b915e9e0SDimitry Andric int32_t BranchOffset = SignExtend32<21>(Offset) * 4 + 4;
21405ca98fd9SDimitry Andric
21415a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(BranchOffset));
21425ca98fd9SDimitry Andric return MCDisassembler::Success;
21435ca98fd9SDimitry Andric }
21445ca98fd9SDimitry Andric
DecodeBranchTarget26(MCInst & Inst,unsigned Offset,uint64_t Address,const MCDisassembler * Decoder)2145145449b1SDimitry Andric static DecodeStatus DecodeBranchTarget26(MCInst &Inst, unsigned Offset,
21465ca98fd9SDimitry Andric uint64_t Address,
2147145449b1SDimitry Andric const MCDisassembler *Decoder) {
214801095a5dSDimitry Andric int32_t BranchOffset = SignExtend32<26>(Offset) * 4 + 4;
21495ca98fd9SDimitry Andric
21505a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(BranchOffset));
21515ca98fd9SDimitry Andric return MCDisassembler::Success;
21525ca98fd9SDimitry Andric }
21535ca98fd9SDimitry Andric
DecodeBranchTarget7MM(MCInst & Inst,unsigned Offset,uint64_t Address,const MCDisassembler * Decoder)2154145449b1SDimitry Andric static DecodeStatus DecodeBranchTarget7MM(MCInst &Inst, unsigned Offset,
215567c32a98SDimitry Andric uint64_t Address,
2156145449b1SDimitry Andric const MCDisassembler *Decoder) {
2157044eb2f6SDimitry Andric int32_t BranchOffset = SignExtend32<8>(Offset << 1);
21585a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(BranchOffset));
21595a5ac124SDimitry Andric return MCDisassembler::Success;
21605a5ac124SDimitry Andric }
21615a5ac124SDimitry Andric
DecodeBranchTarget10MM(MCInst & Inst,unsigned Offset,uint64_t Address,const MCDisassembler * Decoder)2162145449b1SDimitry Andric static DecodeStatus DecodeBranchTarget10MM(MCInst &Inst, unsigned Offset,
21635a5ac124SDimitry Andric uint64_t Address,
2164145449b1SDimitry Andric const MCDisassembler *Decoder) {
2165044eb2f6SDimitry Andric int32_t BranchOffset = SignExtend32<11>(Offset << 1);
21665a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(BranchOffset));
216767c32a98SDimitry Andric return MCDisassembler::Success;
216867c32a98SDimitry Andric }
216967c32a98SDimitry Andric
DecodeBranchTargetMM(MCInst & Inst,unsigned Offset,uint64_t Address,const MCDisassembler * Decoder)2170145449b1SDimitry Andric static DecodeStatus DecodeBranchTargetMM(MCInst &Inst, unsigned Offset,
2171f8af5cf6SDimitry Andric uint64_t Address,
2172145449b1SDimitry Andric const MCDisassembler *Decoder) {
2173b915e9e0SDimitry Andric int32_t BranchOffset = SignExtend32<16>(Offset) * 2 + 4;
21745a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(BranchOffset));
2175f8af5cf6SDimitry Andric return MCDisassembler::Success;
2176f8af5cf6SDimitry Andric }
2177f8af5cf6SDimitry Andric
DecodeBranchTarget26MM(MCInst & Inst,unsigned Offset,uint64_t Address,const MCDisassembler * Decoder)2178145449b1SDimitry Andric static DecodeStatus DecodeBranchTarget26MM(MCInst &Inst, unsigned Offset,
2179dd58ef01SDimitry Andric uint64_t Address,
2180145449b1SDimitry Andric const MCDisassembler *Decoder) {
2181044eb2f6SDimitry Andric int32_t BranchOffset = SignExtend32<27>(Offset << 1);
2182dd58ef01SDimitry Andric
2183dd58ef01SDimitry Andric Inst.addOperand(MCOperand::createImm(BranchOffset));
2184dd58ef01SDimitry Andric return MCDisassembler::Success;
2185dd58ef01SDimitry Andric }
2186dd58ef01SDimitry Andric
DecodeJumpTargetMM(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)2187145449b1SDimitry Andric static DecodeStatus DecodeJumpTargetMM(MCInst &Inst, unsigned Insn,
2188f8af5cf6SDimitry Andric uint64_t Address,
2189145449b1SDimitry Andric const MCDisassembler *Decoder) {
2190f8af5cf6SDimitry Andric unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 1;
21915a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(JumpOffset));
2192f8af5cf6SDimitry Andric return MCDisassembler::Success;
2193f8af5cf6SDimitry Andric }
2194b61ab53cSDimitry Andric
DecodeJumpTargetXMM(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)2195145449b1SDimitry Andric static DecodeStatus DecodeJumpTargetXMM(MCInst &Inst, unsigned Insn,
21961d5ae102SDimitry Andric uint64_t Address,
2197145449b1SDimitry Andric const MCDisassembler *Decoder) {
21981d5ae102SDimitry Andric unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 2;
21991d5ae102SDimitry Andric Inst.addOperand(MCOperand::createImm(JumpOffset));
22001d5ae102SDimitry Andric return MCDisassembler::Success;
22011d5ae102SDimitry Andric }
22021d5ae102SDimitry Andric
DecodeAddiur2Simm7(MCInst & Inst,unsigned Value,uint64_t Address,const MCDisassembler * Decoder)2203145449b1SDimitry Andric static DecodeStatus DecodeAddiur2Simm7(MCInst &Inst, unsigned Value,
220467c32a98SDimitry Andric uint64_t Address,
2205145449b1SDimitry Andric const MCDisassembler *Decoder) {
220667c32a98SDimitry Andric if (Value == 0)
22075a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(1));
220867c32a98SDimitry Andric else if (Value == 0x7)
22095a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(-1));
221067c32a98SDimitry Andric else
22115a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(Value << 2));
221267c32a98SDimitry Andric return MCDisassembler::Success;
221367c32a98SDimitry Andric }
221467c32a98SDimitry Andric
DecodeLi16Imm(MCInst & Inst,unsigned Value,uint64_t Address,const MCDisassembler * Decoder)2215145449b1SDimitry Andric static DecodeStatus DecodeLi16Imm(MCInst &Inst, unsigned Value,
221667c32a98SDimitry Andric uint64_t Address,
2217145449b1SDimitry Andric const MCDisassembler *Decoder) {
221867c32a98SDimitry Andric if (Value == 0x7F)
22195a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(-1));
222067c32a98SDimitry Andric else
22215a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(Value));
222267c32a98SDimitry Andric return MCDisassembler::Success;
222367c32a98SDimitry Andric }
222467c32a98SDimitry Andric
DecodePOOL16BEncodedField(MCInst & Inst,unsigned Value,uint64_t Address,const MCDisassembler * Decoder)2225145449b1SDimitry Andric static DecodeStatus DecodePOOL16BEncodedField(MCInst &Inst, unsigned Value,
2226dd58ef01SDimitry Andric uint64_t Address,
2227145449b1SDimitry Andric const MCDisassembler *Decoder) {
2228dd58ef01SDimitry Andric Inst.addOperand(MCOperand::createImm(Value == 0x0 ? 8 : Value));
2229dd58ef01SDimitry Andric return MCDisassembler::Success;
2230dd58ef01SDimitry Andric }
2231dd58ef01SDimitry Andric
223201095a5dSDimitry Andric template <unsigned Bits, int Offset, int Scale>
2233145449b1SDimitry Andric static DecodeStatus
DecodeUImmWithOffsetAndScale(MCInst & Inst,unsigned Value,uint64_t Address,const MCDisassembler * Decoder)2234145449b1SDimitry Andric DecodeUImmWithOffsetAndScale(MCInst &Inst, unsigned Value, uint64_t Address,
2235145449b1SDimitry Andric const MCDisassembler *Decoder) {
2236dd58ef01SDimitry Andric Value &= ((1 << Bits) - 1);
223701095a5dSDimitry Andric Value *= Scale;
2238dd58ef01SDimitry Andric Inst.addOperand(MCOperand::createImm(Value + Offset));
2239f8af5cf6SDimitry Andric return MCDisassembler::Success;
2240f8af5cf6SDimitry Andric }
2241f8af5cf6SDimitry Andric
224201095a5dSDimitry Andric template <unsigned Bits, int Offset, int ScaleBy>
2243145449b1SDimitry Andric static DecodeStatus
DecodeSImmWithOffsetAndScale(MCInst & Inst,unsigned Value,uint64_t Address,const MCDisassembler * Decoder)2244145449b1SDimitry Andric DecodeSImmWithOffsetAndScale(MCInst &Inst, unsigned Value, uint64_t Address,
2245145449b1SDimitry Andric const MCDisassembler *Decoder) {
224601095a5dSDimitry Andric int32_t Imm = SignExtend32<Bits>(Value) * ScaleBy;
224701095a5dSDimitry Andric Inst.addOperand(MCOperand::createImm(Imm + Offset));
224801095a5dSDimitry Andric return MCDisassembler::Success;
224901095a5dSDimitry Andric }
225001095a5dSDimitry Andric
DecodeInsSize(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)2251145449b1SDimitry Andric static DecodeStatus DecodeInsSize(MCInst &Inst, unsigned Insn, uint64_t Address,
2252145449b1SDimitry Andric const MCDisassembler *Decoder) {
2253b61ab53cSDimitry Andric // First we need to grab the pos(lsb) from MCInst.
2254044eb2f6SDimitry Andric // This function only handles the 32 bit variants of ins, as dins
2255044eb2f6SDimitry Andric // variants are handled differently.
2256b61ab53cSDimitry Andric int Pos = Inst.getOperand(2).getImm();
2257044eb2f6SDimitry Andric int Size = (int) Insn - Pos + 1;
22585a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(SignExtend32<16>(Size)));
2259b61ab53cSDimitry Andric return MCDisassembler::Success;
2260b61ab53cSDimitry Andric }
2261b61ab53cSDimitry Andric
DecodeSimm19Lsl2(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)22625ca98fd9SDimitry Andric static DecodeStatus DecodeSimm19Lsl2(MCInst &Inst, unsigned Insn,
2263145449b1SDimitry Andric uint64_t Address,
2264145449b1SDimitry Andric const MCDisassembler *Decoder) {
22655a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(SignExtend32<19>(Insn) * 4));
22665ca98fd9SDimitry Andric return MCDisassembler::Success;
22675ca98fd9SDimitry Andric }
22685ca98fd9SDimitry Andric
DecodeSimm18Lsl3(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)22695ca98fd9SDimitry Andric static DecodeStatus DecodeSimm18Lsl3(MCInst &Inst, unsigned Insn,
2270145449b1SDimitry Andric uint64_t Address,
2271145449b1SDimitry Andric const MCDisassembler *Decoder) {
22725a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(SignExtend32<18>(Insn) * 8));
22735ca98fd9SDimitry Andric return MCDisassembler::Success;
22745ca98fd9SDimitry Andric }
227567c32a98SDimitry Andric
DecodeSimm9SP(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)2276145449b1SDimitry Andric static DecodeStatus DecodeSimm9SP(MCInst &Inst, unsigned Insn, uint64_t Address,
2277145449b1SDimitry Andric const MCDisassembler *Decoder) {
227867c32a98SDimitry Andric int32_t DecodedValue;
227967c32a98SDimitry Andric switch (Insn) {
228067c32a98SDimitry Andric case 0: DecodedValue = 256; break;
228167c32a98SDimitry Andric case 1: DecodedValue = 257; break;
228267c32a98SDimitry Andric case 510: DecodedValue = -258; break;
228367c32a98SDimitry Andric case 511: DecodedValue = -257; break;
228467c32a98SDimitry Andric default: DecodedValue = SignExtend32<9>(Insn); break;
228567c32a98SDimitry Andric }
22865a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(DecodedValue * 4));
228767c32a98SDimitry Andric return MCDisassembler::Success;
228867c32a98SDimitry Andric }
228967c32a98SDimitry Andric
DecodeANDI16Imm(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)229067c32a98SDimitry Andric static DecodeStatus DecodeANDI16Imm(MCInst &Inst, unsigned Insn,
2291145449b1SDimitry Andric uint64_t Address,
2292145449b1SDimitry Andric const MCDisassembler *Decoder) {
229367c32a98SDimitry Andric // Insn must be >= 0, since it is unsigned that condition is always true.
229467c32a98SDimitry Andric assert(Insn < 16);
229567c32a98SDimitry Andric int32_t DecodedValues[] = {128, 1, 2, 3, 4, 7, 8, 15, 16, 31, 32, 63, 64,
229667c32a98SDimitry Andric 255, 32768, 65535};
22975a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(DecodedValues[Insn]));
229867c32a98SDimitry Andric return MCDisassembler::Success;
229967c32a98SDimitry Andric }
230067c32a98SDimitry Andric
DecodeRegListOperand(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)2301145449b1SDimitry Andric static DecodeStatus DecodeRegListOperand(MCInst &Inst, unsigned Insn,
230267c32a98SDimitry Andric uint64_t Address,
2303145449b1SDimitry Andric const MCDisassembler *Decoder) {
230467c32a98SDimitry Andric unsigned Regs[] = {Mips::S0, Mips::S1, Mips::S2, Mips::S3, Mips::S4, Mips::S5,
2305dd58ef01SDimitry Andric Mips::S6, Mips::S7, Mips::FP};
230667c32a98SDimitry Andric unsigned RegNum;
230767c32a98SDimitry Andric
230867c32a98SDimitry Andric unsigned RegLst = fieldFromInstruction(Insn, 21, 5);
2309dd58ef01SDimitry Andric
231067c32a98SDimitry Andric // Empty register lists are not allowed.
231167c32a98SDimitry Andric if (RegLst == 0)
231267c32a98SDimitry Andric return MCDisassembler::Fail;
231367c32a98SDimitry Andric
231467c32a98SDimitry Andric RegNum = RegLst & 0xf;
2315dd58ef01SDimitry Andric
2316dd58ef01SDimitry Andric // RegLst values 10-15, and 26-31 are reserved.
2317dd58ef01SDimitry Andric if (RegNum > 9)
2318dd58ef01SDimitry Andric return MCDisassembler::Fail;
2319dd58ef01SDimitry Andric
232067c32a98SDimitry Andric for (unsigned i = 0; i < RegNum; i++)
23215a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(Regs[i]));
232267c32a98SDimitry Andric
232367c32a98SDimitry Andric if (RegLst & 0x10)
23245a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(Mips::RA));
232567c32a98SDimitry Andric
232667c32a98SDimitry Andric return MCDisassembler::Success;
232767c32a98SDimitry Andric }
232867c32a98SDimitry Andric
DecodeRegListOperand16(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)232967c32a98SDimitry Andric static DecodeStatus DecodeRegListOperand16(MCInst &Inst, unsigned Insn,
233067c32a98SDimitry Andric uint64_t Address,
2331145449b1SDimitry Andric const MCDisassembler *Decoder) {
233267c32a98SDimitry Andric unsigned Regs[] = {Mips::S0, Mips::S1, Mips::S2, Mips::S3};
2333dd58ef01SDimitry Andric unsigned RegLst;
2334dd58ef01SDimitry Andric switch(Inst.getOpcode()) {
2335dd58ef01SDimitry Andric default:
2336dd58ef01SDimitry Andric RegLst = fieldFromInstruction(Insn, 4, 2);
2337dd58ef01SDimitry Andric break;
2338dd58ef01SDimitry Andric case Mips::LWM16_MMR6:
2339dd58ef01SDimitry Andric case Mips::SWM16_MMR6:
2340dd58ef01SDimitry Andric RegLst = fieldFromInstruction(Insn, 8, 2);
2341dd58ef01SDimitry Andric break;
2342dd58ef01SDimitry Andric }
23435a5ac124SDimitry Andric unsigned RegNum = RegLst & 0x3;
23445a5ac124SDimitry Andric
23455a5ac124SDimitry Andric for (unsigned i = 0; i <= RegNum; i++)
23465a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(Regs[i]));
23475a5ac124SDimitry Andric
23485a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(Mips::RA));
23495a5ac124SDimitry Andric
23505a5ac124SDimitry Andric return MCDisassembler::Success;
23515a5ac124SDimitry Andric }
23525a5ac124SDimitry Andric
DecodeMovePOperands(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)2353d8e91e46SDimitry Andric static DecodeStatus DecodeMovePOperands(MCInst &Inst, unsigned Insn,
2354d8e91e46SDimitry Andric uint64_t Address,
2355145449b1SDimitry Andric const MCDisassembler *Decoder) {
2356d8e91e46SDimitry Andric unsigned RegPair = fieldFromInstruction(Insn, 7, 3);
2357d8e91e46SDimitry Andric if (DecodeMovePRegPair(Inst, RegPair, Address, Decoder) ==
2358d8e91e46SDimitry Andric MCDisassembler::Fail)
2359d8e91e46SDimitry Andric return MCDisassembler::Fail;
2360d8e91e46SDimitry Andric
2361d8e91e46SDimitry Andric unsigned RegRs;
2362d8e91e46SDimitry Andric if (static_cast<const MipsDisassembler*>(Decoder)->hasMips32r6())
2363d8e91e46SDimitry Andric RegRs = fieldFromInstruction(Insn, 0, 2) |
2364d8e91e46SDimitry Andric (fieldFromInstruction(Insn, 3, 1) << 2);
2365d8e91e46SDimitry Andric else
2366d8e91e46SDimitry Andric RegRs = fieldFromInstruction(Insn, 1, 3);
2367d8e91e46SDimitry Andric if (DecodeGPRMM16MovePRegisterClass(Inst, RegRs, Address, Decoder) ==
2368d8e91e46SDimitry Andric MCDisassembler::Fail)
2369d8e91e46SDimitry Andric return MCDisassembler::Fail;
2370d8e91e46SDimitry Andric
2371d8e91e46SDimitry Andric unsigned RegRt = fieldFromInstruction(Insn, 4, 3);
2372d8e91e46SDimitry Andric if (DecodeGPRMM16MovePRegisterClass(Inst, RegRt, Address, Decoder) ==
2373d8e91e46SDimitry Andric MCDisassembler::Fail)
2374d8e91e46SDimitry Andric return MCDisassembler::Fail;
2375d8e91e46SDimitry Andric
2376d8e91e46SDimitry Andric return MCDisassembler::Success;
2377d8e91e46SDimitry Andric }
2378d8e91e46SDimitry Andric
DecodeMovePRegPair(MCInst & Inst,unsigned RegPair,uint64_t Address,const MCDisassembler * Decoder)2379044eb2f6SDimitry Andric static DecodeStatus DecodeMovePRegPair(MCInst &Inst, unsigned RegPair,
2380145449b1SDimitry Andric uint64_t Address,
2381145449b1SDimitry Andric const MCDisassembler *Decoder) {
23825a5ac124SDimitry Andric switch (RegPair) {
23835a5ac124SDimitry Andric default:
238467c32a98SDimitry Andric return MCDisassembler::Fail;
23855a5ac124SDimitry Andric case 0:
23865a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(Mips::A1));
23875a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(Mips::A2));
23885a5ac124SDimitry Andric break;
23895a5ac124SDimitry Andric case 1:
23905a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(Mips::A1));
23915a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(Mips::A3));
23925a5ac124SDimitry Andric break;
23935a5ac124SDimitry Andric case 2:
23945a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(Mips::A2));
23955a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(Mips::A3));
23965a5ac124SDimitry Andric break;
23975a5ac124SDimitry Andric case 3:
23985a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(Mips::A0));
23995a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(Mips::S5));
24005a5ac124SDimitry Andric break;
24015a5ac124SDimitry Andric case 4:
24025a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(Mips::A0));
24035a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(Mips::S6));
24045a5ac124SDimitry Andric break;
24055a5ac124SDimitry Andric case 5:
24065a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(Mips::A0));
24075a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(Mips::A1));
24085a5ac124SDimitry Andric break;
24095a5ac124SDimitry Andric case 6:
24105a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(Mips::A0));
24115a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(Mips::A2));
24125a5ac124SDimitry Andric break;
24135a5ac124SDimitry Andric case 7:
24145a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(Mips::A0));
24155a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(Mips::A3));
24165a5ac124SDimitry Andric break;
24175a5ac124SDimitry Andric }
241867c32a98SDimitry Andric
24195a5ac124SDimitry Andric return MCDisassembler::Success;
24205a5ac124SDimitry Andric }
242167c32a98SDimitry Andric
DecodeSimm23Lsl2(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)24225a5ac124SDimitry Andric static DecodeStatus DecodeSimm23Lsl2(MCInst &Inst, unsigned Insn,
2423145449b1SDimitry Andric uint64_t Address,
2424145449b1SDimitry Andric const MCDisassembler *Decoder) {
24251a82d4c0SDimitry Andric Inst.addOperand(MCOperand::createImm(SignExtend32<25>(Insn << 2)));
242667c32a98SDimitry Andric return MCDisassembler::Success;
242767c32a98SDimitry Andric }
242801095a5dSDimitry Andric
242901095a5dSDimitry Andric template <typename InsnType>
DecodeBgtzGroupBranchMMR6(MCInst & MI,InsnType insn,uint64_t Address,const MCDisassembler * Decoder)243001095a5dSDimitry Andric static DecodeStatus DecodeBgtzGroupBranchMMR6(MCInst &MI, InsnType insn,
243101095a5dSDimitry Andric uint64_t Address,
2432145449b1SDimitry Andric const MCDisassembler *Decoder) {
243301095a5dSDimitry Andric // We have:
243401095a5dSDimitry Andric // 0b000111 ttttt sssss iiiiiiiiiiiiiiii
243501095a5dSDimitry Andric // Invalid if rt == 0
243601095a5dSDimitry Andric // BGTZALC_MMR6 if rs == 0 && rt != 0
243701095a5dSDimitry Andric // BLTZALC_MMR6 if rs != 0 && rs == rt
243801095a5dSDimitry Andric // BLTUC_MMR6 if rs != 0 && rs != rt
243901095a5dSDimitry Andric
244001095a5dSDimitry Andric InsnType Rt = fieldFromInstruction(insn, 21, 5);
244101095a5dSDimitry Andric InsnType Rs = fieldFromInstruction(insn, 16, 5);
2442b915e9e0SDimitry Andric InsnType Imm = 0;
244301095a5dSDimitry Andric bool HasRs = false;
244401095a5dSDimitry Andric bool HasRt = false;
244501095a5dSDimitry Andric
244601095a5dSDimitry Andric if (Rt == 0)
244701095a5dSDimitry Andric return MCDisassembler::Fail;
244801095a5dSDimitry Andric else if (Rs == 0) {
244901095a5dSDimitry Andric MI.setOpcode(Mips::BGTZALC_MMR6);
245001095a5dSDimitry Andric HasRt = true;
2451b915e9e0SDimitry Andric Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
245201095a5dSDimitry Andric }
245301095a5dSDimitry Andric else if (Rs == Rt) {
245401095a5dSDimitry Andric MI.setOpcode(Mips::BLTZALC_MMR6);
245501095a5dSDimitry Andric HasRs = true;
2456b915e9e0SDimitry Andric Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
245701095a5dSDimitry Andric }
245801095a5dSDimitry Andric else {
245901095a5dSDimitry Andric MI.setOpcode(Mips::BLTUC_MMR6);
246001095a5dSDimitry Andric HasRs = true;
246101095a5dSDimitry Andric HasRt = true;
2462b915e9e0SDimitry Andric Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
246301095a5dSDimitry Andric }
246401095a5dSDimitry Andric
246501095a5dSDimitry Andric if (HasRs)
246601095a5dSDimitry Andric MI.addOperand(
246701095a5dSDimitry Andric MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rs)));
246801095a5dSDimitry Andric
246901095a5dSDimitry Andric if (HasRt)
247001095a5dSDimitry Andric MI.addOperand(
247101095a5dSDimitry Andric MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rt)));
247201095a5dSDimitry Andric
247301095a5dSDimitry Andric MI.addOperand(MCOperand::createImm(Imm));
247401095a5dSDimitry Andric
247501095a5dSDimitry Andric return MCDisassembler::Success;
247601095a5dSDimitry Andric }
247701095a5dSDimitry Andric
247801095a5dSDimitry Andric template <typename InsnType>
DecodeBlezGroupBranchMMR6(MCInst & MI,InsnType insn,uint64_t Address,const MCDisassembler * Decoder)247901095a5dSDimitry Andric static DecodeStatus DecodeBlezGroupBranchMMR6(MCInst &MI, InsnType insn,
248001095a5dSDimitry Andric uint64_t Address,
2481145449b1SDimitry Andric const MCDisassembler *Decoder) {
248201095a5dSDimitry Andric // We have:
248301095a5dSDimitry Andric // 0b000110 ttttt sssss iiiiiiiiiiiiiiii
2484b915e9e0SDimitry Andric // Invalid if rt == 0
248501095a5dSDimitry Andric // BLEZALC_MMR6 if rs == 0 && rt != 0
248601095a5dSDimitry Andric // BGEZALC_MMR6 if rs == rt && rt != 0
248701095a5dSDimitry Andric // BGEUC_MMR6 if rs != rt && rs != 0 && rt != 0
248801095a5dSDimitry Andric
248901095a5dSDimitry Andric InsnType Rt = fieldFromInstruction(insn, 21, 5);
249001095a5dSDimitry Andric InsnType Rs = fieldFromInstruction(insn, 16, 5);
2491b915e9e0SDimitry Andric InsnType Imm = 0;
249201095a5dSDimitry Andric bool HasRs = false;
249301095a5dSDimitry Andric
249401095a5dSDimitry Andric if (Rt == 0)
249501095a5dSDimitry Andric return MCDisassembler::Fail;
2496b915e9e0SDimitry Andric else if (Rs == 0) {
249701095a5dSDimitry Andric MI.setOpcode(Mips::BLEZALC_MMR6);
2498b915e9e0SDimitry Andric Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
2499b915e9e0SDimitry Andric }
2500b915e9e0SDimitry Andric else if (Rs == Rt) {
250101095a5dSDimitry Andric MI.setOpcode(Mips::BGEZALC_MMR6);
2502b915e9e0SDimitry Andric Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
2503b915e9e0SDimitry Andric }
250401095a5dSDimitry Andric else {
250501095a5dSDimitry Andric HasRs = true;
250601095a5dSDimitry Andric MI.setOpcode(Mips::BGEUC_MMR6);
2507b915e9e0SDimitry Andric Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
250801095a5dSDimitry Andric }
250901095a5dSDimitry Andric
251001095a5dSDimitry Andric if (HasRs)
251101095a5dSDimitry Andric MI.addOperand(
251201095a5dSDimitry Andric MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rs)));
251301095a5dSDimitry Andric MI.addOperand(
251401095a5dSDimitry Andric MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rt)));
251501095a5dSDimitry Andric
251601095a5dSDimitry Andric MI.addOperand(MCOperand::createImm(Imm));
251701095a5dSDimitry Andric
251801095a5dSDimitry Andric return MCDisassembler::Success;
251901095a5dSDimitry Andric }
2520e3b55780SDimitry Andric
2521e3b55780SDimitry Andric // This instruction does not have a working decoder, and needs to be
2522e3b55780SDimitry Andric // fixed. This "fixme" function was introduced to keep the backend compiling,
2523e3b55780SDimitry Andric // while making changes to tablegen code.
DecodeFIXMEInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)2524e3b55780SDimitry Andric static DecodeStatus DecodeFIXMEInstruction(MCInst &Inst, unsigned Insn,
2525e3b55780SDimitry Andric uint64_t Address,
2526e3b55780SDimitry Andric const MCDisassembler *Decoder) {
2527e3b55780SDimitry Andric return MCDisassembler::Fail;
2528e3b55780SDimitry Andric }
2529