bool IsWin64Prologue = MF.getTarget().getMCAsmInfo()->usesWindowsCFI();
bool NeedsWinCFI =
IsWin64Prologue && MF.getFunction()->needsUnwindTableEntry();
+ bool IsFunclet = isFuncletReturnInstr(MBBI);
+ MachineBasicBlock *RestoreMBB = nullptr;
// Get the number of bytes to allocate from the FrameInfo.
uint64_t StackSize = MFI->getStackSize();
}
// For 32-bit, create a new block for the restore code.
- MachineBasicBlock *RestoreMBB = TargetMBB;
+ RestoreMBB = TargetMBB;
if (STI.is32Bit()) {
RestoreMBB = MF.CreateMachineBasicBlock(MBB.getBasicBlock());
MF.insert(TargetMBB, RestoreMBB);
MBBI->getOperand(0).setMBB(RestoreMBB);
}
- // Fill EAX/RAX with the address of the target block.
- unsigned ReturnReg = STI.is64Bit() ? X86::RAX : X86::EAX;
- if (STI.is64Bit()) {
- // LEA64r RestoreMBB(%rip), %rax
- BuildMI(MBB, MBBI, DL, TII.get(X86::LEA64r), ReturnReg)
- .addReg(X86::RIP)
- .addImm(0)
- .addReg(0)
- .addMBB(RestoreMBB)
- .addReg(0);
- } else {
- // MOV32ri $RestoreMBB, %eax
- BuildMI(MBB, MBBI, DL, TII.get(X86::MOV32ri))
- .addReg(ReturnReg)
- .addMBB(RestoreMBB);
- }
-
// Pop EBP.
BuildMI(MBB, MBBI, DL, TII.get(Is64Bit ? X86::POP64r : X86::POP32r),
MachineFramePtr)
}
MachineBasicBlock::iterator FirstCSPop = MBBI;
+ if (RestoreMBB) {
+ // Fill EAX/RAX with the address of the target block.
+ unsigned ReturnReg = STI.is64Bit() ? X86::RAX : X86::EAX;
+ if (STI.is64Bit()) {
+ // LEA64r RestoreMBB(%rip), %rax
+ BuildMI(MBB, FirstCSPop, DL, TII.get(X86::LEA64r), ReturnReg)
+ .addReg(X86::RIP)
+ .addImm(0)
+ .addReg(0)
+ .addMBB(RestoreMBB)
+ .addReg(0);
+ } else {
+ // MOV32ri $RestoreMBB, %eax
+ BuildMI(MBB, FirstCSPop, DL, TII.get(X86::MOV32ri))
+ .addReg(ReturnReg)
+ .addMBB(RestoreMBB);
+ }
+ }
+
if (MBBI != MBB.end())
DL = MBBI->getDebugLoc();
// If dynamic alloca is used, then reset esp to point to the last callee-saved
// slot before popping them off! Same applies for the case, when stack was
- // realigned.
- if (TRI->needsStackRealignment(MF) || MFI->hasVarSizedObjects()) {
+ // realigned. Don't do this if this was a funclet epilogue, since the funclets
+ // will not do realignment or dynamic stack allocation.
+ if ((TRI->needsStackRealignment(MF) || MFI->hasVarSizedObjects()) &&
+ !IsFunclet) {
if (TRI->needsStackRealignment(MF))
MBBI = FirstCSPop;
unsigned SEHFrameOffset = calculateSetFPREG(SEHStackAllocAmt);
int EHRegOffset = getFrameIndexReference(MF, FI, UsedReg);
int EndOffset = -EHRegOffset - EHRegSize;
FuncInfo.EHRegNodeEndOffset = EndOffset;
- assert(EndOffset >= 0 &&
- "end of registration object above normal EBP position!");
if (UsedReg == FramePtr) {
// ADD $offset, %ebp
- assert(UsedReg == FramePtr);
unsigned ADDri = getADDriOpcode(false, EndOffset);
BuildMI(MBB, MBBI, DL, TII.get(ADDri), FramePtr)
.addReg(FramePtr)
.setMIFlag(MachineInstr::FrameSetup)
->getOperand(3)
.setIsDead();
- } else {
- assert(UsedReg == BasePtr);
+ assert(EndOffset >= 0 &&
+ "end of registration object above normal EBP position!");
+ } else if (UsedReg == BasePtr) {
// LEA offset(%ebp), %esi
addRegOffset(BuildMI(MBB, MBBI, DL, TII.get(X86::LEA32r), BasePtr),
FramePtr, false, EndOffset)
addRegOffset(BuildMI(MBB, MBBI, DL, TII.get(X86::MOV32rm), FramePtr),
UsedReg, true, Offset)
.setMIFlag(MachineInstr::FrameSetup);
+ } else {
+ llvm_unreachable("32-bit frames with WinEH must use FramePtr or BasePtr");
}
return MBBI;
}