Index: lib/Target/X86/X86FrameLowering.cpp |
diff --git a/lib/Target/X86/X86FrameLowering.cpp b/lib/Target/X86/X86FrameLowering.cpp |
index f8ada8db29287068890f590e75ce7ce5969d774d..6502987257f3329837d845ccfdb7348d28bc3c79 100644 |
--- a/lib/Target/X86/X86FrameLowering.cpp |
+++ b/lib/Target/X86/X86FrameLowering.cpp |
@@ -15,6 +15,7 @@ |
#include "X86InstrBuilder.h" |
#include "X86InstrInfo.h" |
#include "X86MachineFunctionInfo.h" |
+#include "X86NaClDecls.h" // @LOCALMOD |
#include "X86Subtarget.h" |
#include "X86TargetMachine.h" |
#include "llvm/ADT/SmallSet.h" |
@@ -130,6 +131,7 @@ static unsigned findDeadCallerSavedReg(MachineBasicBlock &MBB, |
case X86::TCRETURNmi: |
case X86::TCRETURNdi64: |
case X86::TCRETURNri64: |
+ case X86::NACL_CG_TCRETURNdi64: // @LOCALMOD |
case X86::TCRETURNmi64: |
case X86::EH_RETURN: |
case X86::EH_RETURN64: { |
@@ -585,8 +587,49 @@ void X86FrameLowering::emitPrologue(MachineFunction &MF) const { |
MFI->setOffsetAdjustment(-NumBytes); |
// Save EBP/RBP into the appropriate stack slot. |
+ // @LOCALMOD-BEGIN |
+ unsigned RegToPush = MachineFramePtr; |
+ const bool HideSandboxBase = (FlagHideSandboxBase && |
+ STI.isTargetNaCl64() && |
+ !FlagUseZeroBasedSandbox); |
+ if (HideSandboxBase) { |
+ // Hide the sandbox base address by masking off the upper 32 |
+ // bits of the pushed/saved RBP on the stack, using: |
+ // mov %ebp, %r10d |
+ // push %r10 |
+ // instead of: |
+ // push %rbp |
+ // Additionally, we can use rax instead of r10 when it is not a |
+ // varargs function and therefore rax is available, saving one |
+ // byte of REX prefix per instruction. |
+ // Note that the epilog already adds R15 when restoring RBP. |
+ |
+ // mov %ebp, %r10d |
+ if (Fn->isVarArg()) { |
+ // Note: This use of r10 in the prolog can't be used with the |
+ // gcc "nest" attribute, due to its use of r10. Example: |
+ // target triple = "x86_64-pc-linux-gnu" |
+ // define i64 @func(i64 nest %arg) { |
+ // ret i64 %arg |
+ // } |
+ // |
+ // $ clang -m64 llvm_nest_attr.ll -S -o - |
+ // ... |
+ // func: |
+ // movq %r10, %rax |
+ // ret |
+ RegToPush = X86::R10; |
+ } else { |
+ RegToPush = X86::RAX; |
+ } |
+ BuildMI(MBB, MBBI, DL, TII.get(X86::MOV32rr), |
+ getX86SubSuperRegister(RegToPush, MVT::i32, false)) |
+ .addReg(getX86SubSuperRegister(FramePtr, MVT::i32, false)) |
+ .setMIFlag(MachineInstr::FrameSetup); |
+ } |
+ // @LOCALMOD-END |
BuildMI(MBB, MBBI, DL, TII.get(Is64Bit ? X86::PUSH64r : X86::PUSH32r)) |
- .addReg(MachineFramePtr, RegState::Kill) |
+ .addReg(RegToPush, RegState::Kill) // @LOCALMOD |
.setMIFlag(MachineInstr::FrameSetup); |
if (NeedsDwarfCFI) { |
@@ -900,6 +943,7 @@ void X86FrameLowering::emitEpilogue(MachineFunction &MF, |
case X86::TCRETURNdi64: |
case X86::TCRETURNri64: |
case X86::TCRETURNmi64: |
+ case X86::NACL_CG_TCRETURNdi64: // @LOCALMOD |
case X86::EH_RETURN: |
case X86::EH_RETURN64: |
break; // These are ok |
@@ -1005,6 +1049,7 @@ void X86FrameLowering::emitEpilogue(MachineFunction &MF, |
} else if (RetOpcode == X86::TCRETURNri || RetOpcode == X86::TCRETURNdi || |
RetOpcode == X86::TCRETURNmi || |
RetOpcode == X86::TCRETURNri64 || RetOpcode == X86::TCRETURNdi64 || |
+ RetOpcode == X86::NACL_CG_TCRETURNdi64 || // @LOCALMOD |
RetOpcode == X86::TCRETURNmi64) { |
bool isMem = RetOpcode == X86::TCRETURNmi || RetOpcode == X86::TCRETURNmi64; |
// Tail call return: adjust the stack pointer and jump to callee. |
@@ -1031,10 +1076,22 @@ void X86FrameLowering::emitEpilogue(MachineFunction &MF, |
} |
// Jump to label or value in register. |
- if (RetOpcode == X86::TCRETURNdi || RetOpcode == X86::TCRETURNdi64) { |
+ if (RetOpcode == X86::TCRETURNdi || RetOpcode == X86::TCRETURNdi64 || |
+ RetOpcode == X86::NACL_CG_TCRETURNdi64) { // @LOCALMOD |
+ // @LOCALMOD-BEGIN |
+ unsigned TailJmpOpc; |
+ switch (RetOpcode) { |
+ case X86::TCRETURNdi : TailJmpOpc = X86::TAILJMPd; break; |
+ case X86::TCRETURNdi64: TailJmpOpc = X86::TAILJMPd64; break; |
+ case X86::NACL_CG_TCRETURNdi64: |
+ TailJmpOpc = X86::NACL_CG_TAILJMPd64; |
+ break; |
+ default: llvm_unreachable("Unexpected return opcode"); |
+ } |
+ // @LOCALMOD-END |
MachineInstrBuilder MIB = |
- BuildMI(MBB, MBBI, DL, TII.get((RetOpcode == X86::TCRETURNdi) |
- ? X86::TAILJMPd : X86::TAILJMPd64)); |
+ BuildMI(MBB, MBBI, DL, TII.get(TailJmpOpc)); // @LOCALMOD |
+ |
if (JumpTarget.isGlobal()) |
MIB.addGlobalAddress(JumpTarget.getGlobal(), JumpTarget.getOffset(), |
JumpTarget.getTargetFlags()); |
@@ -1800,7 +1857,11 @@ eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, |
int Opcode = I->getOpcode(); |
bool isDestroy = Opcode == TII.getCallFrameDestroyOpcode(); |
const X86Subtarget &STI = MF.getTarget().getSubtarget<X86Subtarget>(); |
- bool IsLP64 = STI.isTarget64BitLP64(); |
+ // @LOCALMOD-BEGIN |
+ // standard x86_64 and NaCl use 64-bit frame/stack pointers, x32 - 32-bit. |
+ const bool Uses64BitStackPtr = |
+ STI.isTarget64BitLP64() || STI.isTargetNaCl64(); |
+ // @LOCALMOD-END |
DebugLoc DL = I->getDebugLoc(); |
uint64_t Amount = !reseveCallFrame ? I->getOperand(0).getImm() : 0; |
uint64_t CalleeAmt = isDestroy ? I->getOperand(1).getImm() : 0; |
@@ -1825,7 +1886,8 @@ eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, |
MachineInstr *New = nullptr; |
if (Opcode == TII.getCallFrameSetupOpcode()) { |
- New = BuildMI(MF, DL, TII.get(getSUBriOpcode(IsLP64, Amount)), |
+ // @LOCALMOD |
+ New = BuildMI(MF, DL, TII.get(getSUBriOpcode(Uses64BitStackPtr, Amount)), |
StackPtr) |
.addReg(StackPtr) |
.addImm(Amount); |
@@ -1836,7 +1898,8 @@ eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, |
Amount -= CalleeAmt; |
if (Amount) { |
- unsigned Opc = getADDriOpcode(IsLP64, Amount); |
+ // @LOCALMOD |
+ unsigned Opc = getADDriOpcode(Uses64BitStackPtr, Amount); |
New = BuildMI(MF, DL, TII.get(Opc), StackPtr) |
.addReg(StackPtr).addImm(Amount); |
} |
@@ -1857,7 +1920,8 @@ eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, |
// If we are performing frame pointer elimination and if the callee pops |
// something off the stack pointer, add it back. We do this until we have |
// more advanced stack pointer tracking ability. |
- unsigned Opc = getSUBriOpcode(IsLP64, CalleeAmt); |
+ // @LOCALMOD |
+ unsigned Opc = getSUBriOpcode(Uses64BitStackPtr, CalleeAmt); |
MachineInstr *New = BuildMI(MF, DL, TII.get(Opc), StackPtr) |
.addReg(StackPtr).addImm(CalleeAmt); |
@@ -1873,4 +1937,3 @@ eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, |
MBB.insert(I, New); |
} |
} |
- |