diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Target/Mips/MipsInstrInfo.cpp | 157 | ||||
-rw-r--r-- | llvm/lib/Target/Mips/MipsInstrInfo.h | 4 | ||||
-rw-r--r-- | llvm/lib/Target/Mips/MipsLongBranch.cpp | 8 | ||||
-rw-r--r-- | llvm/lib/Target/Mips/MipsSEInstrInfo.cpp | 50 |
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; } } |