Committed.

2013-09-17  Nick Clifton  <ni...@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.

Index: config/rl78/rl78.c
===================================================================
--- config/rl78/rl78.c  (revision 202666)
+++ config/rl78/rl78.c  (working copy)
@@ -537,40 +537,45 @@ rl78_force_nonfar_3 (rtx *operands, rtx 
 static bool
 rl78_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to 
ATTRIBUTE_UNUSED)
 {
   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.  */
 static rtx
 F (rtx x)
 {
@@ -1023,20 +1028,26 @@ rl78_expand_prologue (void)
   rtx sp = gen_rtx_REG (HImode, STACK_POINTER_REGNUM);
   int rb = 0;
 
   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])
       {
        if (TARGET_G10)
          {

Reply via email to