diff options
author | gingold <gingold@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-06-25 08:25:43 +0000 |
---|---|---|
committer | gingold <gingold@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-06-25 08:25:43 +0000 |
commit | 595bdb35c2eac4618cbfe3c64232a1d9643efc64 (patch) | |
tree | 3b9eb13086b15baf1c0123d9959f48428c51189d /gcc/config/i386/winnt.c | |
parent | a9dc3c0cc1f80d918430d3c59ecb4784c20a9b9e (diff) | |
download | gcc-595bdb35c2eac4618cbfe3c64232a1d9643efc64.tar.gz |
2012-06-25 Tristan Gingold <gingold@adacore.com>
* config/i386/winnt.c (i386_pe_seh_end_prologue): Move code to ...
(seh_cfa_adjust_cfa): ... that function.
(seh_emit_stackalloc): Do not emit out of range values.
* config/i386/i386.md: Delete unused UNSPEC_REG_SAVE,
UNSPEC_DEF_CFA constants.
* config/i386/i386.h (SEH_MAX_FRAME_SIZE): Define.
* config/i386/i386.c (ix86_frame_pointer_required): Required
for very large frames on SEH target.
(ix86_compute_frame_layout): Save area is before frame pointer
on SEH target. Handle very large frames.
(ix86_expand_prologue): Likewise.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@188928 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config/i386/winnt.c')
-rw-r--r-- | gcc/config/i386/winnt.c | 32 |
1 files changed, 15 insertions, 17 deletions
diff --git a/gcc/config/i386/winnt.c b/gcc/config/i386/winnt.c index c1ed1c04369..10cdee80022 100644 --- a/gcc/config/i386/winnt.c +++ b/gcc/config/i386/winnt.c @@ -829,22 +829,6 @@ i386_pe_seh_end_prologue (FILE *f) return; seh = cfun->machine->seh; - /* Emit an assembler directive to set up the frame pointer. Always do - this last. The documentation talks about doing this "before" any - other code that uses offsets, but (experimentally) that's after we - emit the codes in reverse order (handled by the assembler). */ - if (seh->cfa_reg != stack_pointer_rtx) - { - HOST_WIDE_INT offset = seh->sp_offset - seh->cfa_offset; - - gcc_assert ((offset & 15) == 0); - gcc_assert (IN_RANGE (offset, 0, 240)); - - fputs ("\t.seh_setframe\t", f); - print_reg (seh->cfa_reg, 0, f); - fprintf (f, ", " HOST_WIDE_INT_PRINT_DEC "\n", offset); - } - XDELETE (seh); cfun->machine->seh = NULL; @@ -915,7 +899,10 @@ seh_emit_stackalloc (FILE *f, struct seh_frame_state *seh, seh->cfa_offset += offset; seh->sp_offset += offset; - fprintf (f, "\t.seh_stackalloc\t" HOST_WIDE_INT_PRINT_DEC "\n", offset); + /* Do not output the stackalloc in that case (it won't work as there is no + encoding for very large frame size). */ + if (offset < SEH_MAX_FRAME_SIZE) + fprintf (f, "\t.seh_stackalloc\t" HOST_WIDE_INT_PRINT_DEC "\n", offset); } /* Process REG_CFA_ADJUST_CFA for SEH. */ @@ -948,8 +935,19 @@ seh_cfa_adjust_cfa (FILE *f, struct seh_frame_state *seh, rtx pat) seh_emit_stackalloc (f, seh, reg_offset); else if (dest_regno == HARD_FRAME_POINTER_REGNUM) { + HOST_WIDE_INT offset; + seh->cfa_reg = dest; seh->cfa_offset -= reg_offset; + + offset = seh->sp_offset - seh->cfa_offset; + + gcc_assert ((offset & 15) == 0); + gcc_assert (IN_RANGE (offset, 0, 240)); + + fputs ("\t.seh_setframe\t", f); + print_reg (seh->cfa_reg, 0, f); + fprintf (f, ", " HOST_WIDE_INT_PRINT_DEC "\n", offset); } else gcc_unreachable (); |