//===- MipsDisassembler.cpp - Disassembler for Mips -----------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file is part of the Mips Disassembler.
//
//===----------------------------------------------------------------------===//

#include "MCTargetDesc/MipsMCTargetDesc.h"
#include "Mips.h"
#include "TargetInfo/MipsTargetInfo.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCDecoderOps.h"
#include "llvm/MC/MCDisassembler/MCDisassembler.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/MC/TargetRegistry.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
#include <cassert>
#include <cstdint>

using namespace llvm;

#define DEBUG_TYPE "mips-disassembler"

using DecodeStatus = MCDisassembler::DecodeStatus;

namespace {

class MipsDisassembler : public MCDisassembler {
  bool IsMicroMips;
  bool IsBigEndian;

public:
  MipsDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx, bool IsBigEndian)
      : MCDisassembler(STI, Ctx),
        IsMicroMips(STI.getFeatureBits()[Mips::FeatureMicroMips]),
        IsBigEndian(IsBigEndian) {}

  bool hasMips2() const { return STI.getFeatureBits()[Mips::FeatureMips2]; }
  bool hasMips3() const { return STI.getFeatureBits()[Mips::FeatureMips3]; }
  bool hasMips32() const { return STI.getFeatureBits()[Mips::FeatureMips32]; }

  bool hasMips32r6() const {
    return STI.getFeatureBits()[Mips::FeatureMips32r6];
  }

  bool isFP64() const { return STI.getFeatureBits()[Mips::FeatureFP64Bit]; }

  bool isGP64() const { return STI.getFeatureBits()[Mips::FeatureGP64Bit]; }

  bool isPTR64() const { return STI.getFeatureBits()[Mips::FeaturePTR64Bit]; }

  bool hasCnMips() const { return STI.getFeatureBits()[Mips::FeatureCnMips]; }

  bool hasCnMipsP() const { return STI.getFeatureBits()[Mips::FeatureCnMipsP]; }

  bool hasCOP3() const {
    // Only present in MIPS-I and MIPS-II
    return !hasMips32() && !hasMips3();
  }

  DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
                              ArrayRef<uint8_t> Bytes, uint64_t Address,
                              raw_ostream &CStream) const override;
};

} // end anonymous namespace

// Forward declare these because the autogenerated code will reference them.
// Definitions are further down.
static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst, unsigned RegNo,
                                             uint64_t Address,
                                             const MCDisassembler *Decoder);

static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst, unsigned RegNo,
                                                 uint64_t Address,
                                                 const MCDisassembler *Decoder);

static DecodeStatus DecodeGPRMM16RegisterClass(MCInst &Inst, unsigned RegNo,
                                               uint64_t Address,
                                               const MCDisassembler *Decoder);

static DecodeStatus
DecodeGPRMM16ZeroRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address,
                               const MCDisassembler *Decoder);

static DecodeStatus
DecodeGPRMM16MovePRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address,
                                const MCDisassembler *Decoder);

static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst, unsigned RegNo,
                                             uint64_t Address,
                                             const MCDisassembler *Decoder);

static DecodeStatus DecodePtrRegisterClass(MCInst &Inst, unsigned Insn,
                                           uint64_t Address,
                                           const MCDisassembler *Decoder);

static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst, unsigned RegNo,
                                            uint64_t Address,
                                            const MCDisassembler *Decoder);

static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst, unsigned RegNo,
                                             uint64_t Address,
                                             const MCDisassembler *Decoder);

static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst, unsigned RegNo,
                                             uint64_t Address,
                                             const MCDisassembler *Decoder);

static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst, unsigned RegNo,
                                           uint64_t Address,
                                           const MCDisassembler *Decoder);

static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst, unsigned RegNo,
                                           uint64_t Address,
                                           const MCDisassembler *Decoder);

static DecodeStatus DecodeFGRCCRegisterClass(MCInst &Inst, unsigned RegNo,
                                             uint64_t Address,
                                             const MCDisassembler *Decoder);

static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst, unsigned Insn,
                                              uint64_t Address,
                                              const MCDisassembler *Decoder);

static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst, unsigned RegNo,
                                              uint64_t Address,
                                              const MCDisassembler *Decoder);

static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst, unsigned RegNo,
                                                uint64_t Address,
                                                const MCDisassembler *Decoder);

static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst, unsigned RegNo,
                                               uint64_t Address,
                                               const MCDisassembler *Decoder);

static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst, unsigned RegNo,
                                               uint64_t Address,
                                               const MCDisassembler *Decoder);

static DecodeStatus DecodeMSA128BRegisterClass(MCInst &Inst, unsigned RegNo,
                                               uint64_t Address,
                                               const MCDisassembler *Decoder);

static DecodeStatus DecodeMSA128HRegisterClass(MCInst &Inst, unsigned RegNo,
                                               uint64_t Address,
                                               const MCDisassembler *Decoder);

static DecodeStatus DecodeMSA128WRegisterClass(MCInst &Inst, unsigned RegNo,
                                               uint64_t Address,
                                               const MCDisassembler *Decoder);

static DecodeStatus DecodeMSA128DRegisterClass(MCInst &Inst, unsigned RegNo,
                                               uint64_t Address,
                                               const MCDisassembler *Decoder);

static DecodeStatus DecodeMSACtrlRegisterClass(MCInst &Inst, unsigned RegNo,
                                               uint64_t Address,
                                               const MCDisassembler *Decoder);

static DecodeStatus DecodeCOP0RegisterClass(MCInst &Inst, unsigned RegNo,
                                            uint64_t Address,
                                            const MCDisassembler *Decoder);

static DecodeStatus DecodeCOP2RegisterClass(MCInst &Inst, unsigned RegNo,
                                            uint64_t Address,
                                            const MCDisassembler *Decoder);

static DecodeStatus DecodeBranchTarget(MCInst &Inst, unsigned Offset,
                                       uint64_t Address,
                                       const MCDisassembler *Decoder);

static DecodeStatus DecodeBranchTarget1SImm16(MCInst &Inst, unsigned Offset,
                                              uint64_t Address,
                                              const MCDisassembler *Decoder);

static DecodeStatus DecodeJumpTarget(MCInst &Inst, unsigned Insn,
                                     uint64_t Address,
                                     const MCDisassembler *Decoder);

static DecodeStatus DecodeBranchTarget21(MCInst &Inst, unsigned Offset,
                                         uint64_t Address,
                                         const MCDisassembler *Decoder);

static DecodeStatus DecodeBranchTarget21MM(MCInst &Inst, unsigned Offset,
                                           uint64_t Address,
                                           const MCDisassembler *Decoder);

static DecodeStatus DecodeBranchTarget26(MCInst &Inst, unsigned Offset,
                                         uint64_t Address,
                                         const MCDisassembler *Decoder);

// DecodeBranchTarget7MM - Decode microMIPS branch offset, which is
// shifted left by 1 bit.
static DecodeStatus DecodeBranchTarget7MM(MCInst &Inst, unsigned Offset,
                                          uint64_t Address,
                                          const MCDisassembler *Decoder);

// DecodeBranchTarget10MM - Decode microMIPS branch offset, which is
// shifted left by 1 bit.
static DecodeStatus DecodeBranchTarget10MM(MCInst &Inst, unsigned Offset,
                                           uint64_t Address,
                                           const MCDisassembler *Decoder);

// DecodeBranchTargetMM - Decode microMIPS branch offset, which is
// shifted left by 1 bit.
static DecodeStatus DecodeBranchTargetMM(MCInst &Inst, unsigned Offset,
                                         uint64_t Address,
                                         const MCDisassembler *Decoder);

// DecodeBranchTarget26MM - Decode microMIPS branch offset, which is
// shifted left by 1 bit.
static DecodeStatus DecodeBranchTarget26MM(MCInst &Inst, unsigned Offset,
                                           uint64_t Address,
                                           const MCDisassembler *Decoder);

// DecodeJumpTargetMM - Decode microMIPS jump target, which is
// shifted left by 1 bit.
static DecodeStatus DecodeJumpTargetMM(MCInst &Inst, unsigned Insn,
                                       uint64_t Address,
                                       const MCDisassembler *Decoder);

// DecodeJumpTargetXMM - Decode microMIPS jump and link exchange target,
// which is shifted left by 2 bit.
static DecodeStatus DecodeJumpTargetXMM(MCInst &Inst, unsigned Insn,
                                        uint64_t Address,
                                        const MCDisassembler *Decoder);

static DecodeStatus DecodeMem(MCInst &Inst, unsigned Insn, uint64_t Address,
                              const MCDisassembler *Decoder);

static DecodeStatus DecodeMemEVA(MCInst &Inst, unsigned Insn, uint64_t Address,
                                 const MCDisassembler *Decoder);

static DecodeStatus DecodeLoadByte15(MCInst &Inst, unsigned Insn,
                                     uint64_t Address,
                                     const MCDisassembler *Decoder);

static DecodeStatus DecodeCacheOp(MCInst &Inst, unsigned Insn, uint64_t Address,
                                  const MCDisassembler *Decoder);

static DecodeStatus DecodeCacheeOp_CacheOpR6(MCInst &Inst, unsigned Insn,
                                             uint64_t Address,
                                             const MCDisassembler *Decoder);

static DecodeStatus DecodeCacheOpMM(MCInst &Inst, unsigned Insn,
                                    uint64_t Address,
                                    const MCDisassembler *Decoder);

static DecodeStatus DecodePrefeOpMM(MCInst &Inst, unsigned Insn,
                                    uint64_t Address,
                                    const MCDisassembler *Decoder);

static DecodeStatus DecodeSyncI(MCInst &Inst, unsigned Insn, uint64_t Address,
                                const MCDisassembler *Decoder);

static DecodeStatus DecodeSyncI_MM(MCInst &Inst, unsigned Insn,
                                   uint64_t Address,
                                   const MCDisassembler *Decoder);

static DecodeStatus DecodeSynciR6(MCInst &Inst, unsigned Insn, uint64_t Address,
                                  const MCDisassembler *Decoder);

static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn,
                                    uint64_t Address,
                                    const MCDisassembler *Decoder);

static DecodeStatus DecodeMemMMImm4(MCInst &Inst, unsigned Insn,
                                    uint64_t Address,
                                    const MCDisassembler *Decoder);

static DecodeStatus DecodeMemMMSPImm5Lsl2(MCInst &Inst, unsigned Insn,
                                          uint64_t Address,
                                          const MCDisassembler *Decoder);

static DecodeStatus DecodeMemMMGPImm7Lsl2(MCInst &Inst, unsigned Insn,
                                          uint64_t Address,
                                          const MCDisassembler *Decoder);

static DecodeStatus DecodeMemMMReglistImm4Lsl2(MCInst &Inst, unsigned Insn,
                                               uint64_t Address,
                                               const MCDisassembler *Decoder);

static DecodeStatus DecodeMemMMImm9(MCInst &Inst, unsigned Insn,
                                    uint64_t Address,
                                    const MCDisassembler *Decoder);

static DecodeStatus DecodeMemMMImm12(MCInst &Inst, unsigned Insn,
                                     uint64_t Address,
                                     const MCDisassembler *Decoder);

static DecodeStatus DecodeMemMMImm16(MCInst &Inst, unsigned Insn,
                                     uint64_t Address,
                                     const MCDisassembler *Decoder);

static DecodeStatus DecodeFMem(MCInst &Inst, unsigned Insn, uint64_t Address,
                               const MCDisassembler *Decoder);

static DecodeStatus DecodeFMemMMR2(MCInst &Inst, unsigned Insn,
                                   uint64_t Address,
                                   const MCDisassembler *Decoder);

static DecodeStatus DecodeFMem2(MCInst &Inst, unsigned Insn, uint64_t Address,
                                const MCDisassembler *Decoder);

