Skip to content

Commit 667b3ec

Browse files
committed
Update libquadmath fmaq from glibc, fix nanq issues.
This patch extends update-quadmath.py to update fmaq from glibc. The issue in that function was that quadmath-imp.h had a struct in a union with mant_high and mant_low fields (up to 64-bit) whereas glibc has mantissa0, mantissa1, mantissa2 and mantissa3 (up to 32-bit). The patch changes those fields to be the same as in glibc, moving printf / strtod code that also uses those fields back to closer to the glibc form. This allows fmaq to be updated automatically from glibc (which brings in at least one bug fix from glibc from 2015). nanq was also using the mant_high field name, and had other issues: it only partly initialized the union from which a value was returned, and setting mant_high to 1 meant a signaling NaN would be returned rather than a quiet NaN. This patch fixes those issues as part of updating it to use the changed interfaces (but does not fix the issue of not using the argument). Bootstrapped with no regressions on x86_64-pc-linux-gnu. * quadmath-imp.h (ieee854_float128): Use mantissa0, mantissa1, mantissa2 and mantissa3 fields instead of mant_high and mant_low. Change nan field to ieee_nan. * update-quadmath.py (update_sources): Also update fmaq.c. * math/nanq.c (nanq): Use ieee_nan field of union. Zero-initialize f. Set quiet_nan field. * printf/flt1282mpn.c, printf/printf_fphex.c, strtod/mpn2flt128.c, strtod/strtoflt128.c: Use mantissa0, mantissa1, mantissa2 and mantissa3 fields. Use ieee_nan and quiet_nan field. * math/fmaq.c: Regenerate from glibc sources with update-quadmath.py. From-SVN: r265874
1 parent 296b0b0 commit 667b3ec

File tree

9 files changed

+93
-91
lines changed

9 files changed

+93
-91
lines changed

libquadmath/ChangeLog

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,17 @@
1+
2018-11-07 Joseph Myers <[email protected]>
2+
3+
* quadmath-imp.h (ieee854_float128): Use mantissa0, mantissa1,
4+
mantissa2 and mantissa3 fields instead of mant_high and mant_low.
5+
Change nan field to ieee_nan.
6+
* update-quadmath.py (update_sources): Also update fmaq.c.
7+
* math/nanq.c (nanq): Use ieee_nan field of union.
8+
Zero-initialize f. Set quiet_nan field.
9+
* printf/flt1282mpn.c, printf/printf_fphex.c, strtod/mpn2flt128.c,
10+
strtod/strtoflt128.c: Use mantissa0, mantissa1, mantissa2 and
11+
mantissa3 fields. Use ieee_nan and quiet_nan field.
12+
* math/fmaq.c: Regenerate from glibc sources with
13+
update-quadmath.py.
14+
115
2018-11-05 Joseph Myers <[email protected]>
216

317
PR libquadmath/68686

libquadmath/math/fmaq.c

Lines changed: 28 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* Compute x * y + z as ternary operation.
2-
Copyright (C) 2010-2017 Free Software Foundation, Inc.
2+
Copyright (C) 2010-2018 Free Software Foundation, Inc.
33
This file is part of the GNU C Library.
44
Contributed by Jakub Jelinek <[email protected]>, 2010.
55
@@ -18,16 +18,6 @@
1818
<http://www.gnu.org/licenses/>. */
1919

2020
#include "quadmath-imp.h"
21-
#include <math.h>
22-
#include <float.h>
23-
#ifdef HAVE_FENV_H
24-
# include <fenv.h>
25-
# if defined HAVE_FEHOLDEXCEPT && defined HAVE_FESETROUND \
26-
&& defined HAVE_FEUPDATEENV && defined HAVE_FETESTEXCEPT \
27-
&& defined FE_TOWARDZERO && defined FE_INEXACT
28-
# define USE_FENV_H
29-
# endif
30-
#endif
3121

