[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
This commit is contained in:
Sasa Stankovic 2014-06-05 13:52:08 +00:00
parent 56c12e679a
commit 6781426130
2 changed files with 64 additions and 6 deletions

View File

@ -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<MipsSubtarget>().getTargetABI()),
LongBranchSeqSize(!IsPIC ? 2 : (ABI == MipsSubtarget::N64 ? 10 : 9)) {}
LongBranchSeqSize(!IsPIC ? 2 : (ABI == MipsSubtarget::N64 ? 10 :
(!TM.getSubtarget<MipsSubtarget>().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<MipsSubtarget>().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<MipsSubtarget>().inMicroMipsMode() ? 2 : 4;
int64_t Offset = computeOffset(I->Br) / ShVal;
if (TM.getSubtarget<MipsSubtarget>().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;

View File

@ -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
}