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

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

index d05b99b623f344c3089dc629617a66c1a65304c0..bf62e0fca5193e893d9e03f50e57fd6b783ccad1 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.
+
 Thu Oct 31 18:31:22 CET 2002  Jan Hubicka  <jh@suse.cz>
 
        * i386.c (override_options): Set defaults for flag_omit_frame_pointer,
index f07a281f4a3691aeaa86694647f1666b788e1a84..8c696c6fd8e71c58e1449c3348931a0c8743b735 100644 (file)
@@ -890,6 +890,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)
@@ -912,23 +913,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)