3222
/* This implementation uses rounding to odd to avoid problems with
3323
double rounding. See a paper by Boldo and Melquiond:
@@ -73,7 +63,7 @@ fmaq (__float128 x, __float128 y, __float128 z)
7363
if (u.ieee.exponent + v.ieee.exponent
7464
> 0x7fff + IEEE854_FLOAT128_BIAS)
7565
return x * y;
76-
/* If x * y is less than 1/4 of FLT128_DENORM_MIN, neither the
66+
/* If x * y is less than 1/4 of FLT128_TRUE_MIN, neither the
7767
result nor whether there is underflow depends on its exact
7868
value, only on its sign. */
7969
if (u.ieee.exponent + v.ieee.exponent
@@ -94,8 +84,10 @@ fmaq (__float128 x, __float128 y, __float128 z)
9484
: (w.ieee.exponent == 0
9585
|| (w.ieee.exponent == 1
9686
&& w.ieee.negative != neg
97-
&& w.ieee.mant_low == 0
98-
&& w.ieee.mant_high == 0)))
87+
&& w.ieee.mantissa3 == 0
88+
&& w.ieee.mantissa2 == 0
89+
&& w.ieee.mantissa1 == 0
90+
&& w.ieee.mantissa0 == 0)))
9991
{
10092
__float128 force_underflow = x * y;
10193
math_force_eval (force_underflow);
@@ -124,7 +116,7 @@ fmaq (__float128 x, __float128 y, __float128 z)
124116
very small, adjust them up to avoid spurious underflows,
125117
rather than down. */
126118
if (u.ieee.exponent + v.ieee.exponent
127-
<= IEEE854_FLOAT128_BIAS + FLT128_MANT_DIG)
119+
<= IEEE854_FLOAT128_BIAS + 2 * FLT128_MANT_DIG)
128120
{
129121
if (u.ieee.exponent > v.ieee.exponent)
130122
u.ieee.exponent += 2 * FLT128_MANT_DIG + 2;
@@ -181,17 +173,15 @@ fmaq (__float128 x, __float128 y, __float128 z)
181173
}
182174

183175
/* Ensure correct sign of exact 0 + 0. */
184-
if (__builtin_expect ((x == 0 || y == 0) && z == 0, 0))
176+
if (__glibc_unlikely ((x == 0 || y == 0) && z == 0))
185177
{
186178
x = math_opt_barrier (x);
187179
return x * y + z;
188180
}
189181

190-
#ifdef USE_FENV_H
191182
fenv_t env;
192183
feholdexcept (&env);
193184
fesetround (FE_TONEAREST);
194-
#endif
195185

196186
/* Multiplication m1 + m2 = x * y using Dekker's algorithm. */
197187
#define C ((1LL << (FLT128_MANT_DIG + 1) / 2) + 1)
@@ -214,62 +204,46 @@ fmaq (__float128 x, __float128 y, __float128 z)
214204
/* Ensure the arithmetic is not scheduled after feclearexcept call. */
215205
math_force_eval (m2);
216206
math_force_eval (a2);
217-
#ifdef USE_FENV_H
218207
feclearexcept (FE_INEXACT);
219-
#endif
220208

221209
/* If the result is an exact zero, ensure it has the correct sign. */
222210
if (a1 == 0 && m2 == 0)
223211
{
224-
#ifdef USE_FENV_H
225212
feupdateenv (&env);
226-
#endif
227213
/* Ensure that round-to-nearest value of z + m1 is not reused. */
228214
z = math_opt_barrier (z);
229215
return z + m1;
230216
}
231217

232-
#ifdef USE_FENV_H
233218
fesetround (FE_TOWARDZERO);
234-
#endif
235219
/* Perform m2 + a2 addition with round to odd. */
236220
u.value = a2 + m2;
237221

