summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp')
-rw-r--r--contrib/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp376
1 files changed, 313 insertions, 63 deletions
diff --git a/contrib/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp b/contrib/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp
index 3c1a771..aebb4ef 100644
--- a/contrib/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp
+++ b/contrib/llvm/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;
+}
OpenPOWER on IntegriCloud