This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Add double_int_not, double_int_lshift and double_int_rshift functions.


2010/4/10 Anatoly Sokolov <aesok@post.ru>:
> Hello.
>
> ?This patch add double_int_not, double_int_lshift and double_int_rshift
> functions in the GCC and do clean up code by using double_int_* functions.
>
> ?Bootstrapped/regtested on x86_64-unknown-linux-gnu, OK for mainline?

Ok.

Thanks for these cleanups.  Can you move both tree_to_double_int
and double_int_negative_p to double-int.h from double-int.c as
a followup?  A patch to do so is pre-approved.

Thanks,
Richard.

>
> ? ? ? ?* double-int.h (HOST_BITS_PER_DOUBLE_INT): Define.
> ? ? ? ?(double_int_not, double_int_lshift, double_int_rshift): Declare.
> ? ? ? ?* double-int.c (double_int_lshift, double_int_lshift): Add new function.
> ? ? ? ?* 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.).
> ? ? ? ?* expmed.c (mask_rtx, lshift_value): (Ditto.).
>
>
> Index: gcc/tree.c
> ===================================================================
> --- gcc/tree.c ?(revision 158010)
> +++ gcc/tree.c ?(working copy)
> @@ -1221,32 +1221,18 @@
> ?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: gcc/fold-const.c
> ===================================================================
> --- gcc/fold-const.c ? ?(revision 158010)
> +++ gcc/fold-const.c ? ?(working copy)
> @@ -881,10 +881,7 @@
> ?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 @@
> ? ? ? && 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;
> ?}
>
> ?/* This is nonzero if we should defer warnings about undefined
> @@ -2295,7 +2289,7 @@
> ? ? ?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);
>
> @@ -2313,8 +2307,7 @@
> ? 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
> @@ -2327,8 +2320,7 @@
> ? ? ? 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);
> ? ? ? ?}
> ? ? }
>
> @@ -2341,16 +2333,15 @@
> ? ? ? ? ?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;
> ?}
> @@ -2370,39 +2361,32 @@
> ? 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: gcc/double-int.c
> ===================================================================
> --- gcc/double-int.c ? ?(revision 158010)
> +++ gcc/double-int.c ? ?(working copy)
> @@ -290,6 +290,30 @@
> ? return double_int_mod (a, b, true, code);
> ?}
>
> +/* Shift the 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 the A rigth 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_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. ?*/
>
> Index: gcc/double-int.h
> ===================================================================
> --- gcc/double-int.h ? ?(revision 158010)
> +++ gcc/double-int.h ? ?(working copy)
> @@ -57,6 +57,8 @@
> ? 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,6 +129,20 @@
> ?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 *);
> +
> +/* 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);
> +
> ?bool double_int_negative_p (double_int);
> ?int double_int_cmp (double_int, double_int, bool);
> ?int double_int_scmp (double_int, double_int);
> Index: gcc/expmed.c
> ===================================================================
> --- gcc/expmed.c ? ? ? ?(revision 158010)
> +++ gcc/expmed.c ? ? ? ?(working copy)
> @@ -1839,39 +1839,15 @@
> ?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;
> + ?mask = double_int_mask (bitsize);
> + ?mask = double_int_lshift (mask, bitpos, HOST_BITS_PER_DOUBLE_INT, false);
>
> - ?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;
> -
> ? 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 @@
> ?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;
> + ?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);
>
> - ?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);
> - ? ?}
> -
> - ?return immed_double_const (low, high, mode);
> + ?return immed_double_const (val.low, val.high, mode);
> ?}
>
> ?/* Extract a bit field that is split across two words
>
>
> ?Anatoly.
>
>


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]