238-
if (__builtin_expect (adjust == 0, 1))
222+
if (__glibc_likely (adjust == 0))
239223
{
240-
#ifdef USE_FENV_H
241-
if ((u.ieee.mant_low & 1) == 0 && u.ieee.exponent != 0x7fff)
242-
u.ieee.mant_low |= fetestexcept (FE_INEXACT) != 0;
224+
if ((u.ieee.mantissa3 & 1) == 0 && u.ieee.exponent != 0x7fff)
225+
u.ieee.mantissa3 |= fetestexcept (FE_INEXACT) != 0;
243226
feupdateenv (&env);
244-
#endif
245227
/* Result is a1 + u.value. */
246228
return a1 + u.value;
247229
}
248-
else if (__builtin_expect (adjust > 0, 1))
230+
else if (__glibc_likely (adjust > 0))
249231
{
250-
#ifdef USE_FENV_H
251-
if ((u.ieee.mant_low & 1) == 0 && u.ieee.exponent != 0x7fff)
252-
u.ieee.mant_low |= fetestexcept (FE_INEXACT) != 0;
232+
if ((u.ieee.mantissa3 & 1) == 0 && u.ieee.exponent != 0x7fff)
233+
u.ieee.mantissa3 |= fetestexcept (FE_INEXACT) != 0;
253234
feupdateenv (&env);
254-
#endif
255235
/* Result is a1 + u.value, scaled up. */
256236
return (a1 + u.value) * 0x1p113Q;
257237
}
258238
else
259239
{
260-
#ifdef USE_FENV_H
261-
if ((u.ieee.mant_low & 1) == 0)
262-
u.ieee.mant_low |= fetestexcept (FE_INEXACT) != 0;
263-
#endif
240+
if ((u.ieee.mantissa3 & 1) == 0)
241+
u.ieee.mantissa3 |= fetestexcept (FE_INEXACT) != 0;
264242
v.value = a1 + u.value;
265243
/* Ensure the addition is not scheduled after fetestexcept call. */
266-
asm volatile ("" : : "m" (v.value));
267-
#ifdef USE_FENV_H
244+
math_force_eval (v.value);
268245
int j = fetestexcept (FE_INEXACT) != 0;
269246
feupdateenv (&env);
270-
#else
271-
int j = 0;
272-
#endif
273247
/* Ensure the following computations are performed in default rounding
274248
mode instead of just reusing the round to zero computation. */
275249
asm volatile ("" : "=m" (u) : "m" (u));
@@ -281,11 +255,11 @@ fmaq (__float128 x, __float128 y, __float128 z)
281255
rounding will occur. */
282256
if (v.ieee.exponent > 228)
283257
return (a1 + u.value) * 0x1p-228Q;
284-
/* If v.value * 0x1p-228Q with round to zero is a subnormal above
285-
or equal to FLT128_MIN / 2, then v.value * 0x1p-228Q shifts mantissa
286-
down just by 1 bit, which means v.ieee.mant_low |= j would
258+
/* If v.value * 0x1p-228L with round to zero is a subnormal above
259+
or equal to FLT128_MIN / 2, then v.value * 0x1p-228L shifts mantissa
260+
down just by 1 bit, which means v.ieee.mantissa3 |= j would
287261
change the round bit, not sticky or guard bit.
288-
v.value * 0x1p-228Q never normalizes by shifting up,
262+
v.value * 0x1p-228L never normalizes by shifting up,
289263
so round bit plus sticky bit should be already enough
290264
for proper rounding. */
291265
if (v.ieee.exponent == 228)
@@ -301,18 +275,18 @@ fmaq (__float128 x, __float128 y, __float128 z)
301275
if (w.ieee.exponent == 229)
302276
return w.value * 0x1p-228Q;
303277
}
304-
/* v.ieee.mant_low & 2 is LSB bit of the result before rounding,
305-
v.ieee.mant_low & 1 is the round bit and j is our sticky
306-
bit. */
307-
w.value = 0.0Q;
308-
w.ieee.mant_low = ((v.ieee.mant_low & 3) << 1) | j;
278+
/* v.ieee.mantissa3 & 2 is LSB bit of the result before rounding,
279+
v.ieee.mantissa3 & 1 is the round bit and j is our sticky
280+
bit. */
281+
w.value = 0;
282+
w.ieee.mantissa3 = ((v.ieee.mantissa3 & 3) << 1) | j;
309283
w.ieee.negative = v.ieee.negative;
310-
v.ieee.mant_low &= ~3U;
284+
v.ieee.mantissa3 &= ~3U;
311285
v.value *= 0x1p-228Q;
312286
w.value *= 0x1p-2Q;
313287
return v.value + w.value;
314288
}
315-
v.ieee.mant_low |= j;
289+
v.ieee.mantissa3 |= j;
316290
return v.value * 0x1p-228Q;
317291
}
318292
}

libquadmath/math/nanq.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ __float128
44
nanq (const char *tagp __attribute__ ((unused)))
55
{
66
// FIXME -- we should use the argument
7-
ieee854_float128 f;
8-
f.ieee.exponent = 0x7fff;
9-
f.ieee.mant_high = 0x1;
7+
ieee854_float128 f = { 0 };
8+
f.ieee_nan.exponent = 0x7fff;
9+
f.ieee_nan.quiet_nan = 0x1;
1010
return f.value;
1111
}

