re PR target/7856 ([arm] invalid offset in constant pool reference)
authorRichard Earnshaw <rearnsha@arm.com>
Fri, 1 Nov 2002 14:41:57 +0000 (14:41 +0000)
committerRichard Earnshaw <rearnsha@gcc.gnu.org>
Fri, 1 Nov 2002 14:41:57 +0000 (14:41 +0000)
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.

From-SVN: r58716

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

index 85f6174594ad523a1a442ff2ffba6d4e9b832400..d904fc4eacc6633d028456957909291dc21e4c39 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 b06cb9bb3373f43a9fd45de1e58d31b3c8f67d87..5c0eea7cd9d8fe43ccde95d7a031623afeeeafcf 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)