diff options
-rw-r--r-- | ChangeLog | 12 | ||||
-rw-r--r-- | NEWS | 24 | ||||
-rw-r--r-- | math/Makefile | 2 | ||||
-rw-r--r-- | math/test-nearbyint-except.c | 82 | ||||
-rw-r--r-- | sysdeps/i386/fpu/s_nearbyint.S | 23 | ||||
-rw-r--r-- | sysdeps/i386/fpu/s_nearbyintf.S | 23 | ||||
-rw-r--r-- | sysdeps/i386/fpu/s_nearbyintl.S | 26 | ||||
-rw-r--r-- | sysdeps/x86_64/fpu/s_nearbyintl.S | 14 |
8 files changed, 145 insertions, 61 deletions
diff --git a/ChangeLog b/ChangeLog index b6fea8ec16..ab42228a0c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2015-10-22 Joseph Myers <joseph@codesourcery.com> + + [BZ #15491] + * sysdeps/i386/fpu/s_nearbyint.S (__nearbyint): Save and restore + floating-point environment instead of clearing all exceptions. + * sysdeps/i386/fpu/s_nearbyintf.S (__nearbyintf): Likewise. + * sysdeps/i386/fpu/s_nearbyintl.S (__nearbyintl): Likewise, + merging in "invalid" exceptions from frndint. + * sysdeps/x86_64/fpu/s_nearbyintl.S (__nearbyintl): Likewise. + * math/test-nearbyint-except.c: New file. + * math/Makefile (tests): Add test-nearbyint-except. + 2015-10-22 Chris Metcalf <cmetcalf@ezchip.com> * NEWS: Mention bug 18699 fixed by commit fe8c2b33aed0. diff --git a/NEWS b/NEWS index 00e3b03e5e..77534b941c 100644 --- a/NEWS +++ b/NEWS @@ -10,18 +10,18 @@ Version 2.23 * The following bugs are resolved with this release: 887, 2542, 2543, 2558, 2898, 4404, 6803, 10432, 14341, 14912, 15367, - 15384, 15470, 15786, 15918, 16141, 16296, 16347, 16399, 16415, 16422, - 16517, 16519, 16520, 16521, 16620, 16734, 16973, 16985, 17118, 17243, - 17244, 17250, 17441, 17787, 17886, 17887, 17905, 18084, 18086, 18240, - 18265, 18370, 18421, 18480, 18525, 18595, 18589, 18610, 18618, 18647, - 18661, 18674, 18675, 18681, 18699, 18724, 18743, 18757, 18778, 18781, - 18787, 18789, 18790, 18795, 18796, 18803, 18820, 18823, 18824, 18825, - 18857, 18863, 18870, 18872, 18873, 18875, 18887, 18918, 18921, 18928, - 18951, 18952, 18953, 18956, 18961, 18966, 18967, 18969, 18970, 18977, - 18980, 18981, 18982, 18985, 19003, 19007, 19012, 19016, 19018, 19032, - 19046, 19049, 19050, 19059, 19071, 19074, 19076, 19077, 19078, 19079, - 19085, 19086, 19088, 19094, 19095, 19124, 19125, 19129, 19134, 19137, - 19156. + 15384, 15470, 15491, 15786, 15918, 16141, 16296, 16347, 16399, 16415, + 16422, 16517, 16519, 16520, 16521, 16620, 16734, 16973, 16985, 17118, + 17243, 17244, 17250, 17441, 17787, 17886, 17887, 17905, 18084, 18086, + 18240, 18265, 18370, 18421, 18480, 18525, 18595, 18589, 18610, 18618, + 18647, 18661, 18674, 18675, 18681, 18699, 18724, 18743, 18757, 18778, + 18781, 18787, 18789, 18790, 18795, 18796, 18803, 18820, 18823, 18824, + 18825, 18857, 18863, 18870, 18872, 18873, 18875, 18887, 18918, 18921, + 18928, 18951, 18952, 18953, 18956, 18961, 18966, 18967, 18969, 18970, + 18977, 18980, 18981, 18982, 18985, 19003, 19007, 19012, 19016, 19018, + 19032, 19046, 19049, 19050, 19059, 19071, 19074, 19076, 19077, 19078, + 19079, 19085, 19086, 19088, 19094, 19095, 19124, 19125, 19129, 19134, + 19137, 19156. * There is now a --disable-timezone-tools configure option for disabling the building and installing of the timezone related utilities (zic, zdump, and diff --git a/math/Makefile b/math/Makefile index 8a2620919f..97004f956b 100644 --- a/math/Makefile +++ b/math/Makefile @@ -108,7 +108,7 @@ tests = test-matherr test-fenv atest-exp atest-sincos atest-exp2 basic-test \ test-tgmath-ret bug-nextafter bug-nexttoward bug-tgmath1 \ test-tgmath-int test-tgmath2 test-powl tst-CMPLX tst-CMPLX2 test-snan \ test-fenv-tls test-fenv-preserve test-fenv-return test-fenvinline \ - $(tests-static) + test-nearbyint-except $(tests-static) tests-static = test-fpucw-static test-fpucw-ieee-static # We do the `long double' tests only if this data type is available and # distinct from `double'. diff --git a/math/test-nearbyint-except.c b/math/test-nearbyint-except.c new file mode 100644 index 0000000000..86491eda58 --- /dev/null +++ b/math/test-nearbyint-except.c @@ -0,0 +1,82 @@ +/* Test nearbyint functions do not clear exceptions (bug 15491). + Copyright (C) 2015 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 + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <fenv.h> +#include <math.h> +#include <stdio.h> + +#include <math-tests.h> + +#ifndef FE_INVALID +# define FE_INVALID 0 +#endif + +#define TEST_FUNC(NAME, FLOAT, SUFFIX) \ +static int \ +NAME (void) \ +{ \ + int result = 0; \ + volatile FLOAT a, b __attribute__ ((unused)); \ + a = 1.0; \ + /* nearbyint must not clear already-raised exceptions. */ \ + feraiseexcept (FE_ALL_EXCEPT); \ + b = nearbyint ## SUFFIX (a); \ + if (fetestexcept (FE_ALL_EXCEPT) == FE_ALL_EXCEPT) \ + puts ("PASS: " #FLOAT); \ + else \ + { \ + puts ("FAIL: " #FLOAT); \ + result = 1; \ + } \ + /* But it mustn't lose exceptions from sNaN arguments. */ \ + if (SNAN_TESTS (FLOAT) && EXCEPTION_TESTS (FLOAT)) \ + { \ + static volatile FLOAT snan = __builtin_nans ## SUFFIX (""); \ + volatile FLOAT c __attribute__ ((unused)); \ + feclearexcept (FE_ALL_EXCEPT); \ + c = nearbyint ## SUFFIX (snan); \ + if (fetestexcept (FE_INVALID) == FE_INVALID) \ + puts ("PASS: " #FLOAT " sNaN"); \ + else \ + { \ + puts ("FAIL: " #FLOAT " sNaN"); \ + result = 1; \ + } \ + } \ + return result; \ +} + +TEST_FUNC (float_test, float, f) +TEST_FUNC (double_test, double, ) +#ifndef NO_LONG_DOUBLE +TEST_FUNC (ldouble_test, long double, l) +#endif + +static int +do_test (void) +{ + int result = float_test (); + result |= double_test (); +#ifndef NO_LONG_DOUBLE + result |= ldouble_test (); +#endif + return result; +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/sysdeps/i386/fpu/s_nearbyint.S b/sysdeps/i386/fpu/s_nearbyint.S index 52909139a9..8da8ae9792 100644 --- a/sysdeps/i386/fpu/s_nearbyint.S +++ b/sysdeps/i386/fpu/s_nearbyint.S @@ -8,22 +8,17 @@ ENTRY(__nearbyint) fldl 4(%esp) - pushl %eax - cfi_adjust_cfa_offset (4) - pushl %ecx - cfi_adjust_cfa_offset (4) - fnstcw (%esp) - movl (%esp), %eax + subl $32, %esp + cfi_adjust_cfa_offset (32) + fnstenv 4(%esp) + movl 4(%esp), %eax orl $0x20, %eax - movl %eax, 4(%esp) - fldcw 4(%esp) - frndint - fclex + movl %eax, (%esp) fldcw (%esp) - popl %ecx - cfi_adjust_cfa_offset (-4) - popl %eax - cfi_adjust_cfa_offset (-4) + frndint + fldenv 4(%esp) + addl $32, %esp + cfi_adjust_cfa_offset (-32) ret END (__nearbyint) weak_alias (__nearbyint, nearbyint) diff --git a/sysdeps/i386/fpu/s_nearbyintf.S b/sysdeps/i386/fpu/s_nearbyintf.S index 6a6b1d6c2b..0c51f72364 100644 --- a/sysdeps/i386/fpu/s_nearbyintf.S +++ b/sysdeps/i386/fpu/s_nearbyintf.S @@ -8,22 +8,17 @@ ENTRY(__nearbyintf) flds 4(%esp) - pushl %eax - cfi_adjust_cfa_offset (4) - pushl %ecx - cfi_adjust_cfa_offset (4) - fnstcw (%esp) - movl (%esp), %eax + subl $32, %esp + cfi_adjust_cfa_offset (32) + fnstenv 4(%esp) + movl 4(%esp), %eax orl $0x20, %eax - movl %eax, 4(%esp) - fldcw 4(%esp) - frndint - fclex + movl %eax, (%esp) fldcw (%esp) - popl %ecx - cfi_adjust_cfa_offset (-4) - popl %eax - cfi_adjust_cfa_offset (-4) + frndint + fldenv 4(%esp) + addl $32, %esp + cfi_adjust_cfa_offset (-32) ret END (__nearbyintf) weak_alias (__nearbyintf, nearbyintf) diff --git a/sysdeps/i386/fpu/s_nearbyintl.S b/sysdeps/i386/fpu/s_nearbyintl.S index 819af63a8d..b260ab5914 100644 --- a/sysdeps/i386/fpu/s_nearbyintl.S +++ b/sysdeps/i386/fpu/s_nearbyintl.S @@ -8,22 +8,20 @@ ENTRY(__nearbyintl) fldt 4(%esp) - pushl %eax - cfi_adjust_cfa_offset (4) - pushl %ecx - cfi_adjust_cfa_offset (4) - fnstcw (%esp) - movl (%esp), %eax + subl $32, %esp + cfi_adjust_cfa_offset (32) + fnstenv 4(%esp) + movl 4(%esp), %eax orl $0x20, %eax - movl %eax, 4(%esp) - fldcw 4(%esp) - frndint - fclex + movl %eax, (%esp) fldcw (%esp) - popl %ecx - cfi_adjust_cfa_offset (-4) - popl %eax - cfi_adjust_cfa_offset (-4) + frndint + fnstsw + andl $0x1, %eax + orl %eax, 8(%esp) + fldenv 4(%esp) + addl $32, %esp + cfi_adjust_cfa_offset (-32) ret END (__nearbyintl) weak_alias (__nearbyintl, nearbyintl) diff --git a/sysdeps/x86_64/fpu/s_nearbyintl.S b/sysdeps/x86_64/fpu/s_nearbyintl.S index dab2750a23..76d41bdd52 100644 --- a/sysdeps/x86_64/fpu/s_nearbyintl.S +++ b/sysdeps/x86_64/fpu/s_nearbyintl.S @@ -8,14 +8,16 @@ ENTRY(__nearbyintl) fldt 8(%rsp) - fnstcw -4(%rsp) - movl -4(%rsp), %eax + fnstenv -28(%rsp) + movl -28(%rsp), %eax orl $0x20, %eax - movl %eax, -8(%rsp) - fldcw -8(%rsp) + movl %eax, -32(%rsp) + fldcw -32(%rsp) frndint - fclex - fldcw -4(%rsp) + fnstsw + andl $0x1, %eax + orl %eax, -24(%rsp) + fldenv -28(%rsp) ret END (__nearbyintl) weak_alias (__nearbyintl, nearbyintl) |