From 67814261305cf58efd7df63bafcb6a65926ebd0c Mon Sep 17 00:00:00 2001 From: Sasa Stankovic Date: Thu, 5 Jun 2014 13:52:08 +0000 Subject: [PATCH] [mips] Modify long branch for NaCl: * Move the instruction that changes sp outside of the branch delay slot. * Bundle-align the target of indirect branch. Differential Revision: http://llvm-reviews.chandlerc.com/D3928 llvm-svn: 210262 --- llvm/lib/Target/Mips/MipsLongBranch.cpp | 36 +++++++++++++++++++++++++++------ llvm/test/CodeGen/Mips/longbranch.ll | 34 +++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+), 6 deletions(-) diff --git a/llvm/lib/Target/Mips/MipsLongBranch.cpp b/llvm/lib/Target/Mips/MipsLongBranch.cpp index acfe76e..e72db15 100644 --- a/llvm/lib/Target/Mips/MipsLongBranch.cpp +++ b/llvm/lib/Target/Mips/MipsLongBranch.cpp @@ -15,6 +15,7 @@ #include "Mips.h" #include "MCTargetDesc/MipsBaseInfo.h" +#include "MCTargetDesc/MipsMCNaCl.h" #include "MipsTargetMachine.h" #include "llvm/ADT/Statistic.h" #include "llvm/CodeGen/MachineFunctionPass.h" @@ -64,7 +65,8 @@ namespace { : MachineFunctionPass(ID), TM(tm), IsPIC(TM.getRelocationModel() == Reloc::PIC_), ABI(TM.getSubtarget().getTargetABI()), - LongBranchSeqSize(!IsPIC ? 2 : (ABI == MipsSubtarget::N64 ? 10 : 9)) {} + LongBranchSeqSize(!IsPIC ? 2 : (ABI == MipsSubtarget::N64 ? 10 : + (!TM.getSubtarget().isTargetNaCl() ? 9 : 10))) {} const char *getPassName() const override { return "Mips Long Branch"; @@ -316,10 +318,23 @@ void MipsLongBranch::expandToLongBranch(MBBInfo &I) { 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 (!TM.getSubtarget().isTargetNaCl()) { + 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 { + // In NaCl, modifying the 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))); + + // Bundle-align the target of indirect branch JR. + TgtMBB->setAlignment(MIPS_NACL_BUNDLE_ALIGN); + } } else { // $longbr: // daddiu $sp, $sp, -16 @@ -450,9 +465,18 @@ bool MipsLongBranch::runOnMachineFunction(MachineFunction &F) { continue; int ShVal = TM.getSubtarget().inMicroMipsMode() ? 2 : 4; + int64_t Offset = computeOffset(I->Br) / ShVal; + + if (TM.getSubtarget().isTargetNaCl()) { + // The 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 "sandboxing" will add, we + // conservatively estimate that code will not grow more than 100%. + Offset *= 2; + } // Check if offset fits into 16-bit immediate field of branches. - if (!ForceLongBranch && isInt<16>(computeOffset(I->Br) / ShVal)) + if (!ForceLongBranch && isInt<16>(Offset)) continue; I->HasLongBranch = true; diff --git a/llvm/test/CodeGen/Mips/longbranch.ll b/llvm/test/CodeGen/Mips/longbranch.ll index c7fe6fd6..a403744c 100644 --- a/llvm/test/CodeGen/Mips/longbranch.ll +++ b/llvm/test/CodeGen/Mips/longbranch.ll @@ -7,6 +7,8 @@ ; RUN: < %s | FileCheck %s -check-prefix=N64 ; RUN: llc -march=mipsel -mcpu=mips32r2 -mattr=micromips \ ; RUN: -force-mips-long-branch -O3 < %s | FileCheck %s -check-prefix=MICROMIPS +; RUN: llc -mtriple=mipsel-none-nacl -force-mips-long-branch -O3 < %s \ +; RUN: | FileCheck %s -check-prefix=NACL @x = external global i32 @@ -126,4 +128,36 @@ end: ; MICROMIPS: $[[BB2]]: ; MICROMIPS: jr $ra ; MICROMIPS: nop + + +; Check the NaCl version. Check that sp change is not in the branch delay slot +; of "jr $1" instruction. Check that target of indirect branch "jr $1" is +; bundle aligned. + +; NACL: lui $[[R0:[0-9]+]], %hi(_gp_disp) +; NACL: addiu $[[R0]], $[[R0]], %lo(_gp_disp) +; NACL: bnez $4, $[[BB0:BB[0-9_]+]] +; NACL: addu $[[GP:[0-9]+]], $[[R0]], $25 + +; Check for long branch expansion: +; NACL: addiu $sp, $sp, -8 +; NACL-NEXT: sw $ra, 0($sp) +; NACL-NEXT: lui $1, %hi(($[[BB2:BB[0-9_]+]])-($[[BB1:BB[0-9_]+]])) +; NACL-NEXT: bal $[[BB1]] +; NACL-NEXT: addiu $1, $1, %lo(($[[BB2]])-($[[BB1]])) +; NACL-NEXT: $[[BB1]]: +; NACL-NEXT: addu $1, $ra, $1 +; NACL-NEXT: lw $ra, 0($sp) +; NACL-NEXT: addiu $sp, $sp, 8 +; NACL-NEXT: jr $1 +; NACL-NEXT: nop + +; NACL: $[[BB0]]: +; NACL: lw $[[R1:[0-9]+]], %got(x)($[[GP]]) +; NACL: addiu $[[R2:[0-9]+]], $zero, 1 +; NACL: sw $[[R2]], 0($[[R1]]) +; NACL: .align 4 +; NACL-NEXT: $[[BB2]]: +; NACL: jr $ra +; NACL: nop } -- 2.7.4