@@ -33,6 +33,9 @@ along with GCC; see the file COPYING3. If not see
#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
#endif
+#undef TARGET_SEH
+#define TARGET_SEH TARGET_64BIT_MS_ABI
+
#undef DEFAULT_ABI
#define DEFAULT_ABI (TARGET_64BIT ? MS_ABI : SYSV_ABI)
@@ -9751,6 +9751,11 @@ ix86_expand_prologue (void)
/* Emit cld instruction if stringops are used in the function. */
if (TARGET_CLD && ix86_current_function_needs_cld)
emit_insn (gen_cld ());
+
+ /* SEH requires that the prologue end within 256 bytes of the start of
+ the function. Prevent instruction schedules that would extend that. */
+ if (TARGET_SEH)
+ emit_insn (gen_blockage ());
}
/* Emit code to restore REG using a POP insn. */
@@ -9973,13 +9978,16 @@ ix86_expand_epilogue (int style)
if (crtl->calls_eh_return && style != 2)
frame.reg_save_offset -= 2 * UNITS_PER_WORD;
+ /* EH_RETURN requires the use of moves to function properly. */
+ if (crtl->calls_eh_return)
+ restore_regs_via_mov = true;
+ /* SEH requires the use of pops to identify the epilogue. */
+ else if (TARGET_SEH)
+ restore_regs_via_mov = false;
/* If we're only restoring one register and sp is not valid then
using a move instruction to restore the register since it's
less work than reloading sp and popping the register. */
- if (!m->fs.sp_valid && frame.nregs <= 1)
- restore_regs_via_mov = true;
- /* EH_RETURN requires the use of moves to function properly. */
- else if (crtl->calls_eh_return)
+ else if (!m->fs.sp_valid && frame.nregs <= 1)
restore_regs_via_mov = true;
else if (TARGET_EPILOGUE_USING_MOVE
&& cfun->machine->use_fast_prologue_epilogue
@@ -10090,6 +10098,13 @@ ix86_expand_epilogue (int style)
}
else
{
+ /* SEH requires that the function end with (1) a stack adjustment
+ if necessary, (2) a sequence of pops, and (3) a return or
+ jump instruction. Prevent insns from the function body from
+ being scheduled into this sequence. */
+ if (TARGET_SEH)
+ emit_insn (gen_blockage ());
+
/* First step is to deallocate the stack frame so that we can
pop the registers. */
if (!m->fs.sp_valid)
@@ -486,6 +486,9 @@ extern tree x86_mfence;
/* For the Windows 64-bit ABI. */
#define TARGET_64BIT_MS_ABI (TARGET_64BIT && ix86_cfun_abi () == MS_ABI)
+/* This is re-defined by cygming.h. */
+#define TARGET_SEH 0
+
/* Available call abi. */
enum calling_abi
{
From: Richard Henderson <rth@twiddle.net> --- gcc/config/i386/cygming.h | 3 +++ gcc/config/i386/i386.c | 23 +++++++++++++++++++---- gcc/config/i386/i386.h | 3 +++ 3 files changed, 25 insertions(+), 4 deletions(-)