rx.c (push_regs): New function.
authorNick Clifton <nickc@redhat.com>
Thu, 28 May 2015 07:16:51 +0000 (07:16 +0000)
committerNick Clifton <nickc@gcc.gnu.org>
Thu, 28 May 2015 07:16:51 +0000 (07:16 +0000)
* 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

gcc/ChangeLog
gcc/config/rx/rx.c

index 8742a222141b485df0e43671d6c72598d0287a21..712dacc8f07f8a7875431a5a26de5f1c36a11a15 100644 (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>
 
        * tree-vectorizer.h (struct _slp_instance): Remove body_cost_vec
index fd985f5fc944cbdf98058a863f81e42bae121b06..4c1c5d161f1ed9c3ae34d6d066a4e6c01caa826a 100644 (file)
@@ -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))
        {