//===- 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.h"
#include "llvm/MC/MCFixedLenDisassembler.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/MemoryObject.h"
#include "llvm/Support/TargetRegistry.h"

using namespace llvm;

#define DEBUG_TYPE "mips-disassembler"

typedef MCDisassembler::DecodeStatus DecodeStatus;

namespace {

/// MipsDisassemblerBase - a disasembler class for Mips.
class MipsDisassemblerBase : public MCDisassembler {
public:
  /// Constructor     - Initializes the disassembler.
  ///
  MipsDisassemblerBase(const MCSubtargetInfo &STI, MCContext &Ctx,
                       bool bigEndian) :
    MCDisassembler(STI, Ctx),
    IsN64(STI.getFeatureBits() & Mips::FeatureN64), isBigEndian(bigEndian) {}

  virtual ~MipsDisassemblerBase() {}

  bool isN64() const { return IsN64; }

private:
  bool IsN64;
protected:
  bool isBigEndian;
};

/// MipsDisassembler - a disasembler class for Mips32.
class MipsDisassembler : public MipsDisassemblerBase {
  bool IsMicroMips;
public:
  /// Constructor     - Initializes the disassembler.
  ///
  MipsDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx, bool bigEndian)
      : MipsDisassemblerBase(STI, Ctx, bigEndian) {
    IsMicroMips = STI.getFeatureBits() & Mips::FeatureMicroMips;
  }

  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 isGP64() const { return STI.getFeatureBits() & Mips::FeatureGP64Bit; }

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

  /// getInstruction - See MCDisassembler.
  DecodeStatus getInstruction(MCInst &instr,
                              uint64_t &size,
                              const MemoryObject &region,
                              uint64_t address,
                              raw_ostream &vStream,
                              raw_ostream &cStream) const override;
};


/// Mips64Disassembler - a disasembler class for Mips64.
class Mips64Disassembler : public MipsDisassemblerBase {
public:
  /// Constructor     - Initializes the disassembler.
  ///
  Mips64Disassembler(const MCSubtargetInfo &STI, MCContext &Ctx,
                     bool bigEndian) :
    MipsDisassemblerBase(STI, Ctx, bigEndian) {}

  /// getInstruction - See MCDisassembler.
  DecodeStatus getInstruction(MCInst &instr,
                              uint64_t &size,
                              const MemoryObject &region,
                              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 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 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 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 DecodeBranchTarget26(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);

// 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 DecodeCacheOp(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 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 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 DecodeSpecial3LlSc(MCInst &Inst,
                                       unsigned Insn,
                                       uint64_t Address,
                                       const void *Decoder);

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

// Decode the immediate field of an LSA instruction which
// is off by one.
static DecodeStatus DecodeLSAImm(MCInst &Inst,
                                 unsigned Insn,
                                 uint64_t Address,
                                 const void *Decoder);

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

static DecodeStatus DecodeExtSize(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);

/// 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
DecodeDaddiGroupBranch(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);

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

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

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

extern "C" void LLVMInitializeMipsDisassembler() {
  // Register the disassembler.
  TargetRegistry::RegisterMCDisassembler(TheMipsTarget,
                                         createMipsDisassembler);
  TargetRegistry::RegisterMCDisassembler(TheMipselTarget,
                                         createMipselDisassembler);
  TargetRegistry::RegisterMCDisassembler(TheMips64Target,
                                         createMips64Disassembler);
  TargetRegistry::RegisterMCDisassembler(TheMips64elTarget,
                                         createMips64elDisassembler);
}

#include "MipsGenDisassemblerTables.inc"

static unsigned getReg(const void *D, unsigned RC, unsigned RegNo) {
  const MipsDisassemblerBase *Dis = static_cast<const MipsDisassemblerBase*>(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);
  InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 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 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);
  InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 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 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);
  InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 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);
  InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 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);
  InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 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);
  InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 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;
}

  /// readInstruction - read four bytes from the MemoryObject
  /// and return 32 bit word sorted according to the given endianess
static DecodeStatus readInstruction32(const MemoryObject &region,
                                      uint64_t address,
                                      uint64_t &size,
                                      uint32_t &insn,
                                      bool isBigEndian,
                                      bool IsMicroMips) {
  uint8_t Bytes[4];

  // We want to read exactly 4 Bytes of data.
  if (region.readBytes(address, 4, Bytes) == -1) {
    size = 0;
    return MCDisassembler::Fail;
  }

  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 {
    // Encoded as a small-endian 32-bit word in the stream.
    // Little-endian byte ordering:
    //   mips32r2:   4 | 3 | 2 | 1
    //   microMIPS:  2 | 1 | 4 | 3
    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,
                                 const MemoryObject &Region,
                                 uint64_t Address,
                                 raw_ostream &vStream,
                                 raw_ostream &cStream) const {
  uint32_t Insn;

  DecodeStatus Result = readInstruction32(Region, Address, Size,
                                          Insn, isBigEndian, IsMicroMips);
  if (Result == MCDisassembler::Fail)
    return MCDisassembler::Fail;

  if (IsMicroMips) {
    DEBUG(dbgs() << "Trying MicroMips32 table (32-bit opcodes):\n");
    // Calling the auto-generated decoder function.
    Result = decodeInstruction(DecoderTableMicroMips32, instr, Insn, Address,
                               this, STI);
    if (Result != MCDisassembler::Fail) {
      Size = 4;
      return Result;
    }
    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()) {
    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;
    }
  }

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

  return MCDisassembler::Fail;
}

DecodeStatus
Mips64Disassembler::getInstruction(MCInst &instr,
                                   uint64_t &Size,
                                   const MemoryObject &Region,
                                   uint64_t Address,
                                   raw_ostream &vStream,
                                   raw_ostream &cStream) const {
  uint32_t Insn;

  DecodeStatus Result = readInstruction32(Region, Address, Size,
                                          Insn, isBigEndian, false);
  if (Result == MCDisassembler::Fail)
    return MCDisassembler::Fail;

  // Calling the auto-generated decoder function.
  Result = decodeInstruction(DecoderTableMips6432, instr, Insn, Address,
                             this, STI);
  if (Result != MCDisassembler::Fail) {
    Size = 4;
    return Result;
  }
  // If we fail to decode in Mips64 decoder space we can try in Mips32
  Result = decodeInstruction(DecoderTableMips32, instr, Insn, Address,
                             this, STI);
  if (Result != MCDisassembler::Fail) {
    Size = 4;
    return Result;
  }

  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 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)->isN64())
    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.addOperand(MCOperand::CreateReg(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 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 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);

  if (Inst.getOpcode() == Mips::SC_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 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 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 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 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 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;

  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;

  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 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 DecodeSimm16(MCInst &Inst,
                                 unsigned Insn,
                                 uint64_t Address,
                                 const void *Decoder) {
  Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Insn)));
  return MCDisassembler::Success;
}

static DecodeStatus DecodeLSAImm(MCInst &Inst,
                                 unsigned Insn,
                                 uint64_t Address,
                                 const void *Decoder) {
  // We add one to the immediate field as it was encoded as 'imm - 1'.
  Inst.addOperand(MCOperand::CreateImm(Insn + 1));
  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 DecodeExtSize(MCInst &Inst,
                                  unsigned Insn,
                                  uint64_t Address,
                                  const void *Decoder) {
  int Size = (int) Insn  + 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;
}
