aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2015-05-28 07:16:51 +0000
committerNick Clifton <nickc@gcc.gnu.org>2015-05-28 07:16:51 +0000
commit55ffa75632e635c049c238db332c20de1b3116c2 (patch)
treef3a694ae8b01dca33cfbef5748c76cca1667f7fa /gcc
parent1a4b99c172b8a5485d84e24db16ccbd847a4b1b7 (diff)
downloadgcc-55ffa75632e635c049c238db332c20de1b3116c2.zip
gcc-55ffa75632e635c049c238db332c20de1b3116c2.tar.gz
gcc-55ffa75632e635c049c238db332c20de1b3116c2.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/config/rx/rx.c73
2 files changed, 61 insertions, 21 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 8742a22..712dacc 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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>
* tree-vectorizer.h (struct _slp_instance): Remove body_cost_vec
diff --git a/gcc/config/rx/rx.c b/gcc/config/rx/rx.c
index fd985f5..4c1c5d1 100644
--- a/gcc/config/rx/rx.c
+++ b/gcc/config/rx/rx.c
@@ -1567,6 +1567,10 @@ rx_get_stack_layout (unsigned int * lowest,
has specified --fixed-<reg-name> on the command line and in such
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 ? */
pushed_mask = (-1 << low) & ~(-1 << (high + 1));
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;
}
+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
rx_expand_prologue (void)
{
@@ -1725,7 +1742,6 @@ rx_expand_prologue (void)
unsigned int low;
unsigned int high;
unsigned int reg;
- rtx insn;
/* Naked functions use their own, programmer provided prologues. */
if (is_naked_func (NULL_TREE))
@@ -1735,7 +1751,7 @@ rx_expand_prologue (void)
if (flag_stack_usage_info)
current_function_static_stack_size = frame_size + stack_size;
-
+
/* If we use any of the callee-saved registers, save them now. */
if (mask)
{
@@ -1743,20 +1759,25 @@ rx_expand_prologue (void)
for (reg = CC_REGNUM; reg --;)
if (mask & (1 << reg))
{
- insn = emit_insn (gen_stack_push (gen_rtx_REG (SImode, reg)));
- mark_frame_related (insn);
+ low = high = reg;
+
+ /* 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)
- {
- 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);
- }
+ push_regs (high, low);
if (MUST_SAVE_ACC_REGISTER)
{
@@ -2031,6 +2052,16 @@ rx_can_use_simple_return (void)
&& 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
rx_expand_epilogue (bool is_sibcall)
{
@@ -2143,16 +2174,16 @@ rx_expand_epilogue (bool is_sibcall)
{
for (reg = 0; reg < CC_REGNUM; 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)
- {
- 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)));
- }
+ pop_regs (high, low);
if (is_fast_interrupt_func (NULL_TREE))
{