]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
Add canonicalize, canonicalizef, canonicalizel.
authorJoseph Myers <joseph@codesourcery.com>
Wed, 26 Oct 2016 23:14:31 +0000 (23:14 +0000)
committerJoseph Myers <joseph@codesourcery.com>
Wed, 26 Oct 2016 23:14:31 +0000 (23:14 +0000)
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.

49 files changed:
ChangeLog
NEWS
manual/arith.texi
manual/libm-err-tab.pl
math/Makefile
math/Versions
math/bits/mathcalls.h
math/libm-test.inc
math/s_canonicalize_template.c [new file with mode: 0644]
sysdeps/generic/math-tests.h
sysdeps/ieee754/ldbl-128ibm/Makefile
sysdeps/ieee754/ldbl-128ibm/include/bits/iscanonical.h [new file with mode: 0644]
sysdeps/ieee754/ldbl-128ibm/s_iscanonicall.c
sysdeps/ieee754/ldbl-128ibm/test-canonical-ldbl-128ibm.c [moved from sysdeps/ieee754/ldbl-128ibm/test-iscanonical-ldbl-128ibm.c with 90% similarity]
sysdeps/ieee754/ldbl-96/Makefile
sysdeps/ieee754/ldbl-96/include/bits/iscanonical.h [new file with mode: 0644]
sysdeps/ieee754/ldbl-96/s_iscanonicall.c
sysdeps/ieee754/ldbl-96/test-canonical-ldbl-96.c [moved from sysdeps/ieee754/ldbl-96/test-iscanonical-ldbl-96.c with 82% similarity]
sysdeps/ieee754/ldbl-opt/Makefile
sysdeps/ieee754/ldbl-opt/nldbl-canonicalize.c [new file with mode: 0644]
sysdeps/ieee754/ldbl-opt/s_canonicalizel.c [new file with mode: 0644]
sysdeps/mips/math-tests.h
sysdeps/nacl/libm.abilist
sysdeps/unix/sysv/linux/aarch64/libm.abilist
sysdeps/unix/sysv/linux/alpha/libm.abilist
sysdeps/unix/sysv/linux/arm/libm.abilist
sysdeps/unix/sysv/linux/hppa/libm.abilist
sysdeps/unix/sysv/linux/i386/libm.abilist
sysdeps/unix/sysv/linux/ia64/libm.abilist
sysdeps/unix/sysv/linux/m68k/coldfire/libm.abilist
sysdeps/unix/sysv/linux/m68k/m680x0/libm.abilist
sysdeps/unix/sysv/linux/microblaze/libm.abilist
sysdeps/unix/sysv/linux/mips/mips32/libm.abilist
sysdeps/unix/sysv/linux/mips/mips64/libm.abilist
sysdeps/unix/sysv/linux/nios2/libm.abilist
sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libm.abilist
sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libm.abilist
sysdeps/unix/sysv/linux/powerpc/powerpc64/libm-le.abilist
sysdeps/unix/sysv/linux/powerpc/powerpc64/libm.abilist
sysdeps/unix/sysv/linux/s390/s390-32/libm.abilist
sysdeps/unix/sysv/linux/s390/s390-64/libm.abilist
sysdeps/unix/sysv/linux/sh/libm.abilist
sysdeps/unix/sysv/linux/sparc/sparc32/libm.abilist
sysdeps/unix/sysv/linux/sparc/sparc64/libm.abilist
sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libm.abilist
sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libm.abilist
sysdeps/unix/sysv/linux/tile/tilepro/libm.abilist
sysdeps/unix/sysv/linux/x86_64/64/libm.abilist
sysdeps/unix/sysv/linux/x86_64/x32/libm.abilist

index 35813818cae718fc9008ce06e662dea297fe9fd4..7dbfbc8d653020129764cf5eee2e52c1bf61170c 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,99 @@
 2016-10-26  Joseph Myers  <joseph@codesourcery.com>
 
+       * 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.
+
        * sysdeps/ieee754/ldbl-opt/nldbl-getpayload.c: New file.
        * sysdeps/ieee754/ldbl-opt/Makefile (libnldbl-calls): Add
        getpayload.
diff --git a/NEWS b/NEWS
index ea1a0e03719ac8bc3f5f6e018937bf7349f5936c..2da72cdf7a307888ba53acb9ea3860fa36a8ed6c 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -58,6 +58,8 @@ Version 2.25
   - Total order functions: totalorder, totalorderf, totalorderl,
     totalordermag, totalordermagf, totalordermagl.
 
+  - Canonicalize functions: canonicalize, canonicalizef, canonicalizel.
+
   - NaN functions: getpayload, getpayloadf, getpayloadl.
 
 * The functions strfromd, strfromf, and strfroml, from ISO/IEC TS 18661-1:2014,
index eaaf2b71278ca96bc84fc35d69709fa891c40dda..a5c04e475f11636c0130b24d51112218397d952a 100644 (file)
@@ -1855,6 +1855,36 @@ The argument @var{tagp} is used in an unspecified manner.  On @w{IEEE
 selects one.  On other systems it may do nothing.
 @end deftypefun
 
+@comment math.h
+@comment ISO
+@deftypefun int canonicalize (double *@var{cx}, const double *@var{x})
+@comment math.h
+@comment ISO
+@deftypefunx int canonicalizef (float *@var{cx}, const float *@var{x})
+@comment math.h
+@comment ISO
+@deftypefunx int canonicalizel (long double *@var{cx}, const long double *@var{x})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+In some floating-point formats, some values have canonical (preferred)
+and noncanonical encodings (for IEEE interchange binary formats, all
+encodings are canonical).  These functions, defined by TS
+18661-1:2014, attempt to produce a canonical version of the
+floating-point value pointed to by @var{x}; if that value is a
+signaling NaN, they raise the invalid exception and produce a quiet
+NaN.  If a canonical value is produced, it is stored in the object
+pointed to by @var{cx}, and these functions return zero.  Otherwise
+(if a canonical value could not be produced because the object pointed
+to by @var{x} is not a valid representation of any floating-point
+value), the object pointed to by @var{cx} is unchanged and a nonzero
+value is returned.
+
+Note that some formats have multiple encodings of a value which are
+all equally canonical; when such an encoding is used as an input to
+this function, any such encoding of the same value (or of the
+corresponding quiet NaN, if that value is a signaling NaN) may be
+produced as output.
+@end deftypefun
+
 @comment math.h
 @comment ISO
 @deftypefun double getpayload (const double *@var{x})
index 59c53720b3259bae01718cb5d0da6fdf50ed58c2..18b8ca988f4569e48f57bab7b9136c2ec18f385f 100755 (executable)
@@ -77,10 +77,10 @@ use vars qw (%results @all_floats %suffices @all_functions);
     "nextup", "pow", "remainder", "remquo", "rint", "round", "scalb",
     "scalbn", "sin", "sincos", "sinh", "sqrt", "tan", "tanh", "tgamma",
     "trunc", "y0", "y1", "yn" );
