OLD | NEW |
1 //===-- MipsLongBranch.cpp - Emit long branches ---------------------------===// | 1 //===-- MipsLongBranch.cpp - Emit long branches ---------------------------===// |
2 // | 2 // |
3 // The LLVM Compiler Infrastructure | 3 // The LLVM Compiler Infrastructure |
4 // | 4 // |
5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
7 // | 7 // |
8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
9 // | 9 // |
10 // This pass expands a branch or jump instruction into a long branch if its | 10 // This pass expands a branch or jump instruction into a long branch if its |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
61 | 61 |
62 class MipsLongBranch : public MachineFunctionPass { | 62 class MipsLongBranch : public MachineFunctionPass { |
63 | 63 |
64 public: | 64 public: |
65 static char ID; | 65 static char ID; |
66 MipsLongBranch(TargetMachine &tm) | 66 MipsLongBranch(TargetMachine &tm) |
67 : MachineFunctionPass(ID), TM(tm), | 67 : MachineFunctionPass(ID), TM(tm), |
68 TII(static_cast<const MipsInstrInfo*>(tm.getInstrInfo())), | 68 TII(static_cast<const MipsInstrInfo*>(tm.getInstrInfo())), |
69 IsPIC(TM.getRelocationModel() == Reloc::PIC_), | 69 IsPIC(TM.getRelocationModel() == Reloc::PIC_), |
70 ABI(TM.getSubtarget<MipsSubtarget>().getTargetABI()), | 70 ABI(TM.getSubtarget<MipsSubtarget>().getTargetABI()), |
71 LongBranchSeqSize(!IsPIC ? 2 : (ABI == MipsSubtarget::N64 ? 13 : 9)) {} | 71 LongBranchSeqSize(!IsPIC ? 2 : (ABI == MipsSubtarget::N64 ? 13 : |
| 72 (/*@LOCALMOD*/Triple(TM.getTargetTriple()).isOSNaCl() ? 10 : 9))) {} |
72 | 73 |
73 virtual const char *getPassName() const { | 74 virtual const char *getPassName() const { |
74 return "Mips Long Branch"; | 75 return "Mips Long Branch"; |
75 } | 76 } |
76 | 77 |
77 bool runOnMachineFunction(MachineFunction &F); | 78 bool runOnMachineFunction(MachineFunction &F); |
78 | 79 |
79 private: | 80 private: |
80 void splitMBB(MachineBasicBlock *MBB); | 81 void splitMBB(MachineBasicBlock *MBB); |
81 void initMBBInfo(); | 82 void initMBBInfo(); |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
256 MBB->removeSuccessor(TgtMBB); | 257 MBB->removeSuccessor(TgtMBB); |
257 MBB->addSuccessor(LongBrMBB); | 258 MBB->addSuccessor(LongBrMBB); |
258 | 259 |
259 if (IsPIC) { | 260 if (IsPIC) { |
260 MachineBasicBlock *BalTgtMBB = MF->CreateMachineBasicBlock(BB); | 261 MachineBasicBlock *BalTgtMBB = MF->CreateMachineBasicBlock(BB); |
261 MF->insert(FallThroughMBB, BalTgtMBB); | 262 MF->insert(FallThroughMBB, BalTgtMBB); |
262 LongBrMBB->addSuccessor(BalTgtMBB); | 263 LongBrMBB->addSuccessor(BalTgtMBB); |
263 BalTgtMBB->addSuccessor(TgtMBB); | 264 BalTgtMBB->addSuccessor(TgtMBB); |
264 | 265 |
265 int64_t TgtAddress = MBBInfos[TgtMBB->getNumber()].Address; | 266 int64_t TgtAddress = MBBInfos[TgtMBB->getNumber()].Address; |
266 unsigned BalTgtMBBSize = 5; | 267 // @LOCALMOD-START |
| 268 unsigned BalTgtMBBSize = Triple(TM.getTargetTriple()).isOSNaCl() ? 6 : 5; |
| 269 // @LOCALMOD-END |
267 int64_t Offset = TgtAddress - (I.Address + I.Size - BalTgtMBBSize * 4); | 270 int64_t Offset = TgtAddress - (I.Address + I.Size - BalTgtMBBSize * 4); |
268 int64_t Lo = SignExtend64<16>(Offset & 0xffff); | 271 int64_t Lo = SignExtend64<16>(Offset & 0xffff); |
269 int64_t Hi = SignExtend64<16>(((Offset + 0x8000) >> 16) & 0xffff); | 272 int64_t Hi = SignExtend64<16>(((Offset + 0x8000) >> 16) & 0xffff); |
270 | 273 |
271 if (ABI != MipsSubtarget::N64) { | 274 if (ABI != MipsSubtarget::N64) { |
272 // $longbr: | 275 // $longbr: |
273 // addiu $sp, $sp, -8 | 276 // addiu $sp, $sp, -8 |
274 // sw $ra, 0($sp) | 277 // sw $ra, 0($sp) |
275 // bal $baltgt | 278 // bal $baltgt |
276 // lui $at, %hi($tgt - $baltgt) | 279 // lui $at, %hi($tgt - $baltgt) |
277 // $baltgt: | 280 // $baltgt: |
278 // addiu $at, $at, %lo($tgt - $baltgt) | 281 // addiu $at, $at, %lo($tgt - $baltgt) |
279 // addu $at, $ra, $at | 282 // addu $at, $ra, $at |
280 // lw $ra, 0($sp) | 283 // lw $ra, 0($sp) |
281 // jr $at | 284 // jr $at |
282 // addiu $sp, $sp, 8 | 285 // addiu $sp, $sp, 8 |
283 // $fallthrough: | 286 // $fallthrough: |
284 // | 287 // |
285 | 288 |
286 Pos = LongBrMBB->begin(); | 289 Pos = LongBrMBB->begin(); |
287 | 290 |
288 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::ADDiu), Mips::SP) | 291 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::ADDiu), Mips::SP) |
289 .addReg(Mips::SP).addImm(-8); | 292 .addReg(Mips::SP).addImm(-8); |
290 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::SW)).addReg(Mips::RA) | 293 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::SW)).addReg(Mips::RA) |
291 .addReg(Mips::SP).addImm(0); | 294 .addReg(Mips::SP).addImm(0); |
292 | 295 |
293 MIBundleBuilder(*LongBrMBB, Pos) | 296 if (Triple(TM.getTargetTriple()).isOSNaCl()) { |
294 .append(BuildMI(*MF, DL, TII->get(Mips::BAL_BR)).addMBB(BalTgtMBB)) | 297 // @LOCALMOD-START |
295 .append(BuildMI(*MF, DL, TII->get(Mips::LUi), Mips::AT).addImm(Hi)); | 298 // LUi and ADDiu instructions create 32-bit offset of the target basic |
| 299 // block from the BAL target. We cannot use immediate value as the |
| 300 // offset (as non-NaCl version does) because it does not take |
| 301 // sandboxed instructions into account ("sanboxing" is run after this |
| 302 // pass). We therefore replace it with relocation expressions |
| 303 // %hi($tgt-$baltgt) and %lo($tgt-$baltgt). This expressions are |
| 304 // resolved during the fixup after all sandboxing code is added, so the |
| 305 // values will always be correct. |
| 306 // |
| 307 // Since we cannot create %hi($tgt-$baltgt) and %lo($tgt-$baltgt) |
| 308 // expressions at this point (it is possible only at the MC layer), |
| 309 // we replace LUi and ADDiu with pseudo instructions |
| 310 // NACL_LONG_BRANCH_LUi and NACL_LONG_BRANCH_ADDiu, and add both basic |
| 311 // block as operands to these instructions. When lowering these pseudo |
| 312 // instructions to LUi and ADDiu in the MC layer, we will create |
| 313 // %hi($tgt-$baltgt) and %lo($tgt-$baltgt) expressions add add them as |
| 314 // operands to lowered instructions. |
| 315 MIBundleBuilder(*LongBrMBB, Pos) |
| 316 .append(BuildMI(*MF, DL, TII->get(Mips::BAL_BR)).addMBB(BalTgtMBB)) |
| 317 .append(BuildMI(*MF, DL, TII->get(Mips::NACL_LONG_BRANCH_LUi), |
| 318 Mips::AT).addMBB(TgtMBB).addMBB(BalTgtMBB)); |
296 | 319 |
297 Pos = BalTgtMBB->begin(); | 320 Pos = BalTgtMBB->begin(); |
298 | 321 |
299 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::ADDiu), Mips::AT) | 322 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::NACL_LONG_BRANCH_ADDiu), |
300 .addReg(Mips::AT).addImm(Lo); | 323 Mips::AT).addReg(Mips::AT).addMBB(TgtMBB).addMBB(BalTgtMBB); |
301 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::ADDu), Mips::AT) | 324 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::ADDu), Mips::AT) |
302 .addReg(Mips::RA).addReg(Mips::AT); | 325 .addReg(Mips::RA).addReg(Mips::AT); |
303 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::LW), Mips::RA) | 326 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::LW), Mips::RA) |
304 .addReg(Mips::SP).addImm(0); | 327 .addReg(Mips::SP).addImm(0); |
305 | 328 |
306 MIBundleBuilder(*BalTgtMBB, Pos) | 329 // In NaCl, modifying sp is not allowed in branch delay slot. |
307 .append(BuildMI(*MF, DL, TII->get(Mips::JR)).addReg(Mips::AT)) | 330 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::ADDiu), Mips::SP) |
308 .append(BuildMI(*MF, DL, TII->get(Mips::ADDiu), Mips::SP) | 331 .addReg(Mips::SP).addImm(8); |
309 .addReg(Mips::SP).addImm(8)); | 332 |
| 333 MIBundleBuilder(*BalTgtMBB, Pos) |
| 334 .append(BuildMI(*MF, DL, TII->get(Mips::JR)).addReg(Mips::AT)) |
| 335 .append(BuildMI(*MF, DL, TII->get(Mips::NOP))); |
| 336 |
| 337 // Align target of JR instruction. |
| 338 TgtMBB->setAlignment(4); |
| 339 // @LOCALMOD-END |
| 340 } else { |
| 341 MIBundleBuilder(*LongBrMBB, Pos) |
| 342 .append(BuildMI(*MF, DL, TII->get(Mips::BAL_BR)).addMBB(BalTgtMBB)) |
| 343 .append(BuildMI(*MF, DL, TII->get(Mips::LUi), Mips::AT).addImm(Hi)); |
| 344 |
| 345 Pos = BalTgtMBB->begin(); |
| 346 |
| 347 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::ADDiu), Mips::AT) |
| 348 .addReg(Mips::AT).addImm(Lo); |
| 349 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::ADDu), Mips::AT) |
| 350 .addReg(Mips::RA).addReg(Mips::AT); |
| 351 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::LW), Mips::RA) |
| 352 .addReg(Mips::SP).addImm(0); |
| 353 |
| 354 MIBundleBuilder(*BalTgtMBB, Pos) |
| 355 .append(BuildMI(*MF, DL, TII->get(Mips::JR)).addReg(Mips::AT)) |
| 356 .append(BuildMI(*MF, DL, TII->get(Mips::ADDiu), Mips::SP) |
| 357 .addReg(Mips::SP).addImm(8)); |
| 358 } |
310 } else { | 359 } else { |
311 // $longbr: | 360 // $longbr: |
312 // daddiu $sp, $sp, -16 | 361 // daddiu $sp, $sp, -16 |
313 // sd $ra, 0($sp) | 362 // sd $ra, 0($sp) |
314 // lui64 $at, %highest($tgt - $baltgt) | 363 // lui64 $at, %highest($tgt - $baltgt) |
315 // daddiu $at, $at, %higher($tgt - $baltgt) | 364 // daddiu $at, $at, %higher($tgt - $baltgt) |
316 // dsll $at, $at, 16 | 365 // dsll $at, $at, 16 |
317 // daddiu $at, $at, %hi($tgt - $baltgt) | 366 // daddiu $at, $at, %hi($tgt - $baltgt) |
318 // bal $baltgt | 367 // bal $baltgt |
319 // dsll $at, $at, 16 | 368 // dsll $at, $at, 16 |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
423 while (MadeChange) { | 472 while (MadeChange) { |
424 MadeChange = false; | 473 MadeChange = false; |
425 | 474 |
426 for (I = MBBInfos.begin(); I != E; ++I) { | 475 for (I = MBBInfos.begin(); I != E; ++I) { |
427 // Skip if this MBB doesn't have a branch or the branch has already been | 476 // Skip if this MBB doesn't have a branch or the branch has already been |
428 // converted to a long branch. | 477 // converted to a long branch. |
429 if (!I->Br || I->HasLongBranch) | 478 if (!I->Br || I->HasLongBranch) |
430 continue; | 479 continue; |
431 | 480 |
432 // Check if offset fits into 16-bit immediate field of branches. | 481 // Check if offset fits into 16-bit immediate field of branches. |
433 if (!ForceLongBranch && isInt<16>(computeOffset(I->Br) / 4)) | 482 if (Triple(TM.getTargetTriple()).isOSNaCl()) { |
434 continue; | 483 // @LOCALMOD-START |
| 484 int64_t Offset = computeOffset(I->Br) / 4; |
| 485 |
| 486 // This offset calculation does not include sandboxing instructions |
| 487 // that will be added later in the MC layer. Since at this point we |
| 488 // don't know the exact amount of code that "sanboxing" will add, we |
| 489 // conservatively estimate that code will not grow more than 100%. |
| 490 Offset *= 2; |
| 491 |
| 492 if (!ForceLongBranch && isInt<16>(Offset)) |
| 493 continue; |
| 494 // @LOCALMOD-END |
| 495 } else { |
| 496 if (!ForceLongBranch && isInt<16>(computeOffset(I->Br) / 4)) |
| 497 continue; |
| 498 } |
435 | 499 |
436 I->HasLongBranch = true; | 500 I->HasLongBranch = true; |
437 I->Size += LongBranchSeqSize * 4; | 501 I->Size += LongBranchSeqSize * 4; |
438 ++LongBranches; | 502 ++LongBranches; |
439 EverMadeChange = MadeChange = true; | 503 EverMadeChange = MadeChange = true; |
440 } | 504 } |
441 } | 505 } |
442 | 506 |
443 if (!EverMadeChange) | 507 if (!EverMadeChange) |
444 return true; | 508 return true; |
445 | 509 |
446 // Compute basic block addresses. | 510 // Compute basic block addresses. |
447 if (TM.getRelocationModel() == Reloc::PIC_) { | 511 if (TM.getRelocationModel() == Reloc::PIC_) { |
448 uint64_t Address = 0; | 512 uint64_t Address = 0; |
449 | 513 |
450 for (I = MBBInfos.begin(); I != E; Address += I->Size, ++I) | 514 for (I = MBBInfos.begin(); I != E; Address += I->Size, ++I) |
451 I->Address = Address; | 515 I->Address = Address; |
452 } | 516 } |
453 | 517 |
454 // Do the expansion. | 518 // Do the expansion. |
455 for (I = MBBInfos.begin(); I != E; ++I) | 519 for (I = MBBInfos.begin(); I != E; ++I) |
456 if (I->HasLongBranch) | 520 if (I->HasLongBranch) |
457 expandToLongBranch(*I); | 521 expandToLongBranch(*I); |
458 | 522 |
459 MF->RenumberBlocks(); | 523 MF->RenumberBlocks(); |
460 | 524 |
461 return true; | 525 return true; |
462 } | 526 } |
OLD | NEW |