diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2016-07-23 20:41:05 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2016-07-23 20:41:05 +0000 | 
| commit | 01095a5d43bbfde13731688ddcf6048ebb8b7721 (patch) | |
| tree | 4def12e759965de927d963ac65840d663ef9d1ea /lib/Target/Mips/Disassembler/MipsDisassembler.cpp | |
| parent | f0f4822ed4b66e3579e92a89f368f8fb860e218e (diff) | |
Notes
Diffstat (limited to 'lib/Target/Mips/Disassembler/MipsDisassembler.cpp')
| -rw-r--r-- | lib/Target/Mips/Disassembler/MipsDisassembler.cpp | 376 | 
1 files changed, 313 insertions, 63 deletions
diff --git a/lib/Target/Mips/Disassembler/MipsDisassembler.cpp b/lib/Target/Mips/Disassembler/MipsDisassembler.cpp index 3c1a771f97e9..aebb4ef419d1 100644 --- a/lib/Target/Mips/Disassembler/MipsDisassembler.cpp +++ b/lib/Target/Mips/Disassembler/MipsDisassembler.cpp @@ -15,7 +15,7 @@  #include "MipsRegisterInfo.h"  #include "MipsSubtarget.h"  #include "llvm/MC/MCContext.h" -#include "llvm/MC/MCDisassembler.h" +#include "llvm/MC/MCDisassembler/MCDisassembler.h"  #include "llvm/MC/MCFixedLenDisassembler.h"  #include "llvm/MC/MCInst.h"  #include "llvm/MC/MCSubtargetInfo.h" @@ -39,14 +39,18 @@ public:          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 { @@ -193,6 +197,11 @@ static DecodeStatus DecodeBranchTarget(MCInst &Inst,                                         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, @@ -203,6 +212,11 @@ static DecodeStatus DecodeBranchTarget21(MCInst &Inst,                                           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, @@ -340,6 +354,10 @@ 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); @@ -352,6 +370,10 @@ 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, @@ -362,12 +384,7 @@ static DecodeStatus DecodeAddiur2Simm7(MCInst &Inst,                                         uint64_t Address,                                         const void *Decoder); -static DecodeStatus DecodeUImm6Lsl2(MCInst &Inst, -                                    unsigned Value, -                                    uint64_t Address, -                                    const void *Decoder); - -static DecodeStatus DecodeLiSimm7(MCInst &Inst, +static DecodeStatus DecodeLi16Imm(MCInst &Inst,                                    unsigned Value,                                    uint64_t Address,                                    const void *Decoder); @@ -377,19 +394,23 @@ static DecodeStatus DecodePOOL16BEncodedField(MCInst &Inst,                                                uint64_t Address,                                                const void *Decoder); -static DecodeStatus DecodeSimm4(MCInst &Inst, -                                unsigned Value, -                                uint64_t Address, -                                const void *Decoder); - -static DecodeStatus DecodeSimm16(MCInst &Inst, -                                 unsigned Insn, -                                 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); +                                         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, @@ -408,9 +429,6 @@ static DecodeStatus DecodeSimm9SP(MCInst &Inst, unsigned Insn,  static DecodeStatus DecodeANDI16Imm(MCInst &Inst, unsigned Insn,                                      uint64_t Address, const void *Decoder); -static DecodeStatus DecodeUImm5lsl2(MCInst &Inst, unsigned Insn, -                                   uint64_t Address, const void *Decoder); -  static DecodeStatus DecodeSimm23Lsl2(MCInst &Inst, unsigned Insn,                                       uint64_t Address, const void *Decoder); @@ -427,11 +445,21 @@ DecodeAddiGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,  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); @@ -450,6 +478,16 @@ 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); @@ -563,7 +601,7 @@ static DecodeStatus DecodeAddiGroupBranch(MCInst &MI, InsnType insn,    InsnType Rs = fieldFromInstruction(insn, 21, 5);    InsnType Rt = fieldFromInstruction(insn, 16, 5); -  InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4; +  int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;    bool HasRs = false;    if (Rs >= Rt) { @@ -587,6 +625,37 @@ static DecodeStatus DecodeAddiGroupBranch(MCInst &MI, InsnType insn,  }  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) { @@ -602,7 +671,7 @@ static DecodeStatus DecodeDaddiGroupBranch(MCInst &MI, InsnType insn,    InsnType Rs = fieldFromInstruction(insn, 21, 5);    InsnType Rt = fieldFromInstruction(insn, 16, 5); -  InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4; +  int64_t  Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;    bool HasRs = false;    if (Rs >= Rt) { @@ -626,6 +695,37 @@ static DecodeStatus DecodeDaddiGroupBranch(MCInst &MI, InsnType insn,  }  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) { @@ -642,7 +742,7 @@ static DecodeStatus DecodeBlezlGroupBranch(MCInst &MI, InsnType insn,    InsnType Rs = fieldFromInstruction(insn, 21, 5);    InsnType Rt = fieldFromInstruction(insn, 16, 5); -  InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4; +  int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;    bool HasRs = false;    if (Rt == 0) @@ -687,7 +787,7 @@ static DecodeStatus DecodeBgtzlGroupBranch(MCInst &MI, InsnType insn,    InsnType Rs = fieldFromInstruction(insn, 21, 5);    InsnType Rt = fieldFromInstruction(insn, 16, 5); -  InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4; +  int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;    if (Rt == 0)      return MCDisassembler::Fail; @@ -729,7 +829,7 @@ static DecodeStatus DecodeBgtzGroupBranch(MCInst &MI, InsnType insn,    InsnType Rs = fieldFromInstruction(insn, 21, 5);    InsnType Rt = fieldFromInstruction(insn, 16, 5); -  InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4; +  int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;    bool HasRs = false;    bool HasRt = false; @@ -778,7 +878,7 @@ static DecodeStatus DecodeBlezGroupBranch(MCInst &MI, InsnType insn,    InsnType Rs = fieldFromInstruction(insn, 21, 5);    InsnType Rt = fieldFromInstruction(insn, 16, 5); -  InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4; +  int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;    bool HasRs = false;    if (Rt == 0) @@ -917,6 +1017,17 @@ DecodeStatus MipsDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,        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; @@ -949,6 +1060,16 @@ DecodeStatus MipsDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,      }    } +  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, @@ -959,6 +1080,16 @@ DecodeStatus MipsDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,      }    } +  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, @@ -1534,7 +1665,8 @@ static DecodeStatus DecodeMemMMImm12(MCInst &Inst,      // fallthrough    default:      Inst.addOperand(MCOperand::createReg(Reg)); -    if (Inst.getOpcode() == Mips::LWP_MM || Inst.getOpcode() == Mips::SWP_MM) +    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)); @@ -1580,6 +1712,24 @@ static DecodeStatus DecodeFMem(MCInst &Inst,    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, @@ -1633,6 +1783,23 @@ static DecodeStatus DecodeFMemCop2R6(MCInst &Inst,    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, @@ -1808,6 +1975,15 @@ static DecodeStatus DecodeBranchTarget(MCInst &Inst,    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, @@ -1822,7 +1998,17 @@ static DecodeStatus DecodeBranchTarget21(MCInst &Inst,                                           unsigned Offset,                                           uint64_t Address,                                           const void *Decoder) { -  int32_t BranchOffset = SignExtend32<21>(Offset) * 4; +  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; @@ -1832,7 +2018,7 @@ static DecodeStatus DecodeBranchTarget26(MCInst &Inst,                                           unsigned Offset,                                           uint64_t Address,                                           const void *Decoder) { -  int32_t BranchOffset = SignExtend32<26>(Offset) * 4; +  int32_t BranchOffset = SignExtend32<26>(Offset) * 4 + 4;    Inst.addOperand(MCOperand::createImm(BranchOffset));    return MCDisassembler::Success; @@ -1897,15 +2083,7 @@ static DecodeStatus DecodeAddiur2Simm7(MCInst &Inst,    return MCDisassembler::Success;  } -static DecodeStatus DecodeUImm6Lsl2(MCInst &Inst, -                                    unsigned Value, -                                    uint64_t Address, -                                    const void *Decoder) { -  Inst.addOperand(MCOperand::createImm(Value << 2)); -  return MCDisassembler::Success; -} - -static DecodeStatus DecodeLiSimm7(MCInst &Inst, +static DecodeStatus DecodeLi16Imm(MCInst &Inst,                                    unsigned Value,                                    uint64_t Address,                                    const void *Decoder) { @@ -1924,28 +2102,22 @@ static DecodeStatus DecodePOOL16BEncodedField(MCInst &Inst,    return MCDisassembler::Success;  } -static DecodeStatus DecodeSimm4(MCInst &Inst, -                                unsigned Value, -                                uint64_t Address, -                                const void *Decoder) { -  Inst.addOperand(MCOperand::createImm(SignExtend32<4>(Value))); -  return MCDisassembler::Success; -} - -static DecodeStatus DecodeSimm16(MCInst &Inst, -                                 unsigned Insn, -                                 uint64_t Address, -                                 const void *Decoder) { -  Inst.addOperand(MCOperand::createImm(SignExtend32<16>(Insn))); +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> -static DecodeStatus DecodeUImmWithOffset(MCInst &Inst, unsigned Value, -                                         uint64_t Address, -                                         const void *Decoder) { -  Value &= ((1 << Bits) - 1); -  Inst.addOperand(MCOperand::createImm(Value + Offset)); +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;  } @@ -1996,12 +2168,6 @@ static DecodeStatus DecodeANDI16Imm(MCInst &Inst, unsigned Insn,    return MCDisassembler::Success;  } -static DecodeStatus DecodeUImm5lsl2(MCInst &Inst, unsigned Insn, -                                    uint64_t Address, const void *Decoder) { -  Inst.addOperand(MCOperand::createImm(Insn << 2)); -  return MCDisassembler::Success; -} -  static DecodeStatus DecodeRegListOperand(MCInst &Inst,                                           unsigned Insn,                                           uint64_t Address, @@ -2105,3 +2271,87 @@ static DecodeStatus DecodeSimm23Lsl2(MCInst &Inst, unsigned Insn,    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; +}  | 