static DecodeStatus DecodeFMem3(MCInst &Inst, unsigned Insn, uint64_t Address,
                                const MCDisassembler *Decoder);

static DecodeStatus DecodeFMemCop2R6(MCInst &Inst, unsigned Insn,
                                     uint64_t Address,
                                     const MCDisassembler *Decoder);

static DecodeStatus DecodeFMemCop2MMR6(MCInst &Inst, unsigned Insn,
                                       uint64_t Address,
                                       const MCDisassembler *Decoder);

static DecodeStatus DecodeSpecial3LlSc(MCInst &Inst, unsigned Insn,
                                       uint64_t Address,
                                       const MCDisassembler *Decoder);

static DecodeStatus DecodeAddiur2Simm7(MCInst &Inst, unsigned Value,
                                       uint64_t Address,
                                       const MCDisassembler *Decoder);

static DecodeStatus DecodeLi16Imm(MCInst &Inst, unsigned Value,
                                  uint64_t Address,
                                  const MCDisassembler *Decoder);

static DecodeStatus DecodePOOL16BEncodedField(MCInst &Inst, unsigned Value,
                                              uint64_t Address,
                                              const MCDisassembler *Decoder);

template <unsigned Bits, int Offset, int Scale>
static DecodeStatus DecodeUImmWithOffsetAndScale(MCInst &Inst, unsigned Value,
                                                 uint64_t Address,
                                                 const MCDisassembler *Decoder);

template <unsigned Bits, int Offset>
static DecodeStatus DecodeUImmWithOffset(MCInst &Inst, unsigned Value,
                                         uint64_t Address,
                                         const MCDisassembler *Decoder) {
  return DecodeUImmWithOffsetAndScale<Bits, Offset, 1>(Inst, Value, Address,
                                                       Decoder);
}

template <unsigned Bits, int Offset = 0, int ScaleBy = 1>
static DecodeStatus DecodeSImmWithOffsetAndScale(MCInst &Inst, unsigned Value,
                                                 uint64_t Address,
                                                 const MCDisassembler *Decoder);

static DecodeStatus DecodeInsSize(MCInst &Inst, unsigned Insn, uint64_t Address,
                                  const MCDisassembler *Decoder);

static DecodeStatus DecodeSimm19Lsl2(MCInst &Inst, unsigned Insn,
                                     uint64_t Address,
                                     const MCDisassembler *Decoder);

static DecodeStatus DecodeSimm18Lsl3(MCInst &Inst, unsigned Insn,
                                     uint64_t Address,
                                     const MCDisassembler *Decoder);

static DecodeStatus DecodeSimm9SP(MCInst &Inst, unsigned Insn, uint64_t Address,
                                  const MCDisassembler *Decoder);

static DecodeStatus DecodeANDI16Imm(MCInst &Inst, unsigned Insn,
                                    uint64_t Address,
                                    const MCDisassembler *Decoder);

static DecodeStatus DecodeSimm23Lsl2(MCInst &Inst, unsigned Insn,
                                     uint64_t Address,
                                     const MCDisassembler *Decoder);

/// INSVE_[BHWD] have an implicit operand that the generated decoder doesn't
/// handle.
template <typename InsnType>
static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address,
                                   const MCDisassembler *Decoder);

template <typename InsnType>
static DecodeStatus DecodeDAHIDATIMMR6(MCInst &MI, InsnType insn,
                                       uint64_t Address,
                                       const MCDisassembler *Decoder);

template <typename InsnType>
static DecodeStatus DecodeDAHIDATI(MCInst &MI, InsnType insn, uint64_t Address,
                                   const MCDisassembler *Decoder);

template <typename InsnType>
static DecodeStatus DecodeAddiGroupBranch(MCInst &MI, InsnType insn,
                                          uint64_t Address,
                                          const MCDisassembler *Decoder);

template <typename InsnType>
static DecodeStatus DecodePOP35GroupBranchMMR6(MCInst &MI, InsnType insn,
                                               uint64_t Address,
                                               const MCDisassembler *Decoder);

template <typename InsnType>
static DecodeStatus DecodeDaddiGroupBranch(MCInst &MI, InsnType insn,
                                           uint64_t Address,
                                           const MCDisassembler *Decoder);

template <typename InsnType>
static DecodeStatus DecodePOP37GroupBranchMMR6(MCInst &MI, InsnType insn,
                                               uint64_t Address,
                                               const MCDisassembler *Decoder);

template <typename InsnType>
static DecodeStatus DecodePOP65GroupBranchMMR6(MCInst &MI, InsnType insn,
                                               uint64_t Address,
                                               const MCDisassembler *Decoder);

template <typename InsnType>
static DecodeStatus DecodePOP75GroupBranchMMR6(MCInst &MI, InsnType insn,
                                               uint64_t Address,
                                               const MCDisassembler *Decoder);

template <typename InsnType>
static DecodeStatus DecodeBlezlGroupBranch(MCInst &MI, InsnType insn,
                                           uint64_t Address,
                                           const MCDisassembler *Decoder);

template <typename InsnType>
static DecodeStatus DecodeBgtzlGroupBranch(MCInst &MI, InsnType insn,
                                           uint64_t Address,
                                           const MCDisassembler *Decoder);

template <typename InsnType>
static DecodeStatus DecodeBgtzGroupBranch(MCInst &MI, InsnType insn,
                                          uint64_t Address,
                                          const MCDisassembler *Decoder);

template <typename InsnType>
static DecodeStatus DecodeBlezGroupBranch(MCInst &MI, InsnType insn,
                                          uint64_t Address,
                                          const MCDisassembler *Decoder);

template <typename InsnType>
static DecodeStatus DecodeBgtzGroupBranchMMR6(MCInst &MI, InsnType insn,
                                              uint64_t Address,
                                              const MCDisassembler *Decoder);

template <typename InsnType>
static DecodeStatus DecodeBlezGroupBranchMMR6(MCInst &MI, InsnType insn,
                                              uint64_t Address,
                                              const MCDisassembler *Decoder);

template <typename InsnType>
static DecodeStatus DecodeDINS(MCInst &MI, InsnType Insn, uint64_t Address,
                               const MCDisassembler *Decoder);

template <typename InsnType>
static DecodeStatus DecodeDEXT(MCInst &MI, InsnType Insn, uint64_t Address,
                               const MCDisassembler *Decoder);

template <typename InsnType>
static DecodeStatus DecodeCRC(MCInst &MI, InsnType Insn, uint64_t Address,
                              const MCDisassembler *Decoder);

static DecodeStatus DecodeRegListOperand(MCInst &Inst, unsigned Insn,
                                         uint64_t Address,
                                         const MCDisassembler *Decoder);

static DecodeStatus DecodeRegListOperand16(MCInst &Inst, unsigned Insn,
                                           uint64_t Address,
                                           const MCDisassembler *Decoder);

static DecodeStatus DecodeMovePRegPair(MCInst &Inst, unsigned RegPair,
                                       uint64_t Address,
                                       const MCDisassembler *Decoder);

static DecodeStatus DecodeMovePOperands(MCInst &Inst, unsigned Insn,
                                        uint64_t Address,
                                        const MCDisassembler *Decoder);

static DecodeStatus DecodeFIXMEInstruction(MCInst &Inst, unsigned Insn,
                                           uint64_t Address,
                                           const MCDisassembler *Decoder);

static MCDisassembler *createMipsDisassembler(
                       const Target &T,
                       const MCSubtargetInfo &STI,
                       MCContext &Ctx) {
  return new MipsDisassembler(STI, Ctx, true);
}

static MCDisassembler *createMipselDisassembler(
                       const Target &T,
                       const MCSubtargetInfo &STI,
                       MCContext &Ctx) {
  return new MipsDisassembler(STI, Ctx, false);
}

extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeMipsDisassembler() {
  // Register the disassembler.
  TargetRegistry::RegisterMCDisassembler(getTheMipsTarget(),
                                         createMipsDisassembler);
  TargetRegistry::RegisterMCDisassembler(getTheMipselTarget(),
                                         createMipselDisassembler);
  TargetRegistry::RegisterMCDisassembler(getTheMips64Target(),
                                         createMipsDisassembler);
  TargetRegistry::RegisterMCDisassembler(getTheMips64elTarget(),
                                         createMipselDisassembler);
}

#include "MipsGenDisassemblerTables.inc"

static unsigned getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo) {
  const MCRegisterInfo *RegInfo = D->getContext().getRegisterInfo();
  return *(RegInfo->getRegClass(RC).begin() + RegNo);
}

template <typename InsnType>
static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address,
                                   const MCDisassembler *Decoder) {
  using DecodeFN =
      DecodeStatus (*)(MCInst &, unsigned, uint64_t, const MCDisassembler *);

  // The size of the n field depends on the element size
  // The register class also depends on this.
  InsnType tmp = fieldFromInstruction(insn, 17, 5);
  unsigned NSize = 0;
  DecodeFN RegDecoder = nullptr;
  if ((tmp & 0x18) == 0x00) { // INSVE_B
    NSize = 4;
    RegDecoder = DecodeMSA128BRegisterClass;
  } else if ((tmp & 0x1c) == 0x10) { // INSVE_H
    NSize = 3;
    RegDecoder = DecodeMSA128HRegisterClass;
  } else if ((tmp & 0x1e) == 0x18) { // INSVE_W
    NSize = 2;
    RegDecoder = DecodeMSA128WRegisterClass;
  } else if ((tmp & 0x1f) == 0x1c) { // INSVE_D
    NSize = 1;
    RegDecoder = DecodeMSA128DRegisterClass;
  } else
    llvm_unreachable("Invalid encoding");

  assert(NSize != 0 && RegDecoder != nullptr);

  // $wd
  tmp = fieldFromInstruction(insn, 6, 5);
  if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
    return MCDisassembler::Fail;
  // $wd_in
  if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
    return MCDisassembler::Fail;
  // $n
  tmp = fieldFromInstruction(insn, 16, NSize);
  MI.addOperand(MCOperand::createImm(tmp));
  // $ws
  tmp = fieldFromInstruction(insn, 11, 5);
  if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
    return MCDisassembler::Fail;
  // $n2
  MI.addOperand(MCOperand::createImm(0));

  return MCDisassembler::Success;
}

template <typename InsnType>
static DecodeStatus DecodeDAHIDATIMMR6(MCInst &MI, InsnType insn,
                                       uint64_t Address,
                                       const MCDisassembler *Decoder) {
  InsnType Rs = fieldFromInstruction(insn, 16, 5);
  InsnType Imm = fieldFromInstruction(insn, 0, 16);
  MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID,
                                       Rs)));
  MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID,
                                       Rs)));
  MI.addOperand(MCOperand::createImm(Imm));

  return MCDisassembler::Success;
}

template <typename InsnType>
static DecodeStatus DecodeDAHIDATI(MCInst &MI, InsnType insn, uint64_t Address,
                                   const MCDisassembler *Decoder) {
  InsnType Rs = fieldFromInstruction(insn, 21, 5);
  InsnType Imm = fieldFromInstruction(insn, 0, 16);
  MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID,
                                       Rs)));
  MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID,
                                       Rs)));
  MI.addOperand(MCOperand::createImm(Imm));

  return MCDisassembler::Success;
}