-# fpclassify, getpayload, iscanonical, isnormal, isfinite, isinf, isnan,
-# issignaling, issubnormal, iszero, signbit, iseqsig, isgreater,
-# isgreaterequal, isless, islessequal, islessgreater, isunordered,
-# totalorder, totalordermag
+# canonicalize, fpclassify, getpayload, iscanonical, isnormal,
+# isfinite, isinf, isnan, issignaling, issubnormal, iszero, signbit,
+# iseqsig, isgreater, isgreaterequal, isless, islessequal,
+# islessgreater, isunordered, totalorder, totalordermag
 # are not tabulated.
 
 if ($#ARGV == 0) {
index 7cecba5357a83b9be127eaad94672713d94f1abe..f400d7b74156562fac301bbe8989f3d85e215a01 100644 (file)
@@ -51,7 +51,7 @@ gen-libm-calls = cargF conjF cimagF crealF cabsF s_cacosF               \
                 k_casinhF s_csinhF k_casinhF s_csinhF s_catanhF s_catanF \
                 s_ctanF s_ctanhF s_cexpF s_clogF s_cprojF s_csqrtF       \
                 s_cpowF s_clog10F s_fdimF s_nextdownF s_fmaxF s_fminF    \
-                s_nanF s_iseqsigF
+                s_nanF s_iseqsigF s_canonicalizeF
 
 libm-calls =                                                             \
        e_acosF e_acoshF e_asinF e_atan2F e_atanhF e_coshF e_expF e_fmodF \
index a2e0d900ad224e55521d04d17a1fa7d5e3dc9657..0cd594b3781b9b5034e1b69e25c3c7168fe2b14e 100644 (file)
@@ -220,5 +220,6 @@ libm {
     totalorder; totalorderf; totalorderl;
     totalordermag; totalordermagf; totalordermagl;
     getpayload; getpayloadf; getpayloadl;
+    canonicalize; canonicalizef; canonicalizel;
   }
 }
index c5853a325f27584e2e8e640cf8d930a36de00519..2fd1d289dae8389c06d1e86ca4991f1155df591f 100644 (file)
@@ -395,6 +395,9 @@ __MATHDECL_1 (int, totalorder,, (_Mdouble_ __x, _Mdouble_ __y))
 __MATHDECL_1 (int, totalordermag,, (_Mdouble_ __x, _Mdouble_ __y))
      __attribute__ ((__const__));
 
+/* Canonicalize floating-point representation.  */
+__MATHDECL_1 (int, canonicalize,, (_Mdouble_ *__cx, const _Mdouble_ *__x));
+
 /* Get NaN payload.  */
 __MATHCALL (getpayload,, (const _Mdouble_ *__x));
 #endif
index 89e0e596384f8b809098eb109b4ef77767198ccb..710633842cdb80e366520103964e602aaaee350e 100644 (file)
@@ -43,7 +43,8 @@
 
 /* This testsuite has currently tests for:
    acos, acosh, asin, asinh, atan, atan2, atanh,
-   cbrt, ceil, copysign, cos, cosh, drem, erf, erfc, exp, exp10, exp2, expm1,
+   canonicalize, cbrt, ceil, copysign, cos, cosh, drem,
+   erf, erfc, exp, exp10, exp2, expm1,
    fabs, fdim, finite, floor, fma, fmax, fmin, fmod, fpclassify,
    frexp, gamma, getpayload, hypot,
    ilogb, iscanonical, isfinite, isinf, isnan, isnormal, issignaling,
@@ -85,8 +86,9 @@
    against.  These implemented tests should check all cases that are
    specified in ISO C99.
 
-   NaN values: The payload of NaNs is not examined, but is set in
-   inputs for functions where it is significant.
+   NaN values: The payload of NaNs is set in inputs for functions
+   where it is significant, and is examined in the outputs of some
+   functions.
 
    Inline functions: Inlining functions should give an improvement in
    speed - but not in precission.  The inlined functions return
 /* Some special test flags, passed together with exceptions.  */
 #define IGNORE_ZERO_INF_SIGN           0x400
 #define TEST_NAN_SIGN                  0x800
-#define NO_TEST_INLINE                 0x1000
-#define XFAIL_TEST                     0x2000
+#define TEST_NAN_PAYLOAD               0x1000
+#define NO_TEST_INLINE                 0x2000
+#define XFAIL_TEST                     0x4000
 /* Indicate errno settings required or disallowed.  */
-#define ERRNO_UNCHANGED                        0x4000
-#define ERRNO_EDOM                     0x8000
-#define ERRNO_ERANGE                   0x10000
+#define ERRNO_UNCHANGED                        0x8000
+#define ERRNO_EDOM                     0x10000
+#define ERRNO_ERANGE                   0x20000
 /* Flags generated by gen-libm-test.pl, not entered here manually.  */
-#define IGNORE_RESULT                  0x20000
-#define NON_FINITE                     0x40000
-#define TEST_SNAN                      0x80000
-#define NO_TEST_MATHVEC                        0x100000
+#define IGNORE_RESULT                  0x40000
+#define NON_FINITE                     0x80000
+#define TEST_SNAN                      0x100000
+#define NO_TEST_MATHVEC                        0x200000
+
+#define TEST_NAN_PAYLOAD_CANONICALIZE  (SNAN_TESTS_PRESERVE_PAYLOAD    \
+                                        ? TEST_NAN_PAYLOAD             \
+                                        : 0)
 
 #define __CONCATX(a,b) __CONCAT(a,b)
 
@@ -801,6 +808,13 @@ check_float_internal (const char *test_name, FLOAT computed, FLOAT expected,
          ok = 0;
          printf ("signaling NaN has wrong sign.\n");
        }
+      else if ((exceptions & TEST_NAN_PAYLOAD) != 0
+              && (FUNC (getpayload) (&computed)
+                  != FUNC (getpayload) (&expected)))
+       {
+         ok = 0;
+         printf ("signaling NaN has wrong payload.\n");
+       }
       else
        ok = 1;
     }
@@ -814,6 +828,13 @@ check_float_internal (const char *test_name, FLOAT computed, FLOAT expected,
          ok = 0;
          printf ("quiet NaN has wrong sign.\n");
        }
