mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-08 22:30:07 +00:00
Make fma use of Dekker and Knuth algorithms use round-to-nearest (bug 14796).
This commit is contained in:
parent
fbeafedeea
commit
5b5b04d628
41
ChangeLog
41
ChangeLog
@ -1,5 +1,46 @@
|
||||
2012-11-03 Joseph Myers <joseph@codesourcery.com>
|
||||
|
||||
[BZ #14796]
|
||||
* sysdeps/ieee754/dbl-64/s_fma.c (__fma): Set rounding mode to
|
||||
FE_TONEAREST before applying Dekker multiplication and Knuth
|
||||
addition. Clear inexact exceptions and check for exact zero
|
||||
results afterwards.
|
||||
* sysdeps/ieee754/ldbl-128/s_fmal.c (__fmal): Likewise.
|
||||
* sysdeps/ieee754/ldbl-96/s_fma.c (__fma): Likewise.
|
||||
* sysdeps/ieee754/ldbl-96/s_fmal.c (__fmal): Likewise.
|
||||
* math/libm-test.inc (fma_test): Add more tests.
|
||||
(fma_test_towardzero): Likewise.
|
||||
(fma_test_downward): Likewise.
|
||||
(fma_test_upward): Likewise.
|
||||
* sysdeps/generic/math_private.h (default_libc_fesetround): New
|
||||
function.
|
||||
(libc_fesetround): New macro.
|
||||
(libc_fesetroundf): Likewise.
|
||||
(libc_fesetroundl): Likewise.
|
||||
* sysdeps/i386/fpu/fenv_private.h (libc_fesetround_sse): New
|
||||
function.
|
||||
(libc_fesetround_387): Likewise.
|
||||
(libc_fesetroundf): New macro.
|
||||
(libc_fesetround): Likewise.
|
||||
(libc_fesetroundl): Likewise.
|
||||
* sysdeps/sparc/fpu/fenv_private.h (libc_fesetround): New
|
||||
function.
|
||||
(libc_fesetroundf): New macro.
|
||||
(libc_fesetround): Likewise.
|
||||
(libc_fesetroundl): Likewise.
|
||||
* include/fenv.h (feclearexcept): Add libm_hidden_proto.
|
||||
* math/fclrexcpt.c (feclearexcept): Add libm_hidden_ver.
|
||||
* sysdeps/i386/fpu/fclrexcpt.c (feclearexcept): Add
|
||||
libm_hidden_ver.
|
||||
* sysdeps/powerpc/fpu/fclrexcpt.c (feclearexcept): Likewise.
|
||||
* sysdeps/s390/fpu/fclrexcpt.c (feclearexcept): Add
|
||||
libm_hidden_def.
|
||||
* sysdeps/sh/sh4/fpu/fclrexcpt.c (feclearexcept): Likewise.
|
||||
* sysdeps/sparc/fpu/fclrexcpt.c (feclearexcept): Add
|
||||
libm_hidden_ver.
|
||||
* sysdeps/x86_64/fpu/fclrexcpt.c (feclearexcept): Add
|
||||
libm_hidden_def.
|
||||
|
||||
[BZ #3439]
|
||||
* sysdeps/powerpc/bits/fenv.h (FE_INEXACT): Define macro to
|
||||
integer constant usable in #if and use that to give value to enum
|
||||
|
2
NEWS
2
NEWS
@ -18,7 +18,7 @@ Version 2.17
|
||||
14532, 14538, 14543, 14544, 14545, 14557, 14562, 14568, 14576, 14579,
|
||||
14583, 14587, 14595, 14602, 14610, 14621, 14638, 14645, 14648, 14652,
|
||||
14660, 14661, 14669, 14683, 14694, 14716, 14743, 14767, 14783, 14784,
|
||||
14785.
|
||||
14785, 14796.
|
||||
|
||||
* Support for STT_GNU_IFUNC symbols added for s390 and s390x.
|
||||
Optimized versions of memcpy, memset, and memcmp added for System z10 and
|
||||
|
@ -20,6 +20,7 @@ libm_hidden_proto (fesetround)
|
||||
libm_hidden_proto (feholdexcept)
|
||||
libm_hidden_proto (feupdateenv)
|
||||
libm_hidden_proto (fetestexcept)
|
||||
libm_hidden_proto (feclearexcept)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -30,6 +30,7 @@ __feclearexcept (int excepts)
|
||||
strong_alias (__feclearexcept, __old_feclearexcept)
|
||||
compat_symbol (libm, __old_feclearexcept, feclearexcept, GLIBC_2_1);
|
||||
#endif
|
||||
libm_hidden_ver (__feclearexcept, feclearexcept)
|
||||
versioned_symbol (libm, __feclearexcept, feclearexcept, GLIBC_2_2);
|
||||
|
||||
stub_warning (feclearexcept)
|
||||
|
@ -4649,6 +4649,10 @@ fma_test (void)
|
||||
TEST_fff_f (fma, 0x1p-149, -0x1p-149, 0x1p-149, 0x1p-149, UNDERFLOW_EXCEPTION);
|
||||
TEST_fff_f (fma, 0x1p-149, 0x1p-149, -0x1p-149, -0x1p-149, UNDERFLOW_EXCEPTION);
|
||||
TEST_fff_f (fma, 0x1p-149, -0x1p-149, -0x1p-149, -0x1p-149, UNDERFLOW_EXCEPTION);
|
||||
TEST_fff_f (fma, 0x0.fffp0, 0x0.fffp0, -0x0.ffep0, 0x1p-24);
|
||||
TEST_fff_f (fma, 0x0.fffp0, -0x0.fffp0, 0x0.ffep0, -0x1p-24);
|
||||
TEST_fff_f (fma, -0x0.fffp0, 0x0.fffp0, 0x0.ffep0, -0x1p-24);
|
||||
TEST_fff_f (fma, -0x0.fffp0, -0x0.fffp0, -0x0.ffep0, 0x1p-24);
|
||||
#endif
|
||||
#if defined (TEST_DOUBLE) && DBL_MANT_DIG == 53
|
||||
TEST_fff_f (fma, 0x1.7fp+13, 0x1.0000000000001p+0, 0x1.ffep-48, 0x1.7f00000000001p+13);
|
||||
@ -4695,6 +4699,10 @@ fma_test (void)
|
||||
TEST_fff_f (fma, 0x1p-1074, -0x1p-1074, 0x1p-1074, 0x1p-1074, UNDERFLOW_EXCEPTION);
|
||||
TEST_fff_f (fma, 0x1p-1074, 0x1p-1074, -0x1p-1074, -0x1p-1074, UNDERFLOW_EXCEPTION);
|
||||
TEST_fff_f (fma, 0x1p-1074, -0x1p-1074, -0x1p-1074, -0x1p-1074, UNDERFLOW_EXCEPTION);
|
||||
TEST_fff_f (fma, 0x0.fffffffffffff8p0, 0x0.fffffffffffff8p0, -0x0.fffffffffffffp0, 0x1p-106);
|
||||
TEST_fff_f (fma, 0x0.fffffffffffff8p0, -0x0.fffffffffffff8p0, 0x0.fffffffffffffp0, -0x1p-106);
|
||||
TEST_fff_f (fma, -0x0.fffffffffffff8p0, 0x0.fffffffffffff8p0, 0x0.fffffffffffffp0, -0x1p-106);
|
||||
TEST_fff_f (fma, -0x0.fffffffffffff8p0, -0x0.fffffffffffff8p0, -0x0.fffffffffffffp0, 0x1p-106);
|
||||
#endif
|
||||
#if defined (TEST_LDOUBLE) && LDBL_MANT_DIG == 64
|
||||
TEST_fff_f (fma, -0x8.03fcp+3696L, 0xf.fffffffffffffffp-6140L, 0x8.3ffffffffffffffp-2450L, -0x8.01ecp-2440L);
|
||||
@ -4727,6 +4735,10 @@ fma_test (void)
|
||||
TEST_fff_f (fma, 0x1p-16445L, -0x1p-16445L, 0x1p-16445L, 0x1p-16445L, UNDERFLOW_EXCEPTION);
|
||||
TEST_fff_f (fma, 0x1p-16445L, 0x1p-16445L, -0x1p-16445L, -0x1p-16445L, UNDERFLOW_EXCEPTION);
|
||||
TEST_fff_f (fma, 0x1p-16445L, -0x1p-16445L, -0x1p-16445L, -0x1p-16445L, UNDERFLOW_EXCEPTION);
|
||||
TEST_fff_f (fma, 0x0.ffffffffffffffffp0L, 0x0.ffffffffffffffffp0L, -0x0.fffffffffffffffep0L, 0x1p-128L);
|
||||
TEST_fff_f (fma, 0x0.ffffffffffffffffp0L, -0x0.ffffffffffffffffp0L, 0x0.fffffffffffffffep0L, -0x1p-128L);
|
||||
TEST_fff_f (fma, -0x0.ffffffffffffffffp0L, 0x0.ffffffffffffffffp0L, 0x0.fffffffffffffffep0L, -0x1p-128L);
|
||||
TEST_fff_f (fma, -0x0.ffffffffffffffffp0L, -0x0.ffffffffffffffffp0L, -0x0.fffffffffffffffep0L, 0x1p-128L);
|
||||
#endif
|
||||
#if defined (TEST_LDOUBLE) && LDBL_MANT_DIG == 113
|
||||
TEST_fff_f (fma, 0x1.bb2de33e02ccbbfa6e245a7c1f71p-2584L, -0x1.6b500daf0580d987f1bc0cadfcddp-13777L, 0x1.613cd91d9fed34b33820e5ab9d8dp-16378L, -0x1.3a79fb50eb9ce887cffa0f09bd9fp-16360L);
|
||||
@ -4766,6 +4778,10 @@ fma_test (void)
|
||||
TEST_fff_f (fma, 0x1p-16494L, -0x1p-16494L, 0x1p-16494L, 0x1p-16494L, UNDERFLOW_EXCEPTION);
|
||||
TEST_fff_f (fma, 0x1p-16494L, 0x1p-16494L, -0x1p-16494L, -0x1p-16494L, UNDERFLOW_EXCEPTION);
|
||||
TEST_fff_f (fma, 0x1p-16494L, -0x1p-16494L, -0x1p-16494L, -0x1p-16494L, UNDERFLOW_EXCEPTION);
|
||||
TEST_fff_f (fma, 0x0.ffffffffffffffffffffffffffff8p0L, 0x0.ffffffffffffffffffffffffffff8p0L, -0x0.ffffffffffffffffffffffffffffp0L, 0x1p-226L);
|
||||
TEST_fff_f (fma, 0x0.ffffffffffffffffffffffffffff8p0L, -0x0.ffffffffffffffffffffffffffff8p0L, 0x0.ffffffffffffffffffffffffffffp0L, -0x1p-226L);
|
||||
TEST_fff_f (fma, -0x0.ffffffffffffffffffffffffffff8p0L, 0x0.ffffffffffffffffffffffffffff8p0L, 0x0.ffffffffffffffffffffffffffffp0L, -0x1p-226L);
|
||||
TEST_fff_f (fma, -0x0.ffffffffffffffffffffffffffff8p0L, -0x0.ffffffffffffffffffffffffffff8p0L, -0x0.ffffffffffffffffffffffffffffp0L, 0x1p-226L);
|
||||
#endif
|
||||
|
||||
END (fma);
|
||||
@ -4846,6 +4862,10 @@ fma_test_towardzero (void)
|
||||
TEST_fff_f (fma, 0x1p-149, -0x1p-149, 0x1p-149, plus_zero, UNDERFLOW_EXCEPTION);
|
||||
TEST_fff_f (fma, 0x1p-149, 0x1p-149, -0x1p-149, minus_zero, UNDERFLOW_EXCEPTION);
|
||||
TEST_fff_f (fma, 0x1p-149, -0x1p-149, -0x1p-149, -0x1p-149, UNDERFLOW_EXCEPTION);
|
||||
TEST_fff_f (fma, 0x0.fffp0, 0x0.fffp0, -0x0.ffep0, 0x1p-24);
|
||||
TEST_fff_f (fma, 0x0.fffp0, -0x0.fffp0, 0x0.ffep0, -0x1p-24);
|
||||
TEST_fff_f (fma, -0x0.fffp0, 0x0.fffp0, 0x0.ffep0, -0x1p-24);
|
||||
TEST_fff_f (fma, -0x0.fffp0, -0x0.fffp0, -0x0.ffep0, 0x1p-24);
|
||||
#endif
|
||||
#if defined (TEST_DOUBLE) && DBL_MANT_DIG == 53
|
||||
TEST_fff_f (fma, 0x1.4p-1022, 0x1.0000000000002p-1, 0x1p-1024, 0x1.c000000000002p-1023, UNDERFLOW_EXCEPTION);
|
||||
@ -4872,6 +4892,10 @@ fma_test_towardzero (void)
|
||||
TEST_fff_f (fma, 0x1p-1074, -0x1p-1074, 0x1p-1074, plus_zero, UNDERFLOW_EXCEPTION);
|
||||
TEST_fff_f (fma, 0x1p-1074, 0x1p-1074, -0x1p-1074, minus_zero, UNDERFLOW_EXCEPTION);
|
||||
TEST_fff_f (fma, 0x1p-1074, -0x1p-1074, -0x1p-1074, -0x1p-1074, UNDERFLOW_EXCEPTION);
|
||||
TEST_fff_f (fma, 0x0.fffffffffffff8p0, 0x0.fffffffffffff8p0, -0x0.fffffffffffffp0, 0x1p-106);
|
||||
TEST_fff_f (fma, 0x0.fffffffffffff8p0, -0x0.fffffffffffff8p0, 0x0.fffffffffffffp0, -0x1p-106);
|
||||
TEST_fff_f (fma, -0x0.fffffffffffff8p0, 0x0.fffffffffffff8p0, 0x0.fffffffffffffp0, -0x1p-106);
|
||||
TEST_fff_f (fma, -0x0.fffffffffffff8p0, -0x0.fffffffffffff8p0, -0x0.fffffffffffffp0, 0x1p-106);
|
||||
#endif
|
||||
#if defined (TEST_LDOUBLE) && LDBL_MANT_DIG == 64
|
||||
TEST_fff_f (fma, 0x1.4p-16382L, 0x1.0000000000000004p-1L, 0x1p-16384L, 0x1.c000000000000004p-16383L, UNDERFLOW_EXCEPTION);
|
||||
@ -4898,6 +4922,10 @@ fma_test_towardzero (void)
|
||||
TEST_fff_f (fma, 0x1p-16445L, -0x1p-16445L, 0x1p-16445L, plus_zero, UNDERFLOW_EXCEPTION);
|
||||
TEST_fff_f (fma, 0x1p-16445L, 0x1p-16445L, -0x1p-16445L, minus_zero, UNDERFLOW_EXCEPTION);
|
||||
TEST_fff_f (fma, 0x1p-16445L, -0x1p-16445L, -0x1p-16445L, -0x1p-16445L, UNDERFLOW_EXCEPTION);
|
||||
TEST_fff_f (fma, 0x0.ffffffffffffffffp0L, 0x0.ffffffffffffffffp0L, -0x0.fffffffffffffffep0L, 0x1p-128L);
|
||||
TEST_fff_f (fma, 0x0.ffffffffffffffffp0L, -0x0.ffffffffffffffffp0L, 0x0.fffffffffffffffep0L, -0x1p-128L);
|
||||
TEST_fff_f (fma, -0x0.ffffffffffffffffp0L, 0x0.ffffffffffffffffp0L, 0x0.fffffffffffffffep0L, -0x1p-128L);
|
||||
TEST_fff_f (fma, -0x0.ffffffffffffffffp0L, -0x0.ffffffffffffffffp0L, -0x0.fffffffffffffffep0L, 0x1p-128L);
|
||||
#endif
|
||||
#if defined (TEST_LDOUBLE) && LDBL_MANT_DIG == 113
|
||||
TEST_fff_f (fma, 0x1.4p-16382L, 0x1.0000000000000000000000000002p-1L, 0x1p-16384L, 0x1.c000000000000000000000000002p-16383L, UNDERFLOW_EXCEPTION);
|
||||
@ -4924,6 +4952,10 @@ fma_test_towardzero (void)
|
||||
TEST_fff_f (fma, 0x1p-16494L, -0x1p-16494L, 0x1p-16494L, plus_zero, UNDERFLOW_EXCEPTION);
|
||||
TEST_fff_f (fma, 0x1p-16494L, 0x1p-16494L, -0x1p-16494L, minus_zero, UNDERFLOW_EXCEPTION);
|
||||
TEST_fff_f (fma, 0x1p-16494L, -0x1p-16494L, -0x1p-16494L, -0x1p-16494L, UNDERFLOW_EXCEPTION);
|
||||
TEST_fff_f (fma, 0x0.ffffffffffffffffffffffffffff8p0L, 0x0.ffffffffffffffffffffffffffff8p0L, -0x0.ffffffffffffffffffffffffffffp0L, 0x1p-226L);
|
||||
TEST_fff_f (fma, 0x0.ffffffffffffffffffffffffffff8p0L, -0x0.ffffffffffffffffffffffffffff8p0L, 0x0.ffffffffffffffffffffffffffffp0L, -0x1p-226L);
|
||||
TEST_fff_f (fma, -0x0.ffffffffffffffffffffffffffff8p0L, 0x0.ffffffffffffffffffffffffffff8p0L, 0x0.ffffffffffffffffffffffffffffp0L, -0x1p-226L);
|
||||
TEST_fff_f (fma, -0x0.ffffffffffffffffffffffffffff8p0L, -0x0.ffffffffffffffffffffffffffff8p0L, -0x0.ffffffffffffffffffffffffffffp0L, 0x1p-226L);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -5007,6 +5039,10 @@ fma_test_downward (void)
|
||||
TEST_fff_f (fma, 0x1p-149, -0x1p-149, 0x1p-149, plus_zero, UNDERFLOW_EXCEPTION);
|
||||
TEST_fff_f (fma, 0x1p-149, 0x1p-149, -0x1p-149, -0x1p-149, UNDERFLOW_EXCEPTION);
|
||||
TEST_fff_f (fma, 0x1p-149, -0x1p-149, -0x1p-149, -0x1p-148, UNDERFLOW_EXCEPTION);
|
||||
TEST_fff_f (fma, 0x0.fffp0, 0x0.fffp0, -0x0.ffep0, 0x1p-24);
|
||||
TEST_fff_f (fma, 0x0.fffp0, -0x0.fffp0, 0x0.ffep0, -0x1p-24);
|
||||
TEST_fff_f (fma, -0x0.fffp0, 0x0.fffp0, 0x0.ffep0, -0x1p-24);
|
||||
TEST_fff_f (fma, -0x0.fffp0, -0x0.fffp0, -0x0.ffep0, 0x1p-24);
|
||||
#endif
|
||||
#if defined (TEST_DOUBLE) && DBL_MANT_DIG == 53
|
||||
TEST_fff_f (fma, 0x1.4p-1022, 0x1.0000000000002p-1, 0x1p-1024, 0x1.c000000000002p-1023, UNDERFLOW_EXCEPTION);
|
||||
@ -5033,6 +5069,10 @@ fma_test_downward (void)
|
||||
TEST_fff_f (fma, 0x1p-1074, -0x1p-1074, 0x1p-1074, plus_zero, UNDERFLOW_EXCEPTION);
|
||||
TEST_fff_f (fma, 0x1p-1074, 0x1p-1074, -0x1p-1074, -0x1p-1074, UNDERFLOW_EXCEPTION);
|
||||
TEST_fff_f (fma, 0x1p-1074, -0x1p-1074, -0x1p-1074, -0x1p-1073, UNDERFLOW_EXCEPTION);
|
||||
TEST_fff_f (fma, 0x0.fffffffffffff8p0, 0x0.fffffffffffff8p0, -0x0.fffffffffffffp0, 0x1p-106);
|
||||
TEST_fff_f (fma, 0x0.fffffffffffff8p0, -0x0.fffffffffffff8p0, 0x0.fffffffffffffp0, -0x1p-106);
|
||||
TEST_fff_f (fma, -0x0.fffffffffffff8p0, 0x0.fffffffffffff8p0, 0x0.fffffffffffffp0, -0x1p-106);
|
||||
TEST_fff_f (fma, -0x0.fffffffffffff8p0, -0x0.fffffffffffff8p0, -0x0.fffffffffffffp0, 0x1p-106);
|
||||
#endif
|
||||
#if defined (TEST_LDOUBLE) && LDBL_MANT_DIG == 64
|
||||
TEST_fff_f (fma, 0x1.4p-16382L, 0x1.0000000000000004p-1L, 0x1p-16384L, 0x1.c000000000000004p-16383L, UNDERFLOW_EXCEPTION);
|
||||
@ -5059,6 +5099,10 @@ fma_test_downward (void)
|
||||
TEST_fff_f (fma, 0x1p-16445L, -0x1p-16445L, 0x1p-16445L, plus_zero, UNDERFLOW_EXCEPTION);
|
||||
TEST_fff_f (fma, 0x1p-16445L, 0x1p-16445L, -0x1p-16445L, -0x1p-16445L, UNDERFLOW_EXCEPTION);
|
||||
TEST_fff_f (fma, 0x1p-16445L, -0x1p-16445L, -0x1p-16445L, -0x1p-16444L, UNDERFLOW_EXCEPTION);
|
||||
TEST_fff_f (fma, 0x0.ffffffffffffffffp0L, 0x0.ffffffffffffffffp0L, -0x0.fffffffffffffffep0L, 0x1p-128L);
|
||||
TEST_fff_f (fma, 0x0.ffffffffffffffffp0L, -0x0.ffffffffffffffffp0L, 0x0.fffffffffffffffep0L, -0x1p-128L);
|
||||
TEST_fff_f (fma, -0x0.ffffffffffffffffp0L, 0x0.ffffffffffffffffp0L, 0x0.fffffffffffffffep0L, -0x1p-128L);
|
||||
TEST_fff_f (fma, -0x0.ffffffffffffffffp0L, -0x0.ffffffffffffffffp0L, -0x0.fffffffffffffffep0L, 0x1p-128L);
|
||||
#endif
|
||||
#if defined (TEST_LDOUBLE) && LDBL_MANT_DIG == 113
|
||||
TEST_fff_f (fma, 0x1.4p-16382L, 0x1.0000000000000000000000000002p-1L, 0x1p-16384L, 0x1.c000000000000000000000000002p-16383L, UNDERFLOW_EXCEPTION);
|
||||
@ -5085,6 +5129,10 @@ fma_test_downward (void)
|
||||
TEST_fff_f (fma, 0x1p-16494L, -0x1p-16494L, 0x1p-16494L, plus_zero, UNDERFLOW_EXCEPTION);
|
||||
TEST_fff_f (fma, 0x1p-16494L, 0x1p-16494L, -0x1p-16494L, -0x1p-16494L, UNDERFLOW_EXCEPTION);
|
||||
TEST_fff_f (fma, 0x1p-16494L, -0x1p-16494L, -0x1p-16494L, -0x1p-16493L, UNDERFLOW_EXCEPTION);
|
||||
TEST_fff_f (fma, 0x0.ffffffffffffffffffffffffffff8p0L, 0x0.ffffffffffffffffffffffffffff8p0L, -0x0.ffffffffffffffffffffffffffffp0L, 0x1p-226L);
|
||||
TEST_fff_f (fma, 0x0.ffffffffffffffffffffffffffff8p0L, -0x0.ffffffffffffffffffffffffffff8p0L, 0x0.ffffffffffffffffffffffffffffp0L, -0x1p-226L);
|
||||
TEST_fff_f (fma, -0x0.ffffffffffffffffffffffffffff8p0L, 0x0.ffffffffffffffffffffffffffff8p0L, 0x0.ffffffffffffffffffffffffffffp0L, -0x1p-226L);
|
||||
TEST_fff_f (fma, -0x0.ffffffffffffffffffffffffffff8p0L, -0x0.ffffffffffffffffffffffffffff8p0L, -0x0.ffffffffffffffffffffffffffffp0L, 0x1p-226L);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -5168,6 +5216,10 @@ fma_test_upward (void)
|
||||
TEST_fff_f (fma, 0x1p-149, -0x1p-149, 0x1p-149, 0x1p-149, UNDERFLOW_EXCEPTION);
|
||||
TEST_fff_f (fma, 0x1p-149, 0x1p-149, -0x1p-149, minus_zero, UNDERFLOW_EXCEPTION);
|
||||
TEST_fff_f (fma, 0x1p-149, -0x1p-149, -0x1p-149, -0x1p-149, UNDERFLOW_EXCEPTION);
|
||||
TEST_fff_f (fma, 0x0.fffp0, 0x0.fffp0, -0x0.ffep0, 0x1p-24);
|
||||
TEST_fff_f (fma, 0x0.fffp0, -0x0.fffp0, 0x0.ffep0, -0x1p-24);
|
||||
TEST_fff_f (fma, -0x0.fffp0, 0x0.fffp0, 0x0.ffep0, -0x1p-24);
|
||||
TEST_fff_f (fma, -0x0.fffp0, -0x0.fffp0, -0x0.ffep0, 0x1p-24);
|
||||
#endif
|
||||
#if defined (TEST_DOUBLE) && DBL_MANT_DIG == 53
|
||||
TEST_fff_f (fma, 0x1.4p-1022, 0x1.0000000000002p-1, 0x1p-1024, 0x1.c000000000004p-1023, UNDERFLOW_EXCEPTION);
|
||||
@ -5194,6 +5246,10 @@ fma_test_upward (void)
|
||||
TEST_fff_f (fma, 0x1p-1074, -0x1p-1074, 0x1p-1074, 0x1p-1074, UNDERFLOW_EXCEPTION);
|
||||
TEST_fff_f (fma, 0x1p-1074, 0x1p-1074, -0x1p-1074, minus_zero, UNDERFLOW_EXCEPTION);
|
||||
TEST_fff_f (fma, 0x1p-1074, -0x1p-1074, -0x1p-1074, -0x1p-1074, UNDERFLOW_EXCEPTION);
|
||||
TEST_fff_f (fma, 0x0.fffffffffffff8p0, 0x0.fffffffffffff8p0, -0x0.fffffffffffffp0, 0x1p-106);
|
||||
TEST_fff_f (fma, 0x0.fffffffffffff8p0, -0x0.fffffffffffff8p0, 0x0.fffffffffffffp0, -0x1p-106);
|
||||
TEST_fff_f (fma, -0x0.fffffffffffff8p0, 0x0.fffffffffffff8p0, 0x0.fffffffffffffp0, -0x1p-106);
|
||||
TEST_fff_f (fma, -0x0.fffffffffffff8p0, -0x0.fffffffffffff8p0, -0x0.fffffffffffffp0, 0x1p-106);
|
||||
#endif
|
||||
#if defined (TEST_LDOUBLE) && LDBL_MANT_DIG == 64
|
||||
TEST_fff_f (fma, 0x1.4p-16382L, 0x1.0000000000000004p-1L, 0x1p-16384L, 0x1.c000000000000008p-16383L, UNDERFLOW_EXCEPTION);
|
||||
@ -5220,6 +5276,10 @@ fma_test_upward (void)
|
||||
TEST_fff_f (fma, 0x1p-16445L, -0x1p-16445L, 0x1p-16445L, 0x1p-16445L, UNDERFLOW_EXCEPTION);
|
||||
TEST_fff_f (fma, 0x1p-16445L, 0x1p-16445L, -0x1p-16445L, minus_zero, UNDERFLOW_EXCEPTION);
|
||||
TEST_fff_f (fma, 0x1p-16445L, -0x1p-16445L, -0x1p-16445L, -0x1p-16445L, UNDERFLOW_EXCEPTION);
|
||||
TEST_fff_f (fma, 0x0.ffffffffffffffffp0L, 0x0.ffffffffffffffffp0L, -0x0.fffffffffffffffep0L, 0x1p-128L);
|
||||
TEST_fff_f (fma, 0x0.ffffffffffffffffp0L, -0x0.ffffffffffffffffp0L, 0x0.fffffffffffffffep0L, -0x1p-128L);
|
||||
TEST_fff_f (fma, -0x0.ffffffffffffffffp0L, 0x0.ffffffffffffffffp0L, 0x0.fffffffffffffffep0L, -0x1p-128L);
|
||||
TEST_fff_f (fma, -0x0.ffffffffffffffffp0L, -0x0.ffffffffffffffffp0L, -0x0.fffffffffffffffep0L, 0x1p-128L);
|
||||
#endif
|
||||
#if defined (TEST_LDOUBLE) && LDBL_MANT_DIG == 113
|
||||
TEST_fff_f (fma, 0x1.4p-16382L, 0x1.0000000000000000000000000002p-1L, 0x1p-16384L, 0x1.c000000000000000000000000004p-16383L, UNDERFLOW_EXCEPTION);
|
||||
@ -5246,6 +5306,10 @@ fma_test_upward (void)
|
||||
TEST_fff_f (fma, 0x1p-16494L, -0x1p-16494L, 0x1p-16494L, 0x1p-16494L, UNDERFLOW_EXCEPTION);
|
||||
TEST_fff_f (fma, 0x1p-16494L, 0x1p-16494L, -0x1p-16494L, minus_zero, UNDERFLOW_EXCEPTION);
|
||||
TEST_fff_f (fma, 0x1p-16494L, -0x1p-16494L, -0x1p-16494L, -0x1p-16494L, UNDERFLOW_EXCEPTION);
|
||||
TEST_fff_f (fma, 0x0.ffffffffffffffffffffffffffff8p0L, 0x0.ffffffffffffffffffffffffffff8p0L, -0x0.ffffffffffffffffffffffffffffp0L, 0x1p-226L);
|
||||
TEST_fff_f (fma, 0x0.ffffffffffffffffffffffffffff8p0L, -0x0.ffffffffffffffffffffffffffff8p0L, 0x0.ffffffffffffffffffffffffffffp0L, -0x1p-226L);
|
||||
TEST_fff_f (fma, -0x0.ffffffffffffffffffffffffffff8p0L, 0x0.ffffffffffffffffffffffffffff8p0L, 0x0.ffffffffffffffffffffffffffffp0L, -0x1p-226L);
|
||||
TEST_fff_f (fma, -0x0.ffffffffffffffffffffffffffff8p0L, -0x0.ffffffffffffffffffffffffffff8p0L, -0x0.ffffffffffffffffffffffffffffp0L, 0x1p-226L);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,8 @@
|
||||
2012-11-03 Joseph Myers <joseph@codesourcery.com>
|
||||
|
||||
* sysdeps/alpha/fpu/fclrexcpt.c (feclearexcept): Add
|
||||
libm_hidden_ver.
|
||||
|
||||
[BZ #3439]
|
||||
* sysdeps/alpha/fpu/bits/fenv.h (FE_DENORMAL): Define macro to
|
||||
integer constant usable in #if and use that to give value to enum
|
||||
|
@ -1,5 +1,8 @@
|
||||
2012-11-03 Joseph Myers <joseph@codesourcery.com>
|
||||
|
||||
* sysdeps/am33/fpu/fclrexcpt.c (feclearexcept): Add
|
||||
libm_hidden_ver.
|
||||
|
||||
[BZ #3439]
|
||||
* sysdeps/am33/fpu/bits/fenv.h (FE_INEXACT): Define macro to
|
||||
integer constant usable in #if and use that to give value to enum
|
||||
|
@ -1,5 +1,7 @@
|
||||
2012-11-03 Joseph Myers <joseph@codesourcery.com>
|
||||
|
||||
* sysdeps/arm/fclrexcpt.c (feclearexcept): Add libm_hidden_ver.
|
||||
|
||||
[BZ #3439]
|
||||
* sysdeps/arm/bits/fenv.h (FE_INVALID): Define macro to integer
|
||||
constant usable in #if and use that to give value to enum
|
||||
|
@ -1,5 +1,8 @@
|
||||
2012-11-03 Joseph Myers <joseph@codesourcery.com>
|
||||
|
||||
* sysdeps/hppa/fpu/fclrexcpt.c (feclearexcept): Add
|
||||
libm_hidden_def.
|
||||
|
||||
[BZ #3439]
|
||||
* sysdeps/hppa/fpu/bits/fenv.h (FE_INVALID): Define macro to
|
||||
integer constant usable in #if and use that to give value to enum
|
||||
|
@ -1,5 +1,8 @@
|
||||
2012-11-03 Joseph Myers <joseph@codesourcery.com>
|
||||
|
||||
* sysdeps/ia64/fpu/fclrexcpt.c (feclearexcept): Add
|
||||
libm_hidden_def.
|
||||
|
||||
[BZ #3439]
|
||||
* sysdeps/ia64/bits/fenv.h (FE_INEXACT): Define macro to integer
|
||||
constant usable in #if and use that to give value to enum
|
||||
|
@ -1,5 +1,8 @@
|
||||
2012-11-03 Joseph Myers <joseph@codesourcery.com>
|
||||
|
||||
* sysdeps/m68k/fpu/fclrexcpt.c (feclearexcept): Add
|
||||
libm_hidden_ver.
|
||||
|
||||
[BZ #3439]
|
||||
* sysdeps/m68k/fpu/bits/fenv.h (FE_INEXACT): Define macro to
|
||||
integer constant usable in #if and use that to give value to enum
|
||||
|
@ -1,5 +1,8 @@
|
||||
2012-11-03 Joseph Myers <joseph@codesourcery.com>
|
||||
|
||||
* sysdeps/mips/fpu/fclrexcpt.c (feclearexcept): Add
|
||||
libm_hidden_def.
|
||||
|
||||
[BZ #3439]
|
||||
* sysdeps/mips/bits/fenv.h (FE_INEXACT): Define macro to integer
|
||||
constant usable in #if and use that to give value to enum
|
||||
|
@ -1,3 +1,8 @@
|
||||
2012-11-03 Joseph Myers <joseph@codesourcery.com>
|
||||
|
||||
* sysdeps/powerpc/nofpu/fclrexcpt.c (feclearexcept): Add
|
||||
libm_hidden_ver.
|
||||
|
||||
2012-10-31 Andreas Schwab <schwab@linux-m68k.org>
|
||||
|
||||
* sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/nptl/libc.abilist:
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Clear given exceptions in current floating-point environment.
|
||||
Copyright (C) 1997,99,2000,01 Free Software Foundation, Inc.
|
||||
Copyright (C) 1997-2012 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Richard Henderson <rth@tamu.edu>, 1997.
|
||||
|
||||
@ -43,4 +43,5 @@ strong_alias (__feclearexcept, __old_feclearexcept)
|
||||
compat_symbol (libm, __old_feclearexcept, feclearexcept, GLIBC_2_1);
|
||||
#endif
|
||||
|
||||
libm_hidden_ver (__feclearexcept, feclearexcept)
|
||||
versioned_symbol (libm, __feclearexcept, feclearexcept, GLIBC_2_2);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Clear given exceptions in current floating-point environment.
|
||||
Copyright (C) 1998, 1999, 2000, 2002, 2004 Free Software Foundation, Inc.
|
||||
Copyright (C) 1998-2012 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Alexandre Oliva <aoliva@redhat.com>
|
||||
based on corresponding file in the MIPS port.
|
||||
@ -48,4 +48,5 @@ __feclearexcept (int excepts)
|
||||
return 0;
|
||||
}
|
||||
|
||||
libm_hidden_ver (__feclearexcept, feclearexcept)
|
||||
versioned_symbol (libm, __feclearexcept, feclearexcept, GLIBC_2_2);
|
||||
|
@ -54,4 +54,5 @@ strong_alias (__feclearexcept, __old_feclearexcept)
|
||||
compat_symbol (libm, __old_feclearexcept, feclearexcept, GLIBC_2_1);
|
||||
#endif
|
||||
|
||||
libm_hidden_ver (__feclearexcept, feclearexcept)
|
||||
versioned_symbol (libm, __feclearexcept, feclearexcept, GLIBC_2_2);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Clear given exceptions in current floating-point environment.
|
||||
Copyright (C) 2000 Free Software Foundation, Inc.
|
||||
Copyright (C) 2000-2012 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by David Huggins-Daines <dhd@debian.org>, 2000
|
||||
|
||||
@ -33,3 +33,4 @@ feclearexcept (int excepts)
|
||||
/* Success. */
|
||||
return 0;
|
||||
}
|
||||
libm_hidden_def (feclearexcept)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Clear given exceptions in current floating-point environment.
|
||||
Copyright (C) 1997, 1999, 2000 Free Software Foundation, Inc.
|
||||
Copyright (C) 1997-2012 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Christian Boissat <Christian.Boissat@cern.ch>, 1999 and
|
||||
Jes Sorensen <Jes.Sorensen@cern.ch>, 2000
|
||||
@ -36,3 +36,4 @@ feclearexcept (int excepts)
|
||||
/* success */
|
||||
return 0;
|
||||
}
|
||||
libm_hidden_def (feclearexcept)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Clear given exceptions in current floating-point environment.
|
||||
Copyright (C) 1997,99,2000,01 Free Software Foundation, Inc.
|
||||
Copyright (C) 1997-2012 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
|
||||
|
||||
@ -46,4 +46,5 @@ strong_alias (__feclearexcept, __old_feclearexcept)
|
||||
compat_symbol (libm, __old_feclearexcept, feclearexcept, GLIBC_2_1);
|
||||
#endif
|
||||
|
||||
libm_hidden_ver (__feclearexcept, feclearexcept)
|
||||
versioned_symbol (libm, __feclearexcept, feclearexcept, GLIBC_2_2);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Clear given exceptions in current floating-point environment.
|
||||
Copyright (C) 1998, 1999, 2000, 2002 Free Software Foundation, Inc.
|
||||
Copyright (C) 1998-2012 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Andreas Jaeger <aj@suse.de>, 1998.
|
||||
|
||||
@ -44,3 +44,4 @@ feclearexcept (int excepts)
|
||||
/* Success. */
|
||||
return 0;
|
||||
}
|
||||
libm_hidden_def (feclearexcept)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Clear floating-point exceptions (soft-float edition).
|
||||
Copyright (C) 2002 Free Software Foundation, Inc.
|
||||
Copyright (C) 2002-2012 Free Software Foundation, Inc.
|
||||
Contributed by Aldy Hernandez <aldyh@redhat.com>, 2002.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
@ -33,4 +33,5 @@ strong_alias (__feclearexcept, __old_feclearexcept)
|
||||
compat_symbol (libm, __old_feclearexcept, feclearexcept, GLIBC_2_1);
|
||||
#endif
|
||||
|
||||
libm_hidden_ver (__feclearexcept, feclearexcept)
|
||||
versioned_symbol (libm, __feclearexcept, feclearexcept, GLIBC_2_2);
|
||||
|
@ -401,6 +401,22 @@ default_libc_feholdexcept (fenv_t *e)
|
||||
# define libc_feholdexceptl default_libc_feholdexcept
|
||||
#endif
|
||||
|
||||
static __always_inline void
|
||||
default_libc_fesetround (int r)
|
||||
{
|
||||
(void) fesetround (r);
|
||||
}
|
||||
|
||||
#ifndef libc_fesetround
|
||||
# define libc_fesetround default_libc_fesetround
|
||||
#endif
|
||||
#ifndef libc_fesetroundf
|
||||
# define libc_fesetroundf default_libc_fesetround
|
||||
#endif
|
||||
#ifndef libc_fesetroundl
|
||||
# define libc_fesetroundl default_libc_fesetround
|
||||
#endif
|
||||
|
||||
static __always_inline void
|
||||
default_libc_feholdexcept_setround (fenv_t *e, int r)
|
||||
{
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Clear given exceptions in current floating-point environment.
|
||||
Copyright (C) 1997,99,2000, 2001, 2003, 2004 Free Software Foundation, Inc.
|
||||
Copyright (C) 1997-2012 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
|
||||
|
||||
@ -65,4 +65,5 @@ strong_alias (__feclearexcept, __old_feclearexcept)
|
||||
compat_symbol (libm, __old_feclearexcept, feclearexcept, GLIBC_2_1);
|
||||
#endif
|
||||
|
||||
libm_hidden_ver (__feclearexcept, feclearexcept)
|
||||
versioned_symbol (libm, __feclearexcept, feclearexcept, GLIBC_2_2);
|
||||
|
@ -76,6 +76,24 @@ libc_feholdexcept_387 (fenv_t *e)
|
||||
"st(4)", "st(5)", "st(6)", "st(7)");
|
||||
}
|
||||
|
||||
static __always_inline void
|
||||
libc_fesetround_sse (int r)
|
||||
{
|
||||
unsigned int mxcsr;
|
||||
asm (STMXCSR " %0" : "=m" (*&mxcsr));
|
||||
mxcsr = (mxcsr & ~0x6000) | (r << 3);
|
||||
asm volatile (LDMXCSR " %0" : : "m" (*&mxcsr));
|
||||
}
|
||||
|
||||
static __always_inline void
|
||||
libc_fesetround_387 (int r)
|
||||
{
|
||||
fpu_control_t cw;
|
||||
_FPU_GETCW (cw);
|
||||
cw = (cw & ~0xc00) | r;
|
||||
_FPU_SETCW (cw);
|
||||
}
|
||||
|
||||
static __always_inline void
|
||||
libc_feholdexcept_setround_sse (fenv_t *e, int r)
|
||||
{
|
||||
@ -247,6 +265,7 @@ libc_feresetround_387 (fenv_t *e)
|
||||
|
||||
#ifdef __SSE_MATH__
|
||||
# define libc_feholdexceptf libc_feholdexcept_sse
|
||||
# define libc_fesetroundf libc_fesetround_sse
|
||||
# define libc_feholdexcept_setroundf libc_feholdexcept_setround_sse
|
||||
# define libc_fetestexceptf libc_fetestexcept_sse
|
||||
# define libc_fesetenvf libc_fesetenv_sse
|
||||
@ -256,6 +275,7 @@ libc_feresetround_387 (fenv_t *e)
|
||||
# define libc_feresetroundf libc_feresetround_sse
|
||||
#else
|
||||
# define libc_feholdexceptf libc_feholdexcept_387
|
||||
# define libc_fesetroundf libc_fesetround_387
|
||||
# define libc_feholdexcept_setroundf libc_feholdexcept_setround_387
|
||||
# define libc_fetestexceptf libc_fetestexcept_387
|
||||
# define libc_fesetenvf libc_fesetenv_387
|
||||
@ -267,6 +287,7 @@ libc_feresetround_387 (fenv_t *e)
|
||||
|
||||
#ifdef __SSE2_MATH__
|
||||
# define libc_feholdexcept libc_feholdexcept_sse
|
||||
# define libc_fesetround libc_fesetround_sse
|
||||
# define libc_feholdexcept_setround libc_feholdexcept_setround_sse
|
||||
# define libc_fetestexcept libc_fetestexcept_sse
|
||||
# define libc_fesetenv libc_fesetenv_sse
|
||||
@ -276,6 +297,7 @@ libc_feresetround_387 (fenv_t *e)
|
||||
# define libc_feresetround libc_feresetround_sse
|
||||
#else
|
||||
# define libc_feholdexcept libc_feholdexcept_387
|
||||
# define libc_fesetround libc_fesetround_387
|
||||
# define libc_feholdexcept_setround libc_feholdexcept_setround_387
|
||||
# define libc_fetestexcept libc_fetestexcept_387
|
||||
# define libc_fesetenv libc_fesetenv_387
|
||||
@ -286,6 +308,7 @@ libc_feresetround_387 (fenv_t *e)
|
||||
#endif /* __SSE2_MATH__ */
|
||||
|
||||
#define libc_feholdexceptl libc_feholdexcept_387
|
||||
#define libc_fesetroundl libc_fesetround_387
|
||||
#define libc_feholdexcept_setroundl libc_feholdexcept_setround_387
|
||||
#define libc_fetestexceptl libc_fetestexcept_387
|
||||
#define libc_fesetenvl libc_fesetenv_387
|
||||
|
@ -167,6 +167,9 @@ __fma (double x, double y, double z)
|
||||
if (__builtin_expect ((x == 0 || y == 0) && z == 0, 0))
|
||||
return x * y + z;
|
||||
|
||||
fenv_t env;
|
||||
libc_feholdexcept_setround (&env, FE_TONEAREST);
|
||||
|
||||
/* Multiplication m1 + m2 = x * y using Dekker's algorithm. */
|
||||
#define C ((1 << (DBL_MANT_DIG + 1) / 2) + 1)
|
||||
double x1 = x * C;
|
||||
@ -185,9 +188,20 @@ __fma (double x, double y, double z)
|
||||
t1 = m1 - t1;
|
||||
t2 = z - t2;
|
||||
double a2 = t1 + t2;
|
||||
feclearexcept (FE_INEXACT);
|
||||
|
||||
fenv_t env;
|
||||
libc_feholdexcept_setround (&env, FE_TOWARDZERO);
|
||||
/* If the result is an exact zero, ensure it has the correct
|
||||
sign. */
|
||||
if (a1 == 0 && m2 == 0)
|
||||
{
|
||||
libc_feupdateenv (&env);
|
||||
/* Ensure that round-to-nearest value of z + m1 is not
|
||||
reused. */
|
||||
asm volatile ("" : "=m" (z) : "m" (z));
|
||||
return z + m1;
|
||||
}
|
||||
|
||||
libc_fesetround (FE_TOWARDZERO);
|
||||
|
||||
/* Perform m2 + a2 addition with round to odd. */
|
||||
u.d = a2 + m2;
|
||||
|
@ -170,6 +170,10 @@ __fmal (long double x, long double y, long double z)
|
||||
if (__builtin_expect ((x == 0 || y == 0) && z == 0, 0))
|
||||
return x * y + z;
|
||||
|
||||
fenv_t env;
|
||||
feholdexcept (&env);
|
||||
fesetround (FE_TONEAREST);
|
||||
|
||||
/* Multiplication m1 + m2 = x * y using Dekker's algorithm. */
|
||||
#define C ((1LL << (LDBL_MANT_DIG + 1) / 2) + 1)
|
||||
long double x1 = x * C;
|
||||
@ -188,9 +192,19 @@ __fmal (long double x, long double y, long double z)
|
||||
t1 = m1 - t1;
|
||||
t2 = z - t2;
|
||||
long double a2 = t1 + t2;
|
||||
feclearexcept (FE_INEXACT);
|
||||
|
||||
/* If the result is an exact zero, ensure it has the correct
|
||||
sign. */
|
||||
if (a1 == 0 && m2 == 0)
|
||||
{
|
||||
feupdateenv (&env);
|
||||
/* Ensure that round-to-nearest value of z + m1 is not
|
||||
reused. */
|
||||
asm volatile ("" : "=m" (z) : "m" (z));
|
||||
return z + m1;
|
||||
}
|
||||
|
||||
fenv_t env;
|
||||
feholdexcept (&env);
|
||||
fesetround (FE_TOWARDZERO);
|
||||
/* Perform m2 + a2 addition with round to odd. */
|
||||
u.d = a2 + m2;
|
||||
|
@ -42,6 +42,10 @@ __fma (double x, double y, double z)
|
||||
if (__builtin_expect ((x == 0 || y == 0) && z == 0, 0))
|
||||
return x * y + z;
|
||||
|
||||
fenv_t env;
|
||||
feholdexcept (&env);
|
||||
fesetround (FE_TONEAREST);
|
||||
|
||||
/* Multiplication m1 + m2 = x * y using Dekker's algorithm. */
|
||||
#define C ((1ULL << (LDBL_MANT_DIG + 1) / 2) + 1)
|
||||
long double x1 = (long double) x * C;
|
||||
@ -60,9 +64,19 @@ __fma (double x, double y, double z)
|
||||
t1 = m1 - t1;
|
||||
t2 = z - t2;
|
||||
long double a2 = t1 + t2;
|
||||
feclearexcept (FE_INEXACT);
|
||||
|
||||
/* If the result is an exact zero, ensure it has the correct
|
||||
sign. */
|
||||
if (a1 == 0 && m2 == 0)
|
||||
{
|
||||
feupdateenv (&env);
|
||||
/* Ensure that round-to-nearest value of z + m1 is not
|
||||
reused. */
|
||||
asm volatile ("" : "=m" (z) : "m" (z));
|
||||
return z + m1;
|
||||
}
|
||||
|
||||
fenv_t env;
|
||||
feholdexcept (&env);
|
||||
fesetround (FE_TOWARDZERO);
|
||||
/* Perform m2 + a2 addition with round to odd. */
|
||||
a2 = a2 + m2;
|
||||
|
@ -168,6 +168,10 @@ __fmal (long double x, long double y, long double z)
|
||||
if (__builtin_expect ((x == 0 || y == 0) && z == 0, 0))
|
||||
return x * y + z;
|
||||
|
||||
fenv_t env;
|
||||
feholdexcept (&env);
|
||||
fesetround (FE_TONEAREST);
|
||||
|
||||
/* Multiplication m1 + m2 = x * y using Dekker's algorithm. */
|
||||
#define C ((1LL << (LDBL_MANT_DIG + 1) / 2) + 1)
|
||||
long double x1 = x * C;
|
||||
@ -186,9 +190,19 @@ __fmal (long double x, long double y, long double z)
|
||||
t1 = m1 - t1;
|
||||
t2 = z - t2;
|
||||
long double a2 = t1 + t2;
|
||||
feclearexcept (FE_INEXACT);
|
||||
|
||||
/* If the result is an exact zero, ensure it has the correct
|
||||
sign. */
|
||||
if (a1 == 0 && m2 == 0)
|
||||
{
|
||||
feupdateenv (&env);
|
||||
/* Ensure that round-to-nearest value of z + m1 is not
|
||||
reused. */
|
||||
asm volatile ("" : "=m" (z) : "m" (z));
|
||||
return z + m1;
|
||||
}
|
||||
|
||||
fenv_t env;
|
||||
feholdexcept (&env);
|
||||
fesetround (FE_TOWARDZERO);
|
||||
/* Perform m2 + a2 addition with round to odd. */
|
||||
u.d = a2 + m2;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Clear given exceptions in current floating-point environment.
|
||||
Copyright (C) 1997,99,2000,01 Free Software Foundation, Inc.
|
||||
Copyright (C) 1997-2012 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
@ -44,4 +44,5 @@ strong_alias (__feclearexcept, __old_feclearexcept)
|
||||
compat_symbol (libm, __old_feclearexcept, feclearexcept, GLIBC_2_1);
|
||||
#endif
|
||||
|
||||
libm_hidden_ver (__feclearexcept, feclearexcept)
|
||||
versioned_symbol (libm, __feclearexcept, feclearexcept, GLIBC_2_2);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Clear given exceptions in current floating-point environment.
|
||||
Copyright (C) 2000 Free Software Foundation, Inc.
|
||||
Copyright (C) 2000-2012 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
@ -37,3 +37,4 @@ feclearexcept (int excepts)
|
||||
/* Success. */
|
||||
return 0;
|
||||
}
|
||||
libm_hidden_def (feclearexcept)
|
||||
|
@ -39,3 +39,4 @@ feclearexcept (int excepts)
|
||||
|
||||
return 0;
|
||||
}
|
||||
libm_hidden_def (feclearexcept)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Clear given exceptions in current floating-point environment.
|
||||
Copyright (C) 1997, 1999, 2000 Free Software Foundation, Inc.
|
||||
Copyright (C) 1997-2012 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
@ -39,4 +39,5 @@ strong_alias (__feclearexcept, __old_feclearexcept)
|
||||
compat_symbol (libm, __old_feclearexcept, feclearexcept, GLIBC_2_1);
|
||||
#endif
|
||||
|
||||
libm_hidden_ver (__feclearexcept, feclearexcept)
|
||||
versioned_symbol (libm, __feclearexcept, feclearexcept, GLIBC_2_2);
|
||||
|
@ -13,6 +13,15 @@ libc_feholdexcept (fenv_t *e)
|
||||
__fenv_ldfsr(etmp);
|
||||
}
|
||||
|
||||
static __always_inline void
|
||||
libc_fesetround (int r)
|
||||
{
|
||||
fenv_t etmp;
|
||||
__fenv_stfsr(etmp);
|
||||
etmp = (etmp & ~__FE_ROUND_MASK) | (r);
|
||||
__fenv_ldfsr(etmp);
|
||||
}
|
||||
|
||||
static __always_inline void
|
||||
libc_feholdexcept_setround (fenv_t *e, int r)
|
||||
{
|
||||
@ -79,6 +88,7 @@ libc_feresetround (fenv_t *e)
|
||||
}
|
||||
|
||||
#define libc_feholdexceptf libc_feholdexcept
|
||||
#define libc_fesetroundf libc_fesetround
|
||||
#define libc_feholdexcept_setroundf libc_feholdexcept_setround
|
||||
#define libc_fetestexceptf libc_fetestexcept
|
||||
#define libc_fesetenvf libc_fesetenv
|
||||
@ -87,6 +97,7 @@ libc_feresetround (fenv_t *e)
|
||||
#define libc_feholdsetroundf libc_feholdsetround
|
||||
#define libc_feresetroundf libc_feresetround
|
||||
#define libc_feholdexcept libc_feholdexcept
|
||||
#define libc_fesetround libc_fesetround
|
||||
#define libc_feholdexcept_setround libc_feholdexcept_setround
|
||||
#define libc_fetestexcept libc_fetestexcept
|
||||
#define libc_fesetenv libc_fesetenv
|
||||
@ -95,6 +106,7 @@ libc_feresetround (fenv_t *e)
|
||||
#define libc_feholdsetround libc_feholdsetround
|
||||
#define libc_feresetround libc_feresetround
|
||||
#define libc_feholdexceptl libc_feholdexcept
|
||||
#define libc_fesetroundl libc_fesetround
|
||||
#define libc_feholdexcept_setroundl libc_feholdexcept_setround
|
||||
#define libc_fetestexceptl libc_fetestexcept
|
||||
#define libc_fesetenvl libc_fesetenv
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Clear given exceptions in current floating-point environment.
|
||||
Copyright (C) 2001 Free Software Foundation, Inc.
|
||||
Copyright (C) 2001-2012 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
@ -49,3 +49,4 @@ feclearexcept (int excepts)
|
||||
/* Success. */
|
||||
return 0;
|
||||
}
|
||||
libm_hidden_def (feclearexcept)
|
||||
|
Loading…
Reference in New Issue
Block a user