template <typename InsnType>
static DecodeStatus DecodeAddiGroupBranch(MCInst &MI, InsnType insn,
                                          uint64_t Address,
                                          const MCDisassembler *Decoder) {
  // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
  // (otherwise we would have matched the ADDI instruction from the earlier
  // ISA's instead).
  //
  // We have:
  //    0b001000 sssss ttttt iiiiiiiiiiiiiiii
  //      BOVC if rs >= rt
  //      BEQZALC if rs == 0 && rt != 0
  //      BEQC if rs < rt && rs != 0

  InsnType Rs = fieldFromInstruction(insn, 21, 5);
  InsnType Rt = fieldFromInstruction(insn, 16, 5);
  int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
  bool HasRs = false;

  if (Rs >= Rt) {
    MI.setOpcode(Mips::BOVC);
    HasRs = true;
  } else if (Rs != 0 && Rs < Rt) {
    MI.setOpcode(Mips::BEQC);
    HasRs = true;
  } else
    MI.setOpcode(Mips::BEQZALC);

  if (HasRs)
    MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
                                       Rs)));

  MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
                                     Rt)));
  MI.addOperand(MCOperand::createImm(Imm));

  return MCDisassembler::Success;
}

template <typename InsnType>
static DecodeStatus DecodePOP35GroupBranchMMR6(MCInst &MI, InsnType insn,
                                               uint64_t Address,
                                               const MCDisassembler *Decoder) {
  InsnType Rt = fieldFromInstruction(insn, 21, 5);
  InsnType Rs = fieldFromInstruction(insn, 16, 5);
  int64_t Imm = 0;

  if (Rs >= Rt) {
    MI.setOpcode(Mips::BOVC_MMR6);
    MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
                                       Rt)));
    MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
                                       Rs)));
    Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
  } else if (Rs != 0 && Rs < Rt) {
    MI.setOpcode(Mips::BEQC_MMR6);
    MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
                                       Rs)));
    MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
                                       Rt)));
    Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
  } else {
    MI.setOpcode(Mips::BEQZALC_MMR6);
    MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
                                       Rt)));
    Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
  }

  MI.addOperand(MCOperand::createImm(Imm));

  return MCDisassembler::Success;
}

template <typename InsnType>
static DecodeStatus DecodeDaddiGroupBranch(MCInst &MI, InsnType insn,
                                           uint64_t Address,
                                           const MCDisassembler *Decoder) {
  // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
  // (otherwise we would have matched the ADDI instruction from the earlier
  // ISA's instead).
  //
  // We have:
  //    0b011000 sssss ttttt iiiiiiiiiiiiiiii
  //      BNVC if rs >= rt
  //      BNEZALC if rs == 0 && rt != 0
  //      BNEC if rs < rt && rs != 0

  InsnType Rs = fieldFromInstruction(insn, 21, 5);
  InsnType Rt = fieldFromInstruction(insn, 16, 5);
  int64_t  Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
  bool HasRs = false;

  if (Rs >= Rt) {
    MI.setOpcode(Mips::BNVC);
    HasRs = true;
  } else if (Rs != 0 && Rs < Rt) {
    MI.setOpcode(Mips::BNEC);
    HasRs = true;
  } else
    MI.setOpcode(Mips::BNEZALC);

  if (HasRs)
    MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
                                       Rs)));

  MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
                                     Rt)));
  MI.addOperand(MCOperand::createImm(Imm));

  return MCDisassembler::Success;
}

template <typename InsnType>
static DecodeStatus DecodePOP37GroupBranchMMR6(MCInst &MI, InsnType insn,
                                               uint64_t Address,
                                               const MCDisassembler *Decoder) {
  InsnType Rt = fieldFromInstruction(insn, 21, 5);
  InsnType Rs = fieldFromInstruction(insn, 16, 5);
  int64_t Imm = 0;

  if (Rs >= Rt) {
    MI.setOpcode(Mips::BNVC_MMR6);
    MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
                                       Rt)));
    MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
                                       Rs)));
    Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
  } else if (Rs != 0 && Rs < Rt) {
    MI.setOpcode(Mips::BNEC_MMR6);
    MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
                                       Rs)));
    MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
                                       Rt)));
    Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
  } else {
    MI.setOpcode(Mips::BNEZALC_MMR6);
    MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
                                       Rt)));
    Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
  }

  MI.addOperand(MCOperand::createImm(Imm));

  return MCDisassembler::Success;
}

template <typename InsnType>
static DecodeStatus DecodePOP65GroupBranchMMR6(MCInst &MI, InsnType insn,
                                               uint64_t Address,
                                               const MCDisassembler *Decoder) {
  // We have:
  //    0b110101 ttttt sssss iiiiiiiiiiiiiiii
  //      Invalid if rt == 0
  //      BGTZC_MMR6   if rs == 0  && rt != 0
  //      BLTZC_MMR6   if rs == rt && rt != 0
  //      BLTC_MMR6    if rs != rt && rs != 0  && rt != 0

  InsnType Rt = fieldFromInstruction(insn, 21, 5);
  InsnType Rs = fieldFromInstruction(insn, 16, 5);
  int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
  bool HasRs = false;

  if (Rt == 0)
    return MCDisassembler::Fail;
  else if (Rs == 0)
    MI.setOpcode(Mips::BGTZC_MMR6);
  else if (Rs == Rt)
    MI.setOpcode(Mips::BLTZC_MMR6);
  else {
    MI.setOpcode(Mips::BLTC_MMR6);
    HasRs = true;
  }

  if (HasRs)
    MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
                                              Rs)));

  MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
                                     Rt)));

  MI.addOperand(MCOperand::createImm(Imm));

  return MCDisassembler::Success;
}

template <typename InsnType>
static DecodeStatus DecodePOP75GroupBranchMMR6(MCInst &MI, InsnType insn,
                                               uint64_t Address,
                                               const MCDisassembler *Decoder) {
  // We have:
  //    0b111101 ttttt sssss iiiiiiiiiiiiiiii
  //      Invalid if rt == 0
  //      BLEZC_MMR6   if rs == 0  && rt != 0
  //      BGEZC_MMR6   if rs == rt && rt != 0
  //      BGEC_MMR6    if rs != rt && rs != 0  && rt != 0

  InsnType Rt = fieldFromInstruction(insn, 21, 5);
  InsnType Rs = fieldFromInstruction(insn, 16, 5);
  int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
  bool HasRs = false;

  if (Rt == 0)
    return MCDisassembler::Fail;
  else if (Rs == 0)
    MI.setOpcode(Mips::BLEZC_MMR6);
  else if (Rs == Rt)
    MI.setOpcode(Mips::BGEZC_MMR6);
  else {
    HasRs = true;
    MI.setOpcode(Mips::BGEC_MMR6);
  }

  if (HasRs)
    MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
                                       Rs)));

  MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
                                     Rt)));

  MI.addOperand(MCOperand::createImm(Imm));

  return MCDisassembler::Success;
}

template <typename InsnType>
static DecodeStatus DecodeBlezlGroupBranch(MCInst &MI, InsnType insn,
                                           uint64_t Address,
                                           const MCDisassembler *Decoder) {
  // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
  // (otherwise we would have matched the BLEZL instruction from the earlier
  // ISA's instead).
  //
  // We have:
  //    0b010110 sssss ttttt iiiiiiiiiiiiiiii
  //      Invalid if rs == 0
  //      BLEZC   if rs == 0  && rt != 0
  //      BGEZC   if rs == rt && rt != 0
  //      BGEC    if rs != rt && rs != 0  && rt != 0

  InsnType Rs = fieldFromInstruction(insn, 21, 5);
  InsnType Rt = fieldFromInstruction(insn, 16, 5);
  int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
  bool HasRs = false;

  if (Rt == 0)
    return MCDisassembler::Fail;
  else if (Rs == 0)
    MI.setOpcode(Mips::BLEZC);
  else if (Rs == Rt)
    MI.setOpcode(Mips::BGEZC);
  else {
    HasRs = true;
    MI.setOpcode(Mips::BGEC);
  }

  if (HasRs)
    MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
                                       Rs)));

  MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
                                     Rt)));

  MI.addOperand(MCOperand::createImm(Imm));

  return MCDisassembler::Success;
}

template <typename InsnType>
static DecodeStatus DecodeBgtzlGroupBranch(MCInst &MI, InsnType insn,
                                           uint64_t Address,
                                           const MCDisassembler *Decoder) {
  // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
  // (otherwise we would have matched the BGTZL instruction from the earlier
  // ISA's instead).
  //
  // We have:
  //    0b010111 sssss ttttt iiiiiiiiiiiiiiii
  //      Invalid if rs == 0
  //      BGTZC   if rs == 0  && rt != 0
  //      BLTZC   if rs == rt && rt != 0
  //      BLTC    if rs != rt && rs != 0  && rt != 0

  bool HasRs = false;

  InsnType Rs = fieldFromInstruction(insn, 21, 5);
  InsnType Rt = fieldFromInstruction(insn, 16, 5);
  int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;

  if (Rt == 0)
    return MCDisassembler::Fail;
  else if (Rs == 0)
    MI.setOpcode(Mips::BGTZC);
  else if (Rs == Rt)
    MI.setOpcode(Mips::BLTZC);
  else {
    MI.setOpcode(Mips::BLTC);
    HasRs = true;
  }

  if (HasRs)
    MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
                                              Rs)));

  MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
                                     Rt)));

  MI.addOperand(MCOperand::createImm(Imm));

  return MCDisassembler::Success;
}

template <typename InsnType>
static DecodeStatus DecodeBgtzGroupBranch(MCInst &MI, InsnType insn,
                                          uint64_t Address,
                                          const MCDisassembler *Decoder) {
  // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
  // (otherwise we would have matched the BGTZ instruction from the earlier
  // ISA's instead).
  //
  // We have:
  //    0b000111 sssss ttttt iiiiiiiiiiiiiiii
  //      BGTZ    if rt == 0
  //      BGTZALC if rs == 0 && rt != 0
  //      BLTZALC if rs != 0 && rs == rt
  //      BLTUC   if rs != 0 && rs != rt

  InsnType Rs = fieldFromInstruction(insn, 21, 5);
  InsnType Rt = fieldFromInstruction(insn, 16, 5);
  int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
  bool HasRs = false;
  bool HasRt = false;

  if (Rt == 0) {
    MI.setOpcode(Mips::BGTZ);
    HasRs = true;
  } else if (Rs == 0) {
    MI.setOpcode(Mips::BGTZALC);
    HasRt = true;
  } else if (Rs == Rt) {
    MI.setOpcode(Mips::BLTZALC);
    HasRs = true;
  } else {
    MI.setOpcode(Mips::BLTUC);
    HasRs = true;
    HasRt = true;
  }

  if (HasRs)
    MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
                                       Rs)));

  if (HasRt)
    MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
                                       Rt)));

  MI.addOperand(MCOperand::createImm(Imm));

  return MCDisassembler::Success;
}

template <typename InsnType>
static DecodeStatus DecodeBlezGroupBranch(MCInst &MI, InsnType insn,
                                          uint64_t Address,
                                          const MCDisassembler *Decoder) {
  // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
  // (otherwise we would have matched the BLEZL instruction from the earlier
  // ISA's instead).
  //
  // We have:
  //    0b000110 sssss ttttt iiiiiiiiiiiiiiii
  //      Invalid   if rs == 0
  //      BLEZALC   if rs == 0  && rt != 0
  //      BGEZALC   if rs == rt && rt != 0
  //      BGEUC     if rs != rt && rs != 0  && rt != 0

  InsnType Rs = fieldFromInstruction(insn, 21, 5);
  InsnType Rt = fieldFromInstruction(insn, 16, 5);
  int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
  bool HasRs = false;

  if (Rt == 0)
    return MCDisassembler::Fail;
  else if (Rs == 0)
    MI.setOpcode(Mips::BLEZALC);
  else if (Rs == Rt)
    MI.setOpcode(Mips::BGEZALC);
  else {
    HasRs = true;
    MI.setOpcode(Mips::BGEUC);
  }

  if (HasRs)
    MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
                                       Rs)));
  MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
                                     Rt)));

  MI.addOperand(MCOperand::createImm(Imm));

  return MCDisassembler::Success;
}