libquadmath/printf/flt1282mpn.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,14 +39,14 @@ mpn_extract_flt128 (mp_ptr res_ptr, mp_size_t size,
3939
*expt = (int) u.ieee.exponent - IEEE854_FLOAT128_BIAS;
4040

4141
#if BITS_PER_MP_LIMB == 32
42-
res_ptr[0] = u.ieee.mant_low; /* Low-order 32 bits of fraction. */
43-
res_ptr[1] = (u.ieee.mant_low >> 32);
44-
res_ptr[2] = u.ieee.mant_high;
45-
res_ptr[3] = (u.ieee.mant_high >> 32); /* High-order 32 bits. */
42+
res_ptr[0] = u.ieee.mantissa3; /* Low-order 32 bits of fraction. */
43+
res_ptr[1] = u.ieee.mantissa2;
44+
res_ptr[2] = u.ieee.mantissa1;
45+
res_ptr[3] = u.ieee.mantissa0; /* High-order 32 bits. */
4646
#define N 4
4747
#elif BITS_PER_MP_LIMB == 64
48-
res_ptr[0] = u.ieee.mant_low;
49-
res_ptr[1] = u.ieee.mant_high;
48+
res_ptr[0] = ((mp_limb_t) u.ieee.mantissa2 << 32) | u.ieee.mantissa3;
49+
res_ptr[1] = ((mp_limb_t) u.ieee.mantissa0 << 32) | u.ieee.mantissa1;
5050
#define N 2
5151
#else
5252
#error "mp_limb size " BITS_PER_MP_LIMB "not accounted for"

libquadmath/printf/printf_fphex.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -235,8 +235,10 @@ __quadmath_printf_fphex (struct __quadmath_printf_file *fp,
235235

236236
assert (sizeof (long double) == 16);
237237

238-
num0 = fpnum.ieee.mant_high;
239-
num1 = fpnum.ieee.mant_low;
238+
num0 = (((unsigned long long int) fpnum.ieee.mantissa0) << 32
239+
| fpnum.ieee.mantissa1);
240+
num1 = (((unsigned long long int) fpnum.ieee.mantissa2) << 32
241+
| fpnum.ieee.mantissa3);
240242

241243
zero_mantissa = (num0|num1) == 0;
242244

libquadmath/quadmath-imp.h

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -96,11 +96,15 @@ typedef union
9696
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
9797
unsigned negative:1;
9898
unsigned exponent:15;
99-
uint64_t mant_high:48;
100-
uint64_t mant_low:64;
99+
unsigned mantissa0:16;
100+
unsigned mantissa1:32;
101+
unsigned mantissa2:32;
102+
unsigned mantissa3:32;
101103
#else
102-
uint64_t mant_low:64;
103-
uint64_t mant_high:48;
104+
unsigned mantissa3:32;
105+
unsigned mantissa2:32;
106+
unsigned mantissa1:32;
107+
unsigned mantissa0:16;
104108
unsigned exponent:15;
105109
unsigned negative:1;
106110
#endif
@@ -142,16 +146,20 @@ typedef union
142146
unsigned negative:1;
143147
unsigned exponent:15;
144148
unsigned quiet_nan:1;
145-
uint64_t mant_high:47;
146-
uint64_t mant_low:64;
149+
unsigned mantissa0:15;
150+
unsigned mantissa1:32;
151+
unsigned mantissa2:32;
152+
unsigned mantissa3:32;
147153
#else
148-
uint64_t mant_low:64;
149-
uint64_t mant_high:47;
154+
unsigned mantissa3:32;
155+
unsigned mantissa2:32;
156+
unsigned mantissa1:32;
157+
unsigned mantissa0:15;
150158
unsigned quiet_nan:1;
151159
unsigned exponent:15;
152160
unsigned negative:1;
153161
#endif
154-
} nan;
162+
} ieee_nan;
155163

156164
} ieee854_float128;
157165

