Chromium Code Reviews| Index: lib/Target/Mips/MipsLongBranch.cpp |
| diff --git a/lib/Target/Mips/MipsLongBranch.cpp b/lib/Target/Mips/MipsLongBranch.cpp |
| index 24b42b9150447a9da5925368352fe8c3e9e0dbdb..16c546417724601060aea3992ccfca5b9a97297d 100644 |
| --- a/lib/Target/Mips/MipsLongBranch.cpp |
| +++ b/lib/Target/Mips/MipsLongBranch.cpp |
| @@ -68,7 +68,8 @@ namespace { |
| TII(static_cast<const MipsInstrInfo*>(tm.getInstrInfo())), |
| IsPIC(TM.getRelocationModel() == Reloc::PIC_), |
| ABI(TM.getSubtarget<MipsSubtarget>().getTargetABI()), |
| - LongBranchSeqSize(!IsPIC ? 2 : (ABI == MipsSubtarget::N64 ? 13 : 9)) {} |
| + LongBranchSeqSize(!IsPIC ? 2 : (ABI == MipsSubtarget::N64 ? 13 : |
| + (/*@LOCALMOD*/Triple(TM.getTargetTriple()).isOSNaCl() ? 10 : 9))) {} |
| virtual const char *getPassName() const { |
| return "Mips Long Branch"; |
| @@ -263,7 +264,9 @@ void MipsLongBranch::expandToLongBranch(MBBInfo &I) { |
| BalTgtMBB->addSuccessor(TgtMBB); |
| int64_t TgtAddress = MBBInfos[TgtMBB->getNumber()].Address; |
| - unsigned BalTgtMBBSize = 5; |
| + // @LOCALMOD-START |
| + unsigned BalTgtMBBSize = Triple(TM.getTargetTriple()).isOSNaCl() ? 6 : 5; |
| + // @LOCALMOD-END |
| int64_t Offset = TgtAddress - (I.Address + I.Size - BalTgtMBBSize * 4); |
| int64_t Lo = SignExtend64<16>(Offset & 0xffff); |
| int64_t Hi = SignExtend64<16>(((Offset + 0x8000) >> 16) & 0xffff); |
| @@ -290,23 +293,57 @@ void MipsLongBranch::expandToLongBranch(MBBInfo &I) { |
| BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::SW)).addReg(Mips::RA) |
| .addReg(Mips::SP).addImm(0); |
| - MIBundleBuilder(*LongBrMBB, Pos) |
| - .append(BuildMI(*MF, DL, TII->get(Mips::BAL_BR)).addMBB(BalTgtMBB)) |
| - .append(BuildMI(*MF, DL, TII->get(Mips::LUi), Mips::AT).addImm(Hi)); |
| - |
| - Pos = BalTgtMBB->begin(); |
| - |
| - BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::ADDiu), Mips::AT) |
| - .addReg(Mips::AT).addImm(Lo); |
| - BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::ADDu), Mips::AT) |
| - .addReg(Mips::RA).addReg(Mips::AT); |
| - BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::LW), Mips::RA) |
| - .addReg(Mips::SP).addImm(0); |
| - |
| - MIBundleBuilder(*BalTgtMBB, Pos) |
| - .append(BuildMI(*MF, DL, TII->get(Mips::JR)).addReg(Mips::AT)) |
| - .append(BuildMI(*MF, DL, TII->get(Mips::ADDiu), Mips::SP) |
| - .addReg(Mips::SP).addImm(8)); |
| + if (Triple(TM.getTargetTriple()).isOSNaCl()) { |
| + // @LOCALMOD-START |
| + // We cannot use immediate value in LUi and ADDiu instructions below |
| + // which create 32-bit offset of the target basic block from the BAL |
| + // target because it does not take sandboxed instructions into account |
| + // (sanboxing is run after this pass). We therefore replace it with |
|
Mark Seaborn
2013/10/24 23:38:43
"sandboxing"
petarj
2013/11/21 18:23:42
Done.
|
| + // basic block operand which is resolved during fixup. |
| + MIBundleBuilder(*LongBrMBB, Pos) |
| + .append(BuildMI(*MF, DL, TII->get(Mips::BAL_BR)).addMBB(BalTgtMBB)) |
| + .append(BuildMI(*MF, DL, TII->get(Mips::LUi), Mips::AT) |
| + .addMBB(TgtMBB, MipsII::MO_NACL_LONG_BRANCH_HI16)); |
| + |
| + Pos = BalTgtMBB->begin(); |
| + |
| + BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::ADDiu), Mips::AT) |
| + .addReg(Mips::AT).addMBB(TgtMBB, MipsII::MO_NACL_LONG_BRANCH_LO16); |
| + BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::ADDu), Mips::AT) |
| + .addReg(Mips::RA).addReg(Mips::AT); |
| + BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::LW), Mips::RA) |
| + .addReg(Mips::SP).addImm(0); |
| + |
| + // In NaCl, modifying sp is not allowed in branch delay slot. |
| + BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::ADDiu), Mips::SP) |
| + .addReg(Mips::SP).addImm(8); |
| + |
| + MIBundleBuilder(*BalTgtMBB, Pos) |
| + .append(BuildMI(*MF, DL, TII->get(Mips::JR)).addReg(Mips::AT)) |
| + .append(BuildMI(*MF, DL, TII->get(Mips::NOP))); |
| + |
| + // Align target of JR instruction. |
| + TgtMBB->setAlignment(4); |
| + // @LOCALMOD-END |
| + } else { |
| + MIBundleBuilder(*LongBrMBB, Pos) |
| + .append(BuildMI(*MF, DL, TII->get(Mips::BAL_BR)).addMBB(BalTgtMBB)) |
| + .append(BuildMI(*MF, DL, TII->get(Mips::LUi), Mips::AT).addImm(Hi)); |
| + |
| + Pos = BalTgtMBB->begin(); |
| + |
| + BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::ADDiu), Mips::AT) |
| + .addReg(Mips::AT).addImm(Lo); |
| + BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::ADDu), Mips::AT) |
| + .addReg(Mips::RA).addReg(Mips::AT); |
| + BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::LW), Mips::RA) |
| + .addReg(Mips::SP).addImm(0); |
| + |
| + MIBundleBuilder(*BalTgtMBB, Pos) |
| + .append(BuildMI(*MF, DL, TII->get(Mips::JR)).addReg(Mips::AT)) |
| + .append(BuildMI(*MF, DL, TII->get(Mips::ADDiu), Mips::SP) |
| + .addReg(Mips::SP).addImm(8)); |
| + } |
| } else { |
| // $longbr: |
| // daddiu $sp, $sp, -16 |
| @@ -430,8 +467,23 @@ bool MipsLongBranch::runOnMachineFunction(MachineFunction &F) { |
| continue; |
| // Check if offset fits into 16-bit immediate field of branches. |
| - if (!ForceLongBranch && isInt<16>(computeOffset(I->Br) / 4)) |
| - continue; |
| + if (Triple(TM.getTargetTriple()).isOSNaCl()) { |
| + // @LOCALMOD-START |
| + int64_t Offset = computeOffset(I->Br) / 4; |
| + |
| + // This offset calculation does not include sandboxing instructions |
| + // that will be added later. Since at this point we dont know the |
|
Mark Seaborn
2013/10/24 23:38:43
"don't". Maybe "added later in the MC layer" (whi
petarj
2013/11/21 18:23:42
Done.
|
| + // exact amount of code that sanboxing will add, we conservatively |
|
Mark Seaborn
2013/10/24 23:38:43
"sandboxing"
petarj
2013/11/21 18:23:42
Done.
|
| + // estimate that code will not grow more than 100%. |
| + Offset *= 2; |
| + |
| + if (!ForceLongBranch && isInt<16>(Offset)) |
| + continue; |
| + // @LOCALMOD-END |
| + } else { |
| + if (!ForceLongBranch && isInt<16>(computeOffset(I->Br) / 4)) |
| + continue; |
| + } |
| I->HasLongBranch = true; |
| I->Size += LongBranchSeqSize * 4; |