xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp (revision 0b57cec536236d46e3dba9bd041533462f33dbb7)
1*0b57cec5SDimitry Andric //===- MipsDisassembler.cpp - Disassembler for Mips -----------------------===//
2*0b57cec5SDimitry Andric //
3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*0b57cec5SDimitry Andric //
7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
8*0b57cec5SDimitry Andric //
9*0b57cec5SDimitry Andric // This file is part of the Mips Disassembler.
10*0b57cec5SDimitry Andric //
11*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
12*0b57cec5SDimitry Andric 
13*0b57cec5SDimitry Andric #include "MCTargetDesc/MipsMCTargetDesc.h"
14*0b57cec5SDimitry Andric #include "Mips.h"
15*0b57cec5SDimitry Andric #include "TargetInfo/MipsTargetInfo.h"
16*0b57cec5SDimitry Andric #include "llvm/ADT/ArrayRef.h"
17*0b57cec5SDimitry Andric #include "llvm/MC/MCContext.h"
18*0b57cec5SDimitry Andric #include "llvm/MC/MCDisassembler/MCDisassembler.h"
19*0b57cec5SDimitry Andric #include "llvm/MC/MCFixedLenDisassembler.h"
20*0b57cec5SDimitry Andric #include "llvm/MC/MCInst.h"
21*0b57cec5SDimitry Andric #include "llvm/MC/MCRegisterInfo.h"
22*0b57cec5SDimitry Andric #include "llvm/MC/MCSubtargetInfo.h"
23*0b57cec5SDimitry Andric #include "llvm/Support/Compiler.h"
24*0b57cec5SDimitry Andric #include "llvm/Support/Debug.h"
25*0b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
26*0b57cec5SDimitry Andric #include "llvm/Support/MathExtras.h"
27*0b57cec5SDimitry Andric #include "llvm/Support/TargetRegistry.h"
28*0b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
29*0b57cec5SDimitry Andric #include <cassert>
30*0b57cec5SDimitry Andric #include <cstdint>
31*0b57cec5SDimitry Andric 
32*0b57cec5SDimitry Andric using namespace llvm;
33*0b57cec5SDimitry Andric 
34*0b57cec5SDimitry Andric #define DEBUG_TYPE "mips-disassembler"
35*0b57cec5SDimitry Andric 
36*0b57cec5SDimitry Andric using DecodeStatus = MCDisassembler::DecodeStatus;
37*0b57cec5SDimitry Andric 
38*0b57cec5SDimitry Andric namespace {
39*0b57cec5SDimitry Andric 
40*0b57cec5SDimitry Andric class MipsDisassembler : public MCDisassembler {
41*0b57cec5SDimitry Andric   bool IsMicroMips;
42*0b57cec5SDimitry Andric   bool IsBigEndian;
43*0b57cec5SDimitry Andric 
44*0b57cec5SDimitry Andric public:
45*0b57cec5SDimitry Andric   MipsDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx, bool IsBigEndian)
46*0b57cec5SDimitry Andric       : MCDisassembler(STI, Ctx),
47*0b57cec5SDimitry Andric         IsMicroMips(STI.getFeatureBits()[Mips::FeatureMicroMips]),
48*0b57cec5SDimitry Andric         IsBigEndian(IsBigEndian) {}
49*0b57cec5SDimitry Andric 
50*0b57cec5SDimitry Andric   bool hasMips2() const { return STI.getFeatureBits()[Mips::FeatureMips2]; }
51*0b57cec5SDimitry Andric   bool hasMips3() const { return STI.getFeatureBits()[Mips::FeatureMips3]; }
52*0b57cec5SDimitry Andric   bool hasMips32() const { return STI.getFeatureBits()[Mips::FeatureMips32]; }
53*0b57cec5SDimitry Andric 
54*0b57cec5SDimitry Andric   bool hasMips32r6() const {
55*0b57cec5SDimitry Andric     return STI.getFeatureBits()[Mips::FeatureMips32r6];
56*0b57cec5SDimitry Andric   }
57*0b57cec5SDimitry Andric 
58*0b57cec5SDimitry Andric   bool isFP64() const { return STI.getFeatureBits()[Mips::FeatureFP64Bit]; }
59*0b57cec5SDimitry Andric 
60*0b57cec5SDimitry Andric   bool isGP64() const { return STI.getFeatureBits()[Mips::FeatureGP64Bit]; }
61*0b57cec5SDimitry Andric 
62*0b57cec5SDimitry Andric   bool isPTR64() const { return STI.getFeatureBits()[Mips::FeaturePTR64Bit]; }
63*0b57cec5SDimitry Andric 
64*0b57cec5SDimitry Andric   bool hasCnMips() const { return STI.getFeatureBits()[Mips::FeatureCnMips]; }
65*0b57cec5SDimitry Andric 
66*0b57cec5SDimitry Andric   bool hasCnMipsP() const { return STI.getFeatureBits()[Mips::FeatureCnMipsP]; }
67*0b57cec5SDimitry Andric 
68*0b57cec5SDimitry Andric   bool hasCOP3() const {
69*0b57cec5SDimitry Andric     // Only present in MIPS-I and MIPS-II
70*0b57cec5SDimitry Andric     return !hasMips32() && !hasMips3();
71*0b57cec5SDimitry Andric   }
72*0b57cec5SDimitry Andric 
73*0b57cec5SDimitry Andric   DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
74*0b57cec5SDimitry Andric                               ArrayRef<uint8_t> Bytes, uint64_t Address,
75*0b57cec5SDimitry Andric                               raw_ostream &VStream,
76*0b57cec5SDimitry Andric                               raw_ostream &CStream) const override;
77*0b57cec5SDimitry Andric };
78*0b57cec5SDimitry Andric 
79*0b57cec5SDimitry Andric } // end anonymous namespace
80*0b57cec5SDimitry Andric 
81*0b57cec5SDimitry Andric // Forward declare these because the autogenerated code will reference them.
82*0b57cec5SDimitry Andric // Definitions are further down.
83*0b57cec5SDimitry Andric static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst,
84*0b57cec5SDimitry Andric                                              unsigned RegNo,
85*0b57cec5SDimitry Andric                                              uint64_t Address,
86*0b57cec5SDimitry Andric                                              const void *Decoder);
87*0b57cec5SDimitry Andric 
88*0b57cec5SDimitry Andric static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst,
89*0b57cec5SDimitry Andric                                                  unsigned RegNo,
90*0b57cec5SDimitry Andric                                                  uint64_t Address,
91*0b57cec5SDimitry Andric                                                  const void *Decoder);
92*0b57cec5SDimitry Andric 
93*0b57cec5SDimitry Andric static DecodeStatus DecodeGPRMM16RegisterClass(MCInst &Inst,
94*0b57cec5SDimitry Andric                                                unsigned RegNo,
95*0b57cec5SDimitry Andric                                                uint64_t Address,
96*0b57cec5SDimitry Andric                                                const void *Decoder);
97*0b57cec5SDimitry Andric 
98*0b57cec5SDimitry Andric static DecodeStatus DecodeGPRMM16ZeroRegisterClass(MCInst &Inst,
99*0b57cec5SDimitry Andric                                                    unsigned RegNo,
100*0b57cec5SDimitry Andric                                                    uint64_t Address,
101*0b57cec5SDimitry Andric                                                    const void *Decoder);
102*0b57cec5SDimitry Andric 
103*0b57cec5SDimitry Andric static DecodeStatus DecodeGPRMM16MovePRegisterClass(MCInst &Inst,
104*0b57cec5SDimitry Andric                                                     unsigned RegNo,
105*0b57cec5SDimitry Andric                                                     uint64_t Address,
106*0b57cec5SDimitry Andric                                                     const void *Decoder);
107*0b57cec5SDimitry Andric 
108*0b57cec5SDimitry Andric static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst,
109*0b57cec5SDimitry Andric                                              unsigned RegNo,
110*0b57cec5SDimitry Andric                                              uint64_t Address,
111*0b57cec5SDimitry Andric                                              const void *Decoder);
112*0b57cec5SDimitry Andric 
113*0b57cec5SDimitry Andric static DecodeStatus DecodePtrRegisterClass(MCInst &Inst,
114*0b57cec5SDimitry Andric                                            unsigned Insn,
115*0b57cec5SDimitry Andric                                            uint64_t Address,
116*0b57cec5SDimitry Andric                                            const void *Decoder);
117*0b57cec5SDimitry Andric 
118*0b57cec5SDimitry Andric static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst,
119*0b57cec5SDimitry Andric                                             unsigned RegNo,
120*0b57cec5SDimitry Andric                                             uint64_t Address,
121*0b57cec5SDimitry Andric                                             const void *Decoder);
122*0b57cec5SDimitry Andric 
123*0b57cec5SDimitry Andric static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
124*0b57cec5SDimitry Andric                                              unsigned RegNo,
125*0b57cec5SDimitry Andric                                              uint64_t Address,
126*0b57cec5SDimitry Andric                                              const void *Decoder);
127*0b57cec5SDimitry Andric 
128*0b57cec5SDimitry Andric static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
129*0b57cec5SDimitry Andric                                              unsigned RegNo,
130*0b57cec5SDimitry Andric                                              uint64_t Address,
131*0b57cec5SDimitry Andric                                              const void *Decoder);
132*0b57cec5SDimitry Andric 
133*0b57cec5SDimitry Andric static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
134*0b57cec5SDimitry Andric                                            unsigned RegNo,
135*0b57cec5SDimitry Andric                                            uint64_t Address,
136*0b57cec5SDimitry Andric                                            const void *Decoder);
137*0b57cec5SDimitry Andric 
138*0b57cec5SDimitry Andric static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst,
139*0b57cec5SDimitry Andric                                            unsigned RegNo,
140*0b57cec5SDimitry Andric                                            uint64_t Address,
141*0b57cec5SDimitry Andric                                            const void *Decoder);
142*0b57cec5SDimitry Andric 
143*0b57cec5SDimitry Andric static DecodeStatus DecodeFGRCCRegisterClass(MCInst &Inst, unsigned RegNo,
144*0b57cec5SDimitry Andric                                              uint64_t Address,
145*0b57cec5SDimitry Andric                                              const void *Decoder);
146*0b57cec5SDimitry Andric 
147*0b57cec5SDimitry Andric static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
148*0b57cec5SDimitry Andric                                               unsigned Insn,
149*0b57cec5SDimitry Andric                                               uint64_t Address,
150*0b57cec5SDimitry Andric                                               const void *Decoder);
151*0b57cec5SDimitry Andric 
152*0b57cec5SDimitry Andric static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
153*0b57cec5SDimitry Andric                                               unsigned RegNo,
154*0b57cec5SDimitry Andric                                               uint64_t Address,
155*0b57cec5SDimitry Andric                                               const void *Decoder);
156*0b57cec5SDimitry Andric 
157*0b57cec5SDimitry Andric static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst,
158*0b57cec5SDimitry Andric                                                 unsigned RegNo,
159*0b57cec5SDimitry Andric                                                 uint64_t Address,
160*0b57cec5SDimitry Andric                                                 const void *Decoder);
161*0b57cec5SDimitry Andric 
162*0b57cec5SDimitry Andric static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst,
163*0b57cec5SDimitry Andric                                                unsigned RegNo,
164*0b57cec5SDimitry Andric                                                uint64_t Address,
165*0b57cec5SDimitry Andric                                                const void *Decoder);
166*0b57cec5SDimitry Andric 
167*0b57cec5SDimitry Andric static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst,
168*0b57cec5SDimitry Andric                                                unsigned RegNo,
169*0b57cec5SDimitry Andric                                                uint64_t Address,
170*0b57cec5SDimitry Andric                                                const void *Decoder);
171*0b57cec5SDimitry Andric 
172*0b57cec5SDimitry Andric static DecodeStatus DecodeMSA128BRegisterClass(MCInst &Inst,
173*0b57cec5SDimitry Andric                                                unsigned RegNo,
174*0b57cec5SDimitry Andric                                                uint64_t Address,
175*0b57cec5SDimitry Andric                                                const void *Decoder);
176*0b57cec5SDimitry Andric 
177*0b57cec5SDimitry Andric static DecodeStatus DecodeMSA128HRegisterClass(MCInst &Inst,
178*0b57cec5SDimitry Andric                                                unsigned RegNo,
179*0b57cec5SDimitry Andric                                                uint64_t Address,
180*0b57cec5SDimitry Andric                                                const void *Decoder);
181*0b57cec5SDimitry Andric 
182*0b57cec5SDimitry Andric static DecodeStatus DecodeMSA128WRegisterClass(MCInst &Inst,
183*0b57cec5SDimitry Andric                                                unsigned RegNo,
184*0b57cec5SDimitry Andric                                                uint64_t Address,
185*0b57cec5SDimitry Andric                                                const void *Decoder);
186*0b57cec5SDimitry Andric 
187*0b57cec5SDimitry Andric static DecodeStatus DecodeMSA128DRegisterClass(MCInst &Inst,
188*0b57cec5SDimitry Andric                                                unsigned RegNo,
189*0b57cec5SDimitry Andric                                                uint64_t Address,
190*0b57cec5SDimitry Andric                                                const void *Decoder);
191*0b57cec5SDimitry Andric 
192*0b57cec5SDimitry Andric static DecodeStatus DecodeMSACtrlRegisterClass(MCInst &Inst,
193*0b57cec5SDimitry Andric                                                unsigned RegNo,
194*0b57cec5SDimitry Andric                                                uint64_t Address,
195*0b57cec5SDimitry Andric                                                const void *Decoder);
196*0b57cec5SDimitry Andric 
197*0b57cec5SDimitry Andric static DecodeStatus DecodeCOP0RegisterClass(MCInst &Inst,
198*0b57cec5SDimitry Andric                                             unsigned RegNo,
199*0b57cec5SDimitry Andric                                             uint64_t Address,
200*0b57cec5SDimitry Andric                                             const void *Decoder);
201*0b57cec5SDimitry Andric 
202*0b57cec5SDimitry Andric static DecodeStatus DecodeCOP2RegisterClass(MCInst &Inst,
203*0b57cec5SDimitry Andric                                             unsigned RegNo,
204*0b57cec5SDimitry Andric                                             uint64_t Address,
205*0b57cec5SDimitry Andric                                             const void *Decoder);
206*0b57cec5SDimitry Andric 
207*0b57cec5SDimitry Andric static DecodeStatus DecodeBranchTarget(MCInst &Inst,
208*0b57cec5SDimitry Andric                                        unsigned Offset,
209*0b57cec5SDimitry Andric                                        uint64_t Address,
210*0b57cec5SDimitry Andric                                        const void *Decoder);
211*0b57cec5SDimitry Andric 
212*0b57cec5SDimitry Andric static DecodeStatus DecodeBranchTarget1SImm16(MCInst &Inst,
213*0b57cec5SDimitry Andric                                               unsigned Offset,
214*0b57cec5SDimitry Andric                                               uint64_t Address,
215*0b57cec5SDimitry Andric                                               const void *Decoder);
216*0b57cec5SDimitry Andric 
217*0b57cec5SDimitry Andric static DecodeStatus DecodeJumpTarget(MCInst &Inst,
218*0b57cec5SDimitry Andric                                      unsigned Insn,
219*0b57cec5SDimitry Andric                                      uint64_t Address,
220*0b57cec5SDimitry Andric                                      const void *Decoder);
221*0b57cec5SDimitry Andric 
222*0b57cec5SDimitry Andric static DecodeStatus DecodeBranchTarget21(MCInst &Inst,
223*0b57cec5SDimitry Andric                                          unsigned Offset,
224*0b57cec5SDimitry Andric                                          uint64_t Address,
225*0b57cec5SDimitry Andric                                          const void *Decoder);
226*0b57cec5SDimitry Andric 
227*0b57cec5SDimitry Andric static DecodeStatus DecodeBranchTarget21MM(MCInst &Inst,
228*0b57cec5SDimitry Andric                                            unsigned Offset,
229*0b57cec5SDimitry Andric                                            uint64_t Address,
230*0b57cec5SDimitry Andric                                            const void *Decoder);
231*0b57cec5SDimitry Andric 
232*0b57cec5SDimitry Andric static DecodeStatus DecodeBranchTarget26(MCInst &Inst,
233*0b57cec5SDimitry Andric                                          unsigned Offset,
234*0b57cec5SDimitry Andric                                          uint64_t Address,
235*0b57cec5SDimitry Andric                                          const void *Decoder);
236*0b57cec5SDimitry Andric 
237*0b57cec5SDimitry Andric // DecodeBranchTarget7MM - Decode microMIPS branch offset, which is
238*0b57cec5SDimitry Andric // shifted left by 1 bit.
239*0b57cec5SDimitry Andric static DecodeStatus DecodeBranchTarget7MM(MCInst &Inst,
240*0b57cec5SDimitry Andric                                           unsigned Offset,
241*0b57cec5SDimitry Andric                                           uint64_t Address,
242*0b57cec5SDimitry Andric                                           const void *Decoder);
243*0b57cec5SDimitry Andric 
244*0b57cec5SDimitry Andric // DecodeBranchTarget10MM - Decode microMIPS branch offset, which is
245*0b57cec5SDimitry Andric // shifted left by 1 bit.
246*0b57cec5SDimitry Andric static DecodeStatus DecodeBranchTarget10MM(MCInst &Inst,
247*0b57cec5SDimitry Andric                                            unsigned Offset,
248*0b57cec5SDimitry Andric                                            uint64_t Address,
249*0b57cec5SDimitry Andric                                            const void *Decoder);
250*0b57cec5SDimitry Andric 
251*0b57cec5SDimitry Andric // DecodeBranchTargetMM - Decode microMIPS branch offset, which is
252*0b57cec5SDimitry Andric // shifted left by 1 bit.
253*0b57cec5SDimitry Andric static DecodeStatus DecodeBranchTargetMM(MCInst &Inst,
254*0b57cec5SDimitry Andric                                          unsigned Offset,
255*0b57cec5SDimitry Andric                                          uint64_t Address,
256*0b57cec5SDimitry Andric                                          const void *Decoder);
257*0b57cec5SDimitry Andric 
258*0b57cec5SDimitry Andric // DecodeBranchTarget26MM - Decode microMIPS branch offset, which is
259*0b57cec5SDimitry Andric // shifted left by 1 bit.
260*0b57cec5SDimitry Andric static DecodeStatus DecodeBranchTarget26MM(MCInst &Inst,
261*0b57cec5SDimitry Andric                                            unsigned Offset,
262*0b57cec5SDimitry Andric                                            uint64_t Address,
263*0b57cec5SDimitry Andric                                            const void *Decoder);
264*0b57cec5SDimitry Andric 
265*0b57cec5SDimitry Andric // DecodeJumpTargetMM - Decode microMIPS jump target, which is
266*0b57cec5SDimitry Andric // shifted left by 1 bit.
267*0b57cec5SDimitry Andric static DecodeStatus DecodeJumpTargetMM(MCInst &Inst,
268*0b57cec5SDimitry Andric                                        unsigned Insn,
269*0b57cec5SDimitry Andric                                        uint64_t Address,
270*0b57cec5SDimitry Andric                                        const void *Decoder);
271*0b57cec5SDimitry Andric 
272*0b57cec5SDimitry Andric static DecodeStatus DecodeMem(MCInst &Inst,
273*0b57cec5SDimitry Andric                               unsigned Insn,
274*0b57cec5SDimitry Andric                               uint64_t Address,
275*0b57cec5SDimitry Andric                               const void *Decoder);
276*0b57cec5SDimitry Andric 
277*0b57cec5SDimitry Andric static DecodeStatus DecodeMemEVA(MCInst &Inst,
278*0b57cec5SDimitry Andric                                  unsigned Insn,
279*0b57cec5SDimitry Andric                                  uint64_t Address,
280*0b57cec5SDimitry Andric                                  const void *Decoder);
281*0b57cec5SDimitry Andric 
282*0b57cec5SDimitry Andric static DecodeStatus DecodeLoadByte15(MCInst &Inst,
283*0b57cec5SDimitry Andric                                      unsigned Insn,
284*0b57cec5SDimitry Andric                                      uint64_t Address,
285*0b57cec5SDimitry Andric                                      const void *Decoder);
286*0b57cec5SDimitry Andric 
287*0b57cec5SDimitry Andric static DecodeStatus DecodeCacheOp(MCInst &Inst, unsigned Insn, uint64_t Address,
288*0b57cec5SDimitry Andric                                   const void *Decoder);
289*0b57cec5SDimitry Andric 
290*0b57cec5SDimitry Andric static DecodeStatus DecodeCacheeOp_CacheOpR6(MCInst &Inst,
291*0b57cec5SDimitry Andric                                              unsigned Insn,
292*0b57cec5SDimitry Andric                                              uint64_t Address,
293*0b57cec5SDimitry Andric                                              const void *Decoder);
294*0b57cec5SDimitry Andric 
295*0b57cec5SDimitry Andric static DecodeStatus DecodeCacheOpMM(MCInst &Inst,
296*0b57cec5SDimitry Andric                                     unsigned Insn,
297*0b57cec5SDimitry Andric                                     uint64_t Address,
298*0b57cec5SDimitry Andric                                     const void *Decoder);
299*0b57cec5SDimitry Andric 
300*0b57cec5SDimitry Andric static DecodeStatus DecodePrefeOpMM(MCInst &Inst,
301*0b57cec5SDimitry Andric                                     unsigned Insn,
302*0b57cec5SDimitry Andric                                     uint64_t Address,
303*0b57cec5SDimitry Andric                                     const void *Decoder);
304*0b57cec5SDimitry Andric 
305*0b57cec5SDimitry Andric static DecodeStatus DecodeSyncI(MCInst &Inst,
306*0b57cec5SDimitry Andric                                 unsigned Insn,
307*0b57cec5SDimitry Andric                                 uint64_t Address,
308*0b57cec5SDimitry Andric                                 const void *Decoder);
309*0b57cec5SDimitry Andric 
310*0b57cec5SDimitry Andric static DecodeStatus DecodeSyncI_MM(MCInst &Inst,
311*0b57cec5SDimitry Andric                                    unsigned Insn,
312*0b57cec5SDimitry Andric                                    uint64_t Address,
313*0b57cec5SDimitry Andric                                    const void *Decoder);
314*0b57cec5SDimitry Andric 
315*0b57cec5SDimitry Andric static DecodeStatus DecodeSynciR6(MCInst &Inst,
316*0b57cec5SDimitry Andric                                   unsigned Insn,
317*0b57cec5SDimitry Andric                                   uint64_t Address,
318*0b57cec5SDimitry Andric                                   const void *Decoder);
319*0b57cec5SDimitry Andric 
320*0b57cec5SDimitry Andric static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn,
321*0b57cec5SDimitry Andric                                     uint64_t Address, const void *Decoder);
322*0b57cec5SDimitry Andric 
323*0b57cec5SDimitry Andric static DecodeStatus DecodeMemMMImm4(MCInst &Inst,
324*0b57cec5SDimitry Andric                                     unsigned Insn,
325*0b57cec5SDimitry Andric                                     uint64_t Address,
326*0b57cec5SDimitry Andric                                     const void *Decoder);
327*0b57cec5SDimitry Andric 
328*0b57cec5SDimitry Andric static DecodeStatus DecodeMemMMSPImm5Lsl2(MCInst &Inst,
329*0b57cec5SDimitry Andric                                           unsigned Insn,
330*0b57cec5SDimitry Andric                                           uint64_t Address,
331*0b57cec5SDimitry Andric                                           const void *Decoder);
332*0b57cec5SDimitry Andric 
333*0b57cec5SDimitry Andric static DecodeStatus DecodeMemMMGPImm7Lsl2(MCInst &Inst,
334*0b57cec5SDimitry Andric                                           unsigned Insn,
335*0b57cec5SDimitry Andric                                           uint64_t Address,
336*0b57cec5SDimitry Andric                                           const void *Decoder);
337*0b57cec5SDimitry Andric 
338*0b57cec5SDimitry Andric static DecodeStatus DecodeMemMMReglistImm4Lsl2(MCInst &Inst,
339*0b57cec5SDimitry Andric                                                unsigned Insn,
340*0b57cec5SDimitry Andric                                                uint64_t Address,
341*0b57cec5SDimitry Andric                                                const void *Decoder);
342*0b57cec5SDimitry Andric 
343*0b57cec5SDimitry Andric static DecodeStatus DecodeMemMMImm9(MCInst &Inst,
344*0b57cec5SDimitry Andric                                     unsigned Insn,
345*0b57cec5SDimitry Andric                                     uint64_t Address,
346*0b57cec5SDimitry Andric                                     const void *Decoder);
347*0b57cec5SDimitry Andric 
348*0b57cec5SDimitry Andric static DecodeStatus DecodeMemMMImm12(MCInst &Inst,
349*0b57cec5SDimitry Andric                                      unsigned Insn,
350*0b57cec5SDimitry Andric                                      uint64_t Address,
351*0b57cec5SDimitry Andric                                      const void *Decoder);
352*0b57cec5SDimitry Andric 
353*0b57cec5SDimitry Andric static DecodeStatus DecodeMemMMImm16(MCInst &Inst,
354*0b57cec5SDimitry Andric                                      unsigned Insn,
355*0b57cec5SDimitry Andric                                      uint64_t Address,
356*0b57cec5SDimitry Andric                                      const void *Decoder);
357*0b57cec5SDimitry Andric 
358*0b57cec5SDimitry Andric static DecodeStatus DecodeFMem(MCInst &Inst, unsigned Insn,
359*0b57cec5SDimitry Andric                                uint64_t Address,
360*0b57cec5SDimitry Andric                                const void *Decoder);
361*0b57cec5SDimitry Andric 
362*0b57cec5SDimitry Andric static DecodeStatus DecodeFMemMMR2(MCInst &Inst, unsigned Insn,
363*0b57cec5SDimitry Andric                                    uint64_t Address,
364*0b57cec5SDimitry Andric                                    const void *Decoder);
365*0b57cec5SDimitry Andric 
366*0b57cec5SDimitry Andric static DecodeStatus DecodeFMem2(MCInst &Inst, unsigned Insn, uint64_t Address,
367*0b57cec5SDimitry Andric                                 const void *Decoder);
368*0b57cec5SDimitry Andric 
369*0b57cec5SDimitry Andric static DecodeStatus DecodeFMem3(MCInst &Inst, unsigned Insn, uint64_t Address,
370*0b57cec5SDimitry Andric                                 const void *Decoder);
371*0b57cec5SDimitry Andric 
372*0b57cec5SDimitry Andric static DecodeStatus DecodeFMemCop2R6(MCInst &Inst, unsigned Insn,
373*0b57cec5SDimitry Andric                                      uint64_t Address, const void *Decoder);
374*0b57cec5SDimitry Andric 
375*0b57cec5SDimitry Andric static DecodeStatus DecodeFMemCop2MMR6(MCInst &Inst, unsigned Insn,
376*0b57cec5SDimitry Andric                                        uint64_t Address,
377*0b57cec5SDimitry Andric                                        const void *Decoder);
378*0b57cec5SDimitry Andric 
379*0b57cec5SDimitry Andric static DecodeStatus DecodeSpecial3LlSc(MCInst &Inst,
380*0b57cec5SDimitry Andric                                        unsigned Insn,
381*0b57cec5SDimitry Andric                                        uint64_t Address,
382*0b57cec5SDimitry Andric                                        const void *Decoder);
383*0b57cec5SDimitry Andric 
384*0b57cec5SDimitry Andric static DecodeStatus DecodeAddiur2Simm7(MCInst &Inst,
385*0b57cec5SDimitry Andric                                        unsigned Value,
386*0b57cec5SDimitry Andric                                        uint64_t Address,
387*0b57cec5SDimitry Andric                                        const void *Decoder);
388*0b57cec5SDimitry Andric 
389*0b57cec5SDimitry Andric static DecodeStatus DecodeLi16Imm(MCInst &Inst,
390*0b57cec5SDimitry Andric                                   unsigned Value,
391*0b57cec5SDimitry Andric                                   uint64_t Address,
392*0b57cec5SDimitry Andric                                   const void *Decoder);
393*0b57cec5SDimitry Andric 
394*0b57cec5SDimitry Andric static DecodeStatus DecodePOOL16BEncodedField(MCInst &Inst,
395*0b57cec5SDimitry Andric                                               unsigned Value,
396*0b57cec5SDimitry Andric                                               uint64_t Address,
397*0b57cec5SDimitry Andric                                               const void *Decoder);
398*0b57cec5SDimitry Andric 
399*0b57cec5SDimitry Andric template <unsigned Bits, int Offset, int Scale>
400*0b57cec5SDimitry Andric static DecodeStatus DecodeUImmWithOffsetAndScale(MCInst &Inst, unsigned Value,
401*0b57cec5SDimitry Andric                                                  uint64_t Address,
402*0b57cec5SDimitry Andric                                                  const void *Decoder);
403*0b57cec5SDimitry Andric 
404*0b57cec5SDimitry Andric template <unsigned Bits, int Offset>
405*0b57cec5SDimitry Andric static DecodeStatus DecodeUImmWithOffset(MCInst &Inst, unsigned Value,
406*0b57cec5SDimitry Andric                                          uint64_t Address,
407*0b57cec5SDimitry Andric                                          const void *Decoder) {
408*0b57cec5SDimitry Andric   return DecodeUImmWithOffsetAndScale<Bits, Offset, 1>(Inst, Value, Address,
409*0b57cec5SDimitry Andric                                                        Decoder);
410*0b57cec5SDimitry Andric }
411*0b57cec5SDimitry Andric 
412*0b57cec5SDimitry Andric template <unsigned Bits, int Offset = 0, int ScaleBy = 1>
413*0b57cec5SDimitry Andric static DecodeStatus DecodeSImmWithOffsetAndScale(MCInst &Inst, unsigned Value,
414*0b57cec5SDimitry Andric                                                  uint64_t Address,
415*0b57cec5SDimitry Andric                                                  const void *Decoder);
416*0b57cec5SDimitry Andric 
417*0b57cec5SDimitry Andric static DecodeStatus DecodeInsSize(MCInst &Inst,
418*0b57cec5SDimitry Andric                                   unsigned Insn,
419*0b57cec5SDimitry Andric                                   uint64_t Address,
420*0b57cec5SDimitry Andric                                   const void *Decoder);
421*0b57cec5SDimitry Andric 
422*0b57cec5SDimitry Andric static DecodeStatus DecodeSimm19Lsl2(MCInst &Inst, unsigned Insn,
423*0b57cec5SDimitry Andric                                      uint64_t Address, const void *Decoder);
424*0b57cec5SDimitry Andric 
425*0b57cec5SDimitry Andric static DecodeStatus DecodeSimm18Lsl3(MCInst &Inst, unsigned Insn,
426*0b57cec5SDimitry Andric                                      uint64_t Address, const void *Decoder);
427*0b57cec5SDimitry Andric 
428*0b57cec5SDimitry Andric static DecodeStatus DecodeSimm9SP(MCInst &Inst, unsigned Insn,
429*0b57cec5SDimitry Andric                                   uint64_t Address, const void *Decoder);
430*0b57cec5SDimitry Andric 
431*0b57cec5SDimitry Andric static DecodeStatus DecodeANDI16Imm(MCInst &Inst, unsigned Insn,
432*0b57cec5SDimitry Andric                                     uint64_t Address, const void *Decoder);
433*0b57cec5SDimitry Andric 
434*0b57cec5SDimitry Andric static DecodeStatus DecodeSimm23Lsl2(MCInst &Inst, unsigned Insn,
435*0b57cec5SDimitry Andric                                      uint64_t Address, const void *Decoder);
436*0b57cec5SDimitry Andric 
437*0b57cec5SDimitry Andric /// INSVE_[BHWD] have an implicit operand that the generated decoder doesn't
438*0b57cec5SDimitry Andric /// handle.
439*0b57cec5SDimitry Andric template <typename InsnType>
440*0b57cec5SDimitry Andric static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address,
441*0b57cec5SDimitry Andric                                    const void *Decoder);
442*0b57cec5SDimitry Andric 
443*0b57cec5SDimitry Andric template <typename InsnType>
444*0b57cec5SDimitry Andric static DecodeStatus DecodeDAHIDATIMMR6(MCInst &MI, InsnType insn, uint64_t Address,
445*0b57cec5SDimitry Andric                                    const void *Decoder);
446*0b57cec5SDimitry Andric 
447*0b57cec5SDimitry Andric template <typename InsnType>
448*0b57cec5SDimitry Andric static DecodeStatus DecodeDAHIDATI(MCInst &MI, InsnType insn, uint64_t Address,
449*0b57cec5SDimitry Andric                                    const void *Decoder);
450*0b57cec5SDimitry Andric 
451*0b57cec5SDimitry Andric template <typename InsnType>
452*0b57cec5SDimitry Andric static DecodeStatus DecodeDAHIDATIMMR6(MCInst &MI, InsnType insn, uint64_t Address,
453*0b57cec5SDimitry Andric                                    const void *Decoder);
454*0b57cec5SDimitry Andric 
455*0b57cec5SDimitry Andric template <typename InsnType>
456*0b57cec5SDimitry Andric static DecodeStatus DecodeDAHIDATI(MCInst &MI, InsnType insn, uint64_t Address,
457*0b57cec5SDimitry Andric                                    const void *Decoder);
458*0b57cec5SDimitry Andric 
459*0b57cec5SDimitry Andric template <typename InsnType>
460*0b57cec5SDimitry Andric static DecodeStatus
461*0b57cec5SDimitry Andric DecodeAddiGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
462*0b57cec5SDimitry Andric                       const void *Decoder);
463*0b57cec5SDimitry Andric 
464*0b57cec5SDimitry Andric template <typename InsnType>
465*0b57cec5SDimitry Andric static DecodeStatus
466*0b57cec5SDimitry Andric DecodePOP35GroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address,
467*0b57cec5SDimitry Andric                            const void *Decoder);
468*0b57cec5SDimitry Andric 
469*0b57cec5SDimitry Andric template <typename InsnType>
470*0b57cec5SDimitry Andric static DecodeStatus
471*0b57cec5SDimitry Andric DecodeDaddiGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
472*0b57cec5SDimitry Andric                        const void *Decoder);
473*0b57cec5SDimitry Andric 
474*0b57cec5SDimitry Andric template <typename InsnType>
475*0b57cec5SDimitry Andric static DecodeStatus
476*0b57cec5SDimitry Andric DecodePOP37GroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address,
477*0b57cec5SDimitry Andric                            const void *Decoder);
478*0b57cec5SDimitry Andric 
479*0b57cec5SDimitry Andric template <typename InsnType>
480*0b57cec5SDimitry Andric static DecodeStatus
481*0b57cec5SDimitry Andric DecodePOP65GroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address,
482*0b57cec5SDimitry Andric                            const void *Decoder);
483*0b57cec5SDimitry Andric 
484*0b57cec5SDimitry Andric template <typename InsnType>
485*0b57cec5SDimitry Andric static DecodeStatus
486*0b57cec5SDimitry Andric DecodePOP75GroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address,
487*0b57cec5SDimitry Andric                            const void *Decoder);
488*0b57cec5SDimitry Andric 
489*0b57cec5SDimitry Andric template <typename InsnType>
490*0b57cec5SDimitry Andric static DecodeStatus
491*0b57cec5SDimitry Andric DecodeBlezlGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
492*0b57cec5SDimitry Andric                        const void *Decoder);
493*0b57cec5SDimitry Andric 
494*0b57cec5SDimitry Andric template <typename InsnType>
495*0b57cec5SDimitry Andric static DecodeStatus
496*0b57cec5SDimitry Andric DecodeBgtzlGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
497*0b57cec5SDimitry Andric                        const void *Decoder);
498*0b57cec5SDimitry Andric 
499*0b57cec5SDimitry Andric template <typename InsnType>
500*0b57cec5SDimitry Andric static DecodeStatus
501*0b57cec5SDimitry Andric DecodeBgtzGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
502*0b57cec5SDimitry Andric                       const void *Decoder);
503*0b57cec5SDimitry Andric 
504*0b57cec5SDimitry Andric template <typename InsnType>
505*0b57cec5SDimitry Andric static DecodeStatus
506*0b57cec5SDimitry Andric DecodeBlezGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
507*0b57cec5SDimitry Andric                        const void *Decoder);
508*0b57cec5SDimitry Andric 
509*0b57cec5SDimitry Andric template <typename InsnType>
510*0b57cec5SDimitry Andric static DecodeStatus
511*0b57cec5SDimitry Andric DecodeBgtzGroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address,
512*0b57cec5SDimitry Andric                           const void *Decoder);
513*0b57cec5SDimitry Andric 
514*0b57cec5SDimitry Andric template <typename InsnType>
515*0b57cec5SDimitry Andric static DecodeStatus
516*0b57cec5SDimitry Andric DecodeBlezGroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address,
517*0b57cec5SDimitry Andric                           const void *Decoder);
518*0b57cec5SDimitry Andric 
519*0b57cec5SDimitry Andric template <typename InsnType>
520*0b57cec5SDimitry Andric static DecodeStatus DecodeDINS(MCInst &MI, InsnType Insn, uint64_t Address,
521*0b57cec5SDimitry Andric                                const void *Decoder);
522*0b57cec5SDimitry Andric 
523*0b57cec5SDimitry Andric template <typename InsnType>
524*0b57cec5SDimitry Andric static DecodeStatus DecodeDEXT(MCInst &MI, InsnType Insn, uint64_t Address,
525*0b57cec5SDimitry Andric                                const void *Decoder);
526*0b57cec5SDimitry Andric 
527*0b57cec5SDimitry Andric template <typename InsnType>
528*0b57cec5SDimitry Andric static DecodeStatus DecodeCRC(MCInst &MI, InsnType Insn, uint64_t Address,
529*0b57cec5SDimitry Andric                               const void *Decoder);
530*0b57cec5SDimitry Andric 
531*0b57cec5SDimitry Andric static DecodeStatus DecodeRegListOperand(MCInst &Inst, unsigned Insn,
532*0b57cec5SDimitry Andric                                          uint64_t Address,
533*0b57cec5SDimitry Andric                                          const void *Decoder);
534*0b57cec5SDimitry Andric 
535*0b57cec5SDimitry Andric static DecodeStatus DecodeRegListOperand16(MCInst &Inst, unsigned Insn,
536*0b57cec5SDimitry Andric                                            uint64_t Address,
537*0b57cec5SDimitry Andric                                            const void *Decoder);
538*0b57cec5SDimitry Andric 
539*0b57cec5SDimitry Andric static DecodeStatus DecodeMovePRegPair(MCInst &Inst, unsigned RegPair,
540*0b57cec5SDimitry Andric                                        uint64_t Address,
541*0b57cec5SDimitry Andric                                        const void *Decoder);
542*0b57cec5SDimitry Andric 
543*0b57cec5SDimitry Andric static DecodeStatus DecodeMovePOperands(MCInst &Inst, unsigned Insn,
544*0b57cec5SDimitry Andric                                         uint64_t Address, const void *Decoder);
545*0b57cec5SDimitry Andric 
546*0b57cec5SDimitry Andric static MCDisassembler *createMipsDisassembler(
547*0b57cec5SDimitry Andric                        const Target &T,
548*0b57cec5SDimitry Andric                        const MCSubtargetInfo &STI,
549*0b57cec5SDimitry Andric                        MCContext &Ctx) {
550*0b57cec5SDimitry Andric   return new MipsDisassembler(STI, Ctx, true);
551*0b57cec5SDimitry Andric }
552*0b57cec5SDimitry Andric 
553*0b57cec5SDimitry Andric static MCDisassembler *createMipselDisassembler(
554*0b57cec5SDimitry Andric                        const Target &T,
555*0b57cec5SDimitry Andric                        const MCSubtargetInfo &STI,
556*0b57cec5SDimitry Andric                        MCContext &Ctx) {
557*0b57cec5SDimitry Andric   return new MipsDisassembler(STI, Ctx, false);
558*0b57cec5SDimitry Andric }
559*0b57cec5SDimitry Andric 
560*0b57cec5SDimitry Andric extern "C" void LLVMInitializeMipsDisassembler() {
561*0b57cec5SDimitry Andric   // Register the disassembler.
562*0b57cec5SDimitry Andric   TargetRegistry::RegisterMCDisassembler(getTheMipsTarget(),
563*0b57cec5SDimitry Andric                                          createMipsDisassembler);
564*0b57cec5SDimitry Andric   TargetRegistry::RegisterMCDisassembler(getTheMipselTarget(),
565*0b57cec5SDimitry Andric                                          createMipselDisassembler);
566*0b57cec5SDimitry Andric   TargetRegistry::RegisterMCDisassembler(getTheMips64Target(),
567*0b57cec5SDimitry Andric                                          createMipsDisassembler);
568*0b57cec5SDimitry Andric   TargetRegistry::RegisterMCDisassembler(getTheMips64elTarget(),
569*0b57cec5SDimitry Andric                                          createMipselDisassembler);
570*0b57cec5SDimitry Andric }
571*0b57cec5SDimitry Andric 
572*0b57cec5SDimitry Andric #include "MipsGenDisassemblerTables.inc"
573*0b57cec5SDimitry Andric 
574*0b57cec5SDimitry Andric static unsigned getReg(const void *D, unsigned RC, unsigned RegNo) {
575*0b57cec5SDimitry Andric   const MipsDisassembler *Dis = static_cast<const MipsDisassembler*>(D);
576*0b57cec5SDimitry Andric   const MCRegisterInfo *RegInfo = Dis->getContext().getRegisterInfo();
577*0b57cec5SDimitry Andric   return *(RegInfo->getRegClass(RC).begin() + RegNo);
578*0b57cec5SDimitry Andric }
579*0b57cec5SDimitry Andric 
580*0b57cec5SDimitry Andric template <typename InsnType>
581*0b57cec5SDimitry Andric static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address,
582*0b57cec5SDimitry Andric                                    const void *Decoder) {
583*0b57cec5SDimitry Andric   using DecodeFN = DecodeStatus (*)(MCInst &, unsigned, uint64_t, const void *);
584*0b57cec5SDimitry Andric 
585*0b57cec5SDimitry Andric   // The size of the n field depends on the element size
586*0b57cec5SDimitry Andric   // The register class also depends on this.
587*0b57cec5SDimitry Andric   InsnType tmp = fieldFromInstruction(insn, 17, 5);
588*0b57cec5SDimitry Andric   unsigned NSize = 0;
589*0b57cec5SDimitry Andric   DecodeFN RegDecoder = nullptr;
590*0b57cec5SDimitry Andric   if ((tmp & 0x18) == 0x00) { // INSVE_B
591*0b57cec5SDimitry Andric     NSize = 4;
592*0b57cec5SDimitry Andric     RegDecoder = DecodeMSA128BRegisterClass;
593*0b57cec5SDimitry Andric   } else if ((tmp & 0x1c) == 0x10) { // INSVE_H
594*0b57cec5SDimitry Andric     NSize = 3;
595*0b57cec5SDimitry Andric     RegDecoder = DecodeMSA128HRegisterClass;
596*0b57cec5SDimitry Andric   } else if ((tmp & 0x1e) == 0x18) { // INSVE_W
597*0b57cec5SDimitry Andric     NSize = 2;
598*0b57cec5SDimitry Andric     RegDecoder = DecodeMSA128WRegisterClass;
599*0b57cec5SDimitry Andric   } else if ((tmp & 0x1f) == 0x1c) { // INSVE_D
600*0b57cec5SDimitry Andric     NSize = 1;
601*0b57cec5SDimitry Andric     RegDecoder = DecodeMSA128DRegisterClass;
602*0b57cec5SDimitry Andric   } else
603*0b57cec5SDimitry Andric     llvm_unreachable("Invalid encoding");
604*0b57cec5SDimitry Andric 
605*0b57cec5SDimitry Andric   assert(NSize != 0 && RegDecoder != nullptr);
606*0b57cec5SDimitry Andric 
607*0b57cec5SDimitry Andric   // $wd
608*0b57cec5SDimitry Andric   tmp = fieldFromInstruction(insn, 6, 5);
609*0b57cec5SDimitry Andric   if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
610*0b57cec5SDimitry Andric     return MCDisassembler::Fail;
611*0b57cec5SDimitry Andric   // $wd_in
612*0b57cec5SDimitry Andric   if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
613*0b57cec5SDimitry Andric     return MCDisassembler::Fail;
614*0b57cec5SDimitry Andric   // $n
615*0b57cec5SDimitry Andric   tmp = fieldFromInstruction(insn, 16, NSize);
616*0b57cec5SDimitry Andric   MI.addOperand(MCOperand::createImm(tmp));
617*0b57cec5SDimitry Andric   // $ws
618*0b57cec5SDimitry Andric   tmp = fieldFromInstruction(insn, 11, 5);
619*0b57cec5SDimitry Andric   if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
620*0b57cec5SDimitry Andric     return MCDisassembler::Fail;
621*0b57cec5SDimitry Andric   // $n2
622*0b57cec5SDimitry Andric   MI.addOperand(MCOperand::createImm(0));
623*0b57cec5SDimitry Andric 
624*0b57cec5SDimitry Andric   return MCDisassembler::Success;
625*0b57cec5SDimitry Andric }
626*0b57cec5SDimitry Andric 
627*0b57cec5SDimitry Andric template <typename InsnType>
628*0b57cec5SDimitry Andric static DecodeStatus DecodeDAHIDATIMMR6(MCInst &MI, InsnType insn, uint64_t Address,
629*0b57cec5SDimitry Andric                                const void *Decoder) {
630*0b57cec5SDimitry Andric   InsnType Rs = fieldFromInstruction(insn, 16, 5);
631*0b57cec5SDimitry Andric   InsnType Imm = fieldFromInstruction(insn, 0, 16);
632*0b57cec5SDimitry Andric   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID,
633*0b57cec5SDimitry Andric                                        Rs)));
634*0b57cec5SDimitry Andric   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID,
635*0b57cec5SDimitry Andric                                        Rs)));
636*0b57cec5SDimitry Andric   MI.addOperand(MCOperand::createImm(Imm));
637*0b57cec5SDimitry Andric 
638*0b57cec5SDimitry Andric   return MCDisassembler::Success;
639*0b57cec5SDimitry Andric }
640*0b57cec5SDimitry Andric 
641*0b57cec5SDimitry Andric template <typename InsnType>
642*0b57cec5SDimitry Andric static DecodeStatus DecodeDAHIDATI(MCInst &MI, InsnType insn, uint64_t Address,
643*0b57cec5SDimitry Andric                                const void *Decoder) {
644*0b57cec5SDimitry Andric   InsnType Rs = fieldFromInstruction(insn, 21, 5);
645*0b57cec5SDimitry Andric   InsnType Imm = fieldFromInstruction(insn, 0, 16);
646*0b57cec5SDimitry Andric   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID,
647*0b57cec5SDimitry Andric                                        Rs)));
648*0b57cec5SDimitry Andric   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID,
649*0b57cec5SDimitry Andric                                        Rs)));
650*0b57cec5SDimitry Andric   MI.addOperand(MCOperand::createImm(Imm));
651*0b57cec5SDimitry Andric 
652*0b57cec5SDimitry Andric   return MCDisassembler::Success;
653*0b57cec5SDimitry Andric }
654*0b57cec5SDimitry Andric 
655*0b57cec5SDimitry Andric template <typename InsnType>
656*0b57cec5SDimitry Andric static DecodeStatus DecodeAddiGroupBranch(MCInst &MI, InsnType insn,
657*0b57cec5SDimitry Andric                                           uint64_t Address,
658*0b57cec5SDimitry Andric                                           const void *Decoder) {
659*0b57cec5SDimitry Andric   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
660*0b57cec5SDimitry Andric   // (otherwise we would have matched the ADDI instruction from the earlier
661*0b57cec5SDimitry Andric   // ISA's instead).
662*0b57cec5SDimitry Andric   //
663*0b57cec5SDimitry Andric   // We have:
664*0b57cec5SDimitry Andric   //    0b001000 sssss ttttt iiiiiiiiiiiiiiii
665*0b57cec5SDimitry Andric   //      BOVC if rs >= rt
666*0b57cec5SDimitry Andric   //      BEQZALC if rs == 0 && rt != 0
667*0b57cec5SDimitry Andric   //      BEQC if rs < rt && rs != 0
668*0b57cec5SDimitry Andric 
669*0b57cec5SDimitry Andric   InsnType Rs = fieldFromInstruction(insn, 21, 5);
670*0b57cec5SDimitry Andric   InsnType Rt = fieldFromInstruction(insn, 16, 5);
671*0b57cec5SDimitry Andric   int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
672*0b57cec5SDimitry Andric   bool HasRs = false;
673*0b57cec5SDimitry Andric 
674*0b57cec5SDimitry Andric   if (Rs >= Rt) {
675*0b57cec5SDimitry Andric     MI.setOpcode(Mips::BOVC);
676*0b57cec5SDimitry Andric     HasRs = true;
677*0b57cec5SDimitry Andric   } else if (Rs != 0 && Rs < Rt) {
678*0b57cec5SDimitry Andric     MI.setOpcode(Mips::BEQC);
679*0b57cec5SDimitry Andric     HasRs = true;
680*0b57cec5SDimitry Andric   } else
681*0b57cec5SDimitry Andric     MI.setOpcode(Mips::BEQZALC);
682*0b57cec5SDimitry Andric 
683*0b57cec5SDimitry Andric   if (HasRs)
684*0b57cec5SDimitry Andric     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
685*0b57cec5SDimitry Andric                                        Rs)));
686*0b57cec5SDimitry Andric 
687*0b57cec5SDimitry Andric   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
688*0b57cec5SDimitry Andric                                      Rt)));
689*0b57cec5SDimitry Andric   MI.addOperand(MCOperand::createImm(Imm));
690*0b57cec5SDimitry Andric 
691*0b57cec5SDimitry Andric   return MCDisassembler::Success;
692*0b57cec5SDimitry Andric }
693*0b57cec5SDimitry Andric 
694*0b57cec5SDimitry Andric template <typename InsnType>
695*0b57cec5SDimitry Andric static DecodeStatus DecodePOP35GroupBranchMMR6(MCInst &MI, InsnType insn,
696*0b57cec5SDimitry Andric                                                uint64_t Address,
697*0b57cec5SDimitry Andric                                                const void *Decoder) {
698*0b57cec5SDimitry Andric   InsnType Rt = fieldFromInstruction(insn, 21, 5);
699*0b57cec5SDimitry Andric   InsnType Rs = fieldFromInstruction(insn, 16, 5);
700*0b57cec5SDimitry Andric   int64_t Imm = 0;
701*0b57cec5SDimitry Andric 
702*0b57cec5SDimitry Andric   if (Rs >= Rt) {
703*0b57cec5SDimitry Andric     MI.setOpcode(Mips::BOVC_MMR6);
704*0b57cec5SDimitry Andric     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
705*0b57cec5SDimitry Andric                                        Rt)));
706*0b57cec5SDimitry Andric     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
707*0b57cec5SDimitry Andric                                        Rs)));
708*0b57cec5SDimitry Andric     Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
709*0b57cec5SDimitry Andric   } else if (Rs != 0 && Rs < Rt) {
710*0b57cec5SDimitry Andric     MI.setOpcode(Mips::BEQC_MMR6);
711*0b57cec5SDimitry Andric     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
712*0b57cec5SDimitry Andric                                        Rs)));
713*0b57cec5SDimitry Andric     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
714*0b57cec5SDimitry Andric                                        Rt)));
715*0b57cec5SDimitry Andric     Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
716*0b57cec5SDimitry Andric   } else {
717*0b57cec5SDimitry Andric     MI.setOpcode(Mips::BEQZALC_MMR6);
718*0b57cec5SDimitry Andric     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
719*0b57cec5SDimitry Andric                                        Rt)));
720*0b57cec5SDimitry Andric     Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
721*0b57cec5SDimitry Andric   }
722*0b57cec5SDimitry Andric 
723*0b57cec5SDimitry Andric   MI.addOperand(MCOperand::createImm(Imm));
724*0b57cec5SDimitry Andric 
725*0b57cec5SDimitry Andric   return MCDisassembler::Success;
726*0b57cec5SDimitry Andric }
727*0b57cec5SDimitry Andric 
728*0b57cec5SDimitry Andric template <typename InsnType>
729*0b57cec5SDimitry Andric static DecodeStatus DecodeDaddiGroupBranch(MCInst &MI, InsnType insn,
730*0b57cec5SDimitry Andric                                            uint64_t Address,
731*0b57cec5SDimitry Andric                                            const void *Decoder) {
732*0b57cec5SDimitry Andric   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
733*0b57cec5SDimitry Andric   // (otherwise we would have matched the ADDI instruction from the earlier
734*0b57cec5SDimitry Andric   // ISA's instead).
735*0b57cec5SDimitry Andric   //
736*0b57cec5SDimitry Andric   // We have:
737*0b57cec5SDimitry Andric   //    0b011000 sssss ttttt iiiiiiiiiiiiiiii
738*0b57cec5SDimitry Andric   //      BNVC if rs >= rt
739*0b57cec5SDimitry Andric   //      BNEZALC if rs == 0 && rt != 0
740*0b57cec5SDimitry Andric   //      BNEC if rs < rt && rs != 0
741*0b57cec5SDimitry Andric 
742*0b57cec5SDimitry Andric   InsnType Rs = fieldFromInstruction(insn, 21, 5);
743*0b57cec5SDimitry Andric   InsnType Rt = fieldFromInstruction(insn, 16, 5);
744*0b57cec5SDimitry Andric   int64_t  Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
745*0b57cec5SDimitry Andric   bool HasRs = false;
746*0b57cec5SDimitry Andric 
747*0b57cec5SDimitry Andric   if (Rs >= Rt) {
748*0b57cec5SDimitry Andric     MI.setOpcode(Mips::BNVC);
749*0b57cec5SDimitry Andric     HasRs = true;
750*0b57cec5SDimitry Andric   } else if (Rs != 0 && Rs < Rt) {
751*0b57cec5SDimitry Andric     MI.setOpcode(Mips::BNEC);
752*0b57cec5SDimitry Andric     HasRs = true;
753*0b57cec5SDimitry Andric   } else
754*0b57cec5SDimitry Andric     MI.setOpcode(Mips::BNEZALC);
755*0b57cec5SDimitry Andric 
756*0b57cec5SDimitry Andric   if (HasRs)
757*0b57cec5SDimitry Andric     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
758*0b57cec5SDimitry Andric                                        Rs)));
759*0b57cec5SDimitry Andric 
760*0b57cec5SDimitry Andric   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
761*0b57cec5SDimitry Andric                                      Rt)));
762*0b57cec5SDimitry Andric   MI.addOperand(MCOperand::createImm(Imm));
763*0b57cec5SDimitry Andric 
764*0b57cec5SDimitry Andric   return MCDisassembler::Success;
765*0b57cec5SDimitry Andric }
766*0b57cec5SDimitry Andric 
767*0b57cec5SDimitry Andric template <typename InsnType>
768*0b57cec5SDimitry Andric static DecodeStatus DecodePOP37GroupBranchMMR6(MCInst &MI, InsnType insn,
769*0b57cec5SDimitry Andric                                                uint64_t Address,
770*0b57cec5SDimitry Andric                                                const void *Decoder) {
771*0b57cec5SDimitry Andric   InsnType Rt = fieldFromInstruction(insn, 21, 5);
772*0b57cec5SDimitry Andric   InsnType Rs = fieldFromInstruction(insn, 16, 5);
773*0b57cec5SDimitry Andric   int64_t Imm = 0;
774*0b57cec5SDimitry Andric 
775*0b57cec5SDimitry Andric   if (Rs >= Rt) {
776*0b57cec5SDimitry Andric     MI.setOpcode(Mips::BNVC_MMR6);
777*0b57cec5SDimitry Andric     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
778*0b57cec5SDimitry Andric                                        Rt)));
779*0b57cec5SDimitry Andric     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
780*0b57cec5SDimitry Andric                                        Rs)));
781*0b57cec5SDimitry Andric     Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
782*0b57cec5SDimitry Andric   } else if (Rs != 0 && Rs < Rt) {
783*0b57cec5SDimitry Andric     MI.setOpcode(Mips::BNEC_MMR6);
784*0b57cec5SDimitry Andric     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
785*0b57cec5SDimitry Andric                                        Rs)));
786*0b57cec5SDimitry Andric     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
787*0b57cec5SDimitry Andric                                        Rt)));
788*0b57cec5SDimitry Andric     Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
789*0b57cec5SDimitry Andric   } else {
790*0b57cec5SDimitry Andric     MI.setOpcode(Mips::BNEZALC_MMR6);
791*0b57cec5SDimitry Andric     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
792*0b57cec5SDimitry Andric                                        Rt)));
793*0b57cec5SDimitry Andric     Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
794*0b57cec5SDimitry Andric   }
795*0b57cec5SDimitry Andric 
796*0b57cec5SDimitry Andric   MI.addOperand(MCOperand::createImm(Imm));
797*0b57cec5SDimitry Andric 
798*0b57cec5SDimitry Andric   return MCDisassembler::Success;
799*0b57cec5SDimitry Andric }
800*0b57cec5SDimitry Andric 
801*0b57cec5SDimitry Andric template <typename InsnType>
802*0b57cec5SDimitry Andric static DecodeStatus DecodePOP65GroupBranchMMR6(MCInst &MI, InsnType insn,
803*0b57cec5SDimitry Andric                                                uint64_t Address,
804*0b57cec5SDimitry Andric                                                const void *Decoder) {
805*0b57cec5SDimitry Andric   // We have:
806*0b57cec5SDimitry Andric   //    0b110101 ttttt sssss iiiiiiiiiiiiiiii
807*0b57cec5SDimitry Andric   //      Invalid if rt == 0
808*0b57cec5SDimitry Andric   //      BGTZC_MMR6   if rs == 0  && rt != 0
809*0b57cec5SDimitry Andric   //      BLTZC_MMR6   if rs == rt && rt != 0
810*0b57cec5SDimitry Andric   //      BLTC_MMR6    if rs != rt && rs != 0  && rt != 0
811*0b57cec5SDimitry Andric 
812*0b57cec5SDimitry Andric   InsnType Rt = fieldFromInstruction(insn, 21, 5);
813*0b57cec5SDimitry Andric   InsnType Rs = fieldFromInstruction(insn, 16, 5);
814*0b57cec5SDimitry Andric   int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
815*0b57cec5SDimitry Andric   bool HasRs = false;
816*0b57cec5SDimitry Andric 
817*0b57cec5SDimitry Andric   if (Rt == 0)
818*0b57cec5SDimitry Andric     return MCDisassembler::Fail;
819*0b57cec5SDimitry Andric   else if (Rs == 0)
820*0b57cec5SDimitry Andric     MI.setOpcode(Mips::BGTZC_MMR6);
821*0b57cec5SDimitry Andric   else if (Rs == Rt)
822*0b57cec5SDimitry Andric     MI.setOpcode(Mips::BLTZC_MMR6);
823*0b57cec5SDimitry Andric   else {
824*0b57cec5SDimitry Andric     MI.setOpcode(Mips::BLTC_MMR6);
825*0b57cec5SDimitry Andric     HasRs = true;
826*0b57cec5SDimitry Andric   }
827*0b57cec5SDimitry Andric 
828*0b57cec5SDimitry Andric   if (HasRs)
829*0b57cec5SDimitry Andric     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
830*0b57cec5SDimitry Andric                                               Rs)));
831*0b57cec5SDimitry Andric 
832*0b57cec5SDimitry Andric   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
833*0b57cec5SDimitry Andric                                      Rt)));
834*0b57cec5SDimitry Andric 
835*0b57cec5SDimitry Andric   MI.addOperand(MCOperand::createImm(Imm));
836*0b57cec5SDimitry Andric 
837*0b57cec5SDimitry Andric   return MCDisassembler::Success;
838*0b57cec5SDimitry Andric }
839*0b57cec5SDimitry Andric 
840*0b57cec5SDimitry Andric template <typename InsnType>
841*0b57cec5SDimitry Andric static DecodeStatus DecodePOP75GroupBranchMMR6(MCInst &MI, InsnType insn,
842*0b57cec5SDimitry Andric                                                uint64_t Address,
843*0b57cec5SDimitry Andric                                                const void *Decoder) {
844*0b57cec5SDimitry Andric   // We have:
845*0b57cec5SDimitry Andric   //    0b111101 ttttt sssss iiiiiiiiiiiiiiii
846*0b57cec5SDimitry Andric   //      Invalid if rt == 0
847*0b57cec5SDimitry Andric   //      BLEZC_MMR6   if rs == 0  && rt != 0
848*0b57cec5SDimitry Andric   //      BGEZC_MMR6   if rs == rt && rt != 0
849*0b57cec5SDimitry Andric   //      BGEC_MMR6    if rs != rt && rs != 0  && rt != 0
850*0b57cec5SDimitry Andric 
851*0b57cec5SDimitry Andric   InsnType Rt = fieldFromInstruction(insn, 21, 5);
852*0b57cec5SDimitry Andric   InsnType Rs = fieldFromInstruction(insn, 16, 5);
853*0b57cec5SDimitry Andric   int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
854*0b57cec5SDimitry Andric   bool HasRs = false;
855*0b57cec5SDimitry Andric 
856*0b57cec5SDimitry Andric   if (Rt == 0)
857*0b57cec5SDimitry Andric     return MCDisassembler::Fail;
858*0b57cec5SDimitry Andric   else if (Rs == 0)
859*0b57cec5SDimitry Andric     MI.setOpcode(Mips::BLEZC_MMR6);
860*0b57cec5SDimitry Andric   else if (Rs == Rt)
861*0b57cec5SDimitry Andric     MI.setOpcode(Mips::BGEZC_MMR6);
862*0b57cec5SDimitry Andric   else {
863*0b57cec5SDimitry Andric     HasRs = true;
864*0b57cec5SDimitry Andric     MI.setOpcode(Mips::BGEC_MMR6);
865*0b57cec5SDimitry Andric   }
866*0b57cec5SDimitry Andric 
867*0b57cec5SDimitry Andric   if (HasRs)
868*0b57cec5SDimitry Andric     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
869*0b57cec5SDimitry Andric                                        Rs)));
870*0b57cec5SDimitry Andric 
871*0b57cec5SDimitry Andric   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
872*0b57cec5SDimitry Andric                                      Rt)));
873*0b57cec5SDimitry Andric 
874*0b57cec5SDimitry Andric   MI.addOperand(MCOperand::createImm(Imm));
875*0b57cec5SDimitry Andric 
876*0b57cec5SDimitry Andric   return MCDisassembler::Success;
877*0b57cec5SDimitry Andric }
878*0b57cec5SDimitry Andric 
879*0b57cec5SDimitry Andric template <typename InsnType>
880*0b57cec5SDimitry Andric static DecodeStatus DecodeBlezlGroupBranch(MCInst &MI, InsnType insn,
881*0b57cec5SDimitry Andric                                            uint64_t Address,
882*0b57cec5SDimitry Andric                                            const void *Decoder) {
883*0b57cec5SDimitry Andric   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
884*0b57cec5SDimitry Andric   // (otherwise we would have matched the BLEZL instruction from the earlier
885*0b57cec5SDimitry Andric   // ISA's instead).
886*0b57cec5SDimitry Andric   //
887*0b57cec5SDimitry Andric   // We have:
888*0b57cec5SDimitry Andric   //    0b010110 sssss ttttt iiiiiiiiiiiiiiii
889*0b57cec5SDimitry Andric   //      Invalid if rs == 0
890*0b57cec5SDimitry Andric   //      BLEZC   if rs == 0  && rt != 0
891*0b57cec5SDimitry Andric   //      BGEZC   if rs == rt && rt != 0
892*0b57cec5SDimitry Andric   //      BGEC    if rs != rt && rs != 0  && rt != 0
893*0b57cec5SDimitry Andric 
894*0b57cec5SDimitry Andric   InsnType Rs = fieldFromInstruction(insn, 21, 5);
895*0b57cec5SDimitry Andric   InsnType Rt = fieldFromInstruction(insn, 16, 5);
896*0b57cec5SDimitry Andric   int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
897*0b57cec5SDimitry Andric   bool HasRs = false;
898*0b57cec5SDimitry Andric 
899*0b57cec5SDimitry Andric   if (Rt == 0)
900*0b57cec5SDimitry Andric     return MCDisassembler::Fail;
901*0b57cec5SDimitry Andric   else if (Rs == 0)
902*0b57cec5SDimitry Andric     MI.setOpcode(Mips::BLEZC);
903*0b57cec5SDimitry Andric   else if (Rs == Rt)
904*0b57cec5SDimitry Andric     MI.setOpcode(Mips::BGEZC);
905*0b57cec5SDimitry Andric   else {
906*0b57cec5SDimitry Andric     HasRs = true;
907*0b57cec5SDimitry Andric     MI.setOpcode(Mips::BGEC);
908*0b57cec5SDimitry Andric   }
909*0b57cec5SDimitry Andric 
910*0b57cec5SDimitry Andric   if (HasRs)
911*0b57cec5SDimitry Andric     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
912*0b57cec5SDimitry Andric                                        Rs)));
913*0b57cec5SDimitry Andric 
914*0b57cec5SDimitry Andric   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
915*0b57cec5SDimitry Andric                                      Rt)));
916*0b57cec5SDimitry Andric 
917*0b57cec5SDimitry Andric   MI.addOperand(MCOperand::createImm(Imm));
918*0b57cec5SDimitry Andric 
919*0b57cec5SDimitry Andric   return MCDisassembler::Success;
920*0b57cec5SDimitry Andric }
921*0b57cec5SDimitry Andric 
922*0b57cec5SDimitry Andric template <typename InsnType>
923*0b57cec5SDimitry Andric static DecodeStatus DecodeBgtzlGroupBranch(MCInst &MI, InsnType insn,
924*0b57cec5SDimitry Andric                                            uint64_t Address,
925*0b57cec5SDimitry Andric                                            const void *Decoder) {
926*0b57cec5SDimitry Andric   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
927*0b57cec5SDimitry Andric   // (otherwise we would have matched the BGTZL instruction from the earlier
928*0b57cec5SDimitry Andric   // ISA's instead).
929*0b57cec5SDimitry Andric   //
930*0b57cec5SDimitry Andric   // We have:
931*0b57cec5SDimitry Andric   //    0b010111 sssss ttttt iiiiiiiiiiiiiiii
932*0b57cec5SDimitry Andric   //      Invalid if rs == 0
933*0b57cec5SDimitry Andric   //      BGTZC   if rs == 0  && rt != 0
934*0b57cec5SDimitry Andric   //      BLTZC   if rs == rt && rt != 0
935*0b57cec5SDimitry Andric   //      BLTC    if rs != rt && rs != 0  && rt != 0
936*0b57cec5SDimitry Andric 
937*0b57cec5SDimitry Andric   bool HasRs = false;
938*0b57cec5SDimitry Andric 
939*0b57cec5SDimitry Andric   InsnType Rs = fieldFromInstruction(insn, 21, 5);
940*0b57cec5SDimitry Andric   InsnType Rt = fieldFromInstruction(insn, 16, 5);
941*0b57cec5SDimitry Andric   int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
942*0b57cec5SDimitry Andric 
943*0b57cec5SDimitry Andric   if (Rt == 0)
944*0b57cec5SDimitry Andric     return MCDisassembler::Fail;
945*0b57cec5SDimitry Andric   else if (Rs == 0)
946*0b57cec5SDimitry Andric     MI.setOpcode(Mips::BGTZC);
947*0b57cec5SDimitry Andric   else if (Rs == Rt)
948*0b57cec5SDimitry Andric     MI.setOpcode(Mips::BLTZC);
949*0b57cec5SDimitry Andric   else {
950*0b57cec5SDimitry Andric     MI.setOpcode(Mips::BLTC);
951*0b57cec5SDimitry Andric     HasRs = true;
952*0b57cec5SDimitry Andric   }
953*0b57cec5SDimitry Andric 
954*0b57cec5SDimitry Andric   if (HasRs)
955*0b57cec5SDimitry Andric     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
956*0b57cec5SDimitry Andric                                               Rs)));
957*0b57cec5SDimitry Andric 
958*0b57cec5SDimitry Andric   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
959*0b57cec5SDimitry Andric                                      Rt)));
960*0b57cec5SDimitry Andric 
961*0b57cec5SDimitry Andric   MI.addOperand(MCOperand::createImm(Imm));
962*0b57cec5SDimitry Andric 
963*0b57cec5SDimitry Andric   return MCDisassembler::Success;
964*0b57cec5SDimitry Andric }
965*0b57cec5SDimitry Andric 
966*0b57cec5SDimitry Andric template <typename InsnType>
967*0b57cec5SDimitry Andric static DecodeStatus DecodeBgtzGroupBranch(MCInst &MI, InsnType insn,
968*0b57cec5SDimitry Andric                                           uint64_t Address,
969*0b57cec5SDimitry Andric                                           const void *Decoder) {
970*0b57cec5SDimitry Andric   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
971*0b57cec5SDimitry Andric   // (otherwise we would have matched the BGTZ instruction from the earlier
972*0b57cec5SDimitry Andric   // ISA's instead).
973*0b57cec5SDimitry Andric   //
974*0b57cec5SDimitry Andric   // We have:
975*0b57cec5SDimitry Andric   //    0b000111 sssss ttttt iiiiiiiiiiiiiiii
976*0b57cec5SDimitry Andric   //      BGTZ    if rt == 0
977*0b57cec5SDimitry Andric   //      BGTZALC if rs == 0 && rt != 0
978*0b57cec5SDimitry Andric   //      BLTZALC if rs != 0 && rs == rt
979*0b57cec5SDimitry Andric   //      BLTUC   if rs != 0 && rs != rt
980*0b57cec5SDimitry Andric 
981*0b57cec5SDimitry Andric   InsnType Rs = fieldFromInstruction(insn, 21, 5);
982*0b57cec5SDimitry Andric   InsnType Rt = fieldFromInstruction(insn, 16, 5);
983*0b57cec5SDimitry Andric   int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
984*0b57cec5SDimitry Andric   bool HasRs = false;
985*0b57cec5SDimitry Andric   bool HasRt = false;
986*0b57cec5SDimitry Andric 
987*0b57cec5SDimitry Andric   if (Rt == 0) {
988*0b57cec5SDimitry Andric     MI.setOpcode(Mips::BGTZ);
989*0b57cec5SDimitry Andric     HasRs = true;
990*0b57cec5SDimitry Andric   } else if (Rs == 0) {
991*0b57cec5SDimitry Andric     MI.setOpcode(Mips::BGTZALC);
992*0b57cec5SDimitry Andric     HasRt = true;
993*0b57cec5SDimitry Andric   } else if (Rs == Rt) {
994*0b57cec5SDimitry Andric     MI.setOpcode(Mips::BLTZALC);
995*0b57cec5SDimitry Andric     HasRs = true;
996*0b57cec5SDimitry Andric   } else {
997*0b57cec5SDimitry Andric     MI.setOpcode(Mips::BLTUC);
998*0b57cec5SDimitry Andric     HasRs = true;
999*0b57cec5SDimitry Andric     HasRt = true;
1000*0b57cec5SDimitry Andric   }
1001*0b57cec5SDimitry Andric 
1002*0b57cec5SDimitry Andric   if (HasRs)
1003*0b57cec5SDimitry Andric     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
1004*0b57cec5SDimitry Andric                                        Rs)));
1005*0b57cec5SDimitry Andric 
1006*0b57cec5SDimitry Andric   if (HasRt)
1007*0b57cec5SDimitry Andric     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
1008*0b57cec5SDimitry Andric                                        Rt)));
1009*0b57cec5SDimitry Andric 
1010*0b57cec5SDimitry Andric   MI.addOperand(MCOperand::createImm(Imm));
1011*0b57cec5SDimitry Andric 
1012*0b57cec5SDimitry Andric   return MCDisassembler::Success;
1013*0b57cec5SDimitry Andric }
1014*0b57cec5SDimitry Andric 
1015*0b57cec5SDimitry Andric template <typename InsnType>
1016*0b57cec5SDimitry Andric static DecodeStatus DecodeBlezGroupBranch(MCInst &MI, InsnType insn,
1017*0b57cec5SDimitry Andric                                            uint64_t Address,
1018*0b57cec5SDimitry Andric                                            const void *Decoder) {
1019*0b57cec5SDimitry Andric   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
1020*0b57cec5SDimitry Andric   // (otherwise we would have matched the BLEZL instruction from the earlier
1021*0b57cec5SDimitry Andric   // ISA's instead).
1022*0b57cec5SDimitry Andric   //
1023*0b57cec5SDimitry Andric   // We have:
1024*0b57cec5SDimitry Andric   //    0b000110 sssss ttttt iiiiiiiiiiiiiiii
1025*0b57cec5SDimitry Andric   //      Invalid   if rs == 0
1026*0b57cec5SDimitry Andric   //      BLEZALC   if rs == 0  && rt != 0
1027*0b57cec5SDimitry Andric   //      BGEZALC   if rs == rt && rt != 0
1028*0b57cec5SDimitry Andric   //      BGEUC     if rs != rt && rs != 0  && rt != 0
1029*0b57cec5SDimitry Andric 
1030*0b57cec5SDimitry Andric   InsnType Rs = fieldFromInstruction(insn, 21, 5);
1031*0b57cec5SDimitry Andric   InsnType Rt = fieldFromInstruction(insn, 16, 5);
1032*0b57cec5SDimitry Andric   int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
1033*0b57cec5SDimitry Andric   bool HasRs = false;
1034*0b57cec5SDimitry Andric 
1035*0b57cec5SDimitry Andric   if (Rt == 0)
1036*0b57cec5SDimitry Andric     return MCDisassembler::Fail;
1037*0b57cec5SDimitry Andric   else if (Rs == 0)
1038*0b57cec5SDimitry Andric     MI.setOpcode(Mips::BLEZALC);
1039*0b57cec5SDimitry Andric   else if (Rs == Rt)
1040*0b57cec5SDimitry Andric     MI.setOpcode(Mips::BGEZALC);
1041*0b57cec5SDimitry Andric   else {
1042*0b57cec5SDimitry Andric     HasRs = true;
1043*0b57cec5SDimitry Andric     MI.setOpcode(Mips::BGEUC);
1044*0b57cec5SDimitry Andric   }
1045*0b57cec5SDimitry Andric 
1046*0b57cec5SDimitry Andric   if (HasRs)
1047*0b57cec5SDimitry Andric     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
1048*0b57cec5SDimitry Andric                                        Rs)));
1049*0b57cec5SDimitry Andric   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
1050*0b57cec5SDimitry Andric                                      Rt)));
1051*0b57cec5SDimitry Andric 
1052*0b57cec5SDimitry Andric   MI.addOperand(MCOperand::createImm(Imm));
1053*0b57cec5SDimitry Andric 
1054*0b57cec5SDimitry Andric   return MCDisassembler::Success;
1055*0b57cec5SDimitry Andric }
1056*0b57cec5SDimitry Andric 
1057*0b57cec5SDimitry Andric // Override the generated disassembler to produce DEXT all the time. This is
1058*0b57cec5SDimitry Andric // for feature / behaviour parity with  binutils.
1059*0b57cec5SDimitry Andric template <typename InsnType>
1060*0b57cec5SDimitry Andric static DecodeStatus DecodeDEXT(MCInst &MI, InsnType Insn, uint64_t Address,
1061*0b57cec5SDimitry Andric                                const void *Decoder) {
1062*0b57cec5SDimitry Andric   unsigned Msbd = fieldFromInstruction(Insn, 11, 5);
1063*0b57cec5SDimitry Andric   unsigned Lsb = fieldFromInstruction(Insn, 6, 5);
1064*0b57cec5SDimitry Andric   unsigned Size = 0;
1065*0b57cec5SDimitry Andric   unsigned Pos = 0;
1066*0b57cec5SDimitry Andric 
1067*0b57cec5SDimitry Andric   switch (MI.getOpcode()) {
1068*0b57cec5SDimitry Andric     case Mips::DEXT:
1069*0b57cec5SDimitry Andric       Pos = Lsb;
1070*0b57cec5SDimitry Andric       Size = Msbd + 1;
1071*0b57cec5SDimitry Andric       break;
1072*0b57cec5SDimitry Andric     case Mips::DEXTM:
1073*0b57cec5SDimitry Andric       Pos = Lsb;
1074*0b57cec5SDimitry Andric       Size = Msbd + 1 + 32;
1075*0b57cec5SDimitry Andric       break;
1076*0b57cec5SDimitry Andric     case Mips::DEXTU:
1077*0b57cec5SDimitry Andric       Pos = Lsb + 32;
1078*0b57cec5SDimitry Andric       Size = Msbd + 1;
1079*0b57cec5SDimitry Andric       break;
1080*0b57cec5SDimitry Andric     default:
1081*0b57cec5SDimitry Andric       llvm_unreachable("Unknown DEXT instruction!");
1082*0b57cec5SDimitry Andric   }
1083*0b57cec5SDimitry Andric 
1084*0b57cec5SDimitry Andric   MI.setOpcode(Mips::DEXT);
1085*0b57cec5SDimitry Andric 
1086*0b57cec5SDimitry Andric   InsnType Rs = fieldFromInstruction(Insn, 21, 5);
1087*0b57cec5SDimitry Andric   InsnType Rt = fieldFromInstruction(Insn, 16, 5);
1088*0b57cec5SDimitry Andric 
1089*0b57cec5SDimitry Andric   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID, Rt)));
1090*0b57cec5SDimitry Andric   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID, Rs)));
1091*0b57cec5SDimitry Andric   MI.addOperand(MCOperand::createImm(Pos));
1092*0b57cec5SDimitry Andric   MI.addOperand(MCOperand::createImm(Size));
1093*0b57cec5SDimitry Andric 
1094*0b57cec5SDimitry Andric   return MCDisassembler::Success;
1095*0b57cec5SDimitry Andric }
1096*0b57cec5SDimitry Andric 
1097*0b57cec5SDimitry Andric // Override the generated disassembler to produce DINS all the time. This is
1098*0b57cec5SDimitry Andric // for feature / behaviour parity with binutils.
1099*0b57cec5SDimitry Andric template <typename InsnType>
1100*0b57cec5SDimitry Andric static DecodeStatus DecodeDINS(MCInst &MI, InsnType Insn, uint64_t Address,
1101*0b57cec5SDimitry Andric                                const void *Decoder) {
1102*0b57cec5SDimitry Andric   unsigned Msbd = fieldFromInstruction(Insn, 11, 5);
1103*0b57cec5SDimitry Andric   unsigned Lsb = fieldFromInstruction(Insn, 6, 5);
1104*0b57cec5SDimitry Andric   unsigned Size = 0;
1105*0b57cec5SDimitry Andric   unsigned Pos = 0;
1106*0b57cec5SDimitry Andric 
1107*0b57cec5SDimitry Andric   switch (MI.getOpcode()) {
1108*0b57cec5SDimitry Andric     case Mips::DINS:
1109*0b57cec5SDimitry Andric       Pos = Lsb;
1110*0b57cec5SDimitry Andric       Size = Msbd + 1 - Pos;
1111*0b57cec5SDimitry Andric       break;
1112*0b57cec5SDimitry Andric     case Mips::DINSM:
1113*0b57cec5SDimitry Andric       Pos = Lsb;
1114*0b57cec5SDimitry Andric       Size = Msbd + 33 - Pos;
1115*0b57cec5SDimitry Andric       break;
1116*0b57cec5SDimitry Andric     case Mips::DINSU:
1117*0b57cec5SDimitry Andric       Pos = Lsb + 32;
1118*0b57cec5SDimitry Andric       // mbsd = pos + size - 33
1119*0b57cec5SDimitry Andric       // mbsd - pos + 33 = size
1120*0b57cec5SDimitry Andric       Size = Msbd + 33 - Pos;
1121*0b57cec5SDimitry Andric       break;
1122*0b57cec5SDimitry Andric     default:
1123*0b57cec5SDimitry Andric       llvm_unreachable("Unknown DINS instruction!");
1124*0b57cec5SDimitry Andric   }
1125*0b57cec5SDimitry Andric 
1126*0b57cec5SDimitry Andric   InsnType Rs = fieldFromInstruction(Insn, 21, 5);
1127*0b57cec5SDimitry Andric   InsnType Rt = fieldFromInstruction(Insn, 16, 5);
1128*0b57cec5SDimitry Andric 
1129*0b57cec5SDimitry Andric   MI.setOpcode(Mips::DINS);
1130*0b57cec5SDimitry Andric   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID, Rt)));
1131*0b57cec5SDimitry Andric   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID, Rs)));
1132*0b57cec5SDimitry Andric   MI.addOperand(MCOperand::createImm(Pos));
1133*0b57cec5SDimitry Andric   MI.addOperand(MCOperand::createImm(Size));
1134*0b57cec5SDimitry Andric 
1135*0b57cec5SDimitry Andric   return MCDisassembler::Success;
1136*0b57cec5SDimitry Andric }
1137*0b57cec5SDimitry Andric 
1138*0b57cec5SDimitry Andric // Auto-generated decoder wouldn't add the third operand for CRC32*.
1139*0b57cec5SDimitry Andric template <typename InsnType>
1140*0b57cec5SDimitry Andric static DecodeStatus DecodeCRC(MCInst &MI, InsnType Insn, uint64_t Address,
1141*0b57cec5SDimitry Andric                               const void *Decoder) {
1142*0b57cec5SDimitry Andric   InsnType Rs = fieldFromInstruction(Insn, 21, 5);
1143*0b57cec5SDimitry Andric   InsnType Rt = fieldFromInstruction(Insn, 16, 5);
1144*0b57cec5SDimitry Andric   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
1145*0b57cec5SDimitry Andric                                      Rt)));
1146*0b57cec5SDimitry Andric   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
1147*0b57cec5SDimitry Andric                                      Rs)));
1148*0b57cec5SDimitry Andric   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
1149*0b57cec5SDimitry Andric                                      Rt)));
1150*0b57cec5SDimitry Andric   return MCDisassembler::Success;
1151*0b57cec5SDimitry Andric }
1152*0b57cec5SDimitry Andric 
1153*0b57cec5SDimitry Andric /// Read two bytes from the ArrayRef and return 16 bit halfword sorted
1154*0b57cec5SDimitry Andric /// according to the given endianness.
1155*0b57cec5SDimitry Andric static DecodeStatus readInstruction16(ArrayRef<uint8_t> Bytes, uint64_t Address,
1156*0b57cec5SDimitry Andric                                       uint64_t &Size, uint32_t &Insn,
1157*0b57cec5SDimitry Andric                                       bool IsBigEndian) {
1158*0b57cec5SDimitry Andric   // We want to read exactly 2 Bytes of data.
1159*0b57cec5SDimitry Andric   if (Bytes.size() < 2) {
1160*0b57cec5SDimitry Andric     Size = 0;
1161*0b57cec5SDimitry Andric     return MCDisassembler::Fail;
1162*0b57cec5SDimitry Andric   }
1163*0b57cec5SDimitry Andric 
1164*0b57cec5SDimitry Andric   if (IsBigEndian) {
1165*0b57cec5SDimitry Andric     Insn = (Bytes[0] << 8) | Bytes[1];
1166*0b57cec5SDimitry Andric   } else {
1167*0b57cec5SDimitry Andric     Insn = (Bytes[1] << 8) | Bytes[0];
1168*0b57cec5SDimitry Andric   }
1169*0b57cec5SDimitry Andric 
1170*0b57cec5SDimitry Andric   return MCDisassembler::Success;
1171*0b57cec5SDimitry Andric }
1172*0b57cec5SDimitry Andric 
1173*0b57cec5SDimitry Andric /// Read four bytes from the ArrayRef and return 32 bit word sorted
1174*0b57cec5SDimitry Andric /// according to the given endianness.
1175*0b57cec5SDimitry Andric static DecodeStatus readInstruction32(ArrayRef<uint8_t> Bytes, uint64_t Address,
1176*0b57cec5SDimitry Andric                                       uint64_t &Size, uint32_t &Insn,
1177*0b57cec5SDimitry Andric                                       bool IsBigEndian, bool IsMicroMips) {
1178*0b57cec5SDimitry Andric   // We want to read exactly 4 Bytes of data.
1179*0b57cec5SDimitry Andric   if (Bytes.size() < 4) {
1180*0b57cec5SDimitry Andric     Size = 0;
1181*0b57cec5SDimitry Andric     return MCDisassembler::Fail;
1182*0b57cec5SDimitry Andric   }
1183*0b57cec5SDimitry Andric 
1184*0b57cec5SDimitry Andric   // High 16 bits of a 32-bit microMIPS instruction (where the opcode is)
1185*0b57cec5SDimitry Andric   // always precede the low 16 bits in the instruction stream (that is, they
1186*0b57cec5SDimitry Andric   // are placed at lower addresses in the instruction stream).
1187*0b57cec5SDimitry Andric   //
1188*0b57cec5SDimitry Andric   // microMIPS byte ordering:
1189*0b57cec5SDimitry Andric   //   Big-endian:    0 | 1 | 2 | 3
1190*0b57cec5SDimitry Andric   //   Little-endian: 1 | 0 | 3 | 2
1191*0b57cec5SDimitry Andric 
1192*0b57cec5SDimitry Andric   if (IsBigEndian) {
1193*0b57cec5SDimitry Andric     // Encoded as a big-endian 32-bit word in the stream.
1194*0b57cec5SDimitry Andric     Insn =
1195*0b57cec5SDimitry Andric         (Bytes[3] << 0) | (Bytes[2] << 8) | (Bytes[1] << 16) | (Bytes[0] << 24);
1196*0b57cec5SDimitry Andric   } else {
1197*0b57cec5SDimitry Andric     if (IsMicroMips) {
1198*0b57cec5SDimitry Andric       Insn = (Bytes[2] << 0) | (Bytes[3] << 8) | (Bytes[0] << 16) |
1199*0b57cec5SDimitry Andric              (Bytes[1] << 24);
1200*0b57cec5SDimitry Andric     } else {
1201*0b57cec5SDimitry Andric       Insn = (Bytes[0] << 0) | (Bytes[1] << 8) | (Bytes[2] << 16) |
1202*0b57cec5SDimitry Andric              (Bytes[3] << 24);
1203*0b57cec5SDimitry Andric     }
1204*0b57cec5SDimitry Andric   }
1205*0b57cec5SDimitry Andric 
1206*0b57cec5SDimitry Andric   return MCDisassembler::Success;
1207*0b57cec5SDimitry Andric }
1208*0b57cec5SDimitry Andric 
1209*0b57cec5SDimitry Andric DecodeStatus MipsDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,
1210*0b57cec5SDimitry Andric                                               ArrayRef<uint8_t> Bytes,
1211*0b57cec5SDimitry Andric                                               uint64_t Address,
1212*0b57cec5SDimitry Andric                                               raw_ostream &VStream,
1213*0b57cec5SDimitry Andric                                               raw_ostream &CStream) const {
1214*0b57cec5SDimitry Andric   uint32_t Insn;
1215*0b57cec5SDimitry Andric   DecodeStatus Result;
1216*0b57cec5SDimitry Andric   Size = 0;
1217*0b57cec5SDimitry Andric 
1218*0b57cec5SDimitry Andric   if (IsMicroMips) {
1219*0b57cec5SDimitry Andric     Result = readInstruction16(Bytes, Address, Size, Insn, IsBigEndian);
1220*0b57cec5SDimitry Andric     if (Result == MCDisassembler::Fail)
1221*0b57cec5SDimitry Andric       return MCDisassembler::Fail;
1222*0b57cec5SDimitry Andric 
1223*0b57cec5SDimitry Andric     if (hasMips32r6()) {
1224*0b57cec5SDimitry Andric       LLVM_DEBUG(
1225*0b57cec5SDimitry Andric           dbgs() << "Trying MicroMipsR616 table (16-bit instructions):\n");
1226*0b57cec5SDimitry Andric       // Calling the auto-generated decoder function for microMIPS32R6
1227*0b57cec5SDimitry Andric       // 16-bit instructions.
1228*0b57cec5SDimitry Andric       Result = decodeInstruction(DecoderTableMicroMipsR616, Instr, Insn,
1229*0b57cec5SDimitry Andric                                  Address, this, STI);
1230*0b57cec5SDimitry Andric       if (Result != MCDisassembler::Fail) {
1231*0b57cec5SDimitry Andric         Size = 2;
1232*0b57cec5SDimitry Andric         return Result;
1233*0b57cec5SDimitry Andric       }
1234*0b57cec5SDimitry Andric     }
1235*0b57cec5SDimitry Andric 
1236*0b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "Trying MicroMips16 table (16-bit instructions):\n");
1237*0b57cec5SDimitry Andric     // Calling the auto-generated decoder function for microMIPS 16-bit
1238*0b57cec5SDimitry Andric     // instructions.
1239*0b57cec5SDimitry Andric     Result = decodeInstruction(DecoderTableMicroMips16, Instr, Insn, Address,
1240*0b57cec5SDimitry Andric                                this, STI);
1241*0b57cec5SDimitry Andric     if (Result != MCDisassembler::Fail) {
1242*0b57cec5SDimitry Andric       Size = 2;
1243*0b57cec5SDimitry Andric       return Result;
1244*0b57cec5SDimitry Andric     }
1245*0b57cec5SDimitry Andric 
1246*0b57cec5SDimitry Andric     Result = readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, true);
1247*0b57cec5SDimitry Andric     if (Result == MCDisassembler::Fail)
1248*0b57cec5SDimitry Andric       return MCDisassembler::Fail;
1249*0b57cec5SDimitry Andric 
1250*0b57cec5SDimitry Andric     if (hasMips32r6()) {
1251*0b57cec5SDimitry Andric       LLVM_DEBUG(
1252*0b57cec5SDimitry Andric           dbgs() << "Trying MicroMips32r632 table (32-bit instructions):\n");
1253*0b57cec5SDimitry Andric       // Calling the auto-generated decoder function.
1254*0b57cec5SDimitry Andric       Result = decodeInstruction(DecoderTableMicroMipsR632, Instr, Insn, Address,
1255*0b57cec5SDimitry Andric                                  this, STI);
1256*0b57cec5SDimitry Andric       if (Result != MCDisassembler::Fail) {
1257*0b57cec5SDimitry Andric         Size = 4;
1258*0b57cec5SDimitry Andric         return Result;
1259*0b57cec5SDimitry Andric       }
1260*0b57cec5SDimitry Andric     }
1261*0b57cec5SDimitry Andric 
1262*0b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "Trying MicroMips32 table (32-bit instructions):\n");
1263*0b57cec5SDimitry Andric     // Calling the auto-generated decoder function.
1264*0b57cec5SDimitry Andric     Result = decodeInstruction(DecoderTableMicroMips32, Instr, Insn, Address,
1265*0b57cec5SDimitry Andric                                this, STI);
1266*0b57cec5SDimitry Andric     if (Result != MCDisassembler::Fail) {
1267*0b57cec5SDimitry Andric       Size = 4;
1268*0b57cec5SDimitry Andric       return Result;
1269*0b57cec5SDimitry Andric     }
1270*0b57cec5SDimitry Andric 
1271*0b57cec5SDimitry Andric     if (isFP64()) {
1272*0b57cec5SDimitry Andric       LLVM_DEBUG(dbgs() << "Trying MicroMipsFP64 table (32-bit opcodes):\n");
1273*0b57cec5SDimitry Andric       Result = decodeInstruction(DecoderTableMicroMipsFP6432, Instr, Insn,
1274*0b57cec5SDimitry Andric                                  Address, this, STI);
1275*0b57cec5SDimitry Andric       if (Result != MCDisassembler::Fail) {
1276*0b57cec5SDimitry Andric         Size = 4;
1277*0b57cec5SDimitry Andric         return Result;
1278*0b57cec5SDimitry Andric       }
1279*0b57cec5SDimitry Andric     }
1280*0b57cec5SDimitry Andric 
1281*0b57cec5SDimitry Andric     // This is an invalid instruction. Claim that the Size is 2 bytes. Since
1282*0b57cec5SDimitry Andric     // microMIPS instructions have a minimum alignment of 2, the next 2 bytes
1283*0b57cec5SDimitry Andric     // could form a valid instruction. The two bytes we rejected as an
1284*0b57cec5SDimitry Andric     // instruction could have actually beeen an inline constant pool that is
1285*0b57cec5SDimitry Andric     // unconditionally branched over.
1286*0b57cec5SDimitry Andric     Size = 2;
1287*0b57cec5SDimitry Andric     return MCDisassembler::Fail;
1288*0b57cec5SDimitry Andric   }
1289*0b57cec5SDimitry Andric 
1290*0b57cec5SDimitry Andric   // Attempt to read the instruction so that we can attempt to decode it. If
1291*0b57cec5SDimitry Andric   // the buffer is not 4 bytes long, let the higher level logic figure out
1292*0b57cec5SDimitry Andric   // what to do with a size of zero and MCDisassembler::Fail.
1293*0b57cec5SDimitry Andric   Result = readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, false);
1294*0b57cec5SDimitry Andric   if (Result == MCDisassembler::Fail)
1295*0b57cec5SDimitry Andric     return MCDisassembler::Fail;
1296*0b57cec5SDimitry Andric 
1297*0b57cec5SDimitry Andric   // The only instruction size for standard encoded MIPS.
1298*0b57cec5SDimitry Andric   Size = 4;
1299*0b57cec5SDimitry Andric 
1300*0b57cec5SDimitry Andric   if (hasCOP3()) {
1301*0b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "Trying COP3_ table (32-bit opcodes):\n");
1302*0b57cec5SDimitry Andric     Result =
1303*0b57cec5SDimitry Andric         decodeInstruction(DecoderTableCOP3_32, Instr, Insn, Address, this, STI);
1304*0b57cec5SDimitry Andric     if (Result != MCDisassembler::Fail)
1305*0b57cec5SDimitry Andric       return Result;
1306*0b57cec5SDimitry Andric   }
1307*0b57cec5SDimitry Andric 
1308*0b57cec5SDimitry Andric   if (hasMips32r6() && isGP64()) {
1309*0b57cec5SDimitry Andric     LLVM_DEBUG(
1310*0b57cec5SDimitry Andric         dbgs() << "Trying Mips32r6_64r6 (GPR64) table (32-bit opcodes):\n");
1311*0b57cec5SDimitry Andric     Result = decodeInstruction(DecoderTableMips32r6_64r6_GP6432, Instr, Insn,
1312*0b57cec5SDimitry Andric                                Address, this, STI);
1313*0b57cec5SDimitry Andric     if (Result != MCDisassembler::Fail)
1314*0b57cec5SDimitry Andric       return Result;
1315*0b57cec5SDimitry Andric   }
1316*0b57cec5SDimitry Andric 
1317*0b57cec5SDimitry Andric   if (hasMips32r6() && isPTR64()) {
1318*0b57cec5SDimitry Andric     LLVM_DEBUG(
1319*0b57cec5SDimitry Andric         dbgs() << "Trying Mips32r6_64r6 (PTR64) table (32-bit opcodes):\n");
1320*0b57cec5SDimitry Andric     Result = decodeInstruction(DecoderTableMips32r6_64r6_PTR6432, Instr, Insn,
1321*0b57cec5SDimitry Andric                                Address, this, STI);
1322*0b57cec5SDimitry Andric     if (Result != MCDisassembler::Fail)
1323*0b57cec5SDimitry Andric       return Result;
1324*0b57cec5SDimitry Andric   }
1325*0b57cec5SDimitry Andric 
1326*0b57cec5SDimitry Andric   if (hasMips32r6()) {
1327*0b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "Trying Mips32r6_64r6 table (32-bit opcodes):\n");
1328*0b57cec5SDimitry Andric     Result = decodeInstruction(DecoderTableMips32r6_64r632, Instr, Insn,
1329*0b57cec5SDimitry Andric                                Address, this, STI);
1330*0b57cec5SDimitry Andric     if (Result != MCDisassembler::Fail)
1331*0b57cec5SDimitry Andric       return Result;
1332*0b57cec5SDimitry Andric   }
1333*0b57cec5SDimitry Andric 
1334*0b57cec5SDimitry Andric   if (hasMips2() && isPTR64()) {
1335*0b57cec5SDimitry Andric     LLVM_DEBUG(
1336*0b57cec5SDimitry Andric         dbgs() << "Trying Mips32r6_64r6 (PTR64) table (32-bit opcodes):\n");
1337*0b57cec5SDimitry Andric     Result = decodeInstruction(DecoderTableMips32_64_PTR6432, Instr, Insn,
1338*0b57cec5SDimitry Andric                                Address, this, STI);
1339*0b57cec5SDimitry Andric     if (Result != MCDisassembler::Fail)
1340*0b57cec5SDimitry Andric       return Result;
1341*0b57cec5SDimitry Andric   }
1342*0b57cec5SDimitry Andric 
1343*0b57cec5SDimitry Andric   if (hasCnMips()) {
1344*0b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "Trying CnMips table (32-bit opcodes):\n");
1345*0b57cec5SDimitry Andric     Result = decodeInstruction(DecoderTableCnMips32, Instr, Insn,
1346*0b57cec5SDimitry Andric                                Address, this, STI);
1347*0b57cec5SDimitry Andric     if (Result != MCDisassembler::Fail)
1348*0b57cec5SDimitry Andric       return Result;
1349*0b57cec5SDimitry Andric   }
1350*0b57cec5SDimitry Andric 
1351*0b57cec5SDimitry Andric   if (hasCnMipsP()) {
1352*0b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "Trying CnMipsP table (32-bit opcodes):\n");
1353*0b57cec5SDimitry Andric     Result = decodeInstruction(DecoderTableCnMipsP32, Instr, Insn,
1354*0b57cec5SDimitry Andric                                Address, this, STI);
1355*0b57cec5SDimitry Andric     if (Result != MCDisassembler::Fail)
1356*0b57cec5SDimitry Andric       return Result;
1357*0b57cec5SDimitry Andric   }
1358*0b57cec5SDimitry Andric 
1359*0b57cec5SDimitry Andric   if (isGP64()) {
1360*0b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "Trying Mips64 (GPR64) table (32-bit opcodes):\n");
1361*0b57cec5SDimitry Andric     Result = decodeInstruction(DecoderTableMips6432, Instr, Insn,
1362*0b57cec5SDimitry Andric                                Address, this, STI);
1363*0b57cec5SDimitry Andric     if (Result != MCDisassembler::Fail)
1364*0b57cec5SDimitry Andric       return Result;
1365*0b57cec5SDimitry Andric   }
1366*0b57cec5SDimitry Andric 
1367*0b57cec5SDimitry Andric   if (isFP64()) {
1368*0b57cec5SDimitry Andric     LLVM_DEBUG(
1369*0b57cec5SDimitry Andric         dbgs() << "Trying MipsFP64 (64 bit FPU) table (32-bit opcodes):\n");
1370*0b57cec5SDimitry Andric     Result = decodeInstruction(DecoderTableMipsFP6432, Instr, Insn,
1371*0b57cec5SDimitry Andric                                Address, this, STI);
1372*0b57cec5SDimitry Andric     if (Result != MCDisassembler::Fail)
1373*0b57cec5SDimitry Andric       return Result;
1374*0b57cec5SDimitry Andric   }
1375*0b57cec5SDimitry Andric 
1376*0b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "Trying Mips table (32-bit opcodes):\n");
1377*0b57cec5SDimitry Andric   // Calling the auto-generated decoder function.
1378*0b57cec5SDimitry Andric   Result =
1379*0b57cec5SDimitry Andric       decodeInstruction(DecoderTableMips32, Instr, Insn, Address, this, STI);
1380*0b57cec5SDimitry Andric   if (Result != MCDisassembler::Fail)
1381*0b57cec5SDimitry Andric     return Result;
1382*0b57cec5SDimitry Andric 
1383*0b57cec5SDimitry Andric   return MCDisassembler::Fail;
1384*0b57cec5SDimitry Andric }
1385*0b57cec5SDimitry Andric 
1386*0b57cec5SDimitry Andric static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst,
1387*0b57cec5SDimitry Andric                                                  unsigned RegNo,
1388*0b57cec5SDimitry Andric                                                  uint64_t Address,
1389*0b57cec5SDimitry Andric                                                  const void *Decoder) {
1390*0b57cec5SDimitry Andric   return MCDisassembler::Fail;
1391*0b57cec5SDimitry Andric }
1392*0b57cec5SDimitry Andric 
1393*0b57cec5SDimitry Andric static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst,
1394*0b57cec5SDimitry Andric                                              unsigned RegNo,
1395*0b57cec5SDimitry Andric                                              uint64_t Address,
1396*0b57cec5SDimitry Andric                                              const void *Decoder) {
1397*0b57cec5SDimitry Andric   if (RegNo > 31)
1398*0b57cec5SDimitry Andric     return MCDisassembler::Fail;
1399*0b57cec5SDimitry Andric 
1400*0b57cec5SDimitry Andric   unsigned Reg = getReg(Decoder, Mips::GPR64RegClassID, RegNo);
1401*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
1402*0b57cec5SDimitry Andric   return MCDisassembler::Success;
1403*0b57cec5SDimitry Andric }
1404*0b57cec5SDimitry Andric 
1405*0b57cec5SDimitry Andric static DecodeStatus DecodeGPRMM16RegisterClass(MCInst &Inst,
1406*0b57cec5SDimitry Andric                                                unsigned RegNo,
1407*0b57cec5SDimitry Andric                                                uint64_t Address,
1408*0b57cec5SDimitry Andric                                                const void *Decoder) {
1409*0b57cec5SDimitry Andric   if (RegNo > 7)
1410*0b57cec5SDimitry Andric     return MCDisassembler::Fail;
1411*0b57cec5SDimitry Andric   unsigned Reg = getReg(Decoder, Mips::GPRMM16RegClassID, RegNo);
1412*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
1413*0b57cec5SDimitry Andric   return MCDisassembler::Success;
1414*0b57cec5SDimitry Andric }
1415*0b57cec5SDimitry Andric 
1416*0b57cec5SDimitry Andric static DecodeStatus DecodeGPRMM16ZeroRegisterClass(MCInst &Inst,
1417*0b57cec5SDimitry Andric                                                    unsigned RegNo,
1418*0b57cec5SDimitry Andric                                                    uint64_t Address,
1419*0b57cec5SDimitry Andric                                                    const void *Decoder) {
1420*0b57cec5SDimitry Andric   if (RegNo > 7)
1421*0b57cec5SDimitry Andric     return MCDisassembler::Fail;
1422*0b57cec5SDimitry Andric   unsigned Reg = getReg(Decoder, Mips::GPRMM16ZeroRegClassID, RegNo);
1423*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
1424*0b57cec5SDimitry Andric   return MCDisassembler::Success;
1425*0b57cec5SDimitry Andric }
1426*0b57cec5SDimitry Andric 
1427*0b57cec5SDimitry Andric static DecodeStatus DecodeGPRMM16MovePRegisterClass(MCInst &Inst,
1428*0b57cec5SDimitry Andric                                                     unsigned RegNo,
1429*0b57cec5SDimitry Andric                                                     uint64_t Address,
1430*0b57cec5SDimitry Andric                                                     const void *Decoder) {
1431*0b57cec5SDimitry Andric   if (RegNo > 7)
1432*0b57cec5SDimitry Andric     return MCDisassembler::Fail;
1433*0b57cec5SDimitry Andric   unsigned Reg = getReg(Decoder, Mips::GPRMM16MovePRegClassID, RegNo);
1434*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
1435*0b57cec5SDimitry Andric   return MCDisassembler::Success;
1436*0b57cec5SDimitry Andric }
1437*0b57cec5SDimitry Andric 
1438*0b57cec5SDimitry Andric static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst,
1439*0b57cec5SDimitry Andric                                              unsigned RegNo,
1440*0b57cec5SDimitry Andric                                              uint64_t Address,
1441*0b57cec5SDimitry Andric                                              const void *Decoder) {
1442*0b57cec5SDimitry Andric   if (RegNo > 31)
1443*0b57cec5SDimitry Andric     return MCDisassembler::Fail;
1444*0b57cec5SDimitry Andric   unsigned Reg = getReg(Decoder, Mips::GPR32RegClassID, RegNo);
1445*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
1446*0b57cec5SDimitry Andric   return MCDisassembler::Success;
1447*0b57cec5SDimitry Andric }
1448*0b57cec5SDimitry Andric 
1449*0b57cec5SDimitry Andric static DecodeStatus DecodePtrRegisterClass(MCInst &Inst,
1450*0b57cec5SDimitry Andric                                            unsigned RegNo,
1451*0b57cec5SDimitry Andric                                            uint64_t Address,
1452*0b57cec5SDimitry Andric                                            const void *Decoder) {
1453*0b57cec5SDimitry Andric   if (static_cast<const MipsDisassembler *>(Decoder)->isGP64())
1454*0b57cec5SDimitry Andric     return DecodeGPR64RegisterClass(Inst, RegNo, Address, Decoder);
1455*0b57cec5SDimitry Andric 
1456*0b57cec5SDimitry Andric   return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
1457*0b57cec5SDimitry Andric }
1458*0b57cec5SDimitry Andric 
1459*0b57cec5SDimitry Andric static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst,
1460*0b57cec5SDimitry Andric                                             unsigned RegNo,
1461*0b57cec5SDimitry Andric                                             uint64_t Address,
1462*0b57cec5SDimitry Andric                                             const void *Decoder) {
1463*0b57cec5SDimitry Andric   return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
1464*0b57cec5SDimitry Andric }
1465*0b57cec5SDimitry Andric 
1466*0b57cec5SDimitry Andric static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
1467*0b57cec5SDimitry Andric                                              unsigned RegNo,
1468*0b57cec5SDimitry Andric                                              uint64_t Address,
1469*0b57cec5SDimitry Andric                                              const void *Decoder) {
1470*0b57cec5SDimitry Andric   if (RegNo > 31)
1471*0b57cec5SDimitry Andric     return MCDisassembler::Fail;
1472*0b57cec5SDimitry Andric 
1473*0b57cec5SDimitry Andric   unsigned Reg = getReg(Decoder, Mips::FGR64RegClassID, RegNo);
1474*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
1475*0b57cec5SDimitry Andric   return MCDisassembler::Success;
1476*0b57cec5SDimitry Andric }
1477*0b57cec5SDimitry Andric 
1478*0b57cec5SDimitry Andric static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
1479*0b57cec5SDimitry Andric                                              unsigned RegNo,
1480*0b57cec5SDimitry Andric                                              uint64_t Address,
1481*0b57cec5SDimitry Andric                                              const void *Decoder) {
1482*0b57cec5SDimitry Andric   if (RegNo > 31)
1483*0b57cec5SDimitry Andric     return MCDisassembler::Fail;
1484*0b57cec5SDimitry Andric 
1485*0b57cec5SDimitry Andric   unsigned Reg = getReg(Decoder, Mips::FGR32RegClassID, RegNo);
1486*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
1487*0b57cec5SDimitry Andric   return MCDisassembler::Success;
1488*0b57cec5SDimitry Andric }
1489*0b57cec5SDimitry Andric 
1490*0b57cec5SDimitry Andric static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
1491*0b57cec5SDimitry Andric                                            unsigned RegNo,
1492*0b57cec5SDimitry Andric                                            uint64_t Address,
1493*0b57cec5SDimitry Andric                                            const void *Decoder) {
1494*0b57cec5SDimitry Andric   if (RegNo > 31)
1495*0b57cec5SDimitry Andric     return MCDisassembler::Fail;
1496*0b57cec5SDimitry Andric   unsigned Reg = getReg(Decoder, Mips::CCRRegClassID, RegNo);
1497*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
1498*0b57cec5SDimitry Andric   return MCDisassembler::Success;
1499*0b57cec5SDimitry Andric }
1500*0b57cec5SDimitry Andric 
1501*0b57cec5SDimitry Andric static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst,
1502*0b57cec5SDimitry Andric                                            unsigned RegNo,
1503*0b57cec5SDimitry Andric                                            uint64_t Address,
1504*0b57cec5SDimitry Andric                                            const void *Decoder) {
1505*0b57cec5SDimitry Andric   if (RegNo > 7)
1506*0b57cec5SDimitry Andric     return MCDisassembler::Fail;
1507*0b57cec5SDimitry Andric   unsigned Reg = getReg(Decoder, Mips::FCCRegClassID, RegNo);
1508*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
1509*0b57cec5SDimitry Andric   return MCDisassembler::Success;
1510*0b57cec5SDimitry Andric }
1511*0b57cec5SDimitry Andric 
1512*0b57cec5SDimitry Andric static DecodeStatus DecodeFGRCCRegisterClass(MCInst &Inst, unsigned RegNo,
1513*0b57cec5SDimitry Andric                                              uint64_t Address,
1514*0b57cec5SDimitry Andric                                              const void *Decoder) {
1515*0b57cec5SDimitry Andric   if (RegNo > 31)
1516*0b57cec5SDimitry Andric     return MCDisassembler::Fail;
1517*0b57cec5SDimitry Andric 
1518*0b57cec5SDimitry Andric   unsigned Reg = getReg(Decoder, Mips::FGRCCRegClassID, RegNo);
1519*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
1520*0b57cec5SDimitry Andric   return MCDisassembler::Success;
1521*0b57cec5SDimitry Andric }
1522*0b57cec5SDimitry Andric 
1523*0b57cec5SDimitry Andric static DecodeStatus DecodeMem(MCInst &Inst,
1524*0b57cec5SDimitry Andric                               unsigned Insn,
1525*0b57cec5SDimitry Andric                               uint64_t Address,
1526*0b57cec5SDimitry Andric                               const void *Decoder) {
1527*0b57cec5SDimitry Andric   int Offset = SignExtend32<16>(Insn & 0xffff);
1528*0b57cec5SDimitry Andric   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1529*0b57cec5SDimitry Andric   unsigned Base = fieldFromInstruction(Insn, 21, 5);
1530*0b57cec5SDimitry Andric 
1531*0b57cec5SDimitry Andric   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1532*0b57cec5SDimitry Andric   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1533*0b57cec5SDimitry Andric 
1534*0b57cec5SDimitry Andric   if (Inst.getOpcode() == Mips::SC ||
1535*0b57cec5SDimitry Andric       Inst.getOpcode() == Mips::SCD)
1536*0b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(Reg));
1537*0b57cec5SDimitry Andric 
1538*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
1539*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Base));
1540*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Offset));
1541*0b57cec5SDimitry Andric 
1542*0b57cec5SDimitry Andric   return MCDisassembler::Success;
1543*0b57cec5SDimitry Andric }
1544*0b57cec5SDimitry Andric 
1545*0b57cec5SDimitry Andric static DecodeStatus DecodeMemEVA(MCInst &Inst,
1546*0b57cec5SDimitry Andric                                  unsigned Insn,
1547*0b57cec5SDimitry Andric                                  uint64_t Address,
1548*0b57cec5SDimitry Andric                                  const void *Decoder) {
1549*0b57cec5SDimitry Andric   int Offset = SignExtend32<9>(Insn >> 7);
1550*0b57cec5SDimitry Andric   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1551*0b57cec5SDimitry Andric   unsigned Base = fieldFromInstruction(Insn, 21, 5);
1552*0b57cec5SDimitry Andric 
1553*0b57cec5SDimitry Andric   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1554*0b57cec5SDimitry Andric   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1555*0b57cec5SDimitry Andric 
1556*0b57cec5SDimitry Andric    if (Inst.getOpcode() == Mips::SCE)
1557*0b57cec5SDimitry Andric      Inst.addOperand(MCOperand::createReg(Reg));
1558*0b57cec5SDimitry Andric 
1559*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
1560*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Base));
1561*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Offset));
1562*0b57cec5SDimitry Andric 
1563*0b57cec5SDimitry Andric   return MCDisassembler::Success;
1564*0b57cec5SDimitry Andric }
1565*0b57cec5SDimitry Andric 
1566*0b57cec5SDimitry Andric static DecodeStatus DecodeLoadByte15(MCInst &Inst,
1567*0b57cec5SDimitry Andric                                      unsigned Insn,
1568*0b57cec5SDimitry Andric                                      uint64_t Address,
1569*0b57cec5SDimitry Andric                                      const void *Decoder) {
1570*0b57cec5SDimitry Andric   int Offset = SignExtend32<16>(Insn & 0xffff);
1571*0b57cec5SDimitry Andric   unsigned Base = fieldFromInstruction(Insn, 16, 5);
1572*0b57cec5SDimitry Andric   unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1573*0b57cec5SDimitry Andric 
1574*0b57cec5SDimitry Andric   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1575*0b57cec5SDimitry Andric   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1576*0b57cec5SDimitry Andric 
1577*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
1578*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Base));
1579*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Offset));
1580*0b57cec5SDimitry Andric 
1581*0b57cec5SDimitry Andric   return MCDisassembler::Success;
1582*0b57cec5SDimitry Andric }
1583*0b57cec5SDimitry Andric 
1584*0b57cec5SDimitry Andric static DecodeStatus DecodeCacheOp(MCInst &Inst,
1585*0b57cec5SDimitry Andric                               unsigned Insn,
1586*0b57cec5SDimitry Andric                               uint64_t Address,
1587*0b57cec5SDimitry Andric                               const void *Decoder) {
1588*0b57cec5SDimitry Andric   int Offset = SignExtend32<16>(Insn & 0xffff);
1589*0b57cec5SDimitry Andric   unsigned Hint = fieldFromInstruction(Insn, 16, 5);
1590*0b57cec5SDimitry Andric   unsigned Base = fieldFromInstruction(Insn, 21, 5);
1591*0b57cec5SDimitry Andric 
1592*0b57cec5SDimitry Andric   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1593*0b57cec5SDimitry Andric 
1594*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Base));
1595*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Offset));
1596*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Hint));
1597*0b57cec5SDimitry Andric 
1598*0b57cec5SDimitry Andric   return MCDisassembler::Success;
1599*0b57cec5SDimitry Andric }
1600*0b57cec5SDimitry Andric 
1601*0b57cec5SDimitry Andric static DecodeStatus DecodeCacheOpMM(MCInst &Inst,
1602*0b57cec5SDimitry Andric                                     unsigned Insn,
1603*0b57cec5SDimitry Andric                                     uint64_t Address,
1604*0b57cec5SDimitry Andric                                     const void *Decoder) {
1605*0b57cec5SDimitry Andric   int Offset = SignExtend32<12>(Insn & 0xfff);
1606*0b57cec5SDimitry Andric   unsigned Base = fieldFromInstruction(Insn, 16, 5);
1607*0b57cec5SDimitry Andric   unsigned Hint = fieldFromInstruction(Insn, 21, 5);
1608*0b57cec5SDimitry Andric 
1609*0b57cec5SDimitry Andric   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1610*0b57cec5SDimitry Andric 
1611*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Base));
1612*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Offset));
1613*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Hint));
1614*0b57cec5SDimitry Andric 
1615*0b57cec5SDimitry Andric   return MCDisassembler::Success;
1616*0b57cec5SDimitry Andric }
1617*0b57cec5SDimitry Andric 
1618*0b57cec5SDimitry Andric static DecodeStatus DecodePrefeOpMM(MCInst &Inst,
1619*0b57cec5SDimitry Andric                                     unsigned Insn,
1620*0b57cec5SDimitry Andric                                     uint64_t Address,
1621*0b57cec5SDimitry Andric                                     const void *Decoder) {
1622*0b57cec5SDimitry Andric   int Offset = SignExtend32<9>(Insn & 0x1ff);
1623*0b57cec5SDimitry Andric   unsigned Base = fieldFromInstruction(Insn, 16, 5);
1624*0b57cec5SDimitry Andric   unsigned Hint = fieldFromInstruction(Insn, 21, 5);
1625*0b57cec5SDimitry Andric 
1626*0b57cec5SDimitry Andric   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1627*0b57cec5SDimitry Andric 
1628*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Base));
1629*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Offset));
1630*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Hint));
1631*0b57cec5SDimitry Andric 
1632*0b57cec5SDimitry Andric   return MCDisassembler::Success;
1633*0b57cec5SDimitry Andric }
1634*0b57cec5SDimitry Andric 
1635*0b57cec5SDimitry Andric static DecodeStatus DecodeCacheeOp_CacheOpR6(MCInst &Inst,
1636*0b57cec5SDimitry Andric                                              unsigned Insn,
1637*0b57cec5SDimitry Andric                                              uint64_t Address,
1638*0b57cec5SDimitry Andric                                              const void *Decoder) {
1639*0b57cec5SDimitry Andric   int Offset = SignExtend32<9>(Insn >> 7);
1640*0b57cec5SDimitry Andric   unsigned Hint = fieldFromInstruction(Insn, 16, 5);
1641*0b57cec5SDimitry Andric   unsigned Base = fieldFromInstruction(Insn, 21, 5);
1642*0b57cec5SDimitry Andric 
1643*0b57cec5SDimitry Andric   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1644*0b57cec5SDimitry Andric 
1645*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Base));
1646*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Offset));
1647*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Hint));
1648*0b57cec5SDimitry Andric 
1649*0b57cec5SDimitry Andric   return MCDisassembler::Success;
1650*0b57cec5SDimitry Andric }
1651*0b57cec5SDimitry Andric 
1652*0b57cec5SDimitry Andric static DecodeStatus DecodeSyncI(MCInst &Inst,
1653*0b57cec5SDimitry Andric                               unsigned Insn,
1654*0b57cec5SDimitry Andric                               uint64_t Address,
1655*0b57cec5SDimitry Andric                               const void *Decoder) {
1656*0b57cec5SDimitry Andric   int Offset = SignExtend32<16>(Insn & 0xffff);
1657*0b57cec5SDimitry Andric   unsigned Base = fieldFromInstruction(Insn, 21, 5);
1658*0b57cec5SDimitry Andric 
1659*0b57cec5SDimitry Andric   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1660*0b57cec5SDimitry Andric 
1661*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Base));
1662*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Offset));
1663*0b57cec5SDimitry Andric 
1664*0b57cec5SDimitry Andric   return MCDisassembler::Success;
1665*0b57cec5SDimitry Andric }
1666*0b57cec5SDimitry Andric 
1667*0b57cec5SDimitry Andric static DecodeStatus DecodeSyncI_MM(MCInst &Inst, unsigned Insn,
1668*0b57cec5SDimitry Andric                                    uint64_t Address, const void *Decoder) {
1669*0b57cec5SDimitry Andric   int Offset = SignExtend32<16>(Insn & 0xffff);
1670*0b57cec5SDimitry Andric   unsigned Base = fieldFromInstruction(Insn, 16, 5);
1671*0b57cec5SDimitry Andric 
1672*0b57cec5SDimitry Andric   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1673*0b57cec5SDimitry Andric 
1674*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Base));
1675*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Offset));
1676*0b57cec5SDimitry Andric 
1677*0b57cec5SDimitry Andric   return MCDisassembler::Success;
1678*0b57cec5SDimitry Andric }
1679*0b57cec5SDimitry Andric 
1680*0b57cec5SDimitry Andric static DecodeStatus DecodeSynciR6(MCInst &Inst,
1681*0b57cec5SDimitry Andric                                   unsigned Insn,
1682*0b57cec5SDimitry Andric                                   uint64_t Address,
1683*0b57cec5SDimitry Andric                                   const void *Decoder) {
1684*0b57cec5SDimitry Andric   int Immediate = SignExtend32<16>(Insn & 0xffff);
1685*0b57cec5SDimitry Andric   unsigned Base = fieldFromInstruction(Insn, 16, 5);
1686*0b57cec5SDimitry Andric 
1687*0b57cec5SDimitry Andric   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1688*0b57cec5SDimitry Andric 
1689*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Base));
1690*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Immediate));
1691*0b57cec5SDimitry Andric 
1692*0b57cec5SDimitry Andric   return MCDisassembler::Success;
1693*0b57cec5SDimitry Andric }
1694*0b57cec5SDimitry Andric 
1695*0b57cec5SDimitry Andric static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn,
1696*0b57cec5SDimitry Andric                                     uint64_t Address, const void *Decoder) {
1697*0b57cec5SDimitry Andric   int Offset = SignExtend32<10>(fieldFromInstruction(Insn, 16, 10));
1698*0b57cec5SDimitry Andric   unsigned Reg = fieldFromInstruction(Insn, 6, 5);
1699*0b57cec5SDimitry Andric   unsigned Base = fieldFromInstruction(Insn, 11, 5);
1700*0b57cec5SDimitry Andric 
1701*0b57cec5SDimitry Andric   Reg = getReg(Decoder, Mips::MSA128BRegClassID, Reg);
1702*0b57cec5SDimitry Andric   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1703*0b57cec5SDimitry Andric 
1704*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
1705*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Base));
1706*0b57cec5SDimitry Andric 
1707*0b57cec5SDimitry Andric   // The immediate field of an LD/ST instruction is scaled which means it must
1708*0b57cec5SDimitry Andric   // be multiplied (when decoding) by the size (in bytes) of the instructions'
1709*0b57cec5SDimitry Andric   // data format.
1710*0b57cec5SDimitry Andric   // .b - 1 byte
1711*0b57cec5SDimitry Andric   // .h - 2 bytes
1712*0b57cec5SDimitry Andric   // .w - 4 bytes
1713*0b57cec5SDimitry Andric   // .d - 8 bytes
1714*0b57cec5SDimitry Andric   switch(Inst.getOpcode())
1715*0b57cec5SDimitry Andric   {
1716*0b57cec5SDimitry Andric   default:
1717*0b57cec5SDimitry Andric     assert(false && "Unexpected instruction");
1718*0b57cec5SDimitry Andric     return MCDisassembler::Fail;
1719*0b57cec5SDimitry Andric     break;
1720*0b57cec5SDimitry Andric   case Mips::LD_B:
1721*0b57cec5SDimitry Andric   case Mips::ST_B:
1722*0b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(Offset));
1723*0b57cec5SDimitry Andric     break;
1724*0b57cec5SDimitry Andric   case Mips::LD_H:
1725*0b57cec5SDimitry Andric   case Mips::ST_H:
1726*0b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(Offset * 2));
1727*0b57cec5SDimitry Andric     break;
1728*0b57cec5SDimitry Andric   case Mips::LD_W:
1729*0b57cec5SDimitry Andric   case Mips::ST_W:
1730*0b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(Offset * 4));
1731*0b57cec5SDimitry Andric     break;
1732*0b57cec5SDimitry Andric   case Mips::LD_D:
1733*0b57cec5SDimitry Andric   case Mips::ST_D:
1734*0b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(Offset * 8));
1735*0b57cec5SDimitry Andric     break;
1736*0b57cec5SDimitry Andric   }
1737*0b57cec5SDimitry Andric 
1738*0b57cec5SDimitry Andric   return MCDisassembler::Success;
1739*0b57cec5SDimitry Andric }
1740*0b57cec5SDimitry Andric 
1741*0b57cec5SDimitry Andric static DecodeStatus DecodeMemMMImm4(MCInst &Inst,
1742*0b57cec5SDimitry Andric                                     unsigned Insn,
1743*0b57cec5SDimitry Andric                                     uint64_t Address,
1744*0b57cec5SDimitry Andric                                     const void *Decoder) {
1745*0b57cec5SDimitry Andric   unsigned Offset = Insn & 0xf;
1746*0b57cec5SDimitry Andric   unsigned Reg = fieldFromInstruction(Insn, 7, 3);
1747*0b57cec5SDimitry Andric   unsigned Base = fieldFromInstruction(Insn, 4, 3);
1748*0b57cec5SDimitry Andric 
1749*0b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
1750*0b57cec5SDimitry Andric     case Mips::LBU16_MM:
1751*0b57cec5SDimitry Andric     case Mips::LHU16_MM:
1752*0b57cec5SDimitry Andric     case Mips::LW16_MM:
1753*0b57cec5SDimitry Andric       if (DecodeGPRMM16RegisterClass(Inst, Reg, Address, Decoder)
1754*0b57cec5SDimitry Andric             == MCDisassembler::Fail)
1755*0b57cec5SDimitry Andric         return MCDisassembler::Fail;
1756*0b57cec5SDimitry Andric       break;
1757*0b57cec5SDimitry Andric     case Mips::SB16_MM:
1758*0b57cec5SDimitry Andric     case Mips::SB16_MMR6:
1759*0b57cec5SDimitry Andric     case Mips::SH16_MM:
1760*0b57cec5SDimitry Andric     case Mips::SH16_MMR6:
1761*0b57cec5SDimitry Andric     case Mips::SW16_MM:
1762*0b57cec5SDimitry Andric     case Mips::SW16_MMR6:
1763*0b57cec5SDimitry Andric       if (DecodeGPRMM16ZeroRegisterClass(Inst, Reg, Address, Decoder)
1764*0b57cec5SDimitry Andric             == MCDisassembler::Fail)
1765*0b57cec5SDimitry Andric         return MCDisassembler::Fail;
1766*0b57cec5SDimitry Andric       break;
1767*0b57cec5SDimitry Andric   }
1768*0b57cec5SDimitry Andric 
1769*0b57cec5SDimitry Andric   if (DecodeGPRMM16RegisterClass(Inst, Base, Address, Decoder)
1770*0b57cec5SDimitry Andric         == MCDisassembler::Fail)
1771*0b57cec5SDimitry Andric     return MCDisassembler::Fail;
1772*0b57cec5SDimitry Andric 
1773*0b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
1774*0b57cec5SDimitry Andric     case Mips::LBU16_MM:
1775*0b57cec5SDimitry Andric       if (Offset == 0xf)
1776*0b57cec5SDimitry Andric         Inst.addOperand(MCOperand::createImm(-1));
1777*0b57cec5SDimitry Andric       else
1778*0b57cec5SDimitry Andric         Inst.addOperand(MCOperand::createImm(Offset));
1779*0b57cec5SDimitry Andric       break;
1780*0b57cec5SDimitry Andric     case Mips::SB16_MM:
1781*0b57cec5SDimitry Andric     case Mips::SB16_MMR6:
1782*0b57cec5SDimitry Andric       Inst.addOperand(MCOperand::createImm(Offset));
1783*0b57cec5SDimitry Andric       break;
1784*0b57cec5SDimitry Andric     case Mips::LHU16_MM:
1785*0b57cec5SDimitry Andric     case Mips::SH16_MM:
1786*0b57cec5SDimitry Andric     case Mips::SH16_MMR6:
1787*0b57cec5SDimitry Andric       Inst.addOperand(MCOperand::createImm(Offset << 1));
1788*0b57cec5SDimitry Andric       break;
1789*0b57cec5SDimitry Andric     case Mips::LW16_MM:
1790*0b57cec5SDimitry Andric     case Mips::SW16_MM:
1791*0b57cec5SDimitry Andric     case Mips::SW16_MMR6:
1792*0b57cec5SDimitry Andric       Inst.addOperand(MCOperand::createImm(Offset << 2));
1793*0b57cec5SDimitry Andric       break;
1794*0b57cec5SDimitry Andric   }
1795*0b57cec5SDimitry Andric 
1796*0b57cec5SDimitry Andric   return MCDisassembler::Success;
1797*0b57cec5SDimitry Andric }
1798*0b57cec5SDimitry Andric 
1799*0b57cec5SDimitry Andric static DecodeStatus DecodeMemMMSPImm5Lsl2(MCInst &Inst,
1800*0b57cec5SDimitry Andric                                           unsigned Insn,
1801*0b57cec5SDimitry Andric                                           uint64_t Address,
1802*0b57cec5SDimitry Andric                                           const void *Decoder) {
1803*0b57cec5SDimitry Andric   unsigned Offset = Insn & 0x1F;
1804*0b57cec5SDimitry Andric   unsigned Reg = fieldFromInstruction(Insn, 5, 5);
1805*0b57cec5SDimitry Andric 
1806*0b57cec5SDimitry Andric   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1807*0b57cec5SDimitry Andric 
1808*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
1809*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Mips::SP));
1810*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Offset << 2));
1811*0b57cec5SDimitry Andric 
1812*0b57cec5SDimitry Andric   return MCDisassembler::Success;
1813*0b57cec5SDimitry Andric }
1814*0b57cec5SDimitry Andric 
1815*0b57cec5SDimitry Andric static DecodeStatus DecodeMemMMGPImm7Lsl2(MCInst &Inst,
1816*0b57cec5SDimitry Andric                                           unsigned Insn,
1817*0b57cec5SDimitry Andric                                           uint64_t Address,
1818*0b57cec5SDimitry Andric                                           const void *Decoder) {
1819*0b57cec5SDimitry Andric   unsigned Offset = Insn & 0x7F;
1820*0b57cec5SDimitry Andric   unsigned Reg = fieldFromInstruction(Insn, 7, 3);
1821*0b57cec5SDimitry Andric 
1822*0b57cec5SDimitry Andric   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1823*0b57cec5SDimitry Andric 
1824*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
1825*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Mips::GP));
1826*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Offset << 2));
1827*0b57cec5SDimitry Andric 
1828*0b57cec5SDimitry Andric   return MCDisassembler::Success;
1829*0b57cec5SDimitry Andric }
1830*0b57cec5SDimitry Andric 
1831*0b57cec5SDimitry Andric static DecodeStatus DecodeMemMMReglistImm4Lsl2(MCInst &Inst,
1832*0b57cec5SDimitry Andric                                                unsigned Insn,
1833*0b57cec5SDimitry Andric                                                uint64_t Address,
1834*0b57cec5SDimitry Andric                                                const void *Decoder) {
1835*0b57cec5SDimitry Andric   int Offset;
1836*0b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
1837*0b57cec5SDimitry Andric   case Mips::LWM16_MMR6:
1838*0b57cec5SDimitry Andric   case Mips::SWM16_MMR6:
1839*0b57cec5SDimitry Andric     Offset = fieldFromInstruction(Insn, 4, 4);
1840*0b57cec5SDimitry Andric     break;
1841*0b57cec5SDimitry Andric   default:
1842*0b57cec5SDimitry Andric     Offset = SignExtend32<4>(Insn & 0xf);
1843*0b57cec5SDimitry Andric     break;
1844*0b57cec5SDimitry Andric   }
1845*0b57cec5SDimitry Andric 
1846*0b57cec5SDimitry Andric   if (DecodeRegListOperand16(Inst, Insn, Address, Decoder)
1847*0b57cec5SDimitry Andric       == MCDisassembler::Fail)
1848*0b57cec5SDimitry Andric     return MCDisassembler::Fail;
1849*0b57cec5SDimitry Andric 
1850*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Mips::SP));
1851*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Offset << 2));
1852*0b57cec5SDimitry Andric 
1853*0b57cec5SDimitry Andric   return MCDisassembler::Success;
1854*0b57cec5SDimitry Andric }
1855*0b57cec5SDimitry Andric 
1856*0b57cec5SDimitry Andric static DecodeStatus DecodeMemMMImm9(MCInst &Inst,
1857*0b57cec5SDimitry Andric                                     unsigned Insn,
1858*0b57cec5SDimitry Andric                                     uint64_t Address,
1859*0b57cec5SDimitry Andric                                     const void *Decoder) {
1860*0b57cec5SDimitry Andric   int Offset = SignExtend32<9>(Insn & 0x1ff);
1861*0b57cec5SDimitry Andric   unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1862*0b57cec5SDimitry Andric   unsigned Base = fieldFromInstruction(Insn, 16, 5);
1863*0b57cec5SDimitry Andric 
1864*0b57cec5SDimitry Andric   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1865*0b57cec5SDimitry Andric   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1866*0b57cec5SDimitry Andric 
1867*0b57cec5SDimitry Andric   if (Inst.getOpcode() == Mips::SCE_MM || Inst.getOpcode() == Mips::SC_MMR6)
1868*0b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(Reg));
1869*0b57cec5SDimitry Andric 
1870*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
1871*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Base));
1872*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Offset));
1873*0b57cec5SDimitry Andric 
1874*0b57cec5SDimitry Andric   return MCDisassembler::Success;
1875*0b57cec5SDimitry Andric }
1876*0b57cec5SDimitry Andric 
1877*0b57cec5SDimitry Andric static DecodeStatus DecodeMemMMImm12(MCInst &Inst,
1878*0b57cec5SDimitry Andric                                      unsigned Insn,
1879*0b57cec5SDimitry Andric                                      uint64_t Address,
1880*0b57cec5SDimitry Andric                                      const void *Decoder) {
1881*0b57cec5SDimitry Andric   int Offset = SignExtend32<12>(Insn & 0x0fff);
1882*0b57cec5SDimitry Andric   unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1883*0b57cec5SDimitry Andric   unsigned Base = fieldFromInstruction(Insn, 16, 5);
1884*0b57cec5SDimitry Andric 
1885*0b57cec5SDimitry Andric   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1886*0b57cec5SDimitry Andric   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1887*0b57cec5SDimitry Andric 
1888*0b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
1889*0b57cec5SDimitry Andric   case Mips::SWM32_MM:
1890*0b57cec5SDimitry Andric   case Mips::LWM32_MM:
1891*0b57cec5SDimitry Andric     if (DecodeRegListOperand(Inst, Insn, Address, Decoder)
1892*0b57cec5SDimitry Andric         == MCDisassembler::Fail)
1893*0b57cec5SDimitry Andric       return MCDisassembler::Fail;
1894*0b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(Base));
1895*0b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(Offset));
1896*0b57cec5SDimitry Andric     break;
1897*0b57cec5SDimitry Andric   case Mips::SC_MM:
1898*0b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(Reg));
1899*0b57cec5SDimitry Andric     LLVM_FALLTHROUGH;
1900*0b57cec5SDimitry Andric   default:
1901*0b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(Reg));
1902*0b57cec5SDimitry Andric     if (Inst.getOpcode() == Mips::LWP_MM || Inst.getOpcode() == Mips::SWP_MM)
1903*0b57cec5SDimitry Andric       Inst.addOperand(MCOperand::createReg(Reg+1));
1904*0b57cec5SDimitry Andric 
1905*0b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(Base));
1906*0b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(Offset));
1907*0b57cec5SDimitry Andric   }
1908*0b57cec5SDimitry Andric 
1909*0b57cec5SDimitry Andric   return MCDisassembler::Success;
1910*0b57cec5SDimitry Andric }
1911*0b57cec5SDimitry Andric 
1912*0b57cec5SDimitry Andric static DecodeStatus DecodeMemMMImm16(MCInst &Inst,
1913*0b57cec5SDimitry Andric                                      unsigned Insn,
1914*0b57cec5SDimitry Andric                                      uint64_t Address,
1915*0b57cec5SDimitry Andric                                      const void *Decoder) {
1916*0b57cec5SDimitry Andric   int Offset = SignExtend32<16>(Insn & 0xffff);
1917*0b57cec5SDimitry Andric   unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1918*0b57cec5SDimitry Andric   unsigned Base = fieldFromInstruction(Insn, 16, 5);
1919*0b57cec5SDimitry Andric 
1920*0b57cec5SDimitry Andric   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1921*0b57cec5SDimitry Andric   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1922*0b57cec5SDimitry Andric 
1923*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
1924*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Base));
1925*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Offset));
1926*0b57cec5SDimitry Andric 
1927*0b57cec5SDimitry Andric   return MCDisassembler::Success;
1928*0b57cec5SDimitry Andric }
1929*0b57cec5SDimitry Andric 
1930*0b57cec5SDimitry Andric static DecodeStatus DecodeFMem(MCInst &Inst,
1931*0b57cec5SDimitry Andric                                unsigned Insn,
1932*0b57cec5SDimitry Andric                                uint64_t Address,
1933*0b57cec5SDimitry Andric                                const void *Decoder) {
1934*0b57cec5SDimitry Andric   int Offset = SignExtend32<16>(Insn & 0xffff);
1935*0b57cec5SDimitry Andric   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1936*0b57cec5SDimitry Andric   unsigned Base = fieldFromInstruction(Insn, 21, 5);
1937*0b57cec5SDimitry Andric 
1938*0b57cec5SDimitry Andric   Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg);
1939*0b57cec5SDimitry Andric   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1940*0b57cec5SDimitry Andric 
1941*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
1942*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Base));
1943*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Offset));
1944*0b57cec5SDimitry Andric 
1945*0b57cec5SDimitry Andric   return MCDisassembler::Success;
1946*0b57cec5SDimitry Andric }
1947*0b57cec5SDimitry Andric 
1948*0b57cec5SDimitry Andric static DecodeStatus DecodeFMemMMR2(MCInst &Inst, unsigned Insn,
1949*0b57cec5SDimitry Andric                                    uint64_t Address, const void *Decoder) {
1950*0b57cec5SDimitry Andric   // This function is the same as DecodeFMem but with the Reg and Base fields
1951*0b57cec5SDimitry Andric   // swapped according to microMIPS spec.
1952*0b57cec5SDimitry Andric   int Offset = SignExtend32<16>(Insn & 0xffff);
1953*0b57cec5SDimitry Andric   unsigned Base = fieldFromInstruction(Insn, 16, 5);
1954*0b57cec5SDimitry Andric   unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1955*0b57cec5SDimitry Andric 
1956*0b57cec5SDimitry Andric   Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg);
1957*0b57cec5SDimitry Andric   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1958*0b57cec5SDimitry Andric 
1959*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
1960*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Base));
1961*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Offset));
1962*0b57cec5SDimitry Andric 
1963*0b57cec5SDimitry Andric   return MCDisassembler::Success;
1964*0b57cec5SDimitry Andric }
1965*0b57cec5SDimitry Andric 
1966*0b57cec5SDimitry Andric static DecodeStatus DecodeFMem2(MCInst &Inst,
1967*0b57cec5SDimitry Andric                                unsigned Insn,
1968*0b57cec5SDimitry Andric                                uint64_t Address,
1969*0b57cec5SDimitry Andric                                const void *Decoder) {
1970*0b57cec5SDimitry Andric   int Offset = SignExtend32<16>(Insn & 0xffff);
1971*0b57cec5SDimitry Andric   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1972*0b57cec5SDimitry Andric   unsigned Base = fieldFromInstruction(Insn, 21, 5);
1973*0b57cec5SDimitry Andric 
1974*0b57cec5SDimitry Andric   Reg = getReg(Decoder, Mips::COP2RegClassID, Reg);
1975*0b57cec5SDimitry Andric   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1976*0b57cec5SDimitry Andric 
1977*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
1978*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Base));
1979*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Offset));
1980*0b57cec5SDimitry Andric 
1981*0b57cec5SDimitry Andric   return MCDisassembler::Success;
1982*0b57cec5SDimitry Andric }
1983*0b57cec5SDimitry Andric 
1984*0b57cec5SDimitry Andric static DecodeStatus DecodeFMem3(MCInst &Inst,
1985*0b57cec5SDimitry Andric                                unsigned Insn,
1986*0b57cec5SDimitry Andric                                uint64_t Address,
1987*0b57cec5SDimitry Andric                                const void *Decoder) {
1988*0b57cec5SDimitry Andric   int Offset = SignExtend32<16>(Insn & 0xffff);
1989*0b57cec5SDimitry Andric   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1990*0b57cec5SDimitry Andric   unsigned Base = fieldFromInstruction(Insn, 21, 5);
1991*0b57cec5SDimitry Andric 
1992*0b57cec5SDimitry Andric   Reg = getReg(Decoder, Mips::COP3RegClassID, Reg);
1993*0b57cec5SDimitry Andric   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1994*0b57cec5SDimitry Andric 
1995*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
1996*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Base));
1997*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Offset));
1998*0b57cec5SDimitry Andric 
1999*0b57cec5SDimitry Andric   return MCDisassembler::Success;
2000*0b57cec5SDimitry Andric }
2001*0b57cec5SDimitry Andric 
2002*0b57cec5SDimitry Andric static DecodeStatus DecodeFMemCop2R6(MCInst &Inst,
2003*0b57cec5SDimitry Andric                                     unsigned Insn,
2004*0b57cec5SDimitry Andric                                     uint64_t Address,
2005*0b57cec5SDimitry Andric                                     const void *Decoder) {
2006*0b57cec5SDimitry Andric   int Offset = SignExtend32<11>(Insn & 0x07ff);
2007*0b57cec5SDimitry Andric   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
2008*0b57cec5SDimitry Andric   unsigned Base = fieldFromInstruction(Insn, 11, 5);
2009*0b57cec5SDimitry Andric 
2010*0b57cec5SDimitry Andric   Reg = getReg(Decoder, Mips::COP2RegClassID, Reg);
2011*0b57cec5SDimitry Andric   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
2012*0b57cec5SDimitry Andric 
2013*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
2014*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Base));
2015*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Offset));
2016*0b57cec5SDimitry Andric 
2017*0b57cec5SDimitry Andric   return MCDisassembler::Success;
2018*0b57cec5SDimitry Andric }
2019*0b57cec5SDimitry Andric 
2020*0b57cec5SDimitry Andric static DecodeStatus DecodeFMemCop2MMR6(MCInst &Inst, unsigned Insn,
2021*0b57cec5SDimitry Andric                                        uint64_t Address, const void *Decoder) {
2022*0b57cec5SDimitry Andric   int Offset = SignExtend32<11>(Insn & 0x07ff);
2023*0b57cec5SDimitry Andric   unsigned Reg = fieldFromInstruction(Insn, 21, 5);
2024*0b57cec5SDimitry Andric   unsigned Base = fieldFromInstruction(Insn, 16, 5);
2025*0b57cec5SDimitry Andric 
2026*0b57cec5SDimitry Andric   Reg = getReg(Decoder, Mips::COP2RegClassID, Reg);
2027*0b57cec5SDimitry Andric   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
2028*0b57cec5SDimitry Andric 
2029*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
2030*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Base));
2031*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Offset));
2032*0b57cec5SDimitry Andric 
2033*0b57cec5SDimitry Andric   return MCDisassembler::Success;
2034*0b57cec5SDimitry Andric }
2035*0b57cec5SDimitry Andric 
2036*0b57cec5SDimitry Andric static DecodeStatus DecodeSpecial3LlSc(MCInst &Inst,
2037*0b57cec5SDimitry Andric                                        unsigned Insn,
2038*0b57cec5SDimitry Andric                                        uint64_t Address,
2039*0b57cec5SDimitry Andric                                        const void *Decoder) {
2040*0b57cec5SDimitry Andric   int64_t Offset = SignExtend64<9>((Insn >> 7) & 0x1ff);
2041*0b57cec5SDimitry Andric   unsigned Rt = fieldFromInstruction(Insn, 16, 5);
2042*0b57cec5SDimitry Andric   unsigned Base = fieldFromInstruction(Insn, 21, 5);
2043*0b57cec5SDimitry Andric 
2044*0b57cec5SDimitry Andric   Rt = getReg(Decoder, Mips::GPR32RegClassID, Rt);
2045*0b57cec5SDimitry Andric   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
2046*0b57cec5SDimitry Andric 
2047*0b57cec5SDimitry Andric   if(Inst.getOpcode() == Mips::SC_R6 || Inst.getOpcode() == Mips::SCD_R6){
2048*0b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(Rt));
2049*0b57cec5SDimitry Andric   }
2050*0b57cec5SDimitry Andric 
2051*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Rt));
2052*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Base));
2053*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Offset));
2054*0b57cec5SDimitry Andric 
2055*0b57cec5SDimitry Andric   return MCDisassembler::Success;
2056*0b57cec5SDimitry Andric }
2057*0b57cec5SDimitry Andric 
2058*0b57cec5SDimitry Andric static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
2059*0b57cec5SDimitry Andric                                               unsigned RegNo,
2060*0b57cec5SDimitry Andric                                               uint64_t Address,
2061*0b57cec5SDimitry Andric                                               const void *Decoder) {
2062*0b57cec5SDimitry Andric   // Currently only hardware register 29 is supported.
2063*0b57cec5SDimitry Andric   if (RegNo != 29)
2064*0b57cec5SDimitry Andric     return  MCDisassembler::Fail;
2065*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Mips::HWR29));
2066*0b57cec5SDimitry Andric   return MCDisassembler::Success;
2067*0b57cec5SDimitry Andric }
2068*0b57cec5SDimitry Andric 
2069*0b57cec5SDimitry Andric static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
2070*0b57cec5SDimitry Andric                                               unsigned RegNo,
2071*0b57cec5SDimitry Andric                                               uint64_t Address,
2072*0b57cec5SDimitry Andric                                               const void *Decoder) {
2073*0b57cec5SDimitry Andric   if (RegNo > 30 || RegNo %2)
2074*0b57cec5SDimitry Andric     return MCDisassembler::Fail;
2075*0b57cec5SDimitry Andric 
2076*0b57cec5SDimitry Andric   unsigned Reg = getReg(Decoder, Mips::AFGR64RegClassID, RegNo /2);
2077*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
2078*0b57cec5SDimitry Andric   return MCDisassembler::Success;
2079*0b57cec5SDimitry Andric }
2080*0b57cec5SDimitry Andric 
2081*0b57cec5SDimitry Andric static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst,
2082*0b57cec5SDimitry Andric                                                 unsigned RegNo,
2083*0b57cec5SDimitry Andric                                                 uint64_t Address,
2084*0b57cec5SDimitry Andric                                                 const void *Decoder) {
2085*0b57cec5SDimitry Andric   if (RegNo >= 4)
2086*0b57cec5SDimitry Andric     return MCDisassembler::Fail;
2087*0b57cec5SDimitry Andric 
2088*0b57cec5SDimitry Andric   unsigned Reg = getReg(Decoder, Mips::ACC64DSPRegClassID, RegNo);
2089*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
2090*0b57cec5SDimitry Andric   return MCDisassembler::Success;
2091*0b57cec5SDimitry Andric }
2092*0b57cec5SDimitry Andric 
2093*0b57cec5SDimitry Andric static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst,
2094*0b57cec5SDimitry Andric                                                unsigned RegNo,
2095*0b57cec5SDimitry Andric                                                uint64_t Address,
2096*0b57cec5SDimitry Andric                                                const void *Decoder) {
2097*0b57cec5SDimitry Andric   if (RegNo >= 4)
2098*0b57cec5SDimitry Andric     return MCDisassembler::Fail;
2099*0b57cec5SDimitry Andric 
2100*0b57cec5SDimitry Andric   unsigned Reg = getReg(Decoder, Mips::HI32DSPRegClassID, RegNo);
2101*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
2102*0b57cec5SDimitry Andric   return MCDisassembler::Success;
2103*0b57cec5SDimitry Andric }
2104*0b57cec5SDimitry Andric 
2105*0b57cec5SDimitry Andric static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst,
2106*0b57cec5SDimitry Andric                                                unsigned RegNo,
2107*0b57cec5SDimitry Andric                                                uint64_t Address,
2108*0b57cec5SDimitry Andric                                                const void *Decoder) {
2109*0b57cec5SDimitry Andric   if (RegNo >= 4)
2110*0b57cec5SDimitry Andric     return MCDisassembler::Fail;
2111*0b57cec5SDimitry Andric 
2112*0b57cec5SDimitry Andric   unsigned Reg = getReg(Decoder, Mips::LO32DSPRegClassID, RegNo);
2113*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
2114*0b57cec5SDimitry Andric   return MCDisassembler::Success;
2115*0b57cec5SDimitry Andric }
2116*0b57cec5SDimitry Andric 
2117*0b57cec5SDimitry Andric static DecodeStatus DecodeMSA128BRegisterClass(MCInst &Inst,
2118*0b57cec5SDimitry Andric                                                unsigned RegNo,
2119*0b57cec5SDimitry Andric                                                uint64_t Address,
2120*0b57cec5SDimitry Andric                                                const void *Decoder) {
2121*0b57cec5SDimitry Andric   if (RegNo > 31)
2122*0b57cec5SDimitry Andric     return MCDisassembler::Fail;
2123*0b57cec5SDimitry Andric 
2124*0b57cec5SDimitry Andric   unsigned Reg = getReg(Decoder, Mips::MSA128BRegClassID, RegNo);
2125*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
2126*0b57cec5SDimitry Andric   return MCDisassembler::Success;
2127*0b57cec5SDimitry Andric }
2128*0b57cec5SDimitry Andric 
2129*0b57cec5SDimitry Andric static DecodeStatus DecodeMSA128HRegisterClass(MCInst &Inst,
2130*0b57cec5SDimitry Andric                                                unsigned RegNo,
2131*0b57cec5SDimitry Andric                                                uint64_t Address,
2132*0b57cec5SDimitry Andric                                                const void *Decoder) {
2133*0b57cec5SDimitry Andric   if (RegNo > 31)
2134*0b57cec5SDimitry Andric     return MCDisassembler::Fail;
2135*0b57cec5SDimitry Andric 
2136*0b57cec5SDimitry Andric   unsigned Reg = getReg(Decoder, Mips::MSA128HRegClassID, RegNo);
2137*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
2138*0b57cec5SDimitry Andric   return MCDisassembler::Success;
2139*0b57cec5SDimitry Andric }
2140*0b57cec5SDimitry Andric 
2141*0b57cec5SDimitry Andric static DecodeStatus DecodeMSA128WRegisterClass(MCInst &Inst,
2142*0b57cec5SDimitry Andric                                                unsigned RegNo,
2143*0b57cec5SDimitry Andric                                                uint64_t Address,
2144*0b57cec5SDimitry Andric                                                const void *Decoder) {
2145*0b57cec5SDimitry Andric   if (RegNo > 31)
2146*0b57cec5SDimitry Andric     return MCDisassembler::Fail;
2147*0b57cec5SDimitry Andric 
2148*0b57cec5SDimitry Andric   unsigned Reg = getReg(Decoder, Mips::MSA128WRegClassID, RegNo);
2149*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
2150*0b57cec5SDimitry Andric   return MCDisassembler::Success;
2151*0b57cec5SDimitry Andric }
2152*0b57cec5SDimitry Andric 
2153*0b57cec5SDimitry Andric static DecodeStatus DecodeMSA128DRegisterClass(MCInst &Inst,
2154*0b57cec5SDimitry Andric                                                unsigned RegNo,
2155*0b57cec5SDimitry Andric                                                uint64_t Address,
2156*0b57cec5SDimitry Andric                                                const void *Decoder) {
2157*0b57cec5SDimitry Andric   if (RegNo > 31)
2158*0b57cec5SDimitry Andric     return MCDisassembler::Fail;
2159*0b57cec5SDimitry Andric 
2160*0b57cec5SDimitry Andric   unsigned Reg = getReg(Decoder, Mips::MSA128DRegClassID, RegNo);
2161*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
2162*0b57cec5SDimitry Andric   return MCDisassembler::Success;
2163*0b57cec5SDimitry Andric }
2164*0b57cec5SDimitry Andric 
2165*0b57cec5SDimitry Andric static DecodeStatus DecodeMSACtrlRegisterClass(MCInst &Inst,
2166*0b57cec5SDimitry Andric                                                unsigned RegNo,
2167*0b57cec5SDimitry Andric                                                uint64_t Address,
2168*0b57cec5SDimitry Andric                                                const void *Decoder) {
2169*0b57cec5SDimitry Andric   if (RegNo > 7)
2170*0b57cec5SDimitry Andric     return MCDisassembler::Fail;
2171*0b57cec5SDimitry Andric 
2172*0b57cec5SDimitry Andric   unsigned Reg = getReg(Decoder, Mips::MSACtrlRegClassID, RegNo);
2173*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
2174*0b57cec5SDimitry Andric   return MCDisassembler::Success;
2175*0b57cec5SDimitry Andric }
2176*0b57cec5SDimitry Andric 
2177*0b57cec5SDimitry Andric static DecodeStatus DecodeCOP0RegisterClass(MCInst &Inst,
2178*0b57cec5SDimitry Andric                                             unsigned RegNo,
2179*0b57cec5SDimitry Andric                                             uint64_t Address,
2180*0b57cec5SDimitry Andric                                             const void *Decoder) {
2181*0b57cec5SDimitry Andric   if (RegNo > 31)
2182*0b57cec5SDimitry Andric     return MCDisassembler::Fail;
2183*0b57cec5SDimitry Andric 
2184*0b57cec5SDimitry Andric   unsigned Reg = getReg(Decoder, Mips::COP0RegClassID, RegNo);
2185*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
2186*0b57cec5SDimitry Andric   return MCDisassembler::Success;
2187*0b57cec5SDimitry Andric }
2188*0b57cec5SDimitry Andric 
2189*0b57cec5SDimitry Andric static DecodeStatus DecodeCOP2RegisterClass(MCInst &Inst,
2190*0b57cec5SDimitry Andric                                             unsigned RegNo,
2191*0b57cec5SDimitry Andric                                             uint64_t Address,
2192*0b57cec5SDimitry Andric                                             const void *Decoder) {
2193*0b57cec5SDimitry Andric   if (RegNo > 31)
2194*0b57cec5SDimitry Andric     return MCDisassembler::Fail;
2195*0b57cec5SDimitry Andric 
2196*0b57cec5SDimitry Andric   unsigned Reg = getReg(Decoder, Mips::COP2RegClassID, RegNo);
2197*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
2198*0b57cec5SDimitry Andric   return MCDisassembler::Success;
2199*0b57cec5SDimitry Andric }
2200*0b57cec5SDimitry Andric 
2201*0b57cec5SDimitry Andric static DecodeStatus DecodeBranchTarget(MCInst &Inst,
2202*0b57cec5SDimitry Andric                                        unsigned Offset,
2203*0b57cec5SDimitry Andric                                        uint64_t Address,
2204*0b57cec5SDimitry Andric                                        const void *Decoder) {
2205*0b57cec5SDimitry Andric   int32_t BranchOffset = (SignExtend32<16>(Offset) * 4) + 4;
2206*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(BranchOffset));
2207*0b57cec5SDimitry Andric   return MCDisassembler::Success;
2208*0b57cec5SDimitry Andric }
2209*0b57cec5SDimitry Andric 
2210*0b57cec5SDimitry Andric static DecodeStatus DecodeBranchTarget1SImm16(MCInst &Inst,
2211*0b57cec5SDimitry Andric                                               unsigned Offset,
2212*0b57cec5SDimitry Andric                                               uint64_t Address,
2213*0b57cec5SDimitry Andric                                               const void *Decoder) {
2214*0b57cec5SDimitry Andric   int32_t BranchOffset = (SignExtend32<16>(Offset) * 2);
2215*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(BranchOffset));
2216*0b57cec5SDimitry Andric   return MCDisassembler::Success;
2217*0b57cec5SDimitry Andric }
2218*0b57cec5SDimitry Andric 
2219*0b57cec5SDimitry Andric static DecodeStatus DecodeJumpTarget(MCInst &Inst,
2220*0b57cec5SDimitry Andric                                      unsigned Insn,
2221*0b57cec5SDimitry Andric                                      uint64_t Address,
2222*0b57cec5SDimitry Andric                                      const void *Decoder) {
2223*0b57cec5SDimitry Andric   unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 2;
2224*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(JumpOffset));
2225*0b57cec5SDimitry Andric   return MCDisassembler::Success;
2226*0b57cec5SDimitry Andric }
2227*0b57cec5SDimitry Andric 
2228*0b57cec5SDimitry Andric static DecodeStatus DecodeBranchTarget21(MCInst &Inst,
2229*0b57cec5SDimitry Andric                                          unsigned Offset,
2230*0b57cec5SDimitry Andric                                          uint64_t Address,
2231*0b57cec5SDimitry Andric                                          const void *Decoder) {
2232*0b57cec5SDimitry Andric   int32_t BranchOffset = SignExtend32<21>(Offset) * 4 + 4;
2233*0b57cec5SDimitry Andric 
2234*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(BranchOffset));
2235*0b57cec5SDimitry Andric   return MCDisassembler::Success;
2236*0b57cec5SDimitry Andric }
2237*0b57cec5SDimitry Andric 
2238*0b57cec5SDimitry Andric static DecodeStatus DecodeBranchTarget21MM(MCInst &Inst,
2239*0b57cec5SDimitry Andric                                            unsigned Offset,
2240*0b57cec5SDimitry Andric                                            uint64_t Address,
2241*0b57cec5SDimitry Andric                                            const void *Decoder) {
2242*0b57cec5SDimitry Andric   int32_t BranchOffset = SignExtend32<21>(Offset) * 4 + 4;
2243*0b57cec5SDimitry Andric 
2244*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(BranchOffset));
2245*0b57cec5SDimitry Andric   return MCDisassembler::Success;
2246*0b57cec5SDimitry Andric }
2247*0b57cec5SDimitry Andric 
2248*0b57cec5SDimitry Andric static DecodeStatus DecodeBranchTarget26(MCInst &Inst,
2249*0b57cec5SDimitry Andric                                          unsigned Offset,
2250*0b57cec5SDimitry Andric                                          uint64_t Address,
2251*0b57cec5SDimitry Andric                                          const void *Decoder) {
2252*0b57cec5SDimitry Andric   int32_t BranchOffset = SignExtend32<26>(Offset) * 4 + 4;
2253*0b57cec5SDimitry Andric 
2254*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(BranchOffset));
2255*0b57cec5SDimitry Andric   return MCDisassembler::Success;
2256*0b57cec5SDimitry Andric }
2257*0b57cec5SDimitry Andric 
2258*0b57cec5SDimitry Andric static DecodeStatus DecodeBranchTarget7MM(MCInst &Inst,
2259*0b57cec5SDimitry Andric                                           unsigned Offset,
2260*0b57cec5SDimitry Andric                                           uint64_t Address,
2261*0b57cec5SDimitry Andric                                           const void *Decoder) {
2262*0b57cec5SDimitry Andric   int32_t BranchOffset = SignExtend32<8>(Offset << 1);
2263*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(BranchOffset));
2264*0b57cec5SDimitry Andric   return MCDisassembler::Success;
2265*0b57cec5SDimitry Andric }
2266*0b57cec5SDimitry Andric 
2267*0b57cec5SDimitry Andric static DecodeStatus DecodeBranchTarget10MM(MCInst &Inst,
2268*0b57cec5SDimitry Andric                                            unsigned Offset,
2269*0b57cec5SDimitry Andric                                            uint64_t Address,
2270*0b57cec5SDimitry Andric                                            const void *Decoder) {
2271*0b57cec5SDimitry Andric   int32_t BranchOffset = SignExtend32<11>(Offset << 1);
2272*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(BranchOffset));
2273*0b57cec5SDimitry Andric   return MCDisassembler::Success;
2274*0b57cec5SDimitry Andric }
2275*0b57cec5SDimitry Andric 
2276*0b57cec5SDimitry Andric static DecodeStatus DecodeBranchTargetMM(MCInst &Inst,
2277*0b57cec5SDimitry Andric                                          unsigned Offset,
2278*0b57cec5SDimitry Andric                                          uint64_t Address,
2279*0b57cec5SDimitry Andric                                          const void *Decoder) {
2280*0b57cec5SDimitry Andric   int32_t BranchOffset = SignExtend32<16>(Offset) * 2 + 4;
2281*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(BranchOffset));
2282*0b57cec5SDimitry Andric   return MCDisassembler::Success;
2283*0b57cec5SDimitry Andric }
2284*0b57cec5SDimitry Andric 
2285*0b57cec5SDimitry Andric static DecodeStatus DecodeBranchTarget26MM(MCInst &Inst,
2286*0b57cec5SDimitry Andric   unsigned Offset,
2287*0b57cec5SDimitry Andric   uint64_t Address,
2288*0b57cec5SDimitry Andric   const void *Decoder) {
2289*0b57cec5SDimitry Andric   int32_t BranchOffset = SignExtend32<27>(Offset << 1);
2290*0b57cec5SDimitry Andric 
2291*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(BranchOffset));
2292*0b57cec5SDimitry Andric   return MCDisassembler::Success;
2293*0b57cec5SDimitry Andric }
2294*0b57cec5SDimitry Andric 
2295*0b57cec5SDimitry Andric static DecodeStatus DecodeJumpTargetMM(MCInst &Inst,
2296*0b57cec5SDimitry Andric                                        unsigned Insn,
2297*0b57cec5SDimitry Andric                                        uint64_t Address,
2298*0b57cec5SDimitry Andric                                        const void *Decoder) {
2299*0b57cec5SDimitry Andric   unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 1;
2300*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(JumpOffset));
2301*0b57cec5SDimitry Andric   return MCDisassembler::Success;
2302*0b57cec5SDimitry Andric }
2303*0b57cec5SDimitry Andric 
2304*0b57cec5SDimitry Andric static DecodeStatus DecodeAddiur2Simm7(MCInst &Inst,
2305*0b57cec5SDimitry Andric                                        unsigned Value,
2306*0b57cec5SDimitry Andric                                        uint64_t Address,
2307*0b57cec5SDimitry Andric                                        const void *Decoder) {
2308*0b57cec5SDimitry Andric   if (Value == 0)
2309*0b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(1));
2310*0b57cec5SDimitry Andric   else if (Value == 0x7)
2311*0b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(-1));
2312*0b57cec5SDimitry Andric   else
2313*0b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(Value << 2));
2314*0b57cec5SDimitry Andric   return MCDisassembler::Success;
2315*0b57cec5SDimitry Andric }
2316*0b57cec5SDimitry Andric 
2317*0b57cec5SDimitry Andric static DecodeStatus DecodeLi16Imm(MCInst &Inst,
2318*0b57cec5SDimitry Andric                                   unsigned Value,
2319*0b57cec5SDimitry Andric                                   uint64_t Address,
2320*0b57cec5SDimitry Andric                                   const void *Decoder) {
2321*0b57cec5SDimitry Andric   if (Value == 0x7F)
2322*0b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(-1));
2323*0b57cec5SDimitry Andric   else
2324*0b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(Value));
2325*0b57cec5SDimitry Andric   return MCDisassembler::Success;
2326*0b57cec5SDimitry Andric }
2327*0b57cec5SDimitry Andric 
2328*0b57cec5SDimitry Andric static DecodeStatus DecodePOOL16BEncodedField(MCInst &Inst,
2329*0b57cec5SDimitry Andric                                               unsigned Value,
2330*0b57cec5SDimitry Andric                                               uint64_t Address,
2331*0b57cec5SDimitry Andric                                               const void *Decoder) {
2332*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Value == 0x0 ? 8 : Value));
2333*0b57cec5SDimitry Andric   return MCDisassembler::Success;
2334*0b57cec5SDimitry Andric }
2335*0b57cec5SDimitry Andric 
2336*0b57cec5SDimitry Andric template <unsigned Bits, int Offset, int Scale>
2337*0b57cec5SDimitry Andric static DecodeStatus DecodeUImmWithOffsetAndScale(MCInst &Inst, unsigned Value,
2338*0b57cec5SDimitry Andric                                                  uint64_t Address,
2339*0b57cec5SDimitry Andric                                                  const void *Decoder) {
2340*0b57cec5SDimitry Andric   Value &= ((1 << Bits) - 1);
2341*0b57cec5SDimitry Andric   Value *= Scale;
2342*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Value + Offset));
2343*0b57cec5SDimitry Andric   return MCDisassembler::Success;
2344*0b57cec5SDimitry Andric }
2345*0b57cec5SDimitry Andric 
2346*0b57cec5SDimitry Andric template <unsigned Bits, int Offset, int ScaleBy>
2347*0b57cec5SDimitry Andric static DecodeStatus DecodeSImmWithOffsetAndScale(MCInst &Inst, unsigned Value,
2348*0b57cec5SDimitry Andric                                                  uint64_t Address,
2349*0b57cec5SDimitry Andric                                                  const void *Decoder) {
2350*0b57cec5SDimitry Andric   int32_t Imm = SignExtend32<Bits>(Value) * ScaleBy;
2351*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Imm + Offset));
2352*0b57cec5SDimitry Andric   return MCDisassembler::Success;
2353*0b57cec5SDimitry Andric }
2354*0b57cec5SDimitry Andric 
2355*0b57cec5SDimitry Andric static DecodeStatus DecodeInsSize(MCInst &Inst,
2356*0b57cec5SDimitry Andric                                   unsigned Insn,
2357*0b57cec5SDimitry Andric                                   uint64_t Address,
2358*0b57cec5SDimitry Andric                                   const void *Decoder) {
2359*0b57cec5SDimitry Andric   // First we need to grab the pos(lsb) from MCInst.
2360*0b57cec5SDimitry Andric   // This function only handles the 32 bit variants of ins, as dins
2361*0b57cec5SDimitry Andric   // variants are handled differently.
2362*0b57cec5SDimitry Andric   int Pos = Inst.getOperand(2).getImm();
2363*0b57cec5SDimitry Andric   int Size = (int) Insn - Pos + 1;
2364*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(SignExtend32<16>(Size)));
2365*0b57cec5SDimitry Andric   return MCDisassembler::Success;
2366*0b57cec5SDimitry Andric }
2367*0b57cec5SDimitry Andric 
2368*0b57cec5SDimitry Andric static DecodeStatus DecodeSimm19Lsl2(MCInst &Inst, unsigned Insn,
2369*0b57cec5SDimitry Andric                                      uint64_t Address, const void *Decoder) {
2370*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(SignExtend32<19>(Insn) * 4));
2371*0b57cec5SDimitry Andric   return MCDisassembler::Success;
2372*0b57cec5SDimitry Andric }
2373*0b57cec5SDimitry Andric 
2374*0b57cec5SDimitry Andric static DecodeStatus DecodeSimm18Lsl3(MCInst &Inst, unsigned Insn,
2375*0b57cec5SDimitry Andric                                      uint64_t Address, const void *Decoder) {
2376*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(SignExtend32<18>(Insn) * 8));
2377*0b57cec5SDimitry Andric   return MCDisassembler::Success;
2378*0b57cec5SDimitry Andric }
2379*0b57cec5SDimitry Andric 
2380*0b57cec5SDimitry Andric static DecodeStatus DecodeSimm9SP(MCInst &Inst, unsigned Insn,
2381*0b57cec5SDimitry Andric                                   uint64_t Address, const void *Decoder) {
2382*0b57cec5SDimitry Andric   int32_t DecodedValue;
2383*0b57cec5SDimitry Andric   switch (Insn) {
2384*0b57cec5SDimitry Andric   case 0: DecodedValue = 256; break;
2385*0b57cec5SDimitry Andric   case 1: DecodedValue = 257; break;
2386*0b57cec5SDimitry Andric   case 510: DecodedValue = -258; break;
2387*0b57cec5SDimitry Andric   case 511: DecodedValue = -257; break;
2388*0b57cec5SDimitry Andric   default: DecodedValue = SignExtend32<9>(Insn); break;
2389*0b57cec5SDimitry Andric   }
2390*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(DecodedValue * 4));
2391*0b57cec5SDimitry Andric   return MCDisassembler::Success;
2392*0b57cec5SDimitry Andric }
2393*0b57cec5SDimitry Andric 
2394*0b57cec5SDimitry Andric static DecodeStatus DecodeANDI16Imm(MCInst &Inst, unsigned Insn,
2395*0b57cec5SDimitry Andric                                     uint64_t Address, const void *Decoder) {
2396*0b57cec5SDimitry Andric   // Insn must be >= 0, since it is unsigned that condition is always true.
2397*0b57cec5SDimitry Andric   assert(Insn < 16);
2398*0b57cec5SDimitry Andric   int32_t DecodedValues[] = {128, 1, 2, 3, 4, 7, 8, 15, 16, 31, 32, 63, 64,
2399*0b57cec5SDimitry Andric                              255, 32768, 65535};
2400*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(DecodedValues[Insn]));
2401*0b57cec5SDimitry Andric   return MCDisassembler::Success;
2402*0b57cec5SDimitry Andric }
2403*0b57cec5SDimitry Andric 
2404*0b57cec5SDimitry Andric static DecodeStatus DecodeRegListOperand(MCInst &Inst,
2405*0b57cec5SDimitry Andric                                          unsigned Insn,
2406*0b57cec5SDimitry Andric                                          uint64_t Address,
2407*0b57cec5SDimitry Andric                                          const void *Decoder) {
2408*0b57cec5SDimitry Andric   unsigned Regs[] = {Mips::S0, Mips::S1, Mips::S2, Mips::S3, Mips::S4, Mips::S5,
2409*0b57cec5SDimitry Andric                      Mips::S6, Mips::S7, Mips::FP};
2410*0b57cec5SDimitry Andric   unsigned RegNum;
2411*0b57cec5SDimitry Andric 
2412*0b57cec5SDimitry Andric   unsigned RegLst = fieldFromInstruction(Insn, 21, 5);
2413*0b57cec5SDimitry Andric 
2414*0b57cec5SDimitry Andric   // Empty register lists are not allowed.
2415*0b57cec5SDimitry Andric   if (RegLst == 0)
2416*0b57cec5SDimitry Andric     return MCDisassembler::Fail;
2417*0b57cec5SDimitry Andric 
2418*0b57cec5SDimitry Andric   RegNum = RegLst & 0xf;
2419*0b57cec5SDimitry Andric 
2420*0b57cec5SDimitry Andric   // RegLst values 10-15, and 26-31 are reserved.
2421*0b57cec5SDimitry Andric   if (RegNum > 9)
2422*0b57cec5SDimitry Andric     return MCDisassembler::Fail;
2423*0b57cec5SDimitry Andric 
2424*0b57cec5SDimitry Andric   for (unsigned i = 0; i < RegNum; i++)
2425*0b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(Regs[i]));
2426*0b57cec5SDimitry Andric 
2427*0b57cec5SDimitry Andric   if (RegLst & 0x10)
2428*0b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(Mips::RA));
2429*0b57cec5SDimitry Andric 
2430*0b57cec5SDimitry Andric   return MCDisassembler::Success;
2431*0b57cec5SDimitry Andric }
2432*0b57cec5SDimitry Andric 
2433*0b57cec5SDimitry Andric static DecodeStatus DecodeRegListOperand16(MCInst &Inst, unsigned Insn,
2434*0b57cec5SDimitry Andric                                            uint64_t Address,
2435*0b57cec5SDimitry Andric                                            const void *Decoder) {
2436*0b57cec5SDimitry Andric   unsigned Regs[] = {Mips::S0, Mips::S1, Mips::S2, Mips::S3};
2437*0b57cec5SDimitry Andric   unsigned RegLst;
2438*0b57cec5SDimitry Andric   switch(Inst.getOpcode()) {
2439*0b57cec5SDimitry Andric   default:
2440*0b57cec5SDimitry Andric     RegLst = fieldFromInstruction(Insn, 4, 2);
2441*0b57cec5SDimitry Andric     break;
2442*0b57cec5SDimitry Andric   case Mips::LWM16_MMR6:
2443*0b57cec5SDimitry Andric   case Mips::SWM16_MMR6:
2444*0b57cec5SDimitry Andric     RegLst = fieldFromInstruction(Insn, 8, 2);
2445*0b57cec5SDimitry Andric     break;
2446*0b57cec5SDimitry Andric   }
2447*0b57cec5SDimitry Andric   unsigned RegNum = RegLst & 0x3;
2448*0b57cec5SDimitry Andric 
2449*0b57cec5SDimitry Andric   for (unsigned i = 0; i <= RegNum; i++)
2450*0b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(Regs[i]));
2451*0b57cec5SDimitry Andric 
2452*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Mips::RA));
2453*0b57cec5SDimitry Andric 
2454*0b57cec5SDimitry Andric   return MCDisassembler::Success;
2455*0b57cec5SDimitry Andric }
2456*0b57cec5SDimitry Andric 
2457*0b57cec5SDimitry Andric static DecodeStatus DecodeMovePOperands(MCInst &Inst, unsigned Insn,
2458*0b57cec5SDimitry Andric                                           uint64_t Address,
2459*0b57cec5SDimitry Andric                                           const void *Decoder) {
2460*0b57cec5SDimitry Andric   unsigned RegPair = fieldFromInstruction(Insn, 7, 3);
2461*0b57cec5SDimitry Andric   if (DecodeMovePRegPair(Inst, RegPair, Address, Decoder) ==
2462*0b57cec5SDimitry Andric       MCDisassembler::Fail)
2463*0b57cec5SDimitry Andric     return MCDisassembler::Fail;
2464*0b57cec5SDimitry Andric 
2465*0b57cec5SDimitry Andric   unsigned RegRs;
2466*0b57cec5SDimitry Andric   if (static_cast<const MipsDisassembler*>(Decoder)->hasMips32r6())
2467*0b57cec5SDimitry Andric     RegRs = fieldFromInstruction(Insn, 0, 2) |
2468*0b57cec5SDimitry Andric             (fieldFromInstruction(Insn, 3, 1) << 2);
2469*0b57cec5SDimitry Andric   else
2470*0b57cec5SDimitry Andric     RegRs = fieldFromInstruction(Insn, 1, 3);
2471*0b57cec5SDimitry Andric   if (DecodeGPRMM16MovePRegisterClass(Inst, RegRs, Address, Decoder) ==
2472*0b57cec5SDimitry Andric       MCDisassembler::Fail)
2473*0b57cec5SDimitry Andric     return MCDisassembler::Fail;
2474*0b57cec5SDimitry Andric 
2475*0b57cec5SDimitry Andric   unsigned RegRt = fieldFromInstruction(Insn, 4, 3);
2476*0b57cec5SDimitry Andric   if (DecodeGPRMM16MovePRegisterClass(Inst, RegRt, Address, Decoder) ==
2477*0b57cec5SDimitry Andric       MCDisassembler::Fail)
2478*0b57cec5SDimitry Andric     return MCDisassembler::Fail;
2479*0b57cec5SDimitry Andric 
2480*0b57cec5SDimitry Andric   return MCDisassembler::Success;
2481*0b57cec5SDimitry Andric }
2482*0b57cec5SDimitry Andric 
2483*0b57cec5SDimitry Andric static DecodeStatus DecodeMovePRegPair(MCInst &Inst, unsigned RegPair,
2484*0b57cec5SDimitry Andric                                        uint64_t Address, const void *Decoder) {
2485*0b57cec5SDimitry Andric   switch (RegPair) {
2486*0b57cec5SDimitry Andric   default:
2487*0b57cec5SDimitry Andric     return MCDisassembler::Fail;
2488*0b57cec5SDimitry Andric   case 0:
2489*0b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(Mips::A1));
2490*0b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(Mips::A2));
2491*0b57cec5SDimitry Andric     break;
2492*0b57cec5SDimitry Andric   case 1:
2493*0b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(Mips::A1));
2494*0b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(Mips::A3));
2495*0b57cec5SDimitry Andric     break;
2496*0b57cec5SDimitry Andric   case 2:
2497*0b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(Mips::A2));
2498*0b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(Mips::A3));
2499*0b57cec5SDimitry Andric     break;
2500*0b57cec5SDimitry Andric   case 3:
2501*0b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(Mips::A0));
2502*0b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(Mips::S5));
2503*0b57cec5SDimitry Andric     break;
2504*0b57cec5SDimitry Andric   case 4:
2505*0b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(Mips::A0));
2506*0b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(Mips::S6));
2507*0b57cec5SDimitry Andric     break;
2508*0b57cec5SDimitry Andric   case 5:
2509*0b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(Mips::A0));
2510*0b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(Mips::A1));
2511*0b57cec5SDimitry Andric     break;
2512*0b57cec5SDimitry Andric   case 6:
2513*0b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(Mips::A0));
2514*0b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(Mips::A2));
2515*0b57cec5SDimitry Andric     break;
2516*0b57cec5SDimitry Andric   case 7:
2517*0b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(Mips::A0));
2518*0b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(Mips::A3));
2519*0b57cec5SDimitry Andric     break;
2520*0b57cec5SDimitry Andric   }
2521*0b57cec5SDimitry Andric 
2522*0b57cec5SDimitry Andric   return MCDisassembler::Success;
2523*0b57cec5SDimitry Andric }
2524*0b57cec5SDimitry Andric 
2525*0b57cec5SDimitry Andric static DecodeStatus DecodeSimm23Lsl2(MCInst &Inst, unsigned Insn,
2526*0b57cec5SDimitry Andric                                      uint64_t Address, const void *Decoder) {
2527*0b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(SignExtend32<25>(Insn << 2)));
2528*0b57cec5SDimitry Andric   return MCDisassembler::Success;
2529*0b57cec5SDimitry Andric }
2530*0b57cec5SDimitry Andric 
2531*0b57cec5SDimitry Andric template <typename InsnType>
2532*0b57cec5SDimitry Andric static DecodeStatus DecodeBgtzGroupBranchMMR6(MCInst &MI, InsnType insn,
2533*0b57cec5SDimitry Andric   uint64_t Address,
2534*0b57cec5SDimitry Andric   const void *Decoder) {
2535*0b57cec5SDimitry Andric   // We have:
2536*0b57cec5SDimitry Andric   //    0b000111 ttttt sssss iiiiiiiiiiiiiiii
2537*0b57cec5SDimitry Andric   //      Invalid      if rt == 0
2538*0b57cec5SDimitry Andric   //      BGTZALC_MMR6 if rs == 0 && rt != 0
2539*0b57cec5SDimitry Andric   //      BLTZALC_MMR6 if rs != 0 && rs == rt
2540*0b57cec5SDimitry Andric   //      BLTUC_MMR6   if rs != 0 && rs != rt
2541*0b57cec5SDimitry Andric 
2542*0b57cec5SDimitry Andric   InsnType Rt = fieldFromInstruction(insn, 21, 5);
2543*0b57cec5SDimitry Andric   InsnType Rs = fieldFromInstruction(insn, 16, 5);
2544*0b57cec5SDimitry Andric   InsnType Imm = 0;
2545*0b57cec5SDimitry Andric   bool HasRs = false;
2546*0b57cec5SDimitry Andric   bool HasRt = false;
2547*0b57cec5SDimitry Andric 
2548*0b57cec5SDimitry Andric   if (Rt == 0)
2549*0b57cec5SDimitry Andric     return MCDisassembler::Fail;
2550*0b57cec5SDimitry Andric   else if (Rs == 0) {
2551*0b57cec5SDimitry Andric     MI.setOpcode(Mips::BGTZALC_MMR6);
2552*0b57cec5SDimitry Andric     HasRt = true;
2553*0b57cec5SDimitry Andric     Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
2554*0b57cec5SDimitry Andric   }
2555*0b57cec5SDimitry Andric   else if (Rs == Rt) {
2556*0b57cec5SDimitry Andric     MI.setOpcode(Mips::BLTZALC_MMR6);
2557*0b57cec5SDimitry Andric     HasRs = true;
2558*0b57cec5SDimitry Andric     Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
2559*0b57cec5SDimitry Andric   }
2560*0b57cec5SDimitry Andric   else {
2561*0b57cec5SDimitry Andric     MI.setOpcode(Mips::BLTUC_MMR6);
2562*0b57cec5SDimitry Andric     HasRs = true;
2563*0b57cec5SDimitry Andric     HasRt = true;
2564*0b57cec5SDimitry Andric     Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
2565*0b57cec5SDimitry Andric   }
2566*0b57cec5SDimitry Andric 
2567*0b57cec5SDimitry Andric   if (HasRs)
2568*0b57cec5SDimitry Andric     MI.addOperand(
2569*0b57cec5SDimitry Andric     MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rs)));
2570*0b57cec5SDimitry Andric 
2571*0b57cec5SDimitry Andric   if (HasRt)
2572*0b57cec5SDimitry Andric     MI.addOperand(
2573*0b57cec5SDimitry Andric     MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rt)));
2574*0b57cec5SDimitry Andric 
2575*0b57cec5SDimitry Andric   MI.addOperand(MCOperand::createImm(Imm));
2576*0b57cec5SDimitry Andric 
2577*0b57cec5SDimitry Andric   return MCDisassembler::Success;
2578*0b57cec5SDimitry Andric }
2579*0b57cec5SDimitry Andric 
2580*0b57cec5SDimitry Andric template <typename InsnType>
2581*0b57cec5SDimitry Andric static DecodeStatus DecodeBlezGroupBranchMMR6(MCInst &MI, InsnType insn,
2582*0b57cec5SDimitry Andric   uint64_t Address,
2583*0b57cec5SDimitry Andric   const void *Decoder) {
2584*0b57cec5SDimitry Andric   // We have:
2585*0b57cec5SDimitry Andric   //    0b000110 ttttt sssss iiiiiiiiiiiiiiii
2586*0b57cec5SDimitry Andric   //      Invalid        if rt == 0
2587*0b57cec5SDimitry Andric   //      BLEZALC_MMR6   if rs == 0  && rt != 0
2588*0b57cec5SDimitry Andric   //      BGEZALC_MMR6   if rs == rt && rt != 0
2589*0b57cec5SDimitry Andric   //      BGEUC_MMR6     if rs != rt && rs != 0  && rt != 0
2590*0b57cec5SDimitry Andric 
2591*0b57cec5SDimitry Andric   InsnType Rt = fieldFromInstruction(insn, 21, 5);
2592*0b57cec5SDimitry Andric   InsnType Rs = fieldFromInstruction(insn, 16, 5);
2593*0b57cec5SDimitry Andric   InsnType Imm = 0;
2594*0b57cec5SDimitry Andric   bool HasRs = false;
2595*0b57cec5SDimitry Andric 
2596*0b57cec5SDimitry Andric   if (Rt == 0)
2597*0b57cec5SDimitry Andric     return MCDisassembler::Fail;
2598*0b57cec5SDimitry Andric   else if (Rs == 0) {
2599*0b57cec5SDimitry Andric     MI.setOpcode(Mips::BLEZALC_MMR6);
2600*0b57cec5SDimitry Andric     Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
2601*0b57cec5SDimitry Andric   }
2602*0b57cec5SDimitry Andric   else if (Rs == Rt) {
2603*0b57cec5SDimitry Andric     MI.setOpcode(Mips::BGEZALC_MMR6);
2604*0b57cec5SDimitry Andric     Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
2605*0b57cec5SDimitry Andric   }
2606*0b57cec5SDimitry Andric   else {
2607*0b57cec5SDimitry Andric     HasRs = true;
2608*0b57cec5SDimitry Andric     MI.setOpcode(Mips::BGEUC_MMR6);
2609*0b57cec5SDimitry Andric     Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
2610*0b57cec5SDimitry Andric   }
2611*0b57cec5SDimitry Andric 
2612*0b57cec5SDimitry Andric   if (HasRs)
2613*0b57cec5SDimitry Andric     MI.addOperand(
2614*0b57cec5SDimitry Andric     MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rs)));
2615*0b57cec5SDimitry Andric   MI.addOperand(
2616*0b57cec5SDimitry Andric     MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rt)));
2617*0b57cec5SDimitry Andric 
2618*0b57cec5SDimitry Andric   MI.addOperand(MCOperand::createImm(Imm));
2619*0b57cec5SDimitry Andric 
2620*0b57cec5SDimitry Andric   return MCDisassembler::Success;
2621*0b57cec5SDimitry Andric }
2622