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