arm.c (arm_gen_constant): Add new heuristic for generating constant integers that...
authorRichard Earnshaw <rearnsha@arm.com>
Mon, 9 May 2005 21:55:08 +0000 (21:55 +0000)
committerRichard Earnshaw <rearnsha@gcc.gnu.org>
Mon, 9 May 2005 21:55:08 +0000 (21:55 +0000)
* arm.c (arm_gen_constant): Add new heuristic for generating
constant integers that can be expressed as the difference of two
valid immediates.

From-SVN: r99472

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

index ae7d68e46725f3e1d73c3fcc3d715b7f00ab0ca7..e6fd1afebdcaeb234698261ffbb528755b8844f4 100644 (file)
@@ -1,3 +1,9 @@
+2005-05-09  Richard Earnshaw  <richard.earnshaw@arm.com>
+
+       * arm.c (arm_gen_constant): Add new heuristic for generating
+       constant integers that can be expressed as the difference of two
+       valid immediates.
+
 2005-05-09  Roger Sayle  <roger@eyesopen.com>
 
        * c-tree.h (parser_build_unary_op): New prototype.
index 1743980b1cf809d79e9a60c82775d2b3ccf1b2db..aaa9daaeaecc072b9afab1eab5c1b2a157b056b4 100644 (file)
@@ -1531,8 +1531,8 @@ use_return_insn (int iscond, rtx sibling)
 int
 const_ok_for_arm (HOST_WIDE_INT i)
 {
-  unsigned HOST_WIDE_INT mask = ~(unsigned HOST_WIDE_INT)0xFF;
-
+  int lowbit;
+  
   /* For machines with >32 bit HOST_WIDE_INT, the bits above bit 31 must
      be all zero, or all one.  */
   if ((i & ~(unsigned HOST_WIDE_INT) 0xffffffff) != 0
@@ -1541,19 +1541,24 @@ const_ok_for_arm (HOST_WIDE_INT i)
              & ~(unsigned HOST_WIDE_INT) 0xffffffff)))
     return FALSE;
 
-  /* Fast return for 0 and powers of 2 */
-  if ((i & (i - 1)) == 0)
+  i &= (unsigned HOST_WIDE_INT) 0xffffffff;
+  
+  /* Fast return for 0 and small values.  We must do this for zero, since
+     the code below can't handle that one case.  */
+  if ((i & ~(unsigned HOST_WIDE_INT) 0xff) == 0)
     return TRUE;
 
-  do
-    {
-      if ((i & mask & (unsigned HOST_WIDE_INT) 0xffffffff) == 0)
-        return TRUE;
-      mask =
-         (mask << 2) | ((mask & (unsigned HOST_WIDE_INT) 0xffffffff)
-                         >> (32 - 2)) | ~(unsigned HOST_WIDE_INT) 0xffffffff;
-    }
-  while (mask != ~(unsigned HOST_WIDE_INT) 0xFF);
+  /* Get the number of trailing zeros, rounded down to the nearest even
+     number.  */
+  lowbit = (ffs ((int) i) - 1) & ~1;
+
+  if ((i & ~(((unsigned HOST_WIDE_INT) 0xff) << lowbit)) == 0)
+    return TRUE;
+  else if (lowbit <= 4
+          && ((i & ~0xc000003f) == 0
+              || (i & ~0xf000000f) == 0
+              || (i & ~0xfc000003) == 0))
+    return TRUE;
 
   return FALSE;
 }