aboutsummaryrefslogtreecommitdiff
path: root/gcc/config
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@adacore.com>2018-06-13 11:20:23 +0000
committerEric Botcazou <ebotcazou@gcc.gnu.org>2018-06-13 11:20:23 +0000
commit70e18df76ed2ccce4f6695b7f848d25dfa31ce0e (patch)
tree1a324714f7d9bfc0c7a33b273c25abe20f1cda90 /gcc/config
parent8c191c89cfde7c74955c21d488702077cca89117 (diff)
downloadgcc-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.c25
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);