[committed] pa: Fix nonlocal_goto and builtin_longjmp expanders
John David Anglin
dave.anglin@bell.net
Sun Jun 16 21:38:00 GMT 2019
The attached change fixes PR middle-end/64242 on hppa. The nonlocal_goto and
builtin_longjmp expanders are reworked to restore the frame pointer last. Clobbers
and a blockage are added to ensure the restored frame pointer is not used to restore
the stack pointer and the branch address.
Tested on hppa-unknown-linux-gnu and hppa2.0w-hp-hpux11.11. Committed to trunk.
Dave
--
John David Anglin dave.anglin@bell.net
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.
Index: config/pa/pa.md
===================================================================
--- config/pa/pa.md (revision 272327)
+++ config/pa/pa.md (working copy)
@@ -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
+ 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. */
- if (GET_CODE (fp) != REG)
- fp = force_reg (Pmode, fp);
+ 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_stack_restore (SAVE_NONLOCAL, stack);
-
emit_use (hard_frame_pointer_rtx);
emit_use (stack_pointer_rtx);
@@ -8695,23 +8698,26 @@
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);
+ /* 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));
- /* 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);
-
/* 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 ());
More information about the Gcc-patches
mailing list