// Override the generated disassembler to produce DEXT all the time. This is
// for feature / behaviour parity with  binutils.
template <typename InsnType>
static DecodeStatus DecodeDEXT(MCInst &MI, InsnType Insn, uint64_t Address,
                               const MCDisassembler *Decoder) {
  unsigned Msbd = fieldFromInstruction(Insn, 11, 5);
  unsigned Lsb = fieldFromInstruction(Insn, 6, 5);
  unsigned Size = 0;
  unsigned Pos = 0;

  switch (MI.getOpcode()) {
    case Mips::DEXT:
      Pos = Lsb;
      Size = Msbd + 1;
      break;
    case Mips::DEXTM:
      Pos = Lsb;
      Size = Msbd + 1 + 32;
      break;
    case Mips::DEXTU:
      Pos = Lsb + 32;
      Size = Msbd + 1;
      break;
    default:
      llvm_unreachable("Unknown DEXT instruction!");
  }

  MI.setOpcode(Mips::DEXT);

  InsnType Rs = fieldFromInstruction(Insn, 21, 5);
  InsnType Rt = fieldFromInstruction(Insn, 16, 5);

  MI.addOperand(
      MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID, Rt)));
  MI.addOperand(
      MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID, Rs)));
  MI.addOperand(MCOperand::createImm(Pos));
  MI.addOperand(MCOperand::createImm(Size));

  return MCDisassembler::Success;
}

// Override the generated disassembler to produce DINS all the time. This is
// for feature / behaviour parity with binutils.
template <typename InsnType>
static DecodeStatus DecodeDINS(MCInst &MI, InsnType Insn, uint64_t Address,
                               const MCDisassembler *Decoder) {
  unsigned Msbd = fieldFromInstruction(Insn, 11, 5);
  unsigned Lsb = fieldFromInstruction(Insn, 6, 5);
  unsigned Size = 0;
  unsigned Pos = 0;

  switch (MI.getOpcode()) {
    case Mips::DINS:
      Pos = Lsb;
      Size = Msbd + 1 - Pos;
      break;
    case Mips::DINSM:
      Pos = Lsb;
      Size = Msbd + 33 - Pos;
      break;
    case Mips::DINSU:
      Pos = Lsb + 32;
      // mbsd = pos + size - 33
      // mbsd - pos + 33 = size
      Size = Msbd + 33 - Pos;
      break;
    default:
      llvm_unreachable("Unknown DINS instruction!");
  }

  InsnType Rs = fieldFromInstruction(Insn, 21, 5);
  InsnType Rt = fieldFromInstruction(Insn, 16, 5);

  MI.setOpcode(Mips::DINS);
  MI.addOperand(
      MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID, Rt)));
  MI.addOperand(
      MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID, Rs)));
  MI.addOperand(MCOperand::createImm(Pos));
  MI.addOperand(MCOperand::createImm(Size));

  return MCDisassembler::Success;
}

// Auto-generated decoder wouldn't add the third operand for CRC32*.
template <typename InsnType>
static DecodeStatus DecodeCRC(MCInst &MI, InsnType Insn, uint64_t Address,
                              const MCDisassembler *Decoder) {
  InsnType Rs = fieldFromInstruction(Insn, 21, 5);
  InsnType Rt = fieldFromInstruction(Insn, 16, 5);
  MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
                                     Rt)));
  MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
                                     Rs)));
  MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
                                     Rt)));
  return MCDisassembler::Success;
}

/// Read two bytes from the ArrayRef and return 16 bit halfword sorted
/// according to the given endianness.
static DecodeStatus readInstruction16(ArrayRef<uint8_t> Bytes, uint64_t Address,
                                      uint64_t &Size, uint32_t &Insn,
                                      bool IsBigEndian) {
  // We want to read exactly 2 Bytes of data.
  if (Bytes.size() < 2) {
    Size = 0;
    return MCDisassembler::Fail;
  }

  if (IsBigEndian) {
    Insn = (Bytes[0] << 8) | Bytes[1];
  } else {
    Insn = (Bytes[1] << 8) | Bytes[0];
  }

  return MCDisassembler::Success;
}

/// Read four bytes from the ArrayRef and return 32 bit word sorted
/// according to the given endianness.
static DecodeStatus readInstruction32(ArrayRef<uint8_t> Bytes, uint64_t Address,
                                      uint64_t &Size, uint32_t &Insn,
                                      bool IsBigEndian, bool IsMicroMips) {
  // We want to read exactly 4 Bytes of data.
  if (Bytes.size() < 4) {
    Size = 0;
    return MCDisassembler::Fail;
  }

  // High 16 bits of a 32-bit microMIPS instruction (where the opcode is)
  // always precede the low 16 bits in the instruction stream (that is, they
  // are placed at lower addresses in the instruction stream).
  //
  // microMIPS byte ordering:
  //   Big-endian:    0 | 1 | 2 | 3
  //   Little-endian: 1 | 0 | 3 | 2

  if (IsBigEndian) {
    // Encoded as a big-endian 32-bit word in the stream.
    Insn =
        (Bytes[3] << 0) | (Bytes[2] << 8) | (Bytes[1] << 16) | (Bytes[0] << 24);
  } else {
    if (IsMicroMips) {
      Insn = (Bytes[2] << 0) | (Bytes[3] << 8) | (Bytes[0] << 16) |
             (Bytes[1] << 24);
    } else {
      Insn = (Bytes[0] << 0) | (Bytes[1] << 8) | (Bytes[2] << 16) |
             (Bytes[3] << 24);
    }
  }

  return MCDisassembler::Success;
}

DecodeStatus MipsDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,
                                              ArrayRef<uint8_t> Bytes,
                                              uint64_t Address,
                                              raw_ostream &CStream) const {
  uint32_t Insn;
  DecodeStatus Result;
  Size = 0;

  if (IsMicroMips) {
    Result = readInstruction16(Bytes, Address, Size, Insn, IsBigEndian);
    if (Result == MCDisassembler::Fail)
      return MCDisassembler::Fail;

    if (hasMips32r6()) {
      LLVM_DEBUG(
          dbgs() << "Trying MicroMipsR616 table (16-bit instructions):\n");
      // Calling the auto-generated decoder function for microMIPS32R6
      // 16-bit instructions.
      Result = decodeInstruction(DecoderTableMicroMipsR616, Instr, Insn,
                                 Address, this, STI);
      if (Result != MCDisassembler::Fail) {
        Size = 2;
        return Result;
      }
    }

    LLVM_DEBUG(dbgs() << "Trying MicroMips16 table (16-bit instructions):\n");
    // Calling the auto-generated decoder function for microMIPS 16-bit
    // instructions.
    Result = decodeInstruction(DecoderTableMicroMips16, Instr, Insn, Address,
                               this, STI);
    if (Result != MCDisassembler::Fail) {
      Size = 2;
      return Result;
    }

    Result = readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, true);
    if (Result == MCDisassembler::Fail)
      return MCDisassembler::Fail;

    if (hasMips32r6()) {
      LLVM_DEBUG(
          dbgs() << "Trying MicroMips32r632 table (32-bit instructions):\n");
      // Calling the auto-generated decoder function.
      Result = decodeInstruction(DecoderTableMicroMipsR632, Instr, Insn,
                                 Address, this, STI);
      if (Result != MCDisassembler::Fail) {
        Size = 4;
        return Result;
      }
    }

    LLVM_DEBUG(dbgs() << "Trying MicroMips32 table (32-bit instructions):\n");
    // Calling the auto-generated decoder function.
    Result = decodeInstruction(DecoderTableMicroMips32, Instr, Insn, Address,
                               this, STI);
    if (Result != MCDisassembler::Fail) {
      Size = 4;
      return Result;
    }

    if (isFP64()) {
      LLVM_DEBUG(dbgs() << "Trying MicroMipsFP64 table (32-bit opcodes):\n");
      Result = decodeInstruction(DecoderTableMicroMipsFP6432, Instr, Insn,
                                 Address, this, STI);
      if (Result != MCDisassembler::Fail) {
        Size = 4;
        return Result;
      }
    }

    // This is an invalid instruction. Claim that the Size is 2 bytes. Since
    // microMIPS instructions have a minimum alignment of 2, the next 2 bytes
    // could form a valid instruction. The two bytes we rejected as an
    // instruction could have actually beeen an inline constant pool that is
    // unconditionally branched over.
    Size = 2;
    return MCDisassembler::Fail;
  }

  // Attempt to read the instruction so that we can attempt to decode it. If
  // the buffer is not 4 bytes long, let the higher level logic figure out
  // what to do with a size of zero and MCDisassembler::Fail.
  Result = readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, false);
  if (Result == MCDisassembler::Fail)
    return MCDisassembler::Fail;

  // The only instruction size for standard encoded MIPS.
  Size = 4;

  if (hasCOP3()) {
    LLVM_DEBUG(dbgs() << "Trying COP3_ table (32-bit opcodes):\n");
    Result =
        decodeInstruction(DecoderTableCOP3_32, Instr, Insn, Address, this, STI);
    if (Result != MCDisassembler::Fail)
      return Result;
  }

  if (hasMips32r6() && isGP64()) {
    LLVM_DEBUG(
        dbgs() << "Trying Mips32r6_64r6 (GPR64) table (32-bit opcodes):\n");
    Result = decodeInstruction(DecoderTableMips32r6_64r6_GP6432, Instr, Insn,
                               Address, this, STI);
    if (Result != MCDisassembler::Fail)
      return Result;
  }

  if (hasMips32r6() && isPTR64()) {
    LLVM_DEBUG(
        dbgs() << "Trying Mips32r6_64r6 (PTR64) table (32-bit opcodes):\n");
    Result = decodeInstruction(DecoderTableMips32r6_64r6_PTR6432, Instr, Insn,
                               Address, this, STI);
    if (Result != MCDisassembler::Fail)
      return Result;
  }

  if (hasMips32r6()) {
    LLVM_DEBUG(dbgs() << "Trying Mips32r6_64r6 table (32-bit opcodes):\n");
    Result = decodeInstruction(DecoderTableMips32r6_64r632, Instr, Insn,
                               Address, this, STI);
    if (Result != MCDisassembler::Fail)
      return Result;
  }

  if (hasMips2() && isPTR64()) {
    LLVM_DEBUG(
        dbgs() << "Trying Mips32r6_64r6 (PTR64) table (32-bit opcodes):\n");
    Result = decodeInstruction(DecoderTableMips32_64_PTR6432, Instr, Insn,
                               Address, this, STI);
    if (Result != MCDisassembler::Fail)
      return Result;
  }

  if (hasCnMips()) {
    LLVM_DEBUG(dbgs() << "Trying CnMips table (32-bit opcodes):\n");
    Result = decodeInstruction(DecoderTableCnMips32, Instr, Insn,
                               Address, this, STI);
    if (Result != MCDisassembler::Fail)
      return Result;
  }

  if (hasCnMipsP()) {
    LLVM_DEBUG(dbgs() << "Trying CnMipsP table (32-bit opcodes):\n");
    Result = decodeInstruction(DecoderTableCnMipsP32, Instr, Insn,
                               Address, this, STI);
    if (Result != MCDisassembler::Fail)
      return Result;
  }

  if (isGP64()) {
    LLVM_DEBUG(dbgs() << "Trying Mips64 (GPR64) table (32-bit opcodes):\n");
    Result = decodeInstruction(DecoderTableMips6432, Instr, Insn,
                               Address, this, STI);
    if (Result != MCDisassembler::Fail)
      return Result;
  }

  if (isFP64()) {
    LLVM_DEBUG(
        dbgs() << "Trying MipsFP64 (64 bit FPU) table (32-bit opcodes):\n");
    Result = decodeInstruction(DecoderTableMipsFP6432, Instr, Insn,
                               Address, this, STI);
    if (Result != MCDisassembler::Fail)
      return Result;
  }

  LLVM_DEBUG(dbgs() << "Trying Mips table (32-bit opcodes):\n");
  // Calling the auto-generated decoder function.
  Result =
      decodeInstruction(DecoderTableMips32, Instr, Insn, Address, this, STI);
  if (Result != MCDisassembler::Fail)
    return Result;

  return MCDisassembler::Fail;
}

