+2016-11-29 Segher Boessenkool <segher@kernel.crashing.org>
+
+ PR target/77687
+ * config/rs6000/rs6000.c (rs6000_emit_stack_reset): Emit the
+ stack_restore_tie insn instead of stack_tie, for the SVR4 and
+ SPE ABIs.
+ * config/rs6000/rs6000.md (stack_restore_tie): New define_insn.
+
2016-11-28 Segher Boessenkool <segher@kernel.crashing.org>
* shrink-wrap.c (init_separate_shrink_wrap): Do not clear
rtx frame_reg_rtx, HOST_WIDE_INT frame_off,
unsigned updt_regno)
{
- rtx updt_reg_rtx;
+ /* If there is nothing to do, don't do anything. */
+ if (frame_off == 0 && REGNO (frame_reg_rtx) == updt_regno)
+ return NULL_RTX;
+
+ rtx updt_reg_rtx = gen_rtx_REG (Pmode, updt_regno);
/* This blockage is needed so that sched doesn't decide to move
the sp change before the register restores. */
|| (TARGET_SPE_ABI
&& info->spe_64bit_regs_used != 0
&& info->first_gp_reg_save != 32))
- rs6000_emit_stack_tie (frame_reg_rtx, frame_pointer_needed);
+ return emit_insn (gen_stack_restore_tie (updt_reg_rtx, frame_reg_rtx,
+ GEN_INT (frame_off)));
/* If we are restoring registers out-of-line, we will be using the
"exit" variants of the restore routines, which will reset the
stack for us. But we do need to point updt_reg into the
right place for those routines. */
- updt_reg_rtx = gen_rtx_REG (Pmode, updt_regno);
-
if (frame_off != 0)
return emit_insn (gen_add3_insn (updt_reg_rtx,
frame_reg_rtx, GEN_INT (frame_off)));
- else if (REGNO (frame_reg_rtx) != updt_regno)
+ else
return emit_move_insn (updt_reg_rtx, frame_reg_rtx);
return NULL_RTX;
""
[(set_attr "length" "0")])
+; Some 32-bit ABIs do not have a red zone, so the stack deallocation has to
+; stay behind all restores from the stack, it cannot be reordered to before
+; one. See PR77687. This insn is an add or mr, and a stack_tie on the
+; operands of that.
+(define_insn "stack_restore_tie"
+ [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
+ (plus:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
+ (match_operand:SI 2 "reg_or_cint_operand" "O,rI")))
+ (set (mem:BLK (match_dup 0)) (const_int 0))
+ (set (mem:BLK (match_dup 1)) (const_int 0))]
+ "TARGET_32BIT"
+ "@
+ mr %0,%1
+ add%I2 %0,%1,%2"
+ [(set_attr "type" "*,add")])
+
(define_expand "epilogue"
[(use (const_int 0))]
""