mirror of
https://github.com/RPCS3/llvm.git
synced 2025-02-10 12:32:21 +00:00
X86: Make @llvm.frameaddress work correctly with Windows unwind codes
Simply loading or storing the frame pointer is not sufficient for Windows targets. Instead, create a synthetic frame object that we will lower later. References to this synthetic object will be replaced with the correct reference to the frame address. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@228748 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
8ffa03cd98
commit
420f72a301
@ -1242,6 +1242,9 @@ int X86FrameLowering::getFrameIndexOffset(const MachineFunction &MF,
|
||||
NumBytes = FrameSize - CSSize;
|
||||
}
|
||||
uint64_t SEHFrameOffset = calculateSetFPREG(NumBytes);
|
||||
if (FI && FI == X86FI->getFAIndex())
|
||||
return -SEHFrameOffset;
|
||||
|
||||
// FPDelta is the offset from the "traditional" FP location of the old base
|
||||
// pointer followed by return address and the location required by the
|
||||
// restricted Win64 prologue.
|
||||
|
@ -17953,15 +17953,33 @@ SDValue X86TargetLowering::LowerRETURNADDR(SDValue Op,
|
||||
}
|
||||
|
||||
SDValue X86TargetLowering::LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const {
|
||||
MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo();
|
||||
MachineFunction &MF = DAG.getMachineFunction();
|
||||
MachineFrameInfo *MFI = MF.getFrameInfo();
|
||||
X86MachineFunctionInfo *FuncInfo = MF.getInfo<X86MachineFunctionInfo>();
|
||||
const X86RegisterInfo *RegInfo = Subtarget->getRegisterInfo();
|
||||
EVT VT = Op.getValueType();
|
||||
|
||||
MFI->setFrameAddressIsTaken(true);
|
||||
|
||||
EVT VT = Op.getValueType();
|
||||
if (MF.getTarget().getMCAsmInfo()->usesWindowsCFI()) {
|
||||
// Depth > 0 makes no sense on targets which use Windows unwind codes. It
|
||||
// is not possible to crawl up the stack without looking at the unwind codes
|
||||
// simultaneously.
|
||||
int FrameAddrIndex = FuncInfo->getFAIndex();
|
||||
if (!FrameAddrIndex) {
|
||||
// Set up a frame object for the return address.
|
||||
unsigned SlotSize = RegInfo->getSlotSize();
|
||||
FrameAddrIndex = MF.getFrameInfo()->CreateFixedObject(
|
||||
SlotSize, /*Offset=*/INT64_MIN, /*IsImmutable=*/false);
|
||||
FuncInfo->setFAIndex(FrameAddrIndex);
|
||||
}
|
||||
return DAG.getFrameIndex(FrameAddrIndex, VT);
|
||||
}
|
||||
|
||||
unsigned FrameReg =
|
||||
RegInfo->getPtrSizedFrameRegister(DAG.getMachineFunction());
|
||||
SDLoc dl(Op); // FIXME probably not meaningful
|
||||
unsigned Depth = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue();
|
||||
const X86RegisterInfo *RegInfo = Subtarget->getRegisterInfo();
|
||||
unsigned FrameReg = RegInfo->getPtrSizedFrameRegister(
|
||||
DAG.getMachineFunction());
|
||||
assert(((FrameReg == X86::RBP && VT == MVT::i64) ||
|
||||
(FrameReg == X86::EBP && VT == MVT::i32)) &&
|
||||
"Invalid Frame Register!");
|
||||
|
@ -50,6 +50,9 @@ class X86MachineFunctionInfo : public MachineFunctionInfo {
|
||||
/// ReturnAddrIndex - FrameIndex for return slot.
|
||||
int ReturnAddrIndex;
|
||||
|
||||
/// \brief FrameIndex for return slot.
|
||||
int FrameAddrIndex;
|
||||
|
||||
/// TailCallReturnAddrDelta - The number of bytes by which return address
|
||||
/// stack slot is moved as the result of tail call optimization.
|
||||
int TailCallReturnAddrDelta;
|
||||
@ -92,6 +95,7 @@ public:
|
||||
CalleeSavedFrameSize(0),
|
||||
BytesToPopOnReturn(0),
|
||||
ReturnAddrIndex(0),
|
||||
FrameAddrIndex(0),
|
||||
TailCallReturnAddrDelta(0),
|
||||
SRetReturnReg(0),
|
||||
GlobalBaseReg(0),
|
||||
@ -109,6 +113,7 @@ public:
|
||||
CalleeSavedFrameSize(0),
|
||||
BytesToPopOnReturn(0),
|
||||
ReturnAddrIndex(0),
|
||||
FrameAddrIndex(0),
|
||||
TailCallReturnAddrDelta(0),
|
||||
SRetReturnReg(0),
|
||||
GlobalBaseReg(0),
|
||||
@ -139,6 +144,9 @@ public:
|
||||
int getRAIndex() const { return ReturnAddrIndex; }
|
||||
void setRAIndex(int Index) { ReturnAddrIndex = Index; }
|
||||
|
||||
int getFAIndex() const { return FrameAddrIndex; }
|
||||
void setFAIndex(int Index) { FrameAddrIndex = Index; }
|
||||
|
||||
int getTCReturnAddrDelta() const { return TailCallReturnAddrDelta; }
|
||||
void setTCReturnAddrDelta(int delta) {TailCallReturnAddrDelta = delta;}
|
||||
|
||||
|
@ -32,8 +32,12 @@ define void @alloc_func(i32* %s, i32* %d) {
|
||||
}
|
||||
|
||||
; CHECK-LABEL: alloc_func:
|
||||
; CHECK: subq $48, %rsp
|
||||
; CHECK: .seh_stackalloc 48
|
||||
; CHECK: leaq 48(%rsp), %rbp
|
||||
; CHECK: .seh_setframe 5, 48
|
||||
; CHECK: .Lframeallocation_alloc_func = -[[offs:[0-9]+]]
|
||||
; CHECK: movl $42, -[[offs]](%rbp)
|
||||
; CHECK: movq %rbp, %rcx
|
||||
; CHECK: leaq -48(%rbp), %rcx
|
||||
; CHECK: callq print_framealloc_from_fp
|
||||
; CHECK: retq
|
||||
|
Loading…
x
Reference in New Issue
Block a user