mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-28 22:20:37 +00:00
[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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@210262 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
44215458bd
commit
2181b2319e
@ -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;
|
||||
|
@ -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
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user