diff options
author | Joseph Myers <joseph@codesourcery.com> | 2016-10-26 23:14:31 +0000 |
---|---|---|
committer | Joseph Myers <joseph@codesourcery.com> | 2016-10-26 23:14:31 +0000 |
commit | eaf5ad0bc4a67bf40999e22db6f583ebc3a806ba (patch) | |
tree | 683fb3157396c6e76130a8e1fbb4c5db37bc6eab /sysdeps/ieee754/ldbl-96 | |
parent | 873febb5dfbe67eb1c31ce900a20efe0a6ed6ecb (diff) | |
download | glibc-eaf5ad0bc4a67bf40999e22db6f583ebc3a806ba.tar.gz glibc-eaf5ad0bc4a67bf40999e22db6f583ebc3a806ba.tar.xz glibc-eaf5ad0bc4a67bf40999e22db6f583ebc3a806ba.zip |
Add canonicalize, canonicalizef, canonicalizel.
TS 18661-1 defines canonicalize functions to produce a canonical version of a floating-point representation. This patch implements these functions for glibc. As with the iscanonical macro, these functions are oriented to the decimal floating-point case, where some values have both canonical and noncanonical representations. However, the functions have a return value that says whether they succeeded in storing a canonical result; thus, they can fail for the case of an invalid representation (while still not making any particular choice from among multiple equally canonical valid representations of the same value). Since no floating-point formats in glibc actually have noncanonical valid representations, a type-generic implementation of these functions can be used that expects iscanonical to return 0 only for invalid representations. Now that iscanonical is used within libm.so, libm_hidden_proto / libm_hidden_def are added for __iscanonicall. The definition of these functions is intended to correspond to a convertFormat operation to the same floating-point format. Thus, they convert signaling NaNs to quiet NaNs, raising the "invalid" exception. Such a conversion "should" produce "the canonical version of that signaling NaN made quiet". libm-test.inc is made to check NaN payloads for the output of these functions, a new feature (at some point manipulation functions such as fabs and copysign should have tests added that verify payload preservation for them). As however some architectures may not follow the recommended practice of preserving NaN payloads when converting a signaling NaN to quiet, a new math-tests.h macro SNAN_TESTS_PRESERVE_PAYLOAD is added, and defined to 0 for non-NAN2008 MIPS; any other architectures seeing test failures for lack of payload preservation in this case should also define this macro to 0. (If any cases arise where the sign isn't preserved either, those should have a similar macro added.) The ldbl-96 and ldbl-128ibm tests of iscanonical are renamed and adapted to test canonicalizel as well on the same representations. Tested for x86_64, x86, mips64 and powerpc. * math/bits/mathcalls.h [__GLIBC_USE (IEC_60559_BFP_EXT)] (canonicalize): New declaration. * math/Versions (canonicalize): New libm symbol at version GLIBC_2.25. (canonicalizef): Likewise. (canonicalizel): Likewise. * math/Makefile (gen-libm-calls): Add s_canonicalizeF. * math/s_canonicalize_template.c: New file. * math/libm-test.inc: Update comment on functions tested and testing of NaN payloads. (TEST_NAN_PAYLOAD): New macro. (NO_TEST_INLINE): Update value. (XFAIL_TEST): Likewise. (ERRNO_UNCHANGED): Likewise. (ERRNO_EDOM): Likewise. (ERRNO_ERANGE): Likewise. (IGNORE_RESULT): Likewise. (NON_FINITE): Likewise. (TEST_SNAN): Likewise. (NO_TEST_MATHVEC): Likewise. (TEST_NAN_PAYLOAD_CANONICALIZE): New macro. (check_float_internal): Check NaN payloads if TEST_NAN_PAYLOAD. (struct test_Ffp_b1_data): New type. (RUN_TEST_Ffp_b1): New macro. (RUN_TEST_LOOP_Ffp_b1): Likewise. (canonicalize_test_data): New array. (canonicalize_test): New function. (main): Call canonicalize_test. * manual/arith.texi (FP Bit Twiddling): Document canonicalize, canonicalizef and canonicalizel. * manual/libm-err-tab.pl: Update comment on interfaces without ulps tabulated. * sysdeps/ieee754/ldbl-opt/nldbl-canonicalize.c: New file. * sysdeps/ieee754/ldbl-opt/s_canonicalizel.c: Likewise. * sysdeps/ieee754/ldbl-opt/Makefile (libnldbl-calls): Add canonicalize. (CFLAGS-nldbl-canonicalize.c): New variable. * sysdeps/ieee754/ldbl-128ibm/test-iscanonical-ldbl-128ibm.c: Move to ... * sysdeps/ieee754/ldbl-128ibm/test-canonical-ldbl-128ibm.c: ... here. (do_test): Also test canonicalizel. * sysdeps/ieee754/ldbl-128ibm/Makefile (tests): Change test-iscanonical-ldbl-128ibm to test-canonical-ldbl-128ibm. * sysdeps/ieee754/ldbl-128ibm/include/bits/iscanonical.h: New file. * sysdeps/ieee754/ldbl-128ibm/s_iscanonicall.c (__iscanonicall): Use libm_hidden_def. * sysdeps/ieee754/ldbl-96/test-iscanonical-ldbl-96.c: Move to ... * sysdeps/ieee754/ldbl-96/test-canonical-ldbl-96.c: ... here. (do_test): Also test canonicalizel. * sysdeps/ieee754/ldbl-96/Makefile (tests): Change test-iscanonical-ldbl-96 to test-canonical-ldbl-96. * sysdeps/ieee754/ldbl-96/include/bits/iscanonical.h: New file. * sysdeps/ieee754/ldbl-96/s_iscanonicall.c (__iscanonicall): Use libm_hidden_def. * sysdeps/generic/math-tests.h (SNAN_TESTS_PRESERVE_PAYLOAD): New macro. * sysdeps/mips/math-tests.h [__mips_hard_float && !__mips_nan2008] (SNAN_TESTS_PRESERVE_PAYLOAD): Likewise. * sysdeps/nacl/libm.abilist: Update. * sysdeps/unix/sysv/linux/aarch64/libm.abilist: Likewise. * sysdeps/unix/sysv/linux/alpha/libm.abilist: Likewise. * sysdeps/unix/sysv/linux/arm/libm.abilist: Likewise. * sysdeps/unix/sysv/linux/hppa/libm.abilist: Likewise. * sysdeps/unix/sysv/linux/i386/libm.abilist: Likewise. * sysdeps/unix/sysv/linux/ia64/libm.abilist: Likewise. * sysdeps/unix/sysv/linux/m68k/coldfire/libm.abilist: Likewise. * sysdeps/unix/sysv/linux/m68k/m680x0/libm.abilist: Likewise. * sysdeps/unix/sysv/linux/microblaze/libm.abilist: Likewise. * sysdeps/unix/sysv/linux/mips/mips32/libm.abilist: Likewise. * sysdeps/unix/sysv/linux/mips/mips64/libm.abilist: Likewise. * sysdeps/unix/sysv/linux/nios2/libm.abilist: Likewise. * sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libm.abilist: Likewise. * sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libm.abilist: Likewise. * sysdeps/unix/sysv/linux/powerpc/powerpc64/libm-le.abilist: Likewise. * sysdeps/unix/sysv/linux/powerpc/powerpc64/libm.abilist: Likewise. * sysdeps/unix/sysv/linux/s390/s390-32/libm.abilist: Likewise. * sysdeps/unix/sysv/linux/s390/s390-64/libm.abilist: Likewise. * sysdeps/unix/sysv/linux/sh/libm.abilist: Likewise. * sysdeps/unix/sysv/linux/sparc/sparc32/libm.abilist: Likewise. * sysdeps/unix/sysv/linux/sparc/sparc64/libm.abilist: Likewise. * sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libm.abilist: Likewise. * sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libm.abilist: Likewise. * sysdeps/unix/sysv/linux/tile/tilepro/libm.abilist: Likewise. * sysdeps/unix/sysv/linux/x86_64/64/libm.abilist: Likewise. * sysdeps/unix/sysv/linux/x86_64/x32/libm.abilist: Likewise.
Diffstat (limited to 'sysdeps/ieee754/ldbl-96')
-rw-r--r-- | sysdeps/ieee754/ldbl-96/Makefile | 2 | ||||
-rw-r--r-- | sysdeps/ieee754/ldbl-96/include/bits/iscanonical.h | 5 | ||||
-rw-r--r-- | sysdeps/ieee754/ldbl-96/s_iscanonicall.c | 1 | ||||
-rw-r--r-- | sysdeps/ieee754/ldbl-96/test-canonical-ldbl-96.c (renamed from sysdeps/ieee754/ldbl-96/test-iscanonical-ldbl-96.c) | 33 |
4 files changed, 37 insertions, 4 deletions
diff --git a/sysdeps/ieee754/ldbl-96/Makefile b/sysdeps/ieee754/ldbl-96/Makefile index 931976d7b1..dcbfbbac25 100644 --- a/sysdeps/ieee754/ldbl-96/Makefile +++ b/sysdeps/ieee754/ldbl-96/Makefile @@ -17,5 +17,5 @@ # <http://www.gnu.org/licenses/>. ifeq ($(subdir),math) -tests += test-iscanonical-ldbl-96 test-totalorderl-ldbl-96 +tests += test-canonical-ldbl-96 test-totalorderl-ldbl-96 endif diff --git a/sysdeps/ieee754/ldbl-96/include/bits/iscanonical.h b/sysdeps/ieee754/ldbl-96/include/bits/iscanonical.h new file mode 100644 index 0000000000..bee080bd29 --- /dev/null +++ b/sysdeps/ieee754/ldbl-96/include/bits/iscanonical.h @@ -0,0 +1,5 @@ +#include_next <bits/iscanonical.h> + +#ifndef _ISOMAC +libm_hidden_proto (__iscanonicall) +#endif diff --git a/sysdeps/ieee754/ldbl-96/s_iscanonicall.c b/sysdeps/ieee754/ldbl-96/s_iscanonicall.c index f820030dc0..91ce80d4f1 100644 --- a/sysdeps/ieee754/ldbl-96/s_iscanonicall.c +++ b/sysdeps/ieee754/ldbl-96/s_iscanonicall.c @@ -41,3 +41,4 @@ __iscanonicall (long double x) the high bit to be set. */ return ix == 0 || ix == 0x7fff || mant_high; } +libm_hidden_def (__iscanonicall) diff --git a/sysdeps/ieee754/ldbl-96/test-iscanonical-ldbl-96.c b/sysdeps/ieee754/ldbl-96/test-canonical-ldbl-96.c index 6827aa8108..ce6dc5b3fa 100644 --- a/sysdeps/ieee754/ldbl-96/test-iscanonical-ldbl-96.c +++ b/sysdeps/ieee754/ldbl-96/test-canonical-ldbl-96.c @@ -1,4 +1,4 @@ -/* Test iscanonical for ldbl-96. +/* Test iscanonical and canonicalizel for ldbl-96. Copyright (C) 2016 Free Software Foundation, Inc. This file is part of the GNU C Library. @@ -99,10 +99,37 @@ do_test (void) tests[i].mantissa & 0xffffffffULL); bool canonical = iscanonical (ld); if (canonical == tests[i].canonical) - printf ("PASS: test %zu\n", i); + { + printf ("PASS: iscanonical test %zu\n", i); + long double ldc = 12345.0L; + bool canonicalize_ret = canonicalizel (&ldc, &ld); + if (canonicalize_ret == !canonical) + { + printf ("PASS: canonicalizel test %zu\n", i); + bool canon_ok; + if (!canonical) + canon_ok = ldc == 12345.0L; + else if (isnan (ld)) + canon_ok = isnan (ldc) && !issignaling (ldc); + else + canon_ok = ldc == ld; + if (canon_ok) + printf ("PASS: canonicalized value test %zu\n", i); + else + { + printf ("FAIL: canonicalized value test %zu\n", i); + result = 1; + } + } + else + { + printf ("FAIL: canonicalizel test %zu\n", i); + result = 1; + } + } else { - printf ("FAIL: test %zu\n", i); + printf ("FAIL: iscanonical test %zu\n", i); result = 1; } } |