Index: lib/Target/Mips/MipsLongBranch.cpp |
diff --git a/lib/Target/Mips/MipsLongBranch.cpp b/lib/Target/Mips/MipsLongBranch.cpp |
index 24b42b9150447a9da5925368352fe8c3e9e0dbdb..6e1da627a8d4fb390a507b6d678507f2e5015219 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 |
+ // 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)); |
+ |
+ Pos = BalTgtMBB->begin(); |
+ |
+ BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::ADDiu), Mips::AT) |
+ .addReg(Mips::AT).addMBB(TgtMBB, MipsII::MO_NACL_LONG_BRANCH); |
+ 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 PNaCl, modifying sp is not allowed in branch delay slot. |
Mark Seaborn
2013/10/17 19:00:11
Nit: really "NaCl" here; PNaCl does not implement
petarj
2013/10/22 23:10:27
Done.
|
+ 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 |
+ // exact amount of code that sanboxing will add, we conservatively |
+ // 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; |