//===- 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 "TargetInfo/MipsTargetInfo.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCDecoder.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;
using namespace llvm::MCD;

#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.hasFeature(Mips::FeatureMicroMips)),
        IsBigEndian(IsBigEndian) {}

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

  bool hasMips32r6() const {
    return STI.hasFeature(Mips::FeatureMips32r6);
  }

  bool isFP64() const { return STI.hasFeature(Mips::FeatureFP64Bit); }

  bool isGP64() const { return STI.hasFeature(Mips::FeatureGP64Bit); }

  bool isPTR64() const { return STI.hasFeature(Mips::FeaturePTR64Bit); }

  bool hasCnMips() const { return STI.hasFeature(Mips::FeatureCnMips); }

  bool hasCnMipsP() const { return STI.hasFeature(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

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_ABI LLVM_EXTERNAL_VISIBILITY void
LLVMInitializeMipsDisassembler() {
  // Register the disassembler.
  TargetRegistry::RegisterMCDisassembler(getTheMipsTarget(),
                                         createMipsDisassembler);
  TargetRegistry::RegisterMCDisassembler(getTheMipselTarget(),
                                         createMipselDisassembler);
  TargetRegistry::RegisterMCDisassembler(getTheMips64Target(),
                                         createMipsDisassembler);
  TargetRegistry::RegisterMCDisassembler(getTheMips64elTarget(),
                                         createMipselDisassembler);
}

static MCRegister getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo) {
  const MCRegisterInfo *RegInfo = D->getContext().getRegisterInfo();
  return RegInfo->getRegClass(RC).getRegister(RegNo);
}
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;

  MCRegister 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;

  MCRegister 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;

  MCRegister 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;

  MCRegister 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;

  MCRegister 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;

  MCRegister 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;

  MCRegister 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;

  MCRegister 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;

  MCRegister 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;

  MCRegister 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;

  MCRegister Reg = getReg(Decoder, Mips::COP2RegClassID, RegNo);
  Inst.addOperand(MCOperand::createReg(Reg));
  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;
}

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;
}

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;

  MCRegister 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;
  MCRegister 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;
  MCRegister 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;
  MCRegister Reg = getReg(Decoder, Mips::GPRMM16MovePRegClassID, RegNo);
  Inst.addOperand(MCOperand::createReg(Reg));
  return MCDisassembler::Success;
}

// Tablegen emits references to these unimplemented functions due to usage of
// RegClassByHwMode - it does not detect that the RegClassByHwMode decoders are
// unused, which in turn use these register class decoders.
static DecodeStatus DecodeGP32RegisterClass(MCInst &Inst, unsigned RegNo,
                                            uint64_t Address,
                                            const MCDisassembler *Decoder) {
  llvm_unreachable("this is unused");
}

static DecodeStatus DecodeGP64RegisterClass(MCInst &Inst, unsigned RegNo,
                                            uint64_t Address,
                                            const MCDisassembler *Decoder) {
  llvm_unreachable("this is unused");
}

static DecodeStatus DecodeSP32RegisterClass(MCInst &Inst, unsigned RegNo,
                                            uint64_t Address,
                                            const MCDisassembler *Decoder) {
  llvm_unreachable("this is unused");
}

static DecodeStatus DecodeSP64RegisterClass(MCInst &Inst, unsigned RegNo,
                                            uint64_t Address,
                                            const MCDisassembler *Decoder) {
  llvm_unreachable("this is unused");
}

static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst, unsigned RegNo,
                                             uint64_t Address,
                                             const MCDisassembler *Decoder) {
  if (RegNo > 31)
    return MCDisassembler::Fail;
  MCRegister 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;

  MCRegister 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;

  MCRegister 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;
  MCRegister 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;
  MCRegister Reg = getReg(Decoder, Mips::FCCRegClassID, RegNo);
  Inst.addOperand(MCOperand::createReg(Reg));
  return MCDisassembler::Success;
}

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

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

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

  MCRegister Reg = getReg(Decoder, Mips::FGR64CCRegClassID, 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 RegNo = fieldFromInstruction(Insn, 16, 5);
  unsigned BaseNo = fieldFromInstruction(Insn, 21, 5);

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

  if (Inst.getOpcode() == Mips::SC || Inst.getOpcode() == Mips::SC64 ||
      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 RegNo = fieldFromInstruction(Insn, 16, 5);
  unsigned BaseNo = fieldFromInstruction(Insn, 21, 5);

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

  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 BaseNo = fieldFromInstruction(Insn, 16, 5);
  unsigned RegNo = fieldFromInstruction(Insn, 21, 5);

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

  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 BaseNo = fieldFromInstruction(Insn, 21, 5);

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

  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 BaseNo = fieldFromInstruction(Insn, 16, 5);
  unsigned Hint = fieldFromInstruction(Insn, 21, 5);

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

  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 BaseNo = fieldFromInstruction(Insn, 16, 5);
  unsigned Hint = fieldFromInstruction(Insn, 21, 5);

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

  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 BaseNo = fieldFromInstruction(Insn, 21, 5);

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

  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 BaseNo = fieldFromInstruction(Insn, 21, 5);

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

  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 BaseNo = fieldFromInstruction(Insn, 16, 5);

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

  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 BaseNo = fieldFromInstruction(Insn, 16, 5);

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

  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 RegNo = fieldFromInstruction(Insn, 6, 5);
  unsigned BaseNo = fieldFromInstruction(Insn, 11, 5);

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

  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 RegNo = fieldFromInstruction(Insn, 5, 5);

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

  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 RegNo = fieldFromInstruction(Insn, 7, 3);

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

  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 RegNo = fieldFromInstruction(Insn, 21, 5);
  unsigned BaseNo = fieldFromInstruction(Insn, 16, 5);

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

  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 RegNo = fieldFromInstruction(Insn, 21, 5);
  unsigned BaseNo = fieldFromInstruction(Insn, 16, 5);

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

  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 RegNo = fieldFromInstruction(Insn, 21, 5);
  unsigned BaseNo = fieldFromInstruction(Insn, 16, 5);

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

  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 RegNo = fieldFromInstruction(Insn, 16, 5);
  unsigned BaseNo = fieldFromInstruction(Insn, 21, 5);

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

  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 BaseNo = fieldFromInstruction(Insn, 16, 5);
  unsigned RegNo = fieldFromInstruction(Insn, 21, 5);

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

  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 RegNo = fieldFromInstruction(Insn, 16, 5);
  unsigned BaseNo = fieldFromInstruction(Insn, 21, 5);

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

  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 RegNo = fieldFromInstruction(Insn, 16, 5);
  unsigned BaseNo = fieldFromInstruction(Insn, 21, 5);

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

  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 RegNo = fieldFromInstruction(Insn, 16, 5);
  unsigned BaseNo = fieldFromInstruction(Insn, 11, 5);

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

  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 RegNo = fieldFromInstruction(Insn, 21, 5);
  unsigned BaseNo = fieldFromInstruction(Insn, 16, 5);

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

  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 RtNo = fieldFromInstruction(Insn, 16, 5);
  unsigned BaseNo = fieldFromInstruction(Insn, 21, 5);

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

  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 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 = 0, int ScaleBy = 1>
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;
}

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);
}

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 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 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 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;
}

#include "MipsGenDisassemblerTables.inc"

/// 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;
}