+      else if ((exceptions & TEST_NAN_PAYLOAD) != 0
+              && (FUNC (getpayload) (&computed)
+                  != FUNC (getpayload) (&expected)))
+       {
+         ok = 0;
+         printf ("quiet NaN has wrong payload.\n");
+       }
       else
        ok = 1;
     }
@@ -1277,6 +1298,18 @@ struct test_fFF_11_data
     FLOAT extra2_expected;
   } rd, rn, rz, ru;
 };
+struct test_Ffp_b1_data
+{
+  const char *arg_str;
+  FLOAT arg;
+  struct
+  {
+    int expected;
+    int exceptions;
+    int extra_test;
+    FLOAT extra_expected;
+  } rd, rn, rz, ru;
+};
 
 /* Set the rounding mode, or restore the saved value.  */
 #define IF_ROUND_INIT_ /* Empty.  */
@@ -1550,6 +1583,36 @@ struct test_fFF_11_data
                            (ARRAY)[i].RM_##ROUNDING_MODE.extra_test,   \
                            (ARRAY)[i].RM_##ROUNDING_MODE.extra_expected); \
   ROUND_RESTORE_ ## ROUNDING_MODE
+#define RUN_TEST_Ffp_b1(ARG_STR, FUNC_NAME, ARG, EXPECTED,             \
+                       EXCEPTIONS, EXTRA_VAR, EXTRA_TEST,              \
+                       EXTRA_EXPECTED)                                 \
+  do                                                                   \
+    if (enable_test (EXCEPTIONS))                                      \
+      {                                                                        \
+       COMMON_TEST_SETUP (ARG_STR);                                    \
+       (EXTRA_VAR) = (EXTRA_EXPECTED) == 0 ? 1 : 0;                    \
+       check_bool (test_name, FUNC_TEST (FUNC_NAME) (&(EXTRA_VAR),     \
+                                                     &(ARG)),          \
+                   EXPECTED, EXCEPTIONS);                              \
+       EXTRA_OUTPUT_TEST_SETUP (ARG_STR, 1);                           \
+       if (EXTRA_TEST)                                                 \
+         check_float (extra1_name, EXTRA_VAR, EXTRA_EXPECTED,          \
+                      (EXCEPTIONS) & TEST_NAN_PAYLOAD);                \
+       EXTRA_OUTPUT_TEST_CLEANUP (1);                                  \
+       COMMON_TEST_CLEANUP;                                            \
+      }                                                                        \
+  while (0)
+#define RUN_TEST_LOOP_Ffp_b1(FUNC_NAME, ARRAY, ROUNDING_MODE,          \
+                            EXTRA_VAR)                                 \
+  IF_ROUND_INIT_ ## ROUNDING_MODE                                      \
+    for (size_t i = 0; i < sizeof (ARRAY) / sizeof (ARRAY)[0]; i++)    \
+      RUN_TEST_Ffp_b1 ((ARRAY)[i].arg_str, FUNC_NAME, (ARRAY)[i].arg,  \
+                      (ARRAY)[i].RM_##ROUNDING_MODE.expected,          \
+                      (ARRAY)[i].RM_##ROUNDING_MODE.exceptions,        \
+                      EXTRA_VAR,                                       \
+                      (ARRAY)[i].RM_##ROUNDING_MODE.extra_test,        \
+                      (ARRAY)[i].RM_##ROUNDING_MODE.extra_expected);   \
+  ROUND_RESTORE_ ## ROUNDING_MODE
 #define RUN_TEST_c_c(ARG_STR, FUNC_NAME, ARGR, ARGC, EXPR, EXPC,       \
                     EXCEPTIONS)                                        \
   do                                                                   \
@@ -3557,6 +3620,71 @@ cacosh_test (void)
 }
 
 
