xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp (revision 06c3fb2749bda94cb5201f81ffdb8fa6c3161b2e)
10b57cec5SDimitry Andric //===- MipsDisassembler.cpp - Disassembler for Mips -----------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file is part of the Mips Disassembler.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #include "MCTargetDesc/MipsMCTargetDesc.h"
140b57cec5SDimitry Andric #include "Mips.h"
150b57cec5SDimitry Andric #include "TargetInfo/MipsTargetInfo.h"
160b57cec5SDimitry Andric #include "llvm/ADT/ArrayRef.h"
170b57cec5SDimitry Andric #include "llvm/MC/MCContext.h"
1881ad6265SDimitry Andric #include "llvm/MC/MCDecoderOps.h"
190b57cec5SDimitry Andric #include "llvm/MC/MCDisassembler/MCDisassembler.h"
200b57cec5SDimitry Andric #include "llvm/MC/MCInst.h"
210b57cec5SDimitry Andric #include "llvm/MC/MCRegisterInfo.h"
220b57cec5SDimitry Andric #include "llvm/MC/MCSubtargetInfo.h"
23349cc55cSDimitry Andric #include "llvm/MC/TargetRegistry.h"
240b57cec5SDimitry Andric #include "llvm/Support/Compiler.h"
250b57cec5SDimitry Andric #include "llvm/Support/Debug.h"
260b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
270b57cec5SDimitry Andric #include "llvm/Support/MathExtras.h"
280b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
290b57cec5SDimitry Andric #include <cassert>
300b57cec5SDimitry Andric #include <cstdint>
310b57cec5SDimitry Andric 
320b57cec5SDimitry Andric using namespace llvm;
330b57cec5SDimitry Andric 
340b57cec5SDimitry Andric #define DEBUG_TYPE "mips-disassembler"
350b57cec5SDimitry Andric 
360b57cec5SDimitry Andric using DecodeStatus = MCDisassembler::DecodeStatus;
370b57cec5SDimitry Andric 
380b57cec5SDimitry Andric namespace {
390b57cec5SDimitry Andric 
400b57cec5SDimitry Andric class MipsDisassembler : public MCDisassembler {
410b57cec5SDimitry Andric   bool IsMicroMips;
420b57cec5SDimitry Andric   bool IsBigEndian;
430b57cec5SDimitry Andric 
440b57cec5SDimitry Andric public:
MipsDisassembler(const MCSubtargetInfo & STI,MCContext & Ctx,bool IsBigEndian)450b57cec5SDimitry Andric   MipsDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx, bool IsBigEndian)
460b57cec5SDimitry Andric       : MCDisassembler(STI, Ctx),
47*06c3fb27SDimitry Andric         IsMicroMips(STI.hasFeature(Mips::FeatureMicroMips)),
480b57cec5SDimitry Andric         IsBigEndian(IsBigEndian) {}
490b57cec5SDimitry Andric 
hasMips2() const50*06c3fb27SDimitry Andric   bool hasMips2() const { return STI.hasFeature(Mips::FeatureMips2); }
hasMips3() const51*06c3fb27SDimitry Andric   bool hasMips3() const { return STI.hasFeature(Mips::FeatureMips3); }
hasMips32() const52*06c3fb27SDimitry Andric   bool hasMips32() const { return STI.hasFeature(Mips::FeatureMips32); }
530b57cec5SDimitry Andric 
hasMips32r6() const540b57cec5SDimitry Andric   bool hasMips32r6() const {
55*06c3fb27SDimitry Andric     return STI.hasFeature(Mips::FeatureMips32r6);
560b57cec5SDimitry Andric   }
570b57cec5SDimitry Andric 
isFP64() const58*06c3fb27SDimitry Andric   bool isFP64() const { return STI.hasFeature(Mips::FeatureFP64Bit); }
590b57cec5SDimitry Andric 
isGP64() const60*06c3fb27SDimitry Andric   bool isGP64() const { return STI.hasFeature(Mips::FeatureGP64Bit); }
610b57cec5SDimitry Andric 
isPTR64() const62*06c3fb27SDimitry Andric   bool isPTR64() const { return STI.hasFeature(Mips::FeaturePTR64Bit); }
630b57cec5SDimitry Andric 
hasCnMips() const64*06c3fb27SDimitry Andric   bool hasCnMips() const { return STI.hasFeature(Mips::FeatureCnMips); }
650b57cec5SDimitry Andric 
hasCnMipsP() const66*06c3fb27SDimitry Andric   bool hasCnMipsP() const { return STI.hasFeature(Mips::FeatureCnMipsP); }
670b57cec5SDimitry Andric 
hasCOP3() const680b57cec5SDimitry Andric   bool hasCOP3() const {
690b57cec5SDimitry Andric     // Only present in MIPS-I and MIPS-II
700b57cec5SDimitry Andric     return !hasMips32() && !hasMips3();
710b57cec5SDimitry Andric   }
720b57cec5SDimitry Andric 
730b57cec5SDimitry Andric   DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
740b57cec5SDimitry Andric                               ArrayRef<uint8_t> Bytes, uint64_t Address,
750b57cec5SDimitry Andric                               raw_ostream &CStream) const override;
760b57cec5SDimitry Andric };
770b57cec5SDimitry Andric 
780b57cec5SDimitry Andric } // end anonymous namespace
790b57cec5SDimitry Andric 
800b57cec5SDimitry Andric // Forward declare these because the autogenerated code will reference them.
810b57cec5SDimitry Andric // Definitions are further down.
8281ad6265SDimitry Andric static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst, unsigned RegNo,
830b57cec5SDimitry Andric                                              uint64_t Address,
8481ad6265SDimitry Andric                                              const MCDisassembler *Decoder);
850b57cec5SDimitry Andric 
8681ad6265SDimitry Andric static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst, unsigned RegNo,
870b57cec5SDimitry Andric                                                  uint64_t Address,
8881ad6265SDimitry Andric                                                  const MCDisassembler *Decoder);
890b57cec5SDimitry Andric 
9081ad6265SDimitry Andric static DecodeStatus DecodeGPRMM16RegisterClass(MCInst &Inst, unsigned RegNo,
910b57cec5SDimitry Andric                                                uint64_t Address,
9281ad6265SDimitry Andric                                                const MCDisassembler *Decoder);
930b57cec5SDimitry Andric 
9481ad6265SDimitry Andric static DecodeStatus
9581ad6265SDimitry Andric DecodeGPRMM16ZeroRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address,
9681ad6265SDimitry Andric                                const MCDisassembler *Decoder);
970b57cec5SDimitry Andric 
9881ad6265SDimitry Andric static DecodeStatus
9981ad6265SDimitry Andric DecodeGPRMM16MovePRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address,
10081ad6265SDimitry Andric                                 const MCDisassembler *Decoder);
1010b57cec5SDimitry Andric 
10281ad6265SDimitry Andric static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst, unsigned RegNo,
1030b57cec5SDimitry Andric                                              uint64_t Address,
10481ad6265SDimitry Andric                                              const MCDisassembler *Decoder);
1050b57cec5SDimitry Andric 
10681ad6265SDimitry Andric static DecodeStatus DecodePtrRegisterClass(MCInst &Inst, unsigned Insn,
1070b57cec5SDimitry Andric                                            uint64_t Address,
10881ad6265SDimitry Andric                                            const MCDisassembler *Decoder);
1090b57cec5SDimitry Andric 
11081ad6265SDimitry Andric static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst, unsigned RegNo,
1110b57cec5SDimitry Andric                                             uint64_t Address,
11281ad6265SDimitry Andric                                             const MCDisassembler *Decoder);
1130b57cec5SDimitry Andric 
11481ad6265SDimitry Andric static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst, unsigned RegNo,
1150b57cec5SDimitry Andric                                              uint64_t Address,
11681ad6265SDimitry Andric                                              const MCDisassembler *Decoder);
1170b57cec5SDimitry Andric 
11881ad6265SDimitry Andric static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst, unsigned RegNo,
1190b57cec5SDimitry Andric                                              uint64_t Address,
12081ad6265SDimitry Andric                                              const MCDisassembler *Decoder);
1210b57cec5SDimitry Andric 
12281ad6265SDimitry Andric static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst, unsigned RegNo,
1230b57cec5SDimitry Andric                                            uint64_t Address,
12481ad6265SDimitry Andric                                            const MCDisassembler *Decoder);
1250b57cec5SDimitry Andric 
12681ad6265SDimitry Andric static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst, unsigned RegNo,
1270b57cec5SDimitry Andric                                            uint64_t Address,
12881ad6265SDimitry Andric                                            const MCDisassembler *Decoder);
1290b57cec5SDimitry Andric 
1300b57cec5SDimitry Andric static DecodeStatus DecodeFGRCCRegisterClass(MCInst &Inst, unsigned RegNo,
1310b57cec5SDimitry Andric                                              uint64_t Address,
13281ad6265SDimitry Andric                                              const MCDisassembler *Decoder);
1330b57cec5SDimitry Andric 
13481ad6265SDimitry Andric static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst, unsigned Insn,
1350b57cec5SDimitry Andric                                               uint64_t Address,
13681ad6265SDimitry Andric                                               const MCDisassembler *Decoder);
1370b57cec5SDimitry Andric 
13881ad6265SDimitry Andric static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst, unsigned RegNo,
1390b57cec5SDimitry Andric                                               uint64_t Address,
14081ad6265SDimitry Andric                                               const MCDisassembler *Decoder);
1410b57cec5SDimitry Andric 
14281ad6265SDimitry Andric static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst, unsigned RegNo,
1430b57cec5SDimitry Andric                                                 uint64_t Address,
14481ad6265SDimitry Andric                                                 const MCDisassembler *Decoder);
1450b57cec5SDimitry Andric 
14681ad6265SDimitry Andric static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst, unsigned RegNo,
1470b57cec5SDimitry Andric                                                uint64_t Address,
14881ad6265SDimitry Andric                                                const MCDisassembler *Decoder);
1490b57cec5SDimitry Andric 
15081ad6265SDimitry Andric static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst, unsigned RegNo,
1510b57cec5SDimitry Andric                                                uint64_t Address,
15281ad6265SDimitry Andric                                                const MCDisassembler *Decoder);
1530b57cec5SDimitry Andric 
15481ad6265SDimitry Andric static DecodeStatus DecodeMSA128BRegisterClass(MCInst &Inst, unsigned RegNo,
1550b57cec5SDimitry Andric                                                uint64_t Address,
15681ad6265SDimitry Andric                                                const MCDisassembler *Decoder);
1570b57cec5SDimitry Andric 
15881ad6265SDimitry Andric static DecodeStatus DecodeMSA128HRegisterClass(MCInst &Inst, unsigned RegNo,
1590b57cec5SDimitry Andric                                                uint64_t Address,
16081ad6265SDimitry Andric                                                const MCDisassembler *Decoder);
1610b57cec5SDimitry Andric 
16281ad6265SDimitry Andric static DecodeStatus DecodeMSA128WRegisterClass(MCInst &Inst, unsigned RegNo,
1630b57cec5SDimitry Andric                                                uint64_t Address,
16481ad6265SDimitry Andric                                                const MCDisassembler *Decoder);
1650b57cec5SDimitry Andric 
16681ad6265SDimitry Andric static DecodeStatus DecodeMSA128DRegisterClass(MCInst &Inst, unsigned RegNo,
1670b57cec5SDimitry Andric                                                uint64_t Address,
16881ad6265SDimitry Andric                                                const MCDisassembler *Decoder);
1690b57cec5SDimitry Andric 
17081ad6265SDimitry Andric static DecodeStatus DecodeMSACtrlRegisterClass(MCInst &Inst, unsigned RegNo,
1710b57cec5SDimitry Andric                                                uint64_t Address,
17281ad6265SDimitry Andric                                                const MCDisassembler *Decoder);
1730b57cec5SDimitry Andric 
17481ad6265SDimitry Andric static DecodeStatus DecodeCOP0RegisterClass(MCInst &Inst, unsigned RegNo,
1750b57cec5SDimitry Andric                                             uint64_t Address,
17681ad6265SDimitry Andric                                             const MCDisassembler *Decoder);
1770b57cec5SDimitry Andric 
17881ad6265SDimitry Andric static DecodeStatus DecodeCOP2RegisterClass(MCInst &Inst, unsigned RegNo,
1790b57cec5SDimitry Andric                                             uint64_t Address,
18081ad6265SDimitry Andric                                             const MCDisassembler *Decoder);
1810b57cec5SDimitry Andric 
18281ad6265SDimitry Andric static DecodeStatus DecodeBranchTarget(MCInst &Inst, unsigned Offset,
1830b57cec5SDimitry Andric                                        uint64_t Address,
18481ad6265SDimitry Andric                                        const MCDisassembler *Decoder);
1850b57cec5SDimitry Andric 
18681ad6265SDimitry Andric static DecodeStatus DecodeBranchTarget1SImm16(MCInst &Inst, unsigned Offset,
1870b57cec5SDimitry Andric                                               uint64_t Address,
18881ad6265SDimitry Andric                                               const MCDisassembler *Decoder);
1890b57cec5SDimitry Andric 
19081ad6265SDimitry Andric static DecodeStatus DecodeJumpTarget(MCInst &Inst, unsigned Insn,
1910b57cec5SDimitry Andric                                      uint64_t Address,
19281ad6265SDimitry Andric                                      const MCDisassembler *Decoder);
1930b57cec5SDimitry Andric 
19481ad6265SDimitry Andric static DecodeStatus DecodeBranchTarget21(MCInst &Inst, unsigned Offset,
1950b57cec5SDimitry Andric                                          uint64_t Address,
19681ad6265SDimitry Andric                                          const MCDisassembler *Decoder);
1970b57cec5SDimitry Andric 
19881ad6265SDimitry Andric static DecodeStatus DecodeBranchTarget21MM(MCInst &Inst, unsigned Offset,
1990b57cec5SDimitry Andric                                            uint64_t Address,
20081ad6265SDimitry Andric                                            const MCDisassembler *Decoder);
2010b57cec5SDimitry Andric 
20281ad6265SDimitry Andric static DecodeStatus DecodeBranchTarget26(MCInst &Inst, unsigned Offset,
2030b57cec5SDimitry Andric                                          uint64_t Address,
20481ad6265SDimitry Andric                                          const MCDisassembler *Decoder);
2050b57cec5SDimitry Andric 
2060b57cec5SDimitry Andric // DecodeBranchTarget7MM - Decode microMIPS branch offset, which is
2070b57cec5SDimitry Andric // shifted left by 1 bit.
20881ad6265SDimitry Andric static DecodeStatus DecodeBranchTarget7MM(MCInst &Inst, unsigned Offset,
2090b57cec5SDimitry Andric                                           uint64_t Address,
21081ad6265SDimitry Andric                                           const MCDisassembler *Decoder);
2110b57cec5SDimitry Andric 
2120b57cec5SDimitry Andric // DecodeBranchTarget10MM - Decode microMIPS branch offset, which is
2130b57cec5SDimitry Andric // shifted left by 1 bit.
21481ad6265SDimitry Andric static DecodeStatus DecodeBranchTarget10MM(MCInst &Inst, unsigned Offset,
2150b57cec5SDimitry Andric                                            uint64_t Address,
21681ad6265SDimitry Andric                                            const MCDisassembler *Decoder);
2170b57cec5SDimitry Andric 
2180b57cec5SDimitry Andric // DecodeBranchTargetMM - Decode microMIPS branch offset, which is
2190b57cec5SDimitry Andric // shifted left by 1 bit.
22081ad6265SDimitry Andric static DecodeStatus DecodeBranchTargetMM(MCInst &Inst, unsigned Offset,
2210b57cec5SDimitry Andric                                          uint64_t Address,
22281ad6265SDimitry Andric                                          const MCDisassembler *Decoder);
2230b57cec5SDimitry Andric 
2240b57cec5SDimitry Andric // DecodeBranchTarget26MM - Decode microMIPS branch offset, which is
2250b57cec5SDimitry Andric // shifted left by 1 bit.
22681ad6265SDimitry Andric static DecodeStatus DecodeBranchTarget26MM(MCInst &Inst, unsigned Offset,
2270b57cec5SDimitry Andric                                            uint64_t Address,
22881ad6265SDimitry Andric                                            const MCDisassembler *Decoder);
2290b57cec5SDimitry Andric 
2300b57cec5SDimitry Andric // DecodeJumpTargetMM - Decode microMIPS jump target, which is
2310b57cec5SDimitry Andric // shifted left by 1 bit.
23281ad6265SDimitry Andric static DecodeStatus DecodeJumpTargetMM(MCInst &Inst, unsigned Insn,
2330b57cec5SDimitry Andric                                        uint64_t Address,
23481ad6265SDimitry Andric                                        const MCDisassembler *Decoder);
2350b57cec5SDimitry Andric 
2368bcb0991SDimitry Andric // DecodeJumpTargetXMM - Decode microMIPS jump and link exchange target,
2378bcb0991SDimitry Andric // which is shifted left by 2 bit.
23881ad6265SDimitry Andric static DecodeStatus DecodeJumpTargetXMM(MCInst &Inst, unsigned Insn,
2398bcb0991SDimitry Andric                                         uint64_t Address,
24081ad6265SDimitry Andric                                         const MCDisassembler *Decoder);
2418bcb0991SDimitry Andric 
24281ad6265SDimitry Andric static DecodeStatus DecodeMem(MCInst &Inst, unsigned Insn, uint64_t Address,
24381ad6265SDimitry Andric                               const MCDisassembler *Decoder);
2440b57cec5SDimitry Andric 
24581ad6265SDimitry Andric static DecodeStatus DecodeMemEVA(MCInst &Inst, unsigned Insn, uint64_t Address,
24681ad6265SDimitry Andric                                  const MCDisassembler *Decoder);
2470b57cec5SDimitry Andric 
24881ad6265SDimitry Andric static DecodeStatus DecodeLoadByte15(MCInst &Inst, unsigned Insn,
2490b57cec5SDimitry Andric                                      uint64_t Address,
25081ad6265SDimitry Andric                                      const MCDisassembler *Decoder);
2510b57cec5SDimitry Andric 
2520b57cec5SDimitry Andric static DecodeStatus DecodeCacheOp(MCInst &Inst, unsigned Insn, uint64_t Address,
25381ad6265SDimitry Andric                                   const MCDisassembler *Decoder);
2540b57cec5SDimitry Andric 
25581ad6265SDimitry Andric static DecodeStatus DecodeCacheeOp_CacheOpR6(MCInst &Inst, unsigned Insn,
2560b57cec5SDimitry Andric                                              uint64_t Address,
25781ad6265SDimitry Andric                                              const MCDisassembler *Decoder);
2580b57cec5SDimitry Andric 
25981ad6265SDimitry Andric static DecodeStatus DecodeCacheOpMM(MCInst &Inst, unsigned Insn,
2600b57cec5SDimitry Andric                                     uint64_t Address,
26181ad6265SDimitry Andric                                     const MCDisassembler *Decoder);
2620b57cec5SDimitry Andric 
26381ad6265SDimitry Andric static DecodeStatus DecodePrefeOpMM(MCInst &Inst, unsigned Insn,
2640b57cec5SDimitry Andric                                     uint64_t Address,
26581ad6265SDimitry Andric                                     const MCDisassembler *Decoder);
2660b57cec5SDimitry Andric 
26781ad6265SDimitry Andric static DecodeStatus DecodeSyncI(MCInst &Inst, unsigned Insn, uint64_t Address,
26881ad6265SDimitry Andric                                 const MCDisassembler *Decoder);
2690b57cec5SDimitry Andric 
27081ad6265SDimitry Andric static DecodeStatus DecodeSyncI_MM(MCInst &Inst, unsigned Insn,
2710b57cec5SDimitry Andric                                    uint64_t Address,
27281ad6265SDimitry Andric                                    const MCDisassembler *Decoder);
2730b57cec5SDimitry Andric 
27481ad6265SDimitry Andric static DecodeStatus DecodeSynciR6(MCInst &Inst, unsigned Insn, uint64_t Address,
27581ad6265SDimitry Andric                                   const MCDisassembler *Decoder);
2760b57cec5SDimitry Andric 
2770b57cec5SDimitry Andric static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn,
2780b57cec5SDimitry Andric                                     uint64_t Address,
27981ad6265SDimitry Andric                                     const MCDisassembler *Decoder);
2800b57cec5SDimitry Andric 
28181ad6265SDimitry Andric static DecodeStatus DecodeMemMMImm4(MCInst &Inst, unsigned Insn,
2820b57cec5SDimitry Andric                                     uint64_t Address,
28381ad6265SDimitry Andric                                     const MCDisassembler *Decoder);
2840b57cec5SDimitry Andric 
28581ad6265SDimitry Andric static DecodeStatus DecodeMemMMSPImm5Lsl2(MCInst &Inst, unsigned Insn,
2860b57cec5SDimitry Andric                                           uint64_t Address,
28781ad6265SDimitry Andric                                           const MCDisassembler *Decoder);
2880b57cec5SDimitry Andric 
28981ad6265SDimitry Andric static DecodeStatus DecodeMemMMGPImm7Lsl2(MCInst &Inst, unsigned Insn,
2900b57cec5SDimitry Andric                                           uint64_t Address,
29181ad6265SDimitry Andric                                           const MCDisassembler *Decoder);
2920b57cec5SDimitry Andric 
29381ad6265SDimitry Andric static DecodeStatus DecodeMemMMReglistImm4Lsl2(MCInst &Inst, unsigned Insn,
2940b57cec5SDimitry Andric                                                uint64_t Address,
29581ad6265SDimitry Andric                                                const MCDisassembler *Decoder);
2960b57cec5SDimitry Andric 
29781ad6265SDimitry Andric static DecodeStatus DecodeMemMMImm9(MCInst &Inst, unsigned Insn,
2980b57cec5SDimitry Andric                                     uint64_t Address,
29981ad6265SDimitry Andric                                     const MCDisassembler *Decoder);
3000b57cec5SDimitry Andric 
30181ad6265SDimitry Andric static DecodeStatus DecodeMemMMImm12(MCInst &Inst, unsigned Insn,
3020b57cec5SDimitry Andric                                      uint64_t Address,
30381ad6265SDimitry Andric                                      const MCDisassembler *Decoder);
3040b57cec5SDimitry Andric 
30581ad6265SDimitry Andric static DecodeStatus DecodeMemMMImm16(MCInst &Inst, unsigned Insn,
3060b57cec5SDimitry Andric                                      uint64_t Address,
30781ad6265SDimitry Andric                                      const MCDisassembler *Decoder);
30881ad6265SDimitry Andric 
30981ad6265SDimitry Andric static DecodeStatus DecodeFMem(MCInst &Inst, unsigned Insn, uint64_t Address,
31081ad6265SDimitry Andric                                const MCDisassembler *Decoder);
3110b57cec5SDimitry Andric 
3120b57cec5SDimitry Andric static DecodeStatus DecodeFMemMMR2(MCInst &Inst, unsigned Insn,
3130b57cec5SDimitry Andric                                    uint64_t Address,
31481ad6265SDimitry Andric                                    const MCDisassembler *Decoder);
3150b57cec5SDimitry Andric 
3160b57cec5SDimitry Andric static DecodeStatus DecodeFMem2(MCInst &Inst, unsigned Insn, uint64_t Address,
31781ad6265SDimitry Andric                                 const MCDisassembler *Decoder);
3180b57cec5SDimitry Andric 
3190b57cec5SDimitry Andric static DecodeStatus DecodeFMem3(MCInst &Inst, unsigned Insn, uint64_t Address,
32081ad6265SDimitry Andric                                 const MCDisassembler *Decoder);
3210b57cec5SDimitry Andric 
3220b57cec5SDimitry Andric static DecodeStatus DecodeFMemCop2R6(MCInst &Inst, unsigned Insn,
32381ad6265SDimitry Andric                                      uint64_t Address,
32481ad6265SDimitry Andric                                      const MCDisassembler *Decoder);
3250b57cec5SDimitry Andric 
3260b57cec5SDimitry Andric static DecodeStatus DecodeFMemCop2MMR6(MCInst &Inst, unsigned Insn,
3270b57cec5SDimitry Andric                                        uint64_t Address,
32881ad6265SDimitry Andric                                        const MCDisassembler *Decoder);
3290b57cec5SDimitry Andric 
33081ad6265SDimitry Andric static DecodeStatus DecodeSpecial3LlSc(MCInst &Inst, unsigned Insn,
3310b57cec5SDimitry Andric                                        uint64_t Address,
33281ad6265SDimitry Andric                                        const MCDisassembler *Decoder);
3330b57cec5SDimitry Andric 
33481ad6265SDimitry Andric static DecodeStatus DecodeAddiur2Simm7(MCInst &Inst, unsigned Value,
3350b57cec5SDimitry Andric                                        uint64_t Address,
33681ad6265SDimitry Andric                                        const MCDisassembler *Decoder);
3370b57cec5SDimitry Andric 
33881ad6265SDimitry Andric static DecodeStatus DecodeLi16Imm(MCInst &Inst, unsigned Value,
3390b57cec5SDimitry Andric                                   uint64_t Address,
34081ad6265SDimitry Andric                                   const MCDisassembler *Decoder);
3410b57cec5SDimitry Andric 
34281ad6265SDimitry Andric static DecodeStatus DecodePOOL16BEncodedField(MCInst &Inst, unsigned Value,
3430b57cec5SDimitry Andric                                               uint64_t Address,
34481ad6265SDimitry Andric                                               const MCDisassembler *Decoder);
3450b57cec5SDimitry Andric 
3460b57cec5SDimitry Andric template <unsigned Bits, int Offset, int Scale>
3470b57cec5SDimitry Andric static DecodeStatus DecodeUImmWithOffsetAndScale(MCInst &Inst, unsigned Value,
3480b57cec5SDimitry Andric                                                  uint64_t Address,
34981ad6265SDimitry Andric                                                  const MCDisassembler *Decoder);
3500b57cec5SDimitry Andric 
3510b57cec5SDimitry Andric template <unsigned Bits, int Offset>
DecodeUImmWithOffset(MCInst & Inst,unsigned Value,uint64_t Address,const MCDisassembler * Decoder)3520b57cec5SDimitry Andric static DecodeStatus DecodeUImmWithOffset(MCInst &Inst, unsigned Value,
3530b57cec5SDimitry Andric                                          uint64_t Address,
35481ad6265SDimitry Andric                                          const MCDisassembler *Decoder) {
3550b57cec5SDimitry Andric   return DecodeUImmWithOffsetAndScale<Bits, Offset, 1>(Inst, Value, Address,
3560b57cec5SDimitry Andric                                                        Decoder);
3570b57cec5SDimitry Andric }
3580b57cec5SDimitry Andric 
3590b57cec5SDimitry Andric template <unsigned Bits, int Offset = 0, int ScaleBy = 1>
3600b57cec5SDimitry Andric static DecodeStatus DecodeSImmWithOffsetAndScale(MCInst &Inst, unsigned Value,
3610b57cec5SDimitry Andric                                                  uint64_t Address,
36281ad6265SDimitry Andric                                                  const MCDisassembler *Decoder);
3630b57cec5SDimitry Andric 
36481ad6265SDimitry Andric static DecodeStatus DecodeInsSize(MCInst &Inst, unsigned Insn, uint64_t Address,
36581ad6265SDimitry Andric                                   const MCDisassembler *Decoder);
3660b57cec5SDimitry Andric 
3670b57cec5SDimitry Andric static DecodeStatus DecodeSimm19Lsl2(MCInst &Inst, unsigned Insn,
36881ad6265SDimitry Andric                                      uint64_t Address,
36981ad6265SDimitry Andric                                      const MCDisassembler *Decoder);
3700b57cec5SDimitry Andric 
3710b57cec5SDimitry Andric static DecodeStatus DecodeSimm18Lsl3(MCInst &Inst, unsigned Insn,
37281ad6265SDimitry Andric                                      uint64_t Address,
37381ad6265SDimitry Andric                                      const MCDisassembler *Decoder);
3740b57cec5SDimitry Andric 
37581ad6265SDimitry Andric static DecodeStatus DecodeSimm9SP(MCInst &Inst, unsigned Insn, uint64_t Address,
37681ad6265SDimitry Andric                                   const MCDisassembler *Decoder);
3770b57cec5SDimitry Andric 
3780b57cec5SDimitry Andric static DecodeStatus DecodeANDI16Imm(MCInst &Inst, unsigned Insn,
37981ad6265SDimitry Andric                                     uint64_t Address,
38081ad6265SDimitry Andric                                     const MCDisassembler *Decoder);
3810b57cec5SDimitry Andric 
3820b57cec5SDimitry Andric static DecodeStatus DecodeSimm23Lsl2(MCInst &Inst, unsigned Insn,
38381ad6265SDimitry Andric                                      uint64_t Address,
38481ad6265SDimitry Andric                                      const MCDisassembler *Decoder);
3850b57cec5SDimitry Andric 
3860b57cec5SDimitry Andric /// INSVE_[BHWD] have an implicit operand that the generated decoder doesn't
3870b57cec5SDimitry Andric /// handle.
3880b57cec5SDimitry Andric template <typename InsnType>
3890b57cec5SDimitry Andric static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address,
39081ad6265SDimitry Andric                                    const MCDisassembler *Decoder);
3910b57cec5SDimitry Andric 
3920b57cec5SDimitry Andric template <typename InsnType>
393480093f4SDimitry Andric static DecodeStatus DecodeDAHIDATIMMR6(MCInst &MI, InsnType insn,
39481ad6265SDimitry Andric                                        uint64_t Address,
39581ad6265SDimitry Andric                                        const MCDisassembler *Decoder);
3960b57cec5SDimitry Andric 
3970b57cec5SDimitry Andric template <typename InsnType>
3980b57cec5SDimitry Andric static DecodeStatus DecodeDAHIDATI(MCInst &MI, InsnType insn, uint64_t Address,
39981ad6265SDimitry Andric                                    const MCDisassembler *Decoder);
4000b57cec5SDimitry Andric 
4010b57cec5SDimitry Andric template <typename InsnType>
40281ad6265SDimitry Andric static DecodeStatus DecodeAddiGroupBranch(MCInst &MI, InsnType insn,
40381ad6265SDimitry Andric                                           uint64_t Address,
40481ad6265SDimitry Andric                                           const MCDisassembler *Decoder);
4050b57cec5SDimitry Andric 
4060b57cec5SDimitry Andric template <typename InsnType>
40781ad6265SDimitry Andric static DecodeStatus DecodePOP35GroupBranchMMR6(MCInst &MI, InsnType insn,
40881ad6265SDimitry Andric                                                uint64_t Address,
40981ad6265SDimitry Andric                                                const MCDisassembler *Decoder);
4100b57cec5SDimitry Andric 
4110b57cec5SDimitry Andric template <typename InsnType>
41281ad6265SDimitry Andric static DecodeStatus DecodeDaddiGroupBranch(MCInst &MI, InsnType insn,
41381ad6265SDimitry Andric                                            uint64_t Address,
41481ad6265SDimitry Andric                                            const MCDisassembler *Decoder);
4150b57cec5SDimitry Andric 
4160b57cec5SDimitry Andric template <typename InsnType>
41781ad6265SDimitry Andric static DecodeStatus DecodePOP37GroupBranchMMR6(MCInst &MI, InsnType insn,
41881ad6265SDimitry Andric                                                uint64_t Address,
41981ad6265SDimitry Andric                                                const MCDisassembler *Decoder);
4200b57cec5SDimitry Andric 
4210b57cec5SDimitry Andric template <typename InsnType>
42281ad6265SDimitry Andric static DecodeStatus DecodePOP65GroupBranchMMR6(MCInst &MI, InsnType insn,
42381ad6265SDimitry Andric                                                uint64_t Address,
42481ad6265SDimitry Andric                                                const MCDisassembler *Decoder);
4250b57cec5SDimitry Andric 
4260b57cec5SDimitry Andric template <typename InsnType>
42781ad6265SDimitry Andric static DecodeStatus DecodePOP75GroupBranchMMR6(MCInst &MI, InsnType insn,
42881ad6265SDimitry Andric                                                uint64_t Address,
42981ad6265SDimitry Andric                                                const MCDisassembler *Decoder);
4300b57cec5SDimitry Andric 
4310b57cec5SDimitry Andric template <typename InsnType>
43281ad6265SDimitry Andric static DecodeStatus DecodeBlezlGroupBranch(MCInst &MI, InsnType insn,
43381ad6265SDimitry Andric                                            uint64_t Address,
43481ad6265SDimitry Andric                                            const MCDisassembler *Decoder);
4350b57cec5SDimitry Andric 
4360b57cec5SDimitry Andric template <typename InsnType>
43781ad6265SDimitry Andric static DecodeStatus DecodeBgtzlGroupBranch(MCInst &MI, InsnType insn,
43881ad6265SDimitry Andric                                            uint64_t Address,
43981ad6265SDimitry Andric                                            const MCDisassembler *Decoder);
4400b57cec5SDimitry Andric 
4410b57cec5SDimitry Andric template <typename InsnType>
44281ad6265SDimitry Andric static DecodeStatus DecodeBgtzGroupBranch(MCInst &MI, InsnType insn,
44381ad6265SDimitry Andric                                           uint64_t Address,
44481ad6265SDimitry Andric                                           const MCDisassembler *Decoder);
4450b57cec5SDimitry Andric 
4460b57cec5SDimitry Andric template <typename InsnType>
44781ad6265SDimitry Andric static DecodeStatus DecodeBlezGroupBranch(MCInst &MI, InsnType insn,
44881ad6265SDimitry Andric                                           uint64_t Address,
44981ad6265SDimitry Andric                                           const MCDisassembler *Decoder);
4500b57cec5SDimitry Andric 
4510b57cec5SDimitry Andric template <typename InsnType>
45281ad6265SDimitry Andric static DecodeStatus DecodeBgtzGroupBranchMMR6(MCInst &MI, InsnType insn,
45381ad6265SDimitry Andric                                               uint64_t Address,
45481ad6265SDimitry Andric                                               const MCDisassembler *Decoder);
4550b57cec5SDimitry Andric 
4560b57cec5SDimitry Andric template <typename InsnType>
45781ad6265SDimitry Andric static DecodeStatus DecodeBlezGroupBranchMMR6(MCInst &MI, InsnType insn,
45881ad6265SDimitry Andric                                               uint64_t Address,
45981ad6265SDimitry Andric                                               const MCDisassembler *Decoder);
4600b57cec5SDimitry Andric 
4610b57cec5SDimitry Andric template <typename InsnType>
4620b57cec5SDimitry Andric static DecodeStatus DecodeDINS(MCInst &MI, InsnType Insn, uint64_t Address,
46381ad6265SDimitry Andric                                const MCDisassembler *Decoder);
4640b57cec5SDimitry Andric 
4650b57cec5SDimitry Andric template <typename InsnType>
4660b57cec5SDimitry Andric static DecodeStatus DecodeDEXT(MCInst &MI, InsnType Insn, uint64_t Address,
46781ad6265SDimitry Andric                                const MCDisassembler *Decoder);
4680b57cec5SDimitry Andric 
4690b57cec5SDimitry Andric template <typename InsnType>
4700b57cec5SDimitry Andric static DecodeStatus DecodeCRC(MCInst &MI, InsnType Insn, uint64_t Address,
47181ad6265SDimitry Andric                               const MCDisassembler *Decoder);
4720b57cec5SDimitry Andric 
4730b57cec5SDimitry Andric static DecodeStatus DecodeRegListOperand(MCInst &Inst, unsigned Insn,
4740b57cec5SDimitry Andric                                          uint64_t Address,
47581ad6265SDimitry Andric                                          const MCDisassembler *Decoder);
4760b57cec5SDimitry Andric 
4770b57cec5SDimitry Andric static DecodeStatus DecodeRegListOperand16(MCInst &Inst, unsigned Insn,
4780b57cec5SDimitry Andric                                            uint64_t Address,
47981ad6265SDimitry Andric                                            const MCDisassembler *Decoder);
4800b57cec5SDimitry Andric 
4810b57cec5SDimitry Andric static DecodeStatus DecodeMovePRegPair(MCInst &Inst, unsigned RegPair,
4820b57cec5SDimitry Andric                                        uint64_t Address,
48381ad6265SDimitry Andric                                        const MCDisassembler *Decoder);
4840b57cec5SDimitry Andric 
4850b57cec5SDimitry Andric static DecodeStatus DecodeMovePOperands(MCInst &Inst, unsigned Insn,
48681ad6265SDimitry Andric                                         uint64_t Address,
48781ad6265SDimitry Andric                                         const MCDisassembler *Decoder);
4880b57cec5SDimitry Andric 
489bdd1243dSDimitry Andric static DecodeStatus DecodeFIXMEInstruction(MCInst &Inst, unsigned Insn,
490bdd1243dSDimitry Andric                                            uint64_t Address,
491bdd1243dSDimitry Andric                                            const MCDisassembler *Decoder);
492bdd1243dSDimitry Andric 
createMipsDisassembler(const Target & T,const MCSubtargetInfo & STI,MCContext & Ctx)4930b57cec5SDimitry Andric static MCDisassembler *createMipsDisassembler(
4940b57cec5SDimitry Andric                        const Target &T,
4950b57cec5SDimitry Andric                        const MCSubtargetInfo &STI,
4960b57cec5SDimitry Andric                        MCContext &Ctx) {
4970b57cec5SDimitry Andric   return new MipsDisassembler(STI, Ctx, true);
4980b57cec5SDimitry Andric }
4990b57cec5SDimitry Andric 
createMipselDisassembler(const Target & T,const MCSubtargetInfo & STI,MCContext & Ctx)5000b57cec5SDimitry Andric static MCDisassembler *createMipselDisassembler(
5010b57cec5SDimitry Andric                        const Target &T,
5020b57cec5SDimitry Andric                        const MCSubtargetInfo &STI,
5030b57cec5SDimitry Andric                        MCContext &Ctx) {
5040b57cec5SDimitry Andric   return new MipsDisassembler(STI, Ctx, false);
5050b57cec5SDimitry Andric }
5060b57cec5SDimitry Andric 
LLVMInitializeMipsDisassembler()507480093f4SDimitry Andric extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeMipsDisassembler() {
5080b57cec5SDimitry Andric   // Register the disassembler.
5090b57cec5SDimitry Andric   TargetRegistry::RegisterMCDisassembler(getTheMipsTarget(),
5100b57cec5SDimitry Andric                                          createMipsDisassembler);
5110b57cec5SDimitry Andric   TargetRegistry::RegisterMCDisassembler(getTheMipselTarget(),
5120b57cec5SDimitry Andric                                          createMipselDisassembler);
5130b57cec5SDimitry Andric   TargetRegistry::RegisterMCDisassembler(getTheMips64Target(),
5140b57cec5SDimitry Andric                                          createMipsDisassembler);
5150b57cec5SDimitry Andric   TargetRegistry::RegisterMCDisassembler(getTheMips64elTarget(),
5160b57cec5SDimitry Andric                                          createMipselDisassembler);
5170b57cec5SDimitry Andric }
5180b57cec5SDimitry Andric 
5190b57cec5SDimitry Andric #include "MipsGenDisassemblerTables.inc"
5200b57cec5SDimitry Andric 
getReg(const MCDisassembler * D,unsigned RC,unsigned RegNo)52181ad6265SDimitry Andric static unsigned getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo) {
52281ad6265SDimitry Andric   const MCRegisterInfo *RegInfo = D->getContext().getRegisterInfo();
5230b57cec5SDimitry Andric   return *(RegInfo->getRegClass(RC).begin() + RegNo);
5240b57cec5SDimitry Andric }
5250b57cec5SDimitry Andric 
5260b57cec5SDimitry Andric template <typename InsnType>
DecodeINSVE_DF(MCInst & MI,InsnType insn,uint64_t Address,const MCDisassembler * Decoder)5270b57cec5SDimitry Andric static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address,
52881ad6265SDimitry Andric                                    const MCDisassembler *Decoder) {
52981ad6265SDimitry Andric   using DecodeFN =
53081ad6265SDimitry Andric       DecodeStatus (*)(MCInst &, unsigned, uint64_t, const MCDisassembler *);
5310b57cec5SDimitry Andric 
5320b57cec5SDimitry Andric   // The size of the n field depends on the element size
5330b57cec5SDimitry Andric   // The register class also depends on this.
5340b57cec5SDimitry Andric   InsnType tmp = fieldFromInstruction(insn, 17, 5);
5350b57cec5SDimitry Andric   unsigned NSize = 0;
5360b57cec5SDimitry Andric   DecodeFN RegDecoder = nullptr;
5370b57cec5SDimitry Andric   if ((tmp & 0x18) == 0x00) { // INSVE_B
5380b57cec5SDimitry Andric     NSize = 4;
5390b57cec5SDimitry Andric     RegDecoder = DecodeMSA128BRegisterClass;
5400b57cec5SDimitry Andric   } else if ((tmp & 0x1c) == 0x10) { // INSVE_H
5410b57cec5SDimitry Andric     NSize = 3;
5420b57cec5SDimitry Andric     RegDecoder = DecodeMSA128HRegisterClass;
5430b57cec5SDimitry Andric   } else if ((tmp & 0x1e) == 0x18) { // INSVE_W
5440b57cec5SDimitry Andric     NSize = 2;
5450b57cec5SDimitry Andric     RegDecoder = DecodeMSA128WRegisterClass;
5460b57cec5SDimitry Andric   } else if ((tmp & 0x1f) == 0x1c) { // INSVE_D
5470b57cec5SDimitry Andric     NSize = 1;
5480b57cec5SDimitry Andric     RegDecoder = DecodeMSA128DRegisterClass;
5490b57cec5SDimitry Andric   } else
5500b57cec5SDimitry Andric     llvm_unreachable("Invalid encoding");
5510b57cec5SDimitry Andric 
5520b57cec5SDimitry Andric   assert(NSize != 0 && RegDecoder != nullptr);
5530b57cec5SDimitry Andric 
5540b57cec5SDimitry Andric   // $wd
5550b57cec5SDimitry Andric   tmp = fieldFromInstruction(insn, 6, 5);
5560b57cec5SDimitry Andric   if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
5570b57cec5SDimitry Andric     return MCDisassembler::Fail;
5580b57cec5SDimitry Andric   // $wd_in
5590b57cec5SDimitry Andric   if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
5600b57cec5SDimitry Andric     return MCDisassembler::Fail;
5610b57cec5SDimitry Andric   // $n
5620b57cec5SDimitry Andric   tmp = fieldFromInstruction(insn, 16, NSize);
5630b57cec5SDimitry Andric   MI.addOperand(MCOperand::createImm(tmp));
5640b57cec5SDimitry Andric   // $ws
5650b57cec5SDimitry Andric   tmp = fieldFromInstruction(insn, 11, 5);
5660b57cec5SDimitry Andric   if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
5670b57cec5SDimitry Andric     return MCDisassembler::Fail;
5680b57cec5SDimitry Andric   // $n2
5690b57cec5SDimitry Andric   MI.addOperand(MCOperand::createImm(0));
5700b57cec5SDimitry Andric 
5710b57cec5SDimitry Andric   return MCDisassembler::Success;
5720b57cec5SDimitry Andric }
5730b57cec5SDimitry Andric 
5740b57cec5SDimitry Andric template <typename InsnType>
DecodeDAHIDATIMMR6(MCInst & MI,InsnType insn,uint64_t Address,const MCDisassembler * Decoder)575480093f4SDimitry Andric static DecodeStatus DecodeDAHIDATIMMR6(MCInst &MI, InsnType insn,
57681ad6265SDimitry Andric                                        uint64_t Address,
57781ad6265SDimitry Andric                                        const MCDisassembler *Decoder) {
5780b57cec5SDimitry Andric   InsnType Rs = fieldFromInstruction(insn, 16, 5);
5790b57cec5SDimitry Andric   InsnType Imm = fieldFromInstruction(insn, 0, 16);
5800b57cec5SDimitry Andric   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID,
5810b57cec5SDimitry Andric                                        Rs)));
5820b57cec5SDimitry Andric   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID,
5830b57cec5SDimitry Andric                                        Rs)));
5840b57cec5SDimitry Andric   MI.addOperand(MCOperand::createImm(Imm));
5850b57cec5SDimitry Andric 
5860b57cec5SDimitry Andric   return MCDisassembler::Success;
5870b57cec5SDimitry Andric }
5880b57cec5SDimitry Andric 
5890b57cec5SDimitry Andric template <typename InsnType>
DecodeDAHIDATI(MCInst & MI,InsnType insn,uint64_t Address,const MCDisassembler * Decoder)5900b57cec5SDimitry Andric static DecodeStatus DecodeDAHIDATI(MCInst &MI, InsnType insn, uint64_t Address,
59181ad6265SDimitry Andric                                    const MCDisassembler *Decoder) {
5920b57cec5SDimitry Andric   InsnType Rs = fieldFromInstruction(insn, 21, 5);
5930b57cec5SDimitry Andric   InsnType Imm = fieldFromInstruction(insn, 0, 16);
5940b57cec5SDimitry Andric   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID,
5950b57cec5SDimitry Andric                                        Rs)));
5960b57cec5SDimitry Andric   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID,
5970b57cec5SDimitry Andric                                        Rs)));
5980b57cec5SDimitry Andric   MI.addOperand(MCOperand::createImm(Imm));
5990b57cec5SDimitry Andric 
6000b57cec5SDimitry Andric   return MCDisassembler::Success;
6010b57cec5SDimitry Andric }
6020b57cec5SDimitry Andric 
6030b57cec5SDimitry Andric template <typename InsnType>
DecodeAddiGroupBranch(MCInst & MI,InsnType insn,uint64_t Address,const MCDisassembler * Decoder)6040b57cec5SDimitry Andric static DecodeStatus DecodeAddiGroupBranch(MCInst &MI, InsnType insn,
6050b57cec5SDimitry Andric                                           uint64_t Address,
60681ad6265SDimitry Andric                                           const MCDisassembler *Decoder) {
6070b57cec5SDimitry Andric   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
6080b57cec5SDimitry Andric   // (otherwise we would have matched the ADDI instruction from the earlier
6090b57cec5SDimitry Andric   // ISA's instead).
6100b57cec5SDimitry Andric   //
6110b57cec5SDimitry Andric   // We have:
6120b57cec5SDimitry Andric   //    0b001000 sssss ttttt iiiiiiiiiiiiiiii
6130b57cec5SDimitry Andric   //      BOVC if rs >= rt
6140b57cec5SDimitry Andric   //      BEQZALC if rs == 0 && rt != 0
6150b57cec5SDimitry Andric   //      BEQC if rs < rt && rs != 0
6160b57cec5SDimitry Andric 
6170b57cec5SDimitry Andric   InsnType Rs = fieldFromInstruction(insn, 21, 5);
6180b57cec5SDimitry Andric   InsnType Rt = fieldFromInstruction(insn, 16, 5);
6190b57cec5SDimitry Andric   int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
6200b57cec5SDimitry Andric   bool HasRs = false;
6210b57cec5SDimitry Andric 
6220b57cec5SDimitry Andric   if (Rs >= Rt) {
6230b57cec5SDimitry Andric     MI.setOpcode(Mips::BOVC);
6240b57cec5SDimitry Andric     HasRs = true;
6250b57cec5SDimitry Andric   } else if (Rs != 0 && Rs < Rt) {
6260b57cec5SDimitry Andric     MI.setOpcode(Mips::BEQC);
6270b57cec5SDimitry Andric     HasRs = true;
6280b57cec5SDimitry Andric   } else
6290b57cec5SDimitry Andric     MI.setOpcode(Mips::BEQZALC);
6300b57cec5SDimitry Andric 
6310b57cec5SDimitry Andric   if (HasRs)
6320b57cec5SDimitry Andric     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
6330b57cec5SDimitry Andric                                        Rs)));
6340b57cec5SDimitry Andric 
6350b57cec5SDimitry Andric   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
6360b57cec5SDimitry Andric                                      Rt)));
6370b57cec5SDimitry Andric   MI.addOperand(MCOperand::createImm(Imm));
6380b57cec5SDimitry Andric 
6390b57cec5SDimitry Andric   return MCDisassembler::Success;
6400b57cec5SDimitry Andric }
6410b57cec5SDimitry Andric 
6420b57cec5SDimitry Andric template <typename InsnType>
DecodePOP35GroupBranchMMR6(MCInst & MI,InsnType insn,uint64_t Address,const MCDisassembler * Decoder)6430b57cec5SDimitry Andric static DecodeStatus DecodePOP35GroupBranchMMR6(MCInst &MI, InsnType insn,
6440b57cec5SDimitry Andric                                                uint64_t Address,
64581ad6265SDimitry Andric                                                const MCDisassembler *Decoder) {
6460b57cec5SDimitry Andric   InsnType Rt = fieldFromInstruction(insn, 21, 5);
6470b57cec5SDimitry Andric   InsnType Rs = fieldFromInstruction(insn, 16, 5);
6480b57cec5SDimitry Andric   int64_t Imm = 0;
6490b57cec5SDimitry Andric 
6500b57cec5SDimitry Andric   if (Rs >= Rt) {
6510b57cec5SDimitry Andric     MI.setOpcode(Mips::BOVC_MMR6);
6520b57cec5SDimitry Andric     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
6530b57cec5SDimitry Andric                                        Rt)));
6540b57cec5SDimitry Andric     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
6550b57cec5SDimitry Andric                                        Rs)));
6560b57cec5SDimitry Andric     Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
6570b57cec5SDimitry Andric   } else if (Rs != 0 && Rs < Rt) {
6580b57cec5SDimitry Andric     MI.setOpcode(Mips::BEQC_MMR6);
6590b57cec5SDimitry Andric     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
6600b57cec5SDimitry Andric                                        Rs)));
6610b57cec5SDimitry Andric     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
6620b57cec5SDimitry Andric                                        Rt)));
6630b57cec5SDimitry Andric     Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
6640b57cec5SDimitry Andric   } else {
6650b57cec5SDimitry Andric     MI.setOpcode(Mips::BEQZALC_MMR6);
6660b57cec5SDimitry Andric     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
6670b57cec5SDimitry Andric                                        Rt)));
6680b57cec5SDimitry Andric     Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
6690b57cec5SDimitry Andric   }
6700b57cec5SDimitry Andric 
6710b57cec5SDimitry Andric   MI.addOperand(MCOperand::createImm(Imm));
6720b57cec5SDimitry Andric 
6730b57cec5SDimitry Andric   return MCDisassembler::Success;
6740b57cec5SDimitry Andric }
6750b57cec5SDimitry Andric 
6760b57cec5SDimitry Andric template <typename InsnType>
DecodeDaddiGroupBranch(MCInst & MI,InsnType insn,uint64_t Address,const MCDisassembler * Decoder)6770b57cec5SDimitry Andric static DecodeStatus DecodeDaddiGroupBranch(MCInst &MI, InsnType insn,
6780b57cec5SDimitry Andric                                            uint64_t Address,
67981ad6265SDimitry Andric                                            const MCDisassembler *Decoder) {
6800b57cec5SDimitry Andric   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
6810b57cec5SDimitry Andric   // (otherwise we would have matched the ADDI instruction from the earlier
6820b57cec5SDimitry Andric   // ISA's instead).
6830b57cec5SDimitry Andric   //
6840b57cec5SDimitry Andric   // We have:
6850b57cec5SDimitry Andric   //    0b011000 sssss ttttt iiiiiiiiiiiiiiii
6860b57cec5SDimitry Andric   //      BNVC if rs >= rt
6870b57cec5SDimitry Andric   //      BNEZALC if rs == 0 && rt != 0
6880b57cec5SDimitry Andric   //      BNEC if rs < rt && rs != 0
6890b57cec5SDimitry Andric 
6900b57cec5SDimitry Andric   InsnType Rs = fieldFromInstruction(insn, 21, 5);
6910b57cec5SDimitry Andric   InsnType Rt = fieldFromInstruction(insn, 16, 5);
6920b57cec5SDimitry Andric   int64_t  Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
6930b57cec5SDimitry Andric   bool HasRs = false;
6940b57cec5SDimitry Andric 
6950b57cec5SDimitry Andric   if (Rs >= Rt) {
6960b57cec5SDimitry Andric     MI.setOpcode(Mips::BNVC);
6970b57cec5SDimitry Andric     HasRs = true;
6980b57cec5SDimitry Andric   } else if (Rs != 0 && Rs < Rt) {
6990b57cec5SDimitry Andric     MI.setOpcode(Mips::BNEC);
7000b57cec5SDimitry Andric     HasRs = true;
7010b57cec5SDimitry Andric   } else
7020b57cec5SDimitry Andric     MI.setOpcode(Mips::BNEZALC);
7030b57cec5SDimitry Andric 
7040b57cec5SDimitry Andric   if (HasRs)
7050b57cec5SDimitry Andric     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
7060b57cec5SDimitry Andric                                        Rs)));
7070b57cec5SDimitry Andric 
7080b57cec5SDimitry Andric   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
7090b57cec5SDimitry Andric                                      Rt)));
7100b57cec5SDimitry Andric   MI.addOperand(MCOperand::createImm(Imm));
7110b57cec5SDimitry Andric 
7120b57cec5SDimitry Andric   return MCDisassembler::Success;
7130b57cec5SDimitry Andric }
7140b57cec5SDimitry Andric 
7150b57cec5SDimitry Andric template <typename InsnType>
DecodePOP37GroupBranchMMR6(MCInst & MI,InsnType insn,uint64_t Address,const MCDisassembler * Decoder)7160b57cec5SDimitry Andric static DecodeStatus DecodePOP37GroupBranchMMR6(MCInst &MI, InsnType insn,
7170b57cec5SDimitry Andric                                                uint64_t Address,
71881ad6265SDimitry Andric                                                const MCDisassembler *Decoder) {
7190b57cec5SDimitry Andric   InsnType Rt = fieldFromInstruction(insn, 21, 5);
7200b57cec5SDimitry Andric   InsnType Rs = fieldFromInstruction(insn, 16, 5);
7210b57cec5SDimitry Andric   int64_t Imm = 0;
7220b57cec5SDimitry Andric 
7230b57cec5SDimitry Andric   if (Rs >= Rt) {
7240b57cec5SDimitry Andric     MI.setOpcode(Mips::BNVC_MMR6);
7250b57cec5SDimitry Andric     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
7260b57cec5SDimitry Andric                                        Rt)));
7270b57cec5SDimitry Andric     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
7280b57cec5SDimitry Andric                                        Rs)));
7290b57cec5SDimitry Andric     Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
7300b57cec5SDimitry Andric   } else if (Rs != 0 && Rs < Rt) {
7310b57cec5SDimitry Andric     MI.setOpcode(Mips::BNEC_MMR6);
7320b57cec5SDimitry Andric     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
7330b57cec5SDimitry Andric                                        Rs)));
7340b57cec5SDimitry Andric     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
7350b57cec5SDimitry Andric                                        Rt)));
7360b57cec5SDimitry Andric     Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
7370b57cec5SDimitry Andric   } else {
7380b57cec5SDimitry Andric     MI.setOpcode(Mips::BNEZALC_MMR6);
7390b57cec5SDimitry Andric     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
7400b57cec5SDimitry Andric                                        Rt)));
7410b57cec5SDimitry Andric     Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
7420b57cec5SDimitry Andric   }
7430b57cec5SDimitry Andric 
7440b57cec5SDimitry Andric   MI.addOperand(MCOperand::createImm(Imm));
7450b57cec5SDimitry Andric 
7460b57cec5SDimitry Andric   return MCDisassembler::Success;
7470b57cec5SDimitry Andric }
7480b57cec5SDimitry Andric 
7490b57cec5SDimitry Andric template <typename InsnType>
DecodePOP65GroupBranchMMR6(MCInst & MI,InsnType insn,uint64_t Address,const MCDisassembler * Decoder)7500b57cec5SDimitry Andric static DecodeStatus DecodePOP65GroupBranchMMR6(MCInst &MI, InsnType insn,
7510b57cec5SDimitry Andric                                                uint64_t Address,
75281ad6265SDimitry Andric                                                const MCDisassembler *Decoder) {
7530b57cec5SDimitry Andric   // We have:
7540b57cec5SDimitry Andric   //    0b110101 ttttt sssss iiiiiiiiiiiiiiii
7550b57cec5SDimitry Andric   //      Invalid if rt == 0
7560b57cec5SDimitry Andric   //      BGTZC_MMR6   if rs == 0  && rt != 0
7570b57cec5SDimitry Andric   //      BLTZC_MMR6   if rs == rt && rt != 0
7580b57cec5SDimitry Andric   //      BLTC_MMR6    if rs != rt && rs != 0  && rt != 0
7590b57cec5SDimitry Andric 
7600b57cec5SDimitry Andric   InsnType Rt = fieldFromInstruction(insn, 21, 5);
7610b57cec5SDimitry Andric   InsnType Rs = fieldFromInstruction(insn, 16, 5);
7620b57cec5SDimitry Andric   int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
7630b57cec5SDimitry Andric   bool HasRs = false;
7640b57cec5SDimitry Andric 
7650b57cec5SDimitry Andric   if (Rt == 0)
7660b57cec5SDimitry Andric     return MCDisassembler::Fail;
7670b57cec5SDimitry Andric   else if (Rs == 0)
7680b57cec5SDimitry Andric     MI.setOpcode(Mips::BGTZC_MMR6);
7690b57cec5SDimitry Andric   else if (Rs == Rt)
7700b57cec5SDimitry Andric     MI.setOpcode(Mips::BLTZC_MMR6);
7710b57cec5SDimitry Andric   else {
7720b57cec5SDimitry Andric     MI.setOpcode(Mips::BLTC_MMR6);
7730b57cec5SDimitry Andric     HasRs = true;
7740b57cec5SDimitry Andric   }
7750b57cec5SDimitry Andric 
7760b57cec5SDimitry Andric   if (HasRs)
7770b57cec5SDimitry Andric     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
7780b57cec5SDimitry Andric                                               Rs)));
7790b57cec5SDimitry Andric 
7800b57cec5SDimitry Andric   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
7810b57cec5SDimitry Andric                                      Rt)));
7820b57cec5SDimitry Andric 
7830b57cec5SDimitry Andric   MI.addOperand(MCOperand::createImm(Imm));
7840b57cec5SDimitry Andric 
7850b57cec5SDimitry Andric   return MCDisassembler::Success;
7860b57cec5SDimitry Andric }
7870b57cec5SDimitry Andric 
7880b57cec5SDimitry Andric template <typename InsnType>
DecodePOP75GroupBranchMMR6(MCInst & MI,InsnType insn,uint64_t Address,const MCDisassembler * Decoder)7890b57cec5SDimitry Andric static DecodeStatus DecodePOP75GroupBranchMMR6(MCInst &MI, InsnType insn,
7900b57cec5SDimitry Andric                                                uint64_t Address,
79181ad6265SDimitry Andric                                                const MCDisassembler *Decoder) {
7920b57cec5SDimitry Andric   // We have:
7930b57cec5SDimitry Andric   //    0b111101 ttttt sssss iiiiiiiiiiiiiiii
7940b57cec5SDimitry Andric   //      Invalid if rt == 0
7950b57cec5SDimitry Andric   //      BLEZC_MMR6   if rs == 0  && rt != 0
7960b57cec5SDimitry Andric   //      BGEZC_MMR6   if rs == rt && rt != 0
7970b57cec5SDimitry Andric   //      BGEC_MMR6    if rs != rt && rs != 0  && rt != 0
7980b57cec5SDimitry Andric 
7990b57cec5SDimitry Andric   InsnType Rt = fieldFromInstruction(insn, 21, 5);
8000b57cec5SDimitry Andric   InsnType Rs = fieldFromInstruction(insn, 16, 5);
8010b57cec5SDimitry Andric   int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
8020b57cec5SDimitry Andric   bool HasRs = false;
8030b57cec5SDimitry Andric 
8040b57cec5SDimitry Andric   if (Rt == 0)
8050b57cec5SDimitry Andric     return MCDisassembler::Fail;
8060b57cec5SDimitry Andric   else if (Rs == 0)
8070b57cec5SDimitry Andric     MI.setOpcode(Mips::BLEZC_MMR6);
8080b57cec5SDimitry Andric   else if (Rs == Rt)
8090b57cec5SDimitry Andric     MI.setOpcode(Mips::BGEZC_MMR6);
8100b57cec5SDimitry Andric   else {
8110b57cec5SDimitry Andric     HasRs = true;
8120b57cec5SDimitry Andric     MI.setOpcode(Mips::BGEC_MMR6);
8130b57cec5SDimitry Andric   }
8140b57cec5SDimitry Andric 
8150b57cec5SDimitry Andric   if (HasRs)
8160b57cec5SDimitry Andric     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
8170b57cec5SDimitry Andric                                        Rs)));
8180b57cec5SDimitry Andric 
8190b57cec5SDimitry Andric   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
8200b57cec5SDimitry Andric                                      Rt)));
8210b57cec5SDimitry Andric 
8220b57cec5SDimitry Andric   MI.addOperand(MCOperand::createImm(Imm));
8230b57cec5SDimitry Andric 
8240b57cec5SDimitry Andric   return MCDisassembler::Success;
8250b57cec5SDimitry Andric }
8260b57cec5SDimitry Andric 
8270b57cec5SDimitry Andric template <typename InsnType>
DecodeBlezlGroupBranch(MCInst & MI,InsnType insn,uint64_t Address,const MCDisassembler * Decoder)8280b57cec5SDimitry Andric static DecodeStatus DecodeBlezlGroupBranch(MCInst &MI, InsnType insn,
8290b57cec5SDimitry Andric                                            uint64_t Address,
83081ad6265SDimitry Andric                                            const MCDisassembler *Decoder) {
8310b57cec5SDimitry Andric   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
8320b57cec5SDimitry Andric   // (otherwise we would have matched the BLEZL instruction from the earlier
8330b57cec5SDimitry Andric   // ISA's instead).
8340b57cec5SDimitry Andric   //
8350b57cec5SDimitry Andric   // We have:
8360b57cec5SDimitry Andric   //    0b010110 sssss ttttt iiiiiiiiiiiiiiii
8370b57cec5SDimitry Andric   //      Invalid if rs == 0
8380b57cec5SDimitry Andric   //      BLEZC   if rs == 0  && rt != 0
8390b57cec5SDimitry Andric   //      BGEZC   if rs == rt && rt != 0
8400b57cec5SDimitry Andric   //      BGEC    if rs != rt && rs != 0  && rt != 0
8410b57cec5SDimitry Andric 
8420b57cec5SDimitry Andric   InsnType Rs = fieldFromInstruction(insn, 21, 5);
8430b57cec5SDimitry Andric   InsnType Rt = fieldFromInstruction(insn, 16, 5);
8440b57cec5SDimitry Andric   int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
8450b57cec5SDimitry Andric   bool HasRs = false;
8460b57cec5SDimitry Andric 
8470b57cec5SDimitry Andric   if (Rt == 0)
8480b57cec5SDimitry Andric     return MCDisassembler::Fail;
8490b57cec5SDimitry Andric   else if (Rs == 0)
8500b57cec5SDimitry Andric     MI.setOpcode(Mips::BLEZC);
8510b57cec5SDimitry Andric   else if (Rs == Rt)
8520b57cec5SDimitry Andric     MI.setOpcode(Mips::BGEZC);
8530b57cec5SDimitry Andric   else {
8540b57cec5SDimitry Andric     HasRs = true;
8550b57cec5SDimitry Andric     MI.setOpcode(Mips::BGEC);
8560b57cec5SDimitry Andric   }
8570b57cec5SDimitry Andric 
8580b57cec5SDimitry Andric   if (HasRs)
8590b57cec5SDimitry Andric     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
8600b57cec5SDimitry Andric                                        Rs)));
8610b57cec5SDimitry Andric 
8620b57cec5SDimitry Andric   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
8630b57cec5SDimitry Andric                                      Rt)));
8640b57cec5SDimitry Andric 
8650b57cec5SDimitry Andric   MI.addOperand(MCOperand::createImm(Imm));
8660b57cec5SDimitry Andric 
8670b57cec5SDimitry Andric   return MCDisassembler::Success;
8680b57cec5SDimitry Andric }
8690b57cec5SDimitry Andric 
8700b57cec5SDimitry Andric template <typename InsnType>
DecodeBgtzlGroupBranch(MCInst & MI,InsnType insn,uint64_t Address,const MCDisassembler * Decoder)8710b57cec5SDimitry Andric static DecodeStatus DecodeBgtzlGroupBranch(MCInst &MI, InsnType insn,
8720b57cec5SDimitry Andric                                            uint64_t Address,
87381ad6265SDimitry Andric                                            const MCDisassembler *Decoder) {
8740b57cec5SDimitry Andric   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
8750b57cec5SDimitry Andric   // (otherwise we would have matched the BGTZL instruction from the earlier
8760b57cec5SDimitry Andric   // ISA's instead).
8770b57cec5SDimitry Andric   //
8780b57cec5SDimitry Andric   // We have:
8790b57cec5SDimitry Andric   //    0b010111 sssss ttttt iiiiiiiiiiiiiiii
8800b57cec5SDimitry Andric   //      Invalid if rs == 0
8810b57cec5SDimitry Andric   //      BGTZC   if rs == 0  && rt != 0
8820b57cec5SDimitry Andric   //      BLTZC   if rs == rt && rt != 0
8830b57cec5SDimitry Andric   //      BLTC    if rs != rt && rs != 0  && rt != 0
8840b57cec5SDimitry Andric 
8850b57cec5SDimitry Andric   bool HasRs = false;
8860b57cec5SDimitry Andric 
8870b57cec5SDimitry Andric   InsnType Rs = fieldFromInstruction(insn, 21, 5);
8880b57cec5SDimitry Andric   InsnType Rt = fieldFromInstruction(insn, 16, 5);
8890b57cec5SDimitry Andric   int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
8900b57cec5SDimitry Andric 
8910b57cec5SDimitry Andric   if (Rt == 0)
8920b57cec5SDimitry Andric     return MCDisassembler::Fail;
8930b57cec5SDimitry Andric   else if (Rs == 0)
8940b57cec5SDimitry Andric     MI.setOpcode(Mips::BGTZC);
8950b57cec5SDimitry Andric   else if (Rs == Rt)
8960b57cec5SDimitry Andric     MI.setOpcode(Mips::BLTZC);
8970b57cec5SDimitry Andric   else {
8980b57cec5SDimitry Andric     MI.setOpcode(Mips::BLTC);
8990b57cec5SDimitry Andric     HasRs = true;
9000b57cec5SDimitry Andric   }
9010b57cec5SDimitry Andric 
9020b57cec5SDimitry Andric   if (HasRs)
9030b57cec5SDimitry Andric     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
9040b57cec5SDimitry Andric                                               Rs)));
9050b57cec5SDimitry Andric 
9060b57cec5SDimitry Andric   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
9070b57cec5SDimitry Andric                                      Rt)));
9080b57cec5SDimitry Andric 
9090b57cec5SDimitry Andric   MI.addOperand(MCOperand::createImm(Imm));
9100b57cec5SDimitry Andric 
9110b57cec5SDimitry Andric   return MCDisassembler::Success;
9120b57cec5SDimitry Andric }
9130b57cec5SDimitry Andric 
9140b57cec5SDimitry Andric template <typename InsnType>
DecodeBgtzGroupBranch(MCInst & MI,InsnType insn,uint64_t Address,const MCDisassembler * Decoder)9150b57cec5SDimitry Andric static DecodeStatus DecodeBgtzGroupBranch(MCInst &MI, InsnType insn,
9160b57cec5SDimitry Andric                                           uint64_t Address,
91781ad6265SDimitry Andric                                           const MCDisassembler *Decoder) {
9180b57cec5SDimitry Andric   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
9190b57cec5SDimitry Andric   // (otherwise we would have matched the BGTZ instruction from the earlier
9200b57cec5SDimitry Andric   // ISA's instead).
9210b57cec5SDimitry Andric   //
9220b57cec5SDimitry Andric   // We have:
9230b57cec5SDimitry Andric   //    0b000111 sssss ttttt iiiiiiiiiiiiiiii
9240b57cec5SDimitry Andric   //      BGTZ    if rt == 0
9250b57cec5SDimitry Andric   //      BGTZALC if rs == 0 && rt != 0
9260b57cec5SDimitry Andric   //      BLTZALC if rs != 0 && rs == rt
9270b57cec5SDimitry Andric   //      BLTUC   if rs != 0 && rs != rt
9280b57cec5SDimitry Andric 
9290b57cec5SDimitry Andric   InsnType Rs = fieldFromInstruction(insn, 21, 5);
9300b57cec5SDimitry Andric   InsnType Rt = fieldFromInstruction(insn, 16, 5);
9310b57cec5SDimitry Andric   int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
9320b57cec5SDimitry Andric   bool HasRs = false;
9330b57cec5SDimitry Andric   bool HasRt = false;
9340b57cec5SDimitry Andric 
9350b57cec5SDimitry Andric   if (Rt == 0) {
9360b57cec5SDimitry Andric     MI.setOpcode(Mips::BGTZ);
9370b57cec5SDimitry Andric     HasRs = true;
9380b57cec5SDimitry Andric   } else if (Rs == 0) {
9390b57cec5SDimitry Andric     MI.setOpcode(Mips::BGTZALC);
9400b57cec5SDimitry Andric     HasRt = true;
9410b57cec5SDimitry Andric   } else if (Rs == Rt) {
9420b57cec5SDimitry Andric     MI.setOpcode(Mips::BLTZALC);
9430b57cec5SDimitry Andric     HasRs = true;
9440b57cec5SDimitry Andric   } else {
9450b57cec5SDimitry Andric     MI.setOpcode(Mips::BLTUC);
9460b57cec5SDimitry Andric     HasRs = true;
9470b57cec5SDimitry Andric     HasRt = true;
9480b57cec5SDimitry Andric   }
9490b57cec5SDimitry Andric 
9500b57cec5SDimitry Andric   if (HasRs)
9510b57cec5SDimitry Andric     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
9520b57cec5SDimitry Andric                                        Rs)));
9530b57cec5SDimitry Andric 
9540b57cec5SDimitry Andric   if (HasRt)
9550b57cec5SDimitry Andric     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
9560b57cec5SDimitry Andric                                        Rt)));
9570b57cec5SDimitry Andric 
9580b57cec5SDimitry Andric   MI.addOperand(MCOperand::createImm(Imm));
9590b57cec5SDimitry Andric 
9600b57cec5SDimitry Andric   return MCDisassembler::Success;
9610b57cec5SDimitry Andric }
9620b57cec5SDimitry Andric 
9630b57cec5SDimitry Andric template <typename InsnType>
DecodeBlezGroupBranch(MCInst & MI,InsnType insn,uint64_t Address,const MCDisassembler * Decoder)9640b57cec5SDimitry Andric static DecodeStatus DecodeBlezGroupBranch(MCInst &MI, InsnType insn,
9650b57cec5SDimitry Andric                                           uint64_t Address,
96681ad6265SDimitry Andric                                           const MCDisassembler *Decoder) {
9670b57cec5SDimitry Andric   // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
9680b57cec5SDimitry Andric   // (otherwise we would have matched the BLEZL instruction from the earlier
9690b57cec5SDimitry Andric   // ISA's instead).
9700b57cec5SDimitry Andric   //
9710b57cec5SDimitry Andric   // We have:
9720b57cec5SDimitry Andric   //    0b000110 sssss ttttt iiiiiiiiiiiiiiii
9730b57cec5SDimitry Andric   //      Invalid   if rs == 0
9740b57cec5SDimitry Andric   //      BLEZALC   if rs == 0  && rt != 0
9750b57cec5SDimitry Andric   //      BGEZALC   if rs == rt && rt != 0
9760b57cec5SDimitry Andric   //      BGEUC     if rs != rt && rs != 0  && rt != 0
9770b57cec5SDimitry Andric 
9780b57cec5SDimitry Andric   InsnType Rs = fieldFromInstruction(insn, 21, 5);
9790b57cec5SDimitry Andric   InsnType Rt = fieldFromInstruction(insn, 16, 5);
9800b57cec5SDimitry Andric   int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
9810b57cec5SDimitry Andric   bool HasRs = false;
9820b57cec5SDimitry Andric 
9830b57cec5SDimitry Andric   if (Rt == 0)
9840b57cec5SDimitry Andric     return MCDisassembler::Fail;
9850b57cec5SDimitry Andric   else if (Rs == 0)
9860b57cec5SDimitry Andric     MI.setOpcode(Mips::BLEZALC);
9870b57cec5SDimitry Andric   else if (Rs == Rt)
9880b57cec5SDimitry Andric     MI.setOpcode(Mips::BGEZALC);
9890b57cec5SDimitry Andric   else {
9900b57cec5SDimitry Andric     HasRs = true;
9910b57cec5SDimitry Andric     MI.setOpcode(Mips::BGEUC);
9920b57cec5SDimitry Andric   }
9930b57cec5SDimitry Andric 
9940b57cec5SDimitry Andric   if (HasRs)
9950b57cec5SDimitry Andric     MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
9960b57cec5SDimitry Andric                                        Rs)));
9970b57cec5SDimitry Andric   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
9980b57cec5SDimitry Andric                                      Rt)));
9990b57cec5SDimitry Andric 
10000b57cec5SDimitry Andric   MI.addOperand(MCOperand::createImm(Imm));
10010b57cec5SDimitry Andric 
10020b57cec5SDimitry Andric   return MCDisassembler::Success;
10030b57cec5SDimitry Andric }
10040b57cec5SDimitry Andric 
10050b57cec5SDimitry Andric // Override the generated disassembler to produce DEXT all the time. This is
10060b57cec5SDimitry Andric // for feature / behaviour parity with  binutils.
10070b57cec5SDimitry Andric template <typename InsnType>
DecodeDEXT(MCInst & MI,InsnType Insn,uint64_t Address,const MCDisassembler * Decoder)10080b57cec5SDimitry Andric static DecodeStatus DecodeDEXT(MCInst &MI, InsnType Insn, uint64_t Address,
100981ad6265SDimitry Andric                                const MCDisassembler *Decoder) {
10100b57cec5SDimitry Andric   unsigned Msbd = fieldFromInstruction(Insn, 11, 5);
10110b57cec5SDimitry Andric   unsigned Lsb = fieldFromInstruction(Insn, 6, 5);
10120b57cec5SDimitry Andric   unsigned Size = 0;
10130b57cec5SDimitry Andric   unsigned Pos = 0;
10140b57cec5SDimitry Andric 
10150b57cec5SDimitry Andric   switch (MI.getOpcode()) {
10160b57cec5SDimitry Andric     case Mips::DEXT:
10170b57cec5SDimitry Andric       Pos = Lsb;
10180b57cec5SDimitry Andric       Size = Msbd + 1;
10190b57cec5SDimitry Andric       break;
10200b57cec5SDimitry Andric     case Mips::DEXTM:
10210b57cec5SDimitry Andric       Pos = Lsb;
10220b57cec5SDimitry Andric       Size = Msbd + 1 + 32;
10230b57cec5SDimitry Andric       break;
10240b57cec5SDimitry Andric     case Mips::DEXTU:
10250b57cec5SDimitry Andric       Pos = Lsb + 32;
10260b57cec5SDimitry Andric       Size = Msbd + 1;
10270b57cec5SDimitry Andric       break;
10280b57cec5SDimitry Andric     default:
10290b57cec5SDimitry Andric       llvm_unreachable("Unknown DEXT instruction!");
10300b57cec5SDimitry Andric   }
10310b57cec5SDimitry Andric 
10320b57cec5SDimitry Andric   MI.setOpcode(Mips::DEXT);
10330b57cec5SDimitry Andric 
10340b57cec5SDimitry Andric   InsnType Rs = fieldFromInstruction(Insn, 21, 5);
10350b57cec5SDimitry Andric   InsnType Rt = fieldFromInstruction(Insn, 16, 5);
10360b57cec5SDimitry Andric 
1037480093f4SDimitry Andric   MI.addOperand(
1038480093f4SDimitry Andric       MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID, Rt)));
1039480093f4SDimitry Andric   MI.addOperand(
1040480093f4SDimitry Andric       MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID, Rs)));
10410b57cec5SDimitry Andric   MI.addOperand(MCOperand::createImm(Pos));
10420b57cec5SDimitry Andric   MI.addOperand(MCOperand::createImm(Size));
10430b57cec5SDimitry Andric 
10440b57cec5SDimitry Andric   return MCDisassembler::Success;
10450b57cec5SDimitry Andric }
10460b57cec5SDimitry Andric 
10470b57cec5SDimitry Andric // Override the generated disassembler to produce DINS all the time. This is
10480b57cec5SDimitry Andric // for feature / behaviour parity with binutils.
10490b57cec5SDimitry Andric template <typename InsnType>
DecodeDINS(MCInst & MI,InsnType Insn,uint64_t Address,const MCDisassembler * Decoder)10500b57cec5SDimitry Andric static DecodeStatus DecodeDINS(MCInst &MI, InsnType Insn, uint64_t Address,
105181ad6265SDimitry Andric                                const MCDisassembler *Decoder) {
10520b57cec5SDimitry Andric   unsigned Msbd = fieldFromInstruction(Insn, 11, 5);
10530b57cec5SDimitry Andric   unsigned Lsb = fieldFromInstruction(Insn, 6, 5);
10540b57cec5SDimitry Andric   unsigned Size = 0;
10550b57cec5SDimitry Andric   unsigned Pos = 0;
10560b57cec5SDimitry Andric 
10570b57cec5SDimitry Andric   switch (MI.getOpcode()) {
10580b57cec5SDimitry Andric     case Mips::DINS:
10590b57cec5SDimitry Andric       Pos = Lsb;
10600b57cec5SDimitry Andric       Size = Msbd + 1 - Pos;
10610b57cec5SDimitry Andric       break;
10620b57cec5SDimitry Andric     case Mips::DINSM:
10630b57cec5SDimitry Andric       Pos = Lsb;
10640b57cec5SDimitry Andric       Size = Msbd + 33 - Pos;
10650b57cec5SDimitry Andric       break;
10660b57cec5SDimitry Andric     case Mips::DINSU:
10670b57cec5SDimitry Andric       Pos = Lsb + 32;
10680b57cec5SDimitry Andric       // mbsd = pos + size - 33
10690b57cec5SDimitry Andric       // mbsd - pos + 33 = size
10700b57cec5SDimitry Andric       Size = Msbd + 33 - Pos;
10710b57cec5SDimitry Andric       break;
10720b57cec5SDimitry Andric     default:
10730b57cec5SDimitry Andric       llvm_unreachable("Unknown DINS instruction!");
10740b57cec5SDimitry Andric   }
10750b57cec5SDimitry Andric 
10760b57cec5SDimitry Andric   InsnType Rs = fieldFromInstruction(Insn, 21, 5);
10770b57cec5SDimitry Andric   InsnType Rt = fieldFromInstruction(Insn, 16, 5);
10780b57cec5SDimitry Andric 
10790b57cec5SDimitry Andric   MI.setOpcode(Mips::DINS);
1080480093f4SDimitry Andric   MI.addOperand(
1081480093f4SDimitry Andric       MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID, Rt)));
1082480093f4SDimitry Andric   MI.addOperand(
1083480093f4SDimitry Andric       MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID, Rs)));
10840b57cec5SDimitry Andric   MI.addOperand(MCOperand::createImm(Pos));
10850b57cec5SDimitry Andric   MI.addOperand(MCOperand::createImm(Size));
10860b57cec5SDimitry Andric 
10870b57cec5SDimitry Andric   return MCDisassembler::Success;
10880b57cec5SDimitry Andric }
10890b57cec5SDimitry Andric 
10900b57cec5SDimitry Andric // Auto-generated decoder wouldn't add the third operand for CRC32*.
10910b57cec5SDimitry Andric template <typename InsnType>
DecodeCRC(MCInst & MI,InsnType Insn,uint64_t Address,const MCDisassembler * Decoder)10920b57cec5SDimitry Andric static DecodeStatus DecodeCRC(MCInst &MI, InsnType Insn, uint64_t Address,
109381ad6265SDimitry Andric                               const MCDisassembler *Decoder) {
10940b57cec5SDimitry Andric   InsnType Rs = fieldFromInstruction(Insn, 21, 5);
10950b57cec5SDimitry Andric   InsnType Rt = fieldFromInstruction(Insn, 16, 5);
10960b57cec5SDimitry Andric   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
10970b57cec5SDimitry Andric                                      Rt)));
10980b57cec5SDimitry Andric   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
10990b57cec5SDimitry Andric                                      Rs)));
11000b57cec5SDimitry Andric   MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
11010b57cec5SDimitry Andric                                      Rt)));
11020b57cec5SDimitry Andric   return MCDisassembler::Success;
11030b57cec5SDimitry Andric }
11040b57cec5SDimitry Andric 
11050b57cec5SDimitry Andric /// Read two bytes from the ArrayRef and return 16 bit halfword sorted
11060b57cec5SDimitry Andric /// according to the given endianness.
readInstruction16(ArrayRef<uint8_t> Bytes,uint64_t Address,uint64_t & Size,uint32_t & Insn,bool IsBigEndian)11070b57cec5SDimitry Andric static DecodeStatus readInstruction16(ArrayRef<uint8_t> Bytes, uint64_t Address,
11080b57cec5SDimitry Andric                                       uint64_t &Size, uint32_t &Insn,
11090b57cec5SDimitry Andric                                       bool IsBigEndian) {
11100b57cec5SDimitry Andric   // We want to read exactly 2 Bytes of data.
11110b57cec5SDimitry Andric   if (Bytes.size() < 2) {
11120b57cec5SDimitry Andric     Size = 0;
11130b57cec5SDimitry Andric     return MCDisassembler::Fail;
11140b57cec5SDimitry Andric   }
11150b57cec5SDimitry Andric 
11160b57cec5SDimitry Andric   if (IsBigEndian) {
11170b57cec5SDimitry Andric     Insn = (Bytes[0] << 8) | Bytes[1];
11180b57cec5SDimitry Andric   } else {
11190b57cec5SDimitry Andric     Insn = (Bytes[1] << 8) | Bytes[0];
11200b57cec5SDimitry Andric   }
11210b57cec5SDimitry Andric 
11220b57cec5SDimitry Andric   return MCDisassembler::Success;
11230b57cec5SDimitry Andric }
11240b57cec5SDimitry Andric 
11250b57cec5SDimitry Andric /// Read four bytes from the ArrayRef and return 32 bit word sorted
11260b57cec5SDimitry Andric /// according to the given endianness.
readInstruction32(ArrayRef<uint8_t> Bytes,uint64_t Address,uint64_t & Size,uint32_t & Insn,bool IsBigEndian,bool IsMicroMips)11270b57cec5SDimitry Andric static DecodeStatus readInstruction32(ArrayRef<uint8_t> Bytes, uint64_t Address,
11280b57cec5SDimitry Andric                                       uint64_t &Size, uint32_t &Insn,
11290b57cec5SDimitry Andric                                       bool IsBigEndian, bool IsMicroMips) {
11300b57cec5SDimitry Andric   // We want to read exactly 4 Bytes of data.
11310b57cec5SDimitry Andric   if (Bytes.size() < 4) {
11320b57cec5SDimitry Andric     Size = 0;
11330b57cec5SDimitry Andric     return MCDisassembler::Fail;
11340b57cec5SDimitry Andric   }
11350b57cec5SDimitry Andric 
11360b57cec5SDimitry Andric   // High 16 bits of a 32-bit microMIPS instruction (where the opcode is)
11370b57cec5SDimitry Andric   // always precede the low 16 bits in the instruction stream (that is, they
11380b57cec5SDimitry Andric   // are placed at lower addresses in the instruction stream).
11390b57cec5SDimitry Andric   //
11400b57cec5SDimitry Andric   // microMIPS byte ordering:
11410b57cec5SDimitry Andric   //   Big-endian:    0 | 1 | 2 | 3
11420b57cec5SDimitry Andric   //   Little-endian: 1 | 0 | 3 | 2
11430b57cec5SDimitry Andric 
11440b57cec5SDimitry Andric   if (IsBigEndian) {
11450b57cec5SDimitry Andric     // Encoded as a big-endian 32-bit word in the stream.
11460b57cec5SDimitry Andric     Insn =
11470b57cec5SDimitry Andric         (Bytes[3] << 0) | (Bytes[2] << 8) | (Bytes[1] << 16) | (Bytes[0] << 24);
11480b57cec5SDimitry Andric   } else {
11490b57cec5SDimitry Andric     if (IsMicroMips) {
11500b57cec5SDimitry Andric       Insn = (Bytes[2] << 0) | (Bytes[3] << 8) | (Bytes[0] << 16) |
11510b57cec5SDimitry Andric              (Bytes[1] << 24);
11520b57cec5SDimitry Andric     } else {
11530b57cec5SDimitry Andric       Insn = (Bytes[0] << 0) | (Bytes[1] << 8) | (Bytes[2] << 16) |
11540b57cec5SDimitry Andric              (Bytes[3] << 24);
11550b57cec5SDimitry Andric     }
11560b57cec5SDimitry Andric   }
11570b57cec5SDimitry Andric 
11580b57cec5SDimitry Andric   return MCDisassembler::Success;
11590b57cec5SDimitry Andric }
11600b57cec5SDimitry Andric 
getInstruction(MCInst & Instr,uint64_t & Size,ArrayRef<uint8_t> Bytes,uint64_t Address,raw_ostream & CStream) const11610b57cec5SDimitry Andric DecodeStatus MipsDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,
11620b57cec5SDimitry Andric                                               ArrayRef<uint8_t> Bytes,
11630b57cec5SDimitry Andric                                               uint64_t Address,
11640b57cec5SDimitry Andric                                               raw_ostream &CStream) const {
11650b57cec5SDimitry Andric   uint32_t Insn;
11660b57cec5SDimitry Andric   DecodeStatus Result;
11670b57cec5SDimitry Andric   Size = 0;
11680b57cec5SDimitry Andric 
11690b57cec5SDimitry Andric   if (IsMicroMips) {
11700b57cec5SDimitry Andric     Result = readInstruction16(Bytes, Address, Size, Insn, IsBigEndian);
11710b57cec5SDimitry Andric     if (Result == MCDisassembler::Fail)
11720b57cec5SDimitry Andric       return MCDisassembler::Fail;
11730b57cec5SDimitry Andric 
11740b57cec5SDimitry Andric     if (hasMips32r6()) {
11750b57cec5SDimitry Andric       LLVM_DEBUG(
11760b57cec5SDimitry Andric           dbgs() << "Trying MicroMipsR616 table (16-bit instructions):\n");
11770b57cec5SDimitry Andric       // Calling the auto-generated decoder function for microMIPS32R6
11780b57cec5SDimitry Andric       // 16-bit instructions.
11790b57cec5SDimitry Andric       Result = decodeInstruction(DecoderTableMicroMipsR616, Instr, Insn,
11800b57cec5SDimitry Andric                                  Address, this, STI);
11810b57cec5SDimitry Andric       if (Result != MCDisassembler::Fail) {
11820b57cec5SDimitry Andric         Size = 2;
11830b57cec5SDimitry Andric         return Result;
11840b57cec5SDimitry Andric       }
11850b57cec5SDimitry Andric     }
11860b57cec5SDimitry Andric 
11870b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "Trying MicroMips16 table (16-bit instructions):\n");
11880b57cec5SDimitry Andric     // Calling the auto-generated decoder function for microMIPS 16-bit
11890b57cec5SDimitry Andric     // instructions.
11900b57cec5SDimitry Andric     Result = decodeInstruction(DecoderTableMicroMips16, Instr, Insn, Address,
11910b57cec5SDimitry Andric                                this, STI);
11920b57cec5SDimitry Andric     if (Result != MCDisassembler::Fail) {
11930b57cec5SDimitry Andric       Size = 2;
11940b57cec5SDimitry Andric       return Result;
11950b57cec5SDimitry Andric     }
11960b57cec5SDimitry Andric 
11970b57cec5SDimitry Andric     Result = readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, true);
11980b57cec5SDimitry Andric     if (Result == MCDisassembler::Fail)
11990b57cec5SDimitry Andric       return MCDisassembler::Fail;
12000b57cec5SDimitry Andric 
12010b57cec5SDimitry Andric     if (hasMips32r6()) {
12020b57cec5SDimitry Andric       LLVM_DEBUG(
12030b57cec5SDimitry Andric           dbgs() << "Trying MicroMips32r632 table (32-bit instructions):\n");
12040b57cec5SDimitry Andric       // Calling the auto-generated decoder function.
1205480093f4SDimitry Andric       Result = decodeInstruction(DecoderTableMicroMipsR632, Instr, Insn,
1206480093f4SDimitry Andric                                  Address, this, STI);
12070b57cec5SDimitry Andric       if (Result != MCDisassembler::Fail) {
12080b57cec5SDimitry Andric         Size = 4;
12090b57cec5SDimitry Andric         return Result;
12100b57cec5SDimitry Andric       }
12110b57cec5SDimitry Andric     }
12120b57cec5SDimitry Andric 
12130b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "Trying MicroMips32 table (32-bit instructions):\n");
12140b57cec5SDimitry Andric     // Calling the auto-generated decoder function.
12150b57cec5SDimitry Andric     Result = decodeInstruction(DecoderTableMicroMips32, Instr, Insn, Address,
12160b57cec5SDimitry Andric                                this, STI);
12170b57cec5SDimitry Andric     if (Result != MCDisassembler::Fail) {
12180b57cec5SDimitry Andric       Size = 4;
12190b57cec5SDimitry Andric       return Result;
12200b57cec5SDimitry Andric     }
12210b57cec5SDimitry Andric 
12220b57cec5SDimitry Andric     if (isFP64()) {
12230b57cec5SDimitry Andric       LLVM_DEBUG(dbgs() << "Trying MicroMipsFP64 table (32-bit opcodes):\n");
12240b57cec5SDimitry Andric       Result = decodeInstruction(DecoderTableMicroMipsFP6432, Instr, Insn,
12250b57cec5SDimitry Andric                                  Address, this, STI);
12260b57cec5SDimitry Andric       if (Result != MCDisassembler::Fail) {
12270b57cec5SDimitry Andric         Size = 4;
12280b57cec5SDimitry Andric         return Result;
12290b57cec5SDimitry Andric       }
12300b57cec5SDimitry Andric     }
12310b57cec5SDimitry Andric 
12320b57cec5SDimitry Andric     // This is an invalid instruction. Claim that the Size is 2 bytes. Since
12330b57cec5SDimitry Andric     // microMIPS instructions have a minimum alignment of 2, the next 2 bytes
12340b57cec5SDimitry Andric     // could form a valid instruction. The two bytes we rejected as an
12350b57cec5SDimitry Andric     // instruction could have actually beeen an inline constant pool that is
12360b57cec5SDimitry Andric     // unconditionally branched over.
12370b57cec5SDimitry Andric     Size = 2;
12380b57cec5SDimitry Andric     return MCDisassembler::Fail;
12390b57cec5SDimitry Andric   }
12400b57cec5SDimitry Andric 
12410b57cec5SDimitry Andric   // Attempt to read the instruction so that we can attempt to decode it. If
12420b57cec5SDimitry Andric   // the buffer is not 4 bytes long, let the higher level logic figure out
12430b57cec5SDimitry Andric   // what to do with a size of zero and MCDisassembler::Fail.
12440b57cec5SDimitry Andric   Result = readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, false);
12450b57cec5SDimitry Andric   if (Result == MCDisassembler::Fail)
12460b57cec5SDimitry Andric     return MCDisassembler::Fail;
12470b57cec5SDimitry Andric 
12480b57cec5SDimitry Andric   // The only instruction size for standard encoded MIPS.
12490b57cec5SDimitry Andric   Size = 4;
12500b57cec5SDimitry Andric 
12510b57cec5SDimitry Andric   if (hasCOP3()) {
12520b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "Trying COP3_ table (32-bit opcodes):\n");
12530b57cec5SDimitry Andric     Result =
12540b57cec5SDimitry Andric         decodeInstruction(DecoderTableCOP3_32, Instr, Insn, Address, this, STI);
12550b57cec5SDimitry Andric     if (Result != MCDisassembler::Fail)
12560b57cec5SDimitry Andric       return Result;
12570b57cec5SDimitry Andric   }
12580b57cec5SDimitry Andric 
12590b57cec5SDimitry Andric   if (hasMips32r6() && isGP64()) {
12600b57cec5SDimitry Andric     LLVM_DEBUG(
12610b57cec5SDimitry Andric         dbgs() << "Trying Mips32r6_64r6 (GPR64) table (32-bit opcodes):\n");
12620b57cec5SDimitry Andric     Result = decodeInstruction(DecoderTableMips32r6_64r6_GP6432, Instr, Insn,
12630b57cec5SDimitry Andric                                Address, this, STI);
12640b57cec5SDimitry Andric     if (Result != MCDisassembler::Fail)
12650b57cec5SDimitry Andric       return Result;
12660b57cec5SDimitry Andric   }
12670b57cec5SDimitry Andric 
12680b57cec5SDimitry Andric   if (hasMips32r6() && isPTR64()) {
12690b57cec5SDimitry Andric     LLVM_DEBUG(
12700b57cec5SDimitry Andric         dbgs() << "Trying Mips32r6_64r6 (PTR64) table (32-bit opcodes):\n");
12710b57cec5SDimitry Andric     Result = decodeInstruction(DecoderTableMips32r6_64r6_PTR6432, Instr, Insn,
12720b57cec5SDimitry Andric                                Address, this, STI);
12730b57cec5SDimitry Andric     if (Result != MCDisassembler::Fail)
12740b57cec5SDimitry Andric       return Result;
12750b57cec5SDimitry Andric   }
12760b57cec5SDimitry Andric 
12770b57cec5SDimitry Andric   if (hasMips32r6()) {
12780b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "Trying Mips32r6_64r6 table (32-bit opcodes):\n");
12790b57cec5SDimitry Andric     Result = decodeInstruction(DecoderTableMips32r6_64r632, Instr, Insn,
12800b57cec5SDimitry Andric                                Address, this, STI);
12810b57cec5SDimitry Andric     if (Result != MCDisassembler::Fail)
12820b57cec5SDimitry Andric       return Result;
12830b57cec5SDimitry Andric   }
12840b57cec5SDimitry Andric 
12850b57cec5SDimitry Andric   if (hasMips2() && isPTR64()) {
12860b57cec5SDimitry Andric     LLVM_DEBUG(
12870b57cec5SDimitry Andric         dbgs() << "Trying Mips32r6_64r6 (PTR64) table (32-bit opcodes):\n");
12880b57cec5SDimitry Andric     Result = decodeInstruction(DecoderTableMips32_64_PTR6432, Instr, Insn,
12890b57cec5SDimitry Andric                                Address, this, STI);
12900b57cec5SDimitry Andric     if (Result != MCDisassembler::Fail)
12910b57cec5SDimitry Andric       return Result;
12920b57cec5SDimitry Andric   }
12930b57cec5SDimitry Andric 
12940b57cec5SDimitry Andric   if (hasCnMips()) {
12950b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "Trying CnMips table (32-bit opcodes):\n");
12960b57cec5SDimitry Andric     Result = decodeInstruction(DecoderTableCnMips32, Instr, Insn,
12970b57cec5SDimitry Andric                                Address, this, STI);
12980b57cec5SDimitry Andric     if (Result != MCDisassembler::Fail)
12990b57cec5SDimitry Andric       return Result;
13000b57cec5SDimitry Andric   }
13010b57cec5SDimitry Andric 
13020b57cec5SDimitry Andric   if (hasCnMipsP()) {
13030b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "Trying CnMipsP table (32-bit opcodes):\n");
13040b57cec5SDimitry Andric     Result = decodeInstruction(DecoderTableCnMipsP32, Instr, Insn,
13050b57cec5SDimitry Andric                                Address, this, STI);
13060b57cec5SDimitry Andric     if (Result != MCDisassembler::Fail)
13070b57cec5SDimitry Andric       return Result;
13080b57cec5SDimitry Andric   }
13090b57cec5SDimitry Andric 
13100b57cec5SDimitry Andric   if (isGP64()) {
13110b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "Trying Mips64 (GPR64) table (32-bit opcodes):\n");
13120b57cec5SDimitry Andric     Result = decodeInstruction(DecoderTableMips6432, Instr, Insn,
13130b57cec5SDimitry Andric                                Address, this, STI);
13140b57cec5SDimitry Andric     if (Result != MCDisassembler::Fail)
13150b57cec5SDimitry Andric       return Result;
13160b57cec5SDimitry Andric   }
13170b57cec5SDimitry Andric 
13180b57cec5SDimitry Andric   if (isFP64()) {
13190b57cec5SDimitry Andric     LLVM_DEBUG(
13200b57cec5SDimitry Andric         dbgs() << "Trying MipsFP64 (64 bit FPU) table (32-bit opcodes):\n");
13210b57cec5SDimitry Andric     Result = decodeInstruction(DecoderTableMipsFP6432, Instr, Insn,
13220b57cec5SDimitry Andric                                Address, this, STI);
13230b57cec5SDimitry Andric     if (Result != MCDisassembler::Fail)
13240b57cec5SDimitry Andric       return Result;
13250b57cec5SDimitry Andric   }
13260b57cec5SDimitry Andric 
13270b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "Trying Mips table (32-bit opcodes):\n");
13280b57cec5SDimitry Andric   // Calling the auto-generated decoder function.
13290b57cec5SDimitry Andric   Result =
13300b57cec5SDimitry Andric       decodeInstruction(DecoderTableMips32, Instr, Insn, Address, this, STI);
13310b57cec5SDimitry Andric   if (Result != MCDisassembler::Fail)
13320b57cec5SDimitry Andric     return Result;
13330b57cec5SDimitry Andric 
13340b57cec5SDimitry Andric   return MCDisassembler::Fail;
13350b57cec5SDimitry Andric }
13360b57cec5SDimitry Andric 
133781ad6265SDimitry Andric static DecodeStatus
DecodeCPU16RegsRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)133881ad6265SDimitry Andric DecodeCPU16RegsRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address,
133981ad6265SDimitry Andric                              const MCDisassembler *Decoder) {
13400b57cec5SDimitry Andric   return MCDisassembler::Fail;
13410b57cec5SDimitry Andric }
13420b57cec5SDimitry Andric 
DecodeGPR64RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)134381ad6265SDimitry Andric static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst, unsigned RegNo,
13440b57cec5SDimitry Andric                                              uint64_t Address,
134581ad6265SDimitry Andric                                              const MCDisassembler *Decoder) {
13460b57cec5SDimitry Andric   if (RegNo > 31)
13470b57cec5SDimitry Andric     return MCDisassembler::Fail;
13480b57cec5SDimitry Andric 
13490b57cec5SDimitry Andric   unsigned Reg = getReg(Decoder, Mips::GPR64RegClassID, RegNo);
13500b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
13510b57cec5SDimitry Andric   return MCDisassembler::Success;
13520b57cec5SDimitry Andric }
13530b57cec5SDimitry Andric 
DecodeGPRMM16RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)135481ad6265SDimitry Andric static DecodeStatus DecodeGPRMM16RegisterClass(MCInst &Inst, unsigned RegNo,
13550b57cec5SDimitry Andric                                                uint64_t Address,
135681ad6265SDimitry Andric                                                const MCDisassembler *Decoder) {
13570b57cec5SDimitry Andric   if (RegNo > 7)
13580b57cec5SDimitry Andric     return MCDisassembler::Fail;
13590b57cec5SDimitry Andric   unsigned Reg = getReg(Decoder, Mips::GPRMM16RegClassID, RegNo);
13600b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
13610b57cec5SDimitry Andric   return MCDisassembler::Success;
13620b57cec5SDimitry Andric }
13630b57cec5SDimitry Andric 
136481ad6265SDimitry Andric static DecodeStatus
DecodeGPRMM16ZeroRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)136581ad6265SDimitry Andric DecodeGPRMM16ZeroRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address,
136681ad6265SDimitry Andric                                const MCDisassembler *Decoder) {
13670b57cec5SDimitry Andric   if (RegNo > 7)
13680b57cec5SDimitry Andric     return MCDisassembler::Fail;
13690b57cec5SDimitry Andric   unsigned Reg = getReg(Decoder, Mips::GPRMM16ZeroRegClassID, RegNo);
13700b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
13710b57cec5SDimitry Andric   return MCDisassembler::Success;
13720b57cec5SDimitry Andric }
13730b57cec5SDimitry Andric 
137481ad6265SDimitry Andric static DecodeStatus
DecodeGPRMM16MovePRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)137581ad6265SDimitry Andric DecodeGPRMM16MovePRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address,
137681ad6265SDimitry Andric                                 const MCDisassembler *Decoder) {
13770b57cec5SDimitry Andric   if (RegNo > 7)
13780b57cec5SDimitry Andric     return MCDisassembler::Fail;
13790b57cec5SDimitry Andric   unsigned Reg = getReg(Decoder, Mips::GPRMM16MovePRegClassID, RegNo);
13800b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
13810b57cec5SDimitry Andric   return MCDisassembler::Success;
13820b57cec5SDimitry Andric }
13830b57cec5SDimitry Andric 
DecodeGPR32RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)138481ad6265SDimitry Andric static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst, unsigned RegNo,
13850b57cec5SDimitry Andric                                              uint64_t Address,
138681ad6265SDimitry Andric                                              const MCDisassembler *Decoder) {
13870b57cec5SDimitry Andric   if (RegNo > 31)
13880b57cec5SDimitry Andric     return MCDisassembler::Fail;
13890b57cec5SDimitry Andric   unsigned Reg = getReg(Decoder, Mips::GPR32RegClassID, RegNo);
13900b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
13910b57cec5SDimitry Andric   return MCDisassembler::Success;
13920b57cec5SDimitry Andric }
13930b57cec5SDimitry Andric 
DecodePtrRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)139481ad6265SDimitry Andric static DecodeStatus DecodePtrRegisterClass(MCInst &Inst, unsigned RegNo,
13950b57cec5SDimitry Andric                                            uint64_t Address,
139681ad6265SDimitry Andric                                            const MCDisassembler *Decoder) {
13970b57cec5SDimitry Andric   if (static_cast<const MipsDisassembler *>(Decoder)->isGP64())
13980b57cec5SDimitry Andric     return DecodeGPR64RegisterClass(Inst, RegNo, Address, Decoder);
13990b57cec5SDimitry Andric 
14000b57cec5SDimitry Andric   return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
14010b57cec5SDimitry Andric }
14020b57cec5SDimitry Andric 
DecodeDSPRRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)140381ad6265SDimitry Andric static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst, unsigned RegNo,
14040b57cec5SDimitry Andric                                             uint64_t Address,
140581ad6265SDimitry Andric                                             const MCDisassembler *Decoder) {
14060b57cec5SDimitry Andric   return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
14070b57cec5SDimitry Andric }
14080b57cec5SDimitry Andric 
DecodeFGR64RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)140981ad6265SDimitry Andric static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst, unsigned RegNo,
14100b57cec5SDimitry Andric                                              uint64_t Address,
141181ad6265SDimitry Andric                                              const MCDisassembler *Decoder) {
14120b57cec5SDimitry Andric   if (RegNo > 31)
14130b57cec5SDimitry Andric     return MCDisassembler::Fail;
14140b57cec5SDimitry Andric 
14150b57cec5SDimitry Andric   unsigned Reg = getReg(Decoder, Mips::FGR64RegClassID, RegNo);
14160b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
14170b57cec5SDimitry Andric   return MCDisassembler::Success;
14180b57cec5SDimitry Andric }
14190b57cec5SDimitry Andric 
DecodeFGR32RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)142081ad6265SDimitry Andric static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst, unsigned RegNo,
14210b57cec5SDimitry Andric                                              uint64_t Address,
142281ad6265SDimitry Andric                                              const MCDisassembler *Decoder) {
14230b57cec5SDimitry Andric   if (RegNo > 31)
14240b57cec5SDimitry Andric     return MCDisassembler::Fail;
14250b57cec5SDimitry Andric 
14260b57cec5SDimitry Andric   unsigned Reg = getReg(Decoder, Mips::FGR32RegClassID, RegNo);
14270b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
14280b57cec5SDimitry Andric   return MCDisassembler::Success;
14290b57cec5SDimitry Andric }
14300b57cec5SDimitry Andric 
DecodeCCRRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)143181ad6265SDimitry Andric static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst, unsigned RegNo,
14320b57cec5SDimitry Andric                                            uint64_t Address,
143381ad6265SDimitry Andric                                            const MCDisassembler *Decoder) {
14340b57cec5SDimitry Andric   if (RegNo > 31)
14350b57cec5SDimitry Andric     return MCDisassembler::Fail;
14360b57cec5SDimitry Andric   unsigned Reg = getReg(Decoder, Mips::CCRRegClassID, RegNo);
14370b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
14380b57cec5SDimitry Andric   return MCDisassembler::Success;
14390b57cec5SDimitry Andric }
14400b57cec5SDimitry Andric 
DecodeFCCRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)144181ad6265SDimitry Andric static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst, unsigned RegNo,
14420b57cec5SDimitry Andric                                            uint64_t Address,
144381ad6265SDimitry Andric                                            const MCDisassembler *Decoder) {
14440b57cec5SDimitry Andric   if (RegNo > 7)
14450b57cec5SDimitry Andric     return MCDisassembler::Fail;
14460b57cec5SDimitry Andric   unsigned Reg = getReg(Decoder, Mips::FCCRegClassID, RegNo);
14470b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
14480b57cec5SDimitry Andric   return MCDisassembler::Success;
14490b57cec5SDimitry Andric }
14500b57cec5SDimitry Andric 
DecodeFGRCCRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)14510b57cec5SDimitry Andric static DecodeStatus DecodeFGRCCRegisterClass(MCInst &Inst, unsigned RegNo,
14520b57cec5SDimitry Andric                                              uint64_t Address,
145381ad6265SDimitry Andric                                              const MCDisassembler *Decoder) {
14540b57cec5SDimitry Andric   if (RegNo > 31)
14550b57cec5SDimitry Andric     return MCDisassembler::Fail;
14560b57cec5SDimitry Andric 
14570b57cec5SDimitry Andric   unsigned Reg = getReg(Decoder, Mips::FGRCCRegClassID, RegNo);
14580b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
14590b57cec5SDimitry Andric   return MCDisassembler::Success;
14600b57cec5SDimitry Andric }
14610b57cec5SDimitry Andric 
DecodeMem(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)146281ad6265SDimitry Andric static DecodeStatus DecodeMem(MCInst &Inst, unsigned Insn, uint64_t Address,
146381ad6265SDimitry Andric                               const MCDisassembler *Decoder) {
14640b57cec5SDimitry Andric   int Offset = SignExtend32<16>(Insn & 0xffff);
14650b57cec5SDimitry Andric   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
14660b57cec5SDimitry Andric   unsigned Base = fieldFromInstruction(Insn, 21, 5);
14670b57cec5SDimitry Andric 
14680b57cec5SDimitry Andric   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
14690b57cec5SDimitry Andric   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
14700b57cec5SDimitry Andric 
14710b57cec5SDimitry Andric   if (Inst.getOpcode() == Mips::SC ||
14720b57cec5SDimitry Andric       Inst.getOpcode() == Mips::SCD)
14730b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(Reg));
14740b57cec5SDimitry Andric 
14750b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
14760b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Base));
14770b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Offset));
14780b57cec5SDimitry Andric 
14790b57cec5SDimitry Andric   return MCDisassembler::Success;
14800b57cec5SDimitry Andric }
14810b57cec5SDimitry Andric 
DecodeMemEVA(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)148281ad6265SDimitry Andric static DecodeStatus DecodeMemEVA(MCInst &Inst, unsigned Insn, uint64_t Address,
148381ad6265SDimitry Andric                                  const MCDisassembler *Decoder) {
14840b57cec5SDimitry Andric   int Offset = SignExtend32<9>(Insn >> 7);
14850b57cec5SDimitry Andric   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
14860b57cec5SDimitry Andric   unsigned Base = fieldFromInstruction(Insn, 21, 5);
14870b57cec5SDimitry Andric 
14880b57cec5SDimitry Andric   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
14890b57cec5SDimitry Andric   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
14900b57cec5SDimitry Andric 
14910b57cec5SDimitry Andric    if (Inst.getOpcode() == Mips::SCE)
14920b57cec5SDimitry Andric      Inst.addOperand(MCOperand::createReg(Reg));
14930b57cec5SDimitry Andric 
14940b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
14950b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Base));
14960b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Offset));
14970b57cec5SDimitry Andric 
14980b57cec5SDimitry Andric   return MCDisassembler::Success;
14990b57cec5SDimitry Andric }
15000b57cec5SDimitry Andric 
DecodeLoadByte15(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)150181ad6265SDimitry Andric static DecodeStatus DecodeLoadByte15(MCInst &Inst, unsigned Insn,
15020b57cec5SDimitry Andric                                      uint64_t Address,
150381ad6265SDimitry Andric                                      const MCDisassembler *Decoder) {
15040b57cec5SDimitry Andric   int Offset = SignExtend32<16>(Insn & 0xffff);
15050b57cec5SDimitry Andric   unsigned Base = fieldFromInstruction(Insn, 16, 5);
15060b57cec5SDimitry Andric   unsigned Reg = fieldFromInstruction(Insn, 21, 5);
15070b57cec5SDimitry Andric 
15080b57cec5SDimitry Andric   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
15090b57cec5SDimitry Andric   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
15100b57cec5SDimitry Andric 
15110b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
15120b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Base));
15130b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Offset));
15140b57cec5SDimitry Andric 
15150b57cec5SDimitry Andric   return MCDisassembler::Success;
15160b57cec5SDimitry Andric }
15170b57cec5SDimitry Andric 
DecodeCacheOp(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)151881ad6265SDimitry Andric static DecodeStatus DecodeCacheOp(MCInst &Inst, unsigned Insn, uint64_t Address,
151981ad6265SDimitry Andric                                   const MCDisassembler *Decoder) {
15200b57cec5SDimitry Andric   int Offset = SignExtend32<16>(Insn & 0xffff);
15210b57cec5SDimitry Andric   unsigned Hint = fieldFromInstruction(Insn, 16, 5);
15220b57cec5SDimitry Andric   unsigned Base = fieldFromInstruction(Insn, 21, 5);
15230b57cec5SDimitry Andric 
15240b57cec5SDimitry Andric   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
15250b57cec5SDimitry Andric 
15260b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Base));
15270b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Offset));
15280b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Hint));
15290b57cec5SDimitry Andric 
15300b57cec5SDimitry Andric   return MCDisassembler::Success;
15310b57cec5SDimitry Andric }
15320b57cec5SDimitry Andric 
DecodeCacheOpMM(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)153381ad6265SDimitry Andric static DecodeStatus DecodeCacheOpMM(MCInst &Inst, unsigned Insn,
15340b57cec5SDimitry Andric                                     uint64_t Address,
153581ad6265SDimitry Andric                                     const MCDisassembler *Decoder) {
15360b57cec5SDimitry Andric   int Offset = SignExtend32<12>(Insn & 0xfff);
15370b57cec5SDimitry Andric   unsigned Base = fieldFromInstruction(Insn, 16, 5);
15380b57cec5SDimitry Andric   unsigned Hint = fieldFromInstruction(Insn, 21, 5);
15390b57cec5SDimitry Andric 
15400b57cec5SDimitry Andric   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
15410b57cec5SDimitry Andric 
15420b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Base));
15430b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Offset));
15440b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Hint));
15450b57cec5SDimitry Andric 
15460b57cec5SDimitry Andric   return MCDisassembler::Success;
15470b57cec5SDimitry Andric }
15480b57cec5SDimitry Andric 
DecodePrefeOpMM(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)154981ad6265SDimitry Andric static DecodeStatus DecodePrefeOpMM(MCInst &Inst, unsigned Insn,
15500b57cec5SDimitry Andric                                     uint64_t Address,
155181ad6265SDimitry Andric                                     const MCDisassembler *Decoder) {
15520b57cec5SDimitry Andric   int Offset = SignExtend32<9>(Insn & 0x1ff);
15530b57cec5SDimitry Andric   unsigned Base = fieldFromInstruction(Insn, 16, 5);
15540b57cec5SDimitry Andric   unsigned Hint = fieldFromInstruction(Insn, 21, 5);
15550b57cec5SDimitry Andric 
15560b57cec5SDimitry Andric   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
15570b57cec5SDimitry Andric 
15580b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Base));
15590b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Offset));
15600b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Hint));
15610b57cec5SDimitry Andric 
15620b57cec5SDimitry Andric   return MCDisassembler::Success;
15630b57cec5SDimitry Andric }
15640b57cec5SDimitry Andric 
DecodeCacheeOp_CacheOpR6(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)156581ad6265SDimitry Andric static DecodeStatus DecodeCacheeOp_CacheOpR6(MCInst &Inst, unsigned Insn,
15660b57cec5SDimitry Andric                                              uint64_t Address,
156781ad6265SDimitry Andric                                              const MCDisassembler *Decoder) {
15680b57cec5SDimitry Andric   int Offset = SignExtend32<9>(Insn >> 7);
15690b57cec5SDimitry Andric   unsigned Hint = fieldFromInstruction(Insn, 16, 5);
15700b57cec5SDimitry Andric   unsigned Base = fieldFromInstruction(Insn, 21, 5);
15710b57cec5SDimitry Andric 
15720b57cec5SDimitry Andric   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
15730b57cec5SDimitry Andric 
15740b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Base));
15750b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Offset));
15760b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Hint));
15770b57cec5SDimitry Andric 
15780b57cec5SDimitry Andric   return MCDisassembler::Success;
15790b57cec5SDimitry Andric }
15800b57cec5SDimitry Andric 
DecodeSyncI(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)158181ad6265SDimitry Andric static DecodeStatus DecodeSyncI(MCInst &Inst, unsigned Insn, uint64_t Address,
158281ad6265SDimitry Andric                                 const MCDisassembler *Decoder) {
15830b57cec5SDimitry Andric   int Offset = SignExtend32<16>(Insn & 0xffff);
15840b57cec5SDimitry Andric   unsigned Base = fieldFromInstruction(Insn, 21, 5);
15850b57cec5SDimitry Andric 
15860b57cec5SDimitry Andric   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
15870b57cec5SDimitry Andric 
15880b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Base));
15890b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Offset));
15900b57cec5SDimitry Andric 
15910b57cec5SDimitry Andric   return MCDisassembler::Success;
15920b57cec5SDimitry Andric }
15930b57cec5SDimitry Andric 
DecodeSyncI_MM(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)15940b57cec5SDimitry Andric static DecodeStatus DecodeSyncI_MM(MCInst &Inst, unsigned Insn,
159581ad6265SDimitry Andric                                    uint64_t Address,
159681ad6265SDimitry Andric                                    const MCDisassembler *Decoder) {
15970b57cec5SDimitry Andric   int Offset = SignExtend32<16>(Insn & 0xffff);
15980b57cec5SDimitry Andric   unsigned Base = fieldFromInstruction(Insn, 16, 5);
15990b57cec5SDimitry Andric 
16000b57cec5SDimitry Andric   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
16010b57cec5SDimitry Andric 
16020b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Base));
16030b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Offset));
16040b57cec5SDimitry Andric 
16050b57cec5SDimitry Andric   return MCDisassembler::Success;
16060b57cec5SDimitry Andric }
16070b57cec5SDimitry Andric 
DecodeSynciR6(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)160881ad6265SDimitry Andric static DecodeStatus DecodeSynciR6(MCInst &Inst, unsigned Insn, uint64_t Address,
160981ad6265SDimitry Andric                                   const MCDisassembler *Decoder) {
16100b57cec5SDimitry Andric   int Immediate = SignExtend32<16>(Insn & 0xffff);
16110b57cec5SDimitry Andric   unsigned Base = fieldFromInstruction(Insn, 16, 5);
16120b57cec5SDimitry Andric 
16130b57cec5SDimitry Andric   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
16140b57cec5SDimitry Andric 
16150b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Base));
16160b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Immediate));
16170b57cec5SDimitry Andric 
16180b57cec5SDimitry Andric   return MCDisassembler::Success;
16190b57cec5SDimitry Andric }
16200b57cec5SDimitry Andric 
DecodeMSA128Mem(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)16210b57cec5SDimitry Andric static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn,
162281ad6265SDimitry Andric                                     uint64_t Address,
162381ad6265SDimitry Andric                                     const MCDisassembler *Decoder) {
16240b57cec5SDimitry Andric   int Offset = SignExtend32<10>(fieldFromInstruction(Insn, 16, 10));
16250b57cec5SDimitry Andric   unsigned Reg = fieldFromInstruction(Insn, 6, 5);
16260b57cec5SDimitry Andric   unsigned Base = fieldFromInstruction(Insn, 11, 5);
16270b57cec5SDimitry Andric 
16280b57cec5SDimitry Andric   Reg = getReg(Decoder, Mips::MSA128BRegClassID, Reg);
16290b57cec5SDimitry Andric   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
16300b57cec5SDimitry Andric 
16310b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
16320b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Base));
16330b57cec5SDimitry Andric 
16340b57cec5SDimitry Andric   // The immediate field of an LD/ST instruction is scaled which means it must
16350b57cec5SDimitry Andric   // be multiplied (when decoding) by the size (in bytes) of the instructions'
16360b57cec5SDimitry Andric   // data format.
16370b57cec5SDimitry Andric   // .b - 1 byte
16380b57cec5SDimitry Andric   // .h - 2 bytes
16390b57cec5SDimitry Andric   // .w - 4 bytes
16400b57cec5SDimitry Andric   // .d - 8 bytes
16410b57cec5SDimitry Andric   switch(Inst.getOpcode())
16420b57cec5SDimitry Andric   {
16430b57cec5SDimitry Andric   default:
16440b57cec5SDimitry Andric     assert(false && "Unexpected instruction");
16450b57cec5SDimitry Andric     return MCDisassembler::Fail;
16460b57cec5SDimitry Andric     break;
16470b57cec5SDimitry Andric   case Mips::LD_B:
16480b57cec5SDimitry Andric   case Mips::ST_B:
16490b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(Offset));
16500b57cec5SDimitry Andric     break;
16510b57cec5SDimitry Andric   case Mips::LD_H:
16520b57cec5SDimitry Andric   case Mips::ST_H:
16530b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(Offset * 2));
16540b57cec5SDimitry Andric     break;
16550b57cec5SDimitry Andric   case Mips::LD_W:
16560b57cec5SDimitry Andric   case Mips::ST_W:
16570b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(Offset * 4));
16580b57cec5SDimitry Andric     break;
16590b57cec5SDimitry Andric   case Mips::LD_D:
16600b57cec5SDimitry Andric   case Mips::ST_D:
16610b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(Offset * 8));
16620b57cec5SDimitry Andric     break;
16630b57cec5SDimitry Andric   }
16640b57cec5SDimitry Andric 
16650b57cec5SDimitry Andric   return MCDisassembler::Success;
16660b57cec5SDimitry Andric }
16670b57cec5SDimitry Andric 
DecodeMemMMImm4(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)166881ad6265SDimitry Andric static DecodeStatus DecodeMemMMImm4(MCInst &Inst, unsigned Insn,
16690b57cec5SDimitry Andric                                     uint64_t Address,
167081ad6265SDimitry Andric                                     const MCDisassembler *Decoder) {
16710b57cec5SDimitry Andric   unsigned Offset = Insn & 0xf;
16720b57cec5SDimitry Andric   unsigned Reg = fieldFromInstruction(Insn, 7, 3);
16730b57cec5SDimitry Andric   unsigned Base = fieldFromInstruction(Insn, 4, 3);
16740b57cec5SDimitry Andric 
16750b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
16760b57cec5SDimitry Andric     case Mips::LBU16_MM:
16770b57cec5SDimitry Andric     case Mips::LHU16_MM:
16780b57cec5SDimitry Andric     case Mips::LW16_MM:
16790b57cec5SDimitry Andric       if (DecodeGPRMM16RegisterClass(Inst, Reg, Address, Decoder)
16800b57cec5SDimitry Andric             == MCDisassembler::Fail)
16810b57cec5SDimitry Andric         return MCDisassembler::Fail;
16820b57cec5SDimitry Andric       break;
16830b57cec5SDimitry Andric     case Mips::SB16_MM:
16840b57cec5SDimitry Andric     case Mips::SB16_MMR6:
16850b57cec5SDimitry Andric     case Mips::SH16_MM:
16860b57cec5SDimitry Andric     case Mips::SH16_MMR6:
16870b57cec5SDimitry Andric     case Mips::SW16_MM:
16880b57cec5SDimitry Andric     case Mips::SW16_MMR6:
16890b57cec5SDimitry Andric       if (DecodeGPRMM16ZeroRegisterClass(Inst, Reg, Address, Decoder)
16900b57cec5SDimitry Andric             == MCDisassembler::Fail)
16910b57cec5SDimitry Andric         return MCDisassembler::Fail;
16920b57cec5SDimitry Andric       break;
16930b57cec5SDimitry Andric   }
16940b57cec5SDimitry Andric 
16950b57cec5SDimitry Andric   if (DecodeGPRMM16RegisterClass(Inst, Base, Address, Decoder)
16960b57cec5SDimitry Andric         == MCDisassembler::Fail)
16970b57cec5SDimitry Andric     return MCDisassembler::Fail;
16980b57cec5SDimitry Andric 
16990b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
17000b57cec5SDimitry Andric     case Mips::LBU16_MM:
17010b57cec5SDimitry Andric       if (Offset == 0xf)
17020b57cec5SDimitry Andric         Inst.addOperand(MCOperand::createImm(-1));
17030b57cec5SDimitry Andric       else
17040b57cec5SDimitry Andric         Inst.addOperand(MCOperand::createImm(Offset));
17050b57cec5SDimitry Andric       break;
17060b57cec5SDimitry Andric     case Mips::SB16_MM:
17070b57cec5SDimitry Andric     case Mips::SB16_MMR6:
17080b57cec5SDimitry Andric       Inst.addOperand(MCOperand::createImm(Offset));
17090b57cec5SDimitry Andric       break;
17100b57cec5SDimitry Andric     case Mips::LHU16_MM:
17110b57cec5SDimitry Andric     case Mips::SH16_MM:
17120b57cec5SDimitry Andric     case Mips::SH16_MMR6:
17130b57cec5SDimitry Andric       Inst.addOperand(MCOperand::createImm(Offset << 1));
17140b57cec5SDimitry Andric       break;
17150b57cec5SDimitry Andric     case Mips::LW16_MM:
17160b57cec5SDimitry Andric     case Mips::SW16_MM:
17170b57cec5SDimitry Andric     case Mips::SW16_MMR6:
17180b57cec5SDimitry Andric       Inst.addOperand(MCOperand::createImm(Offset << 2));
17190b57cec5SDimitry Andric       break;
17200b57cec5SDimitry Andric   }
17210b57cec5SDimitry Andric 
17220b57cec5SDimitry Andric   return MCDisassembler::Success;
17230b57cec5SDimitry Andric }
17240b57cec5SDimitry Andric 
DecodeMemMMSPImm5Lsl2(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)172581ad6265SDimitry Andric static DecodeStatus DecodeMemMMSPImm5Lsl2(MCInst &Inst, unsigned Insn,
17260b57cec5SDimitry Andric                                           uint64_t Address,
172781ad6265SDimitry Andric                                           const MCDisassembler *Decoder) {
17280b57cec5SDimitry Andric   unsigned Offset = Insn & 0x1F;
17290b57cec5SDimitry Andric   unsigned Reg = fieldFromInstruction(Insn, 5, 5);
17300b57cec5SDimitry Andric 
17310b57cec5SDimitry Andric   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
17320b57cec5SDimitry Andric 
17330b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
17340b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Mips::SP));
17350b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Offset << 2));
17360b57cec5SDimitry Andric 
17370b57cec5SDimitry Andric   return MCDisassembler::Success;
17380b57cec5SDimitry Andric }
17390b57cec5SDimitry Andric 
DecodeMemMMGPImm7Lsl2(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)174081ad6265SDimitry Andric static DecodeStatus DecodeMemMMGPImm7Lsl2(MCInst &Inst, unsigned Insn,
17410b57cec5SDimitry Andric                                           uint64_t Address,
174281ad6265SDimitry Andric                                           const MCDisassembler *Decoder) {
17430b57cec5SDimitry Andric   unsigned Offset = Insn & 0x7F;
17440b57cec5SDimitry Andric   unsigned Reg = fieldFromInstruction(Insn, 7, 3);
17450b57cec5SDimitry Andric 
17460b57cec5SDimitry Andric   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
17470b57cec5SDimitry Andric 
17480b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
17490b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Mips::GP));
17500b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Offset << 2));
17510b57cec5SDimitry Andric 
17520b57cec5SDimitry Andric   return MCDisassembler::Success;
17530b57cec5SDimitry Andric }
17540b57cec5SDimitry Andric 
DecodeMemMMReglistImm4Lsl2(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)175581ad6265SDimitry Andric static DecodeStatus DecodeMemMMReglistImm4Lsl2(MCInst &Inst, unsigned Insn,
17560b57cec5SDimitry Andric                                                uint64_t Address,
175781ad6265SDimitry Andric                                                const MCDisassembler *Decoder) {
17580b57cec5SDimitry Andric   int Offset;
17590b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
17600b57cec5SDimitry Andric   case Mips::LWM16_MMR6:
17610b57cec5SDimitry Andric   case Mips::SWM16_MMR6:
17620b57cec5SDimitry Andric     Offset = fieldFromInstruction(Insn, 4, 4);
17630b57cec5SDimitry Andric     break;
17640b57cec5SDimitry Andric   default:
17650b57cec5SDimitry Andric     Offset = SignExtend32<4>(Insn & 0xf);
17660b57cec5SDimitry Andric     break;
17670b57cec5SDimitry Andric   }
17680b57cec5SDimitry Andric 
17690b57cec5SDimitry Andric   if (DecodeRegListOperand16(Inst, Insn, Address, Decoder)
17700b57cec5SDimitry Andric       == MCDisassembler::Fail)
17710b57cec5SDimitry Andric     return MCDisassembler::Fail;
17720b57cec5SDimitry Andric 
17730b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Mips::SP));
17740b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Offset << 2));
17750b57cec5SDimitry Andric 
17760b57cec5SDimitry Andric   return MCDisassembler::Success;
17770b57cec5SDimitry Andric }
17780b57cec5SDimitry Andric 
DecodeMemMMImm9(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)177981ad6265SDimitry Andric static DecodeStatus DecodeMemMMImm9(MCInst &Inst, unsigned Insn,
17800b57cec5SDimitry Andric                                     uint64_t Address,
178181ad6265SDimitry Andric                                     const MCDisassembler *Decoder) {
17820b57cec5SDimitry Andric   int Offset = SignExtend32<9>(Insn & 0x1ff);
17830b57cec5SDimitry Andric   unsigned Reg = fieldFromInstruction(Insn, 21, 5);
17840b57cec5SDimitry Andric   unsigned Base = fieldFromInstruction(Insn, 16, 5);
17850b57cec5SDimitry Andric 
17860b57cec5SDimitry Andric   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
17870b57cec5SDimitry Andric   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
17880b57cec5SDimitry Andric 
17890b57cec5SDimitry Andric   if (Inst.getOpcode() == Mips::SCE_MM || Inst.getOpcode() == Mips::SC_MMR6)
17900b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(Reg));
17910b57cec5SDimitry Andric 
17920b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
17930b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Base));
17940b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Offset));
17950b57cec5SDimitry Andric 
17960b57cec5SDimitry Andric   return MCDisassembler::Success;
17970b57cec5SDimitry Andric }
17980b57cec5SDimitry Andric 
DecodeMemMMImm12(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)179981ad6265SDimitry Andric static DecodeStatus DecodeMemMMImm12(MCInst &Inst, unsigned Insn,
18000b57cec5SDimitry Andric                                      uint64_t Address,
180181ad6265SDimitry Andric                                      const MCDisassembler *Decoder) {
18020b57cec5SDimitry Andric   int Offset = SignExtend32<12>(Insn & 0x0fff);
18030b57cec5SDimitry Andric   unsigned Reg = fieldFromInstruction(Insn, 21, 5);
18040b57cec5SDimitry Andric   unsigned Base = fieldFromInstruction(Insn, 16, 5);
18050b57cec5SDimitry Andric 
18060b57cec5SDimitry Andric   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
18070b57cec5SDimitry Andric   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
18080b57cec5SDimitry Andric 
18090b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
18100b57cec5SDimitry Andric   case Mips::SWM32_MM:
18110b57cec5SDimitry Andric   case Mips::LWM32_MM:
18120b57cec5SDimitry Andric     if (DecodeRegListOperand(Inst, Insn, Address, Decoder)
18130b57cec5SDimitry Andric         == MCDisassembler::Fail)
18140b57cec5SDimitry Andric       return MCDisassembler::Fail;
18150b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(Base));
18160b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(Offset));
18170b57cec5SDimitry Andric     break;
18180b57cec5SDimitry Andric   case Mips::SC_MM:
18190b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(Reg));
1820bdd1243dSDimitry Andric     [[fallthrough]];
18210b57cec5SDimitry Andric   default:
18220b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(Reg));
18230b57cec5SDimitry Andric     if (Inst.getOpcode() == Mips::LWP_MM || Inst.getOpcode() == Mips::SWP_MM)
18240b57cec5SDimitry Andric       Inst.addOperand(MCOperand::createReg(Reg+1));
18250b57cec5SDimitry Andric 
18260b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(Base));
18270b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(Offset));
18280b57cec5SDimitry Andric   }
18290b57cec5SDimitry Andric 
18300b57cec5SDimitry Andric   return MCDisassembler::Success;
18310b57cec5SDimitry Andric }
18320b57cec5SDimitry Andric 
DecodeMemMMImm16(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)183381ad6265SDimitry Andric static DecodeStatus DecodeMemMMImm16(MCInst &Inst, unsigned Insn,
18340b57cec5SDimitry Andric                                      uint64_t Address,
183581ad6265SDimitry Andric                                      const MCDisassembler *Decoder) {
18360b57cec5SDimitry Andric   int Offset = SignExtend32<16>(Insn & 0xffff);
18370b57cec5SDimitry Andric   unsigned Reg = fieldFromInstruction(Insn, 21, 5);
18380b57cec5SDimitry Andric   unsigned Base = fieldFromInstruction(Insn, 16, 5);
18390b57cec5SDimitry Andric 
18400b57cec5SDimitry Andric   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
18410b57cec5SDimitry Andric   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
18420b57cec5SDimitry Andric 
18430b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
18440b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Base));
18450b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Offset));
18460b57cec5SDimitry Andric 
18470b57cec5SDimitry Andric   return MCDisassembler::Success;
18480b57cec5SDimitry Andric }
18490b57cec5SDimitry Andric 
DecodeFMem(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)185081ad6265SDimitry Andric static DecodeStatus DecodeFMem(MCInst &Inst, unsigned Insn, uint64_t Address,
185181ad6265SDimitry Andric                                const MCDisassembler *Decoder) {
18520b57cec5SDimitry Andric   int Offset = SignExtend32<16>(Insn & 0xffff);
18530b57cec5SDimitry Andric   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
18540b57cec5SDimitry Andric   unsigned Base = fieldFromInstruction(Insn, 21, 5);
18550b57cec5SDimitry Andric 
18560b57cec5SDimitry Andric   Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg);
18570b57cec5SDimitry Andric   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
18580b57cec5SDimitry Andric 
18590b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
18600b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Base));
18610b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Offset));
18620b57cec5SDimitry Andric 
18630b57cec5SDimitry Andric   return MCDisassembler::Success;
18640b57cec5SDimitry Andric }
18650b57cec5SDimitry Andric 
DecodeFMemMMR2(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)18660b57cec5SDimitry Andric static DecodeStatus DecodeFMemMMR2(MCInst &Inst, unsigned Insn,
186781ad6265SDimitry Andric                                    uint64_t Address,
186881ad6265SDimitry Andric                                    const MCDisassembler *Decoder) {
18690b57cec5SDimitry Andric   // This function is the same as DecodeFMem but with the Reg and Base fields
18700b57cec5SDimitry Andric   // swapped according to microMIPS spec.
18710b57cec5SDimitry Andric   int Offset = SignExtend32<16>(Insn & 0xffff);
18720b57cec5SDimitry Andric   unsigned Base = fieldFromInstruction(Insn, 16, 5);
18730b57cec5SDimitry Andric   unsigned Reg = fieldFromInstruction(Insn, 21, 5);
18740b57cec5SDimitry Andric 
18750b57cec5SDimitry Andric   Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg);
18760b57cec5SDimitry Andric   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
18770b57cec5SDimitry Andric 
18780b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
18790b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Base));
18800b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Offset));
18810b57cec5SDimitry Andric 
18820b57cec5SDimitry Andric   return MCDisassembler::Success;
18830b57cec5SDimitry Andric }
18840b57cec5SDimitry Andric 
DecodeFMem2(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)188581ad6265SDimitry Andric static DecodeStatus DecodeFMem2(MCInst &Inst, unsigned Insn, uint64_t Address,
188681ad6265SDimitry Andric                                 const MCDisassembler *Decoder) {
18870b57cec5SDimitry Andric   int Offset = SignExtend32<16>(Insn & 0xffff);
18880b57cec5SDimitry Andric   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
18890b57cec5SDimitry Andric   unsigned Base = fieldFromInstruction(Insn, 21, 5);
18900b57cec5SDimitry Andric 
18910b57cec5SDimitry Andric   Reg = getReg(Decoder, Mips::COP2RegClassID, Reg);
18920b57cec5SDimitry Andric   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
18930b57cec5SDimitry Andric 
18940b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
18950b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Base));
18960b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Offset));
18970b57cec5SDimitry Andric 
18980b57cec5SDimitry Andric   return MCDisassembler::Success;
18990b57cec5SDimitry Andric }
19000b57cec5SDimitry Andric 
DecodeFMem3(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)190181ad6265SDimitry Andric static DecodeStatus DecodeFMem3(MCInst &Inst, unsigned Insn, uint64_t Address,
190281ad6265SDimitry Andric                                 const MCDisassembler *Decoder) {
19030b57cec5SDimitry Andric   int Offset = SignExtend32<16>(Insn & 0xffff);
19040b57cec5SDimitry Andric   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
19050b57cec5SDimitry Andric   unsigned Base = fieldFromInstruction(Insn, 21, 5);
19060b57cec5SDimitry Andric 
19070b57cec5SDimitry Andric   Reg = getReg(Decoder, Mips::COP3RegClassID, Reg);
19080b57cec5SDimitry Andric   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
19090b57cec5SDimitry Andric 
19100b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
19110b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Base));
19120b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Offset));
19130b57cec5SDimitry Andric 
19140b57cec5SDimitry Andric   return MCDisassembler::Success;
19150b57cec5SDimitry Andric }
19160b57cec5SDimitry Andric 
DecodeFMemCop2R6(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)191781ad6265SDimitry Andric static DecodeStatus DecodeFMemCop2R6(MCInst &Inst, unsigned Insn,
19180b57cec5SDimitry Andric                                      uint64_t Address,
191981ad6265SDimitry Andric                                      const MCDisassembler *Decoder) {
19200b57cec5SDimitry Andric   int Offset = SignExtend32<11>(Insn & 0x07ff);
19210b57cec5SDimitry Andric   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
19220b57cec5SDimitry Andric   unsigned Base = fieldFromInstruction(Insn, 11, 5);
19230b57cec5SDimitry Andric 
19240b57cec5SDimitry Andric   Reg = getReg(Decoder, Mips::COP2RegClassID, Reg);
19250b57cec5SDimitry Andric   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
19260b57cec5SDimitry Andric 
19270b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
19280b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Base));
19290b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Offset));
19300b57cec5SDimitry Andric 
19310b57cec5SDimitry Andric   return MCDisassembler::Success;
19320b57cec5SDimitry Andric }
19330b57cec5SDimitry Andric 
DecodeFMemCop2MMR6(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)19340b57cec5SDimitry Andric static DecodeStatus DecodeFMemCop2MMR6(MCInst &Inst, unsigned Insn,
193581ad6265SDimitry Andric                                        uint64_t Address,
193681ad6265SDimitry Andric                                        const MCDisassembler *Decoder) {
19370b57cec5SDimitry Andric   int Offset = SignExtend32<11>(Insn & 0x07ff);
19380b57cec5SDimitry Andric   unsigned Reg = fieldFromInstruction(Insn, 21, 5);
19390b57cec5SDimitry Andric   unsigned Base = fieldFromInstruction(Insn, 16, 5);
19400b57cec5SDimitry Andric 
19410b57cec5SDimitry Andric   Reg = getReg(Decoder, Mips::COP2RegClassID, Reg);
19420b57cec5SDimitry Andric   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
19430b57cec5SDimitry Andric 
19440b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
19450b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Base));
19460b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Offset));
19470b57cec5SDimitry Andric 
19480b57cec5SDimitry Andric   return MCDisassembler::Success;
19490b57cec5SDimitry Andric }
19500b57cec5SDimitry Andric 
DecodeSpecial3LlSc(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)195181ad6265SDimitry Andric static DecodeStatus DecodeSpecial3LlSc(MCInst &Inst, unsigned Insn,
19520b57cec5SDimitry Andric                                        uint64_t Address,
195381ad6265SDimitry Andric                                        const MCDisassembler *Decoder) {
19540b57cec5SDimitry Andric   int64_t Offset = SignExtend64<9>((Insn >> 7) & 0x1ff);
19550b57cec5SDimitry Andric   unsigned Rt = fieldFromInstruction(Insn, 16, 5);
19560b57cec5SDimitry Andric   unsigned Base = fieldFromInstruction(Insn, 21, 5);
19570b57cec5SDimitry Andric 
19580b57cec5SDimitry Andric   Rt = getReg(Decoder, Mips::GPR32RegClassID, Rt);
19590b57cec5SDimitry Andric   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
19600b57cec5SDimitry Andric 
19610b57cec5SDimitry Andric   if(Inst.getOpcode() == Mips::SC_R6 || Inst.getOpcode() == Mips::SCD_R6){
19620b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(Rt));
19630b57cec5SDimitry Andric   }
19640b57cec5SDimitry Andric 
19650b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Rt));
19660b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Base));
19670b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Offset));
19680b57cec5SDimitry Andric 
19690b57cec5SDimitry Andric   return MCDisassembler::Success;
19700b57cec5SDimitry Andric }
19710b57cec5SDimitry Andric 
DecodeHWRegsRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)197281ad6265SDimitry Andric static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst, unsigned RegNo,
19730b57cec5SDimitry Andric                                               uint64_t Address,
197481ad6265SDimitry Andric                                               const MCDisassembler *Decoder) {
19750b57cec5SDimitry Andric   // Currently only hardware register 29 is supported.
19760b57cec5SDimitry Andric   if (RegNo != 29)
19770b57cec5SDimitry Andric     return  MCDisassembler::Fail;
19780b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Mips::HWR29));
19790b57cec5SDimitry Andric   return MCDisassembler::Success;
19800b57cec5SDimitry Andric }
19810b57cec5SDimitry Andric 
DecodeAFGR64RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)198281ad6265SDimitry Andric static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst, unsigned RegNo,
19830b57cec5SDimitry Andric                                               uint64_t Address,
198481ad6265SDimitry Andric                                               const MCDisassembler *Decoder) {
19850b57cec5SDimitry Andric   if (RegNo > 30 || RegNo %2)
19860b57cec5SDimitry Andric     return MCDisassembler::Fail;
19870b57cec5SDimitry Andric 
19880b57cec5SDimitry Andric   unsigned Reg = getReg(Decoder, Mips::AFGR64RegClassID, RegNo /2);
19890b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
19900b57cec5SDimitry Andric   return MCDisassembler::Success;
19910b57cec5SDimitry Andric }
19920b57cec5SDimitry Andric 
DecodeACC64DSPRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)199381ad6265SDimitry Andric static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst, unsigned RegNo,
19940b57cec5SDimitry Andric                                                 uint64_t Address,
199581ad6265SDimitry Andric                                                 const MCDisassembler *Decoder) {
19960b57cec5SDimitry Andric   if (RegNo >= 4)
19970b57cec5SDimitry Andric     return MCDisassembler::Fail;
19980b57cec5SDimitry Andric 
19990b57cec5SDimitry Andric   unsigned Reg = getReg(Decoder, Mips::ACC64DSPRegClassID, RegNo);
20000b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
20010b57cec5SDimitry Andric   return MCDisassembler::Success;
20020b57cec5SDimitry Andric }
20030b57cec5SDimitry Andric 
DecodeHI32DSPRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)200481ad6265SDimitry Andric static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst, unsigned RegNo,
20050b57cec5SDimitry Andric                                                uint64_t Address,
200681ad6265SDimitry Andric                                                const MCDisassembler *Decoder) {
20070b57cec5SDimitry Andric   if (RegNo >= 4)
20080b57cec5SDimitry Andric     return MCDisassembler::Fail;
20090b57cec5SDimitry Andric 
20100b57cec5SDimitry Andric   unsigned Reg = getReg(Decoder, Mips::HI32DSPRegClassID, RegNo);
20110b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
20120b57cec5SDimitry Andric   return MCDisassembler::Success;
20130b57cec5SDimitry Andric }
20140b57cec5SDimitry Andric 
DecodeLO32DSPRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)201581ad6265SDimitry Andric static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst, unsigned RegNo,
20160b57cec5SDimitry Andric                                                uint64_t Address,
201781ad6265SDimitry Andric                                                const MCDisassembler *Decoder) {
20180b57cec5SDimitry Andric   if (RegNo >= 4)
20190b57cec5SDimitry Andric     return MCDisassembler::Fail;
20200b57cec5SDimitry Andric 
20210b57cec5SDimitry Andric   unsigned Reg = getReg(Decoder, Mips::LO32DSPRegClassID, RegNo);
20220b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
20230b57cec5SDimitry Andric   return MCDisassembler::Success;
20240b57cec5SDimitry Andric }
20250b57cec5SDimitry Andric 
DecodeMSA128BRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)202681ad6265SDimitry Andric static DecodeStatus DecodeMSA128BRegisterClass(MCInst &Inst, unsigned RegNo,
20270b57cec5SDimitry Andric                                                uint64_t Address,
202881ad6265SDimitry Andric                                                const MCDisassembler *Decoder) {
20290b57cec5SDimitry Andric   if (RegNo > 31)
20300b57cec5SDimitry Andric     return MCDisassembler::Fail;
20310b57cec5SDimitry Andric 
20320b57cec5SDimitry Andric   unsigned Reg = getReg(Decoder, Mips::MSA128BRegClassID, RegNo);
20330b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
20340b57cec5SDimitry Andric   return MCDisassembler::Success;
20350b57cec5SDimitry Andric }
20360b57cec5SDimitry Andric 
DecodeMSA128HRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)203781ad6265SDimitry Andric static DecodeStatus DecodeMSA128HRegisterClass(MCInst &Inst, unsigned RegNo,
20380b57cec5SDimitry Andric                                                uint64_t Address,
203981ad6265SDimitry Andric                                                const MCDisassembler *Decoder) {
20400b57cec5SDimitry Andric   if (RegNo > 31)
20410b57cec5SDimitry Andric     return MCDisassembler::Fail;
20420b57cec5SDimitry Andric 
20430b57cec5SDimitry Andric   unsigned Reg = getReg(Decoder, Mips::MSA128HRegClassID, RegNo);
20440b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
20450b57cec5SDimitry Andric   return MCDisassembler::Success;
20460b57cec5SDimitry Andric }
20470b57cec5SDimitry Andric 
DecodeMSA128WRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)204881ad6265SDimitry Andric static DecodeStatus DecodeMSA128WRegisterClass(MCInst &Inst, unsigned RegNo,
20490b57cec5SDimitry Andric                                                uint64_t Address,
205081ad6265SDimitry Andric                                                const MCDisassembler *Decoder) {
20510b57cec5SDimitry Andric   if (RegNo > 31)
20520b57cec5SDimitry Andric     return MCDisassembler::Fail;
20530b57cec5SDimitry Andric 
20540b57cec5SDimitry Andric   unsigned Reg = getReg(Decoder, Mips::MSA128WRegClassID, RegNo);
20550b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
20560b57cec5SDimitry Andric   return MCDisassembler::Success;
20570b57cec5SDimitry Andric }
20580b57cec5SDimitry Andric 
DecodeMSA128DRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)205981ad6265SDimitry Andric static DecodeStatus DecodeMSA128DRegisterClass(MCInst &Inst, unsigned RegNo,
20600b57cec5SDimitry Andric                                                uint64_t Address,
206181ad6265SDimitry Andric                                                const MCDisassembler *Decoder) {
20620b57cec5SDimitry Andric   if (RegNo > 31)
20630b57cec5SDimitry Andric     return MCDisassembler::Fail;
20640b57cec5SDimitry Andric 
20650b57cec5SDimitry Andric   unsigned Reg = getReg(Decoder, Mips::MSA128DRegClassID, RegNo);
20660b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
20670b57cec5SDimitry Andric   return MCDisassembler::Success;
20680b57cec5SDimitry Andric }
20690b57cec5SDimitry Andric 
DecodeMSACtrlRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)207081ad6265SDimitry Andric static DecodeStatus DecodeMSACtrlRegisterClass(MCInst &Inst, unsigned RegNo,
20710b57cec5SDimitry Andric                                                uint64_t Address,
207281ad6265SDimitry Andric                                                const MCDisassembler *Decoder) {
20730b57cec5SDimitry Andric   if (RegNo > 7)
20740b57cec5SDimitry Andric     return MCDisassembler::Fail;
20750b57cec5SDimitry Andric 
20760b57cec5SDimitry Andric   unsigned Reg = getReg(Decoder, Mips::MSACtrlRegClassID, RegNo);
20770b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
20780b57cec5SDimitry Andric   return MCDisassembler::Success;
20790b57cec5SDimitry Andric }
20800b57cec5SDimitry Andric 
DecodeCOP0RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)208181ad6265SDimitry Andric static DecodeStatus DecodeCOP0RegisterClass(MCInst &Inst, unsigned RegNo,
20820b57cec5SDimitry Andric                                             uint64_t Address,
208381ad6265SDimitry Andric                                             const MCDisassembler *Decoder) {
20840b57cec5SDimitry Andric   if (RegNo > 31)
20850b57cec5SDimitry Andric     return MCDisassembler::Fail;
20860b57cec5SDimitry Andric 
20870b57cec5SDimitry Andric   unsigned Reg = getReg(Decoder, Mips::COP0RegClassID, RegNo);
20880b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
20890b57cec5SDimitry Andric   return MCDisassembler::Success;
20900b57cec5SDimitry Andric }
20910b57cec5SDimitry Andric 
DecodeCOP2RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)209281ad6265SDimitry Andric static DecodeStatus DecodeCOP2RegisterClass(MCInst &Inst, unsigned RegNo,
20930b57cec5SDimitry Andric                                             uint64_t Address,
209481ad6265SDimitry Andric                                             const MCDisassembler *Decoder) {
20950b57cec5SDimitry Andric   if (RegNo > 31)
20960b57cec5SDimitry Andric     return MCDisassembler::Fail;
20970b57cec5SDimitry Andric 
20980b57cec5SDimitry Andric   unsigned Reg = getReg(Decoder, Mips::COP2RegClassID, RegNo);
20990b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
21000b57cec5SDimitry Andric   return MCDisassembler::Success;
21010b57cec5SDimitry Andric }
21020b57cec5SDimitry Andric 
DecodeBranchTarget(MCInst & Inst,unsigned Offset,uint64_t Address,const MCDisassembler * Decoder)210381ad6265SDimitry Andric static DecodeStatus DecodeBranchTarget(MCInst &Inst, unsigned Offset,
21040b57cec5SDimitry Andric                                        uint64_t Address,
210581ad6265SDimitry Andric                                        const MCDisassembler *Decoder) {
21060b57cec5SDimitry Andric   int32_t BranchOffset = (SignExtend32<16>(Offset) * 4) + 4;
21070b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(BranchOffset));
21080b57cec5SDimitry Andric   return MCDisassembler::Success;
21090b57cec5SDimitry Andric }
21100b57cec5SDimitry Andric 
DecodeBranchTarget1SImm16(MCInst & Inst,unsigned Offset,uint64_t Address,const MCDisassembler * Decoder)211181ad6265SDimitry Andric static DecodeStatus DecodeBranchTarget1SImm16(MCInst &Inst, unsigned Offset,
21120b57cec5SDimitry Andric                                               uint64_t Address,
211381ad6265SDimitry Andric                                               const MCDisassembler *Decoder) {
21140b57cec5SDimitry Andric   int32_t BranchOffset = (SignExtend32<16>(Offset) * 2);
21150b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(BranchOffset));
21160b57cec5SDimitry Andric   return MCDisassembler::Success;
21170b57cec5SDimitry Andric }
21180b57cec5SDimitry Andric 
DecodeJumpTarget(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)211981ad6265SDimitry Andric static DecodeStatus DecodeJumpTarget(MCInst &Inst, unsigned Insn,
21200b57cec5SDimitry Andric                                      uint64_t Address,
212181ad6265SDimitry Andric                                      const MCDisassembler *Decoder) {
21220b57cec5SDimitry Andric   unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 2;
21230b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(JumpOffset));
21240b57cec5SDimitry Andric   return MCDisassembler::Success;
21250b57cec5SDimitry Andric }
21260b57cec5SDimitry Andric 
DecodeBranchTarget21(MCInst & Inst,unsigned Offset,uint64_t Address,const MCDisassembler * Decoder)212781ad6265SDimitry Andric static DecodeStatus DecodeBranchTarget21(MCInst &Inst, unsigned Offset,
21280b57cec5SDimitry Andric                                          uint64_t Address,
212981ad6265SDimitry Andric                                          const MCDisassembler *Decoder) {
21300b57cec5SDimitry Andric   int32_t BranchOffset = SignExtend32<21>(Offset) * 4 + 4;
21310b57cec5SDimitry Andric 
21320b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(BranchOffset));
21330b57cec5SDimitry Andric   return MCDisassembler::Success;
21340b57cec5SDimitry Andric }
21350b57cec5SDimitry Andric 
DecodeBranchTarget21MM(MCInst & Inst,unsigned Offset,uint64_t Address,const MCDisassembler * Decoder)213681ad6265SDimitry Andric static DecodeStatus DecodeBranchTarget21MM(MCInst &Inst, unsigned Offset,
21370b57cec5SDimitry Andric                                            uint64_t Address,
213881ad6265SDimitry Andric                                            const MCDisassembler *Decoder) {
21390b57cec5SDimitry Andric   int32_t BranchOffset = SignExtend32<21>(Offset) * 4 + 4;
21400b57cec5SDimitry Andric 
21410b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(BranchOffset));
21420b57cec5SDimitry Andric   return MCDisassembler::Success;
21430b57cec5SDimitry Andric }
21440b57cec5SDimitry Andric 
DecodeBranchTarget26(MCInst & Inst,unsigned Offset,uint64_t Address,const MCDisassembler * Decoder)214581ad6265SDimitry Andric static DecodeStatus DecodeBranchTarget26(MCInst &Inst, unsigned Offset,
21460b57cec5SDimitry Andric                                          uint64_t Address,
214781ad6265SDimitry Andric                                          const MCDisassembler *Decoder) {
21480b57cec5SDimitry Andric   int32_t BranchOffset = SignExtend32<26>(Offset) * 4 + 4;
21490b57cec5SDimitry Andric 
21500b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(BranchOffset));
21510b57cec5SDimitry Andric   return MCDisassembler::Success;
21520b57cec5SDimitry Andric }
21530b57cec5SDimitry Andric 
DecodeBranchTarget7MM(MCInst & Inst,unsigned Offset,uint64_t Address,const MCDisassembler * Decoder)215481ad6265SDimitry Andric static DecodeStatus DecodeBranchTarget7MM(MCInst &Inst, unsigned Offset,
21550b57cec5SDimitry Andric                                           uint64_t Address,
215681ad6265SDimitry Andric                                           const MCDisassembler *Decoder) {
21570b57cec5SDimitry Andric   int32_t BranchOffset = SignExtend32<8>(Offset << 1);
21580b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(BranchOffset));
21590b57cec5SDimitry Andric   return MCDisassembler::Success;
21600b57cec5SDimitry Andric }
21610b57cec5SDimitry Andric 
DecodeBranchTarget10MM(MCInst & Inst,unsigned Offset,uint64_t Address,const MCDisassembler * Decoder)216281ad6265SDimitry Andric static DecodeStatus DecodeBranchTarget10MM(MCInst &Inst, unsigned Offset,
21630b57cec5SDimitry Andric                                            uint64_t Address,
216481ad6265SDimitry Andric                                            const MCDisassembler *Decoder) {
21650b57cec5SDimitry Andric   int32_t BranchOffset = SignExtend32<11>(Offset << 1);
21660b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(BranchOffset));
21670b57cec5SDimitry Andric   return MCDisassembler::Success;
21680b57cec5SDimitry Andric }
21690b57cec5SDimitry Andric 
DecodeBranchTargetMM(MCInst & Inst,unsigned Offset,uint64_t Address,const MCDisassembler * Decoder)217081ad6265SDimitry Andric static DecodeStatus DecodeBranchTargetMM(MCInst &Inst, unsigned Offset,
21710b57cec5SDimitry Andric                                          uint64_t Address,
217281ad6265SDimitry Andric                                          const MCDisassembler *Decoder) {
21730b57cec5SDimitry Andric   int32_t BranchOffset = SignExtend32<16>(Offset) * 2 + 4;
21740b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(BranchOffset));
21750b57cec5SDimitry Andric   return MCDisassembler::Success;
21760b57cec5SDimitry Andric }
21770b57cec5SDimitry Andric 
DecodeBranchTarget26MM(MCInst & Inst,unsigned Offset,uint64_t Address,const MCDisassembler * Decoder)217881ad6265SDimitry Andric static DecodeStatus DecodeBranchTarget26MM(MCInst &Inst, unsigned Offset,
21790b57cec5SDimitry Andric                                            uint64_t Address,
218081ad6265SDimitry Andric                                            const MCDisassembler *Decoder) {
21810b57cec5SDimitry Andric   int32_t BranchOffset = SignExtend32<27>(Offset << 1);
21820b57cec5SDimitry Andric 
21830b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(BranchOffset));
21840b57cec5SDimitry Andric   return MCDisassembler::Success;
21850b57cec5SDimitry Andric }
21860b57cec5SDimitry Andric 
DecodeJumpTargetMM(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)218781ad6265SDimitry Andric static DecodeStatus DecodeJumpTargetMM(MCInst &Inst, unsigned Insn,
21880b57cec5SDimitry Andric                                        uint64_t Address,
218981ad6265SDimitry Andric                                        const MCDisassembler *Decoder) {
21900b57cec5SDimitry Andric   unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 1;
21910b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(JumpOffset));
21920b57cec5SDimitry Andric   return MCDisassembler::Success;
21930b57cec5SDimitry Andric }
21940b57cec5SDimitry Andric 
DecodeJumpTargetXMM(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)219581ad6265SDimitry Andric static DecodeStatus DecodeJumpTargetXMM(MCInst &Inst, unsigned Insn,
21968bcb0991SDimitry Andric                                         uint64_t Address,
219781ad6265SDimitry Andric                                         const MCDisassembler *Decoder) {
21988bcb0991SDimitry Andric   unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 2;
21998bcb0991SDimitry Andric   Inst.addOperand(MCOperand::createImm(JumpOffset));
22008bcb0991SDimitry Andric   return MCDisassembler::Success;
22018bcb0991SDimitry Andric }
22028bcb0991SDimitry Andric 
DecodeAddiur2Simm7(MCInst & Inst,unsigned Value,uint64_t Address,const MCDisassembler * Decoder)220381ad6265SDimitry Andric static DecodeStatus DecodeAddiur2Simm7(MCInst &Inst, unsigned Value,
22040b57cec5SDimitry Andric                                        uint64_t Address,
220581ad6265SDimitry Andric                                        const MCDisassembler *Decoder) {
22060b57cec5SDimitry Andric   if (Value == 0)
22070b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(1));
22080b57cec5SDimitry Andric   else if (Value == 0x7)
22090b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(-1));
22100b57cec5SDimitry Andric   else
22110b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(Value << 2));
22120b57cec5SDimitry Andric   return MCDisassembler::Success;
22130b57cec5SDimitry Andric }
22140b57cec5SDimitry Andric 
DecodeLi16Imm(MCInst & Inst,unsigned Value,uint64_t Address,const MCDisassembler * Decoder)221581ad6265SDimitry Andric static DecodeStatus DecodeLi16Imm(MCInst &Inst, unsigned Value,
22160b57cec5SDimitry Andric                                   uint64_t Address,
221781ad6265SDimitry Andric                                   const MCDisassembler *Decoder) {
22180b57cec5SDimitry Andric   if (Value == 0x7F)
22190b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(-1));
22200b57cec5SDimitry Andric   else
22210b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(Value));
22220b57cec5SDimitry Andric   return MCDisassembler::Success;
22230b57cec5SDimitry Andric }
22240b57cec5SDimitry Andric 
DecodePOOL16BEncodedField(MCInst & Inst,unsigned Value,uint64_t Address,const MCDisassembler * Decoder)222581ad6265SDimitry Andric static DecodeStatus DecodePOOL16BEncodedField(MCInst &Inst, unsigned Value,
22260b57cec5SDimitry Andric                                               uint64_t Address,
222781ad6265SDimitry Andric                                               const MCDisassembler *Decoder) {
22280b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Value == 0x0 ? 8 : Value));
22290b57cec5SDimitry Andric   return MCDisassembler::Success;
22300b57cec5SDimitry Andric }
22310b57cec5SDimitry Andric 
22320b57cec5SDimitry Andric template <unsigned Bits, int Offset, int Scale>
223381ad6265SDimitry Andric static DecodeStatus
DecodeUImmWithOffsetAndScale(MCInst & Inst,unsigned Value,uint64_t Address,const MCDisassembler * Decoder)223481ad6265SDimitry Andric DecodeUImmWithOffsetAndScale(MCInst &Inst, unsigned Value, uint64_t Address,
223581ad6265SDimitry Andric                              const MCDisassembler *Decoder) {
22360b57cec5SDimitry Andric   Value &= ((1 << Bits) - 1);
22370b57cec5SDimitry Andric   Value *= Scale;
22380b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Value + Offset));
22390b57cec5SDimitry Andric   return MCDisassembler::Success;
22400b57cec5SDimitry Andric }
22410b57cec5SDimitry Andric 
22420b57cec5SDimitry Andric template <unsigned Bits, int Offset, int ScaleBy>
224381ad6265SDimitry Andric static DecodeStatus
DecodeSImmWithOffsetAndScale(MCInst & Inst,unsigned Value,uint64_t Address,const MCDisassembler * Decoder)224481ad6265SDimitry Andric DecodeSImmWithOffsetAndScale(MCInst &Inst, unsigned Value, uint64_t Address,
224581ad6265SDimitry Andric                              const MCDisassembler *Decoder) {
22460b57cec5SDimitry Andric   int32_t Imm = SignExtend32<Bits>(Value) * ScaleBy;
22470b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Imm + Offset));
22480b57cec5SDimitry Andric   return MCDisassembler::Success;
22490b57cec5SDimitry Andric }
22500b57cec5SDimitry Andric 
DecodeInsSize(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)225181ad6265SDimitry Andric static DecodeStatus DecodeInsSize(MCInst &Inst, unsigned Insn, uint64_t Address,
225281ad6265SDimitry Andric                                   const MCDisassembler *Decoder) {
22530b57cec5SDimitry Andric   // First we need to grab the pos(lsb) from MCInst.
22540b57cec5SDimitry Andric   // This function only handles the 32 bit variants of ins, as dins
22550b57cec5SDimitry Andric   // variants are handled differently.
22560b57cec5SDimitry Andric   int Pos = Inst.getOperand(2).getImm();
22570b57cec5SDimitry Andric   int Size = (int) Insn - Pos + 1;
22580b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(SignExtend32<16>(Size)));
22590b57cec5SDimitry Andric   return MCDisassembler::Success;
22600b57cec5SDimitry Andric }
22610b57cec5SDimitry Andric 
DecodeSimm19Lsl2(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)22620b57cec5SDimitry Andric static DecodeStatus DecodeSimm19Lsl2(MCInst &Inst, unsigned Insn,
226381ad6265SDimitry Andric                                      uint64_t Address,
226481ad6265SDimitry Andric                                      const MCDisassembler *Decoder) {
22650b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(SignExtend32<19>(Insn) * 4));
22660b57cec5SDimitry Andric   return MCDisassembler::Success;
22670b57cec5SDimitry Andric }
22680b57cec5SDimitry Andric 
DecodeSimm18Lsl3(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)22690b57cec5SDimitry Andric static DecodeStatus DecodeSimm18Lsl3(MCInst &Inst, unsigned Insn,
227081ad6265SDimitry Andric                                      uint64_t Address,
227181ad6265SDimitry Andric                                      const MCDisassembler *Decoder) {
22720b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(SignExtend32<18>(Insn) * 8));
22730b57cec5SDimitry Andric   return MCDisassembler::Success;
22740b57cec5SDimitry Andric }
22750b57cec5SDimitry Andric 
DecodeSimm9SP(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)227681ad6265SDimitry Andric static DecodeStatus DecodeSimm9SP(MCInst &Inst, unsigned Insn, uint64_t Address,
227781ad6265SDimitry Andric                                   const MCDisassembler *Decoder) {
22780b57cec5SDimitry Andric   int32_t DecodedValue;
22790b57cec5SDimitry Andric   switch (Insn) {
22800b57cec5SDimitry Andric   case 0: DecodedValue = 256; break;
22810b57cec5SDimitry Andric   case 1: DecodedValue = 257; break;
22820b57cec5SDimitry Andric   case 510: DecodedValue = -258; break;
22830b57cec5SDimitry Andric   case 511: DecodedValue = -257; break;
22840b57cec5SDimitry Andric   default: DecodedValue = SignExtend32<9>(Insn); break;
22850b57cec5SDimitry Andric   }
22860b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(DecodedValue * 4));
22870b57cec5SDimitry Andric   return MCDisassembler::Success;
22880b57cec5SDimitry Andric }
22890b57cec5SDimitry Andric 
DecodeANDI16Imm(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)22900b57cec5SDimitry Andric static DecodeStatus DecodeANDI16Imm(MCInst &Inst, unsigned Insn,
229181ad6265SDimitry Andric                                     uint64_t Address,
229281ad6265SDimitry Andric                                     const MCDisassembler *Decoder) {
22930b57cec5SDimitry Andric   // Insn must be >= 0, since it is unsigned that condition is always true.
22940b57cec5SDimitry Andric   assert(Insn < 16);
22950b57cec5SDimitry Andric   int32_t DecodedValues[] = {128, 1, 2, 3, 4, 7, 8, 15, 16, 31, 32, 63, 64,
22960b57cec5SDimitry Andric                              255, 32768, 65535};
22970b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(DecodedValues[Insn]));
22980b57cec5SDimitry Andric   return MCDisassembler::Success;
22990b57cec5SDimitry Andric }
23000b57cec5SDimitry Andric 
DecodeRegListOperand(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)230181ad6265SDimitry Andric static DecodeStatus DecodeRegListOperand(MCInst &Inst, unsigned Insn,
23020b57cec5SDimitry Andric                                          uint64_t Address,
230381ad6265SDimitry Andric                                          const MCDisassembler *Decoder) {
23040b57cec5SDimitry Andric   unsigned Regs[] = {Mips::S0, Mips::S1, Mips::S2, Mips::S3, Mips::S4, Mips::S5,
23050b57cec5SDimitry Andric                      Mips::S6, Mips::S7, Mips::FP};
23060b57cec5SDimitry Andric   unsigned RegNum;
23070b57cec5SDimitry Andric 
23080b57cec5SDimitry Andric   unsigned RegLst = fieldFromInstruction(Insn, 21, 5);
23090b57cec5SDimitry Andric 
23100b57cec5SDimitry Andric   // Empty register lists are not allowed.
23110b57cec5SDimitry Andric   if (RegLst == 0)
23120b57cec5SDimitry Andric     return MCDisassembler::Fail;
23130b57cec5SDimitry Andric 
23140b57cec5SDimitry Andric   RegNum = RegLst & 0xf;
23150b57cec5SDimitry Andric 
23160b57cec5SDimitry Andric   // RegLst values 10-15, and 26-31 are reserved.
23170b57cec5SDimitry Andric   if (RegNum > 9)
23180b57cec5SDimitry Andric     return MCDisassembler::Fail;
23190b57cec5SDimitry Andric 
23200b57cec5SDimitry Andric   for (unsigned i = 0; i < RegNum; i++)
23210b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(Regs[i]));
23220b57cec5SDimitry Andric 
23230b57cec5SDimitry Andric   if (RegLst & 0x10)
23240b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(Mips::RA));
23250b57cec5SDimitry Andric 
23260b57cec5SDimitry Andric   return MCDisassembler::Success;
23270b57cec5SDimitry Andric }
23280b57cec5SDimitry Andric 
DecodeRegListOperand16(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)23290b57cec5SDimitry Andric static DecodeStatus DecodeRegListOperand16(MCInst &Inst, unsigned Insn,
23300b57cec5SDimitry Andric                                            uint64_t Address,
233181ad6265SDimitry Andric                                            const MCDisassembler *Decoder) {
23320b57cec5SDimitry Andric   unsigned Regs[] = {Mips::S0, Mips::S1, Mips::S2, Mips::S3};
23330b57cec5SDimitry Andric   unsigned RegLst;
23340b57cec5SDimitry Andric   switch(Inst.getOpcode()) {
23350b57cec5SDimitry Andric   default:
23360b57cec5SDimitry Andric     RegLst = fieldFromInstruction(Insn, 4, 2);
23370b57cec5SDimitry Andric     break;
23380b57cec5SDimitry Andric   case Mips::LWM16_MMR6:
23390b57cec5SDimitry Andric   case Mips::SWM16_MMR6:
23400b57cec5SDimitry Andric     RegLst = fieldFromInstruction(Insn, 8, 2);
23410b57cec5SDimitry Andric     break;
23420b57cec5SDimitry Andric   }
23430b57cec5SDimitry Andric   unsigned RegNum = RegLst & 0x3;
23440b57cec5SDimitry Andric 
23450b57cec5SDimitry Andric   for (unsigned i = 0; i <= RegNum; i++)
23460b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(Regs[i]));
23470b57cec5SDimitry Andric 
23480b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Mips::RA));
23490b57cec5SDimitry Andric 
23500b57cec5SDimitry Andric   return MCDisassembler::Success;
23510b57cec5SDimitry Andric }
23520b57cec5SDimitry Andric 
DecodeMovePOperands(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)23530b57cec5SDimitry Andric static DecodeStatus DecodeMovePOperands(MCInst &Inst, unsigned Insn,
23540b57cec5SDimitry Andric                                         uint64_t Address,
235581ad6265SDimitry Andric                                         const MCDisassembler *Decoder) {
23560b57cec5SDimitry Andric   unsigned RegPair = fieldFromInstruction(Insn, 7, 3);
23570b57cec5SDimitry Andric   if (DecodeMovePRegPair(Inst, RegPair, Address, Decoder) ==
23580b57cec5SDimitry Andric       MCDisassembler::Fail)
23590b57cec5SDimitry Andric     return MCDisassembler::Fail;
23600b57cec5SDimitry Andric 
23610b57cec5SDimitry Andric   unsigned RegRs;
23620b57cec5SDimitry Andric   if (static_cast<const MipsDisassembler*>(Decoder)->hasMips32r6())
23630b57cec5SDimitry Andric     RegRs = fieldFromInstruction(Insn, 0, 2) |
23640b57cec5SDimitry Andric             (fieldFromInstruction(Insn, 3, 1) << 2);
23650b57cec5SDimitry Andric   else
23660b57cec5SDimitry Andric     RegRs = fieldFromInstruction(Insn, 1, 3);
23670b57cec5SDimitry Andric   if (DecodeGPRMM16MovePRegisterClass(Inst, RegRs, Address, Decoder) ==
23680b57cec5SDimitry Andric       MCDisassembler::Fail)
23690b57cec5SDimitry Andric     return MCDisassembler::Fail;
23700b57cec5SDimitry Andric 
23710b57cec5SDimitry Andric   unsigned RegRt = fieldFromInstruction(Insn, 4, 3);
23720b57cec5SDimitry Andric   if (DecodeGPRMM16MovePRegisterClass(Inst, RegRt, Address, Decoder) ==
23730b57cec5SDimitry Andric       MCDisassembler::Fail)
23740b57cec5SDimitry Andric     return MCDisassembler::Fail;
23750b57cec5SDimitry Andric 
23760b57cec5SDimitry Andric   return MCDisassembler::Success;
23770b57cec5SDimitry Andric }
23780b57cec5SDimitry Andric 
DecodeMovePRegPair(MCInst & Inst,unsigned RegPair,uint64_t Address,const MCDisassembler * Decoder)23790b57cec5SDimitry Andric static DecodeStatus DecodeMovePRegPair(MCInst &Inst, unsigned RegPair,
238081ad6265SDimitry Andric                                        uint64_t Address,
238181ad6265SDimitry Andric                                        const MCDisassembler *Decoder) {
23820b57cec5SDimitry Andric   switch (RegPair) {
23830b57cec5SDimitry Andric   default:
23840b57cec5SDimitry Andric     return MCDisassembler::Fail;
23850b57cec5SDimitry Andric   case 0:
23860b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(Mips::A1));
23870b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(Mips::A2));
23880b57cec5SDimitry Andric     break;
23890b57cec5SDimitry Andric   case 1:
23900b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(Mips::A1));
23910b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(Mips::A3));
23920b57cec5SDimitry Andric     break;
23930b57cec5SDimitry Andric   case 2:
23940b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(Mips::A2));
23950b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(Mips::A3));
23960b57cec5SDimitry Andric     break;
23970b57cec5SDimitry Andric   case 3:
23980b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(Mips::A0));
23990b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(Mips::S5));
24000b57cec5SDimitry Andric     break;
24010b57cec5SDimitry Andric   case 4:
24020b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(Mips::A0));
24030b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(Mips::S6));
24040b57cec5SDimitry Andric     break;
24050b57cec5SDimitry Andric   case 5:
24060b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(Mips::A0));
24070b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(Mips::A1));
24080b57cec5SDimitry Andric     break;
24090b57cec5SDimitry Andric   case 6:
24100b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(Mips::A0));
24110b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(Mips::A2));
24120b57cec5SDimitry Andric     break;
24130b57cec5SDimitry Andric   case 7:
24140b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(Mips::A0));
24150b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(Mips::A3));
24160b57cec5SDimitry Andric     break;
24170b57cec5SDimitry Andric   }
24180b57cec5SDimitry Andric 
24190b57cec5SDimitry Andric   return MCDisassembler::Success;
24200b57cec5SDimitry Andric }
24210b57cec5SDimitry Andric 
DecodeSimm23Lsl2(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)24220b57cec5SDimitry Andric static DecodeStatus DecodeSimm23Lsl2(MCInst &Inst, unsigned Insn,
242381ad6265SDimitry Andric                                      uint64_t Address,
242481ad6265SDimitry Andric                                      const MCDisassembler *Decoder) {
24250b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(SignExtend32<25>(Insn << 2)));
24260b57cec5SDimitry Andric   return MCDisassembler::Success;
24270b57cec5SDimitry Andric }
24280b57cec5SDimitry Andric 
24290b57cec5SDimitry Andric template <typename InsnType>
DecodeBgtzGroupBranchMMR6(MCInst & MI,InsnType insn,uint64_t Address,const MCDisassembler * Decoder)24300b57cec5SDimitry Andric static DecodeStatus DecodeBgtzGroupBranchMMR6(MCInst &MI, InsnType insn,
24310b57cec5SDimitry Andric                                               uint64_t Address,
243281ad6265SDimitry Andric                                               const MCDisassembler *Decoder) {
24330b57cec5SDimitry Andric   // We have:
24340b57cec5SDimitry Andric   //    0b000111 ttttt sssss iiiiiiiiiiiiiiii
24350b57cec5SDimitry Andric   //      Invalid      if rt == 0
24360b57cec5SDimitry Andric   //      BGTZALC_MMR6 if rs == 0 && rt != 0
24370b57cec5SDimitry Andric   //      BLTZALC_MMR6 if rs != 0 && rs == rt
24380b57cec5SDimitry Andric   //      BLTUC_MMR6   if rs != 0 && rs != rt
24390b57cec5SDimitry Andric 
24400b57cec5SDimitry Andric   InsnType Rt = fieldFromInstruction(insn, 21, 5);
24410b57cec5SDimitry Andric   InsnType Rs = fieldFromInstruction(insn, 16, 5);
24420b57cec5SDimitry Andric   InsnType Imm = 0;
24430b57cec5SDimitry Andric   bool HasRs = false;
24440b57cec5SDimitry Andric   bool HasRt = false;
24450b57cec5SDimitry Andric 
24460b57cec5SDimitry Andric   if (Rt == 0)
24470b57cec5SDimitry Andric     return MCDisassembler::Fail;
24480b57cec5SDimitry Andric   else if (Rs == 0) {
24490b57cec5SDimitry Andric     MI.setOpcode(Mips::BGTZALC_MMR6);
24500b57cec5SDimitry Andric     HasRt = true;
24510b57cec5SDimitry Andric     Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
24520b57cec5SDimitry Andric   }
24530b57cec5SDimitry Andric   else if (Rs == Rt) {
24540b57cec5SDimitry Andric     MI.setOpcode(Mips::BLTZALC_MMR6);
24550b57cec5SDimitry Andric     HasRs = true;
24560b57cec5SDimitry Andric     Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
24570b57cec5SDimitry Andric   }
24580b57cec5SDimitry Andric   else {
24590b57cec5SDimitry Andric     MI.setOpcode(Mips::BLTUC_MMR6);
24600b57cec5SDimitry Andric     HasRs = true;
24610b57cec5SDimitry Andric     HasRt = true;
24620b57cec5SDimitry Andric     Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
24630b57cec5SDimitry Andric   }
24640b57cec5SDimitry Andric 
24650b57cec5SDimitry Andric   if (HasRs)
24660b57cec5SDimitry Andric     MI.addOperand(
24670b57cec5SDimitry Andric     MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rs)));
24680b57cec5SDimitry Andric 
24690b57cec5SDimitry Andric   if (HasRt)
24700b57cec5SDimitry Andric     MI.addOperand(
24710b57cec5SDimitry Andric     MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rt)));
24720b57cec5SDimitry Andric 
24730b57cec5SDimitry Andric   MI.addOperand(MCOperand::createImm(Imm));
24740b57cec5SDimitry Andric 
24750b57cec5SDimitry Andric   return MCDisassembler::Success;
24760b57cec5SDimitry Andric }
24770b57cec5SDimitry Andric 
24780b57cec5SDimitry Andric template <typename InsnType>
DecodeBlezGroupBranchMMR6(MCInst & MI,InsnType insn,uint64_t Address,const MCDisassembler * Decoder)24790b57cec5SDimitry Andric static DecodeStatus DecodeBlezGroupBranchMMR6(MCInst &MI, InsnType insn,
24800b57cec5SDimitry Andric                                               uint64_t Address,
248181ad6265SDimitry Andric                                               const MCDisassembler *Decoder) {
24820b57cec5SDimitry Andric   // We have:
24830b57cec5SDimitry Andric   //    0b000110 ttttt sssss iiiiiiiiiiiiiiii
24840b57cec5SDimitry Andric   //      Invalid        if rt == 0
24850b57cec5SDimitry Andric   //      BLEZALC_MMR6   if rs == 0  && rt != 0
24860b57cec5SDimitry Andric   //      BGEZALC_MMR6   if rs == rt && rt != 0
24870b57cec5SDimitry Andric   //      BGEUC_MMR6     if rs != rt && rs != 0  && rt != 0
24880b57cec5SDimitry Andric 
24890b57cec5SDimitry Andric   InsnType Rt = fieldFromInstruction(insn, 21, 5);
24900b57cec5SDimitry Andric   InsnType Rs = fieldFromInstruction(insn, 16, 5);
24910b57cec5SDimitry Andric   InsnType Imm = 0;
24920b57cec5SDimitry Andric   bool HasRs = false;
24930b57cec5SDimitry Andric 
24940b57cec5SDimitry Andric   if (Rt == 0)
24950b57cec5SDimitry Andric     return MCDisassembler::Fail;
24960b57cec5SDimitry Andric   else if (Rs == 0) {
24970b57cec5SDimitry Andric     MI.setOpcode(Mips::BLEZALC_MMR6);
24980b57cec5SDimitry Andric     Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
24990b57cec5SDimitry Andric   }
25000b57cec5SDimitry Andric   else if (Rs == Rt) {
25010b57cec5SDimitry Andric     MI.setOpcode(Mips::BGEZALC_MMR6);
25020b57cec5SDimitry Andric     Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
25030b57cec5SDimitry Andric   }
25040b57cec5SDimitry Andric   else {
25050b57cec5SDimitry Andric     HasRs = true;
25060b57cec5SDimitry Andric     MI.setOpcode(Mips::BGEUC_MMR6);
25070b57cec5SDimitry Andric     Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
25080b57cec5SDimitry Andric   }
25090b57cec5SDimitry Andric 
25100b57cec5SDimitry Andric   if (HasRs)
25110b57cec5SDimitry Andric     MI.addOperand(
25120b57cec5SDimitry Andric     MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rs)));
25130b57cec5SDimitry Andric   MI.addOperand(
25140b57cec5SDimitry Andric     MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rt)));
25150b57cec5SDimitry Andric 
25160b57cec5SDimitry Andric   MI.addOperand(MCOperand::createImm(Imm));
25170b57cec5SDimitry Andric 
25180b57cec5SDimitry Andric   return MCDisassembler::Success;
25190b57cec5SDimitry Andric }
2520bdd1243dSDimitry Andric 
2521bdd1243dSDimitry Andric // This instruction does not have a working decoder, and needs to be
2522bdd1243dSDimitry Andric // fixed. This "fixme" function was introduced to keep the backend compiling,
2523bdd1243dSDimitry Andric // while making changes to tablegen code.
DecodeFIXMEInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)2524bdd1243dSDimitry Andric static DecodeStatus DecodeFIXMEInstruction(MCInst &Inst, unsigned Insn,
2525bdd1243dSDimitry Andric                                            uint64_t Address,
2526bdd1243dSDimitry Andric                                            const MCDisassembler *Decoder) {
2527bdd1243dSDimitry Andric   return MCDisassembler::Fail;
2528bdd1243dSDimitry Andric }
2529