| Index: lib/Target/Mips/MipsLongBranch.cpp
|
| diff --git a/lib/Target/Mips/MipsLongBranch.cpp b/lib/Target/Mips/MipsLongBranch.cpp
|
| index 24b42b9150447a9da5925368352fe8c3e9e0dbdb..e8fe1214bb0273a9272aa5a9eeeff39b141e24d0 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,69 @@ 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
|
| + // LUi and ADDiu instructions create 32-bit offset of the target basic
|
| + // block from the BAL target. We cannot use immediate value as the
|
| + // offset (as non-NaCl version does) because it does not take
|
| + // sandboxed instructions into account ("sanboxing" is run after this
|
| + // pass). We therefore replace it with relocation expressions
|
| + // %hi($tgt-$baltgt) and %lo($tgt-$baltgt). This expressions are
|
| + // resolved during the fixup after all sandboxing code is added, so the
|
| + // values will always be correct.
|
| + //
|
| + // Since we cannot create %hi($tgt-$baltgt) and %lo($tgt-$baltgt)
|
| + // expressions at this point (it is possible only at the MC layer),
|
| + // we replace LUi and ADDiu with pseudo instructions
|
| + // NACL_LONG_BRANCH_LUi and NACL_LONG_BRANCH_ADDiu, and add both basic
|
| + // block as operands to these instructions. When lowering these pseudo
|
| + // instructions to LUi and ADDiu in the MC layer, we will create
|
| + // %hi($tgt-$baltgt) and %lo($tgt-$baltgt) expressions add add them as
|
| + // operands to lowered instructions.
|
| + MIBundleBuilder(*LongBrMBB, Pos)
|
| + .append(BuildMI(*MF, DL, TII->get(Mips::BAL_BR)).addMBB(BalTgtMBB))
|
| + .append(BuildMI(*MF, DL, TII->get(Mips::NACL_LONG_BRANCH_LUi),
|
| + Mips::AT).addMBB(TgtMBB).addMBB(BalTgtMBB));
|
| +
|
| + Pos = BalTgtMBB->begin();
|
| +
|
| + BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::NACL_LONG_BRANCH_ADDiu),
|
| + Mips::AT).addReg(Mips::AT).addMBB(TgtMBB).addMBB(BalTgtMBB);
|
| + 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 +479,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 in the MC layer. Since at this point we
|
| + // don't 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;
|
|
|