+static const struct test_Ffp_b1_data canonicalize_test_data[] =
+  {
+    TEST_Ffp_b1 (canonicalize, plus_infty, 0, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_Ffp_b1 (canonicalize, minus_infty, 0, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_Ffp_b1 (canonicalize, plus_zero, 0, plus_zero, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_Ffp_b1 (canonicalize, minus_zero, 0, minus_zero, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_Ffp_b1 (canonicalize, 1000, 0, 1000, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_Ffp_b1 (canonicalize, max_value, 0, max_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_Ffp_b1 (canonicalize, -max_value, 0, -max_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_Ffp_b1 (canonicalize, min_value, 0, min_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_Ffp_b1 (canonicalize, -min_value, 0, -min_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_Ffp_b1 (canonicalize, min_subnorm_value, 0, min_subnorm_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_Ffp_b1 (canonicalize, -min_subnorm_value, 0, -min_subnorm_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_Ffp_b1 (canonicalize, qnan_value, 0, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED|TEST_NAN_SIGN|TEST_NAN_PAYLOAD),
+    TEST_Ffp_b1 (canonicalize, -qnan_value, 0, -qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED|TEST_NAN_SIGN|TEST_NAN_PAYLOAD),
+    TEST_Ffp_b1 (canonicalize, snan_value, 0, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_UNCHANGED|TEST_NAN_SIGN),
+    TEST_Ffp_b1 (canonicalize, -snan_value, 0, -qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_UNCHANGED|TEST_NAN_SIGN),
+#if HIGH_ORDER_BIT_IS_SET_FOR_SNAN
+    TEST_Ffp_b1 (canonicalize, snan_value_pl ("0x0"), 0, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_UNCHANGED|TEST_NAN_SIGN),
+    TEST_Ffp_b1 (canonicalize, -snan_value_pl ("0x0"), 0, -qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_UNCHANGED|TEST_NAN_SIGN),
+#else
+    TEST_Ffp_b1 (canonicalize, qnan_value_pl ("0x0"), 0, qnan_value_pl ("0x0"), NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED|TEST_NAN_SIGN|TEST_NAN_PAYLOAD),
+    TEST_Ffp_b1 (canonicalize, -qnan_value_pl ("0x0"), 0, -qnan_value_pl ("0x0"), NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED|TEST_NAN_SIGN|TEST_NAN_PAYLOAD),
+#endif
+    TEST_Ffp_b1 (canonicalize, qnan_value_pl ("0x1"), 0, qnan_value_pl ("0x1"), NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED|TEST_NAN_SIGN|TEST_NAN_PAYLOAD),
+    TEST_Ffp_b1 (canonicalize, -qnan_value_pl ("0x1"), 0, -qnan_value_pl ("0x1"), NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED|TEST_NAN_SIGN|TEST_NAN_PAYLOAD),
+    TEST_Ffp_b1 (canonicalize, snan_value_pl ("0x1"), 0, qnan_value_pl ("0x1"), NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_UNCHANGED|TEST_NAN_SIGN|TEST_NAN_PAYLOAD_CANONICALIZE),
+    TEST_Ffp_b1 (canonicalize, -snan_value_pl ("0x1"), 0, -qnan_value_pl ("0x1"), NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_UNCHANGED|TEST_NAN_SIGN|TEST_NAN_PAYLOAD_CANONICALIZE),
+    TEST_Ffp_b1 (canonicalize, qnan_value_pl ("0x2"), 0, qnan_value_pl ("0x2"), NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED|TEST_NAN_SIGN|TEST_NAN_PAYLOAD),
+    TEST_Ffp_b1 (canonicalize, -qnan_value_pl ("0x2"), 0, -qnan_value_pl ("0x2"), NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED|TEST_NAN_SIGN|TEST_NAN_PAYLOAD),
+    TEST_Ffp_b1 (canonicalize, snan_value_pl ("0x2"), 0, qnan_value_pl ("0x2"), NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_UNCHANGED|TEST_NAN_SIGN|TEST_NAN_PAYLOAD_CANONICALIZE),
+    TEST_Ffp_b1 (canonicalize, -snan_value_pl ("0x2"), 0, -qnan_value_pl ("0x2"), NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_UNCHANGED|TEST_NAN_SIGN|TEST_NAN_PAYLOAD_CANONICALIZE),
+    TEST_Ffp_b1 (canonicalize, qnan_value_pl ("0x3fffff"), 0, qnan_value_pl ("0x3fffff"), NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED|TEST_NAN_SIGN|TEST_NAN_PAYLOAD),
+    TEST_Ffp_b1 (canonicalize, -qnan_value_pl ("0x3fffff"), 0, -qnan_value_pl ("0x3fffff"), NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED|TEST_NAN_SIGN|TEST_NAN_PAYLOAD),
+    TEST_Ffp_b1 (canonicalize, snan_value_pl ("0x3fffff"), 0, qnan_value_pl ("0x3fffff"), NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_UNCHANGED|TEST_NAN_SIGN|TEST_NAN_PAYLOAD_CANONICALIZE),
+    TEST_Ffp_b1 (canonicalize, -snan_value_pl ("0x3fffff"), 0, -qnan_value_pl ("0x3fffff"), NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_UNCHANGED|TEST_NAN_SIGN|TEST_NAN_PAYLOAD_CANONICALIZE),
+#if PAYLOAD_DIG >= 51
+    TEST_Ffp_b1 (canonicalize, qnan_value_pl ("0x7ffffffffffff"), 0, qnan_value_pl ("0x7ffffffffffff"), NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED|TEST_NAN_SIGN|TEST_NAN_PAYLOAD),
+    TEST_Ffp_b1 (canonicalize, -qnan_value_pl ("0x7ffffffffffff"), 0, -qnan_value_pl ("0x7ffffffffffff"), NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED|TEST_NAN_SIGN|TEST_NAN_PAYLOAD),
+    TEST_Ffp_b1 (canonicalize, snan_value_pl ("0x7ffffffffffff"), 0, qnan_value_pl ("0x7ffffffffffff"), NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_UNCHANGED|TEST_NAN_SIGN|TEST_NAN_PAYLOAD_CANONICALIZE),
+    TEST_Ffp_b1 (canonicalize, -snan_value_pl ("0x7ffffffffffff"), 0, -qnan_value_pl ("0x7ffffffffffff"), NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_UNCHANGED|TEST_NAN_SIGN|TEST_NAN_PAYLOAD_CANONICALIZE),
+#endif
+#if PAYLOAD_DIG >= 62
+    TEST_Ffp_b1 (canonicalize, qnan_value_pl ("0x3fffffffffffffff"), 0, qnan_value_pl ("0x3fffffffffffffff"), NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED|TEST_NAN_SIGN|TEST_NAN_PAYLOAD),
+    TEST_Ffp_b1 (canonicalize, -qnan_value_pl ("0x3fffffffffffffff"), 0, -qnan_value_pl ("0x3fffffffffffffff"), NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED|TEST_NAN_SIGN|TEST_NAN_PAYLOAD),
+    TEST_Ffp_b1 (canonicalize, snan_value_pl ("0x3fffffffffffffff"), 0, qnan_value_pl ("0x3fffffffffffffff"), NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_UNCHANGED|TEST_NAN_SIGN|TEST_NAN_PAYLOAD_CANONICALIZE),
+    TEST_Ffp_b1 (canonicalize, -snan_value_pl ("0x3fffffffffffffff"), 0, -qnan_value_pl ("0x3fffffffffffffff"), NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_UNCHANGED|TEST_NAN_SIGN|TEST_NAN_PAYLOAD_CANONICALIZE),
+#endif
+#if PAYLOAD_DIG >= 111
+    TEST_Ffp_b1 (canonicalize, qnan_value_pl ("0x7fffffffffffffffffffffffffff"), 0, qnan_value_pl ("0x7fffffffffffffffffffffffffff"), NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED|TEST_NAN_SIGN|TEST_NAN_PAYLOAD),
+    TEST_Ffp_b1 (canonicalize, -qnan_value_pl ("0x7fffffffffffffffffffffffffff"), 0, -qnan_value_pl ("0x7fffffffffffffffffffffffffff"), NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED|TEST_NAN_SIGN|TEST_NAN_PAYLOAD),
+    TEST_Ffp_b1 (canonicalize, snan_value_pl ("0x7fffffffffffffffffffffffffff"), 0, qnan_value_pl ("0x7fffffffffffffffffffffffffff"), NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_UNCHANGED|TEST_NAN_SIGN|TEST_NAN_PAYLOAD_CANONICALIZE),
+    TEST_Ffp_b1 (canonicalize, -snan_value_pl ("0x7fffffffffffffffffffffffffff"), 0, -qnan_value_pl ("0x7fffffffffffffffffffffffffff"), NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_UNCHANGED|TEST_NAN_SIGN|TEST_NAN_PAYLOAD_CANONICALIZE),
+#endif
+  };
+
+static void
+canonicalize_test (void)
+{
+  FLOAT x;
+
+  ALL_RM_TEST (canonicalize, 1, canonicalize_test_data, RUN_TEST_LOOP_Ffp_b1, END, x);
+}
+
+
 static const struct test_c_f_data carg_test_data[] =
   {
     /* carg (x + iy) is specified as atan2 (y, x) */
@@ -13511,6 +13639,9 @@ main (int argc, char **argv)
   totalorder_test ();
   totalordermag_test ();
 
+  /* Canonicalize functions:  */
+  canonicalize_test ();
+
   /* NaN functions:  */
   getpayload_test ();
 
diff --git a/math/s_canonicalize_template.c b/math/s_canonicalize_template.c
new file mode 100644 (file)
index 0000000..fa06f5c
--- /dev/null
@@ -0,0 +1,37 @@
+/* Canonicalize floating-point representation.
+   Copyright (C) 2016 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 <math.h>
+
+int
+M_DECL_FUNC (__canonicalize) (FLOAT *cx, const FLOAT *x)
+{
+  FLOAT val = *x;
+  /* For all binary formats supported by glibc, iscanonical only fails
+     if the representation is not a valid representation of the type,
+     so the only work to do is for signaling NaNs.  */
+  if (!iscanonical (val))
+    return 1;
+  if (issignaling (val))
+    *cx = val + val;
+  else
+    *cx = val;
+  return 0;
+}
+
+declare_mgen_alias (__canonicalize, canonicalize)
index 974dda403a13ae007ecd368ceda6b0e7c45eeaf8..52f4eaee4e048c5404834dd3b395b18c8db1d23a 100644 (file)
 # define SNAN_TESTS_TYPE_CAST  1
 #endif
 
+/* Indicate whether operations on signaling NaNs preserve the payload
+   (if possible; it is not possible with a zero payload if the high
+   bit is set for signaling NaNs) when generating a quiet NaN, and
+   this should be tested.  */
+#ifndef SNAN_TESTS_PRESERVE_PAYLOAD
+# define SNAN_TESTS_PRESERVE_PAYLOAD   1
+#endif
+
 /* Indicate whether to run tests involving a given rounding mode for a
    given floating-point type, given that fesetround succeeds for that
    mode.  All are run if fesetround succeeds unless overridden.  */
index eb625a72342393c25ce048962cb1b8d30c9138f9..bdba6cc6b57e763e88e6c87cd1542712a7690c9f 100644 (file)
@@ -11,6 +11,6 @@ endif
 
 ifeq ($(subdir),math)
 tests += test-fmodl-ldbl-128ibm test-remainderl-ldbl-128ibm \
-        test-remquol-ldbl-128ibm test-iscanonical-ldbl-128ibm \
+        test-remquol-ldbl-128ibm test-canonical-ldbl-128ibm \
         test-totalorderl-ldbl-128ibm
 endif
diff --git a/sysdeps/ieee754/ldbl-128ibm/include/bits/iscanonical.h b/sysdeps/ieee754/ldbl-128ibm/include/bits/iscanonical.h
new file mode 100644 (file)
index 0000000..bee080b
--- /dev/null
@@ -0,0 +1,5 @@
+#include_next <bits/iscanonical.h>
+
+#ifndef _ISOMAC
+libm_hidden_proto (__iscanonicall)
+#endif
index 100b4014e1f520262b4fe30fd44dd6e3f20f41d4..63ddb82402554f2e054f77c5a24935b45a95d71d 100644 (file)
@@ -57,3 +57,4 @@ __iscanonicall (long double x)
   int expdiff = hexp - lexp;
   return expdiff > 53 || (expdiff == 53 && low_p2 && (ix & 1) == 0);
 }
+libm_hidden_def (__iscanonicall)
similarity index 90%
rename from sysdeps/ieee754/ldbl-128ibm/test-iscanonical-ldbl-128ibm.c
rename to sysdeps/ieee754/ldbl-128ibm/test-canonical-ldbl-128ibm.c
index fc16250f5c23f27aa54961d07c5f24c127473946..1fe1bc455583fe7a7df05bec6221982505bcb637 100644 (file)
@@ -1,4 +1,4 @@
-/* Test iscanonical for ldbl-128ibm.
+/* Test iscanonical and canonicalizel for ldbl-128ibm.
    Copyright (C) 2016 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -188,10 +188,37 @@ do_test (void)
       long double ld = ldbl_pack (tests[i].hi, tests[i].lo);
       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;
        }
     }
index 931976d7b1df4c2e911bbd6fddb766d16ea87fe2..dcbfbbac2548d711f3b094c0c4cafff4a77ead1b 100644 (file)
@@ -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 (file)
index 0000000..bee080b
--- /dev/null
@@ -0,0 +1,5 @@
+#include_next <bits/iscanonical.h>
+
+#ifndef _ISOMAC
+libm_hidden_proto (__iscanonicall)
+#endif
index f820030dc0ffffff7246e07ee0e4632e7ac39d55..91ce80d4f1cd824b4de0925c030b327d2153cfaa 100644 (file)
@@ -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)
similarity index 82%
rename from sysdeps/ieee754/ldbl-96/test-iscanonical-ldbl-96.c
rename to sysdeps/ieee754/ldbl-96/test-canonical-ldbl-96.c
index 6827aa81087dd0000f2310f88d09112ac28e759b..ce6dc5b3fad8e04a30d5d5052821321c323ac6b9 100644 (file)
@@ -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;
        }
     }
index e97abdc44dd307fe26edf143d84ce1b2e63dfcfe..745fa4c8cfc7f2c8773fac6e237dc6eb942a698b 100644 (file)
@@ -42,7 +42,8 @@ libnldbl-calls = asprintf dprintf fprintf fscanf fwprintf fwscanf iovfscanf \
                 isoc99_vscanf isoc99_vfscanf isoc99_vsscanf \
                 isoc99_wscanf isoc99_fwscanf isoc99_swscanf \
                 isoc99_vwscanf isoc99_vfwscanf isoc99_vswscanf \
-                nextup nextdown totalorder totalordermag getpayload
+                nextup nextdown totalorder totalordermag getpayload \
+                canonicalize
 libnldbl-routines = $(libnldbl-calls:%=nldbl-%)
 libnldbl-inhibit-o = $(object-suffixes)
 libnldbl-static-only-routines = $(libnldbl-routines)
@@ -58,6 +59,7 @@ CFLAGS-nldbl-atanh.c = -fno-builtin-atanhl
 CFLAGS-nldbl-cabs.c = -fno-builtin-cabsl
 CFLAGS-nldbl-cacos.c = -fno-builtin-cacosl
 CFLAGS-nldbl-cacosh.c = -fno-builtin-cacoshl
+CFLAGS-nldbl-canonicalize.c = -fno-builtin-canonicalizel
 CFLAGS-nldbl-carg.c = -fno-builtin-cargl
 CFLAGS-nldbl-casin.c = -fno-builtin-casinl
 CFLAGS-nldbl-casinh.c = -fno-builtin-casinhl
diff --git a/sysdeps/ieee754/ldbl-opt/nldbl-canonicalize.c b/sysdeps/ieee754/ldbl-opt/nldbl-canonicalize.c
new file mode 100644 (file)
index 0000000..3b33d5c
--- /dev/null
@@ -0,0 +1,26 @@
+/* Compatibility routine for IEEE double as long double for canonicalize.
+   Copyright (C) 2016 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 "nldbl-compat.h"
+
+int
+attribute_hidden
+canonicalizel (double *cx, double *x)
+{
+  return canonicalize (cx, x);
+}
diff --git a/sysdeps/ieee754/ldbl-opt/s_canonicalizel.c b/sysdeps/ieee754/ldbl-opt/s_canonicalizel.c
new file mode 100644 (file)
index 0000000..d5d67df
--- /dev/null
@@ -0,0 +1,5 @@
+/* canonicalizel is not subject to complex aliasing rules.  It was
+   added in glibc 2.25.  */
+#define declare_mgen_alias(from, to) weak_alias (M_SUF (from), M_SUF (to))
+#include <math-type-macros-ldouble.h>
+#include <s_canonicalize_template.c>
index f41c1616b0f35bea6c744466d41e3e7d8fb040cf..fb08bca4184ce44f960565e259b1d51085493136 100644 (file)
 # define EXCEPTION_TESTS_long_double   0
 #endif
 
+/* NaN payload preservation when converting a signaling NaN to quiet
+   is only required in NAN2008 mode.  */
+#if defined __mips_hard_float && !defined __mips_nan2008
+# define SNAN_TESTS_PRESERVE_PAYLOAD   0
+#endif
+
 #include_next <math-tests.h>
index b721bfb379876c46747d924ea456b5f06360f2ae..b0fc19f9f74668bb8eba0732056f4a53bc49874c 100644 (file)
@@ -382,6 +382,9 @@ GLIBC_2.24 nextupl F
 GLIBC_2.25 GLIBC_2.25 A
 GLIBC_2.25 __iseqsig F
 GLIBC_2.25 __iseqsigf F
+GLIBC_2.25 canonicalize F
+GLIBC_2.25 canonicalizef F
+GLIBC_2.25 canonicalizel F
 GLIBC_2.25 fegetmode F
 GLIBC_2.25 fesetexcept F
 GLIBC_2.25 fesetmode F
index dbd620e47437500725a7e202659b7ebcab458084..9d5936c5c6d6be82101c1f3628e61439d0106125 100644 (file)
@@ -414,6 +414,9 @@ GLIBC_2.25 GLIBC_2.25 A
 GLIBC_2.25 __iseqsig F
 GLIBC_2.25 __iseqsigf F
 GLIBC_2.25 __iseqsigl F
+GLIBC_2.25 canonicalize F
+GLIBC_2.25 canonicalizef F
+GLIBC_2.25 canonicalizel F
 GLIBC_2.25 fegetmode F
 GLIBC_2.25 fesetexcept F
 GLIBC_2.25 fesetmode F
index 3af146a00daf87ea8646825b31187f6943064ba5..ce5be3c567eb4dd6d3811150dc1355d078241f6d 100644 (file)
@@ -424,6 +424,9 @@ GLIBC_2.25 GLIBC_2.25 A
 GLIBC_2.25 __iseqsig F
 GLIBC_2.25 __iseqsigf F
 GLIBC_2.25 __iseqsigl F
+GLIBC_2.25 canonicalize F
+GLIBC_2.25 canonicalizef F
+GLIBC_2.25 canonicalizel F
 GLIBC_2.25 fegetmode F
 GLIBC_2.25 fesetexcept F
 GLIBC_2.25 fesetmode F
index 502b5128c874128798f37557ff66f20b252d7897..675dfa5b865049569376ea46e0d8c6d9cb44b9ec 100644 (file)
@@ -71,6 +71,9 @@ GLIBC_2.24 nextupl F
 GLIBC_2.25 GLIBC_2.25 A
 GLIBC_2.25 __iseqsig F
 GLIBC_2.25 __iseqsigf F
+GLIBC_2.25 canonicalize F
+GLIBC_2.25 canonicalizef F
+GLIBC_2.25 canonicalizel F
 GLIBC_2.25 fegetmode F
 GLIBC_2.25 fesetexcept F
 GLIBC_2.25 fesetmode F
index 232ef8ea3eb2dd1d0ccbb84f4c2ab19f1c4c25de..75b71ad8f7f2aaa0a2b9479b3c68a50c827f8746 100644 (file)
@@ -383,6 +383,9 @@ GLIBC_2.24 nextupl F
 GLIBC_2.25 GLIBC_2.25 A
 GLIBC_2.25 __iseqsig F
 GLIBC_2.25 __iseqsigf F
+GLIBC_2.25 canonicalize F
+GLIBC_2.25 canonicalizef F
+GLIBC_2.25 canonicalizel F
 GLIBC_2.25 fegetmode F
 GLIBC_2.25 fesetexcept F
 GLIBC_2.25 fesetmode F
index b6151a96800ab627af93717be1b0a4a479ebceb0..5db3def6fdba86174898c2173d7d002927fab110 100644 (file)
@@ -427,6 +427,9 @@ GLIBC_2.25 __iscanonicall F
 GLIBC_2.25 __iseqsig F
 GLIBC_2.25 __iseqsigf F
 GLIBC_2.25 __iseqsigl F
+GLIBC_2.25 canonicalize F
+GLIBC_2.25 canonicalizef F
+GLIBC_2.25 canonicalizel F
 GLIBC_2.25 fegetmode F
 GLIBC_2.25 fesetexcept F
 GLIBC_2.25 fesetmode F
index 941c4bf49a0c431a01f5e74d66ef8450eb64e222..a80c93a00fc8d95148fa6644df459688f08f7c7a 100644 (file)
@@ -356,6 +356,9 @@ GLIBC_2.25 __iscanonicall F
 GLIBC_2.25 __iseqsig F
 GLIBC_2.25 __iseqsigf F
 GLIBC_2.25 __iseqsigl F
+GLIBC_2.25 canonicalize F
+GLIBC_2.25 canonicalizef F
+GLIBC_2.25 canonicalizel F
 GLIBC_2.25 fegetmode F
 GLIBC_2.25 fesetexcept F
 GLIBC_2.25 fesetmode F
index 502b5128c874128798f37557ff66f20b252d7897..675dfa5b865049569376ea46e0d8c6d9cb44b9ec 100644 (file)
@@ -71,6 +71,9 @@ GLIBC_2.24 nextupl F
 GLIBC_2.25 GLIBC_2.25 A
 GLIBC_2.25 __iseqsig F
 GLIBC_2.25 __iseqsigf F
+GLIBC_2.25 canonicalize F
+GLIBC_2.25 canonicalizef F
+GLIBC_2.25 canonicalizel F
 GLIBC_2.25 fegetmode F
 GLIBC_2.25 fesetexcept F
 GLIBC_2.25 fesetmode F
index 1080dc6cda4bf40e8d49a7479ed8263744da7fc2..c795dbdc88612a8f62972450340bf6390f04df2f 100644 (file)
@@ -425,6 +425,9 @@ GLIBC_2.25 __iscanonicall F
 GLIBC_2.25 __iseqsig F
 GLIBC_2.25 __iseqsigf F
 GLIBC_2.25 __iseqsigl F
+GLIBC_2.25 canonicalize F
+GLIBC_2.25 canonicalizef F
+GLIBC_2.25 canonicalizel F
 GLIBC_2.25 fegetmode F
 GLIBC_2.25 fesetexcept F
 GLIBC_2.25 fesetmode F
index f86e20c775d574283e09efd5c7f05f64ba9f546f..cdc8f19971ebc7eee1ecb51127407cf927765bae 100644 (file)
@@ -382,6 +382,9 @@ GLIBC_2.24 nextupl F
 GLIBC_2.25 GLIBC_2.25 A
 GLIBC_2.25 __iseqsig F
 GLIBC_2.25 __iseqsigf F
+GLIBC_2.25 canonicalize F
+GLIBC_2.25 canonicalizef F
+GLIBC_2.25 canonicalizel F
 GLIBC_2.25 fegetmode F
 GLIBC_2.25 fesetexcept F
 GLIBC_2.25 fesetmode F
index 7965bf20dc577ce692b27e1f4be889a0074dab96..a610b03eba1b2e9c493b96289681a36e3d2c8313 100644 (file)
@@ -384,6 +384,9 @@ GLIBC_2.24 nextupl F
 GLIBC_2.25 GLIBC_2.25 A
 GLIBC_2.25 __iseqsig F
 GLIBC_2.25 __iseqsigf F
+GLIBC_2.25 canonicalize F
+GLIBC_2.25 canonicalizef F
+GLIBC_2.25 canonicalizel F
 GLIBC_2.25 fegetmode F
 GLIBC_2.25 fesetexcept F
 GLIBC_2.25 fesetmode F
index 0711e03a8b40884961a415a0a9e8669067202c38..dfd888cf7062dad86de4a451979fb6c3bcbafa8f 100644 (file)
@@ -416,6 +416,9 @@ GLIBC_2.25 GLIBC_2.25 A
 GLIBC_2.25 __iseqsig F
 GLIBC_2.25 __iseqsigf F
 GLIBC_2.25 __iseqsigl F
+GLIBC_2.25 canonicalize F
+GLIBC_2.25 canonicalizef F
+GLIBC_2.25 canonicalizel F
 GLIBC_2.25 fegetmode F
 GLIBC_2.25 fesetexcept F
 GLIBC_2.25 fesetmode F
index b4b81647ac637cfeda813c05a6cd3b95440d3bd2..a6c505d19a94a873ede646686b77c206c6fa979d 100644 (file)
@@ -382,6 +382,9 @@ GLIBC_2.24 nextupl F
 GLIBC_2.25 GLIBC_2.25 A
 GLIBC_2.25 __iseqsig F
 GLIBC_2.25 __iseqsigf F
+GLIBC_2.25 canonicalize F
+GLIBC_2.25 canonicalizef F
+GLIBC_2.25 canonicalizel F
 GLIBC_2.25 fegetmode F
 GLIBC_2.25 fesetexcept F
 GLIBC_2.25 fesetmode F
index d5253c12445a7a251b8508715a4ea1005075985b..9a5f983c3c716cad17ebd136373253a3a248832b 100644 (file)
@@ -427,6 +427,9 @@ GLIBC_2.25 __iscanonicall F
 GLIBC_2.25 __iseqsig F
 GLIBC_2.25 __iseqsigf F
 GLIBC_2.25 __iseqsigl F
+GLIBC_2.25 canonicalize F
+GLIBC_2.25 canonicalizef F
+GLIBC_2.25 canonicalizel F
 GLIBC_2.25 fegetmode F
 GLIBC_2.25 fesetexcept F
 GLIBC_2.25 fesetmode F
index 274eede94042e72e5d5934caa40c342623e46d2a..24f0127055a1e7e95248320b71cfe4434b784a46 100644 (file)
@@ -426,6 +426,9 @@ GLIBC_2.25 __iscanonicall F
 GLIBC_2.25 __iseqsig F
 GLIBC_2.25 __iseqsigf F
 GLIBC_2.25 __iseqsigl F
+GLIBC_2.25 canonicalize F
+GLIBC_2.25 canonicalizef F
+GLIBC_2.25 canonicalizel F
 GLIBC_2.25 fegetmode F
 GLIBC_2.25 fesetexcept F
 GLIBC_2.25 fesetmode F
index 1af5a2fa7479678bb41e6d536a4203f09f843e26..00c7d22dfc798cdbcaee8bc560d9f950a7107b5d 100644 (file)
@@ -421,6 +421,9 @@ GLIBC_2.25 __iscanonicall F
 GLIBC_2.25 __iseqsig F
 GLIBC_2.25 __iseqsigf F
 GLIBC_2.25 __iseqsigl F
+GLIBC_2.25 canonicalize F
+GLIBC_2.25 canonicalizef F
+GLIBC_2.25 canonicalizel F
 GLIBC_2.25 fegetmode F
 GLIBC_2.25 fesetexcept F
 GLIBC_2.25 fesetmode F
index 767905c8015fac1f7ce3fccf046cfda76747fa69..bfbaa366341f6a5ff6cffb9da80eb10e350565e1 100644 (file)
@@ -102,6 +102,9 @@ GLIBC_2.25 __iscanonicall F
 GLIBC_2.25 __iseqsig F
 GLIBC_2.25 __iseqsigf F
 GLIBC_2.25 __iseqsigl F
+GLIBC_2.25 canonicalize F
+GLIBC_2.25 canonicalizef F
+GLIBC_2.25 canonicalizel F
 GLIBC_2.25 fegetmode F
 GLIBC_2.25 fesetexcept F
 GLIBC_2.25 fesetmode F
index 342a27b7c81d4acb1c1d717bb40a064e6a181190..6e52936a88ad47d3ab50a19e9e14a9060ba16cff 100644 (file)
@@ -414,6 +414,9 @@ GLIBC_2.25 GLIBC_2.25 A
 GLIBC_2.25 __iseqsig F
 GLIBC_2.25 __iseqsigf F
 GLIBC_2.25 __iseqsigl F
+GLIBC_2.25 canonicalize F
+GLIBC_2.25 canonicalizef F
+GLIBC_2.25 canonicalizel F
 GLIBC_2.25 fegetmode F
 GLIBC_2.25 fesetexcept F
 GLIBC_2.25 fesetmode F
index 58b6e50d85a4701e64bd8cc719704a979848a473..a01c58857bedd706f0d58d0e853c7fd07051114d 100644 (file)
@@ -412,6 +412,9 @@ GLIBC_2.25 GLIBC_2.25 A
 GLIBC_2.25 __iseqsig F
 GLIBC_2.25 __iseqsigf F
 GLIBC_2.25 __iseqsigl F
+GLIBC_2.25 canonicalize F
+GLIBC_2.25 canonicalizef F
+GLIBC_2.25 canonicalizel F
 GLIBC_2.25 fegetmode F
 GLIBC_2.25 fesetexcept F
 GLIBC_2.25 fesetmode F
index ab550995a5d9d574815291df69883dda0e5e7aa7..96497844bb48a512c623e40063d3cb82023d6c4e 100644 (file)
@@ -383,6 +383,9 @@ GLIBC_2.24 nextupl F
 GLIBC_2.25 GLIBC_2.25 A
 GLIBC_2.25 __iseqsig F
 GLIBC_2.25 __iseqsigf F
+GLIBC_2.25 canonicalize F
+GLIBC_2.25 canonicalizef F
+GLIBC_2.25 canonicalizel F
 GLIBC_2.25 fegetmode F
 GLIBC_2.25 fesetexcept F
 GLIBC_2.25 fesetmode F
index 76c6e8e818ef7a09fd61fd4859a6cb8c9fcb8fb9..ba109339197a9afce145bdcda91c2e47e2a2f9ba 100644 (file)
@@ -417,6 +417,9 @@ GLIBC_2.25 GLIBC_2.25 A
 GLIBC_2.25 __iseqsig F
 GLIBC_2.25 __iseqsigf F
 GLIBC_2.25 __iseqsigl F
+GLIBC_2.25 canonicalize F
+GLIBC_2.25 canonicalizef F
+GLIBC_2.25 canonicalizel F
 GLIBC_2.25 fegetmode F
 GLIBC_2.25 fesetexcept F
 GLIBC_2.25 fesetmode F
index 4e54a03eff6e4a561fc7d4bad1e064d7ce32a660..82245edfba5b848ce3cd82bcf5e3ff00e6902ab8 100644 (file)
@@ -415,6 +415,9 @@ GLIBC_2.25 GLIBC_2.25 A
 GLIBC_2.25 __iseqsig F
 GLIBC_2.25 __iseqsigf F
 GLIBC_2.25 __iseqsigl F
+GLIBC_2.25 canonicalize F
+GLIBC_2.25 canonicalizef F
+GLIBC_2.25 canonicalizel F
 GLIBC_2.25 fegetmode F
 GLIBC_2.25 fesetexcept F
 GLIBC_2.25 fesetmode F
index e9a7426ac66bf86cea3907c1606f73d1f658784d..1d4d6f98c682ef676cc6112ea0d8ad2905969573 100644 (file)
@@ -383,6 +383,9 @@ GLIBC_2.24 nextupl F
 GLIBC_2.25 GLIBC_2.25 A
 GLIBC_2.25 __iseqsig F
 GLIBC_2.25 __iseqsigf F
+GLIBC_2.25 canonicalize F
+GLIBC_2.25 canonicalizef F
+GLIBC_2.25 canonicalizel F
 GLIBC_2.25 fegetmode F
 GLIBC_2.25 fesetexcept F
 GLIBC_2.25 fesetmode F
index e9a7426ac66bf86cea3907c1606f73d1f658784d..1d4d6f98c682ef676cc6112ea0d8ad2905969573 100644 (file)
@@ -383,6 +383,9 @@ GLIBC_2.24 nextupl F
 GLIBC_2.25 GLIBC_2.25 A
 GLIBC_2.25 __iseqsig F
 GLIBC_2.25 __iseqsigf F
+GLIBC_2.25 canonicalize F
+GLIBC_2.25 canonicalizef F
+GLIBC_2.25 canonicalizel F
 GLIBC_2.25 fegetmode F
 GLIBC_2.25 fesetexcept F
 GLIBC_2.25 fesetmode F
index e9a7426ac66bf86cea3907c1606f73d1f658784d..1d4d6f98c682ef676cc6112ea0d8ad2905969573 100644 (file)
@@ -383,6 +383,9 @@ GLIBC_2.24 nextupl F
 GLIBC_2.25 GLIBC_2.25 A
 GLIBC_2.25 __iseqsig F
 GLIBC_2.25 __iseqsigf F
+GLIBC_2.25 canonicalize F
+GLIBC_2.25 canonicalizef F
+GLIBC_2.25 canonicalizel F
 GLIBC_2.25 fegetmode F
 GLIBC_2.25 fesetexcept F
 GLIBC_2.25 fesetmode F
index ab57b5867d38add164486fcdc901d3c297303cac..b0bbadac0913fd7f899587a6cffee5292bfa8de4 100644 (file)
@@ -416,6 +416,9 @@ GLIBC_2.25 __iscanonicall F
 GLIBC_2.25 __iseqsig F
 GLIBC_2.25 __iseqsigf F
 GLIBC_2.25 __iseqsigl F
+GLIBC_2.25 canonicalize F
+GLIBC_2.25 canonicalizef F
+GLIBC_2.25 canonicalizel F
 GLIBC_2.25 fegetmode F
 GLIBC_2.25 fesetexcept F
 GLIBC_2.25 fesetmode F
index 8aaa2a4ab81778a2a9f3d0c681a5401dade14b18..87f085202fedf0ec35814143fafabd38cfc1bb77 100644 (file)
@@ -415,6 +415,9 @@ GLIBC_2.25 __iscanonicall F
 GLIBC_2.25 __iseqsig F
 GLIBC_2.25 __iseqsigf F
 GLIBC_2.25 __iseqsigl F
+GLIBC_2.25 canonicalize F
+GLIBC_2.25 canonicalizef F
+GLIBC_2.25 canonicalizel F
 GLIBC_2.25 fegetmode F
 GLIBC_2.25 fesetexcept F
 GLIBC_2.25 fesetmode F