PR target/7856
authorrearnsha <rearnsha@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 1 Nov 2002 14:41:57 +0000 (14:41 +0000)
committerrearnsha <rearnsha@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 1 Nov 2002 14:41:57 +0000 (14:41 +0000)
* arm.c (use_return_insn): Don't use a return insn if there are
saved integer regs, but LR is not one of them.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@58716 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/arm/arm.c

index 85f6174..d904fc4 100644 (file)
@@ -1,3 +1,9 @@
+2002-11-01  Richard Earnshaw  (rearnsha@arm.com)
+
+       PR target/7856
+       * arm.c (use_return_insn): Don't use a return insn if there are
+       saved integer regs, but LR is not one of them.
+
 Fri Nov  1 10:33:15 CET 2002  Jan Hubicka  <jh@suse.cz>
 
        * expr.c (emit_move_insn):  Use SCALAR_FLOAT_MODE_P
index b06cb9b..5c0eea7 100644 (file)
@@ -909,6 +909,7 @@ use_return_insn (iscond)
 {
   int regno;
   unsigned int func_type;
+  unsigned long saved_int_regs;
 
   /* Never use a return instruction before reload has run.  */
   if (!reload_completed)
@@ -931,23 +932,31 @@ use_return_insn (iscond)
          && !frame_pointer_needed))
     return 0;
 
+  saved_int_regs = arm_compute_save_reg_mask ();
+
   /* Can't be done if interworking with Thumb, and any registers have been
-     stacked.  Similarly, on StrongARM, conditional returns are expensive
-     if they aren't taken and registers have been stacked.  */
-  if (iscond && arm_is_strong && frame_pointer_needed)
+     stacked.  */
+  if (TARGET_INTERWORK && saved_int_regs != 0)
     return 0;
-  
-  if ((iscond && arm_is_strong)
-      || TARGET_INTERWORK)
+
+  /* On StrongARM, conditional returns are expensive if they aren't
+     taken and multiple registers have been stacked.  */
+  if (iscond && arm_is_strong)
     {
-      for (regno = 0; regno <= LAST_ARM_REGNUM; regno++)
-       if (regs_ever_live[regno] && !call_used_regs[regno])
-         return 0;
+      /* Conditional return when just the LR is stored is a simple 
+        conditional-load instruction, that's not expensive.  */
+      if (saved_int_regs != 0 && saved_int_regs != (1 << LR_REGNUM))
+       return 0;
 
       if (flag_pic && regs_ever_live[PIC_OFFSET_TABLE_REGNUM])
        return 0;
     }
-      
+
+  /* If there are saved registers but the LR isn't saved, then we need
+     two instructions for the return.  */
+  if (saved_int_regs && !(saved_int_regs & (1 << LR_REGNUM)))
+    return 0;
+
   /* Can't be done if any of the FPU regs are pushed,
      since this also requires an insn.  */
   if (TARGET_HARD_FLOAT)