1
0
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:
Joseph Tremoulet 2015-11-05 02:20:07 +00:00
parent 8cb5aa0766
commit 44ef00af57
2 changed files with 28 additions and 9 deletions

View File

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

View File

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