Lines Matching +full:hi +full:- +full:fi

1 //===----------------------- MipsBranchExpansion.cpp ----------------------===//
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
11 /// - it expands a branch or jump instruction into a long branch if its offset
13 /// - it inserts nops to prevent forbidden slot hazards.
34 /// FIXME: Fix pc-region jump instructions which cross 256MB segment boundaries.
73 //===----------------------------------------------------------------------===//
108 #define DEBUG_TYPE "mips-branch-expansion"
114 SkipLongBranch("skip-mips-long-branch", cl::init(false),
118 ForceLongBranch("force-mips-long-branch", cl::init(false),
198 Iter I = Position, E = Position->getParent()->end();
200 [](const Iter &Insn) { return Insn->isTransient(); });
209 if (Position == Parent->end()) {
211 MachineBasicBlock *Succ = Parent->getNextNode();
212 if (Succ != nullptr && Parent->isSuccessor(Succ)) {
213 Position = Succ->begin();
218 } while (Parent->empty());
222 if (Instr == Parent->end()) {
241 // Traverse the list of instructions backwards until a non-debug instruction is
245 if (!B->isDebugInstr())
253 ReverseIter End = MBB->rend();
254 ReverseIter LastBr = getNonDebugInstr(MBB->rbegin(), End);
258 (!LastBr->isConditionalBranch() && !LastBr->isUnconditionalBranch()))
266 (!FirstBr->isConditionalBranch() && !FirstBr->isUnconditionalBranch()))
269 assert(!FirstBr->isIndirectBranch() && "Unexpected indirect branch found.");
273 MFp->CreateMachineBasicBlock(MBB->getBasicBlock());
277 NewMBB->transferSuccessors(MBB);
279 NewMBB->removeSuccessor(Tgt, true);
280 MBB->addSuccessor(NewMBB);
281 MBB->addSuccessor(Tgt);
282 MFp->insert(std::next(MachineFunction::iterator(MBB)), NewMBB);
284 NewMBB->splice(NewMBB->end(), MBB, LastBr.getReverse(), MBB->end());
294 MFp->RenumberBlocks();
296 MBBInfos.resize(MFp->size());
299 MachineBasicBlock *MBB = MFp->getBlockNumbered(I);
302 for (MachineInstr &MI : MBB->instrs())
303 MBBInfos[I].Size += TII->getInstSizeInBytes(MI);
310 int ThisMBB = Br->getParent()->getNumber();
311 int TargetMBB = getTargetMBB(*Br)->getNumber();
322 for (int N = ThisMBB; N >= TargetMBB; --N)
325 return -Offset + 4;
341 unsigned NewOpc = TII->getOppositeBranchOpc(Br->getOpcode());
342 const MCInstrDesc &NewDesc = TII->get(NewOpc);
346 for (unsigned I = 0, E = Br->getDesc().getNumOperands(); I < E; ++I) {
347 MachineOperand &MO = Br->getOperand(I);
356 if (!TII->isBranchWithImm(Br->getOpcode()))
368 if (Br->hasDelaySlot()) {
371 assert(Br->isBundledWithSucc());
373 MIBundleBuilder(&*MIB).append((++II)->removeFromBundle());
375 Br->eraseFromParent();
381 bool HasR6 = ABI.IsN64() ? STI->hasMips64r6() : STI->hasMips32r6();
382 bool AddImm = HasR6 && !STI->useIndirectJumpsHazard();
390 if (STI->useIndirectJumpsHazard())
395 if (JumpOp == Mips::JIC && STI->inMicroMipsMode())
400 BuildMI(*MBB, Pos, DL, TII->get(JumpOp)).addReg(ATReg);
409 // currently assumes that all branches have 16-bit offsets, and will produce
410 // wrong code if branches whose allowed offsets are [-128, -126, ..., 126]
414 MachineBasicBlock *MBB = I.Br->getParent(), *TgtMBB = getTargetMBB(*I.Br);
415 DebugLoc DL = I.Br->getDebugLoc();
416 const BasicBlock *BB = MBB->getBasicBlock();
418 MachineBasicBlock *LongBrMBB = MFp->CreateMachineBasicBlock(BB);
420 MFp->insert(FallThroughMBB, LongBrMBB);
421 MBB->replaceSuccessor(TgtMBB, LongBrMBB);
424 MachineBasicBlock *BalTgtMBB = MFp->CreateMachineBasicBlock(BB);
425 MFp->insert(FallThroughMBB, BalTgtMBB);
426 LongBrMBB->addSuccessor(BalTgtMBB);
427 BalTgtMBB->addSuccessor(TgtMBB);
430 // instruction) and the pre-MIPS32r6/MIPS64r6 definition (which is an
431 // pseudo-instruction wrapping BGEZAL).
433 STI->hasMips32r6()
434 ? STI->inMicroMipsMode() ? Mips::BALC_MMR6 : Mips::BALC
435 : STI->inMicroMipsMode() ? Mips::BAL_BR_MM : Mips::BAL_BR;
440 // addiu $sp, $sp, -8
442 // lui $at, %hi($tgt - $baltgt)
444 // addiu $at, $at, %lo($tgt - $baltgt)
455 // addiu $sp, $sp, -8
457 // lui $at, %hi($tgt - $baltgt)
458 // addiu $at, $at, %lo($tgt - $baltgt)
467 Pos = LongBrMBB->begin();
469 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::ADDiu), Mips::SP)
471 .addImm(-8);
472 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::SW))
477 // LUi and ADDiu instructions create 32-bit offset of the target basic
481 // relocation expressions %hi($tgt-$baltgt) and %lo($tgt-$baltgt) which
484 // Since we cannot create %hi($tgt-$baltgt) and %lo($tgt-$baltgt)
490 // %hi($tgt-$baltgt) and %lo($tgt-$baltgt) expressions and add them as
493 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::LONG_BRANCH_LUi), Mips::AT)
498 BuildMI(*MFp, DL, TII->get(BalOp)).addMBB(BalTgtMBB);
500 BuildMI(*MFp, DL, TII->get(Mips::LONG_BRANCH_ADDiu), Mips::AT)
504 if (STI->hasMips32r6()) {
505 LongBrMBB->insert(Pos, ADDiuInstr);
506 LongBrMBB->insert(Pos, BalInstr);
508 LongBrMBB->insert(Pos, BalInstr);
509 LongBrMBB->insert(Pos, ADDiuInstr);
510 LongBrMBB->rbegin()->bundleWithPred();
513 Pos = BalTgtMBB->begin();
515 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::ADDu), Mips::AT)
518 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::LW), Mips::RA)
521 if (STI->isTargetNaCl())
522 // Bundle-align the target of indirect branch JR.
523 TgtMBB->setAlignment(MIPS_NACL_BUNDLE_ALIGN);
529 if (STI->isTargetNaCl() || !hasDelaySlot) {
530 BuildMI(*BalTgtMBB, std::prev(Pos), DL, TII->get(Mips::ADDiu), Mips::SP)
535 if (STI->isTargetNaCl()) {
536 TII->insertNop(*BalTgtMBB, Pos, DL);
538 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::ADDiu), Mips::SP)
542 BalTgtMBB->rbegin()->bundleWithPred();
547 // daddiu $sp, $sp, -16
549 // daddiu $at, $zero, %hi($tgt - $baltgt)
552 // daddiu $at, $at, %lo($tgt - $baltgt)
562 // daddiu $sp, $sp, -16
564 // daddiu $at, $zero, %hi($tgt - $baltgt)
566 // daddiu $at, $at, %lo($tgt - $baltgt)
575 // We assume the branch is within-function, and that offset is within
576 // +/- 2GB. High 32 bits will therefore always be zero.
580 // offset is -1MB (0xFFFFFFFFFFF00000), the computation for %higher is
590 Pos = LongBrMBB->begin();
592 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::DADDiu), Mips::SP_64)
594 .addImm(-16);
595 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::SD))
599 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::LONG_BRANCH_DADDiu),
604 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::DSLL), Mips::AT_64)
609 BuildMI(*MFp, DL, TII->get(BalOp)).addMBB(BalTgtMBB);
611 BuildMI(*MFp, DL, TII->get(Mips::LONG_BRANCH_DADDiu), Mips::AT_64)
615 if (STI->hasMips32r6()) {
616 LongBrMBB->insert(Pos, DADDiuInstr);
617 LongBrMBB->insert(Pos, BalInstr);
619 LongBrMBB->insert(Pos, BalInstr);
620 LongBrMBB->insert(Pos, DADDiuInstr);
621 LongBrMBB->rbegin()->bundleWithPred();
624 Pos = BalTgtMBB->begin();
626 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::DADDu), Mips::AT_64)
629 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::LD), Mips::RA_64)
636 BuildMI(*BalTgtMBB, std::prev(Pos), DL, TII->get(Mips::DADDiu),
641 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::DADDiu), Mips::SP_64)
644 BalTgtMBB->rbegin()->bundleWithPred();
648 Pos = LongBrMBB->begin();
649 LongBrMBB->addSuccessor(TgtMBB);
653 uint64_t JOffset = computeOffsetFromTheBeginning(MBB->getNumber()) +
654 MBBInfos[MBB->getNumber()].Size + 4;
655 uint64_t TgtMBBOffset = computeOffsetFromTheBeginning(TgtMBB->getNumber());
663 if (STI->hasMips32r6() && TII->isBranchOffsetInRange(Mips::BC, I.Offset)) {
670 TII->get(STI->inMicroMipsMode() ? Mips::BC_MMR6 : Mips::BC))
679 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::J)).addMBB(TgtMBB);
680 TII->insertNop(*LongBrMBB, Pos, DL)->bundleWithPred();
688 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::LONG_BRANCH_LUi2Op_64),
691 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::LONG_BRANCH_DADDiu2Op),
695 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::DSLL), Mips::AT_64)
698 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::LONG_BRANCH_DADDiu2Op),
702 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::DSLL), Mips::AT_64)
705 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::LONG_BRANCH_DADDiu2Op),
710 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::LONG_BRANCH_LUi2Op),
713 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::LONG_BRANCH_ADDiu2Op),
722 if (I.Br->isUnconditionalBranch()) {
724 assert(I.Br->getDesc().getNumOperands() == 1);
725 I.Br->removeOperand(0);
726 I.Br->addOperand(MachineOperand::CreateMBB(LongBrMBB));
736 BuildMI(MBB, I, DL, TII->get(Mips::LUi), Mips::V0)
738 BuildMI(MBB, I, DL, TII->get(Mips::ADDiu), Mips::V0)
748 for (MachineFunction::iterator FI = MFp->begin(); FI != MFp->end(); ++FI) {
749 for (Iter I = FI->begin(); I != FI->end(); ++I) {
757 std::next(I) == FI->end() && std::next(FI) == MFp->end();
759 std::pair<Iter, bool> Res = getNextMachineInstr(std::next(I), &*FI);
765 MachineBasicBlock::instr_iterator Iit = I->getIterator();
766 if (std::next(Iit) == FI->end() ||
767 std::next(Iit)->getOpcode() != Mips::NOP) {
769 TII->insertNop(*(I->getParent()), std::next(I), I->getDebugLoc())
770 ->bundleWithPred();
782 if (!STI->hasMips32r6() || STI->inMicroMipsMode())
786 [this](auto &I) -> bool { return TII->HasForbiddenSlot(I); },
787 [this](auto &IInSlot, auto &I) -> bool {
788 return TII->SafeInForbiddenSlot(IInSlot);
794 if (STI->hasMips32() || STI->hasMips4())
797 return handleSlot([this](auto &I) -> bool { return TII->HasFPUDelaySlot(I); },
798 [this](auto &IInSlot, auto &I) -> bool {
799 return TII->SafeInFPUDelaySlot(IInSlot, I);
805 if (STI->hasMips2())
809 [this](auto &I) -> bool { return TII->HasLoadDelaySlot(I); },
810 [this](auto &IInSlot, auto &I) -> bool {
811 return TII->SafeInLoadDelaySlot(IInSlot, I);
816 if (STI->inMips16Mode() || !STI->enableLongBranchPass())
830 MachineBasicBlock *MBB = MFp->getBlockNumbered(I);
832 ReverseIter End = MBB->rend();
833 ReverseIter Br = getNonDebugInstr(MBB->rbegin(), End);
835 if ((Br != End) && Br->isBranch() && !Br->isIndirectBranch() &&
836 (Br->isConditionalBranch() ||
837 (Br->isUnconditionalBranch() && IsPIC))) {
840 if (STI->isTargetNaCl()) {
849 !TII->isBranchOffsetInRange(Br->getOpcode(), Offset)) {
863 if (!I->Br)
871 MFp->RenumberBlocks();
882 TII = static_cast<const MipsInstrInfo *>(STI->getInstrInfo());
885 MF.getInfo<MipsFunctionInfo>()->globalBaseRegSet())