rl78.c (need_to_save): Change return type to bool.
authorNick Clifton <nickc@redhat.com>
Tue, 17 Sep 2013 21:10:38 +0000 (21:10 +0000)
committerDJ Delorie <dj@gcc.gnu.org>
Tue, 17 Sep 2013 21:10:38 +0000 (17:10 -0400)
* config/rl78/rl78.c (need_to_save): Change return type to bool.
For interrupt functions: save all call clobbered registers if the
interrupt handler is not a leaf function.
(rl78_expand_prologue): Always recompute the frame information.
For interrupt functions: only select bank 0 if one of the bank 0
registers is going to be psuhed.

From-SVN: r202667

gcc/ChangeLog
gcc/config/rl78/rl78.c

index 2b0d211faf60b14a9760ce05833ac15a815bc814..fc511f0570d00d66997b73fc5b336dffe61fd158 100644 (file)
@@ -1,3 +1,12 @@
+2013-09-17  Nick Clifton  <nickc@redhat.com>
+
+       * config/rl78/rl78.c (need_to_save): Change return type to bool.
+       For interrupt functions: save all call clobbered registers if the
+       interrupt handler is not a leaf function.
+       (rl78_expand_prologue): Always recompute the frame information.
+       For interrupt functions: only select bank 0 if one of the bank 0
+       registers is going to be psuhed.
+
 2013-09-17  DJ Delorie  <dj@redhat.com>
 
        * config/rl78/constraints.md: For each W* constraint, rename to C*
index e7bd3deac7d59d8205021526c82e3530e4b0e514..70e1dee2f1456af7508c8ef2fd282a7270ffd880 100644 (file)
@@ -540,34 +540,39 @@ rl78_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to ATTRIBUTE_UNUS
   return true;
 }
 
-/* Returns nonzero if the given register needs to be saved by the
+/* Returns true if the given register needs to be saved by the
    current function.  */
-static int
-need_to_save (int regno)
+static bool
+need_to_save (unsigned int regno)
 {
   if (is_interrupt_func (cfun->decl))
     {
-      if (regno < 8)
-       return 1; /* don't know what devirt will need */
+       /* We don't need to save registers that have
+         been reserved for interrupt handlers.  */
       if (regno > 23)
-       return 0; /* don't need to save interrupt registers */
-      if (crtl->is_leaf)
-       {
-         return df_regs_ever_live_p (regno);
-       }
-      else
-       return 1;
+       return false;
+
+      /* If the handler is a non-leaf function then it may call
+        non-interrupt aware routines which will happily clobber
+        any call_used registers, so we have to preserve them.  */
+      if (!crtl->is_leaf && call_used_regs[regno])
+       return true;
+
+      /* Otherwise we only have to save a register, call_used
+        or not, if it is used by this handler.  */
+      return df_regs_ever_live_p (regno);
     }
+
   if (regno == FRAME_POINTER_REGNUM && frame_pointer_needed)
-    return 1;
+    return true;
   if (fixed_regs[regno])
-    return 0;
+    return false;
   if (crtl->calls_eh_return)
-    return 1;
+    return true;
   if (df_regs_ever_live_p (regno)
       && !call_used_regs[regno])
-    return 1;
-  return 0;
+    return true;
+  return false;
 }
 
 /* We use this to wrap all emitted insns in the prologue.  */
@@ -1026,14 +1031,20 @@ rl78_expand_prologue (void)
   if (rl78_is_naked_func ())
     return;
 
-  if (!cfun->machine->computed)
-    rl78_compute_frame_info ();
+  /* Always re-compute the frame info - the register usage may have changed.  */
+  rl78_compute_frame_info ();
 
   if (flag_stack_usage_info)
     current_function_static_stack_size = cfun->machine->framesize;
 
   if (is_interrupt_func (cfun->decl) && !TARGET_G10)
-    emit_insn (gen_sel_rb (GEN_INT (0)));
+    for (i = 0; i < 4; i++)
+      if (cfun->machine->need_to_push [i])
+       {
+         /* Select Bank 0 if we are using any registers from Bank 0.   */
+         emit_insn (gen_sel_rb (GEN_INT (0)));
+         break;
+       }
 
   for (i = 0; i < 16; i++)
     if (cfun->machine->need_to_push [i])