This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [patch] Finish double_int conversion.
- From: Georg-Johann Lay <avr at gjlay dot de>
- To: Richard Guenther <rguenther at suse dot de>
- Cc: Lawrence Crowl <crowl at googlers dot com>, gcc-patches List <gcc-patches at gcc dot gnu dot org>, chertykov at gmail dot com, aesok at post dot ru, eric dot weddington at atmel dot com, Richard Henderson <rth at redhat dot com>, davem at redhat dot com, ebotcazou at libertysurf dot fr
- Date: Tue, 25 Sep 2012 12:45:32 +0200
- Subject: Re: [patch] Finish double_int conversion.
- References: <CAGqM8fb27dr3z6hnZYAFeWWCfitbvhHUmor6R3XSPNoBgtVsBQ@mail.gmail.com> <alpine.LNX.2.00.1209121041320.28649@zhemvz.fhfr.qr>
Richard Guenther wrote:
> On Tue, 11 Sep 2012, Lawrence Crowl wrote:
>
>> Finish conversion of uses of double_int to the new API.
>>
>> Some old functionality required new interfaces, and these have been
>> added to double-int.[hc]:
>>
>> double_int::from_pair - static constructor function
>> wide_mul_with_sign - double-wide multiply instruction
>> neg_with_overflow - negation with overlow testing
>> divmod_with_overflow - div and mod with overlow testing
>>
>> The prior two generations of the interface have been removed.
>>
>> Some of these old interfaces are still used as static implementation
>> in double-int.c.
>>
>> The changed compiler appears 0.321% faster with 80% confidence of
>> being faster.
>>
>> Tested on x86_64. However, there are changes to the avr and sparc
>> config files, and I have not tested those. Could the maintainers
>> please apply the patch and see if it works?
>>
>> After testing is complete, okay for trunk?
>
> Ok. For avr and sparc you can build cross cc1 (configure for the
> cross and do make all-gcc), if that works it should be fine.
It does not work, at least for avr:
http://gcc.gnu.org/PR54701
g++ -c -g -O2 -DIN_GCC -DCROSS_DIRECTORY_STRUCTURE -fno-exceptions -fno-rtti
-W -Wall -Wwrite-strings -Wcast-qual -Wmissing-format-attribute -pedantic
-Wno-long-long -Wno-variadic-macros -Wno-overlength-strings -fno-common
-DHAVE_CONFIG_H -I. -I. -I../../../gcc.gnu.org/trunk/gcc
-I../../../gcc.gnu.org/trunk/gcc/. -I../../../gcc.gnu.org/trunk/gcc/../include
-I../../../gcc.gnu.org/trunk/gcc/../libcpp/include
-I/home/georg/gnu/build/gcc-trunk-avr/./gmp
-I/home/georg/gnu/gcc.gnu.org/trunk/gmp
-I/home/georg/gnu/build/gcc-trunk-avr/./mpfr
-I/home/georg/gnu/gcc.gnu.org/trunk/mpfr
-I/home/georg/gnu/gcc.gnu.org/trunk/mpc/src
-I../../../gcc.gnu.org/trunk/gcc/../libdecnumber
-I../../../gcc.gnu.org/trunk/gcc/../libdecnumber/dpd -I../libdecnumber \
../../../gcc.gnu.org/trunk/gcc/config/avr/avr.c -o avr.o
../../../gcc.gnu.org/trunk/gcc/config/avr/avr.c: In function 'avr_map_op_t
avr_map_decompose(double_int, const avr_map_op_t*, bool)':
../../../gcc.gnu.org/trunk/gcc/config/avr/avr.c:10955: error:
'uhwi_to_double_int' was not declared in this scope
make[2]: *** [avr.o] Error 1
make[2]: Leaving directory `/local/gnu/build/gcc-trunk-avr/gcc'
make[1]: *** [all-gcc] Error 2
make[1]: Leaving directory `/local/gnu/build/gcc-trunk-avr'
make: *** [all] Error 2
>
> Thanks,
> Richard.
>
>> ========================
>>
>> Index: gcc/java/ChangeLog
>>
>> 2012-09-10 Lawrence Crowl <crowl@google.com>
>>
>> * decl.c (java_init_decl_processing): Change to new double_int API.
>> * jcf-parse.c (get_constant): Likewise.
>> * boehm.c (mark_reference_fields): Likewise.
>> (get_boehm_type_descriptor): Likewise.
>>
>> Index: gcc/ChangeLog
>>
>> 2012-09-10 Lawrence Crowl <crowl@google.com>
>>
>> * double-int.h (double_int::from_pair): New.
>> (double_int::wide_mul_with_sign): New.
>> (double_int::neg_with_overflow): New.
>> (double_int::divmod_with_overflow): New.
>> (shwi_to_double_int): Remove.
>> (uhwi_to_double_int): Remove.
>> (double_int_to_shwi): Remove.
>> (double_int_to_uhwi): Remove.
>> (double_int_fits_in_uhwi_p): Remove.
>> (double_int_fits_in_shwi_p): Remove.
>> (double_int_fits_in_hwi_p): Remove.
>> (double_int_mul): Remove.
>> (double_int_mul_with_sign): Remove.
>> (double_int_add): Remove.
>> (double_int_sub): Remove.
>> (double_int_neg): Remove.
>> (double_int_div): Remove.
>> (double_int_sdiv): Remove.
>> (double_int_udiv): Remove.
>> (double_int_mod): Remove.
>> (double_int_smod): Remove.
>> (double_int_umod): Remove.
>> (double_int_divmod): Remove.
>> (double_int_sdivmod): Remove.
>> (double_int_udivmod): Remove.
>> (double_int_multiple_of): Remove.
>> (double_int_setbit): Remove.
>> (double_int_ctz): Remove.
>> (double_int_not): Remove.
>> (double_int_ior): Remove.
>> (double_int_and): Remove.
>> (double_int_and_not): Remove.
>> (double_int_xor): Remove.
>> (double_int_lshift): Remove.
>> (double_int_rshift): Remove.
>> (double_int_lrotate): Remove.
>> (double_int_rrotate): Remove.
>> (double_int_negative_p): Remove.
>> (double_int_cmp): Remove.
>> (double_int_scmp): Remove.
>> (double_int_ucmp): Remove.
>> (double_int_max): Remove.
>> (double_int_smax): Remove.
>> (double_int_umax): Remove.
>> (double_int_min): Remove.
>> (double_int_smin): Remove.
>> (double_int_umin): Remove.
>> (double_int_ext): Remove.
>> (double_int_sext): Remove.
>> (double_int_zext): Remove.
>> (double_int_mask): Remove.
>> (double_int_max_value): Remove.
>> (double_int_min_value): Remove.
>> (double_int_zero_p): Remove.
>> (double_int_one_p): Remove.
>> (double_int_minus_one_p): Remove.
>> (double_int_equal_p): Remove.
>> (double_int_popcount): Remove.
>> (extern add_double_with_sign): Remove.
>> (#define add_double): Remove.
>> (extern neg_double): Remove.
>> (extern mul_double_with_sign): Remove.
>> (extern mul_double_wide_with_sign): Remove.
>> (#define mul_double): Remove.
>> (extern lshift_double): Remove.
>> (extern div_and_round_double): Remove.
>> * double-int.c (add_double_with_sign): Make static.
>> (#defined add_double): Localized from header.
>> (neg_double): Make static.
>> (mul_double_with_sign): Make static.
>> (mul_double_wide_with_sign): Make static.
>> (#defined mul_double): Localized from header.
>> (lshift_double): Make static.
>> (div_and_round_double): Make static.
>> (double_int::wide_mul_with_sign): New.
>> (double_int::neg_with_overflow): New.
>> (double_int::divmod_with_overflow): New.
>> * emit-rtl.c (init_emit_once): Change to new double_int API.
>> * explow.c (plus_constant): Likewise.
>> * expmed.c (choose_multiplier): Likewise.
>> * fold-const.c (int_const_binop_1): Likewise.
>> (fold_div_compare): Likewise.
>> (maybe_canonicalize_comparison): Likewise.
>> (pointer_may_wrap_p): Likewise.
>> (fold_negate_const): Likewise.
>> (fold_abs_const): Likewise.
>> * simplify-rtx.c (simplify_const_unary_operation): Likewise.
>> (simplify_const_binary_operation): Likewise.
>> * tree-chrec.c (tree_fold_binomial): Likewise.
>> * tree-vrp.c (extract_range_from_binary_expr_1): Likewise.
>> * config/sparc/sparc.c (sparc_fold_builtin): Likewise.
>> * config/avr/avr.c (avr_double_int_push_digit): Likewise.
>> (avr_map): Likewise.
>> (avr_map_decompose): Likewise.
>> (avr_out_insert_bits): Likewise.
>>
>> Index: gcc/cp/ChangeLog
>>
>> 2012-09-10 Lawrence Crowl <crowl@google.com>
>>
>> * init.c (build_new_1): Change to new double_int API.
>> * decl.c (build_enumerator): Likewise.
>> * typeck2.c (process_init_constructor_array): Likewise.
>> * mangle.c (write_array_type): Likewise.
>>
>> Index: gcc/fortran/ChangeLog
>>
>> 2012-09-10 Lawrence Crowl <crowl@google.com>
>>
>> * trans-expr.c (gfc_conv_cst_int_power): Change to new double_int API.
>> * target-memory.c (gfc_interpret_logical): Likewise.
>>
>> ========================
>>
>> Index: gcc/tree-vrp.c
>> ===================================================================
>> --- gcc/tree-vrp.c (revision 191083)
>> +++ gcc/tree-vrp.c (working copy)
>> @@ -2478,7 +2478,7 @@ extract_range_from_binary_expr_1 (value_
>> if (tmin.cmp (tmax, uns) < 0)
>> covers = true;
>> tmax = tem + double_int_minus_one;
>> - if (double_int_cmp (tmax, tem, uns) > 0)
>> + if (tmax.cmp (tem, uns) > 0)
>> covers = true;
>> /* If the anti-range would cover nothing, drop to varying.
>> Likewise if the anti-range bounds are outside of the
>> @@ -2632,37 +2632,26 @@ extract_range_from_binary_expr_1 (value_
>> }
>> uns = uns0 & uns1;
>>
>> - mul_double_wide_with_sign (min0.low, min0.high,
>> - min1.low, min1.high,
>> - &prod0l.low, &prod0l.high,
>> - &prod0h.low, &prod0h.high, true);
>> + bool overflow;
>> + prod0l = min0.wide_mul_with_sign (min1, true, &prod0h, &overflow);
>> if (!uns0 && min0.is_negative ())
>> prod0h -= min1;
>> if (!uns1 && min1.is_negative ())
>> prod0h -= min0;
>>
>> - mul_double_wide_with_sign (min0.low, min0.high,
>> - max1.low, max1.high,
>> - &prod1l.low, &prod1l.high,
>> - &prod1h.low, &prod1h.high, true);
>> + prod1l = min0.wide_mul_with_sign (max1, true, &prod1h, &overflow);
>> if (!uns0 && min0.is_negative ())
>> prod1h -= max1;
>> if (!uns1 && max1.is_negative ())
>> prod1h -= min0;
>>
>> - mul_double_wide_with_sign (max0.low, max0.high,
>> - min1.low, min1.high,
>> - &prod2l.low, &prod2l.high,
>> - &prod2h.low, &prod2h.high, true);
>> + prod2l = max0.wide_mul_with_sign (min1, true, &prod2h, &overflow);
>> if (!uns0 && max0.is_negative ())
>> prod2h -= min1;
>> if (!uns1 && min1.is_negative ())
>> prod2h -= max0;
>>
>> - mul_double_wide_with_sign (max0.low, max0.high,
>> - max1.low, max1.high,
>> - &prod3l.low, &prod3l.high,
>> - &prod3h.low, &prod3h.high, true);
>> + prod3l = max0.wide_mul_with_sign (max1, true, &prod3h, &overflow);
>> if (!uns0 && max0.is_negative ())
>> prod3h -= max1;
>> if (!uns1 && max1.is_negative ())
>> Index: gcc/java/decl.c
>> ===================================================================
>> --- gcc/java/decl.c (revision 191083)
>> +++ gcc/java/decl.c (working copy)
>> @@ -617,7 +617,7 @@ java_init_decl_processing (void)
>> decimal_int_max = build_int_cstu (unsigned_int_type_node, 0x80000000);
>> decimal_long_max
>> = double_int_to_tree (unsigned_long_type_node,
>> - double_int_setbit (double_int_zero, 64));
>> + double_int_zero.set_bit (64));
>>
>> long_zero_node = build_int_cst (long_type_node, 0);
>>
>> Index: gcc/java/jcf-parse.c
>> ===================================================================
>> --- gcc/java/jcf-parse.c (revision 191083)
>> +++ gcc/java/jcf-parse.c (working copy)
>> @@ -1043,9 +1043,9 @@ get_constant (JCF *jcf, int index)
>> double_int val;
>>
>> num = JPOOL_UINT (jcf, index);
>> - val = double_int_lshift (uhwi_to_double_int (num), 32, 64, false);
>> + val = double_int::from_uhwi (num).llshift (32, 64);
>> num = JPOOL_UINT (jcf, index + 1);
>> - val = double_int_ior (val, uhwi_to_double_int (num));
>> + val |= double_int::from_uhwi (num);
>>
>> value = double_int_to_tree (long_type_node, val);
>> break;
>> Index: gcc/java/boehm.c
>> ===================================================================
>> --- gcc/java/boehm.c (revision 191083)
>> +++ gcc/java/boehm.c (working copy)
>> @@ -108,7 +108,7 @@ mark_reference_fields (tree field,
>> bits for all words in the record. This is conservative, but the
>> size_words != 1 case is impossible in regular java code. */
>> for (i = 0; i < size_words; ++i)
>> - *mask = double_int_setbit (*mask, ubit - count - i - 1);
>> + *mask = (*mask).set_bit (ubit - count - i - 1);
>>
>> if (count >= ubit - 2)
>> *pointer_after_end = 1;
>> @@ -200,7 +200,7 @@ get_boehm_type_descriptor (tree type)
>> while (last_set_index)
>> {
>> if ((last_set_index & 1))
>> - mask = double_int_setbit (mask, log2_size + count);
>> + mask = mask.set_bit (log2_size + count);
>> last_set_index >>= 1;
>> ++count;
>> }
>> @@ -209,7 +209,7 @@ get_boehm_type_descriptor (tree type)
>> else if (! pointer_after_end)
>> {
>> /* Bottom two bits for bitmap mark type are 01. */
>> - mask = double_int_setbit (mask, 0);
>> + mask = mask.set_bit (0);
>> value = double_int_to_tree (value_type, mask);
>> }
>> else
>> Index: gcc/fold-const.c
>> ===================================================================
>> --- gcc/fold-const.c (revision 191083)
>> +++ gcc/fold-const.c (working copy)
>> @@ -982,12 +982,6 @@ int_const_binop_1 (enum tree_code code,
>> break;
>>
>> case MINUS_EXPR:
>> -/* FIXME(crowl) Remove this code if the replacment works.
>> - neg_double (op2.low, op2.high, &res.low, &res.high);
>> - add_double (op1.low, op1.high, res.low, res.high,
>> - &res.low, &res.high);
>> - overflow = OVERFLOW_SUM_SIGN (res.high, op2.high, op1.high);
>> -*/
>> res = op1.add_with_sign (-op2, false, &overflow);
>> break;
>>
>> @@ -1035,10 +1029,7 @@ int_const_binop_1 (enum tree_code code,
>> res = double_int_one;
>> break;
>> }
>> - overflow = div_and_round_double (code, uns,
>> - op1.low, op1.high, op2.low, op2.high,
>> - &res.low, &res.high,
>> - &tmp.low, &tmp.high);
>> + res = op1.divmod_with_overflow (op2, uns, code, &tmp, &overflow);
>> break;
>>
>> case TRUNC_MOD_EXPR:
>> @@ -1060,10 +1051,7 @@ int_const_binop_1 (enum tree_code code,
>> case ROUND_MOD_EXPR:
>> if (op2.is_zero ())
>> return NULL_TREE;
>> - overflow = div_and_round_double (code, uns,
>> - op1.low, op1.high, op2.low, op2.high,
>> - &tmp.low, &tmp.high,
>> - &res.low, &res.high);
>> + tmp = op1.divmod_with_overflow (op2, uns, code, &res, &overflow);
>> break;
>>
>> case MIN_EXPR:
>> @@ -6290,15 +6278,12 @@ fold_div_compare (location_t loc,
>> double_int val;
>> bool unsigned_p = TYPE_UNSIGNED (TREE_TYPE (arg0));
>> bool neg_overflow;
>> - int overflow;
>> + bool overflow;
>>
>> /* We have to do this the hard way to detect unsigned overflow.
>> prod = int_const_binop (MULT_EXPR, arg01, arg1); */
>> - overflow = mul_double_with_sign (TREE_INT_CST_LOW (arg01),
>> - TREE_INT_CST_HIGH (arg01),
>> - TREE_INT_CST_LOW (arg1),
>> - TREE_INT_CST_HIGH (arg1),
>> - &val.low, &val.high, unsigned_p);
>> + val = TREE_INT_CST (arg01)
>> + .mul_with_sign (TREE_INT_CST (arg1), unsigned_p, &overflow);
>> prod = force_fit_type_double (TREE_TYPE (arg00), val, -1, overflow);
>> neg_overflow = false;
>>
>> @@ -6309,11 +6294,8 @@ fold_div_compare (location_t loc,
>> lo = prod;
>>
>> /* Likewise hi = int_const_binop (PLUS_EXPR, prod, tmp). */
>> - overflow = add_double_with_sign (TREE_INT_CST_LOW (prod),
>> - TREE_INT_CST_HIGH (prod),
>> - TREE_INT_CST_LOW (tmp),
>> - TREE_INT_CST_HIGH (tmp),
>> - &val.low, &val.high, unsigned_p);
>> + val = TREE_INT_CST (prod)
>> + .add_with_sign (TREE_INT_CST (tmp), unsigned_p, &overflow);
>> hi = force_fit_type_double (TREE_TYPE (arg00), val,
>> -1, overflow | TREE_OVERFLOW (prod));
>> }
>> @@ -8693,8 +8675,7 @@ maybe_canonicalize_comparison (location_
>> static bool
>> pointer_may_wrap_p (tree base, tree offset, HOST_WIDE_INT bitpos)
>> {
>> - unsigned HOST_WIDE_INT offset_low, total_low;
>> - HOST_WIDE_INT size, offset_high, total_high;
>> + double_int di_offset, total;
>>
>> if (!POINTER_TYPE_P (TREE_TYPE (base)))
>> return true;
>> @@ -8703,28 +8684,22 @@ pointer_may_wrap_p (tree base, tree offs
>> return true;
>>
>> if (offset == NULL_TREE)
>> - {
>> - offset_low = 0;
>> - offset_high = 0;
>> - }
>> + di_offset = double_int_zero;
>> else if (TREE_CODE (offset) != INTEGER_CST || TREE_OVERFLOW (offset))
>> return true;
>> else
>> - {
>> - offset_low = TREE_INT_CST_LOW (offset);
>> - offset_high = TREE_INT_CST_HIGH (offset);
>> - }
>> + di_offset = TREE_INT_CST (offset);
>>
>> - if (add_double_with_sign (offset_low, offset_high,
>> - bitpos / BITS_PER_UNIT, 0,
>> - &total_low, &total_high,
>> - true))
>> + bool overflow;
>> + double_int units = double_int::from_uhwi (bitpos / BITS_PER_UNIT);
>> + total = di_offset.add_with_sign (units, true, &overflow);
>> + if (overflow)
>> return true;
>>
>> - if (total_high != 0)
>> + if (total.high != 0)
>> return true;
>>
>> - size = int_size_in_bytes (TREE_TYPE (TREE_TYPE (base)));
>> + HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (TREE_TYPE (base)));
>> if (size <= 0)
>> return true;
>>
>> @@ -8739,7 +8714,7 @@ pointer_may_wrap_p (tree base, tree offs
>> size = base_size;
>> }
>>
>> - return total_low > (unsigned HOST_WIDE_INT) size;
>> + return total.low > (unsigned HOST_WIDE_INT) size;
>> }
>>
>> /* Subroutine of fold_binary. This routine performs all of the
>> @@ -15939,8 +15914,8 @@ fold_negate_const (tree arg0, tree type)
>> case INTEGER_CST:
>> {
>> double_int val = tree_to_double_int (arg0);
>> - int overflow = neg_double (val.low, val.high, &val.low, &val.high);
>> -
>> + bool overflow;
>> + val = val.neg_with_overflow (&overflow);
>> t = force_fit_type_double (type, val, 1,
>> (overflow | TREE_OVERFLOW (arg0))
>> && !TYPE_UNSIGNED (type));
>> @@ -15997,9 +15972,8 @@ fold_abs_const (tree arg0, tree type)
>> its negation. */
>> else
>> {
>> - int overflow;
>> -
>> - overflow = neg_double (val.low, val.high, &val.low, &val.high);
>> + bool overflow;
>> + val = val.neg_with_overflow (&overflow);
>> t = force_fit_type_double (type, val, -1,
>> overflow | TREE_OVERFLOW (arg0));
>> }
>> Index: gcc/tree-chrec.c
>> ===================================================================
>> --- gcc/tree-chrec.c (revision 191083)
>> +++ gcc/tree-chrec.c (working copy)
>> @@ -461,8 +461,8 @@ chrec_fold_multiply (tree type,
>> static tree
>> tree_fold_binomial (tree type, tree n, unsigned int k)
>> {
>> - unsigned HOST_WIDE_INT lidx, lnum, ldenom, lres, ldum;
>> - HOST_WIDE_INT hidx, hnum, hdenom, hres, hdum;
>> + double_int num, denom, idx, di_res;
>> + bool overflow;
>> unsigned int i;
>> tree res;
>>
>> @@ -472,59 +472,41 @@ tree_fold_binomial (tree type, tree n, u
>> if (k == 1)
>> return fold_convert (type, n);
>>
>> + /* Numerator = n. */
>> + num = TREE_INT_CST (n);
>> +
>> /* Check that k <= n. */
>> - if (TREE_INT_CST_HIGH (n) == 0
>> - && TREE_INT_CST_LOW (n) < k)
>> + if (num.ult (double_int::from_uhwi (k)))
>> return NULL_TREE;
>>
>> - /* Numerator = n. */
>> - lnum = TREE_INT_CST_LOW (n);
>> - hnum = TREE_INT_CST_HIGH (n);
>> -
>> /* Denominator = 2. */
>> - ldenom = 2;
>> - hdenom = 0;
>> + denom = double_int::from_uhwi (2);
>>
>> /* Index = Numerator-1. */
>> - if (lnum == 0)
>> - {
>> - hidx = hnum - 1;
>> - lidx = ~ (unsigned HOST_WIDE_INT) 0;
>> - }
>> - else
>> - {
>> - hidx = hnum;
>> - lidx = lnum - 1;
>> - }
>> + idx = num - double_int_one;
>>
>> /* Numerator = Numerator*Index = n*(n-1). */
>> - if (mul_double (lnum, hnum, lidx, hidx, &lnum, &hnum))
>> + num = num.mul_with_sign (idx, false, &overflow);
>> + if (overflow)
>> return NULL_TREE;
>>
>> for (i = 3; i <= k; i++)
>> {
>> /* Index--. */
>> - if (lidx == 0)
>> - {
>> - hidx--;
>> - lidx = ~ (unsigned HOST_WIDE_INT) 0;
>> - }
>> - else
>> - lidx--;
>> + --idx;
>>
>> /* Numerator *= Index. */
>> - if (mul_double (lnum, hnum, lidx, hidx, &lnum, &hnum))
>> + num = num.mul_with_sign (idx, false, &overflow);
>> + if (overflow)
>> return NULL_TREE;
>>
>> /* Denominator *= i. */
>> - mul_double (ldenom, hdenom, i, 0, &ldenom, &hdenom);
>> + denom *= double_int::from_uhwi (i);
>> }
>>
>> /* Result = Numerator / Denominator. */
>> - div_and_round_double (EXACT_DIV_EXPR, 1, lnum, hnum, ldenom, hdenom,
>> - &lres, &hres, &ldum, &hdum);
>> -
>> - res = build_int_cst_wide (type, lres, hres);
>> + di_res = num.div (denom, true, EXACT_DIV_EXPR);
>> + res = build_int_cst_wide (type, di_res.low, di_res.high);
>> return int_fits_type_p (res, type) ? res : NULL_TREE;
>> }
>>
>> Index: gcc/cp/init.c
>> ===================================================================
>> --- gcc/cp/init.c (revision 191083)
>> +++ gcc/cp/init.c (working copy)
>> @@ -2239,11 +2239,11 @@ build_new_1 (VEC(tree,gc) **placement, t
>> if (TREE_CONSTANT (inner_nelts_cst)
>> && TREE_CODE (inner_nelts_cst) == INTEGER_CST)
>> {
>> - double_int result;
>> - if (mul_double (TREE_INT_CST_LOW (inner_nelts_cst),
>> - TREE_INT_CST_HIGH (inner_nelts_cst),
>> - inner_nelts_count.low, inner_nelts_count.high,
>> - &result.low, &result.high))
>> + bool overflow;
>> + double_int result = TREE_INT_CST (inner_nelts_cst)
>> + .mul_with_sign (inner_nelts_count,
>> + false, &overflow);
>> + if (overflow)
>> {
>> if (complain & tf_error)
>> error ("integer overflow in array size");
>> @@ -2345,8 +2345,8 @@ build_new_1 (VEC(tree,gc) **placement, t
>> /* Maximum available size in bytes. Half of the address space
>> minus the cookie size. */
>> double_int max_size
>> - = double_int_lshift (double_int_one, TYPE_PRECISION (sizetype) - 1,
>> - HOST_BITS_PER_DOUBLE_INT, false);
>> + = double_int_one.llshift (TYPE_PRECISION (sizetype) - 1,
>> + HOST_BITS_PER_DOUBLE_INT);
>> /* Size of the inner array elements. */
>> double_int inner_size;
>> /* Maximum number of outer elements which can be allocated. */
>> @@ -2356,22 +2356,21 @@ build_new_1 (VEC(tree,gc) **placement, t
>> gcc_assert (TREE_CODE (size) == INTEGER_CST);
>> cookie_size = targetm.cxx.get_cookie_size (elt_type);
>> gcc_assert (TREE_CODE (cookie_size) == INTEGER_CST);
>> - gcc_checking_assert (double_int_ucmp
>> - (TREE_INT_CST (cookie_size), max_size) < 0);
>> + gcc_checking_assert (TREE_INT_CST (cookie_size).ult (max_size));
>> /* Unconditionally substract the cookie size. This decreases the
>> maximum object size and is safe even if we choose not to use
>> a cookie after all. */
>> - max_size = double_int_sub (max_size, TREE_INT_CST (cookie_size));
>> - if (mul_double (TREE_INT_CST_LOW (size), TREE_INT_CST_HIGH (size),
>> - inner_nelts_count.low, inner_nelts_count.high,
>> - &inner_size.low, &inner_size.high)
>> - || double_int_ucmp (inner_size, max_size) > 0)
>> + max_size -= TREE_INT_CST (cookie_size);
>> + bool overflow;
>> + inner_size = TREE_INT_CST (size)
>> + .mul_with_sign (inner_nelts_count, false, &overflow);
>> + if (overflow || inner_size.ugt (max_size))
>> {
>> if (complain & tf_error)
>> error ("size of array is too large");
>> return error_mark_node;
>> }
>> - max_outer_nelts = double_int_udiv (max_size, inner_size, TRUNC_DIV_EXPR);
>> + max_outer_nelts = max_size.udiv (inner_size, TRUNC_DIV_EXPR);
>> /* Only keep the top-most seven bits, to simplify encoding the
>> constant in the instruction stream. */
>> {
>> @@ -2379,10 +2378,8 @@ build_new_1 (VEC(tree,gc) **placement, t
>> - (max_outer_nelts.high ? clz_hwi (max_outer_nelts.high)
>> : (HOST_BITS_PER_WIDE_INT + clz_hwi (max_outer_nelts.low)));
>> max_outer_nelts
>> - = double_int_lshift (double_int_rshift
>> - (max_outer_nelts, shift,
>> - HOST_BITS_PER_DOUBLE_INT, false),
>> - shift, HOST_BITS_PER_DOUBLE_INT, false);
>> + = max_outer_nelts.lrshift (shift, HOST_BITS_PER_DOUBLE_INT)
>> + .llshift (shift, HOST_BITS_PER_DOUBLE_INT);
>> }
>> max_outer_nelts_tree = double_int_to_tree (sizetype, max_outer_nelts);
>>
>> Index: gcc/cp/decl.c
>> ===================================================================
>> --- gcc/cp/decl.c (revision 191083)
>> +++ gcc/cp/decl.c (working copy)
>> @@ -12448,8 +12448,6 @@ build_enumerator (tree name, tree value,
>> {
>> if (TYPE_VALUES (enumtype))
>> {
>> - HOST_WIDE_INT hi;
>> - unsigned HOST_WIDE_INT lo;
>> tree prev_value;
>> bool overflowed;
>>
>> @@ -12465,15 +12463,13 @@ build_enumerator (tree name, tree value,
>> value = error_mark_node;
>> else
>> {
>> - overflowed = add_double (TREE_INT_CST_LOW (prev_value),
>> - TREE_INT_CST_HIGH (prev_value),
>> - 1, 0, &lo, &hi);
>> + double_int di = TREE_INT_CST (prev_value)
>> + .add_with_sign (double_int_one,
>> + false, &overflowed);
>> if (!overflowed)
>> {
>> - double_int di;
>> tree type = TREE_TYPE (prev_value);
>> - bool pos = (TYPE_UNSIGNED (type) || hi >= 0);
>> - di.low = lo; di.high = hi;
>> + bool pos = TYPE_UNSIGNED (type) || !di.is_negative ();
>> if (!double_int_fits_to_tree_p (type, di))
>> {
>> unsigned int itk;
>> Index: gcc/cp/typeck2.c
>> ===================================================================
>> --- gcc/cp/typeck2.c (revision 191083)
>> +++ gcc/cp/typeck2.c (working copy)
>> @@ -1055,14 +1055,12 @@ process_init_constructor_array (tree typ
>> {
>> tree domain = TYPE_DOMAIN (type);
>> if (domain)
>> - len = double_int_ext
>> - (double_int_add
>> - (double_int_sub
>> - (tree_to_double_int (TYPE_MAX_VALUE (domain)),
>> - tree_to_double_int (TYPE_MIN_VALUE (domain))),
>> - double_int_one),
>> - TYPE_PRECISION (TREE_TYPE (domain)),
>> - TYPE_UNSIGNED (TREE_TYPE (domain))).low;
>> + len = (tree_to_double_int (TYPE_MAX_VALUE (domain))
>> + - tree_to_double_int (TYPE_MIN_VALUE (domain))
>> + + double_int_one)
>> + .ext (TYPE_PRECISION (TREE_TYPE (domain)),
>> + TYPE_UNSIGNED (TREE_TYPE (domain)))
>> + .low;
>> else
>> unbounded = true; /* Take as many as there are. */
>> }
>> Index: gcc/cp/mangle.c
>> ===================================================================
>> --- gcc/cp/mangle.c (revision 191083)
>> +++ gcc/cp/mangle.c (working copy)
>> @@ -3119,12 +3119,11 @@ write_array_type (const tree type)
>> {
>> /* The ABI specifies that we should mangle the number of
>> elements in the array, not the largest allowed index. */
>> - double_int dmax
>> - = double_int_add (tree_to_double_int (max), double_int_one);
>> + double_int dmax = tree_to_double_int (max) + double_int_one;
>> /* Truncate the result - this will mangle [0, SIZE_INT_MAX]
>> number of elements as zero. */
>> - dmax = double_int_zext (dmax, TYPE_PRECISION (TREE_TYPE (max)));
>> - gcc_assert (double_int_fits_in_uhwi_p (dmax));
>> + dmax = dmax.zext (TYPE_PRECISION (TREE_TYPE (max)));
>> + gcc_assert (dmax.fits_uhwi ());
>> write_unsigned_number (dmax.low);
>> }
>> else
>> Index: gcc/double-int.c
>> ===================================================================
>> --- gcc/double-int.c (revision 191083)
>> +++ gcc/double-int.c (working copy)
>> @@ -23,6 +23,41 @@ along with GCC; see the file COPYING3.
>> #include "tm.h" /* For SHIFT_COUNT_TRUNCATED. */
>> #include "tree.h"
>>
>> +static int add_double_with_sign (unsigned HOST_WIDE_INT, HOST_WIDE_INT,
>> + unsigned HOST_WIDE_INT, HOST_WIDE_INT,
>> + unsigned HOST_WIDE_INT *, HOST_WIDE_INT *,
>> + bool);
>> +
>> +#define add_double(l1,h1,l2,h2,lv,hv) \
>> + add_double_with_sign (l1, h1, l2, h2, lv, hv, false)
>> +
>> +static int neg_double (unsigned HOST_WIDE_INT, HOST_WIDE_INT,
>> + unsigned HOST_WIDE_INT *, HOST_WIDE_INT *);
>> +
>> +static int mul_double_with_sign (unsigned HOST_WIDE_INT, HOST_WIDE_INT,
>> + unsigned HOST_WIDE_INT, HOST_WIDE_INT,
>> + unsigned HOST_WIDE_INT *, HOST_WIDE_INT *,
>> + bool);
>> +
>> +static int mul_double_wide_with_sign (unsigned HOST_WIDE_INT, HOST_WIDE_INT,
>> + unsigned HOST_WIDE_INT, HOST_WIDE_INT,
>> + unsigned HOST_WIDE_INT *, HOST_WIDE_INT *,
>> + unsigned HOST_WIDE_INT *, HOST_WIDE_INT *,
>> + bool);
>> +
>> +#define mul_double(l1,h1,l2,h2,lv,hv) \
>> + mul_double_with_sign (l1, h1, l2, h2, lv, hv, false)
>> +
>> +static void lshift_double (unsigned HOST_WIDE_INT, HOST_WIDE_INT,
>> + HOST_WIDE_INT, unsigned int,
>> + unsigned HOST_WIDE_INT *, HOST_WIDE_INT *, bool);
>> +
>> +static int div_and_round_double (unsigned, int, unsigned HOST_WIDE_INT,
>> + HOST_WIDE_INT, unsigned HOST_WIDE_INT,
>> + HOST_WIDE_INT, unsigned HOST_WIDE_INT *,
>> + HOST_WIDE_INT *, unsigned HOST_WIDE_INT *,
>> + HOST_WIDE_INT *);
>> +
>> /* We know that A1 + B1 = SUM1, using 2's complement arithmetic and ignoring
>> overflow. Suppose A, B and SUM have the same respective signs as A1, B1,
>> and SUM1. Then this yields nonzero if overflow occurred during the
>> @@ -75,7 +110,7 @@ decode (HOST_WIDE_INT *words, unsigned H
>> One argument is L1 and H1; the other, L2 and H2.
>> The value is stored as two `HOST_WIDE_INT' pieces in *LV and *HV. */
>>
>> -int
>> +static int
>> add_double_with_sign (unsigned HOST_WIDE_INT l1, HOST_WIDE_INT h1,
>> unsigned HOST_WIDE_INT l2, HOST_WIDE_INT h2,
>> unsigned HOST_WIDE_INT *lv, HOST_WIDE_INT *hv,
>> @@ -105,7 +140,7 @@ add_double_with_sign (unsigned HOST_WIDE
>> The argument is given as two `HOST_WIDE_INT' pieces in L1 and H1.
>> The value is stored as two `HOST_WIDE_INT' pieces in *LV and *HV. */
>>
>> -int
>> +static int
>> neg_double (unsigned HOST_WIDE_INT l1, HOST_WIDE_INT h1,
>> unsigned HOST_WIDE_INT *lv, HOST_WIDE_INT *hv)
>> {
>> @@ -129,7 +164,7 @@ neg_double (unsigned HOST_WIDE_INT l1, H
>> One argument is L1 and H1; the other, L2 and H2.
>> The value is stored as two `HOST_WIDE_INT' pieces in *LV and *HV. */
>>
>> -int
>> +static int
>> mul_double_with_sign (unsigned HOST_WIDE_INT l1, HOST_WIDE_INT h1,
>> unsigned HOST_WIDE_INT l2, HOST_WIDE_INT h2,
>> unsigned HOST_WIDE_INT *lv, HOST_WIDE_INT *hv,
>> @@ -143,7 +178,7 @@ mul_double_with_sign (unsigned HOST_WIDE
>> unsigned_p);
>> }
>>
>> -int
>> +static int
>> mul_double_wide_with_sign (unsigned HOST_WIDE_INT l1, HOST_WIDE_INT h1,
>> unsigned HOST_WIDE_INT l2, HOST_WIDE_INT h2,
>> unsigned HOST_WIDE_INT *lv, HOST_WIDE_INT *hv,
>> @@ -269,7 +304,7 @@ rshift_double (unsigned HOST_WIDE_INT l1
>> ARITH nonzero specifies arithmetic shifting; otherwise use logical shift.
>> Store the value as two `HOST_WIDE_INT' pieces in *LV and *HV. */
>>
>> -void
>> +static 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, bool arith)
>> @@ -335,7 +370,7 @@ lshift_double (unsigned HOST_WIDE_INT l1
>> Return nonzero if the operation overflows.
>> UNS nonzero says do unsigned division. */
>>
>> -int
>> +static int
>> div_and_round_double (unsigned code, int uns,
>> /* num == numerator == dividend */
>> unsigned HOST_WIDE_INT lnum_orig,
>> @@ -762,6 +797,19 @@ double_int::mul_with_sign (double_int b,
>> return ret;
>> }
>>
>> +double_int
>> +double_int::wide_mul_with_sign (double_int b, bool unsigned_p,
>> + double_int *higher, bool *overflow) const
>> +
>> +{
>> + double_int lower;
>> + *overflow = mul_double_wide_with_sign (low, high, b.low, b.high,
>> + &lower.low, &lower.high,
>> + &higher->low, &higher->high,
>> + unsigned_p);
>> + return lower;
>> +}
>> +
>> /* Returns A + B. */
>>
>> double_int
>> @@ -809,12 +857,33 @@ double_int::operator - () const
>> return ret;
>> }
>>
>> +double_int
>> +double_int::neg_with_overflow (bool *overflow) const
>> +{
>> + double_int ret;
>> + *overflow = neg_double (low, high, &ret.low, &ret.high);
>> + return ret;
>> +}
>> +
>> /* Returns A / B (computed as unsigned depending on UNS, and rounded as
>> specified by CODE). CODE is enum tree_code in fact, but double_int.h
>> must be included before tree.h. The remainder after the division is
>> stored to MOD. */
>>
>> double_int
>> +double_int::divmod_with_overflow (double_int b, bool uns, unsigned code,
>> + double_int *mod, bool *overflow) const
>> +{
>> + const double_int &a = *this;
>> + double_int ret;
>> +
>> + *overflow = div_and_round_double (code, uns, a.low, a.high,
>> + b.low, b.high, &ret.low, &ret.high,
>> + &mod->low, &mod->high);
>> + return ret;
>> +}
>> +
>> +double_int
>> double_int::divmod (double_int b, bool uns, unsigned code,
>> double_int *mod) const
>> {
>> Index: gcc/double-int.h
>> ===================================================================
>> --- gcc/double-int.h (revision 191083)
>> +++ gcc/double-int.h (working copy)
>> @@ -61,6 +61,7 @@ struct double_int
>>
>> static double_int from_uhwi (unsigned HOST_WIDE_INT cst);
>> static double_int from_shwi (HOST_WIDE_INT cst);
>> + static double_int from_pair (HOST_WIDE_INT high, unsigned HOST_WIDE_INT low);
>>
>> /* No copy assignment operator or destructor to keep the type a POD. */
>>
>> @@ -105,9 +106,16 @@ struct double_int
>>
>> /* Arithmetic operation functions. */
>>
>> + /* The following operations perform arithmetics modulo 2^precision, so you
>> + do not need to call .ext between them, even if you are representing
>> + numbers with precision less than HOST_BITS_PER_DOUBLE_INT bits. */
>> +
>> double_int set_bit (unsigned) const;
>> double_int mul_with_sign (double_int, bool unsigned_p, bool *overflow) const;
>> + double_int wide_mul_with_sign (double_int, bool unsigned_p,
>> + double_int *higher, bool *overflow) const;
>> double_int add_with_sign (double_int, bool unsigned_p, bool *overflow) const;
>> + double_int neg_with_overflow (bool *overflow) const;
>>
>> double_int operator * (double_int) const;
>> double_int operator + (double_int) const;
>> @@ -131,12 +139,15 @@ struct double_int
>> /* You must ensure that double_int::ext is called on the operands
>> of the following operations, if the precision of the numbers
>> is less than HOST_BITS_PER_DOUBLE_INT bits. */
>> +
>> double_int div (double_int, bool, unsigned) const;
>> double_int sdiv (double_int, unsigned) const;
>> double_int udiv (double_int, unsigned) const;
>> double_int mod (double_int, bool, unsigned) const;
>> double_int smod (double_int, unsigned) const;
>> double_int umod (double_int, unsigned) const;
>> + double_int divmod_with_overflow (double_int, bool, unsigned,
>> + double_int *, bool *) const;
>> double_int divmod (double_int, bool, unsigned, double_int *) const;
>> double_int sdivmod (double_int, unsigned, double_int *) const;
>> double_int udivmod (double_int, unsigned, double_int *) const;
>> @@ -199,13 +210,6 @@ double_int::from_shwi (HOST_WIDE_INT cst
>> return r;
>> }
>>
>> -/* FIXME(crowl): Remove after converting callers. */
>> -static inline double_int
>> -shwi_to_double_int (HOST_WIDE_INT cst)
>> -{
>> - return double_int::from_shwi (cst);
>> -}
>> -
>> /* Some useful constants. */
>> /* FIXME(crowl): Maybe remove after converting callers?
>> The problem is that a named constant would not be as optimizable,
>> @@ -229,11 +233,13 @@ double_int::from_uhwi (unsigned HOST_WID
>> return r;
>> }
>>
>> -/* FIXME(crowl): Remove after converting callers. */
>> -static inline double_int
>> -uhwi_to_double_int (unsigned HOST_WIDE_INT cst)
>> +inline double_int
>> +double_int::from_pair (HOST_WIDE_INT high, unsigned HOST_WIDE_INT low)
>> {
>> - return double_int::from_uhwi (cst);
>> + double_int r;
>> + r.low = low;
>> + r.high = high;
>> + return r;
>> }
>>
>> inline double_int &
>> @@ -301,13 +307,6 @@ double_int::to_shwi () const
>> return (HOST_WIDE_INT) low;
>> }
>>
>> -/* FIXME(crowl): Remove after converting callers. */
>> -static inline HOST_WIDE_INT
>> -double_int_to_shwi (double_int cst)
>> -{
>> - return cst.to_shwi ();
>> -}
>> -
>> /* Returns value of CST as an unsigned number. CST must satisfy
>> double_int::fits_unsigned. */
>>
>> @@ -317,13 +316,6 @@ double_int::to_uhwi () const
>> return low;
>> }
>>
>> -/* FIXME(crowl): Remove after converting callers. */
>> -static inline unsigned HOST_WIDE_INT
>> -double_int_to_uhwi (double_int cst)
>> -{
>> - return cst.to_uhwi ();
>> -}
>> -
>> /* Returns true if CST fits in unsigned HOST_WIDE_INT. */
>>
>> inline bool
>> @@ -332,164 +324,6 @@ double_int::fits_uhwi () const
>> return high == 0;
>> }
>>
>> -/* FIXME(crowl): Remove after converting callers. */
>> -static inline bool
>> -double_int_fits_in_uhwi_p (double_int cst)
>> -{
>> - return cst.fits_uhwi ();
>> -}
>> -
>> -/* Returns true if CST fits in signed HOST_WIDE_INT. */
>> -
>> -/* FIXME(crowl): Remove after converting callers. */
>> -inline bool
>> -double_int_fits_in_shwi_p (double_int cst)
>> -{
>> - return cst.fits_shwi ();
>> -}
>> -
>> -/* FIXME(crowl): Remove after converting callers. */
>> -inline bool
>> -double_int_fits_in_hwi_p (double_int cst, bool uns)
>> -{
>> - return cst.fits_hwi (uns);
>> -}
>> -
>> -/* The following operations perform arithmetics modulo 2^precision,
>> - so you do not need to call double_int_ext between them, even if
>> - you are representing numbers with precision less than
>> - HOST_BITS_PER_DOUBLE_INT bits. */
>> -
>> -/* FIXME(crowl): Remove after converting callers. */
>> -inline double_int
>> -double_int_mul (double_int a, double_int b)
>> -{
>> - return a * b;
>> -}
>> -
>> -/* FIXME(crowl): Remove after converting callers. */
>> -inline double_int
>> -double_int_mul_with_sign (double_int a, double_int b,
>> - bool unsigned_p, int *overflow)
>> -{
>> - bool ovf;
>> - return a.mul_with_sign (b, unsigned_p, &ovf);
>> - *overflow = ovf;
>> -}
>> -
>> -/* FIXME(crowl): Remove after converting callers. */
>> -inline double_int
>> -double_int_add (double_int a, double_int b)
>> -{
>> - return a + b;
>> -}
>> -
>> -/* FIXME(crowl): Remove after converting callers. */
>> -inline double_int
>> -double_int_sub (double_int a, double_int b)
>> -{
>> - return a - b;
>> -}
>> -
>> -/* FIXME(crowl): Remove after converting callers. */
>> -inline double_int
>> -double_int_neg (double_int a)
>> -{
>> - return -a;
>> -}
>> -
>> -/* You must ensure that double_int_ext is called on the operands
>> - of the following operations, if the precision of the numbers
>> - is less than HOST_BITS_PER_DOUBLE_INT bits. */
>> -
>> -/* FIXME(crowl): Remove after converting callers. */
>> -inline double_int
>> -double_int_div (double_int a, double_int b, bool uns, unsigned code)
>> -{
>> - return a.div (b, uns, code);
>> -}
>> -
>> -/* FIXME(crowl): Remove after converting callers. */
>> -inline double_int
>> -double_int_sdiv (double_int a, double_int b, unsigned code)
>> -{
>> - return a.sdiv (b, code);
>> -}
>> -
>> -/* FIXME(crowl): Remove after converting callers. */
>> -inline double_int
>> -double_int_udiv (double_int a, double_int b, unsigned code)
>> -{
>> - return a.udiv (b, code);
>> -}
>> -
>> -/* FIXME(crowl): Remove after converting callers. */
>> -inline double_int
>> -double_int_mod (double_int a, double_int b, bool uns, unsigned code)
>> -{
>> - return a.mod (b, uns, code);
>> -}
>> -
>> -/* FIXME(crowl): Remove after converting callers. */
>> -inline double_int
>> -double_int_smod (double_int a, double_int b, unsigned code)
>> -{
>> - return a.smod (b, code);
>> -}
>> -
>> -/* FIXME(crowl): Remove after converting callers. */
>> -inline double_int
>> -double_int_umod (double_int a, double_int b, unsigned code)
>> -{
>> - return a.umod (b, code);
>> -}
>> -
>> -/* FIXME(crowl): Remove after converting callers. */
>> -inline double_int
>> -double_int_divmod (double_int a, double_int b, bool uns,
>> - unsigned code, double_int *mod)
>> -{
>> - return a.divmod (b, uns, code, mod);
>> -}
>> -
>> -/* FIXME(crowl): Remove after converting callers. */
>> -inline double_int
>> -double_int_sdivmod (double_int a, double_int b, unsigned code, double_int *mod)
>> -{
>> - return a.sdivmod (b, code, mod);
>> -}
>> -
>> -/* FIXME(crowl): Remove after converting callers. */
>> -inline double_int
>> -double_int_udivmod (double_int a, double_int b, unsigned code, double_int *mod)
>> -{
>> - return a.udivmod (b, code, mod);
>> -}
>> -
>> -/***/
>> -
>> -/* FIXME(crowl): Remove after converting callers. */
>> -inline bool
>> -double_int_multiple_of (double_int product, double_int factor,
>> - bool unsigned_p, double_int *multiple)
>> -{
>> - return product.multiple_of (factor, unsigned_p, multiple);
>> -}
>> -
>> -/* FIXME(crowl): Remove after converting callers. */
>> -inline double_int
>> -double_int_setbit (double_int a, unsigned bitpos)
>> -{
>> - return a.set_bit (bitpos);
>> -}
>> -
>> -/* FIXME(crowl): Remove after converting callers. */
>> -inline int
>> -double_int_ctz (double_int a)
>> -{
>> - return a.trailing_zeros ();
>> -}
>> -
>> /* Logical operations. */
>>
>> /* Returns ~A. */
>> @@ -503,13 +337,6 @@ double_int::operator ~ () const
>> return result;
>> }
>>
>> -/* FIXME(crowl): Remove after converting callers. */
>> -static inline double_int
>> -double_int_not (double_int a)
>> -{
>> - return ~a;
>> -}
>> -
>> /* Returns A | B. */
>>
>> inline double_int
>> @@ -521,13 +348,6 @@ double_int::operator | (double_int b) co
>> return result;
>> }
>>
>> -/* FIXME(crowl): Remove after converting callers. */
>> -static inline double_int
>> -double_int_ior (double_int a, double_int b)
>> -{
>> - return a | b;
>> -}
>> -
>> /* Returns A & B. */
>>
>> inline double_int
>> @@ -539,13 +359,6 @@ double_int::operator & (double_int b) co
>> return result;
>> }
>>
>> -/* FIXME(crowl): Remove after converting callers. */
>> -static inline double_int
>> -double_int_and (double_int a, double_int b)
>> -{
>> - return a & b;
>> -}
>> -
>> /* Returns A & ~B. */
>>
>> inline double_int
>> @@ -557,13 +370,6 @@ double_int::and_not (double_int b) const
>> return result;
>> }
>>
>> -/* FIXME(crowl): Remove after converting callers. */
>> -static inline double_int
>> -double_int_and_not (double_int a, double_int b)
>> -{
>> - return a.and_not (b);
>> -}
>> -
>> /* Returns A ^ B. */
>>
>> inline double_int
>> @@ -575,165 +381,8 @@ double_int::operator ^ (double_int b) co
>> return result;
>> }
>>
>> -/* FIXME(crowl): Remove after converting callers. */
>> -static inline double_int
>> -double_int_xor (double_int a, double_int b)
>> -{
>> - return a ^ b;
>> -}
>> -
>> -
>> -/* Shift operations. */
>> -
>> -/* FIXME(crowl): Remove after converting callers. */
>> -inline double_int
>> -double_int_lshift (double_int a, HOST_WIDE_INT count, unsigned int prec,
>> - bool arith)
>> -{
>> - return a.lshift (count, prec, arith);
>> -}
>> -
>> -/* FIXME(crowl): Remove after converting callers. */
>> -inline double_int
>> -double_int_rshift (double_int a, HOST_WIDE_INT count, unsigned int prec,
>> - bool arith)
>> -{
>> - return a.rshift (count, prec, arith);
>> -}
>> -
>> -/* FIXME(crowl): Remove after converting callers. */
>> -inline double_int
>> -double_int_lrotate (double_int a, HOST_WIDE_INT count, unsigned int prec)
>> -{
>> - return a.lrotate (count, prec);
>> -}
>> -
>> -/* FIXME(crowl): Remove after converting callers. */
>> -inline double_int
>> -double_int_rrotate (double_int a, HOST_WIDE_INT count, unsigned int prec)
>> -{
>> - return a.rrotate (count, prec);
>> -}
>> -
>> -/* 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;
>> -}
>> -
>> -/* FIXME(crowl): Remove after converting callers. */
>> -inline int
>> -double_int_cmp (double_int a, double_int b, bool uns)
>> -{
>> - return a.cmp (b, uns);
>> -}
>> -
>> -/* FIXME(crowl): Remove after converting callers. */
>> -inline int
>> -double_int_scmp (double_int a, double_int b)
>> -{
>> - return a.scmp (b);
>> -}
>> -
>> -/* FIXME(crowl): Remove after converting callers. */
>> -inline int
>> -double_int_ucmp (double_int a, double_int b)
>> -{
>> - return a.ucmp (b);
>> -}
>> -
>> -/* FIXME(crowl): Remove after converting callers. */
>> -inline double_int
>> -double_int_max (double_int a, double_int b, bool uns)
>> -{
>> - return a.max (b, uns);
>> -}
>> -
>> -/* FIXME(crowl): Remove after converting callers. */
>> -inline double_int
>> -double_int_smax (double_int a, double_int b)
>> -{
>> - return a.smax (b);
>> -}
>> -
>> -/* FIXME(crowl): Remove after converting callers. */
>> -inline double_int
>> -double_int_umax (double_int a, double_int b)
>> -{
>> - return a.umax (b);
>> -}
>> -
>> -
>> -/* FIXME(crowl): Remove after converting callers. */
>> -inline double_int
>> -double_int_min (double_int a, double_int b, bool uns)
>> -{
>> - return a.min (b, uns);
>> -}
>> -
>> -/* FIXME(crowl): Remove after converting callers. */
>> -inline double_int
>> -double_int_smin (double_int a, double_int b)
>> -{
>> - return a.smin (b);
>> -}
>> -
>> -/* FIXME(crowl): Remove after converting callers. */
>> -inline double_int
>> -double_int_umin (double_int a, double_int b)
>> -{
>> - return a.umin (b);
>> -}
>> -
>> void dump_double_int (FILE *, double_int, bool);
>>
>> -/* Zero and sign extension of numbers in smaller precisions. */
>> -
>> -/* FIXME(crowl): Remove after converting callers. */
>> -inline double_int
>> -double_int_ext (double_int a, unsigned prec, bool uns)
>> -{
>> - return a.ext (prec, uns);
>> -}
>> -
>> -/* FIXME(crowl): Remove after converting callers. */
>> -inline double_int
>> -double_int_sext (double_int a, unsigned prec)
>> -{
>> - return a.sext (prec);
>> -}
>> -
>> -/* FIXME(crowl): Remove after converting callers. */
>> -inline double_int
>> -double_int_zext (double_int a, unsigned prec)
>> -{
>> - return a.zext (prec);
>> -}
>> -
>> -/* FIXME(crowl): Remove after converting callers. */
>> -inline double_int
>> -double_int_mask (unsigned prec)
>> -{
>> - return double_int::mask (prec);
>> -}
>> -
>> -/* FIXME(crowl): Remove after converting callers. */
>> -inline double_int
>> -double_int_max_value (unsigned int prec, bool uns)
>> -{
>> - return double_int::max_value (prec, uns);
>> -}
>> -
>> -/* FIXME(crowl): Remove after converting callers. */
>> -inline double_int
>> -double_int_min_value (unsigned int prec, bool uns)
>> -{
>> - return double_int::min_value (prec, uns);
>> -}
>> -
>> #define ALL_ONES (~((unsigned HOST_WIDE_INT) 0))
>>
>> /* The operands of the following comparison functions must be processed
>> @@ -748,13 +397,6 @@ double_int::is_zero () const
>> return low == 0 && high == 0;
>> }
>>
>> -/* FIXME(crowl): Remove after converting callers. */
>> -static inline bool
>> -double_int_zero_p (double_int cst)
>> -{
>> - return cst.is_zero ();
>> -}
>> -
>> /* Returns true if CST is one. */
>>
>> inline bool
>> @@ -763,13 +405,6 @@ double_int::is_one () const
>> return low == 1 && high == 0;
>> }
>>
>> -/* FIXME(crowl): Remove after converting callers. */
>> -static inline bool
>> -double_int_one_p (double_int cst)
>> -{
>> - return cst.is_one ();
>> -}
>> -
>> /* Returns true if CST is minus one. */
>>
>> inline bool
>> @@ -778,13 +413,6 @@ double_int::is_minus_one () const
>> return low == ALL_ONES && high == -1;
>> }
>>
>> -/* FIXME(crowl): Remove after converting callers. */
>> -static inline bool
>> -double_int_minus_one_p (double_int cst)
>> -{
>> - return cst.is_minus_one ();
>> -}
>> -
>> /* Returns true if CST is negative. */
>>
>> inline bool
>> @@ -801,13 +429,6 @@ double_int::operator == (double_int cst2
>> return low == cst2.low && high == cst2.high;
>> }
>>
>> -/* FIXME(crowl): Remove after converting callers. */
>> -static inline bool
>> -double_int_equal_p (double_int cst1, double_int cst2)
>> -{
>> - return cst1 == cst2;
>> -}
>> -
>> /* Returns true if CST1 != CST2. */
>>
>> inline bool
>> @@ -824,52 +445,6 @@ double_int::popcount () const
>> return popcount_hwi (high) + popcount_hwi (low);
>> }
>>
>> -/* FIXME(crowl): Remove after converting callers. */
>> -static inline int
>> -double_int_popcount (double_int cst)
>> -{
>> - return cst.popcount ();
>> -}
>> -
>> -
>> -/* Legacy interface with decomposed high/low parts. */
>> -
>> -/* FIXME(crowl): Remove after converting callers. */
>> -extern int add_double_with_sign (unsigned HOST_WIDE_INT, HOST_WIDE_INT,
>> - unsigned HOST_WIDE_INT, HOST_WIDE_INT,
>> - unsigned HOST_WIDE_INT *, HOST_WIDE_INT *,
>> - bool);
>> -/* FIXME(crowl): Remove after converting callers. */
>> -#define add_double(l1,h1,l2,h2,lv,hv) \
>> - add_double_with_sign (l1, h1, l2, h2, lv, hv, false)
>> -/* FIXME(crowl): Remove after converting callers. */
>> -extern int neg_double (unsigned HOST_WIDE_INT, HOST_WIDE_INT,
>> - unsigned HOST_WIDE_INT *, HOST_WIDE_INT *);
>> -/* FIXME(crowl): Remove after converting callers. */
>> -extern int mul_double_with_sign (unsigned HOST_WIDE_INT, HOST_WIDE_INT,
>> - unsigned HOST_WIDE_INT, HOST_WIDE_INT,
>> - unsigned HOST_WIDE_INT *, HOST_WIDE_INT *,
>> - bool);
>> -/* FIXME(crowl): Remove after converting callers. */
>> -extern int mul_double_wide_with_sign (unsigned HOST_WIDE_INT, HOST_WIDE_INT,
>> - unsigned HOST_WIDE_INT, HOST_WIDE_INT,
>> - unsigned HOST_WIDE_INT *, HOST_WIDE_INT *,
>> - unsigned HOST_WIDE_INT *, HOST_WIDE_INT *,
>> - bool);
>> -/* FIXME(crowl): Remove after converting callers. */
>> -#define mul_double(l1,h1,l2,h2,lv,hv) \
>> - mul_double_with_sign (l1, h1, l2, h2, lv, hv, false)
>> -/* FIXME(crowl): Remove after converting callers. */
>> -extern void lshift_double (unsigned HOST_WIDE_INT, HOST_WIDE_INT,
>> - HOST_WIDE_INT, unsigned int,
>> - unsigned HOST_WIDE_INT *, HOST_WIDE_INT *, bool);
>> -/* FIXME(crowl): Remove after converting callers. */
>> -extern int div_and_round_double (unsigned, int, unsigned HOST_WIDE_INT,
>> - HOST_WIDE_INT, unsigned HOST_WIDE_INT,
>> - HOST_WIDE_INT, unsigned HOST_WIDE_INT *,
>> - HOST_WIDE_INT *, unsigned HOST_WIDE_INT *,
>> - HOST_WIDE_INT *);
>> -
>>
>> #ifndef GENERATOR_FILE
>> /* Conversion to and from GMP integer representations. */
>> Index: gcc/fortran/trans-expr.c
>> ===================================================================
>> --- gcc/fortran/trans-expr.c (revision 191083)
>> +++ gcc/fortran/trans-expr.c (working copy)
>> @@ -1657,10 +1657,10 @@ gfc_conv_cst_int_power (gfc_se * se, tre
>>
>> /* If exponent is too large, we won't expand it anyway, so don't bother
>> with large integer values. */
>> - if (!double_int_fits_in_shwi_p (TREE_INT_CST (rhs)))
>> + if (!TREE_INT_CST (rhs).fits_shwi ())
>> return 0;
>>
>> - m = double_int_to_shwi (TREE_INT_CST (rhs));
>> + m = TREE_INT_CST (rhs).to_shwi ();
>> /* There's no ABS for HOST_WIDE_INT, so here we go. It also takes care
>> of the asymmetric range of the integer type. */
>> n = (unsigned HOST_WIDE_INT) (m < 0 ? -m : m);
>> Index: gcc/fortran/target-memory.c
>> ===================================================================
>> --- gcc/fortran/target-memory.c (revision 191083)
>> +++ gcc/fortran/target-memory.c (working copy)
>> @@ -395,8 +395,7 @@ gfc_interpret_logical (int kind, unsigne
>> {
>> tree t = native_interpret_expr (gfc_get_logical_type (kind), buffer,
>> buffer_size);
>> - *logical = double_int_zero_p (tree_to_double_int (t))
>> - ? 0 : 1;
>> + *logical = tree_to_double_int (t).is_zero () ? 0 : 1;
>> return size_logical (kind);
>> }
>>
>> Index: gcc/expmed.c
>> ===================================================================
>> --- gcc/expmed.c (revision 191083)
>> +++ gcc/expmed.c (working copy)
>> @@ -3404,12 +3404,9 @@ choose_multiplier (unsigned HOST_WIDE_IN
>> unsigned HOST_WIDE_INT *multiplier_ptr,
>> int *post_shift_ptr, int *lgup_ptr)
>> {
>> - HOST_WIDE_INT mhigh_hi, mlow_hi;
>> - unsigned HOST_WIDE_INT mhigh_lo, mlow_lo;
>> + double_int mhigh, mlow;
>> int lgup, post_shift;
>> int pow, pow2;
>> - unsigned HOST_WIDE_INT nl, dummy1;
>> - HOST_WIDE_INT nh, dummy2;
>>
>> /* lgup = ceil(log2(divisor)); */
>> lgup = ceil_log2 (d);
>> @@ -3425,32 +3422,17 @@ choose_multiplier (unsigned HOST_WIDE_IN
>> gcc_assert (pow != HOST_BITS_PER_DOUBLE_INT);
>>
>> /* mlow = 2^(N + lgup)/d */
>> - if (pow >= HOST_BITS_PER_WIDE_INT)
>> - {
>> - nh = (HOST_WIDE_INT) 1 << (pow - HOST_BITS_PER_WIDE_INT);
>> - nl = 0;
>> - }
>> - else
>> - {
>> - nh = 0;
>> - nl = (unsigned HOST_WIDE_INT) 1 << pow;
>> - }
>> - div_and_round_double (TRUNC_DIV_EXPR, 1, nl, nh, d, (HOST_WIDE_INT) 0,
>> - &mlow_lo, &mlow_hi, &dummy1, &dummy2);
>> + double_int val = double_int_zero.set_bit (pow);
>> + mlow = val.div (double_int::from_uhwi (d), true, TRUNC_DIV_EXPR);
>>
>> - /* mhigh = (2^(N + lgup) + 2^N + lgup - precision)/d */
>> - if (pow2 >= HOST_BITS_PER_WIDE_INT)
>> - nh |= (HOST_WIDE_INT) 1 << (pow2 - HOST_BITS_PER_WIDE_INT);
>> - else
>> - nl |= (unsigned HOST_WIDE_INT) 1 << pow2;
>> - div_and_round_double (TRUNC_DIV_EXPR, 1, nl, nh, d, (HOST_WIDE_INT) 0,
>> - &mhigh_lo, &mhigh_hi, &dummy1, &dummy2);
>> + /* mhigh = (2^(N + lgup) + 2^(N + lgup - precision))/d */
>> + val |= double_int_zero.set_bit (pow2);
>> + mhigh = val.div (double_int::from_uhwi (d), true, TRUNC_DIV_EXPR);
>>
>> - gcc_assert (!mhigh_hi || nh - d < d);
>> - gcc_assert (mhigh_hi <= 1 && mlow_hi <= 1);
>> + gcc_assert (!mhigh.high || val.high - d < d);
>> + gcc_assert (mhigh.high <= 1 && mlow.high <= 1);
>> /* Assert that mlow < mhigh. */
>> - gcc_assert (mlow_hi < mhigh_hi
>> - || (mlow_hi == mhigh_hi && mlow_lo < mhigh_lo));
>> + gcc_assert (mlow.ult (mhigh));
>>
>> /* If precision == N, then mlow, mhigh exceed 2^N
>> (but they do not exceed 2^(N+1)). */
>> @@ -3458,15 +3440,14 @@ choose_multiplier (unsigned HOST_WIDE_IN
>> /* Reduce to lowest terms. */
>> for (post_shift = lgup; post_shift > 0; post_shift--)
>> {
>> - unsigned HOST_WIDE_INT ml_lo = (mlow_hi <<
>> (HOST_BITS_PER_WIDE_INT - 1)) | (mlow_lo >> 1);
>> - unsigned HOST_WIDE_INT mh_lo = (mhigh_hi <<
>> (HOST_BITS_PER_WIDE_INT - 1)) | (mhigh_lo >> 1);
>> + int shft = HOST_BITS_PER_WIDE_INT - 1;
>> + unsigned HOST_WIDE_INT ml_lo = (mlow.high << shft) | (mlow.low >> 1);
>> + unsigned HOST_WIDE_INT mh_lo = (mhigh.high << shft) | (mhigh.low >> 1);
>> if (ml_lo >= mh_lo)
>> break;
>>
>> - mlow_hi = 0;
>> - mlow_lo = ml_lo;
>> - mhigh_hi = 0;
>> - mhigh_lo = mh_lo;
>> + mlow = double_int::from_uhwi (ml_lo);
>> + mhigh = double_int::from_uhwi (mh_lo);
>> }
>>
>> *post_shift_ptr = post_shift;
>> @@ -3474,13 +3455,13 @@ choose_multiplier (unsigned HOST_WIDE_IN
>> if (n < HOST_BITS_PER_WIDE_INT)
>> {
>> unsigned HOST_WIDE_INT mask = ((unsigned HOST_WIDE_INT) 1 << n) - 1;
>> - *multiplier_ptr = mhigh_lo & mask;
>> - return mhigh_lo >= mask;
>> + *multiplier_ptr = mhigh.low & mask;
>> + return mhigh.low >= mask;
>> }
>> else
>> {
>> - *multiplier_ptr = mhigh_lo;
>> - return mhigh_hi;
>> + *multiplier_ptr = mhigh.low;
>> + return mhigh.high;
>> }
>> }
>>
>> Index: gcc/emit-rtl.c
>> ===================================================================
>> --- gcc/emit-rtl.c (revision 191083)
>> +++ gcc/emit-rtl.c (working copy)
>> @@ -5736,11 +5736,10 @@ init_emit_once (void)
>> FCONST1(mode).data.high = 0;
>> FCONST1(mode).data.low = 0;
>> FCONST1(mode).mode = mode;
>> - lshift_double (1, 0, GET_MODE_FBIT (mode),
>> - HOST_BITS_PER_DOUBLE_INT,
>> - &FCONST1(mode).data.low,
>> - &FCONST1(mode).data.high,
>> - SIGNED_FIXED_POINT_MODE_P (mode));
>> + FCONST1(mode).data
>> + = double_int_one.lshift (GET_MODE_FBIT (mode),
>> + HOST_BITS_PER_DOUBLE_INT,
>> + SIGNED_FIXED_POINT_MODE_P (mode));
>> const_tiny_rtx[1][(int) mode] = CONST_FIXED_FROM_FIXED_VALUE (
>> FCONST1 (mode), mode);
>> }
>> @@ -5759,11 +5758,10 @@ init_emit_once (void)
>> FCONST1(mode).data.high = 0;
>> FCONST1(mode).data.low = 0;
>> FCONST1(mode).mode = mode;
>> - lshift_double (1, 0, GET_MODE_FBIT (mode),
>> - HOST_BITS_PER_DOUBLE_INT,
>> - &FCONST1(mode).data.low,
>> - &FCONST1(mode).data.high,
>> - SIGNED_FIXED_POINT_MODE_P (mode));
>> + FCONST1(mode).data
>> + = double_int_one.lshift (GET_MODE_FBIT (mode),
>> + HOST_BITS_PER_DOUBLE_INT,
>> + SIGNED_FIXED_POINT_MODE_P (mode));
>> const_tiny_rtx[1][(int) mode] = CONST_FIXED_FROM_FIXED_VALUE (
>> FCONST1 (mode), mode);
>> }
>> Index: gcc/simplify-rtx.c
>> ===================================================================
>> --- gcc/simplify-rtx.c (revision 191083)
>> +++ gcc/simplify-rtx.c (working copy)
>> @@ -1525,109 +1525,117 @@ simplify_const_unary_operation (enum rtx
>> else if (width <= HOST_BITS_PER_DOUBLE_INT
>> && (CONST_DOUBLE_AS_INT_P (op) || CONST_INT_P (op)))
>> {
>> - unsigned HOST_WIDE_INT l1, lv;
>> - HOST_WIDE_INT h1, hv;
>> + double_int first, value;
>>
>> if (CONST_DOUBLE_AS_INT_P (op))
>> - l1 = CONST_DOUBLE_LOW (op), h1 = CONST_DOUBLE_HIGH (op);
>> + first = double_int::from_pair (CONST_DOUBLE_HIGH (op),
>> + CONST_DOUBLE_LOW (op));
>> else
>> - l1 = INTVAL (op), h1 = HWI_SIGN_EXTEND (l1);
>> + first = double_int::from_shwi (INTVAL (op));
>>
>> switch (code)
>> {
>> case NOT:
>> - lv = ~ l1;
>> - hv = ~ h1;
>> + value = ~first;
>> break;
>>
>> case NEG:
>> - neg_double (l1, h1, &lv, &hv);
>> + value = -first;
>> break;
>>
>> case ABS:
>> - if (h1 < 0)
>> - neg_double (l1, h1, &lv, &hv);
>> + if (first.is_negative ())
>> + value = -first;
>> else
>> - lv = l1, hv = h1;
>> + value = first;
>> break;
>>
>> case FFS:
>> - hv = 0;
>> - if (l1 != 0)
>> - lv = ffs_hwi (l1);
>> - else if (h1 != 0)
>> - lv = HOST_BITS_PER_WIDE_INT + ffs_hwi (h1);
>> + value.high = 0;
>> + if (first.low != 0)
>> + value.low = ffs_hwi (first.low);
>> + else if (first.high != 0)
>> + value.low = HOST_BITS_PER_WIDE_INT + ffs_hwi (first.high);
>> else
>> - lv = 0;
>> + value.low = 0;
>> break;
>>
>> case CLZ:
>> - hv = 0;
>> - if (h1 != 0)
>> - lv = GET_MODE_PRECISION (mode) - floor_log2 (h1) - 1
>> - - HOST_BITS_PER_WIDE_INT;
>> - else if (l1 != 0)
>> - lv = GET_MODE_PRECISION (mode) - floor_log2 (l1) - 1;
>> - else if (! CLZ_DEFINED_VALUE_AT_ZERO (mode, lv))
>> - lv = GET_MODE_PRECISION (mode);
>> + value.high = 0;
>> + if (first.high != 0)
>> + value.low = GET_MODE_PRECISION (mode) - floor_log2 (first.high) - 1
>> + - HOST_BITS_PER_WIDE_INT;
>> + else if (first.low != 0)
>> + value.low = GET_MODE_PRECISION (mode) - floor_log2 (first.low) - 1;
>> + else if (! CLZ_DEFINED_VALUE_AT_ZERO (mode, value.low))
>> + value.low = GET_MODE_PRECISION (mode);
>> break;
>>
>> case CTZ:
>> - hv = 0;
>> - if (l1 != 0)
>> - lv = ctz_hwi (l1);
>> - else if (h1 != 0)
>> - lv = HOST_BITS_PER_WIDE_INT + ctz_hwi (h1);
>> - else if (! CTZ_DEFINED_VALUE_AT_ZERO (mode, lv))
>> - lv = GET_MODE_PRECISION (mode);
>> + value.high = 0;
>> + if (first.low != 0)
>> + value.low = ctz_hwi (first.low);
>> + else if (first.high != 0)
>> + value.low = HOST_BITS_PER_WIDE_INT + ctz_hwi (first.high);
>> + else if (! CTZ_DEFINED_VALUE_AT_ZERO (mode, value.low))
>> + value.low = GET_MODE_PRECISION (mode);
>> break;
>>
>> case POPCOUNT:
>> - hv = 0;
>> - lv = 0;
>> - while (l1)
>> - lv++, l1 &= l1 - 1;
>> - while (h1)
>> - lv++, h1 &= h1 - 1;
>> + value = double_int_zero;
>> + while (first.low)
>> + {
>> + value.low++;
>> + first.low &= first.low - 1;
>> + }
>> + while (first.high)
>> + {
>> + value.low++;
>> + first.high &= first.high - 1;
>> + }
>> break;
>>
>> case PARITY:
>> - hv = 0;
>> - lv = 0;
>> - while (l1)
>> - lv++, l1 &= l1 - 1;
>> - while (h1)
>> - lv++, h1 &= h1 - 1;
>> - lv &= 1;
>> + value = double_int_zero;
>> + while (first.low)
>> + {
>> + value.low++;
>> + first.low &= first.low - 1;
>> + }
>> + while (first.high)
>> + {
>> + value.low++;
>> + first.high &= first.high - 1;
>> + }
>> + value.low &= 1;
>> break;
>>
>> case BSWAP:
>> {
>> unsigned int s;
>>
>> - hv = 0;
>> - lv = 0;
>> + value = double_int_zero;
>> for (s = 0; s < width; s += 8)
>> {
>> unsigned int d = width - s - 8;
>> unsigned HOST_WIDE_INT byte;
>>
>> if (s < HOST_BITS_PER_WIDE_INT)
>> - byte = (l1 >> s) & 0xff;
>> + byte = (first.low >> s) & 0xff;
>> else
>> - byte = (h1 >> (s - HOST_BITS_PER_WIDE_INT)) & 0xff;
>> + byte = (first.high >> (s - HOST_BITS_PER_WIDE_INT)) & 0xff;
>>
>> if (d < HOST_BITS_PER_WIDE_INT)
>> - lv |= byte << d;
>> + value.low |= byte << d;
>> else
>> - hv |= byte << (d - HOST_BITS_PER_WIDE_INT);
>> + value.high |= byte << (d - HOST_BITS_PER_WIDE_INT);
>> }
>> }
>> break;
>>
>> case TRUNCATE:
>> /* This is just a change-of-mode, so do nothing. */
>> - lv = l1, hv = h1;
>> + value = first;
>> break;
>>
>> case ZERO_EXTEND:
>> @@ -1636,8 +1644,7 @@ simplify_const_unary_operation (enum rtx
>> if (op_width > HOST_BITS_PER_WIDE_INT)
>> return 0;
>>
>> - hv = 0;
>> - lv = l1 & GET_MODE_MASK (op_mode);
>> + value = double_int::from_uhwi (first.low & GET_MODE_MASK (op_mode));
>> break;
>>
>> case SIGN_EXTEND:
>> @@ -1646,11 +1653,11 @@ simplify_const_unary_operation (enum rtx
>> return 0;
>> else
>> {
>> - lv = l1 & GET_MODE_MASK (op_mode);
>> - if (val_signbit_known_set_p (op_mode, lv))
>> - lv |= ~GET_MODE_MASK (op_mode);
>> + value.low = first.low & GET_MODE_MASK (op_mode);
>> + if (val_signbit_known_set_p (op_mode, value.low))
>> + value.low |= ~GET_MODE_MASK (op_mode);
>>
>> - hv = HWI_SIGN_EXTEND (lv);
>> + value.high = HWI_SIGN_EXTEND (value.low);
>> }
>> break;
>>
>> @@ -1661,7 +1668,7 @@ simplify_const_unary_operation (enum rtx
>> return 0;
>> }
>>
>> - return immed_double_const (lv, hv, mode);
>> + return immed_double_int_const (value, mode);
>> }
>>
>> else if (CONST_DOUBLE_AS_FLOAT_P (op)
>> @@ -3578,6 +3585,7 @@ simplify_const_binary_operation (enum rt
>> && (CONST_DOUBLE_AS_INT_P (op1) || CONST_INT_P (op1)))
>> {
>> double_int o0, o1, res, tmp;
>> + bool overflow;
>>
>> o0 = rtx_to_double_int (op0);
>> o1 = rtx_to_double_int (op1);
>> @@ -3599,34 +3607,30 @@ simplify_const_binary_operation (enum rt
>> break;
>>
>> case DIV:
>> - if (div_and_round_double (TRUNC_DIV_EXPR, 0,
>> - o0.low, o0.high, o1.low, o1.high,
>> - &res.low, &res.high,
>> - &tmp.low, &tmp.high))
>> + res = o0.divmod_with_overflow (o1, false, TRUNC_DIV_EXPR,
>> + &tmp, &overflow);
>> + if (overflow)
>> return 0;
>> break;
>>
>> case MOD:
>> - if (div_and_round_double (TRUNC_DIV_EXPR, 0,
>> - o0.low, o0.high, o1.low, o1.high,
>> - &tmp.low, &tmp.high,
>> - &res.low, &res.high))
>> + tmp = o0.divmod_with_overflow (o1, false, TRUNC_DIV_EXPR,
>> + &res, &overflow);
>> + if (overflow)
>> return 0;
>> break;
>>
>> case UDIV:
>> - if (div_and_round_double (TRUNC_DIV_EXPR, 1,
>> - o0.low, o0.high, o1.low, o1.high,
>> - &res.low, &res.high,
>> - &tmp.low, &tmp.high))
>> + res = o0.divmod_with_overflow (o1, true, TRUNC_DIV_EXPR,
>> + &tmp, &overflow);
>> + if (overflow)
>> return 0;
>> break;
>>
>> case UMOD:
>> - if (div_and_round_double (TRUNC_DIV_EXPR, 1,
>> - o0.low, o0.high, o1.low, o1.high,
>> - &tmp.low, &tmp.high,
>> - &res.low, &res.high))
>> + tmp = o0.divmod_with_overflow (o1, true, TRUNC_DIV_EXPR,
>> + &res, &overflow);
>> + if (overflow)
>> return 0;
>> break;
>>
>> Index: gcc/explow.c
>> ===================================================================
>> --- gcc/explow.c (revision 191083)
>> +++ gcc/explow.c (working copy)
>> @@ -100,36 +100,33 @@ plus_constant (enum machine_mode mode, r
>> case CONST_INT:
>> if (GET_MODE_BITSIZE (mode) > HOST_BITS_PER_WIDE_INT)
>> {
>> - unsigned HOST_WIDE_INT l1 = INTVAL (x);
>> - HOST_WIDE_INT h1 = (l1 >> (HOST_BITS_PER_WIDE_INT - 1)) ? -1 : 0;
>> - unsigned HOST_WIDE_INT l2 = c;
>> - HOST_WIDE_INT h2 = c < 0 ? -1 : 0;
>> - unsigned HOST_WIDE_INT lv;
>> - HOST_WIDE_INT hv;
>> + double_int di_x = double_int::from_shwi (INTVAL (x));
>> + double_int di_c = double_int::from_shwi (c);
>>
>> - if (add_double_with_sign (l1, h1, l2, h2, &lv, &hv, false))
>> + bool overflow;
>> + double_int v = di_x.add_with_sign (di_c, false, &overflow);
>> + if (overflow)
>> gcc_unreachable ();
>>
>> - return immed_double_const (lv, hv, VOIDmode);
>> + return immed_double_int_const (v, VOIDmode);
>> }
>>
>> return GEN_INT (INTVAL (x) + c);
>>
>> case CONST_DOUBLE:
>> {
>> - unsigned HOST_WIDE_INT l1 = CONST_DOUBLE_LOW (x);
>> - HOST_WIDE_INT h1 = CONST_DOUBLE_HIGH (x);
>> - unsigned HOST_WIDE_INT l2 = c;
>> - HOST_WIDE_INT h2 = c < 0 ? -1 : 0;
>> - unsigned HOST_WIDE_INT lv;
>> - HOST_WIDE_INT hv;
>> + double_int di_x = double_int::from_pair (CONST_DOUBLE_HIGH (x),
>> + CONST_DOUBLE_LOW (x));
>> + double_int di_c = double_int::from_shwi (c);
>>
>> - if (add_double_with_sign (l1, h1, l2, h2, &lv, &hv, false))
>> + bool overflow;
>> + double_int v = di_x.add_with_sign (di_c, false, &overflow);
>> + if (overflow)
>> /* Sorry, we have no way to represent overflows this wide.
>> To fix, add constant support wider than CONST_DOUBLE. */
>> gcc_assert (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_DOUBLE_INT);
>>
>> - return immed_double_const (lv, hv, VOIDmode);
>> + return immed_double_int_const (v, VOIDmode);
>> }
>>
>> case MEM:
>> Index: gcc/config/sparc/sparc.c
>> ===================================================================
>> --- gcc/config/sparc/sparc.c (revision 191083)
>> +++ gcc/config/sparc/sparc.c (working copy)
>> @@ -10113,33 +10113,27 @@ sparc_fold_builtin (tree fndecl, int n_a
>> && TREE_CODE (arg1) == VECTOR_CST
>> && TREE_CODE (arg2) == INTEGER_CST)
>> {
>> - int overflow = 0;
>> - unsigned HOST_WIDE_INT low = TREE_INT_CST_LOW (arg2);
>> - HOST_WIDE_INT high = TREE_INT_CST_HIGH (arg2);
>> + bool overflow = false;
>> + double_int di_arg2 = TREE_INT_CST (arg2);
>> unsigned i;
>>
>> for (i = 0; i < VECTOR_CST_NELTS (arg0); ++i)
>> {
>> - unsigned HOST_WIDE_INT
>> - low0 = TREE_INT_CST_LOW (VECTOR_CST_ELT (arg0, i)),
>> - low1 = TREE_INT_CST_LOW (VECTOR_CST_ELT (arg1, i));
>> - HOST_WIDE_INT
>> - high0 = TREE_INT_CST_HIGH (VECTOR_CST_ELT (arg0, i));
>> - HOST_WIDE_INT
>> - high1 = TREE_INT_CST_HIGH (VECTOR_CST_ELT (arg1, i));
>> + double_int e0 = TREE_INT_CST (VECTOR_CST_ELT (arg0, i));
>> + double_int e1 = TREE_INT_CST (VECTOR_CST_ELT (arg1, i));
>>
>> - unsigned HOST_WIDE_INT l;
>> - HOST_WIDE_INT h;
>> + bool neg1_ovf, neg2_ovf, add1_ovf, add2_ovf;
>>
>> - overflow |= neg_double (low1, high1, &l, &h);
>> - overflow |= add_double (low0, high0, l, h, &l, &h);
>> - if (h < 0)
>> - overflow |= neg_double (l, h, &l, &h);
>> + double_int tmp = e1.neg_with_overflow (&neg1_ovf);
>> + tmp = e0.add_with_sign (tmp, false, &add1_ovf);
>> + if (tmp.is_negative ())
>> + tmp = tmp.neg_with_overflow (&neg2_ovf);
>>
>> - overflow |= add_double (low, high, l, h, &low, &high);
>> + tmp = di_arg2.add_with_sign (tmp, false, &add2_ovf);
>> + overflow |= neg1_ovf | neg2_ovf | add1_ovf | add2_ovf;
>> }
>>
>> - gcc_assert (overflow == 0);
>> + gcc_assert (!overflow);
>>
>> return build_int_cst_wide (rtype, low, high);
>> }
>> Index: gcc/config/avr/avr.c
>> ===================================================================
>> --- gcc/config/avr/avr.c (revision 191083)
>> +++ gcc/config/avr/avr.c (working copy)
>> @@ -10518,10 +10518,10 @@ avr_double_int_push_digit (double_int va
>> unsigned HOST_WIDE_INT digit)
>> {
>> val = 0 == base
>> - ? double_int_lshift (val, 32, 64, false)
>> - : double_int_mul (val, uhwi_to_double_int (base));
>> + ? val.llshift (32, 64)
>> + : val * double_int::from_uhwi (base);
>>
>> - return double_int_add (val, uhwi_to_double_int (digit));
>> + return val + double_int::from_uhwi (digit);
>> }
>>
>>
>> @@ -10530,7 +10530,7 @@ avr_double_int_push_digit (double_int va
>> static int
>> avr_map (double_int f, int x)
>> {
>> - return 0xf & double_int_to_uhwi (double_int_rshift (f, 4*x, 64, false));
>> + return 0xf & f.lrshift (4*x, 64).to_uhwi ();
>> }
>>
>>
>> @@ -10703,7 +10703,7 @@ avr_map_decompose (double_int f, const a
>> are mapped to 0 and used operands are reloaded to xop[0]. */
>>
>> xop[0] = all_regs_rtx[24];
>> - xop[1] = gen_int_mode (double_int_to_uhwi (f_ginv.map), SImode);
>> + xop[1] = gen_int_mode (f_ginv.map.to_uhwi (), SImode);
>> xop[2] = all_regs_rtx[25];
>> xop[3] = val_used_p ? xop[0] : const0_rtx;
>>
>> @@ -10799,7 +10799,7 @@ avr_out_insert_bits (rtx *op, int *plen)
>> else if (flag_print_asm_name)
>> fprintf (asm_out_file,
>> ASM_COMMENT_START "map = 0x%08" HOST_LONG_FORMAT "x\n",
>> - double_int_to_uhwi (map) & GET_MODE_MASK (SImode));
>> + map.to_uhwi () & GET_MODE_MASK (SImode));
>>
>> /* If MAP has fixed points it might be better to initialize the result
>> with the bits to be inserted instead of moving all bits by hand. */