aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn David Anglin <danglin@gcc.gnu.org>2019-06-16 21:27:14 +0000
committerJohn David Anglin <danglin@gcc.gnu.org>2019-06-16 21:27:14 +0000
commitc669ebe7c3f43e873c495c598df0a90fc4c1bed7 (patch)
tree4c3f66d16c0e8ccc382d550f953da7d29c16168a
parent0fcc78f79e85b816480e0425cc8d7c496e739e88 (diff)
downloadgcc-c669ebe7c3f43e873c495c598df0a90fc4c1bed7.zip
gcc-c669ebe7c3f43e873c495c598df0a90fc4c1bed7.tar.gz
gcc-c669ebe7c3f43e873c495c598df0a90fc4c1bed7.tar.bz2
re PR middle-end/64242 (Longjmp expansion incorrect)
PR middle-end/64242 * config/pa/pa.md (nonlocal_goto): Restore frame pointer last. Add frame clobbers and schedule block. (builtin_longjmp): Likewise. From-SVN: r272361
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/config/pa/pa.md48
2 files changed, 34 insertions, 21 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 1b7528b..369ca4b 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2019-06-16 John David Anglin <danglin@gcc.gnu.org>
+
+ PR middle-end/64242
+ * config/pa/pa.md (nonlocal_goto): Restore frame pointer last. Add
+ frame clobbers and schedule block.
+ (builtin_longjmp): Likewise.
+
2019-06-16 Jozef Lawrynowicz <jozef.l@mittosystems.com>
* config/msp430/msp430.c (msp430_expand_helper): Setup arguments which
diff --git a/gcc/config/pa/pa.md b/gcc/config/pa/pa.md
index 8308b37..84630ad 100644
--- a/gcc/config/pa/pa.md
+++ b/gcc/config/pa/pa.md
@@ -6904,21 +6904,24 @@
rtx stack = operands[2];
rtx fp = operands[3];
- lab = copy_to_reg (lab);
-
emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
- /* Restore the frame pointer. The virtual_stack_vars_rtx is saved
- instead of the hard_frame_pointer_rtx in the save area. As a
- result, an extra instruction is needed to adjust for the offset
- of the virtual stack variables and the hard frame pointer. */
- if (GET_CODE (fp) != REG)
- fp = force_reg (Pmode, fp);
- emit_move_insn (hard_frame_pointer_rtx, plus_constant (Pmode, fp, -8));
+ lab = copy_to_reg (lab);
+ /* Restore the stack and frame pointers. The virtual_stack_vars_rtx
+ is saved instead of the hard_frame_pointer_rtx in the save area.
+ As a result, an extra instruction is needed to adjust for the offset
+ of the virtual stack variables and the hard frame pointer. */
+ fp = copy_to_reg (fp);
emit_stack_restore (SAVE_NONLOCAL, stack);
+ /* Ensure the frame pointer move is not optimized. */
+ emit_insn (gen_blockage ());
+ emit_clobber (hard_frame_pointer_rtx);
+ emit_clobber (frame_pointer_rtx);
+ emit_move_insn (hard_frame_pointer_rtx, plus_constant (Pmode, fp, -8));
+
emit_use (hard_frame_pointer_rtx);
emit_use (stack_pointer_rtx);
@@ -8695,23 +8698,26 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
- /* Restore the frame pointer. The virtual_stack_vars_rtx is saved
- instead of the hard_frame_pointer_rtx in the save area. We need
- to adjust for the offset between these two values. */
- if (GET_CODE (fp) != REG)
- fp = force_reg (Pmode, fp);
- emit_move_insn (hard_frame_pointer_rtx, plus_constant (Pmode, fp, -8));
-
- /* This bit is the same as expand_builtin_longjmp. */
- emit_stack_restore (SAVE_NONLOCAL, stack);
- emit_use (hard_frame_pointer_rtx);
- emit_use (stack_pointer_rtx);
-
/* Load the label we are jumping through into r1 so that we know
where to look for it when we get back to setjmp's function for
restoring the gp. */
emit_move_insn (pv, lab);
+ /* Restore the stack and frame pointers. The virtual_stack_vars_rtx
+ is saved instead of the hard_frame_pointer_rtx in the save area.
+ We need to adjust for the offset between these two values. */
+ fp = copy_to_reg (fp);
+ emit_stack_restore (SAVE_NONLOCAL, stack);
+
+ /* Ensure the frame pointer move is not optimized. */
+ emit_insn (gen_blockage ());
+ emit_clobber (hard_frame_pointer_rtx);
+ emit_clobber (frame_pointer_rtx);
+ emit_move_insn (hard_frame_pointer_rtx, plus_constant (Pmode, fp, -8));
+
+ emit_use (hard_frame_pointer_rtx);
+ emit_use (stack_pointer_rtx);
+
/* Prevent the insns above from being scheduled into the delay slot
of the interspace jump because the space register could change. */
emit_insn (gen_blockage ());