aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp
diff options
context:
space:
mode:
authorHrvoje Varga <Hrvoje.Varga@imgtec.com>2016-08-22 12:17:59 +0000
committerHrvoje Varga <Hrvoje.Varga@imgtec.com>2016-08-22 12:17:59 +0000
commitf0ed16eae58479155639e601bbfbff961f2cc49a (patch)
tree90ad72b01a3a9055d126202e2dd1f41e2aaeb4de /llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp
parent80d379f228409f8d8481a265e04bcb5e082c0e74 (diff)
downloadllvm-f0ed16eae58479155639e601bbfbff961f2cc49a.zip
llvm-f0ed16eae58479155639e601bbfbff961f2cc49a.tar.gz
llvm-f0ed16eae58479155639e601bbfbff961f2cc49a.tar.bz2
[mips][microMIPS] Implement BLTZC, BLEZC, BGEZC and BGTZC instructions, fix disassembly and add operand checking to existing B<cond>C implementations
Differential Revision: https://reviews.llvm.org/D22667 llvm-svn: 279429
Diffstat (limited to 'llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp')
-rw-r--r--llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp120
1 files changed, 111 insertions, 9 deletions
diff --git a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp
index 2357f22..f53998e 100644
--- a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp
+++ b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp
@@ -460,6 +460,16 @@ DecodePOP37GroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address,
template <typename InsnType>
static DecodeStatus
+DecodePOP65GroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address,
+ const void *Decoder);
+
+template <typename InsnType>
+static DecodeStatus
+DecodePOP75GroupBranchMMR6(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);
@@ -630,7 +640,7 @@ static DecodeStatus DecodePOP35GroupBranchMMR6(MCInst &MI, InsnType insn,
const void *Decoder) {
InsnType Rt = fieldFromInstruction(insn, 21, 5);
InsnType Rs = fieldFromInstruction(insn, 16, 5);
- InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2;
+ int64_t Imm = 0;
if (Rs >= Rt) {
MI.setOpcode(Mips::BOVC_MMR6);
@@ -638,16 +648,19 @@ static DecodeStatus DecodePOP35GroupBranchMMR6(MCInst &MI, InsnType insn,
Rt)));
MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Rs)));
+ Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
} 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)));
+ Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
} else {
MI.setOpcode(Mips::BEQZALC_MMR6);
MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Rt)));
+ Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
}
MI.addOperand(MCOperand::createImm(Imm));
@@ -700,7 +713,7 @@ static DecodeStatus DecodePOP37GroupBranchMMR6(MCInst &MI, InsnType insn,
const void *Decoder) {
InsnType Rt = fieldFromInstruction(insn, 21, 5);
InsnType Rs = fieldFromInstruction(insn, 16, 5);
- InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2;
+ int64_t Imm = 0;
if (Rs >= Rt) {
MI.setOpcode(Mips::BNVC_MMR6);
@@ -708,18 +721,99 @@ static DecodeStatus DecodePOP37GroupBranchMMR6(MCInst &MI, InsnType insn,
Rt)));
MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Rs)));
+ Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
} 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)));
+ Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
} else {
MI.setOpcode(Mips::BNEZALC_MMR6);
MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Rt)));
+ Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
+ }
+
+ MI.addOperand(MCOperand::createImm(Imm));
+
+ return MCDisassembler::Success;
+}
+
+template <typename InsnType>
+static DecodeStatus DecodePOP65GroupBranchMMR6(MCInst &MI, InsnType insn,
+ uint64_t Address,
+ const void *Decoder) {
+ // We have:
+ // 0b110101 ttttt sssss iiiiiiiiiiiiiiii
+ // Invalid if rt == 0
+ // BGTZC_MMR6 if rs == 0 && rt != 0
+ // BLTZC_MMR6 if rs == rt && rt != 0
+ // BLTC_MMR6 if rs != rt && rs != 0 && rt != 0
+
+ InsnType Rt = fieldFromInstruction(insn, 21, 5);
+ InsnType Rs = fieldFromInstruction(insn, 16, 5);
+ int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
+ bool HasRs = false;
+
+ if (Rt == 0)
+ return MCDisassembler::Fail;
+ else if (Rs == 0)
+ MI.setOpcode(Mips::BGTZC_MMR6);
+ else if (Rs == Rt)
+ MI.setOpcode(Mips::BLTZC_MMR6);
+ else {
+ MI.setOpcode(Mips::BLTC_MMR6);
+ 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 DecodePOP75GroupBranchMMR6(MCInst &MI, InsnType insn,
+ uint64_t Address,
+ const void *Decoder) {
+ // We have:
+ // 0b111101 ttttt sssss iiiiiiiiiiiiiiii
+ // Invalid if rt == 0
+ // BLEZC_MMR6 if rs == 0 && rt != 0
+ // BGEZC_MMR6 if rs == rt && rt != 0
+ // BGEC_MMR6 if rs != rt && rs != 0 && rt != 0
+
+ InsnType Rt = fieldFromInstruction(insn, 21, 5);
+ InsnType Rs = fieldFromInstruction(insn, 16, 5);
+ int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
+ bool HasRs = false;
+
+ if (Rt == 0)
+ return MCDisassembler::Fail;
+ else if (Rs == 0)
+ MI.setOpcode(Mips::BLEZC_MMR6);
+ else if (Rs == Rt)
+ MI.setOpcode(Mips::BGEZC_MMR6);
+ else {
+ HasRs = true;
+ MI.setOpcode(Mips::BGEC_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;
@@ -2008,7 +2102,7 @@ static DecodeStatus DecodeBranchTarget21MM(MCInst &Inst,
unsigned Offset,
uint64_t Address,
const void *Decoder) {
- int32_t BranchOffset = SignExtend32<21>(Offset) << 1;
+ int32_t BranchOffset = SignExtend32<21>(Offset) * 4 + 4;
Inst.addOperand(MCOperand::createImm(BranchOffset));
return MCDisassembler::Success;
@@ -2046,7 +2140,7 @@ static DecodeStatus DecodeBranchTargetMM(MCInst &Inst,
unsigned Offset,
uint64_t Address,
const void *Decoder) {
- int32_t BranchOffset = SignExtend32<16>(Offset) * 2;
+ int32_t BranchOffset = SignExtend32<16>(Offset) * 2 + 4;
Inst.addOperand(MCOperand::createImm(BranchOffset));
return MCDisassembler::Success;
}
@@ -2285,7 +2379,7 @@ static DecodeStatus DecodeBgtzGroupBranchMMR6(MCInst &MI, InsnType insn,
InsnType Rt = fieldFromInstruction(insn, 21, 5);
InsnType Rs = fieldFromInstruction(insn, 16, 5);
- InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2;
+ InsnType Imm = 0;
bool HasRs = false;
bool HasRt = false;
@@ -2294,15 +2388,18 @@ static DecodeStatus DecodeBgtzGroupBranchMMR6(MCInst &MI, InsnType insn,
else if (Rs == 0) {
MI.setOpcode(Mips::BGTZALC_MMR6);
HasRt = true;
+ Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
}
else if (Rs == Rt) {
MI.setOpcode(Mips::BLTZALC_MMR6);
HasRs = true;
+ Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
}
else {
MI.setOpcode(Mips::BLTUC_MMR6);
HasRs = true;
HasRt = true;
+ Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
}
if (HasRs)
@@ -2324,25 +2421,30 @@ static DecodeStatus DecodeBlezGroupBranchMMR6(MCInst &MI, InsnType insn,
const void *Decoder) {
// We have:
// 0b000110 ttttt sssss iiiiiiiiiiiiiiii
- // Invalid if rs == 0
+ // Invalid if rt == 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;
+ InsnType Imm = 0;
bool HasRs = false;
if (Rt == 0)
return MCDisassembler::Fail;
- else if (Rs == 0)
+ else if (Rs == 0) {
MI.setOpcode(Mips::BLEZALC_MMR6);
- else if (Rs == Rt)
+ Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
+ }
+ else if (Rs == Rt) {
MI.setOpcode(Mips::BGEZALC_MMR6);
+ Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
+ }
else {
HasRs = true;
MI.setOpcode(Mips::BGEUC_MMR6);
+ Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
}
if (HasRs)