| 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;
 | 
| 
 |