aboutsummaryrefslogtreecommitdiff
path: root/lib/Target/Mips/MipsInstrInfo.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Target/Mips/MipsInstrInfo.cpp')
-rw-r--r--lib/Target/Mips/MipsInstrInfo.cpp186
1 files changed, 177 insertions, 9 deletions
diff --git a/lib/Target/Mips/MipsInstrInfo.cpp b/lib/Target/Mips/MipsInstrInfo.cpp
index 51ddc0d44c00..0e0e712dba19 100644
--- a/lib/Target/Mips/MipsInstrInfo.cpp
+++ b/lib/Target/Mips/MipsInstrInfo.cpp
@@ -163,7 +163,7 @@ unsigned MipsInstrInfo::removeBranch(MachineBasicBlock &MBB,
// Note that indirect branches are not removed.
while (I != REnd && removed < 2) {
// Skip past debug instructions.
- if (I->isDebugValue()) {
+ if (I->isDebugInstr()) {
++I;
continue;
}
@@ -195,7 +195,7 @@ MipsInstrInfo::BranchType MipsInstrInfo::analyzeBranch(
MachineBasicBlock::reverse_iterator I = MBB.rbegin(), REnd = MBB.rend();
// Skip all the debug instructions.
- while (I != REnd && I->isDebugValue())
+ while (I != REnd && I->isDebugInstr())
++I;
if (I == REnd || !isUnpredicatedTerminator(*I)) {
@@ -220,7 +220,7 @@ MipsInstrInfo::BranchType MipsInstrInfo::analyzeBranch(
// Skip past any debug instruction to see if the second last actual
// is a branch.
++I;
- while (I != REnd && I->isDebugValue())
+ while (I != REnd && I->isDebugInstr())
++I;
if (I != REnd) {
@@ -276,6 +276,163 @@ MipsInstrInfo::BranchType MipsInstrInfo::analyzeBranch(
return BT_CondUncond;
}
+bool MipsInstrInfo::isBranchOffsetInRange(unsigned BranchOpc, int64_t BrOffset) const {
+ switch (BranchOpc) {
+ case Mips::B:
+ case Mips::BAL:
+ case Mips::BC1F:
+ case Mips::BC1FL:
+ case Mips::BC1T:
+ case Mips::BC1TL:
+ case Mips::BEQ: case Mips::BEQ64:
+ case Mips::BEQL:
+ case Mips::BGEZ: case Mips::BGEZ64:
+ case Mips::BGEZL:
+ case Mips::BGEZAL:
+ case Mips::BGEZALL:
+ case Mips::BGTZ: case Mips::BGTZ64:
+ case Mips::BGTZL:
+ case Mips::BLEZ: case Mips::BLEZ64:
+ case Mips::BLEZL:
+ case Mips::BLTZ: case Mips::BLTZ64:
+ case Mips::BLTZL:
+ case Mips::BLTZAL:
+ case Mips::BLTZALL:
+ case Mips::BNE: case Mips::BNE64:
+ case Mips::BNEL:
+ return isInt<18>(BrOffset);
+
+ // microMIPSr3 branches
+ case Mips::B_MM:
+ case Mips::BC1F_MM:
+ case Mips::BC1T_MM:
+ case Mips::BEQ_MM:
+ case Mips::BGEZ_MM:
+ case Mips::BGEZAL_MM:
+ case Mips::BGTZ_MM:
+ case Mips::BLEZ_MM:
+ case Mips::BLTZ_MM:
+ case Mips::BLTZAL_MM:
+ case Mips::BNE_MM:
+ case Mips::BEQZC_MM:
+ case Mips::BNEZC_MM:
+ return isInt<17>(BrOffset);
+
+ // microMIPSR3 short branches.
+ case Mips::B16_MM:
+ return isInt<11>(BrOffset);
+
+ case Mips::BEQZ16_MM:
+ case Mips::BNEZ16_MM:
+ return isInt<8>(BrOffset);
+
+ // MIPSR6 branches.
+ case Mips::BALC:
+ case Mips::BC:
+ return isInt<28>(BrOffset);
+
+ case Mips::BC1EQZ:
+ case Mips::BC1NEZ:
+ case Mips::BC2EQZ:
+ case Mips::BC2NEZ:
+ case Mips::BEQC: case Mips::BEQC64:
+ case Mips::BNEC: case Mips::BNEC64:
+ case Mips::BGEC: case Mips::BGEC64:
+ case Mips::BGEUC: case Mips::BGEUC64:
+ case Mips::BGEZC: case Mips::BGEZC64:
+ case Mips::BGTZC: case Mips::BGTZC64:
+ case Mips::BLEZC: case Mips::BLEZC64:
+ case Mips::BLTC: case Mips::BLTC64:
+ case Mips::BLTUC: case Mips::BLTUC64:
+ case Mips::BLTZC: case Mips::BLTZC64:
+ case Mips::BNVC:
+ case Mips::BOVC:
+ case Mips::BGEZALC:
+ case Mips::BEQZALC:
+ case Mips::BGTZALC:
+ case Mips::BLEZALC:
+ case Mips::BLTZALC:
+ case Mips::BNEZALC:
+ return isInt<18>(BrOffset);
+
+ case Mips::BEQZC: case Mips::BEQZC64:
+ case Mips::BNEZC: case Mips::BNEZC64:
+ return isInt<23>(BrOffset);
+
+ // microMIPSR6 branches
+ case Mips::BC16_MMR6:
+ return isInt<11>(BrOffset);
+
+ case Mips::BEQZC16_MMR6:
+ case Mips::BNEZC16_MMR6:
+ return isInt<8>(BrOffset);
+
+ case Mips::BALC_MMR6:
+ case Mips::BC_MMR6:
+ return isInt<27>(BrOffset);
+
+ case Mips::BC1EQZC_MMR6:
+ case Mips::BC1NEZC_MMR6:
+ case Mips::BC2EQZC_MMR6:
+ case Mips::BC2NEZC_MMR6:
+ case Mips::BGEZALC_MMR6:
+ case Mips::BEQZALC_MMR6:
+ case Mips::BGTZALC_MMR6:
+ case Mips::BLEZALC_MMR6:
+ case Mips::BLTZALC_MMR6:
+ case Mips::BNEZALC_MMR6:
+ case Mips::BNVC_MMR6:
+ case Mips::BOVC_MMR6:
+ return isInt<17>(BrOffset);
+
+ case Mips::BEQC_MMR6:
+ case Mips::BNEC_MMR6:
+ case Mips::BGEC_MMR6:
+ case Mips::BGEUC_MMR6:
+ case Mips::BGEZC_MMR6:
+ case Mips::BGTZC_MMR6:
+ case Mips::BLEZC_MMR6:
+ case Mips::BLTC_MMR6:
+ case Mips::BLTUC_MMR6:
+ case Mips::BLTZC_MMR6:
+ return isInt<18>(BrOffset);
+
+ case Mips::BEQZC_MMR6:
+ case Mips::BNEZC_MMR6:
+ return isInt<23>(BrOffset);
+
+ // DSP branches.
+ case Mips::BPOSGE32:
+ return isInt<18>(BrOffset);
+ case Mips::BPOSGE32_MM:
+ case Mips::BPOSGE32C_MMR3:
+ return isInt<17>(BrOffset);
+
+ // cnMIPS branches.
+ case Mips::BBIT0:
+ case Mips::BBIT032:
+ case Mips::BBIT1:
+ case Mips::BBIT132:
+ return isInt<18>(BrOffset);
+
+ // MSA branches.
+ case Mips::BZ_B:
+ case Mips::BZ_H:
+ case Mips::BZ_W:
+ case Mips::BZ_D:
+ case Mips::BZ_V:
+ case Mips::BNZ_B:
+ case Mips::BNZ_H:
+ case Mips::BNZ_W:
+ case Mips::BNZ_D:
+ case Mips::BNZ_V:
+ return isInt<18>(BrOffset);
+ }
+
+ llvm_unreachable("Unknown branch instruction!");
+}
+
+
/// Return the corresponding compact (no delay slot) form of a branch.
unsigned MipsInstrInfo::getEquivalentCompactForm(
const MachineBasicBlock::iterator I) const {
@@ -298,7 +455,6 @@ unsigned MipsInstrInfo::getEquivalentCompactForm(
case Mips::JR:
case Mips::PseudoReturn:
case Mips::PseudoIndirectBranch:
- case Mips::TAILCALLREG:
canUseShortMicroMipsCTI = true;
break;
}
@@ -377,18 +533,18 @@ unsigned MipsInstrInfo::getEquivalentCompactForm(
// For MIPSR6, the instruction 'jic' can be used for these cases. Some
// tools will accept 'jrc reg' as an alias for 'jic 0, $reg'.
case Mips::JR:
+ case Mips::PseudoIndirectBranchR6:
case Mips::PseudoReturn:
- case Mips::PseudoIndirectBranch:
- case Mips::TAILCALLREG:
+ case Mips::TAILCALLR6REG:
if (canUseShortMicroMipsCTI)
return Mips::JRC16_MM;
return Mips::JIC;
case Mips::JALRPseudo:
return Mips::JIALC;
case Mips::JR64:
+ case Mips::PseudoIndirectBranch64R6:
case Mips::PseudoReturn64:
- case Mips::PseudoIndirectBranch64:
- case Mips::TAILCALLREG64:
+ case Mips::TAILCALL64R6REG:
return Mips::JIC64;
case Mips::JALR64Pseudo:
return Mips::JIALC64;
@@ -599,7 +755,7 @@ bool MipsInstrInfo::verifyInstruction(const MachineInstr &MI,
case Mips::DINS:
return verifyInsExtInstruction(MI, ErrInfo, 0, 32, 0, 32, 0, 32);
case Mips::DINSM:
- // The ISA spec has a subtle difference difference between dinsm and dextm
+ // The ISA spec has a subtle difference between dinsm and dextm
// in that it says:
// 2 <= size <= 64 for 'dinsm' but 'dextm' has 32 < size <= 64.
// To make the bounds checks similar, the range 1 < size <= 64 is checked
@@ -617,6 +773,18 @@ bool MipsInstrInfo::verifyInstruction(const MachineInstr &MI,
return verifyInsExtInstruction(MI, ErrInfo, 0, 32, 32, 64, 32, 64);
case Mips::DEXTU:
return verifyInsExtInstruction(MI, ErrInfo, 32, 64, 0, 32, 32, 64);
+ case Mips::TAILCALLREG:
+ case Mips::PseudoIndirectBranch:
+ case Mips::JR:
+ case Mips::JR64:
+ case Mips::JALR:
+ case Mips::JALR64:
+ case Mips::JALRPseudo:
+ if (!Subtarget.useIndirectJumpsHazard())
+ return true;
+
+ ErrInfo = "invalid instruction when using jump guards!";
+ return false;
default:
return true;
}