diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/config/sparc/sparc.md | 18 |
2 files changed, 19 insertions, 5 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index fdd5e71..5072232 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2019-07-01 Eric Botcazou <ebotcazou@adacore.com> + + PR middle-end/64242 + * config/sparc/sparc.md (nonlocal_goto): Restore frame pointer last. + Add frame clobber and schedule blockage. + 2019-07-01 Sandra Loosemore <sandra@codesourcery.com> * doc/invoke.texi (Link Options): Further editorial changes to diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md index a1bf557..7af62d5 100644 --- a/gcc/config/sparc/sparc.md +++ b/gcc/config/sparc/sparc.md @@ -7381,7 +7381,7 @@ visl") "" { rtx i7 = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM); - rtx r_label = copy_to_reg (operands[1]); + rtx r_label = operands[1]; rtx r_sp = adjust_address (operands[2], Pmode, 0); rtx r_fp = operands[3]; rtx r_i7 = adjust_address (operands[2], Pmode, GET_MODE_SIZE (Pmode)); @@ -7394,9 +7394,18 @@ visl") emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode))); emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx)); - /* Restore frame pointer for containing function. */ - emit_move_insn (hard_frame_pointer_rtx, r_fp); + r_label = copy_to_reg (r_label); + + /* Restore the frame pointer and stack pointer. We must use a + temporary since the setjmp buffer may be a local. */ + r_fp = copy_to_reg (r_fp); emit_stack_restore (SAVE_NONLOCAL, r_sp); + r_i7 = copy_to_reg (r_i7); + + /* Ensure the frame pointer move is not optimized. */ + emit_insn (gen_blockage ()); + emit_clobber (hard_frame_pointer_rtx); + emit_move_insn (hard_frame_pointer_rtx, r_fp); emit_move_insn (i7, r_i7); /* USE of hard_frame_pointer_rtx added for consistency; @@ -7405,8 +7414,7 @@ visl") emit_use (stack_pointer_rtx); emit_use (i7); - emit_jump_insn (gen_indirect_jump (r_label)); - emit_barrier (); + emit_indirect_jump (r_label); DONE; }) |