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 | |
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
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/config/i386/winnt.c | 25 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr86048.c | 26 |
4 files changed, 58 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 34eb1d9..103877a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2018-06-13 Eric Botcazou <ebotcazou@adacore.com> + + 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. + 2018-06-12 Claudiu Zissulescu <claziss@synopsys.com> * config/arc/fpu.md (fmasf4): Force operand to register. 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); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index cb680c7..8d5d405 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2018-06-13 Eric Botcazou <ebotcazou@adacore.com> + + * gcc.target/i386/pr86048.c: New test. + 2018-06-12 Claudiu Zissulescu <claziss@synopsys.com> * gcc.target/arc/fma-1.c: New test. diff --git a/gcc/testsuite/gcc.target/i386/pr86048.c b/gcc/testsuite/gcc.target/i386/pr86048.c new file mode 100644 index 0000000..cd73579 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr86048.c @@ -0,0 +1,26 @@ +/* PR target/86048 */ +/* { dg-do assemble } */ +/* { dg-options "-O2" } */ +/* { dg-require-effective-target return_address } */ + +extern void abort (void); + +void *foo (unsigned int *data, unsigned int len) +{ + unsigned int local_data[128]; + + if (len > 128) + abort (); + + for (unsigned int i = 0; i < len; i++) + local_data[i] = data[i] + data[len - 1 - i] * 2; + + void *ret = __builtin_frame_address (0); + + for (unsigned int i = 0; i < len; i++) + ret = ret + local_data[i] % 8; + + __asm__ __volatile__ ("" : : : "%xmm6"); + + return ret; +} |