1f4a2713aSLionel Sambuc //===- MipsDisassembler.cpp - Disassembler for Mips -------------*- C++ -*-===//
2f4a2713aSLionel Sambuc //
3f4a2713aSLionel Sambuc //                     The LLVM Compiler Infrastructure
4f4a2713aSLionel Sambuc //
5f4a2713aSLionel Sambuc // This file is distributed under the University of Illinois Open Source
6f4a2713aSLionel Sambuc // License. See LICENSE.TXT for details.
7f4a2713aSLionel Sambuc //
8f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
9f4a2713aSLionel Sambuc //
10f4a2713aSLionel Sambuc // This file is part of the Mips Disassembler.
11f4a2713aSLionel Sambuc //
12f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
13f4a2713aSLionel Sambuc 
14f4a2713aSLionel Sambuc #include "Mips.h"
15f4a2713aSLionel Sambuc #include "MipsRegisterInfo.h"
16f4a2713aSLionel Sambuc #include "MipsSubtarget.h"
17*0a6a1f1dSLionel Sambuc #include "llvm/MC/MCContext.h"
18f4a2713aSLionel Sambuc #include "llvm/MC/MCDisassembler.h"
19f4a2713aSLionel Sambuc #include "llvm/MC/MCFixedLenDisassembler.h"
20f4a2713aSLionel Sambuc #include "llvm/MC/MCInst.h"
21f4a2713aSLionel Sambuc #include "llvm/MC/MCSubtargetInfo.h"
22f4a2713aSLionel Sambuc #include "llvm/Support/MathExtras.h"
23f4a2713aSLionel Sambuc #include "llvm/Support/TargetRegistry.h"
24f4a2713aSLionel Sambuc 
25f4a2713aSLionel Sambuc using namespace llvm;
26f4a2713aSLionel Sambuc 
27*0a6a1f1dSLionel Sambuc #define DEBUG_TYPE "mips-disassembler"
28*0a6a1f1dSLionel Sambuc 
29f4a2713aSLionel Sambuc typedef MCDisassembler::DecodeStatus DecodeStatus;
30f4a2713aSLionel Sambuc 
31f4a2713aSLionel Sambuc namespace {
32f4a2713aSLionel Sambuc 
33*0a6a1f1dSLionel Sambuc /// A disasembler class for Mips.
34f4a2713aSLionel Sambuc class MipsDisassemblerBase : public MCDisassembler {
35f4a2713aSLionel Sambuc public:
MipsDisassemblerBase(const MCSubtargetInfo & STI,MCContext & Ctx,bool IsBigEndian)36*0a6a1f1dSLionel Sambuc   MipsDisassemblerBase(const MCSubtargetInfo &STI, MCContext &Ctx,
37*0a6a1f1dSLionel Sambuc                        bool IsBigEndian)
38*0a6a1f1dSLionel Sambuc       : MCDisassembler(STI, Ctx),
39*0a6a1f1dSLionel Sambuc         IsGP64Bit(STI.getFeatureBits() & Mips::FeatureGP64Bit),
40*0a6a1f1dSLionel Sambuc         IsBigEndian(IsBigEndian) {}
41f4a2713aSLionel Sambuc 
~MipsDisassemblerBase()42f4a2713aSLionel Sambuc   virtual ~MipsDisassemblerBase() {}
43f4a2713aSLionel Sambuc 
isGP64Bit() const44*0a6a1f1dSLionel Sambuc   bool isGP64Bit() const { return IsGP64Bit; }
45f4a2713aSLionel Sambuc 
46f4a2713aSLionel Sambuc private:
47*0a6a1f1dSLionel Sambuc   bool IsGP64Bit;
48f4a2713aSLionel Sambuc protected:
49*0a6a1f1dSLionel Sambuc   bool IsBigEndian;
50f4a2713aSLionel Sambuc };
51f4a2713aSLionel Sambuc 
52*0a6a1f1dSLionel Sambuc /// A disasembler class for Mips32.
53f4a2713aSLionel Sambuc class MipsDisassembler : public MipsDisassemblerBase {
54f4a2713aSLionel Sambuc   bool IsMicroMips;
55f4a2713aSLionel Sambuc public:
MipsDisassembler(const MCSubtargetInfo & STI,MCContext & Ctx,bool bigEndian)56*0a6a1f1dSLionel Sambuc   MipsDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx, bool bigEndian)
57*0a6a1f1dSLionel Sambuc       : MipsDisassemblerBase(STI, Ctx, bigEndian) {
58f4a2713aSLionel Sambuc     IsMicroMips = STI.getFeatureBits() & Mips::FeatureMicroMips;
59f4a2713aSLionel Sambuc   }
60f4a2713aSLionel Sambuc 
hasMips3() const61*0a6a1f1dSLionel Sambuc   bool hasMips3() const { return STI.getFeatureBits() & Mips::FeatureMips3; }
hasMips32() const62*0a6a1f1dSLionel Sambuc   bool hasMips32() const { return STI.getFeatureBits() & Mips::FeatureMips32; }
hasMips32r6() const63*0a6a1f1dSLionel Sambuc   bool hasMips32r6() const {
64*0a6a1f1dSLionel Sambuc     return STI.getFeatureBits() & Mips::FeatureMips32r6;
65*0a6a1f1dSLionel Sambuc   }
66*0a6a1f1dSLionel Sambuc 
isGP64() const67*0a6a1f1dSLionel Sambuc   bool isGP64() const { return STI.getFeatureBits() & Mips::FeatureGP64Bit; }
68*0a6a1f1dSLionel Sambuc 
hasCOP3() const69*0a6a1f1dSLionel Sambuc   bool hasCOP3() const {
70*0a6a1f1dSLionel Sambuc     // Only present in MIPS-I and MIPS-II
71*0a6a1f1dSLionel Sambuc     return !hasMips32() && !hasMips3();
72*0a6a1f1dSLionel Sambuc   }
73*0a6a1f1dSLionel Sambuc 
74*0a6a1f1dSLionel Sambuc   DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
75*0a6a1f1dSLionel Sambuc                               ArrayRef<uint8_t> Bytes, uint64_t Address,
76*0a6a1f1dSLionel Sambuc                               raw_ostream &VStream,
77*0a6a1f1dSLionel Sambuc                               raw_ostream &CStream) const override;
78f4a2713aSLionel Sambuc };
79f4a2713aSLionel Sambuc 
80*0a6a1f1dSLionel Sambuc /// A disasembler class for Mips64.
81f4a2713aSLionel Sambuc class Mips64Disassembler : public MipsDisassemblerBase {
82f4a2713aSLionel Sambuc public:
Mips64Disassembler(const MCSubtargetInfo & STI,MCContext & Ctx,bool bigEndian)83*0a6a1f1dSLionel Sambuc   Mips64Disassembler(const MCSubtargetInfo &STI, MCContext &Ctx,
84f4a2713aSLionel Sambuc                      bool bigEndian) :
85*0a6a1f1dSLionel Sambuc     MipsDisassemblerBase(STI, Ctx, bigEndian) {}
86f4a2713aSLionel Sambuc 
87*0a6a1f1dSLionel Sambuc   DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
88*0a6a1f1dSLionel Sambuc                               ArrayRef<uint8_t> Bytes, uint64_t Address,
89*0a6a1f1dSLionel Sambuc                               raw_ostream &VStream,
90*0a6a1f1dSLionel Sambuc                               raw_ostream &CStream) const override;
91f4a2713aSLionel Sambuc };
92f4a2713aSLionel Sambuc 
93f4a2713aSLionel Sambuc } // end anonymous namespace
94f4a2713aSLionel Sambuc 
95f4a2713aSLionel Sambuc // Forward declare these because the autogenerated code will reference them.
96f4a2713aSLionel Sambuc // Definitions are further down.
97f4a2713aSLionel Sambuc static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst,
98f4a2713aSLionel Sambuc                                              unsigned RegNo,
99f4a2713aSLionel Sambuc                                              uint64_t Address,
100f4a2713aSLionel Sambuc                                              const void *Decoder);
101f4a2713aSLionel Sambuc 
102f4a2713aSLionel Sambuc static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst,
103f4a2713aSLionel Sambuc                                                  unsigned RegNo,
104f4a2713aSLionel Sambuc                                                  uint64_t Address,
105f4a2713aSLionel Sambuc                                                  const void *Decoder);
106f4a2713aSLionel Sambuc 
107*0a6a1f1dSLionel Sambuc static DecodeStatus DecodeGPRMM16RegisterClass(MCInst &Inst,
108*0a6a1f1dSLionel Sambuc                                                unsigned RegNo,
109*0a6a1f1dSLionel Sambuc                                                uint64_t Address,
110*0a6a1f1dSLionel Sambuc                                                const void *Decoder);
111*0a6a1f1dSLionel Sambuc 
112*0a6a1f1dSLionel Sambuc static DecodeStatus DecodeGPRMM16ZeroRegisterClass(MCInst &Inst,
113*0a6a1f1dSLionel Sambuc                                                    unsigned RegNo,
114*0a6a1f1dSLionel Sambuc                                                    uint64_t Address,
115*0a6a1f1dSLionel Sambuc                                                    const void *Decoder);
116*0a6a1f1dSLionel Sambuc 
117f4a2713aSLionel Sambuc static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst,
118f4a2713aSLionel Sambuc                                              unsigned RegNo,
119f4a2713aSLionel Sambuc                                              uint64_t Address,
120f4a2713aSLionel Sambuc                                              const void *Decoder);
121f4a2713aSLionel Sambuc 
122f4a2713aSLionel Sambuc static DecodeStatus DecodePtrRegisterClass(MCInst &Inst,
123f4a2713aSLionel Sambuc                                            unsigned Insn,
124f4a2713aSLionel Sambuc                                            uint64_t Address,
125f4a2713aSLionel Sambuc                                            const void *Decoder);
126f4a2713aSLionel Sambuc 
127f4a2713aSLionel Sambuc static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst,
128f4a2713aSLionel Sambuc                                             unsigned RegNo,
129f4a2713aSLionel Sambuc                                             uint64_t Address,
130f4a2713aSLionel Sambuc                                             const void *Decoder);
131f4a2713aSLionel Sambuc 
132f4a2713aSLionel Sambuc static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
133f4a2713aSLionel Sambuc                                              unsigned RegNo,
134f4a2713aSLionel Sambuc                                              uint64_t Address,
135f4a2713aSLionel Sambuc                                              const void *Decoder);
136f4a2713aSLionel Sambuc 
137f4a2713aSLionel Sambuc static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
138f4a2713aSLionel Sambuc                                              unsigned RegNo,
139f4a2713aSLionel Sambuc                                              uint64_t Address,
140f4a2713aSLionel Sambuc                                              const void *Decoder);
141f4a2713aSLionel Sambuc 
142f4a2713aSLionel Sambuc static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
143f4a2713aSLionel Sambuc                                            unsigned RegNo,
144f4a2713aSLionel Sambuc                                            uint64_t Address,
145f4a2713aSLionel Sambuc                                            const void *Decoder);
146f4a2713aSLionel Sambuc 
147f4a2713aSLionel Sambuc static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst,
148f4a2713aSLionel Sambuc                                            unsigned RegNo,
149f4a2713aSLionel Sambuc                                            uint64_t Address,
150f4a2713aSLionel Sambuc                                            const void *Decoder);
151f4a2713aSLionel Sambuc 
152*0a6a1f1dSLionel Sambuc static DecodeStatus DecodeFGRCCRegisterClass(MCInst &Inst, unsigned RegNo,
153*0a6a1f1dSLionel Sambuc                                              uint64_t Address,
154*0a6a1f1dSLionel Sambuc                                              const void *Decoder);
155*0a6a1f1dSLionel Sambuc 
156f4a2713aSLionel Sambuc static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
157f4a2713aSLionel Sambuc                                               unsigned Insn,
158f4a2713aSLionel Sambuc                                               uint64_t Address,
159f4a2713aSLionel Sambuc                                               const void *Decoder);
160f4a2713aSLionel Sambuc 
161f4a2713aSLionel Sambuc static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
162f4a2713aSLionel Sambuc                                               unsigned RegNo,
163f4a2713aSLionel Sambuc                                               uint64_t Address,
164f4a2713aSLionel Sambuc                                               const void *Decoder);
165f4a2713aSLionel Sambuc 
166f4a2713aSLionel Sambuc static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst,
167f4a2713aSLionel Sambuc                                                 unsigned RegNo,
168f4a2713aSLionel Sambuc                                                 uint64_t Address,
169f4a2713aSLionel Sambuc                                                 const void *Decoder);
170f4a2713aSLionel Sambuc 
171f4a2713aSLionel Sambuc static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst,
172f4a2713aSLionel Sambuc                                                unsigned RegNo,
173f4a2713aSLionel Sambuc                                                uint64_t Address,
174f4a2713aSLionel Sambuc                                                const void *Decoder);
175f4a2713aSLionel Sambuc 
176f4a2713aSLionel Sambuc static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst,
177f4a2713aSLionel Sambuc                                                unsigned RegNo,
178f4a2713aSLionel Sambuc                                                uint64_t Address,
179f4a2713aSLionel Sambuc                                                const void *Decoder);
180f4a2713aSLionel Sambuc 
181f4a2713aSLionel Sambuc static DecodeStatus DecodeMSA128BRegisterClass(MCInst &Inst,
182f4a2713aSLionel Sambuc                                                unsigned RegNo,
183f4a2713aSLionel Sambuc                                                uint64_t Address,
184f4a2713aSLionel Sambuc                                                const void *Decoder);
185f4a2713aSLionel Sambuc 
186f4a2713aSLionel Sambuc static DecodeStatus DecodeMSA128HRegisterClass(MCInst &Inst,
187f4a2713aSLionel Sambuc                                                unsigned RegNo,
188f4a2713aSLionel Sambuc                                                uint64_t Address,
189f4a2713aSLionel Sambuc                                                const void *Decoder);
190f4a2713aSLionel Sambuc 
191f4a2713aSLionel Sambuc static DecodeStatus DecodeMSA128WRegisterClass(MCInst &Inst,
192f4a2713aSLionel Sambuc                                                unsigned RegNo,
193f4a2713aSLionel Sambuc                                                uint64_t Address,
194f4a2713aSLionel Sambuc                                                const void *Decoder);
195f4a2713aSLionel Sambuc 
196f4a2713aSLionel Sambuc static DecodeStatus DecodeMSA128DRegisterClass(MCInst &Inst,
197f4a2713aSLionel Sambuc                                                unsigned RegNo,
198f4a2713aSLionel Sambuc                                                uint64_t Address,
199f4a2713aSLionel Sambuc                                                const void *Decoder);
200f4a2713aSLionel Sambuc 
201f4a2713aSLionel Sambuc static DecodeStatus DecodeMSACtrlRegisterClass(MCInst &Inst,
202f4a2713aSLionel Sambuc                                                unsigned RegNo,
203f4a2713aSLionel Sambuc                                                uint64_t Address,
204f4a2713aSLionel Sambuc                                                const void *Decoder);
205f4a2713aSLionel Sambuc 
206*0a6a1f1dSLionel Sambuc static DecodeStatus DecodeCOP2RegisterClass(MCInst &Inst,
207*0a6a1f1dSLionel Sambuc                                             unsigned RegNo,
208*0a6a1f1dSLionel Sambuc                                             uint64_t Address,
209*0a6a1f1dSLionel Sambuc                                             const void *Decoder);
210*0a6a1f1dSLionel Sambuc 
211f4a2713aSLionel Sambuc static DecodeStatus DecodeBranchTarget(MCInst &Inst,
212f4a2713aSLionel Sambuc                                        unsigned Offset,
213f4a2713aSLionel Sambuc                                        uint64_t Address,
214f4a2713aSLionel Sambuc                                        const void *Decoder);
215f4a2713aSLionel Sambuc 
216f4a2713aSLionel Sambuc static DecodeStatus DecodeJumpTarget(MCInst &Inst,
217f4a2713aSLionel Sambuc                                      unsigned Insn,
218f4a2713aSLionel Sambuc                                      uint64_t Address,
219f4a2713aSLionel Sambuc                                      const void *Decoder);
220f4a2713aSLionel Sambuc 
221*0a6a1f1dSLionel Sambuc static DecodeStatus DecodeBranchTarget21(MCInst &Inst,
222*0a6a1f1dSLionel Sambuc                                          unsigned Offset,
223*0a6a1f1dSLionel Sambuc                                          uint64_t Address,
224*0a6a1f1dSLionel Sambuc                                          const void *Decoder);
225*0a6a1f1dSLionel Sambuc 
226*0a6a1f1dSLionel Sambuc static DecodeStatus DecodeBranchTarget26(MCInst &Inst,
227*0a6a1f1dSLionel Sambuc                                          unsigned Offset,
228*0a6a1f1dSLionel Sambuc                                          uint64_t Address,
229*0a6a1f1dSLionel Sambuc                                          const void *Decoder);
230*0a6a1f1dSLionel Sambuc 
231*0a6a1f1dSLionel Sambuc // DecodeBranchTarget7MM - Decode microMIPS branch offset, which is
232*0a6a1f1dSLionel Sambuc // shifted left by 1 bit.
233*0a6a1f1dSLionel Sambuc static DecodeStatus DecodeBranchTarget7MM(MCInst &Inst,
234*0a6a1f1dSLionel Sambuc                                           unsigned Offset,
235*0a6a1f1dSLionel Sambuc                                           uint64_t Address,
236*0a6a1f1dSLionel Sambuc                                           const void *Decoder);
237*0a6a1f1dSLionel Sambuc 
238f4a2713aSLionel Sambuc // DecodeBranchTargetMM - Decode microMIPS branch offset, which is
239f4a2713aSLionel Sambuc // shifted left by 1 bit.
240f4a2713aSLionel Sambuc static DecodeStatus DecodeBranchTargetMM(MCInst &Inst,
241f4a2713aSLionel Sambuc                                          unsigned Offset,
242f4a2713aSLionel Sambuc                                          uint64_t Address,
243f4a2713aSLionel Sambuc                                          const void *Decoder);
244f4a2713aSLionel Sambuc 
245f4a2713aSLionel Sambuc // DecodeJumpTargetMM - Decode microMIPS jump target, which is
246f4a2713aSLionel Sambuc // shifted left by 1 bit.
247f4a2713aSLionel Sambuc static DecodeStatus DecodeJumpTargetMM(MCInst &Inst,
248f4a2713aSLionel Sambuc                                        unsigned Insn,
249f4a2713aSLionel Sambuc                                        uint64_t Address,
250f4a2713aSLionel Sambuc                                        const void *Decoder);
251f4a2713aSLionel Sambuc 
252f4a2713aSLionel Sambuc static DecodeStatus DecodeMem(MCInst &Inst,
253f4a2713aSLionel Sambuc                               unsigned Insn,
254f4a2713aSLionel Sambuc                               uint64_t Address,
255f4a2713aSLionel Sambuc                               const void *Decoder);
256f4a2713aSLionel Sambuc 
257*0a6a1f1dSLionel Sambuc static DecodeStatus DecodeCacheOp(MCInst &Inst,
258*0a6a1f1dSLionel Sambuc                               unsigned Insn,
259*0a6a1f1dSLionel Sambuc                               uint64_t Address,
260*0a6a1f1dSLionel Sambuc                               const void *Decoder);
261*0a6a1f1dSLionel Sambuc 
262*0a6a1f1dSLionel Sambuc static DecodeStatus DecodeCacheOpR6(MCInst &Inst,
263*0a6a1f1dSLionel Sambuc                                     unsigned Insn,
264*0a6a1f1dSLionel Sambuc                                     uint64_t Address,
265*0a6a1f1dSLionel Sambuc                                     const void *Decoder);
266*0a6a1f1dSLionel Sambuc 
267*0a6a1f1dSLionel Sambuc static DecodeStatus DecodeCacheOpMM(MCInst &Inst,
268*0a6a1f1dSLionel Sambuc                                     unsigned Insn,
269*0a6a1f1dSLionel Sambuc                                     uint64_t Address,
270*0a6a1f1dSLionel Sambuc                                     const void *Decoder);
271*0a6a1f1dSLionel Sambuc 
272*0a6a1f1dSLionel Sambuc static DecodeStatus DecodeSyncI(MCInst &Inst,
273*0a6a1f1dSLionel Sambuc                                 unsigned Insn,
274*0a6a1f1dSLionel Sambuc                                 uint64_t Address,
275*0a6a1f1dSLionel Sambuc                                 const void *Decoder);
276*0a6a1f1dSLionel Sambuc 
277f4a2713aSLionel Sambuc static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn,
278f4a2713aSLionel Sambuc                                     uint64_t Address, const void *Decoder);
279f4a2713aSLionel Sambuc 
280*0a6a1f1dSLionel Sambuc static DecodeStatus DecodeMemMMImm4(MCInst &Inst,
281*0a6a1f1dSLionel Sambuc                                     unsigned Insn,
282*0a6a1f1dSLionel Sambuc                                     uint64_t Address,
283*0a6a1f1dSLionel Sambuc                                     const void *Decoder);
284*0a6a1f1dSLionel Sambuc 
285*0a6a1f1dSLionel Sambuc static DecodeStatus DecodeMemMMSPImm5Lsl2(MCInst &Inst,
286*0a6a1f1dSLionel Sambuc                                           unsigned Insn,
287*0a6a1f1dSLionel Sambuc                                           uint64_t Address,
288*0a6a1f1dSLionel Sambuc                                           const void *Decoder);
289*0a6a1f1dSLionel Sambuc 
290f4a2713aSLionel Sambuc static DecodeStatus DecodeMemMMImm12(MCInst &Inst,
291f4a2713aSLionel Sambuc                                      unsigned Insn,
292f4a2713aSLionel Sambuc                                      uint64_t Address,
293f4a2713aSLionel Sambuc                                      const void *Decoder);
294f4a2713aSLionel Sambuc 
295f4a2713aSLionel Sambuc static DecodeStatus DecodeMemMMImm16(MCInst &Inst,
296f4a2713aSLionel Sambuc                                      unsigned Insn,
297f4a2713aSLionel Sambuc                                      uint64_t Address,
298f4a2713aSLionel Sambuc                                      const void *Decoder);
299f4a2713aSLionel Sambuc 
300f4a2713aSLionel Sambuc static DecodeStatus DecodeFMem(MCInst &Inst, unsigned Insn,
301f4a2713aSLionel Sambuc                                uint64_t Address,
302f4a2713aSLionel Sambuc                                const void *Decoder);
303f4a2713aSLionel Sambuc 
304*0a6a1f1dSLionel Sambuc static DecodeStatus DecodeFMem2(MCInst &Inst, unsigned Insn,
305*0a6a1f1dSLionel Sambuc                                uint64_t Address,
306*0a6a1f1dSLionel Sambuc                                const void *Decoder);
307*0a6a1f1dSLionel Sambuc 
308*0a6a1f1dSLionel Sambuc static DecodeStatus DecodeFMem3(MCInst &Inst, unsigned Insn,
309*0a6a1f1dSLionel Sambuc                                uint64_t Address,
310*0a6a1f1dSLionel Sambuc                                const void *Decoder);
311*0a6a1f1dSLionel Sambuc 
312*0a6a1f1dSLionel Sambuc static DecodeStatus DecodeFMemCop2R6(MCInst &Inst, unsigned Insn,
313*0a6a1f1dSLionel Sambuc                                uint64_t Address,
314*0a6a1f1dSLionel Sambuc                                const void *Decoder);
315*0a6a1f1dSLionel Sambuc 
316*0a6a1f1dSLionel Sambuc static DecodeStatus DecodeSpecial3LlSc(MCInst &Inst,
317*0a6a1f1dSLionel Sambuc                                        unsigned Insn,
318*0a6a1f1dSLionel Sambuc                                        uint64_t Address,
319*0a6a1f1dSLionel Sambuc                                        const void *Decoder);
320*0a6a1f1dSLionel Sambuc 
321*0a6a1f1dSLionel Sambuc static DecodeStatus DecodeAddiur2Simm7(MCInst &Inst,
322*0a6a1f1dSLionel Sambuc                                        unsigned Value,
323*0a6a1f1dSLionel Sambuc                                        uint64_t Address,
324*0a6a1f1dSLionel Sambuc                                        const void *Decoder);
325*0a6a1f1dSLionel Sambuc 
326*0a6a1f1dSLionel Sambuc static DecodeStatus DecodeUImm6Lsl2(MCInst &Inst,
327*0a6a1f1dSLionel Sambuc                                     unsigned Value,
328*0a6a1f1dSLionel Sambuc                                     uint64_t Address,
329*0a6a1f1dSLionel Sambuc                                     const void *Decoder);
330*0a6a1f1dSLionel Sambuc 
331*0a6a1f1dSLionel Sambuc static DecodeStatus DecodeLiSimm7(MCInst &Inst,
332*0a6a1f1dSLionel Sambuc                                   unsigned Value,
333*0a6a1f1dSLionel Sambuc                                   uint64_t Address,
334*0a6a1f1dSLionel Sambuc                                   const void *Decoder);
335*0a6a1f1dSLionel Sambuc 
336*0a6a1f1dSLionel Sambuc static DecodeStatus DecodeSimm4(MCInst &Inst,
337*0a6a1f1dSLionel Sambuc                                 unsigned Value,
338*0a6a1f1dSLionel Sambuc                                 uint64_t Address,
339*0a6a1f1dSLionel Sambuc                                 const void *Decoder);
340*0a6a1f1dSLionel Sambuc 
341f4a2713aSLionel Sambuc static DecodeStatus DecodeSimm16(MCInst &Inst,
342f4a2713aSLionel Sambuc                                  unsigned Insn,
343f4a2713aSLionel Sambuc                                  uint64_t Address,
344f4a2713aSLionel Sambuc                                  const void *Decoder);
345f4a2713aSLionel Sambuc 
346f4a2713aSLionel Sambuc // Decode the immediate field of an LSA instruction which
347f4a2713aSLionel Sambuc // is off by one.
348f4a2713aSLionel Sambuc static DecodeStatus DecodeLSAImm(MCInst &Inst,
349f4a2713aSLionel Sambuc                                  unsigned Insn,
350f4a2713aSLionel Sambuc                                  uint64_t Address,
351f4a2713aSLionel Sambuc                                  const void *Decoder);
352f4a2713aSLionel Sambuc 
353f4a2713aSLionel Sambuc static DecodeStatus DecodeInsSize(MCInst &Inst,
354f4a2713aSLionel Sambuc                                   unsigned Insn,
355f4a2713aSLionel Sambuc                                   uint64_t Address,
356f4a2713aSLionel Sambuc                                   const void *Decoder);
357f4a2713aSLionel Sambuc 
358f4a2713aSLionel Sambuc static DecodeStatus DecodeExtSize(MCInst &Inst,
359f4a2713aSLionel Sambuc                                   unsigned Insn,
360f4a2713aSLionel Sambuc                                   uint64_t Address,
361f4a2713aSLionel Sambuc                                   const void *Decoder);
362f4a2713aSLionel Sambuc 
363*0a6a1f1dSLionel Sambuc static DecodeStatus DecodeSimm19Lsl2(MCInst &Inst, unsigned Insn,
364*0a6a1f1dSLionel Sambuc                                      uint64_t Address, const void *Decoder);
365*0a6a1f1dSLionel Sambuc 
366*0a6a1f1dSLionel Sambuc static DecodeStatus DecodeSimm18Lsl3(MCInst &Inst, unsigned Insn,
367*0a6a1f1dSLionel Sambuc                                      uint64_t Address, const void *Decoder);
368*0a6a1f1dSLionel Sambuc 
369*0a6a1f1dSLionel Sambuc static DecodeStatus DecodeSimm9SP(MCInst &Inst, unsigned Insn,
370*0a6a1f1dSLionel Sambuc                                   uint64_t Address, const void *Decoder);
371*0a6a1f1dSLionel Sambuc 
372*0a6a1f1dSLionel Sambuc static DecodeStatus DecodeANDI16Imm(MCInst &Inst, unsigned Insn,
373*0a6a1f1dSLionel Sambuc                                     uint64_t Address, const void *Decoder);
374*0a6a1f1dSLionel Sambuc 
375*0a6a1f1dSLionel Sambuc static DecodeStatus DecodeUImm5lsl2(MCInst &Inst, unsigned Insn,
376*0a6a1f1dSLionel Sambuc                                    uint64_t Address, const void *Decoder);
377*0a6a1f1dSLionel Sambuc 
378*0a6a1f1dSLionel Sambuc /// INSVE_[BHWD] have an implicit operand that the generated decoder doesn't
379*0a6a1f1dSLionel Sambuc /// handle.
380*0a6a1f1dSLionel Sambuc template <typename InsnType>
381*0a6a1f1dSLionel Sambuc static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address,
382*0a6a1f1dSLionel Sambuc                                    const void *Decoder);
383*0a6a1f1dSLionel Sambuc 
384*0a6a1f1dSLionel Sambuc template <typename InsnType>
385*0a6a1f1dSLionel Sambuc static DecodeStatus
386*0a6a1f1dSLionel Sambuc DecodeAddiGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
387*0a6a1f1dSLionel Sambuc                       const void *Decoder);
388*0a6a1f1dSLionel Sambuc 
389*0a6a1f1dSLionel Sambuc template <typename InsnType>
390*0a6a1f1dSLionel Sambuc static DecodeStatus
391*0a6a1f1dSLionel Sambuc DecodeDaddiGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
392*0a6a1f1dSLionel Sambuc                        const void *Decoder);
393*0a6a1f1dSLionel Sambuc 
394*0a6a1f1dSLionel Sambuc template <typename InsnType>
395*0a6a1f1dSLionel Sambuc static DecodeStatus
396*0a6a1f1dSLionel Sambuc DecodeBlezlGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
397*0a6a1f1dSLionel Sambuc                        const void *Decoder);
398*0a6a1f1dSLionel Sambuc 
399*0a6a1f1dSLionel Sambuc template <typename InsnType>
400*0a6a1f1dSLionel Sambuc static DecodeStatus
401*0a6a1f1dSLionel Sambuc DecodeBgtzlGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
402*0a6a1f1dSLionel Sambuc                        const void *Decoder);
403*0a6a1f1dSLionel Sambuc 
404*0a6a1f1dSLionel Sambuc template <typename InsnType>
405*0a6a1f1dSLionel Sambuc static DecodeStatus
406*0a6a1f1dSLionel Sambuc DecodeBgtzGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
407*0a6a1f1dSLionel Sambuc                       const void *Decoder);
408*0a6a1f1dSLionel Sambuc 
409*0a6a1f1dSLionel Sambuc template <typename InsnType>
410*0a6a1f1dSLionel Sambuc static DecodeStatus
411*0a6a1f1dSLionel Sambuc DecodeBlezGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
412*0a6a1f1dSLionel Sambuc                        const void *Decoder);
413*0a6a1f1dSLionel Sambuc 
414*0a6a1f1dSLionel Sambuc static DecodeStatus DecodeRegListOperand(MCInst &Inst, unsigned Insn,
415*0a6a1f1dSLionel Sambuc                                          uint64_t Address,
416*0a6a1f1dSLionel Sambuc                                          const void *Decoder);
417*0a6a1f1dSLionel Sambuc 
418*0a6a1f1dSLionel Sambuc static DecodeStatus DecodeRegListOperand16(MCInst &Inst, unsigned Insn,
419*0a6a1f1dSLionel Sambuc                                            uint64_t Address,
420*0a6a1f1dSLionel Sambuc                                            const void *Decoder);
421*0a6a1f1dSLionel Sambuc 
422f4a2713aSLionel Sambuc namespace llvm {
423f4a2713aSLionel Sambuc extern Target TheMipselTarget, TheMipsTarget, TheMips64Target,
424f4a2713aSLionel Sambuc               TheMips64elTarget;
425f4a2713aSLionel Sambuc }
426f4a2713aSLionel Sambuc 
createMipsDisassembler(const Target & T,const MCSubtargetInfo & STI,MCContext & Ctx)427f4a2713aSLionel Sambuc static MCDisassembler *createMipsDisassembler(
428f4a2713aSLionel Sambuc                        const Target &T,
429*0a6a1f1dSLionel Sambuc                        const MCSubtargetInfo &STI,
430*0a6a1f1dSLionel Sambuc                        MCContext &Ctx) {
431*0a6a1f1dSLionel Sambuc   return new MipsDisassembler(STI, Ctx, true);
432f4a2713aSLionel Sambuc }
433f4a2713aSLionel Sambuc 
createMipselDisassembler(const Target & T,const MCSubtargetInfo & STI,MCContext & Ctx)434f4a2713aSLionel Sambuc static MCDisassembler *createMipselDisassembler(
435f4a2713aSLionel Sambuc                        const Target &T,
436*0a6a1f1dSLionel Sambuc                        const MCSubtargetInfo &STI,
437*0a6a1f1dSLionel Sambuc                        MCContext &Ctx) {
438*0a6a1f1dSLionel Sambuc   return new MipsDisassembler(STI, Ctx, false);
439f4a2713aSLionel Sambuc }
440f4a2713aSLionel Sambuc 
createMips64Disassembler(const Target & T,const MCSubtargetInfo & STI,MCContext & Ctx)441f4a2713aSLionel Sambuc static MCDisassembler *createMips64Disassembler(
442f4a2713aSLionel Sambuc                        const Target &T,
443*0a6a1f1dSLionel Sambuc                        const MCSubtargetInfo &STI,
444*0a6a1f1dSLionel Sambuc                        MCContext &Ctx) {
445*0a6a1f1dSLionel Sambuc   return new Mips64Disassembler(STI, Ctx, true);
446f4a2713aSLionel Sambuc }
447f4a2713aSLionel Sambuc 
createMips64elDisassembler(const Target & T,const MCSubtargetInfo & STI,MCContext & Ctx)448f4a2713aSLionel Sambuc static MCDisassembler *createMips64elDisassembler(
449f4a2713aSLionel Sambuc                        const Target &T,
450*0a6a1f1dSLionel Sambuc                        const MCSubtargetInfo &STI,
451*0a6a1f1dSLionel Sambuc                        MCContext &Ctx) {
452*0a6a1f1dSLionel Sambuc   return new Mips64Disassembler(STI, Ctx, false);
453f4a2713aSLionel Sambuc }
454f4a2713aSLionel Sambuc 
LLVMInitializeMipsDisassembler()455f4a2713aSLionel Sambuc extern "C" void LLVMInitializeMipsDisassembler() {
456f4a2713aSLionel Sambuc   // Register the disassembler.
457f4a2713aSLionel Sambuc   TargetRegistry::RegisterMCDisassembler(TheMipsTarget,
458f4a2713aSLionel Sambuc                                          createMipsDisassembler);
459f4a2713aSLionel Sambuc   TargetRegistry::RegisterMCDisassembler(TheMipselTarget,
460f4a2713aSLionel Sambuc                                          createMipselDisassembler);
461f4a2713aSLionel Sambuc   TargetRegistry::RegisterMCDisassembler(TheMips64Target,
462f4a2713aSLionel Sambuc                                          createMips64Disassembler);
463f4a2713aSLionel Sambuc   TargetRegistry::RegisterMCDisassembler(TheMips64elTarget,
464f4a2713aSLionel Sambuc                                          createMips64elDisassembler);
465f4a2713aSLionel Sambuc }
466f4a2713aSLionel Sambuc 
467f4a2713aSLionel Sambuc #include "MipsGenDisassemblerTables.inc"
468f4a2713aSLionel Sambuc 
getReg(const void * D,unsigned RC,unsigned RegNo)469*0a6a1f1dSLionel Sambuc static unsigned getReg(const void *D, unsigned RC, unsigned RegNo) {
470*0a6a1f1dSLionel Sambuc   const MipsDisassemblerBase *Dis = static_cast<const MipsDisassemblerBase*>(D);
471*0a6a1f1dSLionel Sambuc   const MCRegisterInfo *RegInfo = Dis->getContext().getRegisterInfo();
472*0a6a1f1dSLionel Sambuc   return *(RegInfo->getRegClass(RC).begin() + RegNo);
473*0a6a1f1dSLionel Sambuc }
474f4a2713aSLionel Sambuc 
475*0a6a1f1dSLionel Sambuc template <typename InsnType>
DecodeINSVE_DF(MCInst & MI,InsnType insn,uint64_t Address,const void * Decoder)476*0a6a1f1dSLionel Sambuc static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address,
477*0a6a1f1dSLionel Sambuc                                    const void *Decoder) {
478*0a6a1f1dSLionel Sambuc   typedef DecodeStatus (*DecodeFN)(MCInst &, unsigned, uint64_t, const void *);
479*0a6a1f1dSLionel Sambuc   // The size of the n field depends on the element size
480*0a6a1f1dSLionel Sambuc   // The register class also depends on this.
481*0a6a1f1dSLionel Sambuc   InsnType tmp = fieldFromInstruction(insn, 17, 5);
482*0a6a1f1dSLionel Sambuc   unsigned NSize = 0;
483*0a6a1f1dSLionel Sambuc   DecodeFN RegDecoder = nullptr;
484*0a6a1f1dSLionel Sambuc   if ((tmp & 0x18) == 0x00) { // INSVE_B
485*0a6a1f1dSLionel Sambuc     NSize = 4;
486*0a6a1f1dSLionel Sambuc     RegDecoder = DecodeMSA128BRegisterClass;
487*0a6a1f1dSLionel Sambuc   } else if ((tmp & 0x1c) == 0x10) { // INSVE_H
488*0a6a1f1dSLionel Sambuc     NSize = 3;
489*0a6a1f1dSLionel Sambuc     RegDecoder = DecodeMSA128HRegisterClass;
490*0a6a1f1dSLionel Sambuc   } else if ((tmp & 0x1e) == 0x18) { // INSVE_W
491*0a6a1f1dSLionel Sambuc     NSize = 2;
492*0a6a1f1dSLionel Sambuc     RegDecoder = DecodeMSA128WRegisterClass;
493*0a6a1f1dSLionel Sambuc   } else if ((tmp & 0x1f) == 0x1c) { // INSVE_D
494*0a6a1f1dSLionel Sambuc     NSize = 1;
495*0a6a1f1dSLionel Sambuc     RegDecoder = DecodeMSA128DRegisterClass;
496*0a6a1f1dSLionel Sambuc   } else
497*0a6a1f1dSLionel Sambuc     llvm_unreachable("Invalid encoding");
498*0a6a1f1dSLionel Sambuc 
499*0a6a1f1dSLionel Sambuc   assert(NSize != 0 && RegDecoder != nullptr);
500*0a6a1f1dSLionel Sambuc 
501*0a6a1f1dSLionel Sambuc   // $wd
502*0a6a1f1dSLionel Sambuc   tmp = fieldFromInstruction(insn, 6, 5);
503*0a6a1f1dSLionel Sambuc   if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
504*0a6a1f1dSLionel Sambuc     return MCDisassembler::Fail;
505*0a6a1f1dSLionel Sambuc   // $wd_in
506*0a6a1f1dSLionel Sambuc   if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
507*0a6a1f1dSLionel Sambuc     return MCDisassembler::Fail;
508*0a6a1f1dSLionel Sambuc   // $n
509*0a6a1f1dSLionel Sambuc   tmp = fieldFromInstruction(insn, 16, NSize);
510*0a6a1f1dSLionel Sambuc   MI.addOperand(MCOperand::CreateImm(tmp));
511*0a6a1f1dSLionel Sambuc   // $ws
512*0a6a1f1dSLionel Sambuc   tmp = fieldFromInstruction(insn, 11, 5);
513*0a6a1f1dSLionel Sambuc   if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
514*0a6a1f1dSLionel Sambuc     return MCDisassembler::Fail;
515*0a6a1f1dSLionel Sambuc   // $n2
516*0a6a1f1dSLionel Sambuc   MI.addOperand(MCOperand::CreateImm(0));
517*0a6a1f1dSLionel Sambuc 
518*0a6a1f1dSLionel Sambuc   return MCDisassembler::Success;
519*0a6a1f1dSLionel Sambuc }
520*0a6a1f1dSLionel Sambuc 
521*0a6a1f1dSLionel Sambuc template <typename InsnType>
DecodeAddiGroupBranch(MCInst & MI,InsnType insn,uint64_t Address,const void * Decoder)522*0a6a1f1dSLionel Sambuc static DecodeStatus DecodeAddiGroupBranch(MCInst &MI, InsnType insn,
523*0a6a1f1dSLionel Sambuc                                           uint64_t Address,
524*0a6a1f1dSLionel Sambuc                                           const void *Decoder) {
525*0a6a1f1dSLionel Sambuc   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
526*0a6a1f1dSLionel Sambuc   // (otherwise we would have matched the ADDI instruction from the earlier
527*0a6a1f1dSLionel Sambuc   // ISA's instead).
528*0a6a1f1dSLionel Sambuc   //
529*0a6a1f1dSLionel Sambuc   // We have:
530*0a6a1f1dSLionel Sambuc   //    0b001000 sssss ttttt iiiiiiiiiiiiiiii
531*0a6a1f1dSLionel Sambuc   //      BOVC if rs >= rt
532*0a6a1f1dSLionel Sambuc   //      BEQZALC if rs == 0 && rt != 0
533*0a6a1f1dSLionel Sambuc   //      BEQC if rs < rt && rs != 0
534*0a6a1f1dSLionel Sambuc 
535*0a6a1f1dSLionel Sambuc   InsnType Rs = fieldFromInstruction(insn, 21, 5);
536*0a6a1f1dSLionel Sambuc   InsnType Rt = fieldFromInstruction(insn, 16, 5);
537*0a6a1f1dSLionel Sambuc   InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4;
538*0a6a1f1dSLionel Sambuc   bool HasRs = false;
539*0a6a1f1dSLionel Sambuc 
540*0a6a1f1dSLionel Sambuc   if (Rs >= Rt) {
541*0a6a1f1dSLionel Sambuc     MI.setOpcode(Mips::BOVC);
542*0a6a1f1dSLionel Sambuc     HasRs = true;
543*0a6a1f1dSLionel Sambuc   } else if (Rs != 0 && Rs < Rt) {
544*0a6a1f1dSLionel Sambuc     MI.setOpcode(Mips::BEQC);
545*0a6a1f1dSLionel Sambuc     HasRs = true;
546*0a6a1f1dSLionel Sambuc   } else
547*0a6a1f1dSLionel Sambuc     MI.setOpcode(Mips::BEQZALC);
548*0a6a1f1dSLionel Sambuc 
549*0a6a1f1dSLionel Sambuc   if (HasRs)
550*0a6a1f1dSLionel Sambuc     MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
551*0a6a1f1dSLionel Sambuc                                        Rs)));
552*0a6a1f1dSLionel Sambuc 
553*0a6a1f1dSLionel Sambuc   MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
554*0a6a1f1dSLionel Sambuc                                      Rt)));
555*0a6a1f1dSLionel Sambuc   MI.addOperand(MCOperand::CreateImm(Imm));
556*0a6a1f1dSLionel Sambuc 
557*0a6a1f1dSLionel Sambuc   return MCDisassembler::Success;
558*0a6a1f1dSLionel Sambuc }
559*0a6a1f1dSLionel Sambuc 
560*0a6a1f1dSLionel Sambuc template <typename InsnType>
DecodeDaddiGroupBranch(MCInst & MI,InsnType insn,uint64_t Address,const void * Decoder)561*0a6a1f1dSLionel Sambuc static DecodeStatus DecodeDaddiGroupBranch(MCInst &MI, InsnType insn,
562*0a6a1f1dSLionel Sambuc                                            uint64_t Address,
563*0a6a1f1dSLionel Sambuc                                            const void *Decoder) {
564*0a6a1f1dSLionel Sambuc   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
565*0a6a1f1dSLionel Sambuc   // (otherwise we would have matched the ADDI instruction from the earlier
566*0a6a1f1dSLionel Sambuc   // ISA's instead).
567*0a6a1f1dSLionel Sambuc   //
568*0a6a1f1dSLionel Sambuc   // We have:
569*0a6a1f1dSLionel Sambuc   //    0b011000 sssss ttttt iiiiiiiiiiiiiiii
570*0a6a1f1dSLionel Sambuc   //      BNVC if rs >= rt
571*0a6a1f1dSLionel Sambuc   //      BNEZALC if rs == 0 && rt != 0
572*0a6a1f1dSLionel Sambuc   //      BNEC if rs < rt && rs != 0
573*0a6a1f1dSLionel Sambuc 
574*0a6a1f1dSLionel Sambuc   InsnType Rs = fieldFromInstruction(insn, 21, 5);
575*0a6a1f1dSLionel Sambuc   InsnType Rt = fieldFromInstruction(insn, 16, 5);
576*0a6a1f1dSLionel Sambuc   InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4;
577*0a6a1f1dSLionel Sambuc   bool HasRs = false;
578*0a6a1f1dSLionel Sambuc 
579*0a6a1f1dSLionel Sambuc   if (Rs >= Rt) {
580*0a6a1f1dSLionel Sambuc     MI.setOpcode(Mips::BNVC);
581*0a6a1f1dSLionel Sambuc     HasRs = true;
582*0a6a1f1dSLionel Sambuc   } else if (Rs != 0 && Rs < Rt) {
583*0a6a1f1dSLionel Sambuc     MI.setOpcode(Mips::BNEC);
584*0a6a1f1dSLionel Sambuc     HasRs = true;
585*0a6a1f1dSLionel Sambuc   } else
586*0a6a1f1dSLionel Sambuc     MI.setOpcode(Mips::BNEZALC);
587*0a6a1f1dSLionel Sambuc 
588*0a6a1f1dSLionel Sambuc   if (HasRs)
589*0a6a1f1dSLionel Sambuc     MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
590*0a6a1f1dSLionel Sambuc                                        Rs)));
591*0a6a1f1dSLionel Sambuc 
592*0a6a1f1dSLionel Sambuc   MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
593*0a6a1f1dSLionel Sambuc                                      Rt)));
594*0a6a1f1dSLionel Sambuc   MI.addOperand(MCOperand::CreateImm(Imm));
595*0a6a1f1dSLionel Sambuc 
596*0a6a1f1dSLionel Sambuc   return MCDisassembler::Success;
597*0a6a1f1dSLionel Sambuc }
598*0a6a1f1dSLionel Sambuc 
599*0a6a1f1dSLionel Sambuc template <typename InsnType>
DecodeBlezlGroupBranch(MCInst & MI,InsnType insn,uint64_t Address,const void * Decoder)600*0a6a1f1dSLionel Sambuc static DecodeStatus DecodeBlezlGroupBranch(MCInst &MI, InsnType insn,
601*0a6a1f1dSLionel Sambuc                                            uint64_t Address,
602*0a6a1f1dSLionel Sambuc                                            const void *Decoder) {
603*0a6a1f1dSLionel Sambuc   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
604*0a6a1f1dSLionel Sambuc   // (otherwise we would have matched the BLEZL instruction from the earlier
605*0a6a1f1dSLionel Sambuc   // ISA's instead).
606*0a6a1f1dSLionel Sambuc   //
607*0a6a1f1dSLionel Sambuc   // We have:
608*0a6a1f1dSLionel Sambuc   //    0b010110 sssss ttttt iiiiiiiiiiiiiiii
609*0a6a1f1dSLionel Sambuc   //      Invalid if rs == 0
610*0a6a1f1dSLionel Sambuc   //      BLEZC   if rs == 0  && rt != 0
611*0a6a1f1dSLionel Sambuc   //      BGEZC   if rs == rt && rt != 0
612*0a6a1f1dSLionel Sambuc   //      BGEC    if rs != rt && rs != 0  && rt != 0
613*0a6a1f1dSLionel Sambuc 
614*0a6a1f1dSLionel Sambuc   InsnType Rs = fieldFromInstruction(insn, 21, 5);
615*0a6a1f1dSLionel Sambuc   InsnType Rt = fieldFromInstruction(insn, 16, 5);
616*0a6a1f1dSLionel Sambuc   InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4;
617*0a6a1f1dSLionel Sambuc   bool HasRs = false;
618*0a6a1f1dSLionel Sambuc 
619*0a6a1f1dSLionel Sambuc   if (Rt == 0)
620*0a6a1f1dSLionel Sambuc     return MCDisassembler::Fail;
621*0a6a1f1dSLionel Sambuc   else if (Rs == 0)
622*0a6a1f1dSLionel Sambuc     MI.setOpcode(Mips::BLEZC);
623*0a6a1f1dSLionel Sambuc   else if (Rs == Rt)
624*0a6a1f1dSLionel Sambuc     MI.setOpcode(Mips::BGEZC);
625*0a6a1f1dSLionel Sambuc   else {
626*0a6a1f1dSLionel Sambuc     HasRs = true;
627*0a6a1f1dSLionel Sambuc     MI.setOpcode(Mips::BGEC);
628*0a6a1f1dSLionel Sambuc   }
629*0a6a1f1dSLionel Sambuc 
630*0a6a1f1dSLionel Sambuc   if (HasRs)
631*0a6a1f1dSLionel Sambuc     MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
632*0a6a1f1dSLionel Sambuc                                        Rs)));
633*0a6a1f1dSLionel Sambuc 
634*0a6a1f1dSLionel Sambuc   MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
635*0a6a1f1dSLionel Sambuc                                      Rt)));
636*0a6a1f1dSLionel Sambuc 
637*0a6a1f1dSLionel Sambuc   MI.addOperand(MCOperand::CreateImm(Imm));
638*0a6a1f1dSLionel Sambuc 
639*0a6a1f1dSLionel Sambuc   return MCDisassembler::Success;
640*0a6a1f1dSLionel Sambuc }
641*0a6a1f1dSLionel Sambuc 
642*0a6a1f1dSLionel Sambuc template <typename InsnType>
DecodeBgtzlGroupBranch(MCInst & MI,InsnType insn,uint64_t Address,const void * Decoder)643*0a6a1f1dSLionel Sambuc static DecodeStatus DecodeBgtzlGroupBranch(MCInst &MI, InsnType insn,
644*0a6a1f1dSLionel Sambuc                                            uint64_t Address,
645*0a6a1f1dSLionel Sambuc                                            const void *Decoder) {
646*0a6a1f1dSLionel Sambuc   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
647*0a6a1f1dSLionel Sambuc   // (otherwise we would have matched the BGTZL instruction from the earlier
648*0a6a1f1dSLionel Sambuc   // ISA's instead).
649*0a6a1f1dSLionel Sambuc   //
650*0a6a1f1dSLionel Sambuc   // We have:
651*0a6a1f1dSLionel Sambuc   //    0b010111 sssss ttttt iiiiiiiiiiiiiiii
652*0a6a1f1dSLionel Sambuc   //      Invalid if rs == 0
653*0a6a1f1dSLionel Sambuc   //      BGTZC   if rs == 0  && rt != 0
654*0a6a1f1dSLionel Sambuc   //      BLTZC   if rs == rt && rt != 0
655*0a6a1f1dSLionel Sambuc   //      BLTC    if rs != rt && rs != 0  && rt != 0
656*0a6a1f1dSLionel Sambuc 
657*0a6a1f1dSLionel Sambuc   bool HasRs = false;
658*0a6a1f1dSLionel Sambuc 
659*0a6a1f1dSLionel Sambuc   InsnType Rs = fieldFromInstruction(insn, 21, 5);
660*0a6a1f1dSLionel Sambuc   InsnType Rt = fieldFromInstruction(insn, 16, 5);
661*0a6a1f1dSLionel Sambuc   InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4;
662*0a6a1f1dSLionel Sambuc 
663*0a6a1f1dSLionel Sambuc   if (Rt == 0)
664*0a6a1f1dSLionel Sambuc     return MCDisassembler::Fail;
665*0a6a1f1dSLionel Sambuc   else if (Rs == 0)
666*0a6a1f1dSLionel Sambuc     MI.setOpcode(Mips::BGTZC);
667*0a6a1f1dSLionel Sambuc   else if (Rs == Rt)
668*0a6a1f1dSLionel Sambuc     MI.setOpcode(Mips::BLTZC);
669*0a6a1f1dSLionel Sambuc   else {
670*0a6a1f1dSLionel Sambuc     MI.setOpcode(Mips::BLTC);
671*0a6a1f1dSLionel Sambuc     HasRs = true;
672*0a6a1f1dSLionel Sambuc   }
673*0a6a1f1dSLionel Sambuc 
674*0a6a1f1dSLionel Sambuc   if (HasRs)
675*0a6a1f1dSLionel Sambuc     MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
676*0a6a1f1dSLionel Sambuc                                               Rs)));
677*0a6a1f1dSLionel Sambuc 
678*0a6a1f1dSLionel Sambuc   MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
679*0a6a1f1dSLionel Sambuc                                      Rt)));
680*0a6a1f1dSLionel Sambuc 
681*0a6a1f1dSLionel Sambuc   MI.addOperand(MCOperand::CreateImm(Imm));
682*0a6a1f1dSLionel Sambuc 
683*0a6a1f1dSLionel Sambuc   return MCDisassembler::Success;
684*0a6a1f1dSLionel Sambuc }
685*0a6a1f1dSLionel Sambuc 
686*0a6a1f1dSLionel Sambuc template <typename InsnType>
DecodeBgtzGroupBranch(MCInst & MI,InsnType insn,uint64_t Address,const void * Decoder)687*0a6a1f1dSLionel Sambuc static DecodeStatus DecodeBgtzGroupBranch(MCInst &MI, InsnType insn,
688*0a6a1f1dSLionel Sambuc                                           uint64_t Address,
689*0a6a1f1dSLionel Sambuc                                           const void *Decoder) {
690*0a6a1f1dSLionel Sambuc   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
691*0a6a1f1dSLionel Sambuc   // (otherwise we would have matched the BGTZ instruction from the earlier
692*0a6a1f1dSLionel Sambuc   // ISA's instead).
693*0a6a1f1dSLionel Sambuc   //
694*0a6a1f1dSLionel Sambuc   // We have:
695*0a6a1f1dSLionel Sambuc   //    0b000111 sssss ttttt iiiiiiiiiiiiiiii
696*0a6a1f1dSLionel Sambuc   //      BGTZ    if rt == 0
697*0a6a1f1dSLionel Sambuc   //      BGTZALC if rs == 0 && rt != 0
698*0a6a1f1dSLionel Sambuc   //      BLTZALC if rs != 0 && rs == rt
699*0a6a1f1dSLionel Sambuc   //      BLTUC   if rs != 0 && rs != rt
700*0a6a1f1dSLionel Sambuc 
701*0a6a1f1dSLionel Sambuc   InsnType Rs = fieldFromInstruction(insn, 21, 5);
702*0a6a1f1dSLionel Sambuc   InsnType Rt = fieldFromInstruction(insn, 16, 5);
703*0a6a1f1dSLionel Sambuc   InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4;
704*0a6a1f1dSLionel Sambuc   bool HasRs = false;
705*0a6a1f1dSLionel Sambuc   bool HasRt = false;
706*0a6a1f1dSLionel Sambuc 
707*0a6a1f1dSLionel Sambuc   if (Rt == 0) {
708*0a6a1f1dSLionel Sambuc     MI.setOpcode(Mips::BGTZ);
709*0a6a1f1dSLionel Sambuc     HasRs = true;
710*0a6a1f1dSLionel Sambuc   } else if (Rs == 0) {
711*0a6a1f1dSLionel Sambuc     MI.setOpcode(Mips::BGTZALC);
712*0a6a1f1dSLionel Sambuc     HasRt = true;
713*0a6a1f1dSLionel Sambuc   } else if (Rs == Rt) {
714*0a6a1f1dSLionel Sambuc     MI.setOpcode(Mips::BLTZALC);
715*0a6a1f1dSLionel Sambuc     HasRs = true;
716*0a6a1f1dSLionel Sambuc   } else {
717*0a6a1f1dSLionel Sambuc     MI.setOpcode(Mips::BLTUC);
718*0a6a1f1dSLionel Sambuc     HasRs = true;
719*0a6a1f1dSLionel Sambuc     HasRt = true;
720*0a6a1f1dSLionel Sambuc   }
721*0a6a1f1dSLionel Sambuc 
722*0a6a1f1dSLionel Sambuc   if (HasRs)
723*0a6a1f1dSLionel Sambuc     MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
724*0a6a1f1dSLionel Sambuc                                        Rs)));
725*0a6a1f1dSLionel Sambuc 
726*0a6a1f1dSLionel Sambuc   if (HasRt)
727*0a6a1f1dSLionel Sambuc     MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
728*0a6a1f1dSLionel Sambuc                                        Rt)));
729*0a6a1f1dSLionel Sambuc 
730*0a6a1f1dSLionel Sambuc   MI.addOperand(MCOperand::CreateImm(Imm));
731*0a6a1f1dSLionel Sambuc 
732*0a6a1f1dSLionel Sambuc   return MCDisassembler::Success;
733*0a6a1f1dSLionel Sambuc }
734*0a6a1f1dSLionel Sambuc 
735*0a6a1f1dSLionel Sambuc template <typename InsnType>
DecodeBlezGroupBranch(MCInst & MI,InsnType insn,uint64_t Address,const void * Decoder)736*0a6a1f1dSLionel Sambuc static DecodeStatus DecodeBlezGroupBranch(MCInst &MI, InsnType insn,
737*0a6a1f1dSLionel Sambuc                                            uint64_t Address,
738*0a6a1f1dSLionel Sambuc                                            const void *Decoder) {
739*0a6a1f1dSLionel Sambuc   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
740*0a6a1f1dSLionel Sambuc   // (otherwise we would have matched the BLEZL instruction from the earlier
741*0a6a1f1dSLionel Sambuc   // ISA's instead).
742*0a6a1f1dSLionel Sambuc   //
743*0a6a1f1dSLionel Sambuc   // We have:
744*0a6a1f1dSLionel Sambuc   //    0b000110 sssss ttttt iiiiiiiiiiiiiiii
745*0a6a1f1dSLionel Sambuc   //      Invalid   if rs == 0
746*0a6a1f1dSLionel Sambuc   //      BLEZALC   if rs == 0  && rt != 0
747*0a6a1f1dSLionel Sambuc   //      BGEZALC   if rs == rt && rt != 0
748*0a6a1f1dSLionel Sambuc   //      BGEUC     if rs != rt && rs != 0  && rt != 0
749*0a6a1f1dSLionel Sambuc 
750*0a6a1f1dSLionel Sambuc   InsnType Rs = fieldFromInstruction(insn, 21, 5);
751*0a6a1f1dSLionel Sambuc   InsnType Rt = fieldFromInstruction(insn, 16, 5);
752*0a6a1f1dSLionel Sambuc   InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4;
753*0a6a1f1dSLionel Sambuc   bool HasRs = false;
754*0a6a1f1dSLionel Sambuc 
755*0a6a1f1dSLionel Sambuc   if (Rt == 0)
756*0a6a1f1dSLionel Sambuc     return MCDisassembler::Fail;
757*0a6a1f1dSLionel Sambuc   else if (Rs == 0)
758*0a6a1f1dSLionel Sambuc     MI.setOpcode(Mips::BLEZALC);
759*0a6a1f1dSLionel Sambuc   else if (Rs == Rt)
760*0a6a1f1dSLionel Sambuc     MI.setOpcode(Mips::BGEZALC);
761*0a6a1f1dSLionel Sambuc   else {
762*0a6a1f1dSLionel Sambuc     HasRs = true;
763*0a6a1f1dSLionel Sambuc     MI.setOpcode(Mips::BGEUC);
764*0a6a1f1dSLionel Sambuc   }
765*0a6a1f1dSLionel Sambuc 
766*0a6a1f1dSLionel Sambuc   if (HasRs)
767*0a6a1f1dSLionel Sambuc     MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
768*0a6a1f1dSLionel Sambuc                                        Rs)));
769*0a6a1f1dSLionel Sambuc   MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
770*0a6a1f1dSLionel Sambuc                                      Rt)));
771*0a6a1f1dSLionel Sambuc 
772*0a6a1f1dSLionel Sambuc   MI.addOperand(MCOperand::CreateImm(Imm));
773*0a6a1f1dSLionel Sambuc 
774*0a6a1f1dSLionel Sambuc   return MCDisassembler::Success;
775*0a6a1f1dSLionel Sambuc }
776*0a6a1f1dSLionel Sambuc 
777*0a6a1f1dSLionel Sambuc /// Read two bytes from the ArrayRef and return 16 bit halfword sorted
778*0a6a1f1dSLionel Sambuc /// according to the given endianess.
readInstruction16(ArrayRef<uint8_t> Bytes,uint64_t Address,uint64_t & Size,uint32_t & Insn,bool IsBigEndian)779*0a6a1f1dSLionel Sambuc static DecodeStatus readInstruction16(ArrayRef<uint8_t> Bytes, uint64_t Address,
780*0a6a1f1dSLionel Sambuc                                       uint64_t &Size, uint32_t &Insn,
781*0a6a1f1dSLionel Sambuc                                       bool IsBigEndian) {
782*0a6a1f1dSLionel Sambuc   // We want to read exactly 2 Bytes of data.
783*0a6a1f1dSLionel Sambuc   if (Bytes.size() < 2) {
784*0a6a1f1dSLionel Sambuc     Size = 0;
785f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
786f4a2713aSLionel Sambuc   }
787f4a2713aSLionel Sambuc 
788*0a6a1f1dSLionel Sambuc   if (IsBigEndian) {
789*0a6a1f1dSLionel Sambuc     Insn = (Bytes[0] << 8) | Bytes[1];
790*0a6a1f1dSLionel Sambuc   } else {
791*0a6a1f1dSLionel Sambuc     Insn = (Bytes[1] << 8) | Bytes[0];
792f4a2713aSLionel Sambuc   }
793*0a6a1f1dSLionel Sambuc 
794*0a6a1f1dSLionel Sambuc   return MCDisassembler::Success;
795*0a6a1f1dSLionel Sambuc }
796*0a6a1f1dSLionel Sambuc 
797*0a6a1f1dSLionel Sambuc /// Read four bytes from the ArrayRef and return 32 bit word sorted
798*0a6a1f1dSLionel Sambuc /// according to the given endianess
readInstruction32(ArrayRef<uint8_t> Bytes,uint64_t Address,uint64_t & Size,uint32_t & Insn,bool IsBigEndian,bool IsMicroMips)799*0a6a1f1dSLionel Sambuc static DecodeStatus readInstruction32(ArrayRef<uint8_t> Bytes, uint64_t Address,
800*0a6a1f1dSLionel Sambuc                                       uint64_t &Size, uint32_t &Insn,
801*0a6a1f1dSLionel Sambuc                                       bool IsBigEndian, bool IsMicroMips) {
802*0a6a1f1dSLionel Sambuc   // We want to read exactly 4 Bytes of data.
803*0a6a1f1dSLionel Sambuc   if (Bytes.size() < 4) {
804*0a6a1f1dSLionel Sambuc     Size = 0;
805*0a6a1f1dSLionel Sambuc     return MCDisassembler::Fail;
806*0a6a1f1dSLionel Sambuc   }
807*0a6a1f1dSLionel Sambuc 
808*0a6a1f1dSLionel Sambuc   // High 16 bits of a 32-bit microMIPS instruction (where the opcode is)
809*0a6a1f1dSLionel Sambuc   // always precede the low 16 bits in the instruction stream (that is, they
810*0a6a1f1dSLionel Sambuc   // are placed at lower addresses in the instruction stream).
811*0a6a1f1dSLionel Sambuc   //
812*0a6a1f1dSLionel Sambuc   // microMIPS byte ordering:
813*0a6a1f1dSLionel Sambuc   //   Big-endian:    0 | 1 | 2 | 3
814*0a6a1f1dSLionel Sambuc   //   Little-endian: 1 | 0 | 3 | 2
815*0a6a1f1dSLionel Sambuc 
816*0a6a1f1dSLionel Sambuc   if (IsBigEndian) {
817*0a6a1f1dSLionel Sambuc     // Encoded as a big-endian 32-bit word in the stream.
818*0a6a1f1dSLionel Sambuc     Insn =
819*0a6a1f1dSLionel Sambuc         (Bytes[3] << 0) | (Bytes[2] << 8) | (Bytes[1] << 16) | (Bytes[0] << 24);
820*0a6a1f1dSLionel Sambuc   } else {
821f4a2713aSLionel Sambuc     if (IsMicroMips) {
822*0a6a1f1dSLionel Sambuc       Insn = (Bytes[2] << 0) | (Bytes[3] << 8) | (Bytes[0] << 16) |
823f4a2713aSLionel Sambuc              (Bytes[1] << 24);
824f4a2713aSLionel Sambuc     } else {
825*0a6a1f1dSLionel Sambuc       Insn = (Bytes[0] << 0) | (Bytes[1] << 8) | (Bytes[2] << 16) |
826f4a2713aSLionel Sambuc              (Bytes[3] << 24);
827f4a2713aSLionel Sambuc     }
828f4a2713aSLionel Sambuc   }
829f4a2713aSLionel Sambuc 
830f4a2713aSLionel Sambuc   return MCDisassembler::Success;
831f4a2713aSLionel Sambuc }
832f4a2713aSLionel Sambuc 
getInstruction(MCInst & Instr,uint64_t & Size,ArrayRef<uint8_t> Bytes,uint64_t Address,raw_ostream & VStream,raw_ostream & CStream) const833*0a6a1f1dSLionel Sambuc DecodeStatus MipsDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,
834*0a6a1f1dSLionel Sambuc                                               ArrayRef<uint8_t> Bytes,
835f4a2713aSLionel Sambuc                                               uint64_t Address,
836*0a6a1f1dSLionel Sambuc                                               raw_ostream &VStream,
837*0a6a1f1dSLionel Sambuc                                               raw_ostream &CStream) const {
838f4a2713aSLionel Sambuc   uint32_t Insn;
839*0a6a1f1dSLionel Sambuc   DecodeStatus Result;
840f4a2713aSLionel Sambuc 
841f4a2713aSLionel Sambuc   if (IsMicroMips) {
842*0a6a1f1dSLionel Sambuc     Result = readInstruction16(Bytes, Address, Size, Insn, IsBigEndian);
843*0a6a1f1dSLionel Sambuc 
844*0a6a1f1dSLionel Sambuc     DEBUG(dbgs() << "Trying MicroMips16 table (16-bit instructions):\n");
845f4a2713aSLionel Sambuc     // Calling the auto-generated decoder function.
846*0a6a1f1dSLionel Sambuc     Result = decodeInstruction(DecoderTableMicroMips16, Instr, Insn, Address,
847*0a6a1f1dSLionel Sambuc                                this, STI);
848*0a6a1f1dSLionel Sambuc     if (Result != MCDisassembler::Fail) {
849*0a6a1f1dSLionel Sambuc       Size = 2;
850*0a6a1f1dSLionel Sambuc       return Result;
851*0a6a1f1dSLionel Sambuc     }
852*0a6a1f1dSLionel Sambuc 
853*0a6a1f1dSLionel Sambuc     Result = readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, true);
854*0a6a1f1dSLionel Sambuc     if (Result == MCDisassembler::Fail)
855*0a6a1f1dSLionel Sambuc       return MCDisassembler::Fail;
856*0a6a1f1dSLionel Sambuc 
857*0a6a1f1dSLionel Sambuc     DEBUG(dbgs() << "Trying MicroMips32 table (32-bit instructions):\n");
858*0a6a1f1dSLionel Sambuc     // Calling the auto-generated decoder function.
859*0a6a1f1dSLionel Sambuc     Result = decodeInstruction(DecoderTableMicroMips32, Instr, Insn, Address,
860f4a2713aSLionel Sambuc                                this, STI);
861f4a2713aSLionel Sambuc     if (Result != MCDisassembler::Fail) {
862f4a2713aSLionel Sambuc       Size = 4;
863f4a2713aSLionel Sambuc       return Result;
864f4a2713aSLionel Sambuc     }
865f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
866f4a2713aSLionel Sambuc   }
867f4a2713aSLionel Sambuc 
868*0a6a1f1dSLionel Sambuc   Result = readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, false);
869*0a6a1f1dSLionel Sambuc   if (Result == MCDisassembler::Fail)
870*0a6a1f1dSLionel Sambuc     return MCDisassembler::Fail;
871*0a6a1f1dSLionel Sambuc 
872*0a6a1f1dSLionel Sambuc   if (hasCOP3()) {
873*0a6a1f1dSLionel Sambuc     DEBUG(dbgs() << "Trying COP3_ table (32-bit opcodes):\n");
874*0a6a1f1dSLionel Sambuc     Result =
875*0a6a1f1dSLionel Sambuc         decodeInstruction(DecoderTableCOP3_32, Instr, Insn, Address, this, STI);
876*0a6a1f1dSLionel Sambuc     if (Result != MCDisassembler::Fail) {
877*0a6a1f1dSLionel Sambuc       Size = 4;
878*0a6a1f1dSLionel Sambuc       return Result;
879*0a6a1f1dSLionel Sambuc     }
880*0a6a1f1dSLionel Sambuc   }
881*0a6a1f1dSLionel Sambuc 
882*0a6a1f1dSLionel Sambuc   if (hasMips32r6() && isGP64()) {
883*0a6a1f1dSLionel Sambuc     DEBUG(dbgs() << "Trying Mips32r6_64r6 (GPR64) table (32-bit opcodes):\n");
884*0a6a1f1dSLionel Sambuc     Result = decodeInstruction(DecoderTableMips32r6_64r6_GP6432, Instr, Insn,
885*0a6a1f1dSLionel Sambuc                                Address, this, STI);
886*0a6a1f1dSLionel Sambuc     if (Result != MCDisassembler::Fail) {
887*0a6a1f1dSLionel Sambuc       Size = 4;
888*0a6a1f1dSLionel Sambuc       return Result;
889*0a6a1f1dSLionel Sambuc     }
890*0a6a1f1dSLionel Sambuc   }
891*0a6a1f1dSLionel Sambuc 
892*0a6a1f1dSLionel Sambuc   if (hasMips32r6()) {
893*0a6a1f1dSLionel Sambuc     DEBUG(dbgs() << "Trying Mips32r6_64r6 table (32-bit opcodes):\n");
894*0a6a1f1dSLionel Sambuc     Result = decodeInstruction(DecoderTableMips32r6_64r632, Instr, Insn,
895*0a6a1f1dSLionel Sambuc                                Address, this, STI);
896*0a6a1f1dSLionel Sambuc     if (Result != MCDisassembler::Fail) {
897*0a6a1f1dSLionel Sambuc       Size = 4;
898*0a6a1f1dSLionel Sambuc       return Result;
899*0a6a1f1dSLionel Sambuc     }
900*0a6a1f1dSLionel Sambuc   }
901*0a6a1f1dSLionel Sambuc 
902*0a6a1f1dSLionel Sambuc   DEBUG(dbgs() << "Trying Mips table (32-bit opcodes):\n");
903f4a2713aSLionel Sambuc   // Calling the auto-generated decoder function.
904*0a6a1f1dSLionel Sambuc   Result =
905*0a6a1f1dSLionel Sambuc       decodeInstruction(DecoderTableMips32, Instr, Insn, Address, this, STI);
906f4a2713aSLionel Sambuc   if (Result != MCDisassembler::Fail) {
907f4a2713aSLionel Sambuc     Size = 4;
908f4a2713aSLionel Sambuc     return Result;
909f4a2713aSLionel Sambuc   }
910f4a2713aSLionel Sambuc 
911f4a2713aSLionel Sambuc   return MCDisassembler::Fail;
912f4a2713aSLionel Sambuc }
913f4a2713aSLionel Sambuc 
getInstruction(MCInst & Instr,uint64_t & Size,ArrayRef<uint8_t> Bytes,uint64_t Address,raw_ostream & VStream,raw_ostream & CStream) const914*0a6a1f1dSLionel Sambuc DecodeStatus Mips64Disassembler::getInstruction(MCInst &Instr, uint64_t &Size,
915*0a6a1f1dSLionel Sambuc                                                 ArrayRef<uint8_t> Bytes,
916f4a2713aSLionel Sambuc                                                 uint64_t Address,
917*0a6a1f1dSLionel Sambuc                                                 raw_ostream &VStream,
918*0a6a1f1dSLionel Sambuc                                                 raw_ostream &CStream) const {
919f4a2713aSLionel Sambuc   uint32_t Insn;
920f4a2713aSLionel Sambuc 
921*0a6a1f1dSLionel Sambuc   DecodeStatus Result =
922*0a6a1f1dSLionel Sambuc       readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, false);
923f4a2713aSLionel Sambuc   if (Result == MCDisassembler::Fail)
924f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
925f4a2713aSLionel Sambuc 
926f4a2713aSLionel Sambuc   // Calling the auto-generated decoder function.
927*0a6a1f1dSLionel Sambuc   Result =
928*0a6a1f1dSLionel Sambuc       decodeInstruction(DecoderTableMips6432, Instr, Insn, Address, this, STI);
929f4a2713aSLionel Sambuc   if (Result != MCDisassembler::Fail) {
930f4a2713aSLionel Sambuc     Size = 4;
931f4a2713aSLionel Sambuc     return Result;
932f4a2713aSLionel Sambuc   }
933f4a2713aSLionel Sambuc   // If we fail to decode in Mips64 decoder space we can try in Mips32
934*0a6a1f1dSLionel Sambuc   Result =
935*0a6a1f1dSLionel Sambuc       decodeInstruction(DecoderTableMips32, Instr, Insn, Address, this, STI);
936f4a2713aSLionel Sambuc   if (Result != MCDisassembler::Fail) {
937f4a2713aSLionel Sambuc     Size = 4;
938f4a2713aSLionel Sambuc     return Result;
939f4a2713aSLionel Sambuc   }
940f4a2713aSLionel Sambuc 
941f4a2713aSLionel Sambuc   return MCDisassembler::Fail;
942f4a2713aSLionel Sambuc }
943f4a2713aSLionel Sambuc 
DecodeCPU16RegsRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)944f4a2713aSLionel Sambuc static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst,
945f4a2713aSLionel Sambuc                                                  unsigned RegNo,
946f4a2713aSLionel Sambuc                                                  uint64_t Address,
947f4a2713aSLionel Sambuc                                                  const void *Decoder) {
948f4a2713aSLionel Sambuc 
949f4a2713aSLionel Sambuc   return MCDisassembler::Fail;
950f4a2713aSLionel Sambuc 
951f4a2713aSLionel Sambuc }
952f4a2713aSLionel Sambuc 
DecodeGPR64RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)953f4a2713aSLionel Sambuc static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst,
954f4a2713aSLionel Sambuc                                              unsigned RegNo,
955f4a2713aSLionel Sambuc                                              uint64_t Address,
956f4a2713aSLionel Sambuc                                              const void *Decoder) {
957f4a2713aSLionel Sambuc 
958f4a2713aSLionel Sambuc   if (RegNo > 31)
959f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
960f4a2713aSLionel Sambuc 
961f4a2713aSLionel Sambuc   unsigned Reg = getReg(Decoder, Mips::GPR64RegClassID, RegNo);
962f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateReg(Reg));
963f4a2713aSLionel Sambuc   return MCDisassembler::Success;
964f4a2713aSLionel Sambuc }
965f4a2713aSLionel Sambuc 
DecodeGPRMM16RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)966*0a6a1f1dSLionel Sambuc static DecodeStatus DecodeGPRMM16RegisterClass(MCInst &Inst,
967*0a6a1f1dSLionel Sambuc                                                unsigned RegNo,
968*0a6a1f1dSLionel Sambuc                                                uint64_t Address,
969*0a6a1f1dSLionel Sambuc                                                const void *Decoder) {
970*0a6a1f1dSLionel Sambuc   if (RegNo > 7)
971*0a6a1f1dSLionel Sambuc     return MCDisassembler::Fail;
972*0a6a1f1dSLionel Sambuc   unsigned Reg = getReg(Decoder, Mips::GPRMM16RegClassID, RegNo);
973*0a6a1f1dSLionel Sambuc   Inst.addOperand(MCOperand::CreateReg(Reg));
974*0a6a1f1dSLionel Sambuc   return MCDisassembler::Success;
975*0a6a1f1dSLionel Sambuc }
976*0a6a1f1dSLionel Sambuc 
DecodeGPRMM16ZeroRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)977*0a6a1f1dSLionel Sambuc static DecodeStatus DecodeGPRMM16ZeroRegisterClass(MCInst &Inst,
978*0a6a1f1dSLionel Sambuc                                                    unsigned RegNo,
979*0a6a1f1dSLionel Sambuc                                                    uint64_t Address,
980*0a6a1f1dSLionel Sambuc                                                    const void *Decoder) {
981*0a6a1f1dSLionel Sambuc   if (RegNo > 7)
982*0a6a1f1dSLionel Sambuc     return MCDisassembler::Fail;
983*0a6a1f1dSLionel Sambuc   unsigned Reg = getReg(Decoder, Mips::GPRMM16ZeroRegClassID, RegNo);
984*0a6a1f1dSLionel Sambuc   Inst.addOperand(MCOperand::CreateReg(Reg));
985*0a6a1f1dSLionel Sambuc   return MCDisassembler::Success;
986*0a6a1f1dSLionel Sambuc }
987*0a6a1f1dSLionel Sambuc 
DecodeGPR32RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)988f4a2713aSLionel Sambuc static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst,
989f4a2713aSLionel Sambuc                                              unsigned RegNo,
990f4a2713aSLionel Sambuc                                              uint64_t Address,
991f4a2713aSLionel Sambuc                                              const void *Decoder) {
992f4a2713aSLionel Sambuc   if (RegNo > 31)
993f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
994f4a2713aSLionel Sambuc   unsigned Reg = getReg(Decoder, Mips::GPR32RegClassID, RegNo);
995f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateReg(Reg));
996f4a2713aSLionel Sambuc   return MCDisassembler::Success;
997f4a2713aSLionel Sambuc }
998f4a2713aSLionel Sambuc 
DecodePtrRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)999f4a2713aSLionel Sambuc static DecodeStatus DecodePtrRegisterClass(MCInst &Inst,
1000f4a2713aSLionel Sambuc                                            unsigned RegNo,
1001f4a2713aSLionel Sambuc                                            uint64_t Address,
1002f4a2713aSLionel Sambuc                                            const void *Decoder) {
1003*0a6a1f1dSLionel Sambuc   if (static_cast<const MipsDisassembler *>(Decoder)->isGP64Bit())
1004f4a2713aSLionel Sambuc     return DecodeGPR64RegisterClass(Inst, RegNo, Address, Decoder);
1005f4a2713aSLionel Sambuc 
1006f4a2713aSLionel Sambuc   return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
1007f4a2713aSLionel Sambuc }
1008f4a2713aSLionel Sambuc 
DecodeDSPRRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)1009f4a2713aSLionel Sambuc static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst,
1010f4a2713aSLionel Sambuc                                             unsigned RegNo,
1011f4a2713aSLionel Sambuc                                             uint64_t Address,
1012f4a2713aSLionel Sambuc                                             const void *Decoder) {
1013f4a2713aSLionel Sambuc   return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
1014f4a2713aSLionel Sambuc }
1015f4a2713aSLionel Sambuc 
DecodeFGR64RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)1016f4a2713aSLionel Sambuc static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
1017f4a2713aSLionel Sambuc                                              unsigned RegNo,
1018f4a2713aSLionel Sambuc                                              uint64_t Address,
1019f4a2713aSLionel Sambuc                                              const void *Decoder) {
1020f4a2713aSLionel Sambuc   if (RegNo > 31)
1021f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
1022f4a2713aSLionel Sambuc 
1023f4a2713aSLionel Sambuc   unsigned Reg = getReg(Decoder, Mips::FGR64RegClassID, RegNo);
1024f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateReg(Reg));
1025f4a2713aSLionel Sambuc   return MCDisassembler::Success;
1026f4a2713aSLionel Sambuc }
1027f4a2713aSLionel Sambuc 
DecodeFGR32RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)1028f4a2713aSLionel Sambuc static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
1029f4a2713aSLionel Sambuc                                              unsigned RegNo,
1030f4a2713aSLionel Sambuc                                              uint64_t Address,
1031f4a2713aSLionel Sambuc                                              const void *Decoder) {
1032f4a2713aSLionel Sambuc   if (RegNo > 31)
1033f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
1034f4a2713aSLionel Sambuc 
1035f4a2713aSLionel Sambuc   unsigned Reg = getReg(Decoder, Mips::FGR32RegClassID, RegNo);
1036f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateReg(Reg));
1037f4a2713aSLionel Sambuc   return MCDisassembler::Success;
1038f4a2713aSLionel Sambuc }
1039f4a2713aSLionel Sambuc 
DecodeCCRRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)1040f4a2713aSLionel Sambuc static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
1041f4a2713aSLionel Sambuc                                            unsigned RegNo,
1042f4a2713aSLionel Sambuc                                            uint64_t Address,
1043f4a2713aSLionel Sambuc                                            const void *Decoder) {
1044f4a2713aSLionel Sambuc   if (RegNo > 31)
1045f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
1046f4a2713aSLionel Sambuc   unsigned Reg = getReg(Decoder, Mips::CCRRegClassID, RegNo);
1047f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateReg(Reg));
1048f4a2713aSLionel Sambuc   return MCDisassembler::Success;
1049f4a2713aSLionel Sambuc }
1050f4a2713aSLionel Sambuc 
DecodeFCCRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)1051f4a2713aSLionel Sambuc static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst,
1052f4a2713aSLionel Sambuc                                            unsigned RegNo,
1053f4a2713aSLionel Sambuc                                            uint64_t Address,
1054f4a2713aSLionel Sambuc                                            const void *Decoder) {
1055f4a2713aSLionel Sambuc   if (RegNo > 7)
1056f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
1057f4a2713aSLionel Sambuc   unsigned Reg = getReg(Decoder, Mips::FCCRegClassID, RegNo);
1058f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateReg(Reg));
1059f4a2713aSLionel Sambuc   return MCDisassembler::Success;
1060f4a2713aSLionel Sambuc }
1061f4a2713aSLionel Sambuc 
DecodeFGRCCRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)1062*0a6a1f1dSLionel Sambuc static DecodeStatus DecodeFGRCCRegisterClass(MCInst &Inst, unsigned RegNo,
1063*0a6a1f1dSLionel Sambuc                                              uint64_t Address,
1064*0a6a1f1dSLionel Sambuc                                              const void *Decoder) {
1065*0a6a1f1dSLionel Sambuc   if (RegNo > 31)
1066*0a6a1f1dSLionel Sambuc     return MCDisassembler::Fail;
1067*0a6a1f1dSLionel Sambuc 
1068*0a6a1f1dSLionel Sambuc   unsigned Reg = getReg(Decoder, Mips::FGRCCRegClassID, RegNo);
1069*0a6a1f1dSLionel Sambuc   Inst.addOperand(MCOperand::CreateReg(Reg));
1070*0a6a1f1dSLionel Sambuc   return MCDisassembler::Success;
1071*0a6a1f1dSLionel Sambuc }
1072*0a6a1f1dSLionel Sambuc 
DecodeMem(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)1073f4a2713aSLionel Sambuc static DecodeStatus DecodeMem(MCInst &Inst,
1074f4a2713aSLionel Sambuc                               unsigned Insn,
1075f4a2713aSLionel Sambuc                               uint64_t Address,
1076f4a2713aSLionel Sambuc                               const void *Decoder) {
1077f4a2713aSLionel Sambuc   int Offset = SignExtend32<16>(Insn & 0xffff);
1078f4a2713aSLionel Sambuc   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1079f4a2713aSLionel Sambuc   unsigned Base = fieldFromInstruction(Insn, 21, 5);
1080f4a2713aSLionel Sambuc 
1081f4a2713aSLionel Sambuc   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1082f4a2713aSLionel Sambuc   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1083f4a2713aSLionel Sambuc 
1084*0a6a1f1dSLionel Sambuc   if(Inst.getOpcode() == Mips::SC ||
1085*0a6a1f1dSLionel Sambuc      Inst.getOpcode() == Mips::SCD){
1086f4a2713aSLionel Sambuc     Inst.addOperand(MCOperand::CreateReg(Reg));
1087f4a2713aSLionel Sambuc   }
1088f4a2713aSLionel Sambuc 
1089f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateReg(Reg));
1090f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateReg(Base));
1091f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(Offset));
1092f4a2713aSLionel Sambuc 
1093f4a2713aSLionel Sambuc   return MCDisassembler::Success;
1094f4a2713aSLionel Sambuc }
1095f4a2713aSLionel Sambuc 
DecodeCacheOp(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)1096*0a6a1f1dSLionel Sambuc static DecodeStatus DecodeCacheOp(MCInst &Inst,
1097*0a6a1f1dSLionel Sambuc                               unsigned Insn,
1098*0a6a1f1dSLionel Sambuc                               uint64_t Address,
1099*0a6a1f1dSLionel Sambuc                               const void *Decoder) {
1100*0a6a1f1dSLionel Sambuc   int Offset = SignExtend32<16>(Insn & 0xffff);
1101*0a6a1f1dSLionel Sambuc   unsigned Hint = fieldFromInstruction(Insn, 16, 5);
1102*0a6a1f1dSLionel Sambuc   unsigned Base = fieldFromInstruction(Insn, 21, 5);
1103*0a6a1f1dSLionel Sambuc 
1104*0a6a1f1dSLionel Sambuc   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1105*0a6a1f1dSLionel Sambuc 
1106*0a6a1f1dSLionel Sambuc   Inst.addOperand(MCOperand::CreateReg(Base));
1107*0a6a1f1dSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(Offset));
1108*0a6a1f1dSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(Hint));
1109*0a6a1f1dSLionel Sambuc 
1110*0a6a1f1dSLionel Sambuc   return MCDisassembler::Success;
1111*0a6a1f1dSLionel Sambuc }
1112*0a6a1f1dSLionel Sambuc 
DecodeCacheOpMM(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)1113*0a6a1f1dSLionel Sambuc static DecodeStatus DecodeCacheOpMM(MCInst &Inst,
1114*0a6a1f1dSLionel Sambuc                                     unsigned Insn,
1115*0a6a1f1dSLionel Sambuc                                     uint64_t Address,
1116*0a6a1f1dSLionel Sambuc                                     const void *Decoder) {
1117*0a6a1f1dSLionel Sambuc   int Offset = SignExtend32<12>(Insn & 0xfff);
1118*0a6a1f1dSLionel Sambuc   unsigned Base = fieldFromInstruction(Insn, 16, 5);
1119*0a6a1f1dSLionel Sambuc   unsigned Hint = fieldFromInstruction(Insn, 21, 5);
1120*0a6a1f1dSLionel Sambuc 
1121*0a6a1f1dSLionel Sambuc   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1122*0a6a1f1dSLionel Sambuc 
1123*0a6a1f1dSLionel Sambuc   Inst.addOperand(MCOperand::CreateReg(Base));
1124*0a6a1f1dSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(Offset));
1125*0a6a1f1dSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(Hint));
1126*0a6a1f1dSLionel Sambuc 
1127*0a6a1f1dSLionel Sambuc   return MCDisassembler::Success;
1128*0a6a1f1dSLionel Sambuc }
1129*0a6a1f1dSLionel Sambuc 
DecodeCacheOpR6(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)1130*0a6a1f1dSLionel Sambuc static DecodeStatus DecodeCacheOpR6(MCInst &Inst,
1131*0a6a1f1dSLionel Sambuc                                     unsigned Insn,
1132*0a6a1f1dSLionel Sambuc                                     uint64_t Address,
1133*0a6a1f1dSLionel Sambuc                                     const void *Decoder) {
1134*0a6a1f1dSLionel Sambuc   int Offset = fieldFromInstruction(Insn, 7, 9);
1135*0a6a1f1dSLionel Sambuc   unsigned Hint = fieldFromInstruction(Insn, 16, 5);
1136*0a6a1f1dSLionel Sambuc   unsigned Base = fieldFromInstruction(Insn, 21, 5);
1137*0a6a1f1dSLionel Sambuc 
1138*0a6a1f1dSLionel Sambuc   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1139*0a6a1f1dSLionel Sambuc 
1140*0a6a1f1dSLionel Sambuc   Inst.addOperand(MCOperand::CreateReg(Base));
1141*0a6a1f1dSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(Offset));
1142*0a6a1f1dSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(Hint));
1143*0a6a1f1dSLionel Sambuc 
1144*0a6a1f1dSLionel Sambuc   return MCDisassembler::Success;
1145*0a6a1f1dSLionel Sambuc }
1146*0a6a1f1dSLionel Sambuc 
DecodeSyncI(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)1147*0a6a1f1dSLionel Sambuc static DecodeStatus DecodeSyncI(MCInst &Inst,
1148*0a6a1f1dSLionel Sambuc                               unsigned Insn,
1149*0a6a1f1dSLionel Sambuc                               uint64_t Address,
1150*0a6a1f1dSLionel Sambuc                               const void *Decoder) {
1151*0a6a1f1dSLionel Sambuc   int Offset = SignExtend32<16>(Insn & 0xffff);
1152*0a6a1f1dSLionel Sambuc   unsigned Base = fieldFromInstruction(Insn, 21, 5);
1153*0a6a1f1dSLionel Sambuc 
1154*0a6a1f1dSLionel Sambuc   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1155*0a6a1f1dSLionel Sambuc 
1156*0a6a1f1dSLionel Sambuc   Inst.addOperand(MCOperand::CreateReg(Base));
1157*0a6a1f1dSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(Offset));
1158*0a6a1f1dSLionel Sambuc 
1159*0a6a1f1dSLionel Sambuc   return MCDisassembler::Success;
1160*0a6a1f1dSLionel Sambuc }
1161*0a6a1f1dSLionel Sambuc 
DecodeMSA128Mem(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)1162f4a2713aSLionel Sambuc static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn,
1163f4a2713aSLionel Sambuc                                     uint64_t Address, const void *Decoder) {
1164f4a2713aSLionel Sambuc   int Offset = SignExtend32<10>(fieldFromInstruction(Insn, 16, 10));
1165f4a2713aSLionel Sambuc   unsigned Reg = fieldFromInstruction(Insn, 6, 5);
1166f4a2713aSLionel Sambuc   unsigned Base = fieldFromInstruction(Insn, 11, 5);
1167f4a2713aSLionel Sambuc 
1168f4a2713aSLionel Sambuc   Reg = getReg(Decoder, Mips::MSA128BRegClassID, Reg);
1169f4a2713aSLionel Sambuc   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1170f4a2713aSLionel Sambuc 
1171f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateReg(Reg));
1172f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateReg(Base));
1173*0a6a1f1dSLionel Sambuc 
1174*0a6a1f1dSLionel Sambuc   // The immediate field of an LD/ST instruction is scaled which means it must
1175*0a6a1f1dSLionel Sambuc   // be multiplied (when decoding) by the size (in bytes) of the instructions'
1176*0a6a1f1dSLionel Sambuc   // data format.
1177*0a6a1f1dSLionel Sambuc   // .b - 1 byte
1178*0a6a1f1dSLionel Sambuc   // .h - 2 bytes
1179*0a6a1f1dSLionel Sambuc   // .w - 4 bytes
1180*0a6a1f1dSLionel Sambuc   // .d - 8 bytes
1181*0a6a1f1dSLionel Sambuc   switch(Inst.getOpcode())
1182*0a6a1f1dSLionel Sambuc   {
1183*0a6a1f1dSLionel Sambuc   default:
1184*0a6a1f1dSLionel Sambuc     assert (0 && "Unexpected instruction");
1185*0a6a1f1dSLionel Sambuc     return MCDisassembler::Fail;
1186*0a6a1f1dSLionel Sambuc     break;
1187*0a6a1f1dSLionel Sambuc   case Mips::LD_B:
1188*0a6a1f1dSLionel Sambuc   case Mips::ST_B:
1189f4a2713aSLionel Sambuc     Inst.addOperand(MCOperand::CreateImm(Offset));
1190*0a6a1f1dSLionel Sambuc     break;
1191*0a6a1f1dSLionel Sambuc   case Mips::LD_H:
1192*0a6a1f1dSLionel Sambuc   case Mips::ST_H:
1193*0a6a1f1dSLionel Sambuc     Inst.addOperand(MCOperand::CreateImm(Offset * 2));
1194*0a6a1f1dSLionel Sambuc     break;
1195*0a6a1f1dSLionel Sambuc   case Mips::LD_W:
1196*0a6a1f1dSLionel Sambuc   case Mips::ST_W:
1197*0a6a1f1dSLionel Sambuc     Inst.addOperand(MCOperand::CreateImm(Offset * 4));
1198*0a6a1f1dSLionel Sambuc     break;
1199*0a6a1f1dSLionel Sambuc   case Mips::LD_D:
1200*0a6a1f1dSLionel Sambuc   case Mips::ST_D:
1201*0a6a1f1dSLionel Sambuc     Inst.addOperand(MCOperand::CreateImm(Offset * 8));
1202*0a6a1f1dSLionel Sambuc     break;
1203*0a6a1f1dSLionel Sambuc   }
1204*0a6a1f1dSLionel Sambuc 
1205*0a6a1f1dSLionel Sambuc   return MCDisassembler::Success;
1206*0a6a1f1dSLionel Sambuc }
1207*0a6a1f1dSLionel Sambuc 
DecodeMemMMImm4(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)1208*0a6a1f1dSLionel Sambuc static DecodeStatus DecodeMemMMImm4(MCInst &Inst,
1209*0a6a1f1dSLionel Sambuc                                     unsigned Insn,
1210*0a6a1f1dSLionel Sambuc                                     uint64_t Address,
1211*0a6a1f1dSLionel Sambuc                                     const void *Decoder) {
1212*0a6a1f1dSLionel Sambuc   unsigned Offset = Insn & 0xf;
1213*0a6a1f1dSLionel Sambuc   unsigned Reg = fieldFromInstruction(Insn, 7, 3);
1214*0a6a1f1dSLionel Sambuc   unsigned Base = fieldFromInstruction(Insn, 4, 3);
1215*0a6a1f1dSLionel Sambuc 
1216*0a6a1f1dSLionel Sambuc   switch (Inst.getOpcode()) {
1217*0a6a1f1dSLionel Sambuc     case Mips::LBU16_MM:
1218*0a6a1f1dSLionel Sambuc     case Mips::LHU16_MM:
1219*0a6a1f1dSLionel Sambuc     case Mips::LW16_MM:
1220*0a6a1f1dSLionel Sambuc       if (DecodeGPRMM16RegisterClass(Inst, Reg, Address, Decoder)
1221*0a6a1f1dSLionel Sambuc             == MCDisassembler::Fail)
1222*0a6a1f1dSLionel Sambuc         return MCDisassembler::Fail;
1223*0a6a1f1dSLionel Sambuc       break;
1224*0a6a1f1dSLionel Sambuc     case Mips::SB16_MM:
1225*0a6a1f1dSLionel Sambuc     case Mips::SH16_MM:
1226*0a6a1f1dSLionel Sambuc     case Mips::SW16_MM:
1227*0a6a1f1dSLionel Sambuc       if (DecodeGPRMM16ZeroRegisterClass(Inst, Reg, Address, Decoder)
1228*0a6a1f1dSLionel Sambuc             == MCDisassembler::Fail)
1229*0a6a1f1dSLionel Sambuc         return MCDisassembler::Fail;
1230*0a6a1f1dSLionel Sambuc       break;
1231*0a6a1f1dSLionel Sambuc   }
1232*0a6a1f1dSLionel Sambuc 
1233*0a6a1f1dSLionel Sambuc   if (DecodeGPRMM16RegisterClass(Inst, Base, Address, Decoder)
1234*0a6a1f1dSLionel Sambuc         == MCDisassembler::Fail)
1235*0a6a1f1dSLionel Sambuc     return MCDisassembler::Fail;
1236*0a6a1f1dSLionel Sambuc 
1237*0a6a1f1dSLionel Sambuc   switch (Inst.getOpcode()) {
1238*0a6a1f1dSLionel Sambuc     case Mips::LBU16_MM:
1239*0a6a1f1dSLionel Sambuc       if (Offset == 0xf)
1240*0a6a1f1dSLionel Sambuc         Inst.addOperand(MCOperand::CreateImm(-1));
1241*0a6a1f1dSLionel Sambuc       else
1242*0a6a1f1dSLionel Sambuc         Inst.addOperand(MCOperand::CreateImm(Offset));
1243*0a6a1f1dSLionel Sambuc       break;
1244*0a6a1f1dSLionel Sambuc     case Mips::SB16_MM:
1245*0a6a1f1dSLionel Sambuc       Inst.addOperand(MCOperand::CreateImm(Offset));
1246*0a6a1f1dSLionel Sambuc       break;
1247*0a6a1f1dSLionel Sambuc     case Mips::LHU16_MM:
1248*0a6a1f1dSLionel Sambuc     case Mips::SH16_MM:
1249*0a6a1f1dSLionel Sambuc       Inst.addOperand(MCOperand::CreateImm(Offset << 1));
1250*0a6a1f1dSLionel Sambuc       break;
1251*0a6a1f1dSLionel Sambuc     case Mips::LW16_MM:
1252*0a6a1f1dSLionel Sambuc     case Mips::SW16_MM:
1253*0a6a1f1dSLionel Sambuc       Inst.addOperand(MCOperand::CreateImm(Offset << 2));
1254*0a6a1f1dSLionel Sambuc       break;
1255*0a6a1f1dSLionel Sambuc   }
1256*0a6a1f1dSLionel Sambuc 
1257*0a6a1f1dSLionel Sambuc   return MCDisassembler::Success;
1258*0a6a1f1dSLionel Sambuc }
1259*0a6a1f1dSLionel Sambuc 
DecodeMemMMSPImm5Lsl2(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)1260*0a6a1f1dSLionel Sambuc static DecodeStatus DecodeMemMMSPImm5Lsl2(MCInst &Inst,
1261*0a6a1f1dSLionel Sambuc                                           unsigned Insn,
1262*0a6a1f1dSLionel Sambuc                                           uint64_t Address,
1263*0a6a1f1dSLionel Sambuc                                           const void *Decoder) {
1264*0a6a1f1dSLionel Sambuc   unsigned Offset = Insn & 0x1F;
1265*0a6a1f1dSLionel Sambuc   unsigned Reg = fieldFromInstruction(Insn, 5, 5);
1266*0a6a1f1dSLionel Sambuc 
1267*0a6a1f1dSLionel Sambuc   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1268*0a6a1f1dSLionel Sambuc 
1269*0a6a1f1dSLionel Sambuc   Inst.addOperand(MCOperand::CreateReg(Reg));
1270*0a6a1f1dSLionel Sambuc   Inst.addOperand(MCOperand::CreateReg(Mips::SP));
1271*0a6a1f1dSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(Offset << 2));
1272f4a2713aSLionel Sambuc 
1273f4a2713aSLionel Sambuc   return MCDisassembler::Success;
1274f4a2713aSLionel Sambuc }
1275f4a2713aSLionel Sambuc 
DecodeMemMMImm12(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)1276f4a2713aSLionel Sambuc static DecodeStatus DecodeMemMMImm12(MCInst &Inst,
1277f4a2713aSLionel Sambuc                                      unsigned Insn,
1278f4a2713aSLionel Sambuc                                      uint64_t Address,
1279f4a2713aSLionel Sambuc                                      const void *Decoder) {
1280f4a2713aSLionel Sambuc   int Offset = SignExtend32<12>(Insn & 0x0fff);
1281f4a2713aSLionel Sambuc   unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1282f4a2713aSLionel Sambuc   unsigned Base = fieldFromInstruction(Insn, 16, 5);
1283f4a2713aSLionel Sambuc 
1284f4a2713aSLionel Sambuc   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1285f4a2713aSLionel Sambuc   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1286f4a2713aSLionel Sambuc 
1287*0a6a1f1dSLionel Sambuc   switch (Inst.getOpcode()) {
1288*0a6a1f1dSLionel Sambuc   case Mips::SWM32_MM:
1289*0a6a1f1dSLionel Sambuc   case Mips::LWM32_MM:
1290*0a6a1f1dSLionel Sambuc     if (DecodeRegListOperand(Inst, Insn, Address, Decoder)
1291*0a6a1f1dSLionel Sambuc         == MCDisassembler::Fail)
1292*0a6a1f1dSLionel Sambuc       return MCDisassembler::Fail;
1293f4a2713aSLionel Sambuc     Inst.addOperand(MCOperand::CreateReg(Base));
1294f4a2713aSLionel Sambuc     Inst.addOperand(MCOperand::CreateImm(Offset));
1295*0a6a1f1dSLionel Sambuc     break;
1296*0a6a1f1dSLionel Sambuc   case Mips::SC_MM:
1297*0a6a1f1dSLionel Sambuc     Inst.addOperand(MCOperand::CreateReg(Reg));
1298*0a6a1f1dSLionel Sambuc     // fallthrough
1299*0a6a1f1dSLionel Sambuc   default:
1300*0a6a1f1dSLionel Sambuc     Inst.addOperand(MCOperand::CreateReg(Reg));
1301*0a6a1f1dSLionel Sambuc     if (Inst.getOpcode() == Mips::LWP_MM || Inst.getOpcode() == Mips::SWP_MM)
1302*0a6a1f1dSLionel Sambuc       Inst.addOperand(MCOperand::CreateReg(Reg+1));
1303*0a6a1f1dSLionel Sambuc 
1304*0a6a1f1dSLionel Sambuc     Inst.addOperand(MCOperand::CreateReg(Base));
1305*0a6a1f1dSLionel Sambuc     Inst.addOperand(MCOperand::CreateImm(Offset));
1306*0a6a1f1dSLionel Sambuc   }
1307f4a2713aSLionel Sambuc 
1308f4a2713aSLionel Sambuc   return MCDisassembler::Success;
1309f4a2713aSLionel Sambuc }
1310f4a2713aSLionel Sambuc 
DecodeMemMMImm16(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)1311f4a2713aSLionel Sambuc static DecodeStatus DecodeMemMMImm16(MCInst &Inst,
1312f4a2713aSLionel Sambuc                                      unsigned Insn,
1313f4a2713aSLionel Sambuc                                      uint64_t Address,
1314f4a2713aSLionel Sambuc                                      const void *Decoder) {
1315f4a2713aSLionel Sambuc   int Offset = SignExtend32<16>(Insn & 0xffff);
1316f4a2713aSLionel Sambuc   unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1317f4a2713aSLionel Sambuc   unsigned Base = fieldFromInstruction(Insn, 16, 5);
1318f4a2713aSLionel Sambuc 
1319f4a2713aSLionel Sambuc   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1320f4a2713aSLionel Sambuc   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1321f4a2713aSLionel Sambuc 
1322f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateReg(Reg));
1323f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateReg(Base));
1324f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(Offset));
1325f4a2713aSLionel Sambuc 
1326f4a2713aSLionel Sambuc   return MCDisassembler::Success;
1327f4a2713aSLionel Sambuc }
1328f4a2713aSLionel Sambuc 
DecodeFMem(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)1329f4a2713aSLionel Sambuc static DecodeStatus DecodeFMem(MCInst &Inst,
1330f4a2713aSLionel Sambuc                                unsigned Insn,
1331f4a2713aSLionel Sambuc                                uint64_t Address,
1332f4a2713aSLionel Sambuc                                const void *Decoder) {
1333f4a2713aSLionel Sambuc   int Offset = SignExtend32<16>(Insn & 0xffff);
1334f4a2713aSLionel Sambuc   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1335f4a2713aSLionel Sambuc   unsigned Base = fieldFromInstruction(Insn, 21, 5);
1336f4a2713aSLionel Sambuc 
1337f4a2713aSLionel Sambuc   Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg);
1338f4a2713aSLionel Sambuc   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1339f4a2713aSLionel Sambuc 
1340f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateReg(Reg));
1341f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateReg(Base));
1342f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(Offset));
1343f4a2713aSLionel Sambuc 
1344f4a2713aSLionel Sambuc   return MCDisassembler::Success;
1345f4a2713aSLionel Sambuc }
1346f4a2713aSLionel Sambuc 
DecodeFMem2(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)1347*0a6a1f1dSLionel Sambuc static DecodeStatus DecodeFMem2(MCInst &Inst,
1348*0a6a1f1dSLionel Sambuc                                unsigned Insn,
1349*0a6a1f1dSLionel Sambuc                                uint64_t Address,
1350*0a6a1f1dSLionel Sambuc                                const void *Decoder) {
1351*0a6a1f1dSLionel Sambuc   int Offset = SignExtend32<16>(Insn & 0xffff);
1352*0a6a1f1dSLionel Sambuc   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1353*0a6a1f1dSLionel Sambuc   unsigned Base = fieldFromInstruction(Insn, 21, 5);
1354*0a6a1f1dSLionel Sambuc 
1355*0a6a1f1dSLionel Sambuc   Reg = getReg(Decoder, Mips::COP2RegClassID, Reg);
1356*0a6a1f1dSLionel Sambuc   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1357*0a6a1f1dSLionel Sambuc 
1358*0a6a1f1dSLionel Sambuc   Inst.addOperand(MCOperand::CreateReg(Reg));
1359*0a6a1f1dSLionel Sambuc   Inst.addOperand(MCOperand::CreateReg(Base));
1360*0a6a1f1dSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(Offset));
1361*0a6a1f1dSLionel Sambuc 
1362*0a6a1f1dSLionel Sambuc   return MCDisassembler::Success;
1363*0a6a1f1dSLionel Sambuc }
1364*0a6a1f1dSLionel Sambuc 
DecodeFMem3(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)1365*0a6a1f1dSLionel Sambuc static DecodeStatus DecodeFMem3(MCInst &Inst,
1366*0a6a1f1dSLionel Sambuc                                unsigned Insn,
1367*0a6a1f1dSLionel Sambuc                                uint64_t Address,
1368*0a6a1f1dSLionel Sambuc                                const void *Decoder) {
1369*0a6a1f1dSLionel Sambuc   int Offset = SignExtend32<16>(Insn & 0xffff);
1370*0a6a1f1dSLionel Sambuc   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1371*0a6a1f1dSLionel Sambuc   unsigned Base = fieldFromInstruction(Insn, 21, 5);
1372*0a6a1f1dSLionel Sambuc 
1373*0a6a1f1dSLionel Sambuc   Reg = getReg(Decoder, Mips::COP3RegClassID, Reg);
1374*0a6a1f1dSLionel Sambuc   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1375*0a6a1f1dSLionel Sambuc 
1376*0a6a1f1dSLionel Sambuc   Inst.addOperand(MCOperand::CreateReg(Reg));
1377*0a6a1f1dSLionel Sambuc   Inst.addOperand(MCOperand::CreateReg(Base));
1378*0a6a1f1dSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(Offset));
1379*0a6a1f1dSLionel Sambuc 
1380*0a6a1f1dSLionel Sambuc   return MCDisassembler::Success;
1381*0a6a1f1dSLionel Sambuc }
1382*0a6a1f1dSLionel Sambuc 
DecodeFMemCop2R6(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)1383*0a6a1f1dSLionel Sambuc static DecodeStatus DecodeFMemCop2R6(MCInst &Inst,
1384*0a6a1f1dSLionel Sambuc                                     unsigned Insn,
1385*0a6a1f1dSLionel Sambuc                                     uint64_t Address,
1386*0a6a1f1dSLionel Sambuc                                     const void *Decoder) {
1387*0a6a1f1dSLionel Sambuc   int Offset = SignExtend32<11>(Insn & 0x07ff);
1388*0a6a1f1dSLionel Sambuc   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1389*0a6a1f1dSLionel Sambuc   unsigned Base = fieldFromInstruction(Insn, 11, 5);
1390*0a6a1f1dSLionel Sambuc 
1391*0a6a1f1dSLionel Sambuc   Reg = getReg(Decoder, Mips::COP2RegClassID, Reg);
1392*0a6a1f1dSLionel Sambuc   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1393*0a6a1f1dSLionel Sambuc 
1394*0a6a1f1dSLionel Sambuc   Inst.addOperand(MCOperand::CreateReg(Reg));
1395*0a6a1f1dSLionel Sambuc   Inst.addOperand(MCOperand::CreateReg(Base));
1396*0a6a1f1dSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(Offset));
1397*0a6a1f1dSLionel Sambuc 
1398*0a6a1f1dSLionel Sambuc   return MCDisassembler::Success;
1399*0a6a1f1dSLionel Sambuc }
DecodeSpecial3LlSc(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)1400*0a6a1f1dSLionel Sambuc static DecodeStatus DecodeSpecial3LlSc(MCInst &Inst,
1401*0a6a1f1dSLionel Sambuc                                        unsigned Insn,
1402*0a6a1f1dSLionel Sambuc                                        uint64_t Address,
1403*0a6a1f1dSLionel Sambuc                                        const void *Decoder) {
1404*0a6a1f1dSLionel Sambuc   int64_t Offset = SignExtend64<9>((Insn >> 7) & 0x1ff);
1405*0a6a1f1dSLionel Sambuc   unsigned Rt = fieldFromInstruction(Insn, 16, 5);
1406*0a6a1f1dSLionel Sambuc   unsigned Base = fieldFromInstruction(Insn, 21, 5);
1407*0a6a1f1dSLionel Sambuc 
1408*0a6a1f1dSLionel Sambuc   Rt = getReg(Decoder, Mips::GPR32RegClassID, Rt);
1409*0a6a1f1dSLionel Sambuc   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1410*0a6a1f1dSLionel Sambuc 
1411*0a6a1f1dSLionel Sambuc   if(Inst.getOpcode() == Mips::SC_R6 || Inst.getOpcode() == Mips::SCD_R6){
1412*0a6a1f1dSLionel Sambuc     Inst.addOperand(MCOperand::CreateReg(Rt));
1413*0a6a1f1dSLionel Sambuc   }
1414*0a6a1f1dSLionel Sambuc 
1415*0a6a1f1dSLionel Sambuc   Inst.addOperand(MCOperand::CreateReg(Rt));
1416*0a6a1f1dSLionel Sambuc   Inst.addOperand(MCOperand::CreateReg(Base));
1417*0a6a1f1dSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(Offset));
1418*0a6a1f1dSLionel Sambuc 
1419*0a6a1f1dSLionel Sambuc   return MCDisassembler::Success;
1420*0a6a1f1dSLionel Sambuc }
1421f4a2713aSLionel Sambuc 
DecodeHWRegsRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)1422f4a2713aSLionel Sambuc static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
1423f4a2713aSLionel Sambuc                                               unsigned RegNo,
1424f4a2713aSLionel Sambuc                                               uint64_t Address,
1425f4a2713aSLionel Sambuc                                               const void *Decoder) {
1426f4a2713aSLionel Sambuc   // Currently only hardware register 29 is supported.
1427f4a2713aSLionel Sambuc   if (RegNo != 29)
1428f4a2713aSLionel Sambuc     return  MCDisassembler::Fail;
1429f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateReg(Mips::HWR29));
1430f4a2713aSLionel Sambuc   return MCDisassembler::Success;
1431f4a2713aSLionel Sambuc }
1432f4a2713aSLionel Sambuc 
DecodeAFGR64RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)1433f4a2713aSLionel Sambuc static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
1434f4a2713aSLionel Sambuc                                               unsigned RegNo,
1435f4a2713aSLionel Sambuc                                               uint64_t Address,
1436f4a2713aSLionel Sambuc                                               const void *Decoder) {
1437f4a2713aSLionel Sambuc   if (RegNo > 30 || RegNo %2)
1438f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
1439f4a2713aSLionel Sambuc 
1440f4a2713aSLionel Sambuc   ;
1441f4a2713aSLionel Sambuc   unsigned Reg = getReg(Decoder, Mips::AFGR64RegClassID, RegNo /2);
1442f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateReg(Reg));
1443f4a2713aSLionel Sambuc   return MCDisassembler::Success;
1444f4a2713aSLionel Sambuc }
1445f4a2713aSLionel Sambuc 
DecodeACC64DSPRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)1446f4a2713aSLionel Sambuc static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst,
1447f4a2713aSLionel Sambuc                                                 unsigned RegNo,
1448f4a2713aSLionel Sambuc                                                 uint64_t Address,
1449f4a2713aSLionel Sambuc                                                 const void *Decoder) {
1450f4a2713aSLionel Sambuc   if (RegNo >= 4)
1451f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
1452f4a2713aSLionel Sambuc 
1453f4a2713aSLionel Sambuc   unsigned Reg = getReg(Decoder, Mips::ACC64DSPRegClassID, RegNo);
1454f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateReg(Reg));
1455f4a2713aSLionel Sambuc   return MCDisassembler::Success;
1456f4a2713aSLionel Sambuc }
1457f4a2713aSLionel Sambuc 
DecodeHI32DSPRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)1458f4a2713aSLionel Sambuc static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst,
1459f4a2713aSLionel Sambuc                                                unsigned RegNo,
1460f4a2713aSLionel Sambuc                                                uint64_t Address,
1461f4a2713aSLionel Sambuc                                                const void *Decoder) {
1462f4a2713aSLionel Sambuc   if (RegNo >= 4)
1463f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
1464f4a2713aSLionel Sambuc 
1465f4a2713aSLionel Sambuc   unsigned Reg = getReg(Decoder, Mips::HI32DSPRegClassID, RegNo);
1466f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateReg(Reg));
1467f4a2713aSLionel Sambuc   return MCDisassembler::Success;
1468f4a2713aSLionel Sambuc }
1469f4a2713aSLionel Sambuc 
DecodeLO32DSPRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)1470f4a2713aSLionel Sambuc static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst,
1471f4a2713aSLionel Sambuc                                                unsigned RegNo,
1472f4a2713aSLionel Sambuc                                                uint64_t Address,
1473f4a2713aSLionel Sambuc                                                const void *Decoder) {
1474f4a2713aSLionel Sambuc   if (RegNo >= 4)
1475f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
1476f4a2713aSLionel Sambuc 
1477f4a2713aSLionel Sambuc   unsigned Reg = getReg(Decoder, Mips::LO32DSPRegClassID, RegNo);
1478f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateReg(Reg));
1479f4a2713aSLionel Sambuc   return MCDisassembler::Success;
1480f4a2713aSLionel Sambuc }
1481f4a2713aSLionel Sambuc 
DecodeMSA128BRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)1482f4a2713aSLionel Sambuc static DecodeStatus DecodeMSA128BRegisterClass(MCInst &Inst,
1483f4a2713aSLionel Sambuc                                                unsigned RegNo,
1484f4a2713aSLionel Sambuc                                                uint64_t Address,
1485f4a2713aSLionel Sambuc                                                const void *Decoder) {
1486f4a2713aSLionel Sambuc   if (RegNo > 31)
1487f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
1488f4a2713aSLionel Sambuc 
1489f4a2713aSLionel Sambuc   unsigned Reg = getReg(Decoder, Mips::MSA128BRegClassID, RegNo);
1490f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateReg(Reg));
1491f4a2713aSLionel Sambuc   return MCDisassembler::Success;
1492f4a2713aSLionel Sambuc }
1493f4a2713aSLionel Sambuc 
DecodeMSA128HRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)1494f4a2713aSLionel Sambuc static DecodeStatus DecodeMSA128HRegisterClass(MCInst &Inst,
1495f4a2713aSLionel Sambuc                                                unsigned RegNo,
1496f4a2713aSLionel Sambuc                                                uint64_t Address,
1497f4a2713aSLionel Sambuc                                                const void *Decoder) {
1498f4a2713aSLionel Sambuc   if (RegNo > 31)
1499f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
1500f4a2713aSLionel Sambuc 
1501f4a2713aSLionel Sambuc   unsigned Reg = getReg(Decoder, Mips::MSA128HRegClassID, RegNo);
1502f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateReg(Reg));
1503f4a2713aSLionel Sambuc   return MCDisassembler::Success;
1504f4a2713aSLionel Sambuc }
1505f4a2713aSLionel Sambuc 
DecodeMSA128WRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)1506f4a2713aSLionel Sambuc static DecodeStatus DecodeMSA128WRegisterClass(MCInst &Inst,
1507f4a2713aSLionel Sambuc                                                unsigned RegNo,
1508f4a2713aSLionel Sambuc                                                uint64_t Address,
1509f4a2713aSLionel Sambuc                                                const void *Decoder) {
1510f4a2713aSLionel Sambuc   if (RegNo > 31)
1511f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
1512f4a2713aSLionel Sambuc 
1513f4a2713aSLionel Sambuc   unsigned Reg = getReg(Decoder, Mips::MSA128WRegClassID, RegNo);
1514f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateReg(Reg));
1515f4a2713aSLionel Sambuc   return MCDisassembler::Success;
1516f4a2713aSLionel Sambuc }
1517f4a2713aSLionel Sambuc 
DecodeMSA128DRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)1518f4a2713aSLionel Sambuc static DecodeStatus DecodeMSA128DRegisterClass(MCInst &Inst,
1519f4a2713aSLionel Sambuc                                                unsigned RegNo,
1520f4a2713aSLionel Sambuc                                                uint64_t Address,
1521f4a2713aSLionel Sambuc                                                const void *Decoder) {
1522f4a2713aSLionel Sambuc   if (RegNo > 31)
1523f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
1524f4a2713aSLionel Sambuc 
1525f4a2713aSLionel Sambuc   unsigned Reg = getReg(Decoder, Mips::MSA128DRegClassID, RegNo);
1526f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateReg(Reg));
1527f4a2713aSLionel Sambuc   return MCDisassembler::Success;
1528f4a2713aSLionel Sambuc }
1529f4a2713aSLionel Sambuc 
DecodeMSACtrlRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)1530f4a2713aSLionel Sambuc static DecodeStatus DecodeMSACtrlRegisterClass(MCInst &Inst,
1531f4a2713aSLionel Sambuc                                                unsigned RegNo,
1532f4a2713aSLionel Sambuc                                                uint64_t Address,
1533f4a2713aSLionel Sambuc                                                const void *Decoder) {
1534f4a2713aSLionel Sambuc   if (RegNo > 7)
1535f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
1536f4a2713aSLionel Sambuc 
1537f4a2713aSLionel Sambuc   unsigned Reg = getReg(Decoder, Mips::MSACtrlRegClassID, RegNo);
1538f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateReg(Reg));
1539f4a2713aSLionel Sambuc   return MCDisassembler::Success;
1540f4a2713aSLionel Sambuc }
1541f4a2713aSLionel Sambuc 
DecodeCOP2RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)1542*0a6a1f1dSLionel Sambuc static DecodeStatus DecodeCOP2RegisterClass(MCInst &Inst,
1543*0a6a1f1dSLionel Sambuc                                             unsigned RegNo,
1544*0a6a1f1dSLionel Sambuc                                             uint64_t Address,
1545*0a6a1f1dSLionel Sambuc                                             const void *Decoder) {
1546*0a6a1f1dSLionel Sambuc   if (RegNo > 31)
1547*0a6a1f1dSLionel Sambuc     return MCDisassembler::Fail;
1548*0a6a1f1dSLionel Sambuc 
1549*0a6a1f1dSLionel Sambuc   unsigned Reg = getReg(Decoder, Mips::COP2RegClassID, RegNo);
1550*0a6a1f1dSLionel Sambuc   Inst.addOperand(MCOperand::CreateReg(Reg));
1551*0a6a1f1dSLionel Sambuc   return MCDisassembler::Success;
1552*0a6a1f1dSLionel Sambuc }
1553*0a6a1f1dSLionel Sambuc 
DecodeBranchTarget(MCInst & Inst,unsigned Offset,uint64_t Address,const void * Decoder)1554f4a2713aSLionel Sambuc static DecodeStatus DecodeBranchTarget(MCInst &Inst,
1555f4a2713aSLionel Sambuc                                        unsigned Offset,
1556f4a2713aSLionel Sambuc                                        uint64_t Address,
1557f4a2713aSLionel Sambuc                                        const void *Decoder) {
1558*0a6a1f1dSLionel Sambuc   int32_t BranchOffset = (SignExtend32<16>(Offset) * 4) + 4;
1559f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(BranchOffset));
1560f4a2713aSLionel Sambuc   return MCDisassembler::Success;
1561f4a2713aSLionel Sambuc }
1562f4a2713aSLionel Sambuc 
DecodeJumpTarget(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)1563f4a2713aSLionel Sambuc static DecodeStatus DecodeJumpTarget(MCInst &Inst,
1564f4a2713aSLionel Sambuc                                      unsigned Insn,
1565f4a2713aSLionel Sambuc                                      uint64_t Address,
1566f4a2713aSLionel Sambuc                                      const void *Decoder) {
1567f4a2713aSLionel Sambuc 
1568f4a2713aSLionel Sambuc   unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 2;
1569f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(JumpOffset));
1570f4a2713aSLionel Sambuc   return MCDisassembler::Success;
1571f4a2713aSLionel Sambuc }
1572f4a2713aSLionel Sambuc 
DecodeBranchTarget21(MCInst & Inst,unsigned Offset,uint64_t Address,const void * Decoder)1573*0a6a1f1dSLionel Sambuc static DecodeStatus DecodeBranchTarget21(MCInst &Inst,
1574*0a6a1f1dSLionel Sambuc                                          unsigned Offset,
1575*0a6a1f1dSLionel Sambuc                                          uint64_t Address,
1576*0a6a1f1dSLionel Sambuc                                          const void *Decoder) {
1577*0a6a1f1dSLionel Sambuc   int32_t BranchOffset = SignExtend32<21>(Offset) * 4;
1578*0a6a1f1dSLionel Sambuc 
1579*0a6a1f1dSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(BranchOffset));
1580*0a6a1f1dSLionel Sambuc   return MCDisassembler::Success;
1581*0a6a1f1dSLionel Sambuc }
1582*0a6a1f1dSLionel Sambuc 
DecodeBranchTarget26(MCInst & Inst,unsigned Offset,uint64_t Address,const void * Decoder)1583*0a6a1f1dSLionel Sambuc static DecodeStatus DecodeBranchTarget26(MCInst &Inst,
1584*0a6a1f1dSLionel Sambuc                                          unsigned Offset,
1585*0a6a1f1dSLionel Sambuc                                          uint64_t Address,
1586*0a6a1f1dSLionel Sambuc                                          const void *Decoder) {
1587*0a6a1f1dSLionel Sambuc   int32_t BranchOffset = SignExtend32<26>(Offset) * 4;
1588*0a6a1f1dSLionel Sambuc 
1589*0a6a1f1dSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(BranchOffset));
1590*0a6a1f1dSLionel Sambuc   return MCDisassembler::Success;
1591*0a6a1f1dSLionel Sambuc }
1592*0a6a1f1dSLionel Sambuc 
DecodeBranchTarget7MM(MCInst & Inst,unsigned Offset,uint64_t Address,const void * Decoder)1593*0a6a1f1dSLionel Sambuc static DecodeStatus DecodeBranchTarget7MM(MCInst &Inst,
1594*0a6a1f1dSLionel Sambuc                                           unsigned Offset,
1595*0a6a1f1dSLionel Sambuc                                           uint64_t Address,
1596*0a6a1f1dSLionel Sambuc                                           const void *Decoder) {
1597*0a6a1f1dSLionel Sambuc   int32_t BranchOffset = SignExtend32<7>(Offset) << 1;
1598*0a6a1f1dSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(BranchOffset));
1599*0a6a1f1dSLionel Sambuc   return MCDisassembler::Success;
1600*0a6a1f1dSLionel Sambuc }
1601*0a6a1f1dSLionel Sambuc 
DecodeBranchTargetMM(MCInst & Inst,unsigned Offset,uint64_t Address,const void * Decoder)1602f4a2713aSLionel Sambuc static DecodeStatus DecodeBranchTargetMM(MCInst &Inst,
1603f4a2713aSLionel Sambuc                                          unsigned Offset,
1604f4a2713aSLionel Sambuc                                          uint64_t Address,
1605f4a2713aSLionel Sambuc                                          const void *Decoder) {
1606*0a6a1f1dSLionel Sambuc   int32_t BranchOffset = SignExtend32<16>(Offset) * 2;
1607f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(BranchOffset));
1608f4a2713aSLionel Sambuc   return MCDisassembler::Success;
1609f4a2713aSLionel Sambuc }
1610f4a2713aSLionel Sambuc 
DecodeJumpTargetMM(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)1611f4a2713aSLionel Sambuc static DecodeStatus DecodeJumpTargetMM(MCInst &Inst,
1612f4a2713aSLionel Sambuc                                        unsigned Insn,
1613f4a2713aSLionel Sambuc                                        uint64_t Address,
1614f4a2713aSLionel Sambuc                                        const void *Decoder) {
1615f4a2713aSLionel Sambuc   unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 1;
1616f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(JumpOffset));
1617f4a2713aSLionel Sambuc   return MCDisassembler::Success;
1618f4a2713aSLionel Sambuc }
1619f4a2713aSLionel Sambuc 
DecodeAddiur2Simm7(MCInst & Inst,unsigned Value,uint64_t Address,const void * Decoder)1620*0a6a1f1dSLionel Sambuc static DecodeStatus DecodeAddiur2Simm7(MCInst &Inst,
1621*0a6a1f1dSLionel Sambuc                                        unsigned Value,
1622*0a6a1f1dSLionel Sambuc                                        uint64_t Address,
1623*0a6a1f1dSLionel Sambuc                                        const void *Decoder) {
1624*0a6a1f1dSLionel Sambuc   if (Value == 0)
1625*0a6a1f1dSLionel Sambuc     Inst.addOperand(MCOperand::CreateImm(1));
1626*0a6a1f1dSLionel Sambuc   else if (Value == 0x7)
1627*0a6a1f1dSLionel Sambuc     Inst.addOperand(MCOperand::CreateImm(-1));
1628*0a6a1f1dSLionel Sambuc   else
1629*0a6a1f1dSLionel Sambuc     Inst.addOperand(MCOperand::CreateImm(Value << 2));
1630*0a6a1f1dSLionel Sambuc   return MCDisassembler::Success;
1631*0a6a1f1dSLionel Sambuc }
1632*0a6a1f1dSLionel Sambuc 
DecodeUImm6Lsl2(MCInst & Inst,unsigned Value,uint64_t Address,const void * Decoder)1633*0a6a1f1dSLionel Sambuc static DecodeStatus DecodeUImm6Lsl2(MCInst &Inst,
1634*0a6a1f1dSLionel Sambuc                                     unsigned Value,
1635*0a6a1f1dSLionel Sambuc                                     uint64_t Address,
1636*0a6a1f1dSLionel Sambuc                                     const void *Decoder) {
1637*0a6a1f1dSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(Value << 2));
1638*0a6a1f1dSLionel Sambuc   return MCDisassembler::Success;
1639*0a6a1f1dSLionel Sambuc }
1640*0a6a1f1dSLionel Sambuc 
DecodeLiSimm7(MCInst & Inst,unsigned Value,uint64_t Address,const void * Decoder)1641*0a6a1f1dSLionel Sambuc static DecodeStatus DecodeLiSimm7(MCInst &Inst,
1642*0a6a1f1dSLionel Sambuc                                   unsigned Value,
1643*0a6a1f1dSLionel Sambuc                                   uint64_t Address,
1644*0a6a1f1dSLionel Sambuc                                   const void *Decoder) {
1645*0a6a1f1dSLionel Sambuc   if (Value == 0x7F)
1646*0a6a1f1dSLionel Sambuc     Inst.addOperand(MCOperand::CreateImm(-1));
1647*0a6a1f1dSLionel Sambuc   else
1648*0a6a1f1dSLionel Sambuc     Inst.addOperand(MCOperand::CreateImm(Value));
1649*0a6a1f1dSLionel Sambuc   return MCDisassembler::Success;
1650*0a6a1f1dSLionel Sambuc }
1651*0a6a1f1dSLionel Sambuc 
DecodeSimm4(MCInst & Inst,unsigned Value,uint64_t Address,const void * Decoder)1652*0a6a1f1dSLionel Sambuc static DecodeStatus DecodeSimm4(MCInst &Inst,
1653*0a6a1f1dSLionel Sambuc                                 unsigned Value,
1654*0a6a1f1dSLionel Sambuc                                 uint64_t Address,
1655*0a6a1f1dSLionel Sambuc                                 const void *Decoder) {
1656*0a6a1f1dSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(SignExtend32<4>(Value)));
1657*0a6a1f1dSLionel Sambuc   return MCDisassembler::Success;
1658*0a6a1f1dSLionel Sambuc }
1659*0a6a1f1dSLionel Sambuc 
DecodeSimm16(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)1660f4a2713aSLionel Sambuc static DecodeStatus DecodeSimm16(MCInst &Inst,
1661f4a2713aSLionel Sambuc                                  unsigned Insn,
1662f4a2713aSLionel Sambuc                                  uint64_t Address,
1663f4a2713aSLionel Sambuc                                  const void *Decoder) {
1664f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Insn)));
1665f4a2713aSLionel Sambuc   return MCDisassembler::Success;
1666f4a2713aSLionel Sambuc }
1667f4a2713aSLionel Sambuc 
DecodeLSAImm(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)1668f4a2713aSLionel Sambuc static DecodeStatus DecodeLSAImm(MCInst &Inst,
1669f4a2713aSLionel Sambuc                                  unsigned Insn,
1670f4a2713aSLionel Sambuc                                  uint64_t Address,
1671f4a2713aSLionel Sambuc                                  const void *Decoder) {
1672f4a2713aSLionel Sambuc   // We add one to the immediate field as it was encoded as 'imm - 1'.
1673f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(Insn + 1));
1674f4a2713aSLionel Sambuc   return MCDisassembler::Success;
1675f4a2713aSLionel Sambuc }
1676f4a2713aSLionel Sambuc 
DecodeInsSize(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)1677f4a2713aSLionel Sambuc static DecodeStatus DecodeInsSize(MCInst &Inst,
1678f4a2713aSLionel Sambuc                                   unsigned Insn,
1679f4a2713aSLionel Sambuc                                   uint64_t Address,
1680f4a2713aSLionel Sambuc                                   const void *Decoder) {
1681f4a2713aSLionel Sambuc   // First we need to grab the pos(lsb) from MCInst.
1682f4a2713aSLionel Sambuc   int Pos = Inst.getOperand(2).getImm();
1683f4a2713aSLionel Sambuc   int Size = (int) Insn - Pos + 1;
1684f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size)));
1685f4a2713aSLionel Sambuc   return MCDisassembler::Success;
1686f4a2713aSLionel Sambuc }
1687f4a2713aSLionel Sambuc 
DecodeExtSize(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)1688f4a2713aSLionel Sambuc static DecodeStatus DecodeExtSize(MCInst &Inst,
1689f4a2713aSLionel Sambuc                                   unsigned Insn,
1690f4a2713aSLionel Sambuc                                   uint64_t Address,
1691f4a2713aSLionel Sambuc                                   const void *Decoder) {
1692f4a2713aSLionel Sambuc   int Size = (int) Insn  + 1;
1693f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size)));
1694f4a2713aSLionel Sambuc   return MCDisassembler::Success;
1695f4a2713aSLionel Sambuc }
1696*0a6a1f1dSLionel Sambuc 
DecodeSimm19Lsl2(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)1697*0a6a1f1dSLionel Sambuc static DecodeStatus DecodeSimm19Lsl2(MCInst &Inst, unsigned Insn,
1698*0a6a1f1dSLionel Sambuc                                      uint64_t Address, const void *Decoder) {
1699*0a6a1f1dSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(SignExtend32<19>(Insn) * 4));
1700*0a6a1f1dSLionel Sambuc   return MCDisassembler::Success;
1701*0a6a1f1dSLionel Sambuc }
1702*0a6a1f1dSLionel Sambuc 
DecodeSimm18Lsl3(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)1703*0a6a1f1dSLionel Sambuc static DecodeStatus DecodeSimm18Lsl3(MCInst &Inst, unsigned Insn,
1704*0a6a1f1dSLionel Sambuc                                      uint64_t Address, const void *Decoder) {
1705*0a6a1f1dSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(SignExtend32<18>(Insn) * 8));
1706*0a6a1f1dSLionel Sambuc   return MCDisassembler::Success;
1707*0a6a1f1dSLionel Sambuc }
1708*0a6a1f1dSLionel Sambuc 
DecodeSimm9SP(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)1709*0a6a1f1dSLionel Sambuc static DecodeStatus DecodeSimm9SP(MCInst &Inst, unsigned Insn,
1710*0a6a1f1dSLionel Sambuc                                   uint64_t Address, const void *Decoder) {
1711*0a6a1f1dSLionel Sambuc   int32_t DecodedValue;
1712*0a6a1f1dSLionel Sambuc   switch (Insn) {
1713*0a6a1f1dSLionel Sambuc   case 0: DecodedValue = 256; break;
1714*0a6a1f1dSLionel Sambuc   case 1: DecodedValue = 257; break;
1715*0a6a1f1dSLionel Sambuc   case 510: DecodedValue = -258; break;
1716*0a6a1f1dSLionel Sambuc   case 511: DecodedValue = -257; break;
1717*0a6a1f1dSLionel Sambuc   default: DecodedValue = SignExtend32<9>(Insn); break;
1718*0a6a1f1dSLionel Sambuc   }
1719*0a6a1f1dSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(DecodedValue * 4));
1720*0a6a1f1dSLionel Sambuc   return MCDisassembler::Success;
1721*0a6a1f1dSLionel Sambuc }
1722*0a6a1f1dSLionel Sambuc 
DecodeANDI16Imm(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)1723*0a6a1f1dSLionel Sambuc static DecodeStatus DecodeANDI16Imm(MCInst &Inst, unsigned Insn,
1724*0a6a1f1dSLionel Sambuc                                     uint64_t Address, const void *Decoder) {
1725*0a6a1f1dSLionel Sambuc   // Insn must be >= 0, since it is unsigned that condition is always true.
1726*0a6a1f1dSLionel Sambuc   assert(Insn < 16);
1727*0a6a1f1dSLionel Sambuc   int32_t DecodedValues[] = {128, 1, 2, 3, 4, 7, 8, 15, 16, 31, 32, 63, 64,
1728*0a6a1f1dSLionel Sambuc                              255, 32768, 65535};
1729*0a6a1f1dSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(DecodedValues[Insn]));
1730*0a6a1f1dSLionel Sambuc   return MCDisassembler::Success;
1731*0a6a1f1dSLionel Sambuc }
1732*0a6a1f1dSLionel Sambuc 
DecodeUImm5lsl2(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)1733*0a6a1f1dSLionel Sambuc static DecodeStatus DecodeUImm5lsl2(MCInst &Inst, unsigned Insn,
1734*0a6a1f1dSLionel Sambuc                                     uint64_t Address, const void *Decoder) {
1735*0a6a1f1dSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(Insn << 2));
1736*0a6a1f1dSLionel Sambuc   return MCDisassembler::Success;
1737*0a6a1f1dSLionel Sambuc }
1738*0a6a1f1dSLionel Sambuc 
DecodeRegListOperand(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)1739*0a6a1f1dSLionel Sambuc static DecodeStatus DecodeRegListOperand(MCInst &Inst,
1740*0a6a1f1dSLionel Sambuc                                          unsigned Insn,
1741*0a6a1f1dSLionel Sambuc                                          uint64_t Address,
1742*0a6a1f1dSLionel Sambuc                                          const void *Decoder) {
1743*0a6a1f1dSLionel Sambuc   unsigned Regs[] = {Mips::S0, Mips::S1, Mips::S2, Mips::S3, Mips::S4, Mips::S5,
1744*0a6a1f1dSLionel Sambuc                      Mips::S6, Mips::FP};
1745*0a6a1f1dSLionel Sambuc   unsigned RegNum;
1746*0a6a1f1dSLionel Sambuc 
1747*0a6a1f1dSLionel Sambuc   unsigned RegLst = fieldFromInstruction(Insn, 21, 5);
1748*0a6a1f1dSLionel Sambuc   // Empty register lists are not allowed.
1749*0a6a1f1dSLionel Sambuc   if (RegLst == 0)
1750*0a6a1f1dSLionel Sambuc     return MCDisassembler::Fail;
1751*0a6a1f1dSLionel Sambuc 
1752*0a6a1f1dSLionel Sambuc   RegNum = RegLst & 0xf;
1753*0a6a1f1dSLionel Sambuc   for (unsigned i = 0; i < RegNum; i++)
1754*0a6a1f1dSLionel Sambuc     Inst.addOperand(MCOperand::CreateReg(Regs[i]));
1755*0a6a1f1dSLionel Sambuc 
1756*0a6a1f1dSLionel Sambuc   if (RegLst & 0x10)
1757*0a6a1f1dSLionel Sambuc     Inst.addOperand(MCOperand::CreateReg(Mips::RA));
1758*0a6a1f1dSLionel Sambuc 
1759*0a6a1f1dSLionel Sambuc   return MCDisassembler::Success;
1760*0a6a1f1dSLionel Sambuc }
1761*0a6a1f1dSLionel Sambuc 
DecodeRegListOperand16(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)1762*0a6a1f1dSLionel Sambuc static DecodeStatus DecodeRegListOperand16(MCInst &Inst, unsigned Insn,
1763*0a6a1f1dSLionel Sambuc                                            uint64_t Address,
1764*0a6a1f1dSLionel Sambuc                                            const void *Decoder) {
1765*0a6a1f1dSLionel Sambuc   unsigned Regs[] = {Mips::S0, Mips::S1, Mips::S2, Mips::S3};
1766*0a6a1f1dSLionel Sambuc   unsigned RegNum;
1767*0a6a1f1dSLionel Sambuc 
1768*0a6a1f1dSLionel Sambuc   unsigned RegLst = fieldFromInstruction(Insn, 4, 2);
1769*0a6a1f1dSLionel Sambuc   // Empty register lists are not allowed.
1770*0a6a1f1dSLionel Sambuc   if (RegLst == 0)
1771*0a6a1f1dSLionel Sambuc     return MCDisassembler::Fail;
1772*0a6a1f1dSLionel Sambuc 
1773*0a6a1f1dSLionel Sambuc   RegNum = RegLst & 0x3;
1774*0a6a1f1dSLionel Sambuc   for (unsigned i = 0; i < RegNum - 1; i++)
1775*0a6a1f1dSLionel Sambuc     Inst.addOperand(MCOperand::CreateReg(Regs[i]));
1776*0a6a1f1dSLionel Sambuc 
1777*0a6a1f1dSLionel Sambuc   Inst.addOperand(MCOperand::CreateReg(Mips::RA));
1778*0a6a1f1dSLionel Sambuc 
1779*0a6a1f1dSLionel Sambuc   return MCDisassembler::Success;
1780*0a6a1f1dSLionel Sambuc }
1781