1 //===----------------------- MipsBranchExpansion.cpp ----------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 /// \file 9 /// 10 /// This pass do two things: 11 /// - it expands a branch or jump instruction into a long branch if its offset 12 /// is too large to fit into its immediate field, 13 /// - it inserts nops to prevent forbidden slot hazards. 14 /// 15 /// The reason why this pass combines these two tasks is that one of these two 16 /// tasks can break the result of the previous one. 17 /// 18 /// Example of that is a situation where at first, no branch should be expanded, 19 /// but after adding at least one nop somewhere in the code to prevent a 20 /// forbidden slot hazard, offset of some branches may go out of range. In that 21 /// case it is necessary to check again if there is some branch that needs 22 /// expansion. On the other hand, expanding some branch may cause a control 23 /// transfer instruction to appear in the forbidden slot, which is a hazard that 24 /// should be fixed. This pass alternates between this two tasks untill no 25 /// changes are made. Only then we can be sure that all branches are expanded 26 /// properly, and no hazard situations exist. 27 /// 28 /// Regarding branch expanding: 29 /// 30 /// When branch instruction like beqzc or bnezc has offset that is too large 31 /// to fit into its immediate field, it has to be expanded to another 32 /// instruction or series of instructions. 33 /// 34 /// FIXME: Fix pc-region jump instructions which cross 256MB segment boundaries. 35 /// TODO: Handle out of range bc, b (pseudo) instructions. 36 /// 37 /// Regarding compact branch hazard prevention: 38 /// 39 /// Hazards handled: forbidden slots for MIPSR6, FPU slots for MIPS3 and below, 40 /// load delay slots for MIPS1. 41 /// 42 /// A forbidden slot hazard occurs when a compact branch instruction is executed 43 /// and the adjacent instruction in memory is a control transfer instruction 44 /// such as a branch or jump, ERET, ERETNC, DERET, WAIT and PAUSE. 45 /// 46 /// For example: 47 /// 48 /// 0x8004 bnec a1,v0,<P+0x18> 49 /// 0x8008 beqc a1,a2,<P+0x54> 50 /// 51 /// In such cases, the processor is required to signal a Reserved Instruction 52 /// exception. 53 /// 54 /// Here, if the instruction at 0x8004 is executed, the processor will raise an 55 /// exception as there is a control transfer instruction at 0x8008. 56 /// 57 /// There are two sources of forbidden slot hazards: 58 /// 59 /// A) A previous pass has created a compact branch directly. 60 /// B) Transforming a delay slot branch into compact branch. This case can be 61 /// difficult to process as lookahead for hazards is insufficient, as 62 /// backwards delay slot fillling can also produce hazards in previously 63 /// processed instuctions. 64 /// 65 /// In future this pass can be extended (or new pass can be created) to handle 66 /// other pipeline hazards, such as various MIPS1 hazards, processor errata that 67 /// require instruction reorganization, etc. 68 /// 69 /// This pass has to run after the delay slot filler as that pass can introduce 70 /// pipeline hazards such as compact branch hazard, hence the existing hazard 71 /// recognizer is not suitable. 72 /// 73 //===----------------------------------------------------------------------===// 74 75 #include "MCTargetDesc/MipsABIInfo.h" 76 #include "MCTargetDesc/MipsBaseInfo.h" 77 #include "MCTargetDesc/MipsMCNaCl.h" 78 #include "MCTargetDesc/MipsMCTargetDesc.h" 79 #include "Mips.h" 80 #include "MipsInstrInfo.h" 81 #include "MipsMachineFunction.h" 82 #include "MipsSubtarget.h" 83 #include "MipsTargetMachine.h" 84 #include "llvm/ADT/SmallVector.h" 85 #include "llvm/ADT/Statistic.h" 86 #include "llvm/ADT/StringRef.h" 87 #include "llvm/CodeGen/MachineBasicBlock.h" 88 #include "llvm/CodeGen/MachineFunction.h" 89 #include "llvm/CodeGen/MachineFunctionPass.h" 90 #include "llvm/CodeGen/MachineInstr.h" 91 #include "llvm/CodeGen/MachineInstrBuilder.h" 92 #include "llvm/CodeGen/MachineModuleInfo.h" 93 #include "llvm/CodeGen/MachineOperand.h" 94 #include "llvm/CodeGen/TargetSubtargetInfo.h" 95 #include "llvm/IR/DebugLoc.h" 96 #include "llvm/Support/CommandLine.h" 97 #include "llvm/Support/ErrorHandling.h" 98 #include "llvm/Target/TargetMachine.h" 99 #include <algorithm> 100 #include <cassert> 101 #include <cstdint> 102 #include <iterator> 103 #include <utility> 104 105 using namespace llvm; 106 107 #define DEBUG_TYPE "mips-branch-expansion" 108 109 STATISTIC(NumInsertedNops, "Number of nops inserted"); 110 STATISTIC(LongBranches, "Number of long branches."); 111 112 static cl::opt<bool> 113 SkipLongBranch("skip-mips-long-branch", cl::init(false), 114 cl::desc("MIPS: Skip branch expansion pass."), cl::Hidden); 115 116 static cl::opt<bool> 117 ForceLongBranch("force-mips-long-branch", cl::init(false), 118 cl::desc("MIPS: Expand all branches to long format."), 119 cl::Hidden); 120 121 namespace { 122 123 using Iter = MachineBasicBlock::iterator; 124 using ReverseIter = MachineBasicBlock::reverse_iterator; 125 126 struct MBBInfo { 127 uint64_t Size = 0; 128 bool HasLongBranch = false; 129 MachineInstr *Br = nullptr; 130 uint64_t Offset = 0; 131 MBBInfo() = default; 132 }; 133 134 class MipsBranchExpansion : public MachineFunctionPass { 135 public: 136 static char ID; 137 138 MipsBranchExpansion() : MachineFunctionPass(ID), ABI(MipsABIInfo::Unknown()) { 139 initializeMipsBranchExpansionPass(*PassRegistry::getPassRegistry()); 140 } 141 142 StringRef getPassName() const override { 143 return "Mips Branch Expansion Pass"; 144 } 145 146 bool runOnMachineFunction(MachineFunction &F) override; 147 148 MachineFunctionProperties getRequiredProperties() const override { 149 return MachineFunctionProperties().set( 150 MachineFunctionProperties::Property::NoVRegs); 151 } 152 153 private: 154 void splitMBB(MachineBasicBlock *MBB); 155 void initMBBInfo(); 156 int64_t computeOffset(const MachineInstr *Br); 157 uint64_t computeOffsetFromTheBeginning(int MBB); 158 void replaceBranch(MachineBasicBlock &MBB, Iter Br, const DebugLoc &DL, 159 MachineBasicBlock *MBBOpnd); 160 bool buildProperJumpMI(MachineBasicBlock *MBB, 161 MachineBasicBlock::iterator Pos, DebugLoc DL); 162 void expandToLongBranch(MBBInfo &Info); 163 template <typename Pred, typename Safe> 164 bool handleSlot(Pred Predicate, Safe SafeInSlot); 165 bool handleForbiddenSlot(); 166 bool handleFPUDelaySlot(); 167 bool handleLoadDelaySlot(); 168 bool handlePossibleLongBranch(); 169 bool handleMFLO(); 170 template <typename Pred, typename Safe> 171 bool handleMFLOSlot(Pred Predicate, Safe SafeInSlot); 172 173 const MipsSubtarget *STI; 174 const MipsInstrInfo *TII; 175 176 MachineFunction *MFp; 177 SmallVector<MBBInfo, 16> MBBInfos; 178 bool IsPIC; 179 MipsABIInfo ABI; 180 bool ForceLongBranchFirstPass = false; 181 }; 182 183 } // end of anonymous namespace 184 185 char MipsBranchExpansion::ID = 0; 186 187 INITIALIZE_PASS(MipsBranchExpansion, DEBUG_TYPE, 188 "Expand out of range branch instructions and fix forbidden" 189 " slot hazards", 190 false, false) 191 192 /// Returns a pass that clears pipeline hazards. 193 FunctionPass *llvm::createMipsBranchExpansion() { 194 return new MipsBranchExpansion(); 195 } 196 197 // Find the next real instruction from the current position in current basic 198 // block. 199 static Iter getNextMachineInstrInBB(Iter Position) { 200 Iter I = Position, E = Position->getParent()->end(); 201 I = std::find_if_not(I, E, 202 [](const Iter &Insn) { return Insn->isTransient(); }); 203 204 return I; 205 } 206 207 // Find the next real instruction from the current position, looking through 208 // basic block boundaries. 209 static std::pair<Iter, bool> getNextMachineInstr(Iter Position, 210 MachineBasicBlock *Parent) { 211 if (Position == Parent->end()) { 212 do { 213 MachineBasicBlock *Succ = Parent->getNextNode(); 214 if (Succ != nullptr && Parent->isSuccessor(Succ)) { 215 Position = Succ->begin(); 216 Parent = Succ; 217 } else { 218 return std::make_pair(Position, true); 219 } 220 } while (Parent->empty()); 221 } 222 223 Iter Instr = getNextMachineInstrInBB(Position); 224 if (Instr == Parent->end()) { 225 return getNextMachineInstr(Instr, Parent); 226 } 227 return std::make_pair(Instr, false); 228 } 229 230 /// Iterate over list of Br's operands and search for a MachineBasicBlock 231 /// operand. 232 static MachineBasicBlock *getTargetMBB(const MachineInstr &Br) { 233 for (unsigned I = 0, E = Br.getDesc().getNumOperands(); I < E; ++I) { 234 const MachineOperand &MO = Br.getOperand(I); 235 236 if (MO.isMBB()) 237 return MO.getMBB(); 238 } 239 240 llvm_unreachable("This instruction does not have an MBB operand."); 241 } 242 243 // Traverse the list of instructions backwards until a non-debug instruction is 244 // found or it reaches E. 245 static ReverseIter getNonDebugInstr(ReverseIter B, const ReverseIter &E) { 246 for (; B != E; ++B) 247 if (!B->isDebugInstr()) 248 return B; 249 250 return E; 251 } 252 253 // Split MBB if it has two direct jumps/branches. 254 void MipsBranchExpansion::splitMBB(MachineBasicBlock *MBB) { 255 ReverseIter End = MBB->rend(); 256 ReverseIter LastBr = getNonDebugInstr(MBB->rbegin(), End); 257 258 // Return if MBB has no branch instructions. 259 if ((LastBr == End) || 260 (!LastBr->isConditionalBranch() && !LastBr->isUnconditionalBranch())) 261 return; 262 263 ReverseIter FirstBr = getNonDebugInstr(std::next(LastBr), End); 264 265 // MBB has only one branch instruction if FirstBr is not a branch 266 // instruction. 267 if ((FirstBr == End) || 268 (!FirstBr->isConditionalBranch() && !FirstBr->isUnconditionalBranch())) 269 return; 270 271 assert(!FirstBr->isIndirectBranch() && "Unexpected indirect branch found."); 272 273 // Create a new MBB. Move instructions in MBB to the newly created MBB. 274 MachineBasicBlock *NewMBB = 275 MFp->CreateMachineBasicBlock(MBB->getBasicBlock()); 276 277 // Insert NewMBB and fix control flow. 278 MachineBasicBlock *Tgt = getTargetMBB(*FirstBr); 279 NewMBB->transferSuccessors(MBB); 280 if (Tgt != getTargetMBB(*LastBr)) 281 NewMBB->removeSuccessor(Tgt, true); 282 MBB->addSuccessor(NewMBB); 283 MBB->addSuccessor(Tgt); 284 MFp->insert(std::next(MachineFunction::iterator(MBB)), NewMBB); 285 286 NewMBB->splice(NewMBB->end(), MBB, LastBr.getReverse(), MBB->end()); 287 } 288 289 // Fill MBBInfos. 290 void MipsBranchExpansion::initMBBInfo() { 291 // Split the MBBs if they have two branches. Each basic block should have at 292 // most one branch after this loop is executed. 293 for (auto &MBB : *MFp) 294 splitMBB(&MBB); 295 296 MFp->RenumberBlocks(); 297 MBBInfos.clear(); 298 MBBInfos.resize(MFp->size()); 299 300 for (unsigned I = 0, E = MBBInfos.size(); I < E; ++I) { 301 MachineBasicBlock *MBB = MFp->getBlockNumbered(I); 302 303 // Compute size of MBB. 304 for (MachineInstr &MI : MBB->instrs()) 305 MBBInfos[I].Size += TII->getInstSizeInBytes(MI); 306 } 307 } 308 309 // Compute offset of branch in number of bytes. 310 int64_t MipsBranchExpansion::computeOffset(const MachineInstr *Br) { 311 int64_t Offset = 0; 312 int ThisMBB = Br->getParent()->getNumber(); 313 int TargetMBB = getTargetMBB(*Br)->getNumber(); 314 315 // Compute offset of a forward branch. 316 if (ThisMBB < TargetMBB) { 317 for (int N = ThisMBB + 1; N < TargetMBB; ++N) 318 Offset += MBBInfos[N].Size; 319 320 return Offset + 4; 321 } 322 323 // Compute offset of a backward branch. 324 for (int N = ThisMBB; N >= TargetMBB; --N) 325 Offset += MBBInfos[N].Size; 326 327 return -Offset + 4; 328 } 329 330 // Returns the distance in bytes up until MBB 331 uint64_t MipsBranchExpansion::computeOffsetFromTheBeginning(int MBB) { 332 uint64_t Offset = 0; 333 for (int N = 0; N < MBB; ++N) 334 Offset += MBBInfos[N].Size; 335 return Offset; 336 } 337 338 // Replace Br with a branch which has the opposite condition code and a 339 // MachineBasicBlock operand MBBOpnd. 340 void MipsBranchExpansion::replaceBranch(MachineBasicBlock &MBB, Iter Br, 341 const DebugLoc &DL, 342 MachineBasicBlock *MBBOpnd) { 343 unsigned NewOpc = TII->getOppositeBranchOpc(Br->getOpcode()); 344 const MCInstrDesc &NewDesc = TII->get(NewOpc); 345 346 MachineInstrBuilder MIB = BuildMI(MBB, Br, DL, NewDesc); 347 348 for (unsigned I = 0, E = Br->getDesc().getNumOperands(); I < E; ++I) { 349 MachineOperand &MO = Br->getOperand(I); 350 351 switch (MO.getType()) { 352 case MachineOperand::MO_Register: 353 MIB.addReg(MO.getReg()); 354 break; 355 case MachineOperand::MO_Immediate: 356 // Octeon BBIT family of branch has an immediate operand 357 // (e.g. BBIT0 $v0, 3, %bb.1). 358 if (!TII->isBranchWithImm(Br->getOpcode())) 359 llvm_unreachable("Unexpected immediate in branch instruction"); 360 MIB.addImm(MO.getImm()); 361 break; 362 case MachineOperand::MO_MachineBasicBlock: 363 MIB.addMBB(MBBOpnd); 364 break; 365 default: 366 llvm_unreachable("Unexpected operand type in branch instruction"); 367 } 368 } 369 370 if (Br->hasDelaySlot()) { 371 // Bundle the instruction in the delay slot to the newly created branch 372 // and erase the original branch. 373 assert(Br->isBundledWithSucc()); 374 MachineBasicBlock::instr_iterator II = Br.getInstrIterator(); 375 MIBundleBuilder(&*MIB).append((++II)->removeFromBundle()); 376 } 377 Br->eraseFromParent(); 378 } 379 380 bool MipsBranchExpansion::buildProperJumpMI(MachineBasicBlock *MBB, 381 MachineBasicBlock::iterator Pos, 382 DebugLoc DL) { 383 bool HasR6 = ABI.IsN64() ? STI->hasMips64r6() : STI->hasMips32r6(); 384 bool AddImm = HasR6 && !STI->useIndirectJumpsHazard(); 385 386 unsigned JR = ABI.IsN64() ? Mips::JR64 : Mips::JR; 387 unsigned JIC = ABI.IsN64() ? Mips::JIC64 : Mips::JIC; 388 unsigned JR_HB = ABI.IsN64() ? Mips::JR_HB64 : Mips::JR_HB; 389 unsigned JR_HB_R6 = ABI.IsN64() ? Mips::JR_HB64_R6 : Mips::JR_HB_R6; 390 391 unsigned JumpOp; 392 if (STI->useIndirectJumpsHazard()) 393 JumpOp = HasR6 ? JR_HB_R6 : JR_HB; 394 else 395 JumpOp = HasR6 ? JIC : JR; 396 397 if (JumpOp == Mips::JIC && STI->inMicroMipsMode()) 398 JumpOp = Mips::JIC_MMR6; 399 400 unsigned ATReg = ABI.IsN64() ? Mips::AT_64 : Mips::AT; 401 MachineInstrBuilder Instr = 402 BuildMI(*MBB, Pos, DL, TII->get(JumpOp)).addReg(ATReg); 403 if (AddImm) 404 Instr.addImm(0); 405 406 return !AddImm; 407 } 408 409 // Expand branch instructions to long branches. 410 // TODO: This function has to be fixed for beqz16 and bnez16, because it 411 // currently assumes that all branches have 16-bit offsets, and will produce 412 // wrong code if branches whose allowed offsets are [-128, -126, ..., 126] 413 // are present. 414 void MipsBranchExpansion::expandToLongBranch(MBBInfo &I) { 415 MachineBasicBlock::iterator Pos; 416 MachineBasicBlock *MBB = I.Br->getParent(), *TgtMBB = getTargetMBB(*I.Br); 417 DebugLoc DL = I.Br->getDebugLoc(); 418 const BasicBlock *BB = MBB->getBasicBlock(); 419 MachineFunction::iterator FallThroughMBB = ++MachineFunction::iterator(MBB); 420 MachineBasicBlock *LongBrMBB = MFp->CreateMachineBasicBlock(BB); 421 422 MFp->insert(FallThroughMBB, LongBrMBB); 423 MBB->replaceSuccessor(TgtMBB, LongBrMBB); 424 425 if (IsPIC) { 426 MachineBasicBlock *BalTgtMBB = MFp->CreateMachineBasicBlock(BB); 427 MFp->insert(FallThroughMBB, BalTgtMBB); 428 LongBrMBB->addSuccessor(BalTgtMBB); 429 BalTgtMBB->addSuccessor(TgtMBB); 430 431 // We must select between the MIPS32r6/MIPS64r6 BALC (which is a normal 432 // instruction) and the pre-MIPS32r6/MIPS64r6 definition (which is an 433 // pseudo-instruction wrapping BGEZAL). 434 const unsigned BalOp = 435 STI->hasMips32r6() 436 ? STI->inMicroMipsMode() ? Mips::BALC_MMR6 : Mips::BALC 437 : STI->inMicroMipsMode() ? Mips::BAL_BR_MM : Mips::BAL_BR; 438 439 if (!ABI.IsN64()) { 440 // Pre R6: 441 // $longbr: 442 // addiu $sp, $sp, -8 443 // sw $ra, 0($sp) 444 // lui $at, %hi($tgt - $baltgt) 445 // bal $baltgt 446 // addiu $at, $at, %lo($tgt - $baltgt) 447 // $baltgt: 448 // addu $at, $ra, $at 449 // lw $ra, 0($sp) 450 // jr $at 451 // addiu $sp, $sp, 8 452 // $fallthrough: 453 // 454 455 // R6: 456 // $longbr: 457 // addiu $sp, $sp, -8 458 // sw $ra, 0($sp) 459 // lui $at, %hi($tgt - $baltgt) 460 // addiu $at, $at, %lo($tgt - $baltgt) 461 // balc $baltgt 462 // $baltgt: 463 // addu $at, $ra, $at 464 // lw $ra, 0($sp) 465 // addiu $sp, $sp, 8 466 // jic $at, 0 467 // $fallthrough: 468 469 Pos = LongBrMBB->begin(); 470 471 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::ADDiu), Mips::SP) 472 .addReg(Mips::SP) 473 .addImm(-8); 474 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::SW)) 475 .addReg(Mips::RA) 476 .addReg(Mips::SP) 477 .addImm(0); 478 479 // LUi and ADDiu instructions create 32-bit offset of the target basic 480 // block from the target of BAL(C) instruction. We cannot use immediate 481 // value for this offset because it cannot be determined accurately when 482 // the program has inline assembly statements. We therefore use the 483 // relocation expressions %hi($tgt-$baltgt) and %lo($tgt-$baltgt) which 484 // are resolved during the fixup, so the values will always be correct. 485 // 486 // Since we cannot create %hi($tgt-$baltgt) and %lo($tgt-$baltgt) 487 // expressions at this point (it is possible only at the MC layer), 488 // we replace LUi and ADDiu with pseudo instructions 489 // LONG_BRANCH_LUi and LONG_BRANCH_ADDiu, and add both basic 490 // blocks as operands to these instructions. When lowering these pseudo 491 // instructions to LUi and ADDiu in the MC layer, we will create 492 // %hi($tgt-$baltgt) and %lo($tgt-$baltgt) expressions and add them as 493 // operands to lowered instructions. 494 495 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::LONG_BRANCH_LUi), Mips::AT) 496 .addMBB(TgtMBB, MipsII::MO_ABS_HI) 497 .addMBB(BalTgtMBB); 498 499 MachineInstrBuilder BalInstr = 500 BuildMI(*MFp, DL, TII->get(BalOp)).addMBB(BalTgtMBB); 501 MachineInstrBuilder ADDiuInstr = 502 BuildMI(*MFp, DL, TII->get(Mips::LONG_BRANCH_ADDiu), Mips::AT) 503 .addReg(Mips::AT) 504 .addMBB(TgtMBB, MipsII::MO_ABS_LO) 505 .addMBB(BalTgtMBB); 506 if (STI->hasMips32r6()) { 507 LongBrMBB->insert(Pos, ADDiuInstr); 508 LongBrMBB->insert(Pos, BalInstr); 509 } else { 510 LongBrMBB->insert(Pos, BalInstr); 511 LongBrMBB->insert(Pos, ADDiuInstr); 512 LongBrMBB->rbegin()->bundleWithPred(); 513 } 514 515 Pos = BalTgtMBB->begin(); 516 517 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::ADDu), Mips::AT) 518 .addReg(Mips::RA) 519 .addReg(Mips::AT); 520 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::LW), Mips::RA) 521 .addReg(Mips::SP) 522 .addImm(0); 523 if (STI->isTargetNaCl()) 524 // Bundle-align the target of indirect branch JR. 525 TgtMBB->setAlignment(MIPS_NACL_BUNDLE_ALIGN); 526 527 // In NaCl, modifying the sp is not allowed in branch delay slot. 528 // For MIPS32R6, we can skip using a delay slot branch. 529 bool hasDelaySlot = buildProperJumpMI(BalTgtMBB, Pos, DL); 530 531 if (STI->isTargetNaCl() || !hasDelaySlot) { 532 BuildMI(*BalTgtMBB, std::prev(Pos), DL, TII->get(Mips::ADDiu), Mips::SP) 533 .addReg(Mips::SP) 534 .addImm(8); 535 } 536 if (hasDelaySlot) { 537 if (STI->isTargetNaCl()) { 538 TII->insertNop(*BalTgtMBB, Pos, DL); 539 } else { 540 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::ADDiu), Mips::SP) 541 .addReg(Mips::SP) 542 .addImm(8); 543 } 544 BalTgtMBB->rbegin()->bundleWithPred(); 545 } 546 } else { 547 // Pre R6: 548 // $longbr: 549 // daddiu $sp, $sp, -16 550 // sd $ra, 0($sp) 551 // daddiu $at, $zero, %hi($tgt - $baltgt) 552 // dsll $at, $at, 16 553 // bal $baltgt 554 // daddiu $at, $at, %lo($tgt - $baltgt) 555 // $baltgt: 556 // daddu $at, $ra, $at 557 // ld $ra, 0($sp) 558 // jr64 $at 559 // daddiu $sp, $sp, 16 560 // $fallthrough: 561 562 // R6: 563 // $longbr: 564 // daddiu $sp, $sp, -16 565 // sd $ra, 0($sp) 566 // daddiu $at, $zero, %hi($tgt - $baltgt) 567 // dsll $at, $at, 16 568 // daddiu $at, $at, %lo($tgt - $baltgt) 569 // balc $baltgt 570 // $baltgt: 571 // daddu $at, $ra, $at 572 // ld $ra, 0($sp) 573 // daddiu $sp, $sp, 16 574 // jic $at, 0 575 // $fallthrough: 576 577 // We assume the branch is within-function, and that offset is within 578 // +/- 2GB. High 32 bits will therefore always be zero. 579 580 // Note that this will work even if the offset is negative, because 581 // of the +1 modification that's added in that case. For example, if the 582 // offset is -1MB (0xFFFFFFFFFFF00000), the computation for %higher is 583 // 584 // 0xFFFFFFFFFFF00000 + 0x80008000 = 0x000000007FF08000 585 // 586 // and the bits [47:32] are zero. For %highest 587 // 588 // 0xFFFFFFFFFFF00000 + 0x800080008000 = 0x000080007FF08000 589 // 590 // and the bits [63:48] are zero. 591 592 Pos = LongBrMBB->begin(); 593 594 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::DADDiu), Mips::SP_64) 595 .addReg(Mips::SP_64) 596 .addImm(-16); 597 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::SD)) 598 .addReg(Mips::RA_64) 599 .addReg(Mips::SP_64) 600 .addImm(0); 601 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::LONG_BRANCH_DADDiu), 602 Mips::AT_64) 603 .addReg(Mips::ZERO_64) 604 .addMBB(TgtMBB, MipsII::MO_ABS_HI) 605 .addMBB(BalTgtMBB); 606 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::DSLL), Mips::AT_64) 607 .addReg(Mips::AT_64) 608 .addImm(16); 609 610 MachineInstrBuilder BalInstr = 611 BuildMI(*MFp, DL, TII->get(BalOp)).addMBB(BalTgtMBB); 612 MachineInstrBuilder DADDiuInstr = 613 BuildMI(*MFp, DL, TII->get(Mips::LONG_BRANCH_DADDiu), Mips::AT_64) 614 .addReg(Mips::AT_64) 615 .addMBB(TgtMBB, MipsII::MO_ABS_LO) 616 .addMBB(BalTgtMBB); 617 if (STI->hasMips32r6()) { 618 LongBrMBB->insert(Pos, DADDiuInstr); 619 LongBrMBB->insert(Pos, BalInstr); 620 } else { 621 LongBrMBB->insert(Pos, BalInstr); 622 LongBrMBB->insert(Pos, DADDiuInstr); 623 LongBrMBB->rbegin()->bundleWithPred(); 624 } 625 626 Pos = BalTgtMBB->begin(); 627 628 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::DADDu), Mips::AT_64) 629 .addReg(Mips::RA_64) 630 .addReg(Mips::AT_64); 631 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::LD), Mips::RA_64) 632 .addReg(Mips::SP_64) 633 .addImm(0); 634 635 bool hasDelaySlot = buildProperJumpMI(BalTgtMBB, Pos, DL); 636 // If there is no delay slot, Insert stack adjustment before 637 if (!hasDelaySlot) { 638 BuildMI(*BalTgtMBB, std::prev(Pos), DL, TII->get(Mips::DADDiu), 639 Mips::SP_64) 640 .addReg(Mips::SP_64) 641 .addImm(16); 642 } else { 643 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::DADDiu), Mips::SP_64) 644 .addReg(Mips::SP_64) 645 .addImm(16); 646 BalTgtMBB->rbegin()->bundleWithPred(); 647 } 648 } 649 } else { // Not PIC 650 Pos = LongBrMBB->begin(); 651 LongBrMBB->addSuccessor(TgtMBB); 652 653 // Compute the position of the potentiall jump instruction (basic blocks 654 // before + 4 for the instruction) 655 uint64_t JOffset = computeOffsetFromTheBeginning(MBB->getNumber()) + 656 MBBInfos[MBB->getNumber()].Size + 4; 657 uint64_t TgtMBBOffset = computeOffsetFromTheBeginning(TgtMBB->getNumber()); 658 // If it's a forward jump, then TgtMBBOffset will be shifted by two 659 // instructions 660 if (JOffset < TgtMBBOffset) 661 TgtMBBOffset += 2 * 4; 662 // Compare 4 upper bits to check if it's the same segment 663 bool SameSegmentJump = JOffset >> 28 == TgtMBBOffset >> 28; 664 665 if (STI->hasMips32r6() && TII->isBranchOffsetInRange(Mips::BC, I.Offset)) { 666 // R6: 667 // $longbr: 668 // bc $tgt 669 // $fallthrough: 670 // 671 BuildMI(*LongBrMBB, Pos, DL, 672 TII->get(STI->inMicroMipsMode() ? Mips::BC_MMR6 : Mips::BC)) 673 .addMBB(TgtMBB); 674 } else if (SameSegmentJump) { 675 // Pre R6: 676 // $longbr: 677 // j $tgt 678 // nop 679 // $fallthrough: 680 // 681 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::J)).addMBB(TgtMBB); 682 TII->insertNop(*LongBrMBB, Pos, DL)->bundleWithPred(); 683 } else { 684 // At this point, offset where we need to branch does not fit into 685 // immediate field of the branch instruction and is not in the same 686 // segment as jump instruction. Therefore we will break it into couple 687 // instructions, where we first load the offset into register, and then we 688 // do branch register. 689 if (ABI.IsN64()) { 690 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::LONG_BRANCH_LUi2Op_64), 691 Mips::AT_64) 692 .addMBB(TgtMBB, MipsII::MO_HIGHEST); 693 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::LONG_BRANCH_DADDiu2Op), 694 Mips::AT_64) 695 .addReg(Mips::AT_64) 696 .addMBB(TgtMBB, MipsII::MO_HIGHER); 697 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::DSLL), Mips::AT_64) 698 .addReg(Mips::AT_64) 699 .addImm(16); 700 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::LONG_BRANCH_DADDiu2Op), 701 Mips::AT_64) 702 .addReg(Mips::AT_64) 703 .addMBB(TgtMBB, MipsII::MO_ABS_HI); 704 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::DSLL), Mips::AT_64) 705 .addReg(Mips::AT_64) 706 .addImm(16); 707 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::LONG_BRANCH_DADDiu2Op), 708 Mips::AT_64) 709 .addReg(Mips::AT_64) 710 .addMBB(TgtMBB, MipsII::MO_ABS_LO); 711 } else { 712 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::LONG_BRANCH_LUi2Op), 713 Mips::AT) 714 .addMBB(TgtMBB, MipsII::MO_ABS_HI); 715 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::LONG_BRANCH_ADDiu2Op), 716 Mips::AT) 717 .addReg(Mips::AT) 718 .addMBB(TgtMBB, MipsII::MO_ABS_LO); 719 } 720 buildProperJumpMI(LongBrMBB, Pos, DL); 721 } 722 } 723 724 if (I.Br->isUnconditionalBranch()) { 725 // Change branch destination. 726 assert(I.Br->getDesc().getNumOperands() == 1); 727 I.Br->removeOperand(0); 728 I.Br->addOperand(MachineOperand::CreateMBB(LongBrMBB)); 729 } else 730 // Change branch destination and reverse condition. 731 replaceBranch(*MBB, I.Br, DL, &*FallThroughMBB); 732 } 733 734 static void emitGPDisp(MachineFunction &F, const MipsInstrInfo *TII) { 735 MachineBasicBlock &MBB = F.front(); 736 MachineBasicBlock::iterator I = MBB.begin(); 737 DebugLoc DL = MBB.findDebugLoc(MBB.begin()); 738 BuildMI(MBB, I, DL, TII->get(Mips::LUi), Mips::V0) 739 .addExternalSymbol("_gp_disp", MipsII::MO_ABS_HI); 740 BuildMI(MBB, I, DL, TII->get(Mips::ADDiu), Mips::V0) 741 .addReg(Mips::V0) 742 .addExternalSymbol("_gp_disp", MipsII::MO_ABS_LO); 743 MBB.removeLiveIn(Mips::V0); 744 } 745 746 template <typename Pred, typename Safe> 747 bool MipsBranchExpansion::handleMFLOSlot(Pred Predicate, Safe SafeInSlot) { 748 bool Changed = false; 749 bool hasPendingMFLO = false; 750 751 for (MachineFunction::iterator FI = MFp->begin(); FI != MFp->end(); ++FI) { 752 for (Iter I = FI->begin(); I != FI->end(); ++I) { 753 754 if (!Predicate(*I) && !hasPendingMFLO) { 755 continue; 756 } 757 758 Iter IInSlot; 759 bool LastInstInFunction = 760 std::next(I) == FI->end() && std::next(FI) == MFp->end(); 761 // We need process several situations: 762 // mflo is last instruction, do not process; 763 // mflo + div, add two nop between them; 764 // mflo + none-div + none-div, do not process; 765 // mflo + none-div + div, add nop between none-div and div. 766 if (!LastInstInFunction) { 767 std::pair<Iter, bool> Res = getNextMachineInstr(std::next(I), &*FI); 768 LastInstInFunction |= Res.second; 769 IInSlot = Res.first; 770 if (LastInstInFunction) 771 continue; 772 if (!SafeInSlot(*IInSlot, *I)) { 773 Changed = true; 774 TII->insertNop(*(I->getParent()), std::next(I), I->getDebugLoc()) 775 ->bundleWithPred(); 776 NumInsertedNops++; 777 if (IsMFLOMFHI(I->getOpcode())) { 778 TII->insertNop(*(I->getParent()), std::next(I), I->getDebugLoc()) 779 ->bundleWithPred(); 780 NumInsertedNops++; 781 } 782 if (hasPendingMFLO) 783 hasPendingMFLO = false; 784 } else if (hasPendingMFLO) 785 hasPendingMFLO = false; 786 else if (IsMFLOMFHI(I->getOpcode())) 787 hasPendingMFLO = true; 788 } 789 } 790 } 791 792 return Changed; 793 } 794 795 template <typename Pred, typename Safe> 796 bool MipsBranchExpansion::handleSlot(Pred Predicate, Safe SafeInSlot) { 797 bool Changed = false; 798 799 for (MachineFunction::iterator FI = MFp->begin(); FI != MFp->end(); ++FI) { 800 for (Iter I = FI->begin(); I != FI->end(); ++I) { 801 802 // Delay slot hazard handling. Use lookahead over state. 803 if (!Predicate(*I)) 804 continue; 805 806 Iter IInSlot; 807 bool LastInstInFunction = 808 std::next(I) == FI->end() && std::next(FI) == MFp->end(); 809 if (!LastInstInFunction) { 810 std::pair<Iter, bool> Res = getNextMachineInstr(std::next(I), &*FI); 811 LastInstInFunction |= Res.second; 812 IInSlot = Res.first; 813 } 814 815 if (LastInstInFunction || !SafeInSlot(*IInSlot, *I)) { 816 MachineBasicBlock::instr_iterator Iit = I->getIterator(); 817 if (std::next(Iit) == FI->end() || 818 std::next(Iit)->getOpcode() != Mips::NOP) { 819 Changed = true; 820 TII->insertNop(*(I->getParent()), std::next(I), I->getDebugLoc()) 821 ->bundleWithPred(); 822 NumInsertedNops++; 823 } 824 } 825 } 826 } 827 828 return Changed; 829 } 830 831 bool MipsBranchExpansion::handleMFLO() { 832 // mips1-4 require a minimum of 2 instructions between a mflo/mfhi 833 // and the next mul/div instruction. 834 if (STI->hasMips32() || STI->hasMips5()) 835 return false; 836 837 return handleMFLOSlot( 838 [this](auto &I) -> bool { return TII->IsMfloOrMfhi(I); }, 839 [this](auto &IInSlot, auto &I) -> bool { 840 return TII->SafeAfterMflo(IInSlot); 841 }); 842 } 843 844 bool MipsBranchExpansion::handleForbiddenSlot() { 845 // Forbidden slot hazards are only defined for MIPSR6 but not microMIPSR6. 846 if (!STI->hasMips32r6() || STI->inMicroMipsMode()) 847 return false; 848 849 return handleSlot( 850 [this](auto &I) -> bool { return TII->HasForbiddenSlot(I); }, 851 [this](auto &IInSlot, auto &I) -> bool { 852 return TII->SafeInForbiddenSlot(IInSlot); 853 }); 854 } 855 856 bool MipsBranchExpansion::handleFPUDelaySlot() { 857 // FPU delay slots are only defined for MIPS3 and below. 858 if (STI->hasMips32() || STI->hasMips4()) 859 return false; 860 861 return handleSlot([this](auto &I) -> bool { return TII->HasFPUDelaySlot(I); }, 862 [this](auto &IInSlot, auto &I) -> bool { 863 return TII->SafeInFPUDelaySlot(IInSlot, I); 864 }); 865 } 866 867 bool MipsBranchExpansion::handleLoadDelaySlot() { 868 // Load delay slot hazards are only for MIPS1. 869 if (STI->hasMips2()) 870 return false; 871 872 return handleSlot( 873 [this](auto &I) -> bool { return TII->HasLoadDelaySlot(I); }, 874 [this](auto &IInSlot, auto &I) -> bool { 875 return TII->SafeInLoadDelaySlot(IInSlot, I); 876 }); 877 } 878 879 bool MipsBranchExpansion::handlePossibleLongBranch() { 880 if (STI->inMips16Mode() || !STI->enableLongBranchPass()) 881 return false; 882 883 if (SkipLongBranch) 884 return false; 885 886 bool EverMadeChange = false, MadeChange = true; 887 888 while (MadeChange) { 889 MadeChange = false; 890 891 initMBBInfo(); 892 893 for (unsigned I = 0, E = MBBInfos.size(); I < E; ++I) { 894 MachineBasicBlock *MBB = MFp->getBlockNumbered(I); 895 // Search for MBB's branch instruction. 896 ReverseIter End = MBB->rend(); 897 ReverseIter Br = getNonDebugInstr(MBB->rbegin(), End); 898 899 if ((Br != End) && Br->isBranch() && !Br->isIndirectBranch() && 900 (Br->isConditionalBranch() || 901 (Br->isUnconditionalBranch() && IsPIC))) { 902 int64_t Offset = computeOffset(&*Br); 903 904 if (STI->isTargetNaCl()) { 905 // The offset calculation does not include sandboxing instructions 906 // that will be added later in the MC layer. Since at this point we 907 // don't know the exact amount of code that "sandboxing" will add, we 908 // conservatively estimate that code will not grow more than 100%. 909 Offset *= 2; 910 } 911 912 if (ForceLongBranchFirstPass || 913 !TII->isBranchOffsetInRange(Br->getOpcode(), Offset)) { 914 MBBInfos[I].Offset = Offset; 915 MBBInfos[I].Br = &*Br; 916 } 917 } 918 } // End for 919 920 ForceLongBranchFirstPass = false; 921 922 SmallVectorImpl<MBBInfo>::iterator I, E = MBBInfos.end(); 923 924 for (I = MBBInfos.begin(); I != E; ++I) { 925 // Skip if this MBB doesn't have a branch or the branch has already been 926 // converted to a long branch. 927 if (!I->Br) 928 continue; 929 930 expandToLongBranch(*I); 931 ++LongBranches; 932 EverMadeChange = MadeChange = true; 933 } 934 935 MFp->RenumberBlocks(); 936 } 937 938 return EverMadeChange; 939 } 940 941 bool MipsBranchExpansion::runOnMachineFunction(MachineFunction &MF) { 942 const TargetMachine &TM = MF.getTarget(); 943 IsPIC = TM.isPositionIndependent(); 944 ABI = static_cast<const MipsTargetMachine &>(TM).getABI(); 945 STI = &MF.getSubtarget<MipsSubtarget>(); 946 TII = static_cast<const MipsInstrInfo *>(STI->getInstrInfo()); 947 948 if (IsPIC && ABI.IsO32() && 949 MF.getInfo<MipsFunctionInfo>()->globalBaseRegSet()) 950 emitGPDisp(MF, TII); 951 952 MFp = &MF; 953 954 ForceLongBranchFirstPass = ForceLongBranch; 955 // Run these at least once. 956 bool longBranchChanged = handlePossibleLongBranch(); 957 bool forbiddenSlotChanged = handleForbiddenSlot(); 958 bool fpuDelaySlotChanged = handleFPUDelaySlot(); 959 bool loadDelaySlotChanged = handleLoadDelaySlot(); 960 bool MfloChanged = handleMFLO(); 961 962 bool Changed = longBranchChanged || forbiddenSlotChanged || 963 fpuDelaySlotChanged || loadDelaySlotChanged || MfloChanged; 964 965 // Then run them alternatively while there are changes. 966 while (forbiddenSlotChanged) { 967 longBranchChanged = handlePossibleLongBranch(); 968 fpuDelaySlotChanged = handleFPUDelaySlot(); 969 loadDelaySlotChanged = handleLoadDelaySlot(); 970 MfloChanged = handleMFLO(); 971 if (!longBranchChanged && !fpuDelaySlotChanged && !loadDelaySlotChanged && 972 !MfloChanged) 973 break; 974 forbiddenSlotChanged = handleForbiddenSlot(); 975 } 976 977 return Changed; 978 } 979