summaryrefslogtreecommitdiff
path: root/gcc/config/i386/winnt.c
diff options
context:
space:
mode:
authorgingold <gingold@138bc75d-0d04-0410-961f-82ee72b054a4>2012-06-25 08:25:43 +0000
committergingold <gingold@138bc75d-0d04-0410-961f-82ee72b054a4>2012-06-25 08:25:43 +0000
commit595bdb35c2eac4618cbfe3c64232a1d9643efc64 (patch)
tree3b9eb13086b15baf1c0123d9959f48428c51189d /gcc/config/i386/winnt.c
parenta9dc3c0cc1f80d918430d3c59ecb4784c20a9b9e (diff)
downloadgcc-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.c32
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 ();