From c669ebe7c3f43e873c495c598df0a90fc4c1bed7 Mon Sep 17 00:00:00 2001 From: John David Anglin Date: Sun, 16 Jun 2019 21:27:14 +0000 Subject: [PATCH] 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 --- gcc/ChangeLog | 7 +++++++ gcc/config/pa/pa.md | 48 +++++++++++++++++++++++++-------------------- 2 files changed, 34 insertions(+), 21 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1b7528b4167..369ca4b995b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2019-06-16 John David Anglin + + 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 * 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 8308b37461d..84630ad536d 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 ()); -- 2.30.2