//===- MipsDisassembler.cpp - Disassembler for Mips -------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file is part of the Mips Disassembler.
//
//===----------------------------------------------------------------------===//

#include "Mips.h"
#include "MipsRegisterInfo.h"
#include "MipsSubtarget.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCDisassembler/MCDisassembler.h"
#include "llvm/MC/MCFixedLenDisassembler.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/TargetRegistry.h"

using namespace llvm;

#define DEBUG_TYPE "mips-disassembler"

typedef MCDisassembler::DecodeStatus 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 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 &VStream,
                              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 void *Decoder);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

template <unsigned Bits, int Offset>
static DecodeStatus DecodeUImmWithOffset(MCInst &Inst, unsigned Value,
                                         uint64_t Address,
                                         const void *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 void *Decoder);

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

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

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

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

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

static DecodeStatus DecodeSimm23Lsl2(MCInst &Inst, unsigned Insn,
                                     uint64_t Address, const void *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 void *Decoder);

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

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

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

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

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

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

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

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

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

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

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

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

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

namespace llvm {
extern Target TheMipselTarget, TheMipsTarget, TheMips64Target,
              TheMips64elTarget;
}

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" void LLVMInitializeMipsDisassembler() {
  // Register the disassembler.
  TargetRegistry::RegisterMCDisassembler(TheMipsTarget,
                                         createMipsDisassembler);
  TargetRegistry::RegisterMCDisassembler(TheMipselTarget,
                                         createMipselDisassembler);
  TargetRegistry::RegisterMCDisassembler(TheMips64Target,
                                         createMipsDisassembler);
  TargetRegistry::RegisterMCDisassembler(TheMips64elTarget,
                                         createMipselDisassembler);
}

#include "MipsGenDisassemblerTables.inc"

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

template <typename InsnType>
static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address,
                                   const void *Decoder) {
  typedef DecodeStatus (*DecodeFN)(MCInst &, unsigned, uint64_t, const void *);
  // 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 DecodeAddiGroupBranch(MCInst &MI, InsnType insn,
                                          uint64_t Address,
                                          const void *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 void *Decoder) {
  InsnType Rt = fieldFromInstruction(insn, 21, 5);
  InsnType Rs = fieldFromInstruction(insn, 16, 5);
  InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2;

  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)));
  } 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)));
  } else {
    MI.setOpcode(Mips::BEQZALC_MMR6);
    MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
                                       Rt)));
  }

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

  return MCDisassembler::Success;
}

template <typename InsnType>
static DecodeStatus DecodeDaddiGroupBranch(MCInst &MI, InsnType insn,
                                           uint64_t Address,
                                           const void *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 void *Decoder) {
  InsnType Rt = fieldFromInstruction(insn, 21, 5);
  InsnType Rs = fieldFromInstruction(insn, 16, 5);
  InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2;

  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)));
  } 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)));
  } else {
    MI.setOpcode(Mips::BNEZALC_MMR6);
    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 void *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 void *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 void *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 void *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;
}

/// Read two bytes from the ArrayRef and return 16 bit halfword sorted
/// according to the given endianess.
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 endianess
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 &VStream,
                                              raw_ostream &CStream) const {
  uint32_t Insn;
  DecodeStatus Result;

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

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

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

    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 (hasMips32r6() && isFP64()) {
      DEBUG(dbgs() << "Trying MicroMips32r6FP64 table (32-bit opcodes):\n");
      Result = decodeInstruction(DecoderTableMicroMips32r6FP6432, Instr, Insn,
                                 Address, this, STI);
      if (Result != MCDisassembler::Fail) {
        Size = 4;
        return Result;
      }
    }

    // This is an invalid instruction. Let the disassembler move forward by the
    // minimum instruction size.
    Size = 2;
    return MCDisassembler::Fail;
  }

  Result = readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, false);
  if (Result == MCDisassembler::Fail) {
    Size = 4;
    return MCDisassembler::Fail;
  }

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

  if (hasMips32r6() && isGP64()) {
    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) {
      Size = 4;
      return Result;
    }
  }

  if (hasMips32r6() && isPTR64()) {
    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) {
      Size = 4;
      return Result;
    }
  }

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

  if (hasMips2() && isPTR64()) {
    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) {
      Size = 4;
      return Result;
    }
  }

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

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

  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) {
    Size = 4;
    return Result;
  }

  Size = 4;
  return MCDisassembler::Fail;
}

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

  return MCDisassembler::Fail;

}

static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst,
                                             unsigned RegNo,
                                             uint64_t Address,
                                             const void *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 void *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 void *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 void *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 void *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 void *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 void *Decoder) {
  return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
}

static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
                                             unsigned RegNo,
                                             uint64_t Address,
                                             const void *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 void *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 void *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 void *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 void *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 void *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 void *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 DecodeLoadByte9(MCInst &Inst,
                                    unsigned Insn,
                                    uint64_t Address,
                                    const void *Decoder) {
  int Offset = SignExtend32<9>(Insn & 0x1ff);
  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 DecodeLoadByte15(MCInst &Inst,
                                     unsigned Insn,
                                     uint64_t Address,
                                     const void *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 void *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 void *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 void *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 void *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 DecodeStoreEvaOpMM(MCInst &Inst,
                                       unsigned Insn,
                                       uint64_t Address,
                                       const void *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);

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

  return MCDisassembler::Success;
}

static DecodeStatus DecodeSyncI(MCInst &Inst,
                              unsigned Insn,
                              uint64_t Address,
                              const void *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 DecodeSynciR6(MCInst &Inst,
                                  unsigned Insn,
                                  uint64_t Address,
                                  const void *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 void *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 (0 && "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 void *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 void *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 void *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 void *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 void *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.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 void *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.getOpcode() == Mips::LWP_MMR6 || Inst.getOpcode() == Mips::SWP_MMR6)
      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 void *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 void *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 void *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 void *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 void *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 void *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 void *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 void *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 void *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 void *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 void *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 void *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 void *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 void *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 void *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 void *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 void *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 void *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 void *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 void *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 void *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 void *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 void *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 void *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 void *Decoder) {
  int32_t BranchOffset = SignExtend32<21>(Offset) << 1;

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

static DecodeStatus DecodeBranchTarget26(MCInst &Inst,
                                         unsigned Offset,
                                         uint64_t Address,
                                         const void *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 void *Decoder) {
  int32_t BranchOffset = SignExtend32<7>(Offset) << 1;
  Inst.addOperand(MCOperand::createImm(BranchOffset));
  return MCDisassembler::Success;
}

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

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

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

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

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

static DecodeStatus DecodeAddiur2Simm7(MCInst &Inst,
                                       unsigned Value,
                                       uint64_t Address,
                                       const void *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 void *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 void *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 void *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 void *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 void *Decoder) {
  // First we need to grab the pos(lsb) from MCInst.
  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 void *Decoder) {
  Inst.addOperand(MCOperand::createImm(SignExtend32<19>(Insn) * 4));
  return MCDisassembler::Success;
}

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

static DecodeStatus DecodeSimm9SP(MCInst &Inst, unsigned Insn,
                                  uint64_t Address, const void *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 void *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 void *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 void *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 DecodeMovePRegPair(MCInst &Inst, unsigned Insn,
                                       uint64_t Address, const void *Decoder) {

  unsigned RegPair = fieldFromInstruction(Insn, 7, 3);

  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 void *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 void *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 = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2;
  bool HasRs = false;
  bool HasRt = false;

  if (Rt == 0)
    return MCDisassembler::Fail;
  else if (Rs == 0) {
    MI.setOpcode(Mips::BGTZALC_MMR6);
    HasRt = true;
  }
  else if (Rs == Rt) {
    MI.setOpcode(Mips::BLTZALC_MMR6);
    HasRs = true;
  }
  else {
    MI.setOpcode(Mips::BLTUC_MMR6);
    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 DecodeBlezGroupBranchMMR6(MCInst &MI, InsnType insn,
  uint64_t Address,
  const void *Decoder) {
  // We have:
  //    0b000110 ttttt sssss iiiiiiiiiiiiiiii
  //      Invalid        if rs == 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 = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2;
  bool HasRs = false;

  if (Rt == 0)
    return MCDisassembler::Fail;
  else if (Rs == 0)
    MI.setOpcode(Mips::BLEZALC_MMR6);
  else if (Rs == Rt)
    MI.setOpcode(Mips::BGEZALC_MMR6);
  else {
    HasRs = true;
    MI.setOpcode(Mips::BGEUC_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;
}
