From patchwork Tue Aug 10 21:07:23 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [2/3] Tweek prologues and epilogues for SEH. Date: Tue, 10 Aug 2010 11:07:23 -0000 From: Richard Henderson X-Patchwork-Id: 61410 Message-Id: <1281474444-8772-3-git-send-email-rth@redhat.com> To: gcc-patches@gcc.gnu.org Cc: Richard Henderson , ktietz70@googlemail.com From: Richard Henderson --- 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(-) diff --git a/gcc/config/i386/cygming.h b/gcc/config/i386/cygming.h index a6434f3..4962921 100644 --- a/gcc/config/i386/cygming.h +++ b/gcc/config/i386/cygming.h @@ -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) diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 3f37066..938a686 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -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) diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h index a2acc71..eb73df7 100644 --- a/gcc/config/i386/i386.h +++ b/gcc/config/i386/i386.h @@ -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 {