summaryrefslogtreecommitdiffstats
path: root/llvm/lib
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
parent80d379f228409f8d8481a265e04bcb5e082c0e74 (diff)
downloadbcm5719-llvm-f0ed16eae58479155639e601bbfbff961f2cc49a.tar.gz
bcm5719-llvm-f0ed16eae58479155639e601bbfbff961f2cc49a.zip
[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')
-rw-r--r--llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp63
-rw-r--r--llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp120
-rw-r--r--llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp28
-rw-r--r--llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h7
-rw-r--r--llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td140
-rw-r--r--llvm/lib/Target/Mips/MicroMipsInstrInfo.td6
-rw-r--r--llvm/lib/Target/Mips/Mips32r6InstrInfo.td38
7 files changed, 306 insertions, 96 deletions
diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
index 0fd56ad8384..f6c0e0475a9 100644
--- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
+++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
@@ -1652,6 +1652,45 @@ bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1LL << (inMicroMipsMode() ? 1 : 2)))
return Error(IDLoc, "branch to misaligned address");
break;
+ case Mips::BGEC: case Mips::BGEC_MMR6:
+ case Mips::BLTC: case Mips::BLTC_MMR6:
+ case Mips::BGEUC: case Mips::BGEUC_MMR6:
+ case Mips::BLTUC: case Mips::BLTUC_MMR6:
+ case Mips::BEQC: case Mips::BEQC_MMR6:
+ case Mips::BNEC: case Mips::BNEC_MMR6:
+ assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
+ Offset = Inst.getOperand(2);
+ if (!Offset.isImm())
+ break; // We'll deal with this situation later on when applying fixups.
+ if (!isIntN(18, Offset.getImm()))
+ return Error(IDLoc, "branch target out of range");
+ if (OffsetToAlignment(Offset.getImm(), 1LL << 2))
+ return Error(IDLoc, "branch to misaligned address");
+ break;
+ case Mips::BLEZC: case Mips::BLEZC_MMR6:
+ case Mips::BGEZC: case Mips::BGEZC_MMR6:
+ case Mips::BGTZC: case Mips::BGTZC_MMR6:
+ case Mips::BLTZC: case Mips::BLTZC_MMR6:
+ assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
+ Offset = Inst.getOperand(1);
+ if (!Offset.isImm())
+ break; // We'll deal with this situation later on when applying fixups.
+ if (!isIntN(18, Offset.getImm()))
+ return Error(IDLoc, "branch target out of range");
+ if (OffsetToAlignment(Offset.getImm(), 1LL << 2))
+ return Error(IDLoc, "branch to misaligned address");
+ break;
+ case Mips::BEQZC: case Mips::BEQZC_MMR6:
+ case Mips::BNEZC: case Mips::BNEZC_MMR6:
+ assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
+ Offset = Inst.getOperand(1);
+ if (!Offset.isImm())
+ break; // We'll deal with this situation later on when applying fixups.
+ if (!isIntN(23, Offset.getImm()))
+ return Error(IDLoc, "branch target out of range");
+ if (OffsetToAlignment(Offset.getImm(), 1LL << 2))
+ return Error(IDLoc, "branch to misaligned address");
+ break;
case Mips::BEQZ16_MM:
case Mips::BEQZC16_MMR6:
case Mips::BNEZ16_MM:
@@ -3808,12 +3847,12 @@ unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
// The compact branches that branch iff the signed addition of two registers
// would overflow must have rs >= rt. That can be handled like beqc/bnec with
// operand swapping. They do not have restriction of using the zero register.
- case Mips::BLEZC:
- case Mips::BGEZC:
- case Mips::BGTZC:
- case Mips::BLTZC:
- case Mips::BEQZC:
- case Mips::BNEZC:
+ case Mips::BLEZC: case Mips::BLEZC_MMR6:
+ case Mips::BGEZC: case Mips::BGEZC_MMR6:
+ case Mips::BGTZC: case Mips::BGTZC_MMR6:
+ case Mips::BLTZC: case Mips::BLTZC_MMR6:
+ case Mips::BEQZC: case Mips::BEQZC_MMR6:
+ case Mips::BNEZC: case Mips::BNEZC_MMR6:
case Mips::BLEZC64:
case Mips::BGEZC64:
case Mips::BGTZC64:
@@ -3824,12 +3863,12 @@ unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
Inst.getOperand(0).getReg() == Mips::ZERO_64)
return Match_RequiresNoZeroRegister;
return Match_Success;
- case Mips::BGEC:
- case Mips::BLTC:
- case Mips::BGEUC:
- case Mips::BLTUC:
- case Mips::BEQC:
- case Mips::BNEC:
+ case Mips::BGEC: case Mips::BGEC_MMR6:
+ case Mips::BLTC: case Mips::BLTC_MMR6:
+ case Mips::BGEUC: case Mips::BGEUC_MMR6:
+ case Mips::BLTUC: case Mips::BLTUC_MMR6:
+ case Mips::BEQC: case Mips::BEQC_MMR6:
+ case Mips::BNEC: case Mips::BNEC_MMR6:
case Mips::BGEC64:
case Mips::BLTC64:
case Mips::BGEUC64:
diff --git a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp
index 2357f226152..f53998ea8e7 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)
diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp
index 4cc55f86a99..0614316d5ac 100644
--- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp
+++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp
@@ -335,6 +335,30 @@ getBranchTargetOpValueMMR6(const MCInst &MI, unsigned OpNo,
return 0;
}
+/// getBranchTargetOpValueLsl2MMR6 - Return binary encoding of the branch
+/// target operand. If the machine operand requires relocation,
+/// record the relocation and return zero.
+unsigned MipsMCCodeEmitter::
+getBranchTargetOpValueLsl2MMR6(const MCInst &MI, unsigned OpNo,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const {
+
+ const MCOperand &MO = MI.getOperand(OpNo);
+
+ // If the destination is an immediate, divide by 4.
+ if (MO.isImm())
+ return MO.getImm() >> 2;
+
+ assert(MO.isExpr() &&
+ "getBranchTargetOpValueLsl2MMR6 expects only expressions or immediates");
+
+ const MCExpr *FixupExpression = MCBinaryExpr::createAdd(
+ MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx);
+ Fixups.push_back(MCFixup::create(0, FixupExpression,
+ MCFixupKind(Mips::fixup_Mips_PC16)));
+ return 0;
+}
+
/// getBranchTarget7OpValueMM - Return binary encoding of the microMIPS branch
/// target operand. If the machine operand requires relocation,
/// record the relocation and return zero.
@@ -435,8 +459,8 @@ getBranchTarget21OpValueMM(const MCInst &MI, unsigned OpNo,
const MCOperand &MO = MI.getOperand(OpNo);
- // If the destination is an immediate, divide by 2.
- if (MO.isImm()) return MO.getImm() >> 1;
+ // If the destination is an immediate, divide by 4.
+ if (MO.isImm()) return MO.getImm() >> 2;
assert(MO.isExpr() &&
"getBranchTarget21OpValueMM expects only expressions or immediates");
diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h
index 0f4dfe1200c..2d041dcbf04 100644
--- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h
+++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h
@@ -116,6 +116,13 @@ public:
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
+ // getBranchTargetOpValueLsl2MMR6 - Return binary encoding of the branch
+ // target operand. If the machine operand requires relocation,
+ // record the relocation and return zero.
+ unsigned getBranchTargetOpValueLsl2MMR6(const MCInst &MI, unsigned OpNo,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const;
+
// getBranchTarget7OpValue - Return binary encoding of the microMIPS branch
// target operand. If the machine operand requires relocation,
// record the relocation and return zero.
diff --git a/llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td b/llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td
index 631789773b2..3d74db4d5e2 100644
--- a/llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td
+++ b/llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td
@@ -32,6 +32,15 @@ def brtargetr6 : Operand<OtherVT> {
let ParserMatchClass = MipsJumpTargetAsmOperand;
}
+def brtarget_lsl2_mm : Operand<OtherVT> {
+ let EncoderMethod = "getBranchTargetOpValueLsl2MMR6";
+ let OperandType = "OPERAND_PCREL";
+ // Instructions that use this operand have their decoder method
+ // set with DecodeDisambiguates
+ let DecoderMethod = "";
+ let ParserMatchClass = MipsJumpTargetAsmOperand;
+}
+
//===----------------------------------------------------------------------===//
//
// Instruction Encodings
@@ -56,16 +65,28 @@ class BITSWAP_MMR6_ENC : POOL32A_BITSWAP_FM_MMR6<0b101100>;
class BRK_MMR6_ENC : BREAK_MMR6_ENC<"break">;
class BEQZC_MMR6_ENC : CMP_BRANCH_OFF21_FM_MMR6<"beqzc", 0b100000>;
class BNEZC_MMR6_ENC : CMP_BRANCH_OFF21_FM_MMR6<"bnezc", 0b101000>;
-class BGEC_MMR6_ENC : CMP_BRANCH_2R_OFF16_FM_MMR6<"bgec", 0b111001>;
+class BGEC_MMR6_ENC : CMP_BRANCH_2R_OFF16_FM_MMR6<"bgec", 0b111101>,
+ DecodeDisambiguates<"POP75GroupBranchMMR6">;
class BGEUC_MMR6_ENC : CMP_BRANCH_2R_OFF16_FM_MMR6<"bgeuc", 0b110000>,
DecodeDisambiguates<"BlezGroupBranchMMR6">;
-class BLTC_MMR6_ENC : CMP_BRANCH_2R_OFF16_FM_MMR6<"bltc", 0b110001>;
+class BLTC_MMR6_ENC : CMP_BRANCH_2R_OFF16_FM_MMR6<"bltc", 0b110101>,
+ DecodeDisambiguates<"POP65GroupBranchMMR6">;
class BLTUC_MMR6_ENC : CMP_BRANCH_2R_OFF16_FM_MMR6<"bltuc", 0b111000>,
DecodeDisambiguates<"BgtzGroupBranchMMR6">;
class BEQC_MMR6_ENC : CMP_BRANCH_2R_OFF16_FM_MMR6<"beqc", 0b011101>;
class BNEC_MMR6_ENC : CMP_BRANCH_2R_OFF16_FM_MMR6<"bnec", 0b011111>;
-class BEQZALC_MMR6_ENC : CMP_BRANCH_1R_RT_OFF16_FM_MMR6<"beqzalc", 0b011101>;
-class BNEZALC_MMR6_ENC : CMP_BRANCH_1R_RT_OFF16_FM_MMR6<"bnezalc", 0b011111>;
+class BLTZC_MMR6_ENC : CMP_BRANCH_1R_BOTH_OFF16_FM_MMR6<"bltzc", 0b110101>,
+ DecodeDisambiguates<"POP65GroupBranchMMR6">;
+class BLEZC_MMR6_ENC : CMP_BRANCH_1R_RT_OFF16_FM_MMR6<"blezc", 0b111101>,
+ DecodeDisambiguates<"POP75GroupBranchMMR6">;
+class BGEZC_MMR6_ENC : CMP_BRANCH_1R_BOTH_OFF16_FM_MMR6<"bgezc", 0b111101>,
+ DecodeDisambiguates<"POP75GroupBranchMMR6">;
+class BGTZC_MMR6_ENC : CMP_BRANCH_1R_RT_OFF16_FM_MMR6<"bgtzc", 0b110101>,
+ DecodeDisambiguates<"POP65GroupBranchMMR6">;
+class BEQZALC_MMR6_ENC : CMP_BRANCH_1R_RT_OFF16_FM_MMR6<"beqzalc", 0b011101>,
+ DecodeDisambiguates<"POP35GroupBranchMMR6">;
+class BNEZALC_MMR6_ENC : CMP_BRANCH_1R_RT_OFF16_FM_MMR6<"bnezalc", 0b011111>,
+ DecodeDisambiguates<"POP37GroupBranchMMR6">;
class BGTZALC_MMR6_ENC : CMP_BRANCH_1R_RT_OFF16_FM_MMR6<"bgtzalc", 0b111000>,
MMDecodeDisambiguatedBy<"BgtzGroupBranchMMR6">;
class BLTZALC_MMR6_ENC : CMP_BRANCH_1R_BOTH_OFF16_FM_MMR6<"bltzalc", 0b111000>,
@@ -230,6 +251,49 @@ class SDC2_MMR6_ENC : POOL32B_LDWC2_SDWC2_FM_MMR6<"sdc2", 0b1010>;
class LWC2_MMR6_ENC : POOL32B_LDWC2_SDWC2_FM_MMR6<"lwc2", 0b0000>;
class SWC2_MMR6_ENC : POOL32B_LDWC2_SDWC2_FM_MMR6<"swc2", 0b1000>;
+/// Floating Point Instructions
+class FADD_S_MMR6_ENC : POOL32F_ARITH_FM_MMR6<"add.s", 0, 0b00110000>;
+class FADD_D_MMR6_ENC : POOL32F_ARITH_FM_MMR6<"add.d", 1, 0b00110000>;
+class FSUB_S_MMR6_ENC : POOL32F_ARITH_FM_MMR6<"sub.s", 0, 0b01110000>;
+class FSUB_D_MMR6_ENC : POOL32F_ARITH_FM_MMR6<"sub.d", 1, 0b01110000>;
+class FMUL_S_MMR6_ENC : POOL32F_ARITH_FM_MMR6<"mul.s", 0, 0b10110000>;
+class FMUL_D_MMR6_ENC : POOL32F_ARITH_FM_MMR6<"mul.d", 1, 0b10110000>;
+class FDIV_S_MMR6_ENC : POOL32F_ARITH_FM_MMR6<"div.s", 0, 0b11110000>;
+class FDIV_D_MMR6_ENC : POOL32F_ARITH_FM_MMR6<"div.d", 1, 0b11110000>;
+class MADDF_S_MMR6_ENC : POOL32F_ARITHF_FM_MMR6<"maddf.s", 0, 0b110111000>;
+class MADDF_D_MMR6_ENC : POOL32F_ARITHF_FM_MMR6<"maddf.d", 1, 0b110111000>;
+class MSUBF_S_MMR6_ENC : POOL32F_ARITHF_FM_MMR6<"msubf.s", 0, 0b111111000>;
+class MSUBF_D_MMR6_ENC : POOL32F_ARITHF_FM_MMR6<"msubf.d", 1, 0b111111000>;
+class FMOV_S_MMR6_ENC : POOL32F_MOV_NEG_FM_MMR6<"mov.s", 0, 0b0000001>;
+class FMOV_D_MMR6_ENC : POOL32F_MOV_NEG_FM_MMR6<"mov.d", 1, 0b0000001>;
+class FNEG_S_MMR6_ENC : POOL32F_MOV_NEG_FM_MMR6<"neg.s", 0, 0b0101101>;
+class FNEG_D_MMR6_ENC : POOL32F_MOV_NEG_FM_MMR6<"neg.d", 1, 0b0101101>;
+class MAX_S_MMR6_ENC : POOL32F_MINMAX_FM<"max.s", 0, 0b000001011>;
+class MAX_D_MMR6_ENC : POOL32F_MINMAX_FM<"max.d", 1, 0b000001011>;
+class MAXA_S_MMR6_ENC : POOL32F_MINMAX_FM<"maxa.s", 0, 0b000101011>;
+class MAXA_D_MMR6_ENC : POOL32F_MINMAX_FM<"maxa.d", 1, 0b000101011>;
+class MIN_S_MMR6_ENC : POOL32F_MINMAX_FM<"min.s", 0, 0b000000011>;
+class MIN_D_MMR6_ENC : POOL32F_MINMAX_FM<"min.d", 1, 0b000000011>;
+class MINA_S_MMR6_ENC : POOL32F_MINMAX_FM<"mina.s", 0, 0b000100011>;
+class MINA_D_MMR6_ENC : POOL32F_MINMAX_FM<"mina.d", 1, 0b000100011>;
+
+class CVT_L_S_MMR6_ENC : POOL32F_CVT_LW_FM<"cvt.l.s", 0, 0b00000100>;
+class CVT_L_D_MMR6_ENC : POOL32F_CVT_LW_FM<"cvt.l.d", 1, 0b00000100>;
+class CVT_W_S_MMR6_ENC : POOL32F_CVT_LW_FM<"cvt.w.s", 0, 0b00100100>;
+class CVT_W_D_MMR6_ENC : POOL32F_CVT_LW_FM<"cvt.w.d", 1, 0b00100100>;
+class CVT_D_S_MMR6_ENC : POOL32F_CVT_DS_FM<"cvt.d.s", 0, 0b1001101>;
+class CVT_D_W_MMR6_ENC : POOL32F_CVT_DS_FM<"cvt.d.w", 1, 0b1001101>;
+class CVT_D_L_MMR6_ENC : POOL32F_CVT_DS_FM<"cvt.d.l", 2, 0b1001101>;
+class CVT_S_D_MMR6_ENC : POOL32F_CVT_DS_FM<"cvt.s.d", 0, 0b1101101>;
+class CVT_S_W_MMR6_ENC : POOL32F_CVT_DS_FM<"cvt.s.w", 1, 0b1101101>;
+class CVT_S_L_MMR6_ENC : POOL32F_CVT_DS_FM<"cvt.s.l", 2, 0b1101101>;
+
+//===----------------------------------------------------------------------===//
+//
+// Instruction Descriptions
+//
+//===----------------------------------------------------------------------===//
+
class CMP_CBR_RT_Z_MMR6_DESC_BASE<string instr_asm, DAGOperand opnd,
RegisterOperand GPROpnd>
: BRANCH_DESC_BASE {
@@ -269,6 +333,15 @@ class BNEZALC_MMR6_DESC : CMP_CBR_RT_Z_MMR6_DESC_BASE<"bnezalc", brtarget_mm,
list<Register> Defs = [RA];
}
+class BLTZC_MMR6_DESC : CMP_CBR_RT_Z_MMR6_DESC_BASE<"bltzc", brtarget_lsl2_mm,
+ GPR32Opnd>;
+class BLEZC_MMR6_DESC : CMP_CBR_RT_Z_MMR6_DESC_BASE<"blezc", brtarget_lsl2_mm,
+ GPR32Opnd>;
+class BGEZC_MMR6_DESC : CMP_CBR_RT_Z_MMR6_DESC_BASE<"bgezc", brtarget_lsl2_mm,
+ GPR32Opnd>;
+class BGTZC_MMR6_DESC : CMP_CBR_RT_Z_MMR6_DESC_BASE<"bgtzc", brtarget_lsl2_mm,
+ GPR32Opnd>;
+
class CMP_CBR_2R_MMR6_DESC_BASE<string instr_asm, DAGOperand opnd,
RegisterOperand GPROpnd> : BRANCH_DESC_BASE {
dag InOperandList = (ins GPROpnd:$rs, GPROpnd:$rt, opnd:$offset);
@@ -277,62 +350,19 @@ class CMP_CBR_2R_MMR6_DESC_BASE<string instr_asm, DAGOperand opnd,
list<Register> Defs = [AT];
}
-class BGEC_MMR6_DESC : CMP_CBR_2R_MMR6_DESC_BASE<"bgec", brtarget_mm,
+class BGEC_MMR6_DESC : CMP_CBR_2R_MMR6_DESC_BASE<"bgec", brtarget_lsl2_mm,
GPR32Opnd>;
-class BGEUC_MMR6_DESC : CMP_CBR_2R_MMR6_DESC_BASE<"bgeuc", brtarget_mm,
+class BGEUC_MMR6_DESC : CMP_CBR_2R_MMR6_DESC_BASE<"bgeuc", brtarget_lsl2_mm,
GPR32Opnd>;
-class BLTC_MMR6_DESC : CMP_CBR_2R_MMR6_DESC_BASE<"bltc", brtarget_mm,
+class BLTC_MMR6_DESC : CMP_CBR_2R_MMR6_DESC_BASE<"bltc", brtarget_lsl2_mm,
GPR32Opnd>;
-class BLTUC_MMR6_DESC : CMP_CBR_2R_MMR6_DESC_BASE<"bltuc", brtarget_mm,
+class BLTUC_MMR6_DESC : CMP_CBR_2R_MMR6_DESC_BASE<"bltuc", brtarget_lsl2_mm,
GPR32Opnd>;
-class BEQC_MMR6_DESC : CMP_CBR_2R_MMR6_DESC_BASE<"beqc", brtarget_mm,
+class BEQC_MMR6_DESC : CMP_CBR_2R_MMR6_DESC_BASE<"beqc", brtarget_lsl2_mm,
GPR32Opnd>;
-class BNEC_MMR6_DESC : CMP_CBR_2R_MMR6_DESC_BASE<"bnec", brtarget_mm,
+class BNEC_MMR6_DESC : CMP_CBR_2R_MMR6_DESC_BASE<"bnec", brtarget_lsl2_mm,
GPR32Opnd>;
-/// Floating Point Instructions
-class FADD_S_MMR6_ENC : POOL32F_ARITH_FM_MMR6<"add.s", 0, 0b00110000>;
-class FADD_D_MMR6_ENC : POOL32F_ARITH_FM_MMR6<"add.d", 1, 0b00110000>;
-class FSUB_S_MMR6_ENC : POOL32F_ARITH_FM_MMR6<"sub.s", 0, 0b01110000>;
-class FSUB_D_MMR6_ENC : POOL32F_ARITH_FM_MMR6<"sub.d", 1, 0b01110000>;
-class FMUL_S_MMR6_ENC : POOL32F_ARITH_FM_MMR6<"mul.s", 0, 0b10110000>;
-class FMUL_D_MMR6_ENC : POOL32F_ARITH_FM_MMR6<"mul.d", 1, 0b10110000>;
-class FDIV_S_MMR6_ENC : POOL32F_ARITH_FM_MMR6<"div.s", 0, 0b11110000>;
-class FDIV_D_MMR6_ENC : POOL32F_ARITH_FM_MMR6<"div.d", 1, 0b11110000>;
-class MADDF_S_MMR6_ENC : POOL32F_ARITHF_FM_MMR6<"maddf.s", 0, 0b110111000>;
-class MADDF_D_MMR6_ENC : POOL32F_ARITHF_FM_MMR6<"maddf.d", 1, 0b110111000>;
-class MSUBF_S_MMR6_ENC : POOL32F_ARITHF_FM_MMR6<"msubf.s", 0, 0b111111000>;
-class MSUBF_D_MMR6_ENC : POOL32F_ARITHF_FM_MMR6<"msubf.d", 1, 0b111111000>;
-class FMOV_S_MMR6_ENC : POOL32F_MOV_NEG_FM_MMR6<"mov.s", 0, 0b0000001>;
-class FMOV_D_MMR6_ENC : POOL32F_MOV_NEG_FM_MMR6<"mov.d", 1, 0b0000001>;
-class FNEG_S_MMR6_ENC : POOL32F_MOV_NEG_FM_MMR6<"neg.s", 0, 0b0101101>;
-class FNEG_D_MMR6_ENC : POOL32F_MOV_NEG_FM_MMR6<"neg.d", 1, 0b0101101>;
-class MAX_S_MMR6_ENC : POOL32F_MINMAX_FM<"max.s", 0, 0b000001011>;
-class MAX_D_MMR6_ENC : POOL32F_MINMAX_FM<"max.d", 1, 0b000001011>;
-class MAXA_S_MMR6_ENC : POOL32F_MINMAX_FM<"maxa.s", 0, 0b000101011>;
-class MAXA_D_MMR6_ENC : POOL32F_MINMAX_FM<"maxa.d", 1, 0b000101011>;
-class MIN_S_MMR6_ENC : POOL32F_MINMAX_FM<"min.s", 0, 0b000000011>;
-class MIN_D_MMR6_ENC : POOL32F_MINMAX_FM<"min.d", 1, 0b000000011>;
-class MINA_S_MMR6_ENC : POOL32F_MINMAX_FM<"mina.s", 0, 0b000100011>;
-class MINA_D_MMR6_ENC : POOL32F_MINMAX_FM<"mina.d", 1, 0b000100011>;
-
-class CVT_L_S_MMR6_ENC : POOL32F_CVT_LW_FM<"cvt.l.s", 0, 0b00000100>;
-class CVT_L_D_MMR6_ENC : POOL32F_CVT_LW_FM<"cvt.l.d", 1, 0b00000100>;
-class CVT_W_S_MMR6_ENC : POOL32F_CVT_LW_FM<"cvt.w.s", 0, 0b00100100>;
-class CVT_W_D_MMR6_ENC : POOL32F_CVT_LW_FM<"cvt.w.d", 1, 0b00100100>;
-class CVT_D_S_MMR6_ENC : POOL32F_CVT_DS_FM<"cvt.d.s", 0, 0b1001101>;
-class CVT_D_W_MMR6_ENC : POOL32F_CVT_DS_FM<"cvt.d.w", 1, 0b1001101>;
-class CVT_D_L_MMR6_ENC : POOL32F_CVT_DS_FM<"cvt.d.l", 2, 0b1001101>;
-class CVT_S_D_MMR6_ENC : POOL32F_CVT_DS_FM<"cvt.s.d", 0, 0b1101101>;
-class CVT_S_W_MMR6_ENC : POOL32F_CVT_DS_FM<"cvt.s.w", 1, 0b1101101>;
-class CVT_S_L_MMR6_ENC : POOL32F_CVT_DS_FM<"cvt.s.l", 2, 0b1101101>;
-
-//===----------------------------------------------------------------------===//
-//
-// Instruction Descriptions
-//
-//===----------------------------------------------------------------------===//
-
class ADD_MMR6_DESC : ArithLogicR<"add", GPR32Opnd>;
class ADDIU_MMR6_DESC : ArithLogicI<"addiu", simm16, GPR32Opnd, II_ADDIU, immSExt16, add>;
class ADDU_MMR6_DESC : ArithLogicR<"addu", GPR32Opnd>;
@@ -1661,6 +1691,10 @@ def BEQC_MMR6 : R6MMR6Rel, BEQC_MMR6_ENC, BEQC_MMR6_DESC, ISA_MICROMIPS32R6,
DecodeDisambiguates<"POP35GroupBranchMMR6">;
def BNEC_MMR6 : R6MMR6Rel, BNEC_MMR6_ENC, BNEC_MMR6_DESC, ISA_MICROMIPS32R6,
DecodeDisambiguates<"POP37GroupBranchMMR6">;
+def BLTZC_MMR6 : R6MMR6Rel, BLTZC_MMR6_ENC, BLTZC_MMR6_DESC, ISA_MICROMIPS32R6;
+def BLEZC_MMR6 : R6MMR6Rel, BLEZC_MMR6_ENC, BLEZC_MMR6_DESC, ISA_MICROMIPS32R6;
+def BGEZC_MMR6 : R6MMR6Rel, BGEZC_MMR6_ENC, BGEZC_MMR6_DESC, ISA_MICROMIPS32R6;
+def BGTZC_MMR6 : R6MMR6Rel, BGTZC_MMR6_ENC, BGTZC_MMR6_DESC, ISA_MICROMIPS32R6;
def BGEZALC_MMR6 : R6MMR6Rel, BGEZALC_MMR6_ENC, BGEZALC_MMR6_DESC,
ISA_MICROMIPS32R6;
def BGTZALC_MMR6 : R6MMR6Rel, BGTZALC_MMR6_ENC, BGTZALC_MMR6_DESC,
diff --git a/llvm/lib/Target/Mips/MicroMipsInstrInfo.td b/llvm/lib/Target/Mips/MicroMipsInstrInfo.td
index d7d2e5dcd29..517661ef768 100644
--- a/llvm/lib/Target/Mips/MicroMipsInstrInfo.td
+++ b/llvm/lib/Target/Mips/MicroMipsInstrInfo.td
@@ -675,13 +675,15 @@ class WaitMM<string opstr> :
InstSE<(outs), (ins uimm10:$code_), !strconcat(opstr, "\t$code_"), [],
NoItinerary, FrmOther, opstr>;
-let DecoderNamespace = "MicroMips", Predicates = [InMicroMips] in {
+let DecoderNamespace = "MicroMips", Predicates = [InMicroMips, NotMips32r6,
+ NotMips64r6] in {
/// Compact Branch Instructions
def BEQZC_MM : CompactBranchMM<"beqzc", brtarget_mm, seteq, GPR32Opnd>,
COMPACT_BRANCH_FM_MM<0x7>;
def BNEZC_MM : CompactBranchMM<"bnezc", brtarget_mm, setne, GPR32Opnd>,
COMPACT_BRANCH_FM_MM<0x5>;
-
+}
+let DecoderNamespace = "MicroMips", Predicates = [InMicroMips] in {
/// Arithmetic Instructions (ALU Immediate)
def ADDiu_MM : MMRel, ArithLogicI<"addiu", simm16, GPR32Opnd>,
ADDI_FM_MM<0xc>;
diff --git a/llvm/lib/Target/Mips/Mips32r6InstrInfo.td b/llvm/lib/Target/Mips/Mips32r6InstrInfo.td
index f552f8d37af..1a5c2b6f8e8 100644
--- a/llvm/lib/Target/Mips/Mips32r6InstrInfo.td
+++ b/llvm/lib/Target/Mips/Mips32r6InstrInfo.td
@@ -754,26 +754,28 @@ let AdditionalPredicates = [NotInMicroMips] in {
def BC2NEZ : BC2NEZ_ENC, BC2NEZ_DESC, ISA_MIPS32R6;
}
def BC : R6MMR6Rel, BC_ENC, BC_DESC, ISA_MIPS32R6;
-def BEQC : R6MMR6Rel, BEQC_ENC, BEQC_DESC, ISA_MIPS32R6;
-def BEQZALC : R6MMR6Rel, BEQZALC_ENC, BEQZALC_DESC, ISA_MIPS32R6;
-def BEQZC : R6MMR6Rel, BEQZC_ENC, BEQZC_DESC, ISA_MIPS32R6;
-def BGEC : R6MMR6Rel, BGEC_ENC, BGEC_DESC, ISA_MIPS32R6;
-def BGEUC : R6MMR6Rel, BGEUC_ENC, BGEUC_DESC, ISA_MIPS32R6;
-def BGEZALC : R6MMR6Rel, BGEZALC_ENC, BGEZALC_DESC, ISA_MIPS32R6;
-def BGEZC : BGEZC_ENC, BGEZC_DESC, ISA_MIPS32R6;
-def BGTZALC : R6MMR6Rel, BGTZALC_ENC, BGTZALC_DESC, ISA_MIPS32R6;
-def BGTZC : BGTZC_ENC, BGTZC_DESC, ISA_MIPS32R6;
+let AdditionalPredicates = [NotInMicroMips] in {
+ def BEQC : R6MMR6Rel, BEQC_ENC, BEQC_DESC, ISA_MIPS32R6;
+ def BEQZALC : R6MMR6Rel, BEQZALC_ENC, BEQZALC_DESC, ISA_MIPS32R6;
+ def BEQZC : R6MMR6Rel, BEQZC_ENC, BEQZC_DESC, ISA_MIPS32R6;
+ def BGEC : R6MMR6Rel, BGEC_ENC, BGEC_DESC, ISA_MIPS32R6;
+ def BGEUC : R6MMR6Rel, BGEUC_ENC, BGEUC_DESC, ISA_MIPS32R6;
+ def BGEZALC : R6MMR6Rel, BGEZALC_ENC, BGEZALC_DESC, ISA_MIPS32R6;
+ def BGEZC : R6MMR6Rel, BGEZC_ENC, BGEZC_DESC, ISA_MIPS32R6;
+ def BGTZALC : R6MMR6Rel, BGTZALC_ENC, BGTZALC_DESC, ISA_MIPS32R6;
+ def BGTZC : R6MMR6Rel, BGTZC_ENC, BGTZC_DESC, ISA_MIPS32R6;
+}
def BITSWAP : R6MMR6Rel, BITSWAP_ENC, BITSWAP_DESC, ISA_MIPS32R6;
-def BLEZALC : R6MMR6Rel, BLEZALC_ENC, BLEZALC_DESC, ISA_MIPS32R6;
-def BLEZC : BLEZC_ENC, BLEZC_DESC, ISA_MIPS32R6;
-def BLTC : R6MMR6Rel, BLTC_ENC, BLTC_DESC, ISA_MIPS32R6;
-def BLTUC : R6MMR6Rel, BLTUC_ENC, BLTUC_DESC, ISA_MIPS32R6;
-def BLTZALC : R6MMR6Rel, BLTZALC_ENC, BLTZALC_DESC, ISA_MIPS32R6;
-def BLTZC : BLTZC_ENC, BLTZC_DESC, ISA_MIPS32R6;
-def BNEC : R6MMR6Rel, BNEC_ENC, BNEC_DESC, ISA_MIPS32R6;
-def BNEZALC : R6MMR6Rel, BNEZALC_ENC, BNEZALC_DESC, ISA_MIPS32R6;
-def BNEZC : R6MMR6Rel, BNEZC_ENC, BNEZC_DESC, ISA_MIPS32R6;
let AdditionalPredicates = [NotInMicroMips] in {
+ def BLEZALC : R6MMR6Rel, BLEZALC_ENC, BLEZALC_DESC, ISA_MIPS32R6;
+ def BLEZC : R6MMR6Rel, BLEZC_ENC, BLEZC_DESC, ISA_MIPS32R6;
+ def BLTC : R6MMR6Rel, BLTC_ENC, BLTC_DESC, ISA_MIPS32R6;
+ def BLTUC : R6MMR6Rel, BLTUC_ENC, BLTUC_DESC, ISA_MIPS32R6;
+ def BLTZALC : R6MMR6Rel, BLTZALC_ENC, BLTZALC_DESC, ISA_MIPS32R6;
+ def BLTZC : R6MMR6Rel, BLTZC_ENC, BLTZC_DESC, ISA_MIPS32R6;
+ def BNEC : R6MMR6Rel, BNEC_ENC, BNEC_DESC, ISA_MIPS32R6;
+ def BNEZALC : R6MMR6Rel, BNEZALC_ENC, BNEZALC_DESC, ISA_MIPS32R6;
+ def BNEZC : R6MMR6Rel, BNEZC_ENC, BNEZC_DESC, ISA_MIPS32R6;
def BNVC : R6MMR6Rel, BNVC_ENC, BNVC_DESC, ISA_MIPS32R6;
def BOVC : R6MMR6Rel, BOVC_ENC, BOVC_DESC, ISA_MIPS32R6;
}
OpenPOWER on IntegriCloud