static DecodeStatus
DecodeCPU16RegsRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address,
                             const MCDisassembler *Decoder) {
  return MCDisassembler::Fail;
}

static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst, unsigned RegNo,
                                             uint64_t Address,
                                             const MCDisassembler *Decoder) {
  if (RegNo > 31)
    return MCDisassembler::Fail;

  unsigned Reg = getReg(Decoder, Mips::GPR64RegClassID, RegNo);
  Inst.addOperand(MCOperand::createReg(Reg));
  return MCDisassembler::Success;
}

static DecodeStatus DecodeGPRMM16RegisterClass(MCInst &Inst, unsigned RegNo,
                                               uint64_t Address,
                                               const MCDisassembler *Decoder) {
  if (RegNo > 7)
    return MCDisassembler::Fail;
  unsigned Reg = getReg(Decoder, Mips::GPRMM16RegClassID, RegNo);
  Inst.addOperand(MCOperand::createReg(Reg));
  return MCDisassembler::Success;
}

static DecodeStatus
DecodeGPRMM16ZeroRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address,
                               const MCDisassembler *Decoder) {
  if (RegNo > 7)
    return MCDisassembler::Fail;
  unsigned Reg = getReg(Decoder, Mips::GPRMM16ZeroRegClassID, RegNo);
  Inst.addOperand(MCOperand::createReg(Reg));
  return MCDisassembler::Success;
}

static DecodeStatus
DecodeGPRMM16MovePRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address,
                                const MCDisassembler *Decoder) {
  if (RegNo > 7)
    return MCDisassembler::Fail;
  unsigned Reg = getReg(Decoder, Mips::GPRMM16MovePRegClassID, RegNo);
  Inst.addOperand(MCOperand::createReg(Reg));
  return MCDisassembler::Success;
}

static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst, unsigned RegNo,
                                             uint64_t Address,
                                             const MCDisassembler *Decoder) {
  if (RegNo > 31)
    return MCDisassembler::Fail;
  unsigned Reg = getReg(Decoder, Mips::GPR32RegClassID, RegNo);
  Inst.addOperand(MCOperand::createReg(Reg));
  return MCDisassembler::Success;
}

static DecodeStatus DecodePtrRegisterClass(MCInst &Inst, unsigned RegNo,
                                           uint64_t Address,
                                           const MCDisassembler *Decoder) {
  if (static_cast<const MipsDisassembler *>(Decoder)->isGP64())
    return DecodeGPR64RegisterClass(Inst, RegNo, Address, Decoder);

  return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
}

static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst, unsigned RegNo,
                                            uint64_t Address,
                                            const MCDisassembler *Decoder) {
  return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
}

static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst, unsigned RegNo,
                                             uint64_t Address,
                                             const MCDisassembler *Decoder) {
  if (RegNo > 31)
    return MCDisassembler::Fail;

  unsigned Reg = getReg(Decoder, Mips::FGR64RegClassID, RegNo);
  Inst.addOperand(MCOperand::createReg(Reg));
  return MCDisassembler::Success;
}

static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst, unsigned RegNo,
                                             uint64_t Address,
                                             const MCDisassembler *Decoder) {
  if (RegNo > 31)
    return MCDisassembler::Fail;

  unsigned Reg = getReg(Decoder, Mips::FGR32RegClassID, RegNo);
  Inst.addOperand(MCOperand::createReg(Reg));
  return MCDisassembler::Success;
}

static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst, unsigned RegNo,
                                           uint64_t Address,
                                           const MCDisassembler *Decoder) {
  if (RegNo > 31)
    return MCDisassembler::Fail;
  unsigned Reg = getReg(Decoder, Mips::CCRRegClassID, RegNo);
  Inst.addOperand(MCOperand::createReg(Reg));
  return MCDisassembler::Success;
}

static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst, unsigned RegNo,
                                           uint64_t Address,
                                           const MCDisassembler *Decoder) {
  if (RegNo > 7)
    return MCDisassembler::Fail;
  unsigned Reg = getReg(Decoder, Mips::FCCRegClassID, RegNo);
  Inst.addOperand(MCOperand::createReg(Reg));
  return MCDisassembler::Success;
}

static DecodeStatus DecodeFGRCCRegisterClass(MCInst &Inst, unsigned RegNo,
                                             uint64_t Address,
                                             const MCDisassembler *Decoder) {
  if (RegNo > 31)
    return MCDisassembler::Fail;

  unsigned Reg = getReg(Decoder, Mips::FGRCCRegClassID, RegNo);
  Inst.addOperand(MCOperand::createReg(Reg));
  return MCDisassembler::Success;
}

static DecodeStatus DecodeMem(MCInst &Inst, unsigned Insn, uint64_t Address,
                              const MCDisassembler *Decoder) {
  int Offset = SignExtend32<16>(Insn & 0xffff);
  unsigned Reg = fieldFromInstruction(Insn, 16, 5);
  unsigned Base = fieldFromInstruction(Insn, 21, 5);

  Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
  Base = getReg(Decoder, Mips::GPR32RegClassID, Base);

  if (Inst.getOpcode() == Mips::SC ||
      Inst.getOpcode() == Mips::SCD)
    Inst.addOperand(MCOperand::createReg(Reg));

  Inst.addOperand(MCOperand::createReg(Reg));
  Inst.addOperand(MCOperand::createReg(Base));
  Inst.addOperand(MCOperand::createImm(Offset));

  return MCDisassembler::Success;
}

static DecodeStatus DecodeMemEVA(MCInst &Inst, unsigned Insn, uint64_t Address,
                                 const MCDisassembler *Decoder) {
  int Offset = SignExtend32<9>(Insn >> 7);
  unsigned Reg = fieldFromInstruction(Insn, 16, 5);
  unsigned Base = fieldFromInstruction(Insn, 21, 5);

  Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
  Base = getReg(Decoder, Mips::GPR32RegClassID, Base);

   if (Inst.getOpcode() == Mips::SCE)
     Inst.addOperand(MCOperand::createReg(Reg));

  Inst.addOperand(MCOperand::createReg(Reg));
  Inst.addOperand(MCOperand::createReg(Base));
  Inst.addOperand(MCOperand::createImm(Offset));

  return MCDisassembler::Success;
}

static DecodeStatus DecodeLoadByte15(MCInst &Inst, unsigned Insn,
                                     uint64_t Address,
                                     const MCDisassembler *Decoder) {
  int Offset = SignExtend32<16>(Insn & 0xffff);
  unsigned Base = fieldFromInstruction(Insn, 16, 5);
  unsigned Reg = fieldFromInstruction(Insn, 21, 5);

  Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
  Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);

  Inst.addOperand(MCOperand::createReg(Reg));
  Inst.addOperand(MCOperand::createReg(Base));
  Inst.addOperand(MCOperand::createImm(Offset));

  return MCDisassembler::Success;
}

static DecodeStatus DecodeCacheOp(MCInst &Inst, unsigned Insn, uint64_t Address,
                                  const MCDisassembler *Decoder) {
  int Offset = SignExtend32<16>(Insn & 0xffff);
  unsigned Hint = fieldFromInstruction(Insn, 16, 5);
  unsigned Base = fieldFromInstruction(Insn, 21, 5);

  Base = getReg(Decoder, Mips::GPR32RegClassID, Base);

  Inst.addOperand(MCOperand::createReg(Base));
  Inst.addOperand(MCOperand::createImm(Offset));
  Inst.addOperand(MCOperand::createImm(Hint));

  return MCDisassembler::Success;
}

static DecodeStatus DecodeCacheOpMM(MCInst &Inst, unsigned Insn,
                                    uint64_t Address,
                                    const MCDisassembler *Decoder) {
  int Offset = SignExtend32<12>(Insn & 0xfff);
  unsigned Base = fieldFromInstruction(Insn, 16, 5);
  unsigned Hint = fieldFromInstruction(Insn, 21, 5);

  Base = getReg(Decoder, Mips::GPR32RegClassID, Base);

  Inst.addOperand(MCOperand::createReg(Base));
  Inst.addOperand(MCOperand::createImm(Offset));
  Inst.addOperand(MCOperand::createImm(Hint));

  return MCDisassembler::Success;
}

static DecodeStatus DecodePrefeOpMM(MCInst &Inst, unsigned Insn,
                                    uint64_t Address,
                                    const MCDisassembler *Decoder) {
  int Offset = SignExtend32<9>(Insn & 0x1ff);
  unsigned Base = fieldFromInstruction(Insn, 16, 5);
  unsigned Hint = fieldFromInstruction(Insn, 21, 5);

  Base = getReg(Decoder, Mips::GPR32RegClassID, Base);

  Inst.addOperand(MCOperand::createReg(Base));
  Inst.addOperand(MCOperand::createImm(Offset));
  Inst.addOperand(MCOperand::createImm(Hint));

  return MCDisassembler::Success;
}

static DecodeStatus DecodeCacheeOp_CacheOpR6(MCInst &Inst, unsigned Insn,
                                             uint64_t Address,
                                             const MCDisassembler *Decoder) {
  int Offset = SignExtend32<9>(Insn >> 7);
  unsigned Hint = fieldFromInstruction(Insn, 16, 5);
  unsigned Base = fieldFromInstruction(Insn, 21, 5);

  Base = getReg(Decoder, Mips::GPR32RegClassID, Base);

  Inst.addOperand(MCOperand::createReg(Base));
  Inst.addOperand(MCOperand::createImm(Offset));
  Inst.addOperand(MCOperand::createImm(Hint));

  return MCDisassembler::Success;
}

static DecodeStatus DecodeSyncI(MCInst &Inst, unsigned Insn, uint64_t Address,
                                const MCDisassembler *Decoder) {
  int Offset = SignExtend32<16>(Insn & 0xffff);
  unsigned Base = fieldFromInstruction(Insn, 21, 5);

  Base = getReg(Decoder, Mips::GPR32RegClassID, Base);

  Inst.addOperand(MCOperand::createReg(Base));
  Inst.addOperand(MCOperand::createImm(Offset));

  return MCDisassembler::Success;
}

static DecodeStatus DecodeSyncI_MM(MCInst &Inst, unsigned Insn,
                                   uint64_t Address,
                                   const MCDisassembler *Decoder) {
  int Offset = SignExtend32<16>(Insn & 0xffff);
  unsigned Base = fieldFromInstruction(Insn, 16, 5);

  Base = getReg(Decoder, Mips::GPR32RegClassID, Base);

  Inst.addOperand(MCOperand::createReg(Base));
  Inst.addOperand(MCOperand::createImm(Offset));

  return MCDisassembler::Success;
}

static DecodeStatus DecodeSynciR6(MCInst &Inst, unsigned Insn, uint64_t Address,
                                  const MCDisassembler *Decoder) {
  int Immediate = SignExtend32<16>(Insn & 0xffff);
  unsigned Base = fieldFromInstruction(Insn, 16, 5);

  Base = getReg(Decoder, Mips::GPR32RegClassID, Base);

  Inst.addOperand(MCOperand::createReg(Base));
  Inst.addOperand(MCOperand::createImm(Immediate));

  return MCDisassembler::Success;
}

