{
int regno;
rtx_insn *insn;
+ bool use_ppx = TARGET_APX_PPX && !crtl->calls_eh_return;
if (!TARGET_APX_PUSH2POP2
|| !ix86_can_use_push2pop2 ()
if (GENERAL_REGNO_P (regno) && ix86_save_reg (regno, true, true))
{
insn = emit_insn (gen_push (gen_rtx_REG (word_mode, regno),
- TARGET_APX_PPX));
+ use_ppx));
RTX_FRAME_RELATED_P (insn) = 1;
}
}
regno_list[0]),
gen_rtx_REG (word_mode,
regno_list[1]),
- TARGET_APX_PPX));
+ use_ppx));
RTX_FRAME_RELATED_P (insn) = 1;
rtx dwarf = gen_rtx_SEQUENCE (VOIDmode, rtvec_alloc (3));
else
{
insn = emit_insn (gen_push (gen_rtx_REG (word_mode, regno),
- TARGET_APX_PPX));
+ use_ppx));
RTX_FRAME_RELATED_P (insn) = 1;
aligned = true;
}
{
insn = emit_insn (gen_push (gen_rtx_REG (word_mode,
regno_list[0]),
- TARGET_APX_PPX));
+ use_ppx));
RTX_FRAME_RELATED_P (insn) = 1;
}
}
if (!frame.save_regs_using_mov)
{
ix86_emit_save_regs ();
+ m->fs.apx_ppx_used = TARGET_APX_PPX && !crtl->calls_eh_return;
int_registers_saved = true;
gcc_assert (m->fs.sp_offset == frame.reg_save_offset);
}
/* SEH requires the use of pops to identify the epilogue. */
else if (TARGET_SEH)
restore_regs_via_mov = false;
+ /* If we already save reg with pushp, don't use move at epilogue. */
+ else if (m->fs.apx_ppx_used)
+ restore_regs_via_mov = false;
/* If we're only restoring one register and sp cannot be used then
using a move instruction to restore the register since it's
less work than reloading sp and popping the register. */
The flags realigned and sp_realigned are mutually exclusive. */
BOOL_BITFIELD sp_realigned : 1;
+ /* When APX_PPX used in prologue, force epilogue to emit
+ popp instead of move and leave. */
+ BOOL_BITFIELD apx_ppx_used : 1;
+
/* If sp_realigned is set, this is the last valid offset from the CFA
that can be used for access with the frame pointer. */
HOST_WIDE_INT sp_realigned_fp_last;
--- /dev/null
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O1 -mapx-features=ppx -fno-omit-frame-pointer" } */
+
+/* { dg-final { scan-assembler "pushp" } } */
+/* { dg-final { scan-assembler "popp" } } */
+/* { dg-final { scan-assembler-not "leave" } } */
+
+extern int bar (int a);
+extern int *q;
+
+void foo (int *a)
+{
+ q[2] = bar (q[1]);
+}
--- /dev/null
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -mapx-features=ppx" } */
+
+/* { dg-final { scan-assembler-not "pushp" } } */
+/* { dg-final { scan-assembler-not "popp" } } */
+
+#include "eh_return-2.c"