summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorSimon Dardis <simon.dardis@mips.com>2018-05-16 10:03:05 +0000
committerSimon Dardis <simon.dardis@mips.com>2018-05-16 10:03:05 +0000
commit5cf9de4b727b9311d5883fa682b1bd00b50647a8 (patch)
treed25a402aefed160fef4ccbcd0e8d66f76e5a181c /llvm/lib
parentcaa163ef6a753e4306a057f8f508f5aea299dba8 (diff)
downloadbcm5719-llvm-5cf9de4b727b9311d5883fa682b1bd00b50647a8.tar.gz
bcm5719-llvm-5cf9de4b727b9311d5883fa682b1bd00b50647a8.zip
[mips] Add support for isBranchOffsetInRange and use it for MipsLongBranch
Add support for this target hook, covering MIPS, microMIPS and MIPSR6, along with some tests. Also add missing getOppositeBranchOpc() cases exposed by the tests. Reviewers: atanasyan, abeserminji, smaksimovic Differential Revision: https://reviews.llvm.org/D46794 llvm-svn: 332446
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Target/Mips/MipsInstrInfo.cpp157
-rw-r--r--llvm/lib/Target/Mips/MipsInstrInfo.h4
-rw-r--r--llvm/lib/Target/Mips/MipsLongBranch.cpp8
-rw-r--r--llvm/lib/Target/Mips/MipsSEInstrInfo.cpp50
4 files changed, 205 insertions, 14 deletions
diff --git a/llvm/lib/Target/Mips/MipsInstrInfo.cpp b/llvm/lib/Target/Mips/MipsInstrInfo.cpp
index 9254ae6a13b..0e0e712dba1 100644
--- a/llvm/lib/Target/Mips/MipsInstrInfo.cpp
+++ b/llvm/lib/Target/Mips/MipsInstrInfo.cpp
@@ -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 {
diff --git a/llvm/lib/Target/Mips/MipsInstrInfo.h b/llvm/lib/Target/Mips/MipsInstrInfo.h
index c18e395f901..9d27b8f6621 100644
--- a/llvm/lib/Target/Mips/MipsInstrInfo.h
+++ b/llvm/lib/Target/Mips/MipsInstrInfo.h
@@ -86,6 +86,10 @@ public:
/// Determine the opcode of a non-delay slot form for a branch if one exists.
unsigned getEquivalentCompactForm(const MachineBasicBlock::iterator I) const;
+ /// Determine if the branch target is in range.
+ bool isBranchOffsetInRange(unsigned BranchOpc,
+ int64_t BrOffset) const override;
+
/// Predicate to determine if an instruction can go in a forbidden slot.
bool SafeInForbiddenSlot(const MachineInstr &MI) const;
diff --git a/llvm/lib/Target/Mips/MipsLongBranch.cpp b/llvm/lib/Target/Mips/MipsLongBranch.cpp
index d31c6392b2a..ef3e044ea07 100644
--- a/llvm/lib/Target/Mips/MipsLongBranch.cpp
+++ b/llvm/lib/Target/Mips/MipsLongBranch.cpp
@@ -584,8 +584,7 @@ bool MipsLongBranch::runOnMachineFunction(MachineFunction &F) {
if (!I->Br || I->HasLongBranch)
continue;
- int ShVal = STI.inMicroMipsMode() ? 2 : 4;
- int64_t Offset = computeOffset(I->Br) / ShVal;
+ int64_t Offset = computeOffset(I->Br);
if (STI.isTargetNaCl()) {
// The offset calculation does not include sandboxing instructions
@@ -595,8 +594,9 @@ bool MipsLongBranch::runOnMachineFunction(MachineFunction &F) {
Offset *= 2;
}
- // Check if offset fits into 16-bit immediate field of branches.
- if (!ForceLongBranch && isInt<16>(Offset))
+ // Check if offset fits into the immediate field of the branch.
+ if (!ForceLongBranch &&
+ TII->isBranchOffsetInRange(I->Br->getOpcode(), Offset))
continue;
I->HasLongBranch = true;
diff --git a/llvm/lib/Target/Mips/MipsSEInstrInfo.cpp b/llvm/lib/Target/Mips/MipsSEInstrInfo.cpp
index 6b7156d089f..386a0cd3bd1 100644
--- a/llvm/lib/Target/Mips/MipsSEInstrInfo.cpp
+++ b/llvm/lib/Target/Mips/MipsSEInstrInfo.cpp
@@ -427,6 +427,10 @@ unsigned MipsSEInstrInfo::getOppositeBranchOpc(unsigned Opc) const {
case Mips::BGEZ: return Mips::BLTZ;
case Mips::BLTZ: return Mips::BGEZ;
case Mips::BLEZ: return Mips::BGTZ;
+ case Mips::BGTZ_MM: return Mips::BLEZ_MM;
+ case Mips::BGEZ_MM: return Mips::BLTZ_MM;
+ case Mips::BLTZ_MM: return Mips::BGEZ_MM;
+ case Mips::BLEZ_MM: return Mips::BGTZ_MM;
case Mips::BEQ64: return Mips::BNE64;
case Mips::BNE64: return Mips::BEQ64;
case Mips::BGTZ64: return Mips::BLEZ64;
@@ -435,24 +439,40 @@ unsigned MipsSEInstrInfo::getOppositeBranchOpc(unsigned Opc) const {
case Mips::BLEZ64: return Mips::BGTZ64;
case Mips::BC1T: return Mips::BC1F;
case Mips::BC1F: return Mips::BC1T;
- case Mips::BEQZC_MM: return Mips::BNEZC_MM;
- case Mips::BNEZC_MM: return Mips::BEQZC_MM;
+ case Mips::BC1T_MM: return Mips::BC1F_MM;
+ case Mips::BC1F_MM: return Mips::BC1T_MM;
+ case Mips::BEQZ16_MM: return Mips::BNEZ16_MM;
+ case Mips::BNEZ16_MM: return Mips::BEQZ16_MM;
+ case Mips::BEQZC_MM: return Mips::BNEZC_MM;
+ case Mips::BNEZC_MM: return Mips::BEQZC_MM;
case Mips::BEQZC: return Mips::BNEZC;
case Mips::BNEZC: return Mips::BEQZC;
- case Mips::BEQC: return Mips::BNEC;
- case Mips::BNEC: return Mips::BEQC;
- case Mips::BGTZC: return Mips::BLEZC;
+ case Mips::BLEZC: return Mips::BGTZC;
case Mips::BGEZC: return Mips::BLTZC;
+ case Mips::BGEC: return Mips::BLTC;
+ case Mips::BGTZC: return Mips::BLEZC;
case Mips::BLTZC: return Mips::BGEZC;
- case Mips::BLEZC: return Mips::BGTZC;
+ case Mips::BLTC: return Mips::BGEC;
+ case Mips::BGEUC: return Mips::BLTUC;
+ case Mips::BLTUC: return Mips::BGEUC;
+ case Mips::BEQC: return Mips::BNEC;
+ case Mips::BNEC: return Mips::BEQC;
+ case Mips::BC1EQZ: return Mips::BC1NEZ;
+ case Mips::BC1NEZ: return Mips::BC1EQZ;
case Mips::BEQZC_MMR6: return Mips::BNEZC_MMR6;
case Mips::BNEZC_MMR6: return Mips::BEQZC_MMR6;
- case Mips::BEQC_MMR6: return Mips::BNEC_MMR6;
- case Mips::BNEC_MMR6: return Mips::BEQC_MMR6;
- case Mips::BGTZC_MMR6: return Mips::BLEZC_MMR6;
+ case Mips::BLEZC_MMR6: return Mips::BGTZC_MMR6;
case Mips::BGEZC_MMR6: return Mips::BLTZC_MMR6;
+ case Mips::BGEC_MMR6: return Mips::BLTC_MMR6;
+ case Mips::BGTZC_MMR6: return Mips::BLEZC_MMR6;
case Mips::BLTZC_MMR6: return Mips::BGEZC_MMR6;
- case Mips::BLEZC_MMR6: return Mips::BGTZC_MMR6;
+ case Mips::BLTC_MMR6: return Mips::BGEC_MMR6;
+ case Mips::BGEUC_MMR6: return Mips::BLTUC_MMR6;
+ case Mips::BLTUC_MMR6: return Mips::BGEUC_MMR6;
+ case Mips::BEQC_MMR6: return Mips::BNEC_MMR6;
+ case Mips::BNEC_MMR6: return Mips::BEQC_MMR6;
+ case Mips::BC1EQZC_MMR6: return Mips::BC1NEZC_MMR6;
+ case Mips::BC1NEZC_MMR6: return Mips::BC1EQZC_MMR6;
case Mips::BEQZC64: return Mips::BNEZC64;
case Mips::BNEZC64: return Mips::BEQZC64;
case Mips::BEQC64: return Mips::BNEC64;
@@ -469,6 +489,16 @@ unsigned MipsSEInstrInfo::getOppositeBranchOpc(unsigned Opc) const {
case Mips::BBIT1: return Mips::BBIT0;
case Mips::BBIT032: return Mips::BBIT132;
case Mips::BBIT132: return Mips::BBIT032;
+ case Mips::BZ_B: return Mips::BNZ_B;
+ case Mips::BZ_H: return Mips::BNZ_H;
+ case Mips::BZ_W: return Mips::BNZ_W;
+ case Mips::BZ_D: return Mips::BNZ_D;
+ case Mips::BZ_V: return Mips::BNZ_V;
+ case Mips::BNZ_B: return Mips::BZ_B;
+ case Mips::BNZ_H: return Mips::BZ_H;
+ case Mips::BNZ_W: return Mips::BZ_W;
+ case Mips::BNZ_D: return Mips::BZ_D;
+ case Mips::BNZ_V: return Mips::BZ_V;
}
}
OpenPOWER on IntegriCloud