Commit 261640d5 by Alan Modra Committed by Alan Modra

rs6000.c (rs6000_emit_allocate_stack): Return stack adjusting insn.

	* config/rs6000/rs6000.c (rs6000_emit_allocate_stack): Return
	stack adjusting insn.  Formatting.
	(rs6000_emit_prologue): Track stack adjusting insn, and use of
	r12.  If possible, emit first -fsplit-stack arg pointer insn
	before stack adjust.  Don't use r12 to save cr if split-stack.

From-SVN: r223427
parent 0f0fd745
2015-05-20 Alan Modra <amodra@gmail.com> 2015-05-20 Alan Modra <amodra@gmail.com>
* config/rs6000/rs6000.c (rs6000_emit_allocate_stack): Return
stack adjusting insn. Formatting.
(rs6000_emit_prologue): Track stack adjusting insn, and use of
r12. If possible, emit first -fsplit-stack arg pointer insn
before stack adjust. Don't use r12 to save cr if split-stack.
2015-05-20 Alan Modra <amodra@gmail.com>
* common/config/rs6000/rs6000-common.c (TARGET_SUPPORTS_SPLIT_STACK): * common/config/rs6000/rs6000-common.c (TARGET_SUPPORTS_SPLIT_STACK):
Define. Define.
(rs6000_supports_split_stack): New function. (rs6000_supports_split_stack): New function.
......
...@@ -22607,7 +22607,7 @@ rs6000_emit_stack_tie (rtx fp, bool hard_frame_needed) ...@@ -22607,7 +22607,7 @@ rs6000_emit_stack_tie (rtx fp, bool hard_frame_needed)
If COPY_REG, make sure a copy of the old frame is left there. If COPY_REG, make sure a copy of the old frame is left there.
The generated code may use hard register 0 as a temporary. */ The generated code may use hard register 0 as a temporary. */
static void static rtx_insn *
rs6000_emit_allocate_stack (HOST_WIDE_INT size, rtx copy_reg, int copy_off) rs6000_emit_allocate_stack (HOST_WIDE_INT size, rtx copy_reg, int copy_off)
{ {
rtx_insn *insn; rtx_insn *insn;
...@@ -22620,7 +22620,7 @@ rs6000_emit_allocate_stack (HOST_WIDE_INT size, rtx copy_reg, int copy_off) ...@@ -22620,7 +22620,7 @@ rs6000_emit_allocate_stack (HOST_WIDE_INT size, rtx copy_reg, int copy_off)
{ {
warning (0, "stack frame too large"); warning (0, "stack frame too large");
emit_insn (gen_trap ()); emit_insn (gen_trap ());
return; return 0;
} }
if (crtl->limit_stack) if (crtl->limit_stack)
...@@ -22671,9 +22671,9 @@ rs6000_emit_allocate_stack (HOST_WIDE_INT size, rtx copy_reg, int copy_off) ...@@ -22671,9 +22671,9 @@ rs6000_emit_allocate_stack (HOST_WIDE_INT size, rtx copy_reg, int copy_off)
insn = emit_insn (TARGET_32BIT insn = emit_insn (TARGET_32BIT
? gen_movsi_update_stack (stack_reg, stack_reg, ? gen_movsi_update_stack (stack_reg, stack_reg,
todec, stack_reg) todec, stack_reg)
: gen_movdi_di_update_stack (stack_reg, stack_reg, : gen_movdi_di_update_stack (stack_reg, stack_reg,
todec, stack_reg)); todec, stack_reg));
/* Since we didn't use gen_frame_mem to generate the MEM, grab /* Since we didn't use gen_frame_mem to generate the MEM, grab
it now and set the alias set/attributes. The above gen_*_update it now and set the alias set/attributes. The above gen_*_update
calls will generate a PARALLEL with the MEM set being the first calls will generate a PARALLEL with the MEM set being the first
...@@ -22691,6 +22691,7 @@ rs6000_emit_allocate_stack (HOST_WIDE_INT size, rtx copy_reg, int copy_off) ...@@ -22691,6 +22691,7 @@ rs6000_emit_allocate_stack (HOST_WIDE_INT size, rtx copy_reg, int copy_off)
add_reg_note (insn, REG_FRAME_RELATED_EXPR, add_reg_note (insn, REG_FRAME_RELATED_EXPR,
gen_rtx_SET (stack_reg, gen_rtx_PLUS (Pmode, stack_reg, gen_rtx_SET (stack_reg, gen_rtx_PLUS (Pmode, stack_reg,
GEN_INT (-size)))); GEN_INT (-size))));
return insn;
} }
#define PROBE_INTERVAL (1 << STACK_CHECK_PROBE_INTERVAL_EXP) #define PROBE_INTERVAL (1 << STACK_CHECK_PROBE_INTERVAL_EXP)
...@@ -23495,6 +23496,10 @@ rs6000_emit_prologue (void) ...@@ -23495,6 +23496,10 @@ rs6000_emit_prologue (void)
/* Offset to top of frame for frame_reg and sp respectively. */ /* Offset to top of frame for frame_reg and sp respectively. */
HOST_WIDE_INT frame_off = 0; HOST_WIDE_INT frame_off = 0;
HOST_WIDE_INT sp_off = 0; HOST_WIDE_INT sp_off = 0;
/* sp_adjust is the stack adjusting instruction, tracked so that the
insn setting up the split-stack arg pointer can be emitted just
prior to it, when r12 is not used here for other purposes. */
rtx_insn *sp_adjust = 0;
#ifdef ENABLE_CHECKING #ifdef ENABLE_CHECKING
/* Track and check usage of r0, r11, r12. */ /* Track and check usage of r0, r11, r12. */
...@@ -23713,7 +23718,10 @@ rs6000_emit_prologue (void) ...@@ -23713,7 +23718,10 @@ rs6000_emit_prologue (void)
ptr_off = info->altivec_save_offset + info->altivec_size; ptr_off = info->altivec_save_offset + info->altivec_size;
frame_off = -ptr_off; frame_off = -ptr_off;
} }
rs6000_emit_allocate_stack (info->total_size, ptr_reg, ptr_off); sp_adjust = rs6000_emit_allocate_stack (info->total_size,
ptr_reg, ptr_off);
if (REGNO (frame_reg_rtx) == 12)
sp_adjust = 0;
sp_off = info->total_size; sp_off = info->total_size;
if (frame_reg_rtx != sp_reg_rtx) if (frame_reg_rtx != sp_reg_rtx)
rs6000_emit_stack_tie (frame_reg_rtx, false); rs6000_emit_stack_tie (frame_reg_rtx, false);
...@@ -23754,7 +23762,8 @@ rs6000_emit_prologue (void) ...@@ -23754,7 +23762,8 @@ rs6000_emit_prologue (void)
if (!WORLD_SAVE_P (info) if (!WORLD_SAVE_P (info)
&& info->cr_save_p && info->cr_save_p
&& REGNO (frame_reg_rtx) != cr_save_regno && REGNO (frame_reg_rtx) != cr_save_regno
&& !(using_static_chain_p && cr_save_regno == 11)) && !(using_static_chain_p && cr_save_regno == 11)
&& !(flag_split_stack && cr_save_regno == 12 && sp_adjust))
{ {
cr_save_rtx = gen_rtx_REG (SImode, cr_save_regno); cr_save_rtx = gen_rtx_REG (SImode, cr_save_regno);
START_USE (cr_save_regno); START_USE (cr_save_regno);
...@@ -23900,6 +23909,8 @@ rs6000_emit_prologue (void) ...@@ -23900,6 +23909,8 @@ rs6000_emit_prologue (void)
int end_save = info->gp_save_offset + info->gp_size; int end_save = info->gp_save_offset + info->gp_size;
int ptr_off; int ptr_off;
if (ptr_regno == 12)
sp_adjust = 0;
if (!ptr_set_up) if (!ptr_set_up)
ptr_reg = gen_rtx_REG (Pmode, ptr_regno); ptr_reg = gen_rtx_REG (Pmode, ptr_regno);
...@@ -24218,7 +24229,10 @@ rs6000_emit_prologue (void) ...@@ -24218,7 +24229,10 @@ rs6000_emit_prologue (void)
} }
else if (REGNO (frame_reg_rtx) == 1) else if (REGNO (frame_reg_rtx) == 1)
frame_off = info->total_size; frame_off = info->total_size;
rs6000_emit_allocate_stack (info->total_size, ptr_reg, ptr_off); sp_adjust = rs6000_emit_allocate_stack (info->total_size,
ptr_reg, ptr_off);
if (REGNO (frame_reg_rtx) == 12)
sp_adjust = 0;
sp_off = info->total_size; sp_off = info->total_size;
if (frame_reg_rtx != sp_reg_rtx) if (frame_reg_rtx != sp_reg_rtx)
rs6000_emit_stack_tie (frame_reg_rtx, false); rs6000_emit_stack_tie (frame_reg_rtx, false);
...@@ -24248,6 +24262,8 @@ rs6000_emit_prologue (void) ...@@ -24248,6 +24262,8 @@ rs6000_emit_prologue (void)
gcc_checking_assert (scratch_regno == 11 || scratch_regno == 12); gcc_checking_assert (scratch_regno == 11 || scratch_regno == 12);
NOT_INUSE (0); NOT_INUSE (0);
if (scratch_regno == 12)
sp_adjust = 0;
if (end_save + frame_off != 0) if (end_save + frame_off != 0)
{ {
rtx offset = GEN_INT (end_save + frame_off); rtx offset = GEN_INT (end_save + frame_off);
...@@ -24325,7 +24341,7 @@ rs6000_emit_prologue (void) ...@@ -24325,7 +24341,7 @@ rs6000_emit_prologue (void)
if ((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) if ((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
&& !using_static_chain_p) && !using_static_chain_p)
save_regno = 11; save_regno = 11;
else if (REGNO (frame_reg_rtx) == 12) else if (flag_split_stack || REGNO (frame_reg_rtx) == 12)
{ {
save_regno = 11; save_regno = 11;
if (using_static_chain_p) if (using_static_chain_p)
...@@ -24371,6 +24387,7 @@ rs6000_emit_prologue (void) ...@@ -24371,6 +24387,7 @@ rs6000_emit_prologue (void)
rtx lr = gen_rtx_REG (Pmode, LR_REGNO); rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
rtx tmp = gen_rtx_REG (Pmode, 12); rtx tmp = gen_rtx_REG (Pmode, 12);
sp_adjust = 0;
insn = emit_move_insn (tmp, lr); insn = emit_move_insn (tmp, lr);
RTX_FRAME_RELATED_P (insn) = 1; RTX_FRAME_RELATED_P (insn) = 1;
...@@ -24433,7 +24450,13 @@ rs6000_emit_prologue (void) ...@@ -24433,7 +24450,13 @@ rs6000_emit_prologue (void)
__morestack was called, it left the arg pointer to the old __morestack was called, it left the arg pointer to the old
stack in r29. Otherwise, the arg pointer is the top of the stack in r29. Otherwise, the arg pointer is the top of the
current frame. */ current frame. */
if (frame_off != 0 || REGNO (frame_reg_rtx) != 12) if (sp_adjust)
{
rtx r12 = gen_rtx_REG (Pmode, 12);
rtx set_r12 = gen_rtx_SET (r12, sp_reg_rtx);
emit_insn_before (set_r12, sp_adjust);
}
else if (frame_off != 0 || REGNO (frame_reg_rtx) != 12)
{ {
rtx r12 = gen_rtx_REG (Pmode, 12); rtx r12 = gen_rtx_REG (Pmode, 12);
if (frame_off == 0) if (frame_off == 0)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment