277 // $longbr: 278 // addiu $sp, $sp, -8 279 // sw $ra, 0($sp) 280 // lui $at, %hi($tgt - $baltgt) 281 // bal $baltgt 282 // addiu $at, $at, %lo($tgt - $baltgt) 283 // $baltgt: 284 // addu $at, $ra, $at 285 // lw $ra, 0($sp) 286 // jr $at 287 // addiu $sp, $sp, 8 288 // $fallthrough: 289 // 290 291 Pos = LongBrMBB->begin(); 292 293 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::ADDiu), Mips::SP) 294 .addReg(Mips::SP).addImm(-8); 295 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::SW)).addReg(Mips::RA) 296 .addReg(Mips::SP).addImm(0); 297 298 // LUi and ADDiu instructions create 32-bit offset of the target basic 299 // block from the target of BAL instruction. We cannot use immediate 300 // value for this offset because it cannot be determined accurately when 301 // the program has inline assembly statements. We therefore use the 302 // relocation expressions %hi($tgt-$baltgt) and %lo($tgt-$baltgt) which 303 // are resolved during the fixup, so the values will always be correct. 304 // 305 // Since we cannot create %hi($tgt-$baltgt) and %lo($tgt-$baltgt) 306 // expressions at this point (it is possible only at the MC layer), 307 // we replace LUi and ADDiu with pseudo instructions 308 // LONG_BRANCH_LUi and LONG_BRANCH_ADDiu, and add both basic 309 // blocks as operands to these instructions. When lowering these pseudo 310 // instructions to LUi and ADDiu in the MC layer, we will create 311 // %hi($tgt-$baltgt) and %lo($tgt-$baltgt) expressions and add them as 312 // operands to lowered instructions. 313 314 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::LONG_BRANCH_LUi), Mips::AT) 315 .addMBB(TgtMBB).addMBB(BalTgtMBB); 316 MIBundleBuilder(*LongBrMBB, Pos) 317 .append(BuildMI(*MF, DL, TII->get(BalOp)).addMBB(BalTgtMBB)) 318 .append(BuildMI(*MF, DL, TII->get(Mips::LONG_BRANCH_ADDiu), Mips::AT) 319 .addReg(Mips::AT) 320 .addMBB(TgtMBB) 321 .addMBB(BalTgtMBB)); 322 323 Pos = BalTgtMBB->begin(); 324 325 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::ADDu), Mips::AT) 326 .addReg(Mips::RA).addReg(Mips::AT); 327 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::LW), Mips::RA) 328 .addReg(Mips::SP).addImm(0); 329 330 if (!TM.getSubtarget<MipsSubtarget>().isTargetNaCl()) { 331 MIBundleBuilder(*BalTgtMBB, Pos) 332 .append(BuildMI(*MF, DL, TII->get(Mips::JR)).addReg(Mips::AT)) 333 .append(BuildMI(*MF, DL, TII->get(Mips::ADDiu), Mips::SP) 334 .addReg(Mips::SP).addImm(8)); 335 } else { 336 // In NaCl, modifying the sp is not allowed in branch delay slot. 337 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::ADDiu), Mips::SP) 338 .addReg(Mips::SP).addImm(8); 339 340 MIBundleBuilder(*BalTgtMBB, Pos) 341 .append(BuildMI(*MF, DL, TII->get(Mips::JR)).addReg(Mips::AT)) 342 .append(BuildMI(*MF, DL, TII->get(Mips::NOP))); 343 344 // Bundle-align the target of indirect branch JR. 345 TgtMBB->setAlignment(MIPS_NACL_BUNDLE_ALIGN); 346 } 347 } else { 348 // $longbr: 349 // daddiu $sp, $sp, -16 350 // sd $ra, 0($sp) 351 // daddiu $at, $zero, %hi($tgt - $baltgt) 352 // dsll $at, $at, 16 353 // bal $baltgt 354 // daddiu $at, $at, %lo($tgt - $baltgt) 355 // $baltgt: 356 // daddu $at, $ra, $at 357 // ld $ra, 0($sp) 358 // jr64 $at 359 // daddiu $sp, $sp, 16 360 // $fallthrough: 361 // 362 363 // We assume the branch is within-function, and that offset is within 364 // +/- 2GB. High 32 bits will therefore always be zero. 365 366 // Note that this will work even if the offset is negative, because 367 // of the +1 modification that's added in that case. For example, if the 368 // offset is -1MB (0xFFFFFFFFFFF00000), the computation for %higher is 369 // 370 // 0xFFFFFFFFFFF00000 + 0x80008000 = 0x000000007FF08000 371 // 372 // and the bits [47:32] are zero. For %highest 373 // 374 // 0xFFFFFFFFFFF00000 + 0x800080008000 = 0x000080007FF08000 375 // 376 // and the bits [63:48] are zero. 377 378 Pos = LongBrMBB->begin(); 379 380 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::DADDiu), Mips::SP_64) 381 .addReg(Mips::SP_64).addImm(-16); 382 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::SD)).addReg(Mips::RA_64) 383 .addReg(Mips::SP_64).addImm(0); 384 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::LONG_BRANCH_DADDiu), 385 Mips::AT_64).addReg(Mips::ZERO_64) 386 .addMBB(TgtMBB, MipsII::MO_ABS_HI).addMBB(BalTgtMBB); 387 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::DSLL), Mips::AT_64) 388 .addReg(Mips::AT_64).addImm(16); 389 390 MIBundleBuilder(*LongBrMBB, Pos) 391 .append(BuildMI(*MF, DL, TII->get(BalOp)).addMBB(BalTgtMBB)) 392 .append( 393 BuildMI(*MF, DL, TII->get(Mips::LONG_BRANCH_DADDiu), Mips::AT_64) 394 .addReg(Mips::AT_64) 395 .addMBB(TgtMBB, MipsII::MO_ABS_LO) 396 .addMBB(BalTgtMBB)); 397 398 Pos = BalTgtMBB->begin(); 399 400 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::DADDu), Mips::AT_64) 401 .addReg(Mips::RA_64).addReg(Mips::AT_64); 402 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::LD), Mips::RA_64) 403 .addReg(Mips::SP_64).addImm(0); 404 405 MIBundleBuilder(*BalTgtMBB, Pos) 406 .append(BuildMI(*MF, DL, TII->get(Mips::JR64)).addReg(Mips::AT_64)) 407 .append(BuildMI(*MF, DL, TII->get(Mips::DADDiu), Mips::SP_64) 408 .addReg(Mips::SP_64).addImm(16)); 409 } 410 411 assert(LongBrMBB->size() + BalTgtMBB->size() == LongBranchSeqSize); 412 } else { 413 // $longbr: 414 // j $tgt 415 // nop 416 // $fallthrough: 417 // 418 Pos = LongBrMBB->begin(); 419 LongBrMBB->addSuccessor(TgtMBB); 420 MIBundleBuilder(*LongBrMBB, Pos) 421 .append(BuildMI(*MF, DL, TII->get(Mips::J)).addMBB(TgtMBB)) 422 .append(BuildMI(*MF, DL, TII->get(Mips::NOP))); 423 424 assert(LongBrMBB->size() == LongBranchSeqSize); 425 } 426 427 if (I.Br->isUnconditionalBranch()) { 428 // Change branch destination. 429 assert(I.Br->getDesc().getNumOperands() == 1); 430 I.Br->RemoveOperand(0); 431 I.Br->addOperand(MachineOperand::CreateMBB(LongBrMBB)); 432 } else 433 // Change branch destination and reverse condition. 434 replaceBranch(*MBB, I.Br, DL, FallThroughMBB); 435} 436 437static void emitGPDisp(MachineFunction &F, const MipsInstrInfo *TII) { 438 MachineBasicBlock &MBB = F.front(); 439 MachineBasicBlock::iterator I = MBB.begin(); 440 DebugLoc DL = MBB.findDebugLoc(MBB.begin()); 441 BuildMI(MBB, I, DL, TII->get(Mips::LUi), Mips::V0) 442 .addExternalSymbol("_gp_disp", MipsII::MO_ABS_HI); 443 BuildMI(MBB, I, DL, TII->get(Mips::ADDiu), Mips::V0) 444 .addReg(Mips::V0).addExternalSymbol("_gp_disp", MipsII::MO_ABS_LO); 445 MBB.removeLiveIn(Mips::V0); 446} 447 448bool MipsLongBranch::runOnMachineFunction(MachineFunction &F) { 449 const MipsInstrInfo *TII = 450 static_cast<const MipsInstrInfo*>(TM.getInstrInfo()); 451 452 const MipsSubtarget &STI = TM.getSubtarget<MipsSubtarget>(); 453 if (STI.inMips16Mode() || !STI.enableLongBranchPass()) 454 return false; 455 if ((TM.getRelocationModel() == Reloc::PIC_) && 456 TM.getSubtarget<MipsSubtarget>().isABI_O32() && 457 F.getInfo<MipsFunctionInfo>()->globalBaseRegSet()) 458 emitGPDisp(F, TII); 459 460 if (SkipLongBranch) 461 return true; 462 463 MF = &F; 464 initMBBInfo(); 465 466 SmallVectorImpl<MBBInfo>::iterator I, E = MBBInfos.end(); 467 bool EverMadeChange = false, MadeChange = true; 468 469 while (MadeChange) { 470 MadeChange = false; 471 472 for (I = MBBInfos.begin(); I != E; ++I) { 473 // Skip if this MBB doesn't have a branch or the branch has already been 474 // converted to a long branch. 475 if (!I->Br || I->HasLongBranch) 476 continue; 477 478 int ShVal = TM.getSubtarget<MipsSubtarget>().inMicroMipsMode() ? 2 : 4; 479 int64_t Offset = computeOffset(I->Br) / ShVal; 480 481 if (TM.getSubtarget<MipsSubtarget>().isTargetNaCl()) { 482 // The offset calculation does not include sandboxing instructions 483 // that will be added later in the MC layer. Since at this point we 484 // don't know the exact amount of code that "sandboxing" will add, we 485 // conservatively estimate that code will not grow more than 100%. 486 Offset *= 2; 487 } 488 489 // Check if offset fits into 16-bit immediate field of branches. 490 if (!ForceLongBranch && isInt<16>(Offset)) 491 continue; 492 493 I->HasLongBranch = true; 494 I->Size += LongBranchSeqSize * 4; 495 ++LongBranches; 496 EverMadeChange = MadeChange = true; 497 } 498 } 499 500 if (!EverMadeChange) 501 return true; 502 503 // Compute basic block addresses. 504 if (TM.getRelocationModel() == Reloc::PIC_) { 505 uint64_t Address = 0; 506 507 for (I = MBBInfos.begin(); I != E; Address += I->Size, ++I) 508 I->Address = Address; 509 } 510 511 // Do the expansion. 512 for (I = MBBInfos.begin(); I != E; ++I) 513 if (I->HasLongBranch) 514 expandToLongBranch(*I); 515 516 MF->RenumberBlocks(); 517 518 return true; 519}
|