static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn,
                                    uint64_t Address,
                                    const MCDisassembler *Decoder) {
  int Offset = SignExtend32<10>(fieldFromInstruction(Insn, 16, 10));
  unsigned Reg = fieldFromInstruction(Insn, 6, 5);
  unsigned Base = fieldFromInstruction(Insn, 11, 5);

  Reg = getReg(Decoder, Mips::MSA128BRegClassID, Reg);
  Base = getReg(Decoder, Mips::GPR32RegClassID, Base);

  Inst.addOperand(MCOperand::createReg(Reg));
  Inst.addOperand(MCOperand::createReg(Base));

  // The immediate field of an LD/ST instruction is scaled which means it must
  // be multiplied (when decoding) by the size (in bytes) of the instructions'
  // data format.
  // .b - 1 byte
  // .h - 2 bytes
  // .w - 4 bytes
  // .d - 8 bytes
  switch(Inst.getOpcode())
  {
  default:
    assert(false && "Unexpected instruction");
    return MCDisassembler::Fail;
    break;
  case Mips::LD_B:
  case Mips::ST_B:
    Inst.addOperand(MCOperand::createImm(Offset));
    break;
  case Mips::LD_H:
  case Mips::ST_H:
    Inst.addOperand(MCOperand::createImm(Offset * 2));
    break;
  case Mips::LD_W:
  case Mips::ST_W:
    Inst.addOperand(MCOperand::createImm(Offset * 4));
    break;
  case Mips::LD_D:
  case Mips::ST_D:
    Inst.addOperand(MCOperand::createImm(Offset * 8));
    break;
  }

  return MCDisassembler::Success;
}

static DecodeStatus DecodeMemMMImm4(MCInst &Inst, unsigned Insn,
                                    uint64_t Address,
                                    const MCDisassembler *Decoder) {
  unsigned Offset = Insn & 0xf;
  unsigned Reg = fieldFromInstruction(Insn, 7, 3);
  unsigned Base = fieldFromInstruction(Insn, 4, 3);

  switch (Inst.getOpcode()) {
    case Mips::LBU16_MM:
    case Mips::LHU16_MM:
    case Mips::LW16_MM:
      if (DecodeGPRMM16RegisterClass(Inst, Reg, Address, Decoder)
            == MCDisassembler::Fail)
        return MCDisassembler::Fail;
      break;
    case Mips::SB16_MM:
    case Mips::SB16_MMR6:
    case Mips::SH16_MM:
    case Mips::SH16_MMR6:
    case Mips::SW16_MM:
    case Mips::SW16_MMR6:
      if (DecodeGPRMM16ZeroRegisterClass(Inst, Reg, Address, Decoder)
            == MCDisassembler::Fail)
        return MCDisassembler::Fail;
      break;
  }

  if (DecodeGPRMM16RegisterClass(Inst, Base, Address, Decoder)
        == MCDisassembler::Fail)
    return MCDisassembler::Fail;

  switch (Inst.getOpcode()) {
    case Mips::LBU16_MM:
      if (Offset == 0xf)
        Inst.addOperand(MCOperand::createImm(-1));
      else
        Inst.addOperand(MCOperand::createImm(Offset));
      break;
    case Mips::SB16_MM:
    case Mips::SB16_MMR6:
      Inst.addOperand(MCOperand::createImm(Offset));
      break;
    case Mips::LHU16_MM:
    case Mips::SH16_MM:
    case Mips::SH16_MMR6:
      Inst.addOperand(MCOperand::createImm(Offset << 1));
      break;
    case Mips::LW16_MM:
    case Mips::SW16_MM:
    case Mips::SW16_MMR6:
      Inst.addOperand(MCOperand::createImm(Offset << 2));
      break;
  }

  return MCDisassembler::Success;
}

static DecodeStatus DecodeMemMMSPImm5Lsl2(MCInst &Inst, unsigned Insn,
                                          uint64_t Address,
                                          const MCDisassembler *Decoder) {
  unsigned Offset = Insn & 0x1F;
  unsigned Reg = fieldFromInstruction(Insn, 5, 5);

  Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);

  Inst.addOperand(MCOperand::createReg(Reg));
  Inst.addOperand(MCOperand::createReg(Mips::SP));
  Inst.addOperand(MCOperand::createImm(Offset << 2));

  return MCDisassembler::Success;
}

static DecodeStatus DecodeMemMMGPImm7Lsl2(MCInst &Inst, unsigned Insn,
                                          uint64_t Address,
                                          const MCDisassembler *Decoder) {
  unsigned Offset = Insn & 0x7F;
  unsigned Reg = fieldFromInstruction(Insn, 7, 3);

  Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);

  Inst.addOperand(MCOperand::createReg(Reg));
  Inst.addOperand(MCOperand::createReg(Mips::GP));
  Inst.addOperand(MCOperand::createImm(Offset << 2));

  return MCDisassembler::Success;
}

static DecodeStatus DecodeMemMMReglistImm4Lsl2(MCInst &Inst, unsigned Insn,
                                               uint64_t Address,
                                               const MCDisassembler *Decoder) {
  int Offset;
  switch (Inst.getOpcode()) {
  case Mips::LWM16_MMR6:
  case Mips::SWM16_MMR6:
    Offset = fieldFromInstruction(Insn, 4, 4);
    break;
  default:
    Offset = SignExtend32<4>(Insn & 0xf);
    break;
  }

  if (DecodeRegListOperand16(Inst, Insn, Address, Decoder)
      == MCDisassembler::Fail)
    return MCDisassembler::Fail;

  Inst.addOperand(MCOperand::createReg(Mips::SP));
  Inst.addOperand(MCOperand::createImm(Offset << 2));

  return MCDisassembler::Success;
}

static DecodeStatus DecodeMemMMImm9(MCInst &Inst, unsigned Insn,
                                    uint64_t Address,
                                    const MCDisassembler *Decoder) {
  int Offset = SignExtend32<9>(Insn & 0x1ff);
  unsigned Reg = fieldFromInstruction(Insn, 21, 5);
  unsigned Base = fieldFromInstruction(Insn, 16, 5);

  Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
  Base = getReg(Decoder, Mips::GPR32RegClassID, Base);

  if (Inst.getOpcode() == Mips::SCE_MM || Inst.getOpcode() == Mips::SC_MMR6)
    Inst.addOperand(MCOperand::createReg(Reg));

  Inst.addOperand(MCOperand::createReg(Reg));
  Inst.addOperand(MCOperand::createReg(Base));
  Inst.addOperand(MCOperand::createImm(Offset));

  return MCDisassembler::Success;
}

static DecodeStatus DecodeMemMMImm12(MCInst &Inst, unsigned Insn,
                                     uint64_t Address,
                                     const MCDisassembler *Decoder) {
  int Offset = SignExtend32<12>(Insn & 0x0fff);
  unsigned Reg = fieldFromInstruction(Insn, 21, 5);
  unsigned Base = fieldFromInstruction(Insn, 16, 5);

  Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
  Base = getReg(Decoder, Mips::GPR32RegClassID, Base);

  switch (Inst.getOpcode()) {
  case Mips::SWM32_MM:
  case Mips::LWM32_MM:
    if (DecodeRegListOperand(Inst, Insn, Address, Decoder)
        == MCDisassembler::Fail)
      return MCDisassembler::Fail;
    Inst.addOperand(MCOperand::createReg(Base));
    Inst.addOperand(MCOperand::createImm(Offset));
    break;
  case Mips::SC_MM:
    Inst.addOperand(MCOperand::createReg(Reg));
    [[fallthrough]];
  default:
    Inst.addOperand(MCOperand::createReg(Reg));
    if (Inst.getOpcode() == Mips::LWP_MM || Inst.getOpcode() == Mips::SWP_MM)
      Inst.addOperand(MCOperand::createReg(Reg+1));

    Inst.addOperand(MCOperand::createReg(Base));
    Inst.addOperand(MCOperand::createImm(Offset));
  }

  return MCDisassembler::Success;
}

static DecodeStatus DecodeMemMMImm16(MCInst &Inst, unsigned Insn,
                                     uint64_t Address,
                                     const MCDisassembler *Decoder) {
  int Offset = SignExtend32<16>(Insn & 0xffff);
  unsigned Reg = fieldFromInstruction(Insn, 21, 5);
  unsigned Base = fieldFromInstruction(Insn, 16, 5);

  Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
  Base = getReg(Decoder, Mips::GPR32RegClassID, Base);

  Inst.addOperand(MCOperand::createReg(Reg));
  Inst.addOperand(MCOperand::createReg(Base));
  Inst.addOperand(MCOperand::createImm(Offset));

  return MCDisassembler::Success;
}

static DecodeStatus DecodeFMem(MCInst &Inst, unsigned Insn, uint64_t Address,
                               const MCDisassembler *Decoder) {
  int Offset = SignExtend32<16>(Insn & 0xffff);
  unsigned Reg = fieldFromInstruction(Insn, 16, 5);
  unsigned Base = fieldFromInstruction(Insn, 21, 5);

  Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg);
  Base = getReg(Decoder, Mips::GPR32RegClassID, Base);

  Inst.addOperand(MCOperand::createReg(Reg));
  Inst.addOperand(MCOperand::createReg(Base));
  Inst.addOperand(MCOperand::createImm(Offset));

  return MCDisassembler::Success;
}

static DecodeStatus DecodeFMemMMR2(MCInst &Inst, unsigned Insn,
                                   uint64_t Address,
                                   const MCDisassembler *Decoder) {
  // This function is the same as DecodeFMem but with the Reg and Base fields
  // swapped according to microMIPS spec.
  int Offset = SignExtend32<16>(Insn & 0xffff);
  unsigned Base = fieldFromInstruction(Insn, 16, 5);
  unsigned Reg = fieldFromInstruction(Insn, 21, 5);

  Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg);
  Base = getReg(Decoder, Mips::GPR32RegClassID, Base);

  Inst.addOperand(MCOperand::createReg(Reg));
  Inst.addOperand(MCOperand::createReg(Base));
  Inst.addOperand(MCOperand::createImm(Offset));

  return MCDisassembler::Success;
}

static DecodeStatus DecodeFMem2(MCInst &Inst, unsigned Insn, uint64_t Address,
                                const MCDisassembler *Decoder) {
  int Offset = SignExtend32<16>(Insn & 0xffff);
  unsigned Reg = fieldFromInstruction(Insn, 16, 5);
  unsigned Base = fieldFromInstruction(Insn, 21, 5);

  Reg = getReg(Decoder, Mips::COP2RegClassID, Reg);
  Base = getReg(Decoder, Mips::GPR32RegClassID, Base);

  Inst.addOperand(MCOperand::createReg(Reg));
  Inst.addOperand(MCOperand::createReg(Base));
  Inst.addOperand(MCOperand::createImm(Offset));

  return MCDisassembler::Success;
}

static DecodeStatus DecodeFMem3(MCInst &Inst, unsigned Insn, uint64_t Address,
                                const MCDisassembler *Decoder) {
  int Offset = SignExtend32<16>(Insn & 0xffff);
  unsigned Reg = fieldFromInstruction(Insn, 16, 5);
  unsigned Base = fieldFromInstruction(Insn, 21, 5);

  Reg = getReg(Decoder, Mips::COP3RegClassID, Reg);
  Base = getReg(Decoder, Mips::GPR32RegClassID, Base);

  Inst.addOperand(MCOperand::createReg(Reg));
  Inst.addOperand(MCOperand::createReg(Base));
  Inst.addOperand(MCOperand::createImm(Offset));

  return MCDisassembler::Success;
}

static DecodeStatus DecodeFMemCop2R6(MCInst &Inst, unsigned Insn,
                                     uint64_t Address,
                                     const MCDisassembler *Decoder) {
  int Offset = SignExtend32<11>(Insn & 0x07ff);
  unsigned Reg = fieldFromInstruction(Insn, 16, 5);
  unsigned Base = fieldFromInstruction(Insn, 11, 5);

  Reg = getReg(Decoder, Mips::COP2RegClassID, Reg);
  Base = getReg(Decoder, Mips::GPR32RegClassID, Base);

  Inst.addOperand(MCOperand::createReg(Reg));
  Inst.addOperand(MCOperand::createReg(Base));
  Inst.addOperand(MCOperand::createImm(Offset));

  return MCDisassembler::Success;
}

