diff options
author | Eric Botcazou <ebotcazou@adacore.com> | 2018-06-13 11:20:23 +0000 |
---|---|---|
committer | Eric Botcazou <ebotcazou@gcc.gnu.org> | 2018-06-13 11:20:23 +0000 |
commit | 70e18df76ed2ccce4f6695b7f848d25dfa31ce0e (patch) | |
tree | 1a324714f7d9bfc0c7a33b273c25abe20f1cda90 /gcc/config | |
parent | 8c191c89cfde7c74955c21d488702077cca89117 (diff) | |
download | gcc-70e18df76ed2ccce4f6695b7f848d25dfa31ce0e.zip gcc-70e18df76ed2ccce4f6695b7f848d25dfa31ce0e.tar.gz gcc-70e18df76ed2ccce4f6695b7f848d25dfa31ce0e.tar.bz2 |
re PR target/86048 (.seh_savexmm offset is negative error when compiling libpng)
PR target/86048
* config/i386/winnt.c (i386_pe_seh_cold_init): Do not emit negative
offsets for register save directives. Emit a second batch of save
directives, if need be, when the function accesses prior frames.
From-SVN: r261544
Diffstat (limited to 'gcc/config')
-rw-r--r-- | gcc/config/i386/winnt.c | 25 |
1 files changed, 21 insertions, 4 deletions
diff --git a/gcc/config/i386/winnt.c b/gcc/config/i386/winnt.c index 3a857f9..89e4b6e 100644 --- a/gcc/config/i386/winnt.c +++ b/gcc/config/i386/winnt.c @@ -922,11 +922,14 @@ i386_pe_seh_cold_init (FILE *f, const char *name) fprintf (f, "\t.seh_stackalloc\t" HOST_WIDE_INT_PRINT_DEC "\n", offset); for (int regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) - if (seh->reg_offset[regno] > 0) + if (seh->reg_offset[regno] > 0 && seh->reg_offset[regno] <= alloc_offset) { - fputs ((SSE_REGNO_P (regno) ? "\t.seh_savexmm\t" - : GENERAL_REGNO_P (regno) ? "\t.seh_savereg\t" - : (gcc_unreachable (), "")), f); + if (SSE_REGNO_P (regno)) + fputs ("\t.seh_savexmm\t", f); + else if (GENERAL_REGNO_P (regno)) + fputs ("\t.seh_savereg\t", f); + else + gcc_unreachable (); print_reg (gen_rtx_REG (DImode, regno), 0, f); fprintf (f, ", " HOST_WIDE_INT_PRINT_DEC "\n", alloc_offset - seh->reg_offset[regno]); @@ -949,6 +952,20 @@ i386_pe_seh_cold_init (FILE *f, const char *name) offset = seh->sp_offset - alloc_offset; if (offset > 0 && offset < SEH_MAX_FRAME_SIZE) fprintf (f, "\t.seh_stackalloc\t" HOST_WIDE_INT_PRINT_DEC "\n", offset); + + for (int regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) + if (seh->reg_offset[regno] > alloc_offset) + { + if (SSE_REGNO_P (regno)) + fputs ("\t.seh_savexmm\t", f); + else if (GENERAL_REGNO_P (regno)) + fputs ("\t.seh_savereg\t", f); + else + gcc_unreachable (); + print_reg (gen_rtx_REG (DImode, regno), 0, f); + fprintf (f, ", " HOST_WIDE_INT_PRINT_DEC "\n", + seh->sp_offset - seh->reg_offset[regno]); + } } fputs ("\t.seh_endprologue\n", f); |