libquadmath/strtod/mpn2flt128.c

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,15 +34,17 @@ mpn_construct_float128 (mp_srcptr frac_ptr, int expt, int sign)
3434
u.ieee.negative = sign;
3535
u.ieee.exponent = expt + IEEE854_FLOAT128_BIAS;
3636
#if BITS_PER_MP_LIMB == 32
37-
u.ieee.mant_low = (((uint64_t) frac_ptr[1]) << 32)
38-
| (frac_ptr[0] & 0xffffffff);
39-
u.ieee.mant_high = (((uint64_t) frac_ptr[3]
40-
& (((mp_limb_t) 1 << (FLT128_MANT_DIG - 96)) - 1))
41-
<< 32) | (frac_ptr[2] & 0xffffffff);
37+
u.ieee.mantissa3 = frac_ptr[0];
38+
u.ieee.mantissa2 = frac_ptr[1];
39+
u.ieee.mantissa1 = frac_ptr[2];
40+
u.ieee.mantissa0 = frac_ptr[3] & (((mp_limb_t) 1
41+
<< (FLT128_MANT_DIG - 96)) - 1);
4242
#elif BITS_PER_MP_LIMB == 64
43-
u.ieee.mant_low = frac_ptr[0];
44-
u.ieee.mant_high = frac_ptr[1]
45-
& (((mp_limb_t) 1 << (FLT128_MANT_DIG - 64)) - 1);
43+
u.ieee.mantissa3 = frac_ptr[0] & (((mp_limb_t) 1 << 32) - 1);
44+
u.ieee.mantissa2 = frac_ptr[0] >> 32;
45+
u.ieee.mantissa1 = frac_ptr[1] & (((mp_limb_t) 1 << 32) - 1);
46+
u.ieee.mantissa0 = (frac_ptr[1] >> 32) & (((mp_limb_t) 1
47+
<< (FLT128_MANT_DIG - 96)) - 1);
4648
#else
4749
#error "mp_limb size " BITS_PER_MP_LIMB "not accounted for"
4850
#endif

libquadmath/strtod/strtoflt128.c

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,15 @@
3030
#endif
3131
#define MPN2FLOAT mpn_construct_float128
3232
#define FLOAT_HUGE_VAL HUGE_VALQ
33-
#define SET_MANTISSA(flt, mant) \
34-
do { ieee854_float128 u; \
35-
u.value = (flt); \
36-
u.ieee.mant_high = 0x800000000000ULL; \
37-
u.ieee.mant_low = mant; \
38-
(flt) = u.value; \
33+
#define SET_MANTISSA(flt, mant) \
34+
do { ieee854_float128 u; \
35+
u.value = (flt); \
36+
u.ieee_nan.mantissa0 = 0; \
37+
u.ieee_nan.mantissa1 = 0; \
38+
u.ieee_nan.mantissa2 = (mant) >> 32; \
39+
u.ieee_nan.mantissa3 = (mant); \
40+
u.ieee_nan.quiet_nan = 1; \
41+
(flt) = u.value; \
3942
} while (0)
4043

4144
static inline __attribute__((__always_inline__))

libquadmath/update-quadmath.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -143,8 +143,7 @@ def update_sources(glibc_srcdir, quadmath_srcdir):
143143
# Replace all #includes with a single include of quadmath-imp.h.
144144
repl_map['(\n+#include[^\n]*)+\n+'] = '\n\n#include "quadmath-imp.h"\n\n'
145145
# Omitted from this list because code comes from more than one
146-
# glibc source file: rem_pio2. Omitted because of a union not
147-
# currently provided in libquadmath: fma.
146+
# glibc source file: rem_pio2.
148147
ldbl_files = {
149148
'e_acoshl.c': 'acoshq.c', 'e_acosl.c': 'acosq.c',
150149
's_asinhl.c': 'asinhq.c', 'e_asinl.c': 'asinq.c',
@@ -155,7 +154,7 @@ def update_sources(glibc_srcdir, quadmath_srcdir):
155154
's_erfl.c': 'erfq.c', 's_expm1l.c': 'expm1q.c', 'e_expl.c': 'expq.c',
156155
't_expl.h': 'expq_table.h', 's_fabsl.c': 'fabsq.c',
157156
's_finitel.c': 'finiteq.c', 's_floorl.c': 'floorq.c',
158-
'e_fmodl.c': 'fmodq.c', 's_frexpl.c': 'frexpq.c',
157+
's_fmal.c': 'fmaq.c', 'e_fmodl.c': 'fmodq.c', 's_frexpl.c': 'frexpq.c',
159158
'e_lgammal_r.c': 'lgammaq.c', 'lgamma_negl.c': 'lgammaq_neg.c',
160159
'lgamma_productl.c': 'lgammaq_product.c', 'e_hypotl.c': 'hypotq.c',
161160
'e_ilogbl.c': 'ilogbq.c', 's_isinfl.c': 'isinfq.c',

0 commit comments

Comments
 (0)