On Sun, Apr 28, 2024 at 7:53 AM liuhongt <hongtao....@intel.com> wrote: > > The Intel Decimal Floating-Point Math Library is available as open-source on > Netlib[1]. > > [1] https://www.netlib.org/misc/intel/. > > Bootstrapped and regtested on x86_64-pc-linux-gnu{-m32,}. > Ok for trunk?
OK for trunk. Thanks, Richard. > libgcc/config/libbid/ChangeLog: > > * bid128_fma.c (add_and_round): Fix bug: the result > of (+5E+368)*(+10E-34)+(-10E+369) was returning > -9999999999999999999999999999999999E+336 instead of expected > result -1000000000000000000000000000000000E+337. > (bid128_ext_fma): Ditto. > (bid64qqq_fma): Ditto. > * bid128_noncomp.c: Change return type of bid128_class from > int to class_t. > * bid128_round_integral.c: Add default case to avoid compiler > warning. > * bid128_string.c (bid128_to_string): Replace 0x30 with '0' > for zero digit. > (bid128_from_string): Ditto. > * bid32_to_bid128.c (bid128_to_bid32): Fix Bug. In addition > to the INEXACT flag, the UNDERFLOW flag needs to be set (and > was not) when converting an input such as > +6931674235302037148946035460357709E+1857 to +1000000E-101 > * bid32_to_bid64.c (bid64_to_bid32): fix Bug, In addition to > the INEXACT flag, the UNDERFLOW flag needs to be set (and was > not) when converting an input such as +9999999000000001E-111 > to +1000000E-101. Furthermore, significant bits of NaNs are > set correctly now. For example, 0x7c00003b9aca0000 was > returning 0x7c000002 instead of 0x 7c000100. > * bid64_noncomp.c: Change return type of bid64_class from int > to class_t. > * bid64_round_integral.c (bid64_round_integral_exact): Add > default case to avoid compiler warning. > * bid64_string.c (bid64_from_string): Fix bug for rounding > up. The input string "10000000000000000" was returning > +1000000000000001E+1 instead of +1000000000000000E+1. > * bid64_to_bid128.c (bid128_to_bid64): Fix bug, in addition to > the INEXACT flag, the UNDERFLOW flag needs to be set (and was > not) when converting an input such as > +9999999999999999999999999999999999E-417 to > +1000000000000000E-398. > * bid_binarydecimal.c (bid32_to_binary64): Fix bug for > conversion between binary and bid types. For example, > 0x7c0F4240 was returning 0x7FFFA12000000000 instead of > expected double precision 0x7FF8000000000000. > (binary64_to_bid32): Ditto. > (binary80_to_bid32): Ditto. > (binary128_to_bid32): Ditto. > (binary80_to_bid64): Ditto. > (binary128_to_bid64): Ditto. > * bid_conf.h (BID_HIGH_128W): New macro. > (BID_LOW_128W): Ditto. > * bid_functions.h (__ENABLE_BINARY80__): Ditto. > (ALIGN): Ditto. > * bid_inline_add.h (get_add128): Add default case to avoid compiler > warning. > * bid_internal.h (get_BID64): Ditto. > (fast_get_BID64_check_OF): Ditto. > (ALIGN): New macro. > > Co-authored-by: Anderson, Cristina S <cristina.s.ander...@intel.com> > Co-authored-by: Akkas, Ahmet <ahmet.ak...@intel.com> > Co-authored-by: Cornea, Marius <marius.cor...@intel.com> > --- > libgcc/config/libbid/bid128_fma.c | 188 ++++++++++--------- > libgcc/config/libbid/bid128_noncomp.c | 2 +- > libgcc/config/libbid/bid128_round_integral.c | 2 + > libgcc/config/libbid/bid128_string.c | 7 +- > libgcc/config/libbid/bid32_to_bid128.c | 3 - > libgcc/config/libbid/bid32_to_bid64.c | 11 +- > libgcc/config/libbid/bid64_noncomp.c | 2 +- > libgcc/config/libbid/bid64_round_integral.c | 2 + > libgcc/config/libbid/bid64_string.c | 21 ++- > libgcc/config/libbid/bid64_to_bid128.c | 3 - > libgcc/config/libbid/bid_binarydecimal.c | 167 ++++++---------- > libgcc/config/libbid/bid_conf.h | 8 + > libgcc/config/libbid/bid_functions.h | 23 ++- > libgcc/config/libbid/bid_inline_add.h | 2 + > libgcc/config/libbid/bid_internal.h | 17 +- > 15 files changed, 220 insertions(+), 238 deletions(-) > > diff --git a/libgcc/config/libbid/bid128_fma.c > b/libgcc/config/libbid/bid128_fma.c > index 67233193a42..cbcf225546f 100644 > --- a/libgcc/config/libbid/bid128_fma.c > +++ b/libgcc/config/libbid/bid128_fma.c > @@ -417,13 +417,12 @@ add_and_round (int q3, > R128.w[1] = R256.w[1]; > R128.w[0] = R256.w[0]; > } > + if (e4 + x0 < expmin) { // for all rounding modes > + is_tiny = 1; > + } > // the rounded result has p34 = 34 digits > e4 = e4 + x0 + incr_exp; > - if (rnd_mode == ROUNDING_TO_NEAREST) { > - if (e4 < expmin) { > - is_tiny = 1; // for other rounding modes apply correction > - } > - } else { > + if (rnd_mode != ROUNDING_TO_NEAREST) { > // for RM, RP, RZ, RA apply correction in order to determine tininess > // but do not save the result; apply the correction to > // (-1)^p_sign * significand * 10^0 > @@ -434,10 +433,6 @@ add_and_round (int q3, > is_inexact_gt_midpoint, is_midpoint_lt_even, > is_midpoint_gt_even, 0, &P128, ptrfpsf); > scale = ((P128.w[1] & MASK_EXP) >> 49) - 6176; // -1, 0, or +1 > - // the number of digits in the significand is p34 = 34 > - if (e4 + scale < expmin) { > - is_tiny = 1; > - } > } > ind = p34; // the number of decimal digits in the signifcand of res > res.w[1] = p_sign | ((UINT64) (e4 + 6176) << 49) | R128.w[1]; // RN > @@ -851,7 +846,6 @@ bid128_ext_fma (int *ptr_is_midpoint_lt_even, > } > } > } > - > p_sign = x_sign ^ y_sign; // sign of the product > > // identify cases where at least one operand is infinity > @@ -988,15 +982,10 @@ bid128_ext_fma (int *ptr_is_midpoint_lt_even, > if (C1.w[1] == 0) { > if (C1.w[0] >= 0x0020000000000000ull) { // x >= 2^53 > // split the 64-bit value in two 32-bit halves to avoid rounding > errors > - if (C1.w[0] >= 0x0000000100000000ull) { // x >= 2^32 > + > tmp.d = (double) (C1.w[0] >> 32); // exact conversion > x_nr_bits = > 33 + ((((unsigned int) (tmp.ui64 >> 52)) & 0x7ff) - 0x3ff); > - } else { // x < 2^32 > - tmp.d = (double) (C1.w[0]); // exact conversion > - x_nr_bits = > - 1 + ((((unsigned int) (tmp.ui64 >> 52)) & 0x7ff) - 0x3ff); > - } > } else { // if x < 2^53 > tmp.d = (double) C1.w[0]; // exact conversion > x_nr_bits = > @@ -1011,42 +1000,36 @@ bid128_ext_fma (int *ptr_is_midpoint_lt_even, > if (q1 == 0) { > q1 = nr_digits[x_nr_bits - 1].digits1; > if (C1.w[1] > nr_digits[x_nr_bits - 1].threshold_hi || > - (C1.w[1] == nr_digits[x_nr_bits - 1].threshold_hi && > - C1.w[0] >= nr_digits[x_nr_bits - 1].threshold_lo)) > + (C1.w[1] == nr_digits[x_nr_bits - 1].threshold_hi && > + C1.w[0] >= nr_digits[x_nr_bits - 1].threshold_lo)) > q1++; > } > } > - > + // q2 = nr. of decimal digits in y > + // determine first the nr. of bits in y > if (C2.w[1] != 0 || C2.w[0] != 0) { // y = f (non-zero finite) > if (C2.w[1] == 0) { > if (C2.w[0] >= 0x0020000000000000ull) { // y >= 2^53 > // split the 64-bit value in two 32-bit halves to avoid rounding > errors > - if (C2.w[0] >= 0x0000000100000000ull) { // y >= 2^32 > tmp.d = (double) (C2.w[0] >> 32); // exact conversion > y_nr_bits = > - 32 + ((((unsigned int) (tmp.ui64 >> 52)) & 0x7ff) - 0x3ff); > - } else { // y < 2^32 > - tmp.d = (double) C2.w[0]; // exact conversion > - y_nr_bits = > - ((((unsigned int) (tmp.ui64 >> 52)) & 0x7ff) - 0x3ff); > - } > + 33 + ((((unsigned int) (tmp.ui64 >> 52)) & 0x7ff) - 0x3ff); > } else { // if y < 2^53 > tmp.d = (double) C2.w[0]; // exact conversion > y_nr_bits = > - ((((unsigned int) (tmp.ui64 >> 52)) & 0x7ff) - 0x3ff); > + 1 + ((((unsigned int) (tmp.ui64 >> 52)) & 0x7ff) - 0x3ff); > } > } else { // C2.w[1] != 0 => nr. bits = 64 + nr_bits (C2.w[1]) > tmp.d = (double) C2.w[1]; // exact conversion > y_nr_bits = > - 64 + ((((unsigned int) (tmp.ui64 >> 52)) & 0x7ff) - 0x3ff); > + 65 + ((((unsigned int) (tmp.ui64 >> 52)) & 0x7ff) - 0x3ff); > } > - > - q2 = nr_digits[y_nr_bits].digits; > + q2 = nr_digits[y_nr_bits - 1].digits; > if (q2 == 0) { > - q2 = nr_digits[y_nr_bits].digits1; > - if (C2.w[1] > nr_digits[y_nr_bits].threshold_hi || > - (C2.w[1] == nr_digits[y_nr_bits].threshold_hi && > - C2.w[0] >= nr_digits[y_nr_bits].threshold_lo)) > + q2 = nr_digits[y_nr_bits - 1].digits1; > + if (C2.w[1] > nr_digits[y_nr_bits - 1].threshold_hi || > + (C2.w[1] == nr_digits[y_nr_bits - 1].threshold_hi && > + C2.w[0] >= nr_digits[y_nr_bits - 1].threshold_lo)) > q2++; > } > } > @@ -1055,32 +1038,25 @@ bid128_ext_fma (int *ptr_is_midpoint_lt_even, > if (C3.w[1] == 0) { > if (C3.w[0] >= 0x0020000000000000ull) { // z >= 2^53 > // split the 64-bit value in two 32-bit halves to avoid rounding > errors > - if (C3.w[0] >= 0x0000000100000000ull) { // z >= 2^32 > tmp.d = (double) (C3.w[0] >> 32); // exact conversion > z_nr_bits = > - 32 + ((((unsigned int) (tmp.ui64 >> 52)) & 0x7ff) - 0x3ff); > - } else { // z < 2^32 > - tmp.d = (double) C3.w[0]; // exact conversion > - z_nr_bits = > - ((((unsigned int) (tmp.ui64 >> 52)) & 0x7ff) - 0x3ff); > - } > + 33 + ((((unsigned int) (tmp.ui64 >> 52)) & 0x7ff) - 0x3ff); > } else { // if z < 2^53 > tmp.d = (double) C3.w[0]; // exact conversion > z_nr_bits = > - ((((unsigned int) (tmp.ui64 >> 52)) & 0x7ff) - 0x3ff); > + 1 + ((((unsigned int) (tmp.ui64 >> 52)) & 0x7ff) - 0x3ff); > } > } else { // C3.w[1] != 0 => nr. bits = 64 + nr_bits (C3.w[1]) > tmp.d = (double) C3.w[1]; // exact conversion > z_nr_bits = > - 64 + ((((unsigned int) (tmp.ui64 >> 52)) & 0x7ff) - 0x3ff); > + 65 + ((((unsigned int) (tmp.ui64 >> 52)) & 0x7ff) - 0x3ff); > } > - > - q3 = nr_digits[z_nr_bits].digits; > + q3 = nr_digits[z_nr_bits - 1].digits; > if (q3 == 0) { > - q3 = nr_digits[z_nr_bits].digits1; > - if (C3.w[1] > nr_digits[z_nr_bits].threshold_hi || > - (C3.w[1] == nr_digits[z_nr_bits].threshold_hi && > - C3.w[0] >= nr_digits[z_nr_bits].threshold_lo)) > + q3 = nr_digits[z_nr_bits - 1].digits1; > + if (C3.w[1] > nr_digits[z_nr_bits - 1].threshold_hi || > + (C3.w[1] == nr_digits[z_nr_bits - 1].threshold_hi && > + C3.w[0] >= nr_digits[z_nr_bits - 1].threshold_lo)) > q3++; > } > } > @@ -1128,7 +1104,6 @@ bid128_ext_fma (int *ptr_is_midpoint_lt_even, > } else { > ; // continue with x = f, y = f, z = 0 or x = f, y = f, z = f > } > - > e1 = (x_exp >> 49) - 6176; // unbiased exponent of x > e2 = (y_exp >> 49) - 6176; // unbiased exponent of y > e3 = (z_exp >> 49) - 6176; // unbiased exponent of z > @@ -1232,22 +1207,18 @@ bid128_ext_fma (int *ptr_is_midpoint_lt_even, > // length of C1 * C2 rounded up to a multiple of 64 bits is len = 192; > q4 = q1 + q2; // q4 in [40, 57] > } > - } else if (q1 + q2 == 58) { // C4 = C1 * C2 fits in 192 or 256 bits > - // both C1 and C2 fit in 128 bits (actually in 113 bits); at most one > - // may fit in 64 bits > - if (C1.w[1] == 0) { // C1 * C2 will fit in 192 bits > - __mul_64x128_full (C4.w[2], C4, C1.w[0], C2); // may use 64x128_to_192 > - } else if (C2.w[1] == 0) { // C1 * C2 will fit in 192 bits > - __mul_64x128_full (C4.w[2], C4, C2.w[0], C1); // may use 64x128_to_192 > - } else { // C1 * C2 will fit in 192 bits or in 256 bits > - __mul_128x128_to_256 (C4, C1, C2); > - } > + } else if (q1 + q2 == 58) { // C4 = C1 * C2 fits in 192 or 256 bits; > + // both C1 and C2 fit in 128 bits (actually in 113 bits); none can > + // fit in 64 bits, because each number must have at least 24 decimal > + // digits for the sum to have 58 (as the max. nr. of digits is 34) => > + // C1.w[1] != 0 and C2.w[1] != 0 > + __mul_128x128_to_256 (C4, C1, C2); > // if C4 < 10^(q1+q2-1) = 10^57 then q4 = q1+q2-1 = 57 else q4 = q1+q2 = > 58 > if (C4.w[3] == 0 && (C4.w[2] < ten2k256[18].w[2] || > - (C4.w[2] == ten2k256[18].w[2] > - && (C4.w[1] < ten2k256[18].w[1] > - || (C4.w[1] == ten2k256[18].w[1] > - && C4.w[0] < ten2k256[18].w[0]))))) { > + (C4.w[2] == ten2k256[18].w[2] > + && (C4.w[1] < ten2k256[18].w[1] > + || (C4.w[1] == ten2k256[18].w[1] > + && C4.w[0] < ten2k256[18].w[0]))))) { > // 18 = 57 - 39 = q1+q2-1 - 39 > // length of C1 * C2 rounded up to a multiple of 64 bits is len = 192; > q4 = 57; // 57 = q1 + q2 - 1 > @@ -1283,7 +1254,6 @@ bid128_ext_fma (int *ptr_is_midpoint_lt_even, > q4 = q1 + q2; // q4 in [59, 68] > } > } > - > if (C3.w[1] == 0x0 && C3.w[0] == 0x0) { // x = f, y = f, z = 0 > save_fpsf = *pfpsf; // sticky bits - caller value must be preserved > *pfpsf = 0; > @@ -1319,10 +1289,11 @@ bid128_ext_fma (int *ptr_is_midpoint_lt_even, > res.w[1] = R256.w[1]; > } > e4 = e4 + x0; > + q4 = p34; > if (incr_exp) { > e4 = e4 + 1; > + if (q4 + e4 == expmin + p34) *pfpsf |= (INEXACT_EXCEPTION | > UNDERFLOW_EXCEPTION); > } > - q4 = p34; > // res is now the coefficient of the result rounded to the destination > // precision, with unbounded exponent; the exponent is e4; > q4=digits(res) > } else { // if (q4 <= p34) > @@ -1648,7 +1619,6 @@ bid128_ext_fma (int *ptr_is_midpoint_lt_even, > delta = q3 + e3 - q4 - e4; > delta_ge_zero: > if (delta >= 0) { > - > if (p34 <= delta - 1 || // Case (1') > (p34 == delta && e3 + 6176 < p34 - q3)) { // Case (1''A) > // check for overflow, which can occur only in Case (1') > @@ -1736,7 +1706,7 @@ delta_ge_zero: > res.w[1] = z_sign | ((UINT64) (e3 + 6176) << 49) | C3.w[1]; > res.w[0] = C3.w[0]; > } > - > + > // use the following to avoid double rounding errors when operating on > // mixed formats in rounding to nearest, and for correcting the result > // if not rounding to nearest > @@ -1795,7 +1765,10 @@ delta_ge_zero: > R64 = 10; > } > } > - if (q4 == 1 && C4.w[0] == 5) { > + > + if (R64 == 5 && !is_inexact_lt_midpoint && !is_inexact_gt_midpoint > && > + !is_midpoint_lt_even && !is_midpoint_gt_even) { > + //if (q4 == 1 && C4.w[0] == 5) { > is_inexact_lt_midpoint = 0; > is_inexact_gt_midpoint = 0; > is_midpoint_lt_even = 1; > @@ -1826,11 +1799,7 @@ delta_ge_zero: > res.w[1] = z_sign | ((UINT64) (e3 + 6176) << 49) | res.w[1]; > } > if (e3 == expmin) { > - if (R64 < 5 || (R64 == 5 && !is_inexact_lt_midpoint)) { > - ; // result not tiny (in round-to-nearest mode) > - } else { > - *pfpsf |= UNDERFLOW_EXCEPTION; > - } > + *pfpsf |= UNDERFLOW_EXCEPTION; // tiny if detected before rounding > } > } // end 10^(q3+scale-1) > // set the inexact flag > @@ -1877,10 +1846,9 @@ delta_ge_zero: > // endif > if ((e3 == expmin && (q3 + scale) < p34) || > (e3 == expmin && (q3 + scale) == p34 && > - (res.w[1] & MASK_COEFF) == 0x0000314dc6448d93ull && // 10^33_high > - res.w[0] == 0x38c15b0a00000000ull && // 10^33_low > - z_sign != p_sign && ((!z_sign && rnd_mode != ROUNDING_UP) || > - (z_sign && rnd_mode != ROUNDING_DOWN)))) { > + (res.w[1] & MASK_COEFF) == 0x0000314dc6448d93ull && // 10^33_high > + res.w[0] == 0x38c15b0a00000000ull && // 10^33_low > + z_sign != p_sign)) { > *pfpsf |= UNDERFLOW_EXCEPTION; > } > if (rnd_mode != ROUNDING_TO_NEAREST) { > @@ -2594,7 +2562,7 @@ delta_ge_zero: > if (e3 > expmin && ((res.w[1] < 0x0000314dc6448d93ull || > (res.w[1] == 0x0000314dc6448d93ull && > res.w[0] < 0x38c15b0a00000000ull)) || > - (is_inexact_lt_midpoint > + ((is_inexact_lt_midpoint | is_midpoint_gt_even) > && res.w[1] == 0x0000314dc6448d93ull > && res.w[0] == 0x38c15b0a00000000ull)) > && x0 >= 1) { > @@ -2678,6 +2646,9 @@ delta_ge_zero: > res.w[0] < 0x38c15b0a00000000ull)) { > is_tiny = 1; > } > + if (((res.w[1] & 0x7fffffffffffffffull) == 0x0000314dc6448d93ull) && > + (res.w[0] == 0x38c15b0a00000000ull) && // 10^33*10^-6176 > + (z_sign != p_sign)) is_tiny = 1; > } else if (e3 < expmin) { > // the result is tiny, so we must truncate more of res > is_tiny = 1; > @@ -3328,9 +3299,6 @@ delta_ge_zero: > 0, &P128, pfpsf); > scale = ((P128.w[1] & MASK_EXP) >> 49) - 6176; // -1, 0, or +1 > // the number of digits in the significand is p34 = 34 > - if (e4 + scale < expmin) { > - is_tiny = 1; > - } > } > > // the result rounded to the destination precision with unbounded > exponent > @@ -3521,6 +3489,19 @@ delta_ge_zero: > is_midpoint_lt_even, is_midpoint_gt_even, > e4, &res, pfpsf); > } > + // correction needed for tininess detection before rounding > + if ((((res.w[1] & 0x7fffffffffffffffull) == 0x0000314dc6448d93ull) && > + // 10^33*10^-6176_high > + (res.w[0] == 0x38c15b0a00000000ull)) && // 10^33*10^-6176_low > + (((rnd_mode == ROUNDING_TO_NEAREST || > + rnd_mode == ROUNDING_TIES_AWAY) && > + (is_midpoint_lt_even || is_inexact_gt_midpoint)) || > + ((((rnd_mode == ROUNDING_UP) && !(res.w[1] & MASK_SIGN)) || > + ((rnd_mode == ROUNDING_DOWN) && (res.w[1] & MASK_SIGN))) > + && (is_midpoint_lt_even || is_midpoint_gt_even || > + is_inexact_lt_midpoint || is_inexact_gt_midpoint)))) { > + is_tiny = 1; > + } > if (is_midpoint_lt_even || is_midpoint_gt_even || > is_inexact_lt_midpoint || is_inexact_gt_midpoint) { > // set the inexact flag > @@ -4162,21 +4143,34 @@ bid64qqq_fma (UINT128 x, UINT128 y, UINT128 z > // determine the unbiased exponent of the result > unbexp = ((res1 >> 53) & 0x3ff) - 398; > > + if (!((res1 & MASK_NAN) == MASK_NAN)) { // res1 not NaN > // if subnormal, res1 must have exp = -398 > // if tiny and inexact set underflow and inexact status flags > - if (!((res1 & MASK_NAN) == MASK_NAN) && // res1 not NaN > - (unbexp == -398) > - && ((res1 & MASK_BINARY_SIG1) < 1000000000000000ull) > - && (is_inexact_lt_midpoint0 || is_inexact_gt_midpoint0 > - || is_midpoint_lt_even0 || is_midpoint_gt_even0)) { > - // set the inexact flag and the underflow flag > - *pfpsf |= (INEXACT_EXCEPTION | UNDERFLOW_EXCEPTION); > + if ((unbexp == -398) > + && ((res1 & MASK_BINARY_SIG1) < 1000000000000000ull) > + && (is_inexact_lt_midpoint0 || is_inexact_gt_midpoint0 > + || is_midpoint_lt_even0 || is_midpoint_gt_even0)) { > + // set the inexact flag and the underflow flag > + *pfpsf |= (INEXACT_EXCEPTION | UNDERFLOW_EXCEPTION); > } else if (is_inexact_lt_midpoint0 || is_inexact_gt_midpoint0 || > is_midpoint_lt_even0 || is_midpoint_gt_even0) { > // set the inexact flag and the underflow flag > *pfpsf |= INEXACT_EXCEPTION; > - } > + } > > + // correction needed for tininess detection before rounding > + if (((res1 & 0x7fffffffffffffffull) == 1000000000000000ull) && > + // 10^15*10^-398 > + (((rnd_mode == ROUNDING_TO_NEAREST || > + rnd_mode == ROUNDING_TIES_AWAY) && > + (is_midpoint_lt_even || is_inexact_gt_midpoint)) || > + ((((rnd_mode == ROUNDING_UP) && !(res1 & MASK_SIGN)) || > + ((rnd_mode == ROUNDING_DOWN) && (res1 & MASK_SIGN))) > + && (is_midpoint_lt_even || is_midpoint_gt_even || > + is_inexact_lt_midpoint || is_inexact_gt_midpoint)))) { > + *pfpsf |= UNDERFLOW_EXCEPTION; > + } > + } > *pfpsf |= save_fpsf; > BID_RETURN (res1); > } // else continue, and use rounding to nearest to round to 16 digits > @@ -4453,6 +4447,20 @@ bid64qqq_fma (UINT128 x, UINT128 y, UINT128 z > res1 = sign | MASK_STEERING_BITS | > ((UINT64) (unbexp + 398) << 51) | (res1 & MASK_BINARY_SIG2); > } > + > + // correction needed for tininess detection before rounding > + if (((res1 & 0x7fffffffffffffffull) == 1000000000000000ull) && > + // 10^15*10^-398 > + (((rnd_mode == ROUNDING_TO_NEAREST || > + rnd_mode == ROUNDING_TIES_AWAY) && > + (is_midpoint_lt_even || is_inexact_gt_midpoint)) || > + ((((rnd_mode == ROUNDING_UP) && !(res1 & MASK_SIGN)) || > + ((rnd_mode == ROUNDING_DOWN) && (res1 & MASK_SIGN))) > + && (is_midpoint_lt_even || is_midpoint_gt_even || > + is_inexact_lt_midpoint || is_inexact_gt_midpoint)))) { > + *pfpsf |= UNDERFLOW_EXCEPTION; > + } > + > *pfpsf |= save_fpsf; > BID_RETURN (res1); > } > diff --git a/libgcc/config/libbid/bid128_noncomp.c > b/libgcc/config/libbid/bid128_noncomp.c > index a79ac859ce1..4ef166c81dc 100644 > --- a/libgcc/config/libbid/bid128_noncomp.c > +++ b/libgcc/config/libbid/bid128_noncomp.c > @@ -443,7 +443,7 @@ void > bid128_class (int *pres, UINT128 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) { > UINT128 x = *px; > #else > -int > +class_t > bid128_class (UINT128 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) { > #endif > int res; > diff --git a/libgcc/config/libbid/bid128_round_integral.c > b/libgcc/config/libbid/bid128_round_integral.c > index ddaa0b818f2..051f8268aa9 100644 > --- a/libgcc/config/libbid/bid128_round_integral.c > +++ b/libgcc/config/libbid/bid128_round_integral.c > @@ -177,6 +177,7 @@ case ROUNDING_TO_ZERO: > BID_RETURN (res); > } > break; > +default: break; // default added to avoid compiler warning > } > > // q = nr. of decimal digits in x > @@ -804,6 +805,7 @@ case ROUNDING_TO_ZERO: > BID_RETURN (res); > } > break; > +default: break; // default added to avoid compiler warning > } > > BID_RETURN (res); > diff --git a/libgcc/config/libbid/bid128_string.c > b/libgcc/config/libbid/bid128_string.c > index ecd295cfbdf..8fc12ee2d76 100644 > --- a/libgcc/config/libbid/bid128_string.c > +++ b/libgcc/config/libbid/bid128_string.c > @@ -56,6 +56,7 @@ bid128_to_string (char *str, UINT128 x > UINT128 C1; > unsigned int k = 0; // pointer in the string > unsigned int d0, d123; > + unsigned int zero_digit = (unsigned int) '0'; > UINT64 HI_18Dig, LO_18Dig, Tmp; > UINT32 MiDi[12], *ptr; > char *c_ptr_start, *c_ptr; > @@ -232,14 +233,14 @@ bid128_to_string (char *str, UINT128 x > d123 = exp - 1000 * d0; > > if (d0) { // 1000 <= exp <= 6144 => 4 digits to return > - str[k++] = d0 + 0x30;// ASCII for decimal digit d0 > + str[k++] = d0 + zero_digit; // ASCII for decimal digit d0 > ind = 3 * d123; > str[k++] = char_table3[ind]; > str[k++] = char_table3[ind + 1]; > str[k++] = char_table3[ind + 2]; > } else { // 0 <= exp <= 999 => d0 = 0 > if (d123 < 10) { // 0 <= exp <= 9 => 1 digit to return > - str[k++] = d123 + 0x30;// ASCII > + str[k++] = d123 + zero_digit; // ASCII > } else if (d123 < 100) { // 10 <= exp <= 99 => 2 digits to return > ind = 2 * (d123 - 10); > str[k++] = char_table2[ind]; > @@ -643,7 +644,7 @@ bid128_from_string (char *ps _RND_MODE_PARAM > _EXC_FLAGS_PARAM > } > break; > > - > + default: break; // default added to avoid compiler warning > } > // now form the coefficient as coeff_high*10^17+coeff_low+carry > scale_high = 100000000000000000ull; > diff --git a/libgcc/config/libbid/bid32_to_bid128.c > b/libgcc/config/libbid/bid32_to_bid128.c > index d1d1d3458fd..5b5ce9504e1 100644 > --- a/libgcc/config/libbid/bid32_to_bid128.c > +++ b/libgcc/config/libbid/bid32_to_bid128.c > @@ -155,9 +155,6 @@ bid128_to_bid32 (UINT128 x _RND_MODE_PARAM > _EXC_FLAGS_PARAM > T128 = round_const_table_128[rmode][extra_digits]; > __add_carry_out (CX1.w[0], carry, T128.w[0], CX.w[0]); > CX1.w[1] = CX.w[1] + T128.w[1] + carry; > - if (__unsigned_compare_ge_128 > - (CX1, power10_table_128[extra_digits + 7])) > - uf_check = 0; > } > extra_digits = > extra_digits + DECIMAL_EXPONENT_BIAS_128 - > diff --git a/libgcc/config/libbid/bid32_to_bid64.c > b/libgcc/config/libbid/bid32_to_bid64.c > index 7802346a3d1..61b24b29915 100644 > --- a/libgcc/config/libbid/bid32_to_bid64.c > +++ b/libgcc/config/libbid/bid32_to_bid64.c > @@ -79,6 +79,7 @@ bid64_to_bid32 (UINT64 x _RND_MODE_PARAM _EXC_FLAGS_PARAM > UINT128 Q; > UINT64 sign_x, coefficient_x, remainder_h, carry, Stemp; > UINT32 res; > + UINT64 t64; > int_float tempx; > int exponent_x, bin_expon_cx, extra_digits, rmode = 0, amount; > unsigned status = 0; > @@ -93,8 +94,10 @@ bid64_to_bid32 (UINT64 x _RND_MODE_PARAM _EXC_FLAGS_PARAM > // unpack arguments, check for NaN or Infinity, 0 > if (!unpack_BID64 (&sign_x, &exponent_x, &coefficient_x, x)) { > if (((x) & 0x7800000000000000ull) == 0x7800000000000000ull) { > - res = (coefficient_x & 0x0003ffffffffffffull); > - res /= 1000000000ull; > + t64 = (coefficient_x & 0x0003ffffffffffffull); > + res = t64/1000000000ull; > + //res = (coefficient_x & 0x0003ffffffffffffull); > + //res /= 1000000000ull; > res |= ((coefficient_x >> 32) & 0xfc000000); > #ifdef SET_STATUS_FLAGS > if ((x & SNAN_MASK64) == SNAN_MASK64) // sNaN > @@ -139,10 +142,6 @@ bid64_to_bid32 (UINT64 x _RND_MODE_PARAM _EXC_FLAGS_PARAM > exponent_x += extra_digits; > if ((exponent_x < 0) && (exponent_x + MAX_FORMAT_DIGITS_32 >= 0)) { > status = UNDERFLOW_EXCEPTION; > - if (exponent_x == -1) > - if (coefficient_x + round_const_table[rmode][extra_digits] >= > - power10_table_128[extra_digits + 7].w[0]) > - status = 0; > extra_digits -= exponent_x; > exponent_x = 0; > } > diff --git a/libgcc/config/libbid/bid64_noncomp.c > b/libgcc/config/libbid/bid64_noncomp.c > index ecc9dddfd8b..ec633693f62 100644 > --- a/libgcc/config/libbid/bid64_noncomp.c > +++ b/libgcc/config/libbid/bid64_noncomp.c > @@ -358,7 +358,7 @@ void > bid64_class (int *pres, UINT64 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) { > UINT64 x = *px; > #else > -int > +class_t > bid64_class (UINT64 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) { > #endif > int res; > diff --git a/libgcc/config/libbid/bid64_round_integral.c > b/libgcc/config/libbid/bid64_round_integral.c > index 99a3e6101ef..5a33c429116 100644 > --- a/libgcc/config/libbid/bid64_round_integral.c > +++ b/libgcc/config/libbid/bid64_round_integral.c > @@ -142,6 +142,7 @@ bid64_round_integral_exact (UINT64 x _RND_MODE_PARAM > _EXC_FLAGS_PARAM > BID_RETURN (res); > } > break; > + default: break; // default added to avoid compiler warning > } // end switch () > > // q = nr. of decimal digits in x (1 <= q <= 54) > @@ -483,6 +484,7 @@ bid64_round_integral_exact (UINT64 x _RND_MODE_PARAM > _EXC_FLAGS_PARAM > BID_RETURN (res); > } > break; > + default: break; // default added to avoid compiler warning > } // end switch () > BID_RETURN (res); > } > diff --git a/libgcc/config/libbid/bid64_string.c > b/libgcc/config/libbid/bid64_string.c > index 55fcd9e9208..81ac5e275a4 100644 > --- a/libgcc/config/libbid/bid64_string.c > +++ b/libgcc/config/libbid/bid64_string.c > @@ -251,7 +251,7 @@ bid64_from_string (char *ps > #endif > UINT64 sign_x, coefficient_x = 0, rounded = 0, res; > int expon_x = 0, sgn_expon, ndigits, add_expon = 0, midpoint = > - 0, rounded_up = 0; > + 0, rounded_up = 0, dround = 0; > int dec_expon_scale = 0, right_radix_leading_zeros = 0, rdx_pt_enc = > 0; > unsigned fpsc; > @@ -419,10 +419,10 @@ bid64_from_string (char *ps > break; > > case ROUNDING_DOWN: > - if(sign_x) { coefficient_x++; rounded_up=1; } > + if(sign_x) { if(c>'0') {coefficient_x++; rounded_up=1;} else > dround=1; } > break; > case ROUNDING_UP: > - if(!sign_x) { coefficient_x++; rounded_up=1; } > + if(!sign_x) { if(c>'0') {coefficient_x++; rounded_up=1;} > else dround=1; } > break; > case ROUNDING_TIES_AWAY: > if(c>='5') { coefficient_x++; rounded_up=1; } > @@ -443,8 +443,21 @@ bid64_from_string (char *ps > midpoint = 0; > rounded_up = 1; > } > - if (c > '0') > + if (c > '0') { > rounded = 1; > + > + if(dround) > + { > + dround = 0; > + coefficient_x ++; > + rounded_up = 1; > + > + if (coefficient_x == 10000000000000000ull) { > + coefficient_x = 1000000000000000ull; > + add_expon = 1; > + } > + } > + } > } > ps++; > c = *ps; > diff --git a/libgcc/config/libbid/bid64_to_bid128.c > b/libgcc/config/libbid/bid64_to_bid128.c > index 6e55ba24e02..a8daddce6bc 100644 > --- a/libgcc/config/libbid/bid64_to_bid128.c > +++ b/libgcc/config/libbid/bid64_to_bid128.c > @@ -153,9 +153,6 @@ bid128_to_bid64 (UINT128 x _RND_MODE_PARAM > _EXC_FLAGS_PARAM > T128 = round_const_table_128[rmode][extra_digits]; > __add_carry_out (CX1.w[0], carry, T128.w[0], CX.w[0]); > CX1.w[1] = CX.w[1] + T128.w[1] + carry; > - if (__unsigned_compare_ge_128 > - (CX1, power10_table_128[extra_digits + 16])) > - uf_check = 0; > } > extra_digits = > extra_digits + DECIMAL_EXPONENT_BIAS_128 - > diff --git a/libgcc/config/libbid/bid_binarydecimal.c > b/libgcc/config/libbid/bid_binarydecimal.c > index 5b5b721ffb3..6df39f69887 100644 > --- a/libgcc/config/libbid/bid_binarydecimal.c > +++ b/libgcc/config/libbid/bid_binarydecimal.c > @@ -566,19 +566,19 @@ BID_BINARY80LDOUBLE; > { if ((x & (0xFull<<27)) == (0xFull<<27)) \ > { if ((x & (0x1Full<<26)) != (0x1Full<<26)) inf; \ > if ((x & (1ul<<25))!=0) *pfpsf |= INVALID_EXCEPTION; \ > - nan(s,((((x) & 0xFFFFul) > 999999ul) ? 0 : \ > + nan(s,((((x) & 0xFFFFFul) > 999999ul) ? 0 : \ > (((unsigned long long) x) << 44)),0ull); \ > } \ > e = ((x >> 21) & ((1ull<<8)-1)) - 101; \ > c = (1ull<<23) + (x & ((1ull<<21)-1)); \ > - if ((unsigned long)(c) > 9999999ul) c = 0; \ > + if ((unsigned long)(c) > 9999999ul) zero; \ > k = 0; \ > } \ > else \ > { e = ((x >> 23) & ((1ull<<8)-1)) - 101; \ > c = x & ((1ull<<23)-1); \ > if (c == 0) zero; \ > - k = clz32(c) - 8; \ > + k = clz32_nz(c) - 8; \ > c = c << k; \ > } \ > } > @@ -594,14 +594,14 @@ BID_BINARY80LDOUBLE; > } \ > e = ((x >> 51) & ((1ull<<10)-1)) - 398; \ > c = (1ull<<53) + (x & ((1ull<<51)-1)); \ > - if ((unsigned long long)(c) > 9999999999999999ull) c = 0; \ > + if ((unsigned long long)(c) > 9999999999999999ull) zero; \ > k = 0; \ > } \ > else \ > { e = ((x >> 53) & ((1ull<<10)-1)) - 398; \ > c = x & ((1ull<<53)-1); \ > if (c == 0) zero; \ > - k = clz64(c) - 10; \ > + k = clz64_nz(c) - 10; \ > c = c << k; \ > } \ > } > @@ -144302,20 +144302,6 @@ bid32_to_binary64 (UINT32 x > // We actually check if e >= ceil((sci_emax + 1) * log_10(2)) > // which in this case is e >= ceil(1024 * log_10(2)) = ceil(308.25) = 309 > > - if (e >= 309) { > - *pfpsf |= (OVERFLOW_EXCEPTION | INEXACT_EXCEPTION); > - return_binary64_ovf (s); > - } > -// Also check for "trivial" underflow, when 10^e * 2^113 <= 2^emin * 1/4, > -// so test e <= floor((emin - 115) * log_10(2)) > -// In this case just fix ourselves at that value for uniformity. > -// > -// This is important not only to keep the tables small but to maintain the > -// testing of the round/sticky words as a correct rounding method > - > - if (e <= -358) > - e = -358; > - > // Look up the breakpoint and approximate exponent > > m_min = (breakpoints_binary64 + 358)[e]; > @@ -144323,7 +144309,7 @@ bid32_to_binary64 (UINT32 x > > // Choose provisional exponent and reciprocal multiplier based on breakpoint > > - if (le128 (c.w[1], c.w[0], m_min.w[1], m_min.w[0])) { > + if (c.w[1] < m_min.w[1]) { > r = (multipliers1_binary64 + 358)[e]; > } else { > r = (multipliers2_binary64 + 358)[e]; > @@ -144332,17 +144318,12 @@ bid32_to_binary64 (UINT32 x > > // Do the reciprocal multiplication > > - __mul_128x256_to_384 (z, c, r) > + __mul_64x256_to_320(z, c.w[1], r); > + z.w[5]=z.w[4]; z.w[4]=z.w[3]; z.w[3]=z.w[2]; z.w[2]=z.w[1]; z.w[1]=z.w[0]; > z.w[0]=0; > + > // Check for exponent underflow and compensate by shifting the product > // Cut off the process at precision+2, since we can't really shift further > - if (e_out < 1) { > - int d; > - d = 1 - e_out; > - if (d > 55) > - d = 55; > - e_out = 1; > - srl256 (z.w[5], z.w[4], z.w[3], z.w[2], d); > - } > + > c_prov = z.w[5]; > > // Round using round-sticky words > @@ -144353,31 +144334,14 @@ bid32_to_binary64 (UINT32 x > w[1], > roundbound_128[(rnd_mode << 2) + ((s & 1) << 1) + > (c_prov & 1)].w[0], z.w[4], z.w[3])) { > - c_prov = c_prov + 1; > - if (c_prov == (1ull << 53)) { > - c_prov = 1ull << 52; > - e_out = e_out + 1; > - } > - } > -// Check for overflow > - > - if (e_out >= 2047) { > - *pfpsf |= (OVERFLOW_EXCEPTION | INEXACT_EXCEPTION); > - return_binary64_ovf (s); > + c_prov = c_prov + 1; > } > -// Modify exponent for a tiny result, otherwise lop the implicit bit > - > - if (c_prov < (1ull << 52)) > - e_out = 0; > - else > - c_prov = c_prov & ((1ull << 52) - 1); > + c_prov = c_prov & ((1ull << 52) - 1); > > // Set the inexact and underflow flag as appropriate > > if ((z.w[4] != 0) || (z.w[3] != 0)) { > *pfpsf |= INEXACT_EXCEPTION; > - if (e_out == 0) > - *pfpsf |= UNDERFLOW_EXCEPTION; > } > // Package up the result as a binary floating-point number > > @@ -145756,6 +145720,14 @@ binary64_to_bid32 (double x > __mul_128x256_to_384 (z, c, r) > c_prov = z.w[5]; > > +// Test inexactness and underflow (when testing tininess before rounding) > + > + if ((z.w[4] != 0) || (z.w[3] != 0)) { > + *pfpsf |= INEXACT_EXCEPTION; > + if (c_prov < 1000000ull) > + *pfpsf |= UNDERFLOW_EXCEPTION; > + } > + > // Round using round-sticky words > // If we spill over into the next decade, correct > // Flag underflow where it may be needed even for |result| = SNN > @@ -145769,27 +145741,16 @@ binary64_to_bid32 (double x > if (c_prov == 10000000ull) { > c_prov = 1000000ull; > e_out = e_out + 1; > - } else if ((c_prov == 1000000ull) && (e_out == 0)) { > - if ((((rnd_mode & 3) == 0) && (z.w[4] <= 17524406870024074035ull)) > - || ((rnd_mode + (s & 1) == 2) > - && (z.w[4] <= 16602069666338596454ull))) > - *pfpsf |= UNDERFLOW_EXCEPTION; > } > } > + > // Check for overflow > > if (e_out > 90 + 101) { > *pfpsf |= (OVERFLOW_EXCEPTION | INEXACT_EXCEPTION); > return_bid32_ovf (s); > } > -// Set the inexact flag as appropriate and check underflow > -// It's no doubt superfluous to check inexactness, but anyway... > > - if ((z.w[4] != 0) || (z.w[3] != 0)) { > - *pfpsf |= INEXACT_EXCEPTION; > - if (c_prov < 1000000ull) > - *pfpsf |= UNDERFLOW_EXCEPTION; > - } > // Package up the result > > return_bid32 (s, e_out, c_prov); > @@ -145919,6 +145880,14 @@ binary80_to_bid32 (BINARY80 x > __mul_128x256_to_384 (z, c, r) > c_prov = z.w[5]; > > +// Test inexactness and underflow (when testing tininess before rounding) > + > + if ((z.w[4] != 0) || (z.w[3] != 0)) { > + *pfpsf |= INEXACT_EXCEPTION; > + if (c_prov < 1000000ull) > + *pfpsf |= UNDERFLOW_EXCEPTION; > + } > + > // Round using round-sticky words > // If we spill over into the next decade, correct > // Flag underflow where it may be needed even for |result| = SNN > @@ -145932,27 +145901,16 @@ binary80_to_bid32 (BINARY80 x > if (c_prov == 10000000ull) { > c_prov = 1000000ull; > e_out = e_out + 1; > - } else if ((c_prov == 1000000ull) && (e_out == 0)) { > - if ((((rnd_mode & 3) == 0) && (z.w[4] <= 17524406870024074035ull)) > - || ((rnd_mode + (s & 1) == 2) > - && (z.w[4] <= 16602069666338596454ull))) > - *pfpsf |= UNDERFLOW_EXCEPTION; > } > } > + > // Check for overflow > > if (e_out > 90 + 101) { > *pfpsf |= (OVERFLOW_EXCEPTION | INEXACT_EXCEPTION); > return_bid32_ovf (s); > } > -// Set the inexact flag as appropriate and check underflow > -// It's no doubt superfluous to check inexactness, but anyway... > > - if ((z.w[4] != 0) || (z.w[3] != 0)) { > - *pfpsf |= INEXACT_EXCEPTION; > - if (c_prov < 1000000ull) > - *pfpsf |= UNDERFLOW_EXCEPTION; > - } > // Package up the result > > return_bid32 (s, e_out, c_prov); > @@ -146071,6 +146029,13 @@ binary128_to_bid32 (BINARY128 x > __mul_128x256_to_384 (z, c, r) > c_prov = z.w[5]; > > +// Test inexactness and underflow (when testing tininess before rounding) > + if ((z.w[4] != 0) || (z.w[3] != 0)) { > + *pfpsf |= INEXACT_EXCEPTION; > + if (c_prov < 1000000ull) > + *pfpsf |= UNDERFLOW_EXCEPTION; > + } > + > // Round using round-sticky words > // If we spill over into the next decade, correct > // Flag underflow where it may be needed even for |result| = SNN > @@ -146086,30 +146051,16 @@ binary128_to_bid32 (BINARY128 x > if (c_prov == 10000000ull) { > c_prov = 1000000ull; > e_out = e_out + 1; > - } else if ((c_prov == 1000000ull) && (e_out == 0)) { > - if ((((rnd_mode & 3) == 0) && > - le128 (z.w[4], z.w[3], > - 17524406870024074035ull, 3689348814741910323ull)) || > - ((rnd_mode + (s & 1) == 2) && > - le128 (z.w[4], z.w[3], > - 16602069666338596454ull, 7378697629483820646ull))) > - *pfpsf |= UNDERFLOW_EXCEPTION; > } > } > + > // Check for overflow > > if (e_out > 90 + 101) { > *pfpsf |= (OVERFLOW_EXCEPTION | INEXACT_EXCEPTION); > return_bid32_ovf (s); > } > -// Set the inexact flag as appropriate and check underflow > -// It's no doubt superfluous to check inexactness, but anyway... > > - if ((z.w[4] != 0) || (z.w[3] != 0)) { > - *pfpsf |= INEXACT_EXCEPTION; > - if (c_prov < 1000000ull) > - *pfpsf |= UNDERFLOW_EXCEPTION; > - } > // Package up the result > > return_bid32 (s, e_out, c_prov); > @@ -146562,6 +146513,14 @@ binary80_to_bid64 (BINARY80 x > __mul_128x256_to_384 (z, c, r) > c_prov = z.w[5]; > > +// Test inexactness and underflow (when testing tininess before rounding) > + > + if ((z.w[4] != 0) || (z.w[3] != 0)) { > + *pfpsf |= INEXACT_EXCEPTION; > + if (c_prov < 1000000000000000ull) > + *pfpsf |= UNDERFLOW_EXCEPTION; > + } > + > // Round using round-sticky words > // If we spill over into the next decade, correct > // Flag underflow where it may be needed even for |result| = SNN > @@ -146575,27 +146534,16 @@ binary80_to_bid64 (BINARY80 x > if (c_prov == 10000000000000000ull) { > c_prov = 1000000000000000ull; > e_out = e_out + 1; > - } else if ((c_prov == 1000000000000000ull) && (e_out == 0)) { > - if ((((rnd_mode & 3) == 0) && (z.w[4] <= 17524406870024074035ull)) > - || ((rnd_mode + (s & 1) == 2) > - && (z.w[4] <= 16602069666338596454ull))) > - *pfpsf |= UNDERFLOW_EXCEPTION; > } > } > + > // Check for overflow > > if (e_out > 369 + 398) { > *pfpsf |= (OVERFLOW_EXCEPTION | INEXACT_EXCEPTION); > return_bid64_ovf (s); > } > -// Set the inexact flag as appropriate and check underflow > -// It's no doubt superfluous to check inexactness, but anyway... > > - if ((z.w[4] != 0) || (z.w[3] != 0)) { > - *pfpsf |= INEXACT_EXCEPTION; > - if (c_prov < 1000000000000000ull) > - *pfpsf |= UNDERFLOW_EXCEPTION; > - } > // Package up the result > > return_bid64 (s, e_out, c_prov); > @@ -146723,6 +146671,14 @@ binary128_to_bid64 (BINARY128 x > __mul_128x256_to_384 (z, c, r) > c_prov = z.w[5]; > > +// Test inexactness and underflow (when testing tininess before rounding) > + > + if ((z.w[4] != 0) || (z.w[3] != 0)) { > + *pfpsf |= INEXACT_EXCEPTION; > + if (c_prov < 1000000000000000ull) > + *pfpsf |= UNDERFLOW_EXCEPTION; > + } > + > // Round using round-sticky words > // If we spill over into the next decade, correct > // Flag underflow where it may be needed even for |result| = SNN > @@ -146736,27 +146692,16 @@ binary128_to_bid64 (BINARY128 x > if (c_prov == 10000000000000000ull) { > c_prov = 1000000000000000ull; > e_out = e_out + 1; > - } else if ((c_prov == 1000000000000000ull) && (e_out == 0)) { > - if ((((rnd_mode & 3) == 0) && (z.w[4] <= 17524406870024074035ull)) > - || ((rnd_mode + (s & 1) == 2) > - && (z.w[4] <= 16602069666338596454ull))) > - *pfpsf |= UNDERFLOW_EXCEPTION; > } > } > + > // Check for overflow > > if (e_out > 369 + 398) { > *pfpsf |= (OVERFLOW_EXCEPTION | INEXACT_EXCEPTION); > return_bid64_ovf (s); > } > -// Set the inexact flag as appropriate and check underflow > -// It's no doubt superfluous to check inexactness, but anyway... > > - if ((z.w[4] != 0) || (z.w[3] != 0)) { > - *pfpsf |= INEXACT_EXCEPTION; > - if (c_prov < 1000000000000000ull) > - *pfpsf |= UNDERFLOW_EXCEPTION; > - } > // Package up the result > > return_bid64 (s, e_out, c_prov); > diff --git a/libgcc/config/libbid/bid_conf.h b/libgcc/config/libbid/bid_conf.h > index dff938edd5d..e054a3ff570 100644 > --- a/libgcc/config/libbid/bid_conf.h > +++ b/libgcc/config/libbid/bid_conf.h > @@ -519,6 +519,14 @@ see the files COPYING3 and COPYING.RUNTIME respectively. > If not, see > #define BID_BIG_ENDIAN __FLOAT_WORD_ORDER__ == __ORDER_BIG_ENDIAN__ > #endif > > +#if BID_BIG_ENDIAN > +#define BID_HIGH_128W 0 > +#define BID_LOW_128W 1 > +#else > +#define BID_HIGH_128W 1 > +#define BID_LOW_128W 0 > +#endif > + > #ifndef BID_THREAD > #if defined (HAVE_CC_TLS) && defined (USE_TLS) > #define BID_THREAD __thread > diff --git a/libgcc/config/libbid/bid_functions.h > b/libgcc/config/libbid/bid_functions.h > index 9b4fbef8d01..cce87eb4d60 100644 > --- a/libgcc/config/libbid/bid_functions.h > +++ b/libgcc/config/libbid/bid_functions.h > @@ -67,9 +67,13 @@ ALIGN (16) > #endif > > > +#if defined __NO_BINARY80__ > +#define __ENABLE_BINARY80__ 0 > +#else > #if !defined _MSC_VER || defined __INTEL_COMPILER > #define __ENABLE_BINARY80__ 1 > #endif > +#endif > > #ifndef HPUX_OS > #define BINARY80 long double > @@ -91,6 +95,19 @@ ALIGN (16) > } UINT256; > typedef unsigned int FPSC; // floating-point status and control > > + typedef enum class_types { > + signalingNaN, > + quietNaN, > + negativeInfinity, > + negativeNormal, > + negativeSubnormal, > + negativeZero, > + positiveZero, > + positiveSubnormal, > + positiveNormal, > + positiveInfinity > + } class_t; > + > // TYPE parameters > #define BID128_MAXDIGITS 34 > #define BID64_MAXDIGITS 16 > @@ -2948,7 +2965,7 @@ ALIGN (16) > extern UINT64 bid64_copySign (UINT64 x, > UINT64 y _EXC_MASKS_PARAM > _EXC_INFO_PARAM); > - extern int bid64_class (UINT64 x _EXC_MASKS_PARAM _EXC_INFO_PARAM); > + extern class_t bid64_class (UINT64 x _EXC_MASKS_PARAM _EXC_INFO_PARAM); > extern int bid64_sameQuantum (UINT64 x, UINT64 y > _EXC_MASKS_PARAM _EXC_INFO_PARAM); > extern int bid64_totalOrder (UINT64 x, UINT64 y > @@ -2984,8 +3001,8 @@ ALIGN (16) > extern UINT128 bid128_copySign (UINT128 x, > UINT128 y _EXC_MASKS_PARAM > _EXC_INFO_PARAM); > - extern int bid128_class (UINT128 x _EXC_MASKS_PARAM > - _EXC_INFO_PARAM); > + extern class_t bid128_class (UINT128 x _EXC_MASKS_PARAM > + _EXC_INFO_PARAM); > extern int bid128_sameQuantum (UINT128 x, > UINT128 y _EXC_MASKS_PARAM > _EXC_INFO_PARAM); > diff --git a/libgcc/config/libbid/bid_inline_add.h > b/libgcc/config/libbid/bid_inline_add.h > index eb16ea8e0ba..9ca41a2f89e 100644 > --- a/libgcc/config/libbid/bid_inline_add.h > +++ b/libgcc/config/libbid/bid_inline_add.h > @@ -918,6 +918,7 @@ get_add128 (UINT64 sign_x, int exponent_x, UINT64 > coefficient_x, > coefficient_x += D; > } > break; > + default: break; // default added to avoid compiler warning > } > if (coefficient_x < 1000000000000000ull) { > coefficient_x -= D; > @@ -1107,6 +1108,7 @@ get_add128 (UINT64 sign_x, int exponent_x, UINT64 > coefficient_x, > } else if (FS.w[1] | FS.w[0]) > CYh++; > break; > + default: break; // default added to avoid compiler warning > } > #endif > #endif > diff --git a/libgcc/config/libbid/bid_internal.h > b/libgcc/config/libbid/bid_internal.h > index 764abf81057..d3c83b5c219 100644 > --- a/libgcc/config/libbid/bid_internal.h > +++ b/libgcc/config/libbid/bid_internal.h > @@ -970,6 +970,8 @@ get_BID64 (UINT64 sgn, int expon, UINT64 coeff, int rmode, > // round up > if (sgn) > r = SMALLEST_BID64; > + default: > + break; > } > return r; > } > @@ -1086,6 +1088,8 @@ fast_get_BID64_check_OF (UINT64 sgn, int expon, UINT64 > coeff, int rmode, > // round up > if (sgn) > r = SMALLEST_BID64; > + default: > + break; > } > return r; > } > @@ -2582,19 +2586,6 @@ ALIGN (16) > A=((tempx.i >>23) & EXPONENT_MASK32) - 0x7f;\ > } > > - enum class_types { > - signalingNaN, > - quietNaN, > - negativeInfinity, > - negativeNormal, > - negativeSubnormal, > - negativeZero, > - positiveZero, > - positiveSubnormal, > - positiveNormal, > - positiveInfinity > - }; > - > typedef union { > UINT64 ui64; > double d; > -- > 2.31.1 >