OSDN Git Service

Make `solaris' reflect the most recent major release.
[pf3gnuchains/gcc-fork.git] / gcc / combine.c
index d986f7d..5b44d66 100644 (file)
@@ -74,6 +74,9 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
    combine anyway.  */
 
 #include "config.h"
+/* Must precede rtl.h for FFS.  */
+#include <stdio.h>
+
 #include "gvarargs.h"
 #include "rtl.h"
 #include "flags.h"
@@ -87,7 +90,6 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "insn-attr.h"
 #include "recog.h"
 #include "real.h"
-#include <stdio.h>
 
 /* It is not safe to use ordinary gen_lowpart in combine.
    Use gen_lowpart_for_combine instead.  See comments there.  */
@@ -2945,7 +2947,7 @@ subst (x, from, to, in_dest, unique_copy)
        || code == MULT || code == AND || code == IOR || code == XOR
        || code == DIV || code == UDIV
        || code == SMAX || code == SMIN || code == UMAX || code == UMIN)
-      && GET_MODE_CLASS (mode) == MODE_INT)
+      && INTEGRAL_MODE_P (mode))
     {
       if (GET_CODE (XEXP (x, 0)) == code)
        {
@@ -3235,7 +3237,7 @@ subst (x, from, to, in_dest, unique_copy)
 
       /* (neg (minus X Y)) can become (minus Y X).  */
       if (GET_CODE (XEXP (x, 0)) == MINUS
-         && (GET_MODE_CLASS (mode) != MODE_FLOAT
+         && (! FLOAT_MODE_P (mode)
              /* x-y != -(y-x) with IEEE floating point. */
              || TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT))
        {
@@ -3330,7 +3332,7 @@ subst (x, from, to, in_dest, unique_copy)
 
       /* In IEEE floating point, x-0 is not the same as x.  */
       if ((TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT
-          || GET_MODE_CLASS (GET_MODE (XEXP (x, 0))) == MODE_INT)
+          || ! FLOAT_MODE_P (GET_MODE (XEXP (x, 0))))
          && XEXP (x, 1) == CONST0_RTX (GET_MODE (XEXP (x, 0))))
        return XEXP (x, 0);
       break;
@@ -3394,7 +3396,22 @@ subst (x, from, to, in_dest, unique_copy)
          goto restart;
        }
 
-      /* If only the low-order bit of X is possible nonzero, (plus x -1)
+      /* (plus (comparison A B) C) can become (neg (rev-comp A B)) if
+        C is 1 and STORE_FLAG_VALUE is -1 or if C is -1 and STORE_FLAG_VALUE
+        is 1.  This produces better code than the alternative immediately
+        below.  */
+      if (GET_RTX_CLASS (GET_CODE (XEXP (x, 0))) == '<'
+         && reversible_comparison_p (XEXP (x, 0))
+         && ((STORE_FLAG_VALUE == -1 && XEXP (x, 1) == const1_rtx)
+             || (STORE_FLAG_VALUE == 1 && XEXP (x, 1) == constm1_rtx)))
+       {
+         x = gen_binary (reverse_condition (GET_CODE (XEXP (x, 0))),
+                         mode, XEXP (XEXP (x, 0), 0), XEXP (XEXP (x, 0), 1));
+         x = gen_unary (NEG, mode, x);
+         goto restart;
+       }
+
+      /* If only the low-order bit of X is possibly nonzero, (plus x -1)
         can become (ashiftrt (ashift (xor x 1) C) C) where C is
         the bitsize of the mode - 1.  This allows simplification of
         "a = (b & 8) == 0;"  */
@@ -3703,7 +3720,7 @@ subst (x, from, to, in_dest, unique_copy)
 
       /* Look for MIN or MAX.  */
 
-      if (GET_MODE_CLASS (mode) == MODE_INT
+      if (! FLOAT_MODE_P (mode)
          && GET_RTX_CLASS (GET_CODE (XEXP (x, 0))) == '<'
          && rtx_equal_p (XEXP (XEXP (x, 0), 0), XEXP (x, 1))
          && rtx_equal_p (XEXP (XEXP (x, 0), 1), XEXP (x, 2))
@@ -3824,12 +3841,10 @@ subst (x, from, to, in_dest, unique_copy)
 
       if (GET_CODE (XEXP (x, 0)) == NE && XEXP (XEXP (x, 0), 1) == const0_rtx
          && XEXP (x, 2) == const0_rtx && GET_CODE (XEXP (x, 1)) == CONST_INT
-         && ((1 == nonzero_bits (XEXP (XEXP (x, 0), 0),
-                                 GET_MODE (XEXP (XEXP (x, 0), 0)))
+         && ((1 == nonzero_bits (XEXP (XEXP (x, 0), 0), mode)
               && (i = exact_log2 (INTVAL (XEXP (x, 1)))) >= 0)
-             || ((num_sign_bit_copies (XEXP (XEXP (x, 0), 0),
-                                       GET_MODE (XEXP (XEXP (x, 0), 0)))
-                  == GET_MODE_BITSIZE (GET_MODE (XEXP (XEXP (x, 0), 0))))
+             || ((num_sign_bit_copies (XEXP (XEXP (x, 0), 0), mode)
+                  == GET_MODE_BITSIZE (mode))
                  && (i = exact_log2 (- INTVAL (XEXP (x, 1)))) >= 0)))
        return
          simplify_shift_const (NULL_RTX, ASHIFT, mode,
@@ -3999,7 +4014,7 @@ subst (x, from, to, in_dest, unique_copy)
         means that we only care about the low bits of the result.
 
         However, on most machines (those with neither BYTE_LOADS_ZERO_EXTEND
-        nor BYTES_LOADS_SIGN_EXTEND defined), we cannot perform a
+        nor BYTE_LOADS_SIGN_EXTEND defined), we cannot perform a
         narrower operation that requested since the high-order bits will
         be undefined.  On machine where BYTE_LOADS_*_EXTEND is defined,
         however, this transformation is safe as long as M1 and M2 have
@@ -5775,7 +5790,7 @@ apply_distributive_law (x)
   /* Distributivity is not true for floating point.
      It can change the value.  So don't do it.
      -- rms and moshier@world.std.com.  */
-  if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT)
+  if (FLOAT_MODE_P (GET_MODE (x)))
     return x;
 
   /* The outer operation can only be one of the following:  */
@@ -6105,7 +6120,10 @@ simplify_and_const_int (x, mode, varop, constop)
                   + num_sign_bit_copies (XEXP (varop, 0),
                                          GET_MODE (XEXP (varop, 0))))
                  >= GET_MODE_BITSIZE (GET_MODE (varop)))
-             && exact_log2 (constop + 1) >= 0)
+             && exact_log2 (constop + 1) >= 0
+             && (num_sign_bit_copies (XEXP (varop, 0),
+                                      GET_MODE (XEXP (varop, 0)))
+                 >= exact_log2 (constop + 1)))
            varop
              = gen_rtx_combine (LSHIFTRT, GET_MODE (varop), XEXP (varop, 0),
                                 GEN_INT (GET_MODE_BITSIZE (GET_MODE (varop))
@@ -8715,7 +8733,7 @@ simplify_comparison (code, pop0, pop1)
              && ((INTVAL (XEXP (op0, 1)) + ! equality_comparison_p)
                  < HOST_BITS_PER_WIDE_INT)
              && ((const_op
-                  &  ((HOST_WIDE_INT) 1 << INTVAL (XEXP (op0, 1))) - 1) == 0)
+                  & (((HOST_WIDE_INT) 1 << INTVAL (XEXP (op0, 1))) - 1)) == 0)
              && mode_width <= HOST_BITS_PER_WIDE_INT
              && (nonzero_bits (XEXP (op0, 0), mode)
                  & ~ (mask >> (INTVAL (XEXP (op0, 1))
@@ -8925,12 +8943,14 @@ reversible_comparison_p (x)
   switch (GET_MODE_CLASS (GET_MODE (XEXP (x, 0))))
     {
     case MODE_INT:
+    case MODE_PARTIAL_INT:
+    case MODE_COMPLEX_INT:
       return 1;
 
     case MODE_CC:
       x = get_last_value (XEXP (x, 0));
       return (x && GET_CODE (x) == COMPARE
-             && GET_MODE_CLASS (GET_MODE (XEXP (x, 0))) == MODE_INT);
+             && ! FLOAT_MODE_P (GET_MODE (XEXP (x, 0))));
     }
 
   return 0;