OSDN Git Service

* double-int.h (HOST_BITS_PER_DOUBLE_INT): Define.
authoraesok <aesok@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 14 Apr 2010 22:05:32 +0000 (22:05 +0000)
committeraesok <aesok@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 14 Apr 2010 22:05:32 +0000 (22:05 +0000)
(double_int_not, double_int_lshift, double_int_rshift): Declare.
(double_int_negative_p): Convert to static inline function.
* double-int.c (double_int_lshift, double_int_lshift): Add new function.
(double_int_negative_p): Remove.
* tree.h (lshift_double, rshift_double):
* tree.c (build_low_bits_mask): Clean up, use double_int_* functions.
* fold-const.c (fold_convert_const_int_from_real,
fold_convert_const_int_from_fixed, div_if_zero_remainder): (Ditto.).
(lshift_double): Change type of arith argument to bool.
(rshift_double): Change type of arith argument to bool. Correct
comment.
* expmed.c (mask_rtx, lshift_value): (Ditto.).

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

gcc/ChangeLog
gcc/double-int.c
gcc/double-int.h
gcc/expmed.c
gcc/fold-const.c
gcc/tree.c
gcc/tree.h

index b09f10f..35a1633 100644 (file)
@@ -1,3 +1,19 @@
+2010-04-15  Anatoly Sokolov  <aesok@post.ru>
+
+       * double-int.h (HOST_BITS_PER_DOUBLE_INT): Define.
+       (double_int_not, double_int_lshift, double_int_rshift): Declare.
+       (double_int_negative_p): Convert to static inline function.
+       * double-int.c (double_int_lshift, double_int_lshift): Add new function.
+       (double_int_negative_p): Remove.
+       * tree.h (lshift_double, rshift_double): 
+       * tree.c (build_low_bits_mask): Clean up, use double_int_* functions.
+       * fold-const.c (fold_convert_const_int_from_real,
+       fold_convert_const_int_from_fixed, div_if_zero_remainder): (Ditto.).
+       (lshift_double): Change type of arith argument to bool.
+       (rshift_double): Change type of arith argument to bool. Correct
+       comment.
+       * expmed.c (mask_rtx, lshift_value): (Ditto.).
+
 2010-04-14  Bernd Schmidt  <bernd.schmidt@codesourcery.com>
        
        PR target/21803
index a49ce47..1a74681 100644 (file)
@@ -1,5 +1,5 @@
 /* Operations with long integers.
-   Copyright (C) 2006, 2007, 2009 Free Software Foundation, Inc.
+   Copyright (C) 2006, 2007, 2009, 2010 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -290,6 +290,30 @@ double_int_umod (double_int a, double_int b, unsigned code)
   return double_int_mod (a, b, true, code);
 }
 
+/* Shift A left by COUNT places keeping only PREC bits of result.  Shift
+   right if COUNT is negative.  ARITH true specifies arithmetic shifting;
+   otherwise use logical shift.  */
+
+double_int
+double_int_lshift (double_int a, HOST_WIDE_INT count, unsigned int prec, bool arith)
+{
+  double_int ret;
+  lshift_double (a.low, a.high, count, prec, &ret.low, &ret.high, arith);
+  return ret;
+}
+
+/* Shift A rigth by COUNT places keeping only PREC bits of result.  Shift
+   left if COUNT is negative.  ARITH true specifies arithmetic shifting;
+   otherwise use logical shift.  */
+
+double_int
+double_int_rshift (double_int a, HOST_WIDE_INT count, unsigned int prec, bool arith)
+{
+  double_int ret;
+  rshift_double (a.low, a.high, count, prec, &ret.low, &ret.high, arith);
+  return ret;
+}
+
 /* Constructs tree in type TYPE from with value given by CST.  Signedness of CST
    is assumed to be the same as the signedness of TYPE.  */
 
@@ -314,15 +338,6 @@ double_int_fits_to_tree_p (const_tree type, double_int cst)
   return double_int_equal_p (cst, ext);
 }
 
