+2017-07-30 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR target/79793
+ * config/i386/i386.c (ix86_function_arg): Update arguments for
+ exception handler.
+ (ix86_compute_frame_layout): Set the initial stack offset to
+ INCOMING_FRAME_SP_OFFSET. Update red-zone offset with
+ INCOMING_FRAME_SP_OFFSET.
+ (ix86_expand_epilogue): Don't pop the 'ERROR_CODE' off the
+ stack before exception handler returns.
+ * config/i386/i386.h (INCOMING_FRAME_SP_OFFSET): Add the
+ the 'ERROR_CODE' for exception handler.
+
2017-07-30 Uros Bizjak <ubizjak@gmail.com>
* config/i386/i386.h (ASM_PRINTF_EXTENSIONS): New macro.
{
/* This is the pointer argument. */
gcc_assert (TYPE_MODE (type) == Pmode);
- if (cfun->machine->func_type == TYPE_INTERRUPT)
- /* -WORD(AP) in the current frame in interrupt handler. */
- arg = plus_constant (Pmode, arg_pointer_rtx,
- -UNITS_PER_WORD);
- else
- /* (AP) in the current frame in exception handler. */
- arg = arg_pointer_rtx;
+ /* It is at -WORD(AP) in the current frame in interrupt and
+ exception handlers. */
+ arg = plus_constant (Pmode, arg_pointer_rtx, -UNITS_PER_WORD);
}
else
{
gcc_assert (cfun->machine->func_type == TYPE_EXCEPTION
&& TREE_CODE (type) == INTEGER_TYPE
&& TYPE_MODE (type) == word_mode);
- /* The integer argument is the error code at -WORD(AP) in
- the current frame in exception handler. */
+ /* The error code is the word-mode integer argument at
+ -2 * WORD(AP) in the current frame of the exception
+ handler. */
arg = gen_rtx_MEM (word_mode,
plus_constant (Pmode,
arg_pointer_rtx,
- -UNITS_PER_WORD));
+ -2 * UNITS_PER_WORD));
}
return arg;
}
the registers need to be saved before allocating the frame. */
&& flag_stack_check != STATIC_BUILTIN_STACK_CHECK);
- /* Skip return address. */
- offset = UNITS_PER_WORD;
+ /* Skip return address and error code in exception handler. */
+ offset = INCOMING_FRAME_SP_OFFSET;
/* Skip pushed static chain. */
if (ix86_static_chain_on_stack)
m->fs.red_zone_offset = 0;
if (ix86_using_red_zone () && crtl->args.pops_args < 65536)
{
- /* The red-zone begins below the return address. */
- m->fs.red_zone_offset = RED_ZONE_SIZE + UNITS_PER_WORD;
+ /* The red-zone begins below return address and error code in
+ exception handler. */
+ m->fs.red_zone_offset = RED_ZONE_SIZE + INCOMING_FRAME_SP_OFFSET;
/* When the register save area is in the aligned portion of
the stack, determine the maximum runtime displacement that
}
if (cfun->machine->func_type != TYPE_NORMAL)
- {
- /* Return with the "IRET" instruction from interrupt handler.
- Pop the 'ERROR_CODE' off the stack before the 'IRET'
- instruction in exception handler. */
- if (cfun->machine->func_type == TYPE_EXCEPTION)
- {
- rtx r = plus_constant (Pmode, stack_pointer_rtx,
- UNITS_PER_WORD);
- emit_insn (gen_rtx_SET (stack_pointer_rtx, r));
- }
- emit_jump_insn (gen_interrupt_return ());
- }
+ emit_jump_insn (gen_interrupt_return ());
else if (crtl->args.pops_args && crtl->args.size)
{
rtx popc = GEN_INT (crtl->args.pops_args);
/* PC is dbx register 8; let's use that column for RA. */
#define DWARF_FRAME_RETURN_COLUMN (TARGET_64BIT ? 16 : 8)
-/* Before the prologue, the top of the frame is at 4(%esp). */
-#define INCOMING_FRAME_SP_OFFSET UNITS_PER_WORD
+/* Before the prologue, there are return address and error code for
+ exception handler on the top of the frame. */
+#define INCOMING_FRAME_SP_OFFSET \
+ (cfun->machine->func_type == TYPE_EXCEPTION \
+ ? 2 * UNITS_PER_WORD : UNITS_PER_WORD)
/* Describe how we implement __builtin_eh_return. */
#define EH_RETURN_DATA_REGNO(N) ((N) <= DX_REG ? (N) : INVALID_REGNUM)
+2017-07-30 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR target/79793
+ * gcc.dg/guality/pr68037-1.c: Update gdb breakpoints.
+ * gcc.target/i386/interrupt-5.c (interrupt_frame): New struct.
+ (foo): Check the builtin return address against the return address
+ in interrupt frame.
+ * gcc.target/i386/pr79793-1.c: New test.
+ * gcc.target/i386/pr79793-2.c: Likewise.
+
2017-07-29 Eric Botcazou <ebotcazou@adacore.com>
* c-c++-common/dump-ada-spec-7.c: New test.
return 0;
}
-/* { dg-final { gdb-test 31 "error" "0x12345670" } } */
-/* { dg-final { gdb-test 31 "frame->ip" "0x12345671" } } */
-/* { dg-final { gdb-test 31 "frame->cs" "0x12345672" } } */
-/* { dg-final { gdb-test 31 "frame->flags" "0x12345673" } } */
-/* { dg-final { gdb-test 31 "frame->sp" "0x12345674" } } */
-/* { dg-final { gdb-test 31 "frame->ss" "0x12345675" } } */
+/* { dg-final { gdb-test 33 "error" "0x12345670" } } */
+/* { dg-final { gdb-test 33 "frame->ip" "0x12345671" } } */
+/* { dg-final { gdb-test 33 "frame->cs" "0x12345672" } } */
+/* { dg-final { gdb-test 33 "frame->flags" "0x12345673" } } */
+/* { dg-final { gdb-test 33 "frame->sp" "0x12345674" } } */
+/* { dg-final { gdb-test 33 "frame->ss" "0x12345675" } } */
typedef unsigned int uword_t __attribute__ ((mode (__word__)));
+struct interrupt_frame
+{
+ uword_t ip;
+ uword_t cs;
+ uword_t flags;
+ uword_t sp;
+ uword_t ss;
+};
+
__attribute__ ((used, interrupt))
void
-foo (void *frame, uword_t error)
+foo (struct interrupt_frame *frame, uword_t error)
{
void *ra = __builtin_return_address (0);
- if ((uintptr_t) ra != (uintptr_t) error)
+ if ((uintptr_t) ra != (uintptr_t) frame->ip)
link_error ();
}
--- /dev/null
+/* { dg-do compile { target { *-*-linux* && { ! ia32 } } } } */
+/* { dg-options "-O2 -mgeneral-regs-only" } */
+
+void
+ __attribute__ ((interrupt))
+fn1 (void *frame)
+{
+ char fxsave_region [512] __attribute__((aligned(16)));
+ __builtin_ia32_fxsave64 (fxsave_region);
+}
+
+/* { dg-final { scan-assembler-times "sub\[lq\]\[\t \]*\\\$400,\[\t \]*%\[re\]sp" 1 } } */
+/* { dg-final { scan-assembler-times "fxsave64\[\t \]*-120\\(%\[re\]sp\\)" 1 } } */
+/* { dg-final { scan-assembler-times "add\[lq\]\[\t \]*\\\$400,\[\t \]*%\[re\]sp" 1 } } */
--- /dev/null
+/* { dg-do compile { target { *-*-linux* && { ! ia32 } } } } */
+/* { dg-options "-O2 -mgeneral-regs-only" } */
+
+typedef unsigned int uword_t __attribute__ ((mode (__word__)));
+
+void
+ __attribute__ ((interrupt))
+fn1 (void *frame, uword_t error)
+{
+ char fxsave_region [512] __attribute__((aligned(16)));
+ __builtin_ia32_fxsave64 (fxsave_region);
+}
+
+/* { dg-final { scan-assembler-times "sub\[lq\]\[\t \]*\\\$392,\[\t \]*%\[re\]sp" 1 } } */
+/* { dg-final { scan-assembler-times "fxsave64\[\t \]*-120\\(%\[re\]sp\\)" 1 } } */
+/* { dg-final { scan-assembler-times "add\[lq\]\[\t \]*\\\$400,\[\t \]*%\[re\]sp" 1 } } */