static DecodeStatus DecodeFMemCop2MMR6(MCInst &Inst, unsigned Insn,
                                       uint64_t Address,
                                       const MCDisassembler *Decoder) {
  int Offset = SignExtend32<11>(Insn & 0x07ff);
  unsigned Reg = fieldFromInstruction(Insn, 21, 5);
  unsigned Base = fieldFromInstruction(Insn, 16, 5);

  Reg = getReg(Decoder, Mips::COP2RegClassID, Reg);
  Base = getReg(Decoder, Mips::GPR32RegClassID, Base);

  Inst.addOperand(MCOperand::createReg(Reg));
  Inst.addOperand(MCOperand::createReg(Base));
  Inst.addOperand(MCOperand::createImm(Offset));

  return MCDisassembler::Success;
}

static DecodeStatus DecodeSpecial3LlSc(MCInst &Inst, unsigned Insn,
                                       uint64_t Address,
                                       const MCDisassembler *Decoder) {
  int64_t Offset = SignExtend64<9>((Insn >> 7) & 0x1ff);
  unsigned Rt = fieldFromInstruction(Insn, 16, 5);
  unsigned Base = fieldFromInstruction(Insn, 21, 5);

  Rt = getReg(Decoder, Mips::GPR32RegClassID, Rt);
  Base = getReg(Decoder, Mips::GPR32RegClassID, Base);

  if(Inst.getOpcode() == Mips::SC_R6 || Inst.getOpcode() == Mips::SCD_R6){
    Inst.addOperand(MCOperand::createReg(Rt));
  }

  Inst.addOperand(MCOperand::createReg(Rt));
  Inst.addOperand(MCOperand::createReg(Base));
  Inst.addOperand(MCOperand::createImm(Offset));

  return MCDisassembler::Success;
}

static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst, unsigned RegNo,
                                              uint64_t Address,
                                              const MCDisassembler *Decoder) {
  // Currently only hardware register 29 is supported.
  if (RegNo != 29)
    return  MCDisassembler::Fail;
  Inst.addOperand(MCOperand::createReg(Mips::HWR29));
  return MCDisassembler::Success;
}

static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst, unsigned RegNo,
                                              uint64_t Address,
                                              const MCDisassembler *Decoder) {
  if (RegNo > 30 || RegNo %2)
    return MCDisassembler::Fail;

  unsigned Reg = getReg(Decoder, Mips::AFGR64RegClassID, RegNo /2);
  Inst.addOperand(MCOperand::createReg(Reg));
  return MCDisassembler::Success;
}

static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst, unsigned RegNo,
                                                uint64_t Address,
                                                const MCDisassembler *Decoder) {
  if (RegNo >= 4)
    return MCDisassembler::Fail;

  unsigned Reg = getReg(Decoder, Mips::ACC64DSPRegClassID, RegNo);
  Inst.addOperand(MCOperand::createReg(Reg));
  return MCDisassembler::Success;
}

static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst, unsigned RegNo,
                                               uint64_t Address,
                                               const MCDisassembler *Decoder) {
  if (RegNo >= 4)
    return MCDisassembler::Fail;

  unsigned Reg = getReg(Decoder, Mips::HI32DSPRegClassID, RegNo);
  Inst.addOperand(MCOperand::createReg(Reg));
  return MCDisassembler::Success;
}

static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst, unsigned RegNo,
                                               uint64_t Address,
                                               const MCDisassembler *Decoder) {
  if (RegNo >= 4)
    return MCDisassembler::Fail;

  unsigned Reg = getReg(Decoder, Mips::LO32DSPRegClassID, RegNo);
  Inst.addOperand(MCOperand::createReg(Reg));
  return MCDisassembler::Success;
}

static DecodeStatus DecodeMSA128BRegisterClass(MCInst &Inst, unsigned RegNo,
                                               uint64_t Address,
                                               const MCDisassembler *Decoder) {
  if (RegNo > 31)
    return MCDisassembler::Fail;

  unsigned Reg = getReg(Decoder, Mips::MSA128BRegClassID, RegNo);
  Inst.addOperand(MCOperand::createReg(Reg));
  return MCDisassembler::Success;
}

static DecodeStatus DecodeMSA128HRegisterClass(MCInst &Inst, unsigned RegNo,
                                               uint64_t Address,
                                               const MCDisassembler *Decoder) {
  if (RegNo > 31)
    return MCDisassembler::Fail;

  unsigned Reg = getReg(Decoder, Mips::MSA128HRegClassID, RegNo);
  Inst.addOperand(MCOperand::createReg(Reg));
  return MCDisassembler::Success;
}

static DecodeStatus DecodeMSA128WRegisterClass(MCInst &Inst, unsigned RegNo,
                                               uint64_t Address,
                                               const MCDisassembler *Decoder) {
  if (RegNo > 31)
    return MCDisassembler::Fail;

  unsigned Reg = getReg(Decoder, Mips::MSA128WRegClassID, RegNo);
  Inst.addOperand(MCOperand::createReg(Reg));
  return MCDisassembler::Success;
}

static DecodeStatus DecodeMSA128DRegisterClass(MCInst &Inst, unsigned RegNo,
                                               uint64_t Address,
                                               const MCDisassembler *Decoder) {
  if (RegNo > 31)
    return MCDisassembler::Fail;

  unsigned Reg = getReg(Decoder, Mips::MSA128DRegClassID, RegNo);
  Inst.addOperand(MCOperand::createReg(Reg));
  return MCDisassembler::Success;
}

static DecodeStatus DecodeMSACtrlRegisterClass(MCInst &Inst, unsigned RegNo,
                                               uint64_t Address,
                                               const MCDisassembler *Decoder) {
  if (RegNo > 7)
    return MCDisassembler::Fail;

  unsigned Reg = getReg(Decoder, Mips::MSACtrlRegClassID, RegNo);
  Inst.addOperand(MCOperand::createReg(Reg));
  return MCDisassembler::Success;
}

static DecodeStatus DecodeCOP0RegisterClass(MCInst &Inst, unsigned RegNo,
                                            uint64_t Address,
                                            const MCDisassembler *Decoder) {
  if (RegNo > 31)
    return MCDisassembler::Fail;

  unsigned Reg = getReg(Decoder, Mips::COP0RegClassID, RegNo);
  Inst.addOperand(MCOperand::createReg(Reg));
  return MCDisassembler::Success;
}

static DecodeStatus DecodeCOP2RegisterClass(MCInst &Inst, unsigned RegNo,
                                            uint64_t Address,
                                            const MCDisassembler *Decoder) {
  if (RegNo > 31)
    return MCDisassembler::Fail;

  unsigned Reg = getReg(Decoder, Mips::COP2RegClassID, RegNo);
  Inst.addOperand(MCOperand::createReg(Reg));
  return MCDisassembler::Success;
}

static DecodeStatus DecodeBranchTarget(MCInst &Inst, unsigned Offset,
                                       uint64_t Address,
                                       const MCDisassembler *Decoder) {
  int32_t BranchOffset = (SignExtend32<16>(Offset) * 4) + 4;
  Inst.addOperand(MCOperand::createImm(BranchOffset));
  return MCDisassembler::Success;
}

static DecodeStatus DecodeBranchTarget1SImm16(MCInst &Inst, unsigned Offset,
                                              uint64_t Address,
                                              const MCDisassembler *Decoder) {
  int32_t BranchOffset = (SignExtend32<16>(Offset) * 2);
  Inst.addOperand(MCOperand::createImm(BranchOffset));
  return MCDisassembler::Success;
}

static DecodeStatus DecodeJumpTarget(MCInst &Inst, unsigned Insn,
                                     uint64_t Address,
                                     const MCDisassembler *Decoder) {
  unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 2;
  Inst.addOperand(MCOperand::createImm(JumpOffset));
  return MCDisassembler::Success;
}

static DecodeStatus DecodeBranchTarget21(MCInst &Inst, unsigned Offset,
                                         uint64_t Address,
                                         const MCDisassembler *Decoder) {
  int32_t BranchOffset = SignExtend32<21>(Offset) * 4 + 4;

  Inst.addOperand(MCOperand::createImm(BranchOffset));
  return MCDisassembler::Success;
}

static DecodeStatus DecodeBranchTarget21MM(MCInst &Inst, unsigned Offset,
                                           uint64_t Address,
                                           const MCDisassembler *Decoder) {
  int32_t BranchOffset = SignExtend32<21>(Offset) * 4 + 4;

  Inst.addOperand(MCOperand::createImm(BranchOffset));
  return MCDisassembler::Success;
}

static DecodeStatus DecodeBranchTarget26(MCInst &Inst, unsigned Offset,
                                         uint64_t Address,
                                         const MCDisassembler *Decoder) {
  int32_t BranchOffset = SignExtend32<26>(Offset) * 4 + 4;

  Inst.addOperand(MCOperand::createImm(BranchOffset));
  return MCDisassembler::Success;
}

static DecodeStatus DecodeBranchTarget7MM(MCInst &Inst, unsigned Offset,
                                          uint64_t Address,
                                          const MCDisassembler *Decoder) {
  int32_t BranchOffset = SignExtend32<8>(Offset << 1);
  Inst.addOperand(MCOperand::createImm(BranchOffset));
  return MCDisassembler::Success;
}

static DecodeStatus DecodeBranchTarget10MM(MCInst &Inst, unsigned Offset,
                                           uint64_t Address,
                                           const MCDisassembler *Decoder) {
  int32_t BranchOffset = SignExtend32<11>(Offset << 1);
  Inst.addOperand(MCOperand::createImm(BranchOffset));
  return MCDisassembler::Success;
}

static DecodeStatus DecodeBranchTargetMM(MCInst &Inst, unsigned Offset,
                                         uint64_t Address,
                                         const MCDisassembler *Decoder) {
  int32_t BranchOffset = SignExtend32<16>(Offset) * 2 + 4;
  Inst.addOperand(MCOperand::createImm(BranchOffset));
  return MCDisassembler::Success;
}

static DecodeStatus DecodeBranchTarget26MM(MCInst &Inst, unsigned Offset,
                                           uint64_t Address,
                                           const MCDisassembler *Decoder) {
  int32_t BranchOffset = SignExtend32<27>(Offset << 1);

  Inst.addOperand(MCOperand::createImm(BranchOffset));
  return MCDisassembler::Success;
}

static DecodeStatus DecodeJumpTargetMM(MCInst &Inst, unsigned Insn,
                                       uint64_t Address,
                                       const MCDisassembler *Decoder) {
  unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 1;
  Inst.addOperand(MCOperand::createImm(JumpOffset));
  return MCDisassembler::Success;
}

static DecodeStatus DecodeJumpTargetXMM(MCInst &Inst, unsigned Insn,
                                        uint64_t Address,
                                        const MCDisassembler *Decoder) {
  unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 2;
  Inst.addOperand(MCOperand::createImm(JumpOffset));
  return MCDisassembler::Success;
}

static DecodeStatus DecodeAddiur2Simm7(MCInst &Inst, unsigned Value,
                                       uint64_t Address,
                                       const MCDisassembler *Decoder) {
  if (Value == 0)
    Inst.addOperand(MCOperand::createImm(1));
  else if (Value == 0x7)
    Inst.addOperand(MCOperand::createImm(-1));
  else
    Inst.addOperand(MCOperand::createImm(Value << 2));
  return MCDisassembler::Success;
}

static DecodeStatus DecodeLi16Imm(MCInst &Inst, unsigned Value,
                                  uint64_t Address,
                                  const MCDisassembler *Decoder) {
  if (Value == 0x7F)
    Inst.addOperand(MCOperand::createImm(-1));
  else
    Inst.addOperand(MCOperand::createImm(Value));
  return MCDisassembler::Success;
}

static DecodeStatus DecodePOOL16BEncodedField(MCInst &Inst, unsigned Value,
                                              uint64_t Address,
                                              const MCDisassembler *Decoder) {
  Inst.addOperand(MCOperand::createImm(Value == 0x0 ? 8 : Value));
  return MCDisassembler::Success;
}

template <unsigned Bits, int Offset, int Scale>
static DecodeStatus
DecodeUImmWithOffsetAndScale(MCInst &Inst, unsigned Value, uint64_t Address,
                             const MCDisassembler *Decoder) {
  Value &= ((1 << Bits) - 1);
  Value *= Scale;
  Inst.addOperand(MCOperand::createImm(Value + Offset));
  return MCDisassembler::Success;
}

template <unsigned Bits, int Offset, int ScaleBy>
static DecodeStatus
DecodeSImmWithOffsetAndScale(MCInst &Inst, unsigned Value, uint64_t Address,
                             const MCDisassembler *Decoder) {
  int32_t Imm = SignExtend32<Bits>(Value) * ScaleBy;
  Inst.addOperand(MCOperand::createImm(Imm + Offset));
  return MCDisassembler::Success;
}

static DecodeStatus DecodeInsSize(MCInst &Inst, unsigned Insn, uint64_t Address,
                                  const MCDisassembler *Decoder) {
  // First we need to grab the pos(lsb) from MCInst.
  // This function only handles the 32 bit variants of ins, as dins
  // variants are handled differently.
  int Pos = Inst.getOperand(2).getImm();
  int Size = (int) Insn - Pos + 1;
  Inst.addOperand(MCOperand::createImm(SignExtend32<16>(Size)));
  return MCDisassembler::Success;
}

static DecodeStatus DecodeSimm19Lsl2(MCInst &Inst, unsigned Insn,
                                     uint64_t Address,
                                     const MCDisassembler *Decoder) {
  Inst.addOperand(MCOperand::createImm(SignExtend32<19>(Insn) * 4));
  return MCDisassembler::Success;
}

static DecodeStatus DecodeSimm18Lsl3(MCInst &Inst, unsigned Insn,
                                     uint64_t Address,
                                     const MCDisassembler *Decoder) {
  Inst.addOperand(MCOperand::createImm(SignExtend32<18>(Insn) * 8));
  return MCDisassembler::Success;
}

static DecodeStatus DecodeSimm9SP(MCInst &Inst, unsigned Insn, uint64_t Address,
                                  const MCDisassembler *Decoder) {
  int32_t DecodedValue;
  switch (Insn) {
  case 0: DecodedValue = 256; break;
  case 1: DecodedValue = 257; break;
  case 510: DecodedValue = -258; break;
  case 511: DecodedValue = -257; break;
  default: DecodedValue = SignExtend32<9>(Insn); break;
  }
  Inst.addOperand(MCOperand::createImm(DecodedValue * 4));
  return MCDisassembler::Success;
}

static DecodeStatus DecodeANDI16Imm(MCInst &Inst, unsigned Insn,
                                    uint64_t Address,
                                    const MCDisassembler *Decoder) {
  // Insn must be >= 0, since it is unsigned that condition is always true.
  assert(Insn < 16);
  int32_t DecodedValues[] = {128, 1, 2, 3, 4, 7, 8, 15, 16, 31, 32, 63, 64,
                             255, 32768, 65535};
  Inst.addOperand(MCOperand::createImm(DecodedValues[Insn]));
  return MCDisassembler::Success;
}

static DecodeStatus DecodeRegListOperand(MCInst &Inst, unsigned Insn,
                                         uint64_t Address,
                                         const MCDisassembler *Decoder) {
  unsigned Regs[] = {Mips::S0, Mips::S1, Mips::S2, Mips::S3, Mips::S4, Mips::S5,
                     Mips::S6, Mips::S7, Mips::FP};
  unsigned RegNum;

  unsigned RegLst = fieldFromInstruction(Insn, 21, 5);

  // Empty register lists are not allowed.
  if (RegLst == 0)
    return MCDisassembler::Fail;

  RegNum = RegLst & 0xf;

  // RegLst values 10-15, and 26-31 are reserved.
  if (RegNum > 9)
    return MCDisassembler::Fail;

  for (unsigned i = 0; i < RegNum; i++)
    Inst.addOperand(MCOperand::createReg(Regs[i]));

  if (RegLst & 0x10)
    Inst.addOperand(MCOperand::createReg(Mips::RA));

  return MCDisassembler::Success;
}

static DecodeStatus DecodeRegListOperand16(MCInst &Inst, unsigned Insn,
                                           uint64_t Address,
                                           const MCDisassembler *Decoder) {
  unsigned Regs[] = {Mips::S0, Mips::S1, Mips::S2, Mips::S3};
  unsigned RegLst;
  switch(Inst.getOpcode()) {
  default:
    RegLst = fieldFromInstruction(Insn, 4, 2);
    break;
  case Mips::LWM16_MMR6:
  case Mips::SWM16_MMR6:
    RegLst = fieldFromInstruction(Insn, 8, 2);
    break;
  }
  unsigned RegNum = RegLst & 0x3;

  for (unsigned i = 0; i <= RegNum; i++)
    Inst.addOperand(MCOperand::createReg(Regs[i]));

  Inst.addOperand(MCOperand::createReg(Mips::RA));

  return MCDisassembler::Success;
}

static DecodeStatus DecodeMovePOperands(MCInst &Inst, unsigned Insn,
                                        uint64_t Address,
                                        const MCDisassembler *Decoder) {
  unsigned RegPair = fieldFromInstruction(Insn, 7, 3);
  if (DecodeMovePRegPair(Inst, RegPair, Address, Decoder) ==
      MCDisassembler::Fail)
    return MCDisassembler::Fail;

  unsigned RegRs;
  if (static_cast<const MipsDisassembler*>(Decoder)->hasMips32r6())
    RegRs = fieldFromInstruction(Insn, 0, 2) |
            (fieldFromInstruction(Insn, 3, 1) << 2);
  else
    RegRs = fieldFromInstruction(Insn, 1, 3);
  if (DecodeGPRMM16MovePRegisterClass(Inst, RegRs, Address, Decoder) ==
      MCDisassembler::Fail)
    return MCDisassembler::Fail;

  unsigned RegRt = fieldFromInstruction(Insn, 4, 3);
  if (DecodeGPRMM16MovePRegisterClass(Inst, RegRt, Address, Decoder) ==
      MCDisassembler::Fail)
    return MCDisassembler::Fail;

  return MCDisassembler::Success;
}

static DecodeStatus DecodeMovePRegPair(MCInst &Inst, unsigned RegPair,
                                       uint64_t Address,
                                       const MCDisassembler *Decoder) {
  switch (RegPair) {
  default:
    return MCDisassembler::Fail;
  case 0:
    Inst.addOperand(MCOperand::createReg(Mips::A1));
    Inst.addOperand(MCOperand::createReg(Mips::A2));
    break;
  case 1:
    Inst.addOperand(MCOperand::createReg(Mips::A1));
    Inst.addOperand(MCOperand::createReg(Mips::A3));
    break;
  case 2:
    Inst.addOperand(MCOperand::createReg(Mips::A2));
    Inst.addOperand(MCOperand::createReg(Mips::A3));
    break;
  case 3:
    Inst.addOperand(MCOperand::createReg(Mips::A0));
    Inst.addOperand(MCOperand::createReg(Mips::S5));
    break;
  case 4:
    Inst.addOperand(MCOperand::createReg(Mips::A0));
    Inst.addOperand(MCOperand::createReg(Mips::S6));
    break;
  case 5:
    Inst.addOperand(MCOperand::createReg(Mips::A0));
    Inst.addOperand(MCOperand::createReg(Mips::A1));
    break;
  case 6:
    Inst.addOperand(MCOperand::createReg(Mips::A0));
    Inst.addOperand(MCOperand::createReg(Mips::A2));
    break;
  case 7:
    Inst.addOperand(MCOperand::createReg(Mips::A0));
    Inst.addOperand(MCOperand::createReg(Mips::A3));
    break;
  }

  return MCDisassembler::Success;
}

static DecodeStatus DecodeSimm23Lsl2(MCInst &Inst, unsigned Insn,
                                     uint64_t Address,
                                     const MCDisassembler *Decoder) {
  Inst.addOperand(MCOperand::createImm(SignExtend32<25>(Insn << 2)));
  return MCDisassembler::Success;
}

template <typename InsnType>
static DecodeStatus DecodeBgtzGroupBranchMMR6(MCInst &MI, InsnType insn,
                                              uint64_t Address,
                                              const MCDisassembler *Decoder) {
  // We have:
  //    0b000111 ttttt sssss iiiiiiiiiiiiiiii
  //      Invalid      if rt == 0
  //      BGTZALC_MMR6 if rs == 0 && rt != 0
  //      BLTZALC_MMR6 if rs != 0 && rs == rt
  //      BLTUC_MMR6   if rs != 0 && rs != rt

  InsnType Rt = fieldFromInstruction(insn, 21, 5);
  InsnType Rs = fieldFromInstruction(insn, 16, 5);
  InsnType Imm = 0;
  bool HasRs = false;
  bool HasRt = false;

  if (Rt == 0)
    return MCDisassembler::Fail;
  else if (Rs == 0) {
    MI.setOpcode(Mips::BGTZALC_MMR6);
    HasRt = true;
    Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
  }
  else if (Rs == Rt) {
    MI.setOpcode(Mips::BLTZALC_MMR6);
    HasRs = true;
    Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
  }
  else {
    MI.setOpcode(Mips::BLTUC_MMR6);
    HasRs = true;
    HasRt = true;
    Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
  }

  if (HasRs)
    MI.addOperand(
    MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rs)));

  if (HasRt)
    MI.addOperand(
    MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rt)));

  MI.addOperand(MCOperand::createImm(Imm));

  return MCDisassembler::Success;
}

template <typename InsnType>
static DecodeStatus DecodeBlezGroupBranchMMR6(MCInst &MI, InsnType insn,
                                              uint64_t Address,
                                              const MCDisassembler *Decoder) {
  // We have:
  //    0b000110 ttttt sssss iiiiiiiiiiiiiiii
  //      Invalid        if rt == 0
  //      BLEZALC_MMR6   if rs == 0  && rt != 0
  //      BGEZALC_MMR6   if rs == rt && rt != 0
  //      BGEUC_MMR6     if rs != rt && rs != 0  && rt != 0

  InsnType Rt = fieldFromInstruction(insn, 21, 5);
  InsnType Rs = fieldFromInstruction(insn, 16, 5);
  InsnType Imm = 0;
  bool HasRs = false;

  if (Rt == 0)
    return MCDisassembler::Fail;
  else if (Rs == 0) {
    MI.setOpcode(Mips::BLEZALC_MMR6);
    Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
  }
  else if (Rs == Rt) {
    MI.setOpcode(Mips::BGEZALC_MMR6);
    Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
  }
  else {
    HasRs = true;
    MI.setOpcode(Mips::BGEUC_MMR6);
    Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
  }

  if (HasRs)
    MI.addOperand(
    MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rs)));
  MI.addOperand(
    MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rt)));

  MI.addOperand(MCOperand::createImm(Imm));

  return MCDisassembler::Success;
}

// This instruction does not have a working decoder, and needs to be
// fixed. This "fixme" function was introduced to keep the backend compiling,
// while making changes to tablegen code.
static DecodeStatus DecodeFIXMEInstruction(MCInst &Inst, unsigned Insn,
                                           uint64_t Address,
                                           const MCDisassembler *Decoder) {
  return MCDisassembler::Fail;
}
