rx.c (push_regs): New function.

* config/rx/rx.c (push_regs): New function.  Extracts code from...
	(rx_expand_prologue): ... here.  Use push_regs to push even small
	spans of registers.
	(pop_regs): New function.
	(rx_expand_epilogue):  Use pop_regs to pop even small spans of
	registers.

From-SVN: r223799
This commit is contained in:
Nick Clifton 2015-05-28 07:16:51 +00:00 committed by Nick Clifton
parent 1a4b99c172
commit 55ffa75632
2 changed files with 61 additions and 21 deletions

View File

@ -1,3 +1,12 @@
2015-05-28 Nick Clifton <nickc@redhat.com>
* config/rx/rx.c (push_regs): New function. Extracts code from...
(rx_expand_prologue): ... here. Use push_regs to push even small
spans of registers.
(pop_regs): New function.
(rx_expand_epilogue): Use pop_regs to pop even small spans of
registers.
2015-05-28 Richard Biener <rguenther@suse.de> 2015-05-28 Richard Biener <rguenther@suse.de>
* tree-vectorizer.h (struct _slp_instance): Remove body_cost_vec * tree-vectorizer.h (struct _slp_instance): Remove body_cost_vec

View File

@ -1567,6 +1567,10 @@ rx_get_stack_layout (unsigned int * lowest,
has specified --fixed-<reg-name> on the command line and in such has specified --fixed-<reg-name> on the command line and in such
circumstances we do not want to touch the fixed registers at all. circumstances we do not want to touch the fixed registers at all.
Note also that the code in the prologue/epilogue handlers will
automatically merge multiple PUSHes of adjacent registers into a single
PUSHM.
FIXME: Is it worth improving this heuristic ? */ FIXME: Is it worth improving this heuristic ? */
pushed_mask = (-1 << low) & ~(-1 << (high + 1)); pushed_mask = (-1 << low) & ~(-1 << (high + 1));
unneeded_pushes = (pushed_mask & (~ save_mask)) & pushed_mask; unneeded_pushes = (pushed_mask & (~ save_mask)) & pushed_mask;
@ -1716,6 +1720,19 @@ gen_safe_add (rtx dest, rtx src, rtx val, bool is_frame_related)
return; return;
} }
static void
push_regs (unsigned int high, unsigned int low)
{
rtx insn;
if (low == high)
insn = emit_insn (gen_stack_push (gen_rtx_REG (SImode, low)));
else
insn = emit_insn (gen_stack_pushm (GEN_INT (((high - low) + 1) * UNITS_PER_WORD),
gen_rx_store_vector (low, high)));
mark_frame_related (insn);
}
void void
rx_expand_prologue (void) rx_expand_prologue (void)
{ {
@ -1725,7 +1742,6 @@ rx_expand_prologue (void)
unsigned int low; unsigned int low;
unsigned int high; unsigned int high;
unsigned int reg; unsigned int reg;
rtx insn;
/* Naked functions use their own, programmer provided prologues. */ /* Naked functions use their own, programmer provided prologues. */
if (is_naked_func (NULL_TREE)) if (is_naked_func (NULL_TREE))
@ -1743,20 +1759,25 @@ rx_expand_prologue (void)
for (reg = CC_REGNUM; reg --;) for (reg = CC_REGNUM; reg --;)
if (mask & (1 << reg)) if (mask & (1 << reg))
{ {
insn = emit_insn (gen_stack_push (gen_rtx_REG (SImode, reg))); low = high = reg;
mark_frame_related (insn);
/* Look for a span of registers.
Note - we do not have to worry about -Os and whether
it is better to use a single, longer PUSHM as
rx_get_stack_layout has already done that for us. */
while (reg-- > 0)
if ((mask & (1 << reg)) == 0)
break;
else
--low;
push_regs (high, low);
if (reg == (unsigned) -1)
break;
} }
} }
else if (low) else if (low)
{ push_regs (high, low);
if (high == low)
insn = emit_insn (gen_stack_push (gen_rtx_REG (SImode, low)));
else
insn = emit_insn (gen_stack_pushm (GEN_INT (((high - low) + 1)
* UNITS_PER_WORD),
gen_rx_store_vector (low, high)));
mark_frame_related (insn);
}
if (MUST_SAVE_ACC_REGISTER) if (MUST_SAVE_ACC_REGISTER)
{ {
@ -2031,6 +2052,16 @@ rx_can_use_simple_return (void)
&& low == 0); && low == 0);
} }
static void
pop_regs (unsigned int high, unsigned int low)
{
if (high == low)
emit_insn (gen_stack_pop (gen_rtx_REG (SImode, low)));
else
emit_insn (gen_stack_popm (GEN_INT (((high - low) + 1) * UNITS_PER_WORD),
gen_rx_popm_vector (low, high)));
}
void void
rx_expand_epilogue (bool is_sibcall) rx_expand_epilogue (bool is_sibcall)
{ {
@ -2143,16 +2174,16 @@ rx_expand_epilogue (bool is_sibcall)
{ {
for (reg = 0; reg < CC_REGNUM; reg ++) for (reg = 0; reg < CC_REGNUM; reg ++)
if (register_mask & (1 << reg)) if (register_mask & (1 << reg))
emit_insn (gen_stack_pop (gen_rtx_REG (SImode, reg))); {
low = high = reg;
while (register_mask & (1 << high))
high ++;
pop_regs (high - 1, low);
reg = high;
}
} }
else if (low) else if (low)
{ pop_regs (high, low);
if (high == low)
emit_insn (gen_stack_pop (gen_rtx_REG (SImode, low)));
else
emit_insn (gen_stack_popm (GEN_INT (regs_size),
gen_rx_popm_vector (low, high)));
}
if (is_fast_interrupt_func (NULL_TREE)) if (is_fast_interrupt_func (NULL_TREE))
{ {