diff options
Diffstat (limited to 'llvm/lib/Target/Mips/MipsLongBranch.cpp')
-rw-r--r-- | llvm/lib/Target/Mips/MipsLongBranch.cpp | 162 |
1 files changed, 116 insertions, 46 deletions
diff --git a/llvm/lib/Target/Mips/MipsLongBranch.cpp b/llvm/lib/Target/Mips/MipsLongBranch.cpp index 9af4f4b1cd4..bbf2050ce1e 100644 --- a/llvm/lib/Target/Mips/MipsLongBranch.cpp +++ b/llvm/lib/Target/Mips/MipsLongBranch.cpp @@ -279,12 +279,16 @@ void MipsLongBranch::expandToLongBranch(MBBInfo &I) { LongBrMBB->addSuccessor(BalTgtMBB); BalTgtMBB->addSuccessor(TgtMBB); - // We must select between the MIPS32r6/MIPS64r6 BAL (which is a normal + // We must select between the MIPS32r6/MIPS64r6 BALC (which is a normal // instruction) and the pre-MIPS32r6/MIPS64r6 definition (which is an // pseudo-instruction wrapping BGEZAL). - unsigned BalOp = Subtarget.hasMips32r6() ? Mips::BAL : Mips::BAL_BR; + const unsigned BalOp = + Subtarget.hasMips32r6() + ? Subtarget.inMicroMipsMode() ? Mips::BALC_MMR6 : Mips::BALC + : Mips::BAL_BR; if (!ABI.IsN64()) { + // Pre R6: // $longbr: // addiu $sp, $sp, -8 // sw $ra, 0($sp) @@ -299,6 +303,20 @@ void MipsLongBranch::expandToLongBranch(MBBInfo &I) { // $fallthrough: // + // R6: + // $longbr: + // addiu $sp, $sp, -8 + // sw $ra, 0($sp) + // lui $at, %hi($tgt - $baltgt) + // addiu $at, $at, %lo($tgt - $baltgt) + // balc $baltgt + // $baltgt: + // addu $at, $ra, $at + // lw $ra, 0($sp) + // addiu $sp, $sp, 8 + // jic $at, 0 + // $fallthrough: + Pos = LongBrMBB->begin(); BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::ADDiu), Mips::SP) @@ -307,7 +325,7 @@ void MipsLongBranch::expandToLongBranch(MBBInfo &I) { .addReg(Mips::SP).addImm(0); // LUi and ADDiu instructions create 32-bit offset of the target basic - // block from the target of BAL instruction. We cannot use immediate + // block from the target of BAL(C) instruction. We cannot use immediate // value for this offset because it cannot be determined accurately when // the program has inline assembly statements. We therefore use the // relocation expressions %hi($tgt-$baltgt) and %lo($tgt-$baltgt) which @@ -324,12 +342,22 @@ void MipsLongBranch::expandToLongBranch(MBBInfo &I) { BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::LONG_BRANCH_LUi), Mips::AT) .addMBB(TgtMBB).addMBB(BalTgtMBB); - MIBundleBuilder(*LongBrMBB, Pos) - .append(BuildMI(*MF, DL, TII->get(BalOp)).addMBB(BalTgtMBB)) - .append(BuildMI(*MF, DL, TII->get(Mips::LONG_BRANCH_ADDiu), Mips::AT) - .addReg(Mips::AT) - .addMBB(TgtMBB) - .addMBB(BalTgtMBB)); + + MachineInstrBuilder BalInstr = + BuildMI(*MF, DL, TII->get(BalOp)).addMBB(BalTgtMBB); + MachineInstrBuilder ADDiuInstr = + BuildMI(*MF, DL, TII->get(Mips::LONG_BRANCH_ADDiu), Mips::AT) + .addReg(Mips::AT) + .addMBB(TgtMBB) + .addMBB(BalTgtMBB); + if (Subtarget.hasMips32r6()) { + LongBrMBB->insert(Pos, ADDiuInstr); + LongBrMBB->insert(Pos, BalInstr); + } else { + LongBrMBB->insert(Pos, BalInstr); + LongBrMBB->insert(Pos, ADDiuInstr); + LongBrMBB->rbegin()->bundleWithPred(); + } Pos = BalTgtMBB->begin(); @@ -337,28 +365,37 @@ void MipsLongBranch::expandToLongBranch(MBBInfo &I) { .addReg(Mips::RA).addReg(Mips::AT); BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::LW), Mips::RA) .addReg(Mips::SP).addImm(0); + if (Subtarget.isTargetNaCl()) + // Bundle-align the target of indirect branch JR. + TgtMBB->setAlignment(MIPS_NACL_BUNDLE_ALIGN); // In NaCl, modifying the sp is not allowed in branch delay slot. - if (Subtarget.isTargetNaCl()) + // For MIPS32R6, we can skip using a delay slot branch. + if (Subtarget.isTargetNaCl() || Subtarget.hasMips32r6()) BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::ADDiu), Mips::SP) .addReg(Mips::SP).addImm(8); - if (Subtarget.hasMips32r6()) - BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::JALR)) - .addReg(Mips::ZERO).addReg(Mips::AT); - else + if (Subtarget.hasMips32r6()) { + const unsigned JICOp = + Subtarget.inMicroMipsMode() ? Mips::JIC_MMR6 : Mips::JIC; + BuildMI(*BalTgtMBB, Pos, DL, TII->get(JICOp)) + .addReg(Mips::AT) + .addImm(0); + + } else { BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::JR)).addReg(Mips::AT); - if (Subtarget.isTargetNaCl()) { - BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::NOP)); - // Bundle-align the target of indirect branch JR. - TgtMBB->setAlignment(MIPS_NACL_BUNDLE_ALIGN); - } else - BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::ADDiu), Mips::SP) - .addReg(Mips::SP).addImm(8); + if (Subtarget.isTargetNaCl()) { + BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::NOP)); + } else + BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::ADDiu), Mips::SP) + .addReg(Mips::SP) + .addImm(8); - BalTgtMBB->rbegin()->bundleWithPred(); + BalTgtMBB->rbegin()->bundleWithPred(); + } } else { + // Pre R6: // $longbr: // daddiu $sp, $sp, -16 // sd $ra, 0($sp) @@ -372,7 +409,21 @@ void MipsLongBranch::expandToLongBranch(MBBInfo &I) { // jr64 $at // daddiu $sp, $sp, 16 // $fallthrough: - // + + // R6: + // $longbr: + // daddiu $sp, $sp, -16 + // sd $ra, 0($sp) + // daddiu $at, $zero, %hi($tgt - $baltgt) + // dsll $at, $at, 16 + // daddiu $at, $at, %lo($tgt - $baltgt) + // balc $baltgt + // $baltgt: + // daddu $at, $ra, $at + // ld $ra, 0($sp) + // daddiu $sp, $sp, 16 + // jic $at, 0 + // $fallthrough: // We assume the branch is within-function, and that offset is within // +/- 2GB. High 32 bits will therefore always be zero. @@ -401,13 +452,21 @@ void MipsLongBranch::expandToLongBranch(MBBInfo &I) { BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::DSLL), Mips::AT_64) .addReg(Mips::AT_64).addImm(16); - MIBundleBuilder(*LongBrMBB, Pos) - .append(BuildMI(*MF, DL, TII->get(BalOp)).addMBB(BalTgtMBB)) - .append( - BuildMI(*MF, DL, TII->get(Mips::LONG_BRANCH_DADDiu), Mips::AT_64) - .addReg(Mips::AT_64) - .addMBB(TgtMBB, MipsII::MO_ABS_LO) - .addMBB(BalTgtMBB)); + MachineInstrBuilder BalInstr = + BuildMI(*MF, DL, TII->get(BalOp)).addMBB(BalTgtMBB); + MachineInstrBuilder DADDiuInstr = + BuildMI(*MF, DL, TII->get(Mips::LONG_BRANCH_DADDiu), Mips::AT_64) + .addReg(Mips::AT_64) + .addMBB(TgtMBB, MipsII::MO_ABS_LO) + .addMBB(BalTgtMBB); + if (Subtarget.hasMips32r6()) { + LongBrMBB->insert(Pos, DADDiuInstr); + LongBrMBB->insert(Pos, BalInstr); + } else { + LongBrMBB->insert(Pos, BalInstr); + LongBrMBB->insert(Pos, DADDiuInstr); + LongBrMBB->rbegin()->bundleWithPred(); + } Pos = BalTgtMBB->begin(); @@ -416,29 +475,40 @@ void MipsLongBranch::expandToLongBranch(MBBInfo &I) { BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::LD), Mips::RA_64) .addReg(Mips::SP_64).addImm(0); - if (Subtarget.hasMips64r6()) - BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::JALR64)) - .addReg(Mips::ZERO_64).addReg(Mips::AT_64); - else + if (Subtarget.hasMips64r6()) { + BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::DADDiu), Mips::SP_64) + .addReg(Mips::SP_64) + .addImm(16); + BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::JIC64)) + .addReg(Mips::AT_64) + .addImm(0); + } else { BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::JR64)).addReg(Mips::AT_64); - - BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::DADDiu), Mips::SP_64) - .addReg(Mips::SP_64).addImm(16); - BalTgtMBB->rbegin()->bundleWithPred(); + BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::DADDiu), Mips::SP_64) + .addReg(Mips::SP_64) + .addImm(16); + BalTgtMBB->rbegin()->bundleWithPred(); + } } assert(LongBrMBB->size() + BalTgtMBB->size() == LongBranchSeqSize); } else { - // $longbr: - // j $tgt - // nop + // Pre R6: R6: + // $longbr: $longbr: + // j $tgt bc $tgt + // nop $fallthrough // $fallthrough: // Pos = LongBrMBB->begin(); LongBrMBB->addSuccessor(TgtMBB); - MIBundleBuilder(*LongBrMBB, Pos) - .append(BuildMI(*MF, DL, TII->get(Mips::J)).addMBB(TgtMBB)) - .append(BuildMI(*MF, DL, TII->get(Mips::NOP))); + if (Subtarget.hasMips32r6()) + BuildMI(*LongBrMBB, Pos, DL, + TII->get(Subtarget.inMicroMipsMode() ? Mips::BC_MMR6 : Mips::BC)) + .addMBB(TgtMBB); + else + MIBundleBuilder(*LongBrMBB, Pos) + .append(BuildMI(*MF, DL, TII->get(Mips::J)).addMBB(TgtMBB)) + .append(BuildMI(*MF, DL, TII->get(Mips::NOP))); assert(LongBrMBB->size() == LongBranchSeqSize); } @@ -474,8 +544,8 @@ bool MipsLongBranch::runOnMachineFunction(MachineFunction &F) { IsPIC = TM.isPositionIndependent(); ABI = static_cast<const MipsTargetMachine &>(TM).getABI(); - LongBranchSeqSize = - !IsPIC ? 2 : (ABI.IsN64() ? 10 : (!STI.isTargetNaCl() ? 9 : 10)); + LongBranchSeqSize = IsPIC ? ((ABI.IsN64() || STI.isTargetNaCl()) ? 10 : 9) + : (STI.hasMips32r6() ? 1 : 2); if (STI.inMips16Mode() || !STI.enableLongBranchPass()) return false; |