-/* Returns true if CST is negative.  Of course, CST is considered to
-   be signed.  */
-
-bool
-double_int_negative_p (double_int cst)
-{
-  return cst.high < 0;
-}
-
 /* Returns -1 if A < B, 0 if A == B and 1 if A > B.  Signedness of the
    comparison is given by UNS.  */
 
index 8418589..30e32fc 100644 (file)
@@ -1,5 +1,5 @@
 /* Operations with long integers.
-   Copyright (C) 2006, 2007, 2008 Free Software Foundation, Inc.
+   Copyright (C) 2006, 2007, 2008, 2010 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -57,6 +57,8 @@ typedef struct
   HOST_WIDE_INT high;
 } double_int;
 
+#define HOST_BITS_PER_DOUBLE_INT (2 * HOST_BITS_PER_WIDE_INT)
+
 union tree_node;
 
 /* Constructors and conversions.  */
@@ -127,7 +129,29 @@ double_int double_int_umod (double_int, double_int, unsigned);
 double_int double_int_divmod (double_int, double_int, bool, unsigned, double_int *);
 double_int double_int_sdivmod (double_int, double_int, unsigned, double_int *);
 double_int double_int_udivmod (double_int, double_int, unsigned, double_int *);
-bool double_int_negative_p (double_int);
+
+/* Logical operations.  */
+static inline double_int
+double_int_not (double_int a)
+{
+  a.low = ~a.low;
+  a.high = ~ a.high;
+  return a;
+}
+
+/* Shift operations.  */
+double_int double_int_lshift (double_int, HOST_WIDE_INT, unsigned int, bool);
+double_int double_int_rshift (double_int, HOST_WIDE_INT, unsigned int, bool);
+
+/* Returns true if CST is negative.  Of course, CST is considered to
+   be signed.  */
+
+static inline bool
+double_int_negative_p (double_int cst)
+{
+  return cst.high < 0;
+}
+
 int double_int_cmp (double_int, double_int, bool);
 int double_int_scmp (double_int, double_int);
 int double_int_ucmp (double_int, double_int);
index aa24099..44de4a6 100644 (file)
@@ -1839,39 +1839,15 @@ extract_fixed_bit_field (enum machine_mode tmode, rtx op0,
 static rtx
 mask_rtx (enum machine_mode mode, int bitpos, int bitsize, int complement)
 {
-  HOST_WIDE_INT masklow, maskhigh;
+  double_int mask;
 
-  if (bitsize == 0)
-    masklow = 0;
-  else if (bitpos < HOST_BITS_PER_WIDE_INT)
-    masklow = (HOST_WIDE_INT) -1 << bitpos;
-  else
-    masklow = 0;
-
-  if (bitpos + bitsize < HOST_BITS_PER_WIDE_INT)
-    masklow &= ((unsigned HOST_WIDE_INT) -1
-               >> (HOST_BITS_PER_WIDE_INT - bitpos - bitsize));
-
-  if (bitpos <= HOST_BITS_PER_WIDE_INT)
-    maskhigh = -1;
-  else
-    maskhigh = (HOST_WIDE_INT) -1 << (bitpos - HOST_BITS_PER_WIDE_INT);
-
-  if (bitsize == 0)
-    maskhigh = 0;
-  else if (bitpos + bitsize > HOST_BITS_PER_WIDE_INT)
-    maskhigh &= ((unsigned HOST_WIDE_INT) -1
-                >> (2 * HOST_BITS_PER_WIDE_INT - bitpos - bitsize));
-  else
-    maskhigh = 0;
+  mask = double_int_mask (bitsize);
+  mask = double_int_lshift (mask, bitpos, HOST_BITS_PER_DOUBLE_INT, false);
 
   if (complement)
-    {
-      maskhigh = ~maskhigh;
-      masklow = ~masklow;
-    }
+    mask = double_int_not (mask);
 
-  return immed_double_const (masklow, maskhigh, mode);
+  return immed_double_const (mask.low, mask.high, mode);
 }
 
 /* Return a constant integer (CONST_INT or CONST_DOUBLE) rtx with the value
@@ -1880,24 +1856,12 @@ mask_rtx (enum machine_mode mode, int bitpos, int bitsize, int complement)
 static rtx
 lshift_value (enum machine_mode mode, rtx value, int bitpos, int bitsize)
 {
-  unsigned HOST_WIDE_INT v = INTVAL (value);
-  HOST_WIDE_INT low, high;
-
-  if (bitsize < HOST_BITS_PER_WIDE_INT)
-    v &= ~((HOST_WIDE_INT) -1 << bitsize);
-
-  if (bitpos < HOST_BITS_PER_WIDE_INT)
-    {
-      low = v << bitpos;
-      high = (bitpos > 0 ? (v >> (HOST_BITS_PER_WIDE_INT - bitpos)) : 0);
-    }
-  else
-    {
-      low = 0;
-      high = v << (bitpos - HOST_BITS_PER_WIDE_INT);
-    }
+  double_int val;
+  
+  val = double_int_zext (uhwi_to_double_int (INTVAL (value)), bitsize);
+  val = double_int_lshift (val, bitpos, HOST_BITS_PER_DOUBLE_INT, false);
 
-  return immed_double_const (low, high, mode);
+  return immed_double_const (val.low, val.high, mode);
 }
 \f
 /* Extract a bit field that is split across two words
index 34e5874..c3fcaa5 100644 (file)
@@ -436,7 +436,7 @@ mul_double_with_sign (unsigned HOST_WIDE_INT l1, HOST_WIDE_INT h1,
 void
 lshift_double (unsigned HOST_WIDE_INT l1, HOST_WIDE_INT h1,
               HOST_WIDE_INT count, unsigned int prec,
-              unsigned HOST_WIDE_INT *lv, HOST_WIDE_INT *hv, int arith)
+              unsigned HOST_WIDE_INT *lv, HOST_WIDE_INT *hv, bool arith)
 {
   unsigned HOST_WIDE_INT signmask;
 
@@ -491,7 +491,7 @@ lshift_double (unsigned HOST_WIDE_INT l1, HOST_WIDE_INT h1,
 }
 
 /* Shift the doubleword integer in L1, H1 right by COUNT places
-   keeping only PREC bits of result.  COUNT must be positive.
+   keeping only PREC bits of result.  Shift left if COUNT is negative.
    ARITH nonzero specifies arithmetic shifting; otherwise use logical shift.
    Store the value as two `HOST_WIDE_INT' pieces in *LV and *HV.  */
 
@@ -499,7 +499,7 @@ void
 rshift_double (unsigned HOST_WIDE_INT l1, HOST_WIDE_INT h1,
               HOST_WIDE_INT count, unsigned int prec,
               unsigned HOST_WIDE_INT *lv, HOST_WIDE_INT *hv,
-              int arith)
+              bool arith)
 {
   unsigned HOST_WIDE_INT signmask;
 
@@ -881,10 +881,7 @@ div_and_round_double (enum tree_code code, int uns,
 tree
 div_if_zero_remainder (enum tree_code code, const_tree arg1, const_tree arg2)
 {
-  unsigned HOST_WIDE_INT int1l, int2l;
-  HOST_WIDE_INT int1h, int2h;
-  unsigned HOST_WIDE_INT quol, reml;
-  HOST_WIDE_INT quoh, remh;
+  double_int quo, rem;
   int uns;
 
   /* The sign of the division is according to operand two, that
@@ -895,17 +892,14 @@ div_if_zero_remainder (enum tree_code code, const_tree arg1, const_tree arg2)
       && TYPE_IS_SIZETYPE (TREE_TYPE (arg2)))
     uns = false;
 
-  int1l = TREE_INT_CST_LOW (arg1);
-  int1h = TREE_INT_CST_HIGH (arg1);
-  int2l = TREE_INT_CST_LOW (arg2);
-  int2h = TREE_INT_CST_HIGH (arg2);
+  quo = double_int_divmod (tree_to_double_int (arg1),
+                          tree_to_double_int (arg2),
+                          uns, code, &rem);
 
-  div_and_round_double (code, uns, int1l, int1h, int2l, int2h,
-                       &quol, &quoh, &reml, &remh);
-  if (remh != 0 || reml != 0)
-    return NULL_TREE;
+  if (double_int_zero_p (rem))
+    return build_int_cst_wide (TREE_TYPE (arg1), quo.low, quo.high);
 
-  return build_int_cst_wide (TREE_TYPE (arg1), quol, quoh);
+  return NULL_TREE; 
 }
 \f
 /* This is nonzero if we should defer warnings about undefined
@@ -2279,7 +2273,7 @@ fold_convert_const_int_from_real (enum tree_code code, tree type, const_tree arg
      C and C++ standards that simply state that the behavior of
      FP-to-integer conversion is unspecified upon overflow.  */
 
-  HOST_WIDE_INT high, low;
+  double_int val;
   REAL_VALUE_TYPE r;
   REAL_VALUE_TYPE x = TREE_REAL_CST (arg1);
 
@@ -2297,8 +2291,7 @@ fold_convert_const_int_from_real (enum tree_code code, tree type, const_tree arg
   if (REAL_VALUE_ISNAN (r))
     {
       overflow = 1;
-      high = 0;
-      low = 0;
+      val = double_int_zero;
     }
 
   /* See if R is less than the lower bound or greater than the
@@ -2311,8 +2304,7 @@ fold_convert_const_int_from_real (enum tree_code code, tree type, const_tree arg
       if (REAL_VALUES_LESS (r, l))
        {
          overflow = 1;
-         high = TREE_INT_CST_HIGH (lt);
-         low = TREE_INT_CST_LOW (lt);
+         val = tree_to_double_int (lt);
        }
     }
 
@@ -2325,16 +2317,15 @@ fold_convert_const_int_from_real (enum tree_code code, tree type, const_tree arg
          if (REAL_VALUES_LESS (u, r))
            {
              overflow = 1;
-             high = TREE_INT_CST_HIGH (ut);
-             low = TREE_INT_CST_LOW (ut);
+             val = tree_to_double_int (ut);
            }
        }
     }
 
   if (! overflow)
-    REAL_VALUE_TO_INT (&low, &high, r);
+    real_to_integer2 ((HOST_WIDE_INT *) &val.low, &val.high, &r);
 
-  t = force_fit_type_double (type, low, high, -1,
+  t = force_fit_type_double (type, val.low, val.high, -1,
                             overflow | TREE_OVERFLOW (arg1));
   return t;
 }
@@ -2354,39 +2345,32 @@ fold_convert_const_int_from_fixed (tree type, const_tree arg1)
   mode = TREE_FIXED_CST (arg1).mode;
   if (GET_MODE_FBIT (mode) < 2 * HOST_BITS_PER_WIDE_INT)
     {
-      lshift_double (temp.low, temp.high,
-                    - GET_MODE_FBIT (mode), 2 * HOST_BITS_PER_WIDE_INT,
-                    &temp.low, &temp.high, SIGNED_FIXED_POINT_MODE_P (mode));
+      temp = double_int_rshift (temp, GET_MODE_FBIT (mode),
+                               HOST_BITS_PER_DOUBLE_INT,
+                               SIGNED_FIXED_POINT_MODE_P (mode));
 
       /* Left shift temp to temp_trunc by fbit.  */
-      lshift_double (temp.low, temp.high,
-                    GET_MODE_FBIT (mode), 2 * HOST_BITS_PER_WIDE_INT,
-                    &temp_trunc.low, &temp_trunc.high,
-                    SIGNED_FIXED_POINT_MODE_P (mode));
+      temp_trunc = double_int_lshift (temp, GET_MODE_FBIT (mode),
+                                     HOST_BITS_PER_DOUBLE_INT,
+                                     SIGNED_FIXED_POINT_MODE_P (mode));
     }
   else
     {
-      temp.low = 0;
-      temp.high = 0;
-      temp_trunc.low = 0;
-      temp_trunc.high = 0;
+      temp = double_int_zero;
+      temp_trunc = double_int_zero;
     }
 
   /* If FIXED_CST is negative, we need to round the value toward 0.
      By checking if the fractional bits are not zero to add 1 to temp.  */
-  if (SIGNED_FIXED_POINT_MODE_P (mode) && temp_trunc.high < 0
+  if (SIGNED_FIXED_POINT_MODE_P (mode)
+      && double_int_negative_p (temp_trunc)
       && !double_int_equal_p (TREE_FIXED_CST (arg1).data, temp_trunc))
-    {
-      double_int one;
-      one.low = 1;
-      one.high = 0;
-      temp = double_int_add (temp, one);
-    }
+    temp = double_int_add (temp, double_int_one);
 
   /* Given a fixed-point constant, make new constant with new type,
      appropriately sign-extended or truncated.  */
   t = force_fit_type_double (type, temp.low, temp.high, -1,
-                            (temp.high < 0
+                            (double_int_negative_p (temp)
                              && (TYPE_UNSIGNED (type)
                                  < TYPE_UNSIGNED (TREE_TYPE (arg1))))
                             | TREE_OVERFLOW (arg1));
index 5da8206..83f1237 100644 (file)
@@ -1221,32 +1221,18 @@ build_int_cst_wide (tree type, unsigned HOST_WIDE_INT low, HOST_WIDE_INT hi)
 tree
 build_low_bits_mask (tree type, unsigned bits)
 {
-  unsigned HOST_WIDE_INT low;
-  HOST_WIDE_INT high;
-  unsigned HOST_WIDE_INT all_ones = ~(unsigned HOST_WIDE_INT) 0;
+  double_int mask;
 
   gcc_assert (bits <= TYPE_PRECISION (type));
 
   if (bits == TYPE_PRECISION (type)
       && !TYPE_UNSIGNED (type))
-    {
-      /* Sign extended all-ones mask.  */
-      low = all_ones;
-      high = -1;
-    }
-  else if (bits <= HOST_BITS_PER_WIDE_INT)
-    {
-      low = all_ones >> (HOST_BITS_PER_WIDE_INT - bits);
-      high = 0;
-    }
+    /* Sign extended all-ones mask.  */
+    mask = double_int_minus_one;
   else
-    {
-      bits -= HOST_BITS_PER_WIDE_INT;
-      low = all_ones;
-      high = all_ones >> (HOST_BITS_PER_WIDE_INT - bits);
-    }
+    mask = double_int_mask (bits);
 
-  return build_int_cst_wide (type, low, high);
+  return build_int_cst_wide (type, mask.low, mask.high);
 }
 
 /* Checks that X is integer constant that can be expressed in (unsigned)
index 1c7c3b3..e30981e 100644 (file)
@@ -4841,10 +4841,10 @@ extern int mul_double_with_sign (unsigned HOST_WIDE_INT, HOST_WIDE_INT,
   mul_double_with_sign (l1, h1, l2, h2, lv, hv, false)
 extern void lshift_double (unsigned HOST_WIDE_INT, HOST_WIDE_INT,
                           HOST_WIDE_INT, unsigned int,
-                          unsigned HOST_WIDE_INT *, HOST_WIDE_INT *, int);
+                          unsigned HOST_WIDE_INT *, HOST_WIDE_INT *, bool);
 extern void rshift_double (unsigned HOST_WIDE_INT, HOST_WIDE_INT,
                           HOST_WIDE_INT, unsigned int,
-                          unsigned HOST_WIDE_INT *, HOST_WIDE_INT *, int);
+                          unsigned HOST_WIDE_INT *, HOST_WIDE_INT *, bool);
 extern void lrotate_double (unsigned HOST_WIDE_INT, HOST_WIDE_INT,
                            HOST_WIDE_INT, unsigned int,
                            unsigned HOST_WIDE_INT *, HOST_WIDE_INT *);