+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.
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]);
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);
--- /dev/null
+/* 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;
+}