mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 11:13:28 +01:00
[WinEH] Fix establisher param reg in CLR funclets
Summary: The CLR's personality routine passes the pointer to the establisher frame in RCX, not RDX. Reviewers: pgavlin, majnemer, rnk Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D14343 llvm-svn: 252135
This commit is contained in:
parent
8cb5aa0766
commit
44ef00af57
@ -18,6 +18,7 @@
|
|||||||
#include "X86Subtarget.h"
|
#include "X86Subtarget.h"
|
||||||
#include "X86TargetMachine.h"
|
#include "X86TargetMachine.h"
|
||||||
#include "llvm/ADT/SmallSet.h"
|
#include "llvm/ADT/SmallSet.h"
|
||||||
|
#include "llvm/Analysis/LibCallSemantics.h"
|
||||||
#include "llvm/CodeGen/MachineFrameInfo.h"
|
#include "llvm/CodeGen/MachineFrameInfo.h"
|
||||||
#include "llvm/CodeGen/MachineFunction.h"
|
#include "llvm/CodeGen/MachineFunction.h"
|
||||||
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
||||||
@ -624,6 +625,9 @@ void X86FrameLowering::emitPrologue(MachineFunction &MF,
|
|||||||
uint64_t MaxAlign = calculateMaxStackAlign(MF); // Desired stack alignment.
|
uint64_t MaxAlign = calculateMaxStackAlign(MF); // Desired stack alignment.
|
||||||
uint64_t StackSize = MFI->getStackSize(); // Number of bytes to allocate.
|
uint64_t StackSize = MFI->getStackSize(); // Number of bytes to allocate.
|
||||||
bool IsFunclet = MBB.isEHFuncletEntry();
|
bool IsFunclet = MBB.isEHFuncletEntry();
|
||||||
|
bool IsClrFunclet =
|
||||||
|
IsFunclet &&
|
||||||
|
classifyEHPersonality(Fn->getPersonalityFn()) == EHPersonality::CoreCLR;
|
||||||
bool HasFP = hasFP(MF);
|
bool HasFP = hasFP(MF);
|
||||||
bool IsWin64CC = STI.isCallingConvWin64(Fn->getCallingConv());
|
bool IsWin64CC = STI.isCallingConvWin64(Fn->getCallingConv());
|
||||||
bool IsWin64Prologue = MF.getTarget().getMCAsmInfo()->usesWindowsCFI();
|
bool IsWin64Prologue = MF.getTarget().getMCAsmInfo()->usesWindowsCFI();
|
||||||
@ -701,13 +705,20 @@ void X86FrameLowering::emitPrologue(MachineFunction &MF,
|
|||||||
uint64_t NumBytes = 0;
|
uint64_t NumBytes = 0;
|
||||||
int stackGrowth = -SlotSize;
|
int stackGrowth = -SlotSize;
|
||||||
|
|
||||||
unsigned RDX = Uses64BitFramePtr ? X86::RDX : X86::EDX;
|
// Find the funclet establisher parameter
|
||||||
if (IsWin64Prologue && IsFunclet) {
|
unsigned Establisher = X86::NoRegister;
|
||||||
// Immediately spill RDX into the home slot. The runtime cares about this.
|
if (IsClrFunclet)
|
||||||
|
Establisher = Uses64BitFramePtr ? X86::RCX : X86::ECX;
|
||||||
|
else if (IsFunclet)
|
||||||
|
Establisher = Uses64BitFramePtr ? X86::RDX : X86::EDX;
|
||||||
|
|
||||||
|
if (IsWin64Prologue && IsFunclet & !IsClrFunclet) {
|
||||||
|
// Immediately spill establisher into the home slot.
|
||||||
|
// The runtime cares about this.
|
||||||
// MOV64mr %rdx, 16(%rsp)
|
// MOV64mr %rdx, 16(%rsp)
|
||||||
unsigned MOVmr = Uses64BitFramePtr ? X86::MOV64mr : X86::MOV32mr;
|
unsigned MOVmr = Uses64BitFramePtr ? X86::MOV64mr : X86::MOV32mr;
|
||||||
addRegOffset(BuildMI(MBB, MBBI, DL, TII.get(MOVmr)), StackPtr, true, 16)
|
addRegOffset(BuildMI(MBB, MBBI, DL, TII.get(MOVmr)), StackPtr, true, 16)
|
||||||
.addReg(RDX)
|
.addReg(Establisher)
|
||||||
.setMIFlag(MachineInstr::FrameSetup);
|
.setMIFlag(MachineInstr::FrameSetup);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -911,16 +922,16 @@ void X86FrameLowering::emitPrologue(MachineFunction &MF,
|
|||||||
int SEHFrameOffset = 0;
|
int SEHFrameOffset = 0;
|
||||||
if (IsWin64Prologue && HasFP) {
|
if (IsWin64Prologue && HasFP) {
|
||||||
// Set RBP to a small fixed offset from RSP. In the funclet case, we base
|
// Set RBP to a small fixed offset from RSP. In the funclet case, we base
|
||||||
// this calculation on the incoming RDX, which holds the value of RSP from
|
// this calculation on the incoming establisher, which holds the value of
|
||||||
// the parent frame at the end of the prologue.
|
// RSP from the parent frame at the end of the prologue.
|
||||||
unsigned SPOrRDX = !IsFunclet ? StackPtr : RDX;
|
unsigned SPOrEstablisher = IsFunclet ? Establisher : StackPtr;
|
||||||
SEHFrameOffset = calculateSetFPREG(ParentFrameNumBytes);
|
SEHFrameOffset = calculateSetFPREG(ParentFrameNumBytes);
|
||||||
if (SEHFrameOffset)
|
if (SEHFrameOffset)
|
||||||
addRegOffset(BuildMI(MBB, MBBI, DL, TII.get(X86::LEA64r), FramePtr),
|
addRegOffset(BuildMI(MBB, MBBI, DL, TII.get(X86::LEA64r), FramePtr),
|
||||||
SPOrRDX, false, SEHFrameOffset);
|
SPOrEstablisher, false, SEHFrameOffset);
|
||||||
else
|
else
|
||||||
BuildMI(MBB, MBBI, DL, TII.get(X86::MOV64rr), FramePtr)
|
BuildMI(MBB, MBBI, DL, TII.get(X86::MOV64rr), FramePtr)
|
||||||
.addReg(SPOrRDX);
|
.addReg(SPOrEstablisher);
|
||||||
|
|
||||||
// If this is not a funclet, emit the CFI describing our frame pointer.
|
// If this is not a funclet, emit the CFI describing our frame pointer.
|
||||||
if (NeedsWinCFI && !IsFunclet)
|
if (NeedsWinCFI && !IsFunclet)
|
||||||
|
@ -50,6 +50,8 @@ catch1.pad:
|
|||||||
%catch1 = catchpad [i32 1]
|
%catch1 = catchpad [i32 1]
|
||||||
to label %catch1.body unwind label %catch2.pad
|
to label %catch1.body unwind label %catch2.pad
|
||||||
catch1.body:
|
catch1.body:
|
||||||
|
; CHECK: leaq {{[0-9]+}}(%rcx), %rbp
|
||||||
|
; ^ establisher frame pointer passed in rcx
|
||||||
; CHECK: .seh_endprologue
|
; CHECK: .seh_endprologue
|
||||||
; CHECK: [[L_before_f3:.+]]:
|
; CHECK: [[L_before_f3:.+]]:
|
||||||
; CHECK-NEXT: movl $3, %ecx
|
; CHECK-NEXT: movl $3, %ecx
|
||||||
@ -64,6 +66,8 @@ catch2.pad:
|
|||||||
%catch2 = catchpad [i32 2]
|
%catch2 = catchpad [i32 2]
|
||||||
to label %catch2.body unwind label %catch.end
|
to label %catch2.body unwind label %catch.end
|
||||||
catch2.body:
|
catch2.body:
|
||||||
|
; CHECK: leaq {{[0-9]+}}(%rcx), %rbp
|
||||||
|
; ^ establisher frame pointer passed in rcx
|
||||||
; CHECK: .seh_endprologue
|
; CHECK: .seh_endprologue
|
||||||
; CHECK: [[L_before_f4:.+]]:
|
; CHECK: [[L_before_f4:.+]]:
|
||||||
; CHECK-NEXT: movl $4, %ecx
|
; CHECK-NEXT: movl $4, %ecx
|
||||||
@ -82,6 +86,8 @@ try_in_catch:
|
|||||||
fault.pad:
|
fault.pad:
|
||||||
; CHECK: .seh_proc [[L_fault:[^ ]+]]
|
; CHECK: .seh_proc [[L_fault:[^ ]+]]
|
||||||
%fault = cleanuppad [i32 undef]
|
%fault = cleanuppad [i32 undef]
|
||||||
|
; CHECK: leaq {{[0-9]+}}(%rcx), %rbp
|
||||||
|
; ^ establisher frame pointer passed in rcx
|
||||||
; CHECK: .seh_endprologue
|
; CHECK: .seh_endprologue
|
||||||
; CHECK: [[L_before_f6:.+]]:
|
; CHECK: [[L_before_f6:.+]]:
|
||||||
; CHECK-NEXT: movl $6, %ecx
|
; CHECK-NEXT: movl $6, %ecx
|
||||||
@ -103,6 +109,8 @@ finally.clone:
|
|||||||
finally.pad:
|
finally.pad:
|
||||||
; CHECK: .seh_proc [[L_finally:[^ ]+]]
|
; CHECK: .seh_proc [[L_finally:[^ ]+]]
|
||||||
%finally = cleanuppad []
|
%finally = cleanuppad []
|
||||||
|
; CHECK: leaq {{[0-9]+}}(%rcx), %rbp
|
||||||
|
; ^ establisher frame pointer passed in rcx
|
||||||
; CHECK: .seh_endprologue
|
; CHECK: .seh_endprologue
|
||||||
; CHECK: [[L_before_f7:.+]]:
|
; CHECK: [[L_before_f7:.+]]:
|
||||||
; CHECK-NEXT: movl $7, %ecx
|
; CHECK-NEXT: movl $7, %ecx
|
||||||
|
Loading…
Reference in New Issue
Block a user