#include "X86InstrInfo.h"
#include "X86MachineFunctionInfo.h"
#include "X86Subtarget.h"
+#include "llvm/Analysis/LibCallSemantics.h"
#include "llvm/CodeGen/Passes.h" // For IDs of passes that are preserved.
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
case X86::EH_RESTORE: {
// Restore ESP and EBP, and optionally ESI if required.
- X86FL->restoreWin32EHStackPointers(MBB, MBBI, DL, /*RestoreSP=*/true);
+ bool IsSEH = isAsynchronousEHPersonality(classifyEHPersonality(
+ MBB.getParent()->getFunction()->getPersonalityFn()));
+ X86FL->restoreWin32EHStackPointers(MBB, MBBI, DL, /*RestoreSP=*/IsSEH);
MBBI->eraseFromParent();
return true;
}
} else if (IsFunclet && STI.is32Bit()) {
// Reset EBP / ESI to something good for funclets.
MBBI = restoreWin32EHStackPointers(MBB, MBBI, DL);
+ // If we're a catch funclet, we can be returned to via catchret. Save ESP
+ // into the registration node so that the runtime will restore it for us.
+ if (!MBB.isCleanupFuncletEntry()) {
+ assert(classifyEHPersonality(Fn->getPersonalityFn()) ==
+ EHPersonality::MSVC_CXX);
+ unsigned FrameReg;
+ int FI = MMI.getWinEHFuncInfo(Fn).EHRegNodeFrameIndex;
+ int64_t EHRegOffset = getFrameIndexReference(MF, FI, FrameReg);
+ // ESP is the first field, so no extra displacement is needed.
+ addRegOffset(BuildMI(MBB, MBBI, DL, TII.get(X86::MOV32mr)), FrameReg,
+ false, EHRegOffset)
+ .addReg(X86::ESP);
+ }
}
while (MBBI != MBB.end() && MBBI->getFlag(MachineInstr::FrameSetup)) {
}
; X86-LABEL: _try_catch_catch:
+; X86: movl %esp, -[[sp_offset:[0-9]+]](%ebp)
; X86: movl $0, -{{[0-9]+}}(%ebp)
; X86: leal -[[local_offs:[0-9]+]](%ebp), %[[addr_reg:[a-z]+]]
; X86-DAG: movl %[[addr_reg]], 4(%esp)
; X86: [[restorebb1:LBB0_[0-9]+]]: # Block address taken
; X86-NEXT: # %invoke.cont.2
-; X86: movl -16(%ebp), %esp
-; X86: addl $12, %ebp
+; X86-NEXT: addl $12, %ebp
; X86: jmp [[contbb]]
; FIXME: These should be de-duplicated.
; X86: [[restorebb2:LBB0_[0-9]+]]: # Block address taken
; X86-NEXT: # %invoke.cont.3
-; X86: movl -16(%ebp), %esp
-; X86: addl $12, %ebp
+; X86-NEXT: addl $12, %ebp
; X86: jmp [[contbb]]
; X86: "?catch$[[catch1bb:[0-9]+]]@?0?try_catch_catch@4HA":
; X86: pushl %ebp
; X86: subl $8, %esp
; X86: addl $12, %ebp
+; X86: movl %esp, -[[sp_offset]](%ebp)
; X86: leal -[[local_offs]](%ebp), %[[addr_reg:[a-z]+]]
; X86: movl -32(%ebp), %[[e_reg:[a-z]+]]
; X86: movl $1, -{{[0-9]+}}(%ebp)
; X86: pushl %ebp
; X86: subl $8, %esp
; X86: addl $12, %ebp
+; X86: movl %esp, -[[sp_offset]](%ebp)
; X86: leal -[[local_offs]](%ebp), %[[addr_reg:[a-z]+]]
; X86: movl $1, -{{[0-9]+}}(%ebp)
; X86-DAG: movl %[[addr_reg]], 4(%esp)
; X86: [[restorebb:LBB1_[0-9]+]]: # Block address taken
; X86-NEXT: # %catch.done
-; X86: movl -16(%ebp), %esp
-; X86: addl $12, %ebp
+; X86-NEXT: addl $12, %ebp
; X86: jmp [[contbb]]
; X86: "?catch$[[catchdispbb:[0-9]+]]@?0?branch_to_normal_dest@4HA":