mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-14 11:32:34 +00:00
X86, Win64: Allow 'mov' to restore the stack pointer if we have a FP
The Win64 epilogue structure is very restrictive, it permits a very small number of opcodes and none of them are 'mov'. This means that given: mov %rbp, %rsp pop %rbp The mov isn't the epilogue, only the pop is. This is problematic unless a frame pointer is present in which case we are free to do whatever we'd like in the "body" of the function. If a frame pointer is present, unwinding will undo the prologue operations in reverse order regardless of the fact that we are at an instruction which is reseting the stack pointer. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@230543 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
dd51ad933e
commit
92d1637e2f
@ -1074,21 +1074,20 @@ void X86FrameLowering::emitEpilogue(MachineFunction &MF,
|
||||
if (RegInfo->needsStackRealignment(MF) || MFI->hasVarSizedObjects()) {
|
||||
if (RegInfo->needsStackRealignment(MF))
|
||||
MBBI = FirstCSPop;
|
||||
if (IsWinEH) {
|
||||
// There are only two legal forms of epilogue:
|
||||
// - add SEHAllocationSize, %rsp
|
||||
// - lea SEHAllocationSize(%FramePtr), %rsp
|
||||
//
|
||||
// We are *not* permitted to use 'mov %FramePtr, %rsp' because the Win64
|
||||
// unwinder will not recognize 'mov' as an epilogue instruction.
|
||||
unsigned SEHFrameOffset = calculateSetFPREG(SEHStackAllocAmt);
|
||||
addRegOffset(BuildMI(MBB, MBBI, DL, TII.get(X86::LEA64r), StackPtr),
|
||||
FramePtr, false, SEHStackAllocAmt - SEHFrameOffset);
|
||||
--MBBI;
|
||||
} else if (CSSize != 0) {
|
||||
unsigned SEHFrameOffset = calculateSetFPREG(SEHStackAllocAmt);
|
||||
uint64_t LEAAmount = IsWinEH ? SEHStackAllocAmt - SEHFrameOffset : -CSSize;
|
||||
|
||||
// There are only two legal forms of epilogue:
|
||||
// - add SEHAllocationSize, %rsp
|
||||
// - lea SEHAllocationSize(%FramePtr), %rsp
|
||||
//
|
||||
// 'mov %FramePtr, %rsp' will not be recognized as an epilogue sequence.
|
||||
// However, we may use this sequence if we have a frame pointer because the
|
||||
// effects of the prologue can safely be undone.
|
||||
if (LEAAmount != 0) {
|
||||
unsigned Opc = getLEArOpcode(Uses64BitFramePtr);
|
||||
addRegOffset(BuildMI(MBB, MBBI, DL, TII.get(Opc), StackPtr),
|
||||
FramePtr, false, -CSSize);
|
||||
FramePtr, false, LEAAmount);
|
||||
--MBBI;
|
||||
} else {
|
||||
unsigned Opc = (Uses64BitFramePtr ? X86::MOV64rr : X86::MOV32rr);
|
||||
|
@ -167,7 +167,7 @@ entry:
|
||||
; WIN64: andq $-64, %rsp
|
||||
; WIN64: movaps -32(%rbp), %xmm6 # 16-byte Reload
|
||||
; WIN64: movaps -16(%rbp), %xmm7 # 16-byte Reload
|
||||
; WIN64: leaq (%rbp), %rsp
|
||||
; WIN64: movq %rbp, %rsp
|
||||
; WIN64: popq %rbx
|
||||
; WIN64: popq %rdi
|
||||
; WIN64: popq %rbp
|
||||
|
Loading…
Reference in New Issue
Block a user