diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2014-11-24 17:02:24 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2014-11-24 17:02:24 +0000 | 
| commit | 91bc56ed825ba56b3cc264aa5c95ab84f86832ab (patch) | |
| tree | 4df130b28021d86e13bf4565ef58c1c5a5e093b4 /contrib/llvm/lib/Target/Mips/Disassembler | |
| parent | 9efc7e72bb1daf5d6019871d9c93a1c488a11229 (diff) | |
| parent | 5ca98fd98791947eba83a1ed3f2c8191ef7afa6c (diff) | |
Notes
Diffstat (limited to 'contrib/llvm/lib/Target/Mips/Disassembler')
| -rw-r--r-- | contrib/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp | 626 | 
1 files changed, 566 insertions, 60 deletions
diff --git a/contrib/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp b/contrib/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp index 60508a8c4fcb..f35a8deefcff 100644 --- a/contrib/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp +++ b/contrib/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp @@ -14,6 +14,7 @@  #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" @@ -24,6 +25,8 @@  using namespace llvm; +#define DEBUG_TYPE "mips-disassembler" +  typedef MCDisassembler::DecodeStatus DecodeStatus;  namespace { @@ -33,19 +36,16 @@ class MipsDisassemblerBase : public MCDisassembler {  public:    /// Constructor     - Initializes the disassembler.    /// -  MipsDisassemblerBase(const MCSubtargetInfo &STI, const MCRegisterInfo *Info, +  MipsDisassemblerBase(const MCSubtargetInfo &STI, MCContext &Ctx,                         bool bigEndian) : -    MCDisassembler(STI), RegInfo(Info), +    MCDisassembler(STI, Ctx),      IsN64(STI.getFeatureBits() & Mips::FeatureN64), isBigEndian(bigEndian) {}    virtual ~MipsDisassemblerBase() {} -  const MCRegisterInfo *getRegInfo() const { return RegInfo.get(); } -    bool isN64() const { return IsN64; }  private: -  OwningPtr<const MCRegisterInfo> RegInfo;    bool IsN64;  protected:    bool isBigEndian; @@ -57,19 +57,31 @@ class MipsDisassembler : public MipsDisassemblerBase {  public:    /// Constructor     - Initializes the disassembler.    /// -  MipsDisassembler(const MCSubtargetInfo &STI, const MCRegisterInfo *Info, -                   bool bigEndian) : -    MipsDisassemblerBase(STI, Info, bigEndian) { -      IsMicroMips = STI.getFeatureBits() & Mips::FeatureMicroMips; -    } +  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. -  virtual DecodeStatus getInstruction(MCInst &instr, -                                      uint64_t &size, -                                      const MemoryObject ®ion, -                                      uint64_t address, -                                      raw_ostream &vStream, -                                      raw_ostream &cStream) const; +  DecodeStatus getInstruction(MCInst &instr, +                              uint64_t &size, +                              const MemoryObject ®ion, +                              uint64_t address, +                              raw_ostream &vStream, +                              raw_ostream &cStream) const override;  }; @@ -78,17 +90,17 @@ class Mips64Disassembler : public MipsDisassemblerBase {  public:    /// Constructor     - Initializes the disassembler.    /// -  Mips64Disassembler(const MCSubtargetInfo &STI, const MCRegisterInfo *Info, +  Mips64Disassembler(const MCSubtargetInfo &STI, MCContext &Ctx,                       bool bigEndian) : -    MipsDisassemblerBase(STI, Info, bigEndian) {} +    MipsDisassemblerBase(STI, Ctx, bigEndian) {}    /// getInstruction - See MCDisassembler. -  virtual DecodeStatus getInstruction(MCInst &instr, -                                      uint64_t &size, -                                      const MemoryObject ®ion, -                                      uint64_t address, -                                      raw_ostream &vStream, -                                      raw_ostream &cStream) const; +  DecodeStatus getInstruction(MCInst &instr, +                              uint64_t &size, +                              const MemoryObject ®ion, +                              uint64_t address, +                              raw_ostream &vStream, +                              raw_ostream &cStream) const override;  };  } // end anonymous namespace @@ -130,11 +142,6 @@ static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,                                               uint64_t Address,                                               const void *Decoder); -static DecodeStatus DecodeFGRH32RegisterClass(MCInst &Inst, -                                              unsigned RegNo, -                                              uint64_t Address, -                                              const void *Decoder); -  static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,                                             unsigned RegNo,                                             uint64_t Address, @@ -145,6 +152,10 @@ static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst,                                             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, @@ -195,6 +206,11 @@ static DecodeStatus DecodeMSACtrlRegisterClass(MCInst &Inst,                                                 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, @@ -205,6 +221,16 @@ static DecodeStatus DecodeJumpTarget(MCInst &Inst,                                       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, @@ -241,6 +267,11 @@ static DecodeStatus DecodeFMem(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, @@ -263,6 +294,48 @@ static DecodeStatus DecodeExtSize(MCInst &Inst,                                    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; @@ -270,26 +343,30 @@ extern Target TheMipselTarget, TheMipsTarget, TheMips64Target,  static MCDisassembler *createMipsDisassembler(                         const Target &T, -                       const MCSubtargetInfo &STI) { -  return new MipsDisassembler(STI, T.createMCRegInfo(""), true); +                       const MCSubtargetInfo &STI, +                       MCContext &Ctx) { +  return new MipsDisassembler(STI, Ctx, true);  }  static MCDisassembler *createMipselDisassembler(                         const Target &T, -                       const MCSubtargetInfo &STI) { -  return new MipsDisassembler(STI, T.createMCRegInfo(""), false); +                       const MCSubtargetInfo &STI, +                       MCContext &Ctx) { +  return new MipsDisassembler(STI, Ctx, false);  }  static MCDisassembler *createMips64Disassembler(                         const Target &T, -                       const MCSubtargetInfo &STI) { -  return new Mips64Disassembler(STI, T.createMCRegInfo(""), true); +                       const MCSubtargetInfo &STI, +                       MCContext &Ctx) { +  return new Mips64Disassembler(STI, Ctx, true);  }  static MCDisassembler *createMips64elDisassembler(                         const Target &T, -                       const MCSubtargetInfo &STI) { -  return new Mips64Disassembler(STI, T.createMCRegInfo(""), false); +                       const MCSubtargetInfo &STI, +                       MCContext &Ctx) { +  return new Mips64Disassembler(STI, Ctx, false);  }  extern "C" void LLVMInitializeMipsDisassembler() { @@ -304,9 +381,316 @@ extern "C" void LLVMInitializeMipsDisassembler() {                                           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) << 2; +  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) << 2; +  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) << 2; +  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) << 2; + +  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) << 2; +  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) << 2; +  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 ®ion, @@ -366,6 +750,7 @@ MipsDisassembler::getInstruction(MCInst &instr,      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); @@ -376,6 +761,37 @@ MipsDisassembler::getInstruction(MCInst &instr,      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); @@ -419,11 +835,6 @@ Mips64Disassembler::getInstruction(MCInst &instr,    return MCDisassembler::Fail;  } -static unsigned getReg(const void *D, unsigned RC, unsigned RegNo) { -  const MipsDisassemblerBase *Dis = static_cast<const MipsDisassemblerBase*>(D); -  return *(Dis->getRegInfo()->getRegClass(RC).begin() + RegNo); -} -  static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst,                                                   unsigned RegNo,                                                   uint64_t Address, @@ -498,18 +909,6 @@ static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,    return MCDisassembler::Success;  } -static DecodeStatus DecodeFGRH32RegisterClass(MCInst &Inst, -                                              unsigned RegNo, -                                              uint64_t Address, -                                              const void *Decoder) { -  if (RegNo > 31) -    return MCDisassembler::Fail; - -  unsigned Reg = getReg(Decoder, Mips::FGRH32RegClassID, RegNo); -  Inst.addOperand(MCOperand::CreateReg(Reg)); -  return MCDisassembler::Success; -} -  static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,                                             unsigned RegNo,                                             uint64_t Address, @@ -532,6 +931,17 @@ static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst,    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, @@ -565,7 +975,37 @@ static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn,    Inst.addOperand(MCOperand::CreateReg(Reg));    Inst.addOperand(MCOperand::CreateReg(Base)); -  Inst.addOperand(MCOperand::CreateImm(Offset)); + +  // 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 << 1)); +    break; +  case Mips::LD_W: +  case Mips::ST_W: +    Inst.addOperand(MCOperand::CreateImm(Offset << 2)); +    break; +  case Mips::LD_D: +  case Mips::ST_D: +    Inst.addOperand(MCOperand::CreateImm(Offset << 3)); +    break; +  }    return MCDisassembler::Success;  } @@ -581,6 +1021,9 @@ static DecodeStatus DecodeMemMMImm12(MCInst &Inst,    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)); @@ -624,6 +1067,27 @@ static DecodeStatus DecodeFMem(MCInst &Inst,    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, @@ -745,12 +1209,23 @@ static DecodeStatus DecodeMSACtrlRegisterClass(MCInst &Inst,    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) { -  unsigned BranchOffset = Offset & 0xffff; -  BranchOffset = SignExtend32<18>(BranchOffset << 2) + 4; +  int32_t BranchOffset = (SignExtend32<16>(Offset) << 2) + 4;    Inst.addOperand(MCOperand::CreateImm(BranchOffset));    return MCDisassembler::Success;  } @@ -765,12 +1240,31 @@ static DecodeStatus DecodeJumpTarget(MCInst &Inst,    return MCDisassembler::Success;  } +static DecodeStatus DecodeBranchTarget21(MCInst &Inst, +                                         unsigned Offset, +                                         uint64_t Address, +                                         const void *Decoder) { +  int32_t BranchOffset = SignExtend32<21>(Offset) << 2; + +  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) << 2; + +  Inst.addOperand(MCOperand::CreateImm(BranchOffset)); +  return MCDisassembler::Success; +} +  static DecodeStatus DecodeBranchTargetMM(MCInst &Inst,                                           unsigned Offset,                                           uint64_t Address,                                           const void *Decoder) { -  unsigned BranchOffset = Offset & 0xffff; -  BranchOffset = SignExtend32<18>(BranchOffset << 1); +  int32_t BranchOffset = SignExtend32<16>(Offset) << 1;    Inst.addOperand(MCOperand::CreateImm(BranchOffset));    return MCDisassembler::Success;  } @@ -820,3 +1314,15 @@ static DecodeStatus DecodeExtSize(MCInst &Inst,    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) << 2)); +  return MCDisassembler::Success; +} + +static DecodeStatus DecodeSimm18Lsl3(MCInst &Inst, unsigned Insn, +                                     uint64_t Address, const void *Decoder) { +  Inst.addOperand(MCOperand::CreateImm(SignExtend32<18>(Insn) << 3)); +  return MCDisassembler::Success; +}  | 
