about summary refs log tree commit diff
path: root/math
diff options
context:
space:
mode:
authorJoseph Myers <joseph@codesourcery.com>2016-11-24 23:56:48 +0000
committerJoseph Myers <joseph@codesourcery.com>2016-11-24 23:56:48 +0000
commit457663a7cd48a675b44769368567713353011b5b (patch)
tree4957e1ec4a3de87e4bf4ee51567e9090f0049e91 /math
parent02c78f02a941461efa566fed8a0209592b0943fc (diff)
downloadglibc-457663a7cd48a675b44769368567713353011b5b.tar.gz
glibc-457663a7cd48a675b44769368567713353011b5b.tar.xz
glibc-457663a7cd48a675b44769368567713353011b5b.zip
Add setpayloadsig, setpayloadsigf, setpayloadsigl.
TS 18661-1 defines functions for manipulating the payloads of NaNs.
This patch implements the setpayloadsig functions for glibc; these are
like the setpayload functions, but produce a signaling NaN instead of
a quiet NaN.

The substance of the implementation was included with the setpayload
implementation, so the new files here just need to wrap the main files
with different defines to build the new functions.

Because the functions store a signaling NaN via a pointer and the
libm-test macros choose a suitable initial value for the variable in
such a case by comparing with the expected value, the relevant macro
needs to clear exceptions after FE_INVALID may have been raised by
that comparison.

Tested for x86_64, x86, mips64 and powerpc.

	* math/bits/mathcalls.h [__GLIBC_USE (IEC_60559_BFP_EXT)]
	(setpayloadsig): New declaration.
	* math/Versions (setpayloadsig): New libm symbol at version
	GLIBC_2.25.
	(setpayloadsigf): Likewise.
	(setpayloadsigl): Likewise.
	* math/Makefile (libm-calls): Add s_setpayloadsigF.
	* math/libm-test.inc (RUN_TEST_Ff_b1): Call feclearexcept
	(FE_ALL_EXCEPT) after initializing EXTRA_VAR.
	(setpayloadsig_test_data): New array.
	(setpayloadsig_test): New function.
	(main): Call setpayloadsig_test.
	* manual/arith.texi (FP Bit Twiddling): Document setpayloadsig,
	setpayloadsigf and setpayloadsigl.
	* manual/libm-err-tab.pl: Update comment on interfaces without
	ulps tabulated.
	* sysdeps/ieee754/dbl-64/s_setpayloadsig.c: New file.
	* sysdeps/ieee754/flt-32/s_setpayloadsigf.c: Likewise.
	* sysdeps/ieee754/ldbl-128/s_setpayloadsigl.c: Likewise.
	* sysdeps/ieee754/ldbl-128ibm/s_setpayloadsigl.c: Likewise.
	* sysdeps/ieee754/ldbl-96/s_setpayloadsigl.c: Likewise.
	* sysdeps/ieee754/ldbl-opt/nldbl-setpayloadsig.c: Likewise.
	* sysdeps/ieee754/ldbl-opt/Makefile (libnldbl-calls): Add
	setpayloadsig.
	(CFLAGS-nldbl-setpayloadsig.c): New variable.
	* 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 'math')
-rw-r--r--math/Makefile2
-rw-r--r--math/Versions1
-rw-r--r--math/bits/mathcalls.h3
-rw-r--r--math/libm-test.inc89
4 files changed, 93 insertions, 2 deletions
diff --git a/math/Makefile b/math/Makefile
index 576e108e7d..7196e5e5a8 100644
--- a/math/Makefile
+++ b/math/Makefile
@@ -74,7 +74,7 @@ libm-calls =								  \
 	s_issignalingF $(calls:s_%=m_%) x2y2m1F				  \
 	gamma_productF lgamma_negF lgamma_productF			  \
 	s_nextupF s_totalorderF s_totalordermagF s_getpayloadF		  \
-	s_setpayloadF $(gen-libm-calls)
+	s_setpayloadF s_setpayloadsigF $(gen-libm-calls)
 
 libm-compat-calls-ldouble-yes = w_lgamma_compatl k_standardl
 libm-compat-calls = w_lgamma_compatf w_lgamma_compat k_standard k_standardf \
diff --git a/math/Versions b/math/Versions
index 4e15aea9cc..143e53f052 100644
--- a/math/Versions
+++ b/math/Versions
@@ -222,5 +222,6 @@ libm {
     getpayload; getpayloadf; getpayloadl;
     canonicalize; canonicalizef; canonicalizel;
     setpayload; setpayloadf; setpayloadl;
+    setpayloadsig; setpayloadsigf; setpayloadsigl;
   }
 }
diff --git a/math/bits/mathcalls.h b/math/bits/mathcalls.h
index 0f4e625928..54ea4b8f30 100644
--- a/math/bits/mathcalls.h
+++ b/math/bits/mathcalls.h
@@ -403,6 +403,9 @@ __MATHCALL (getpayload,, (const _Mdouble_ *__x));
 
 /* Set quiet NaN payload.  */
 __MATHDECL_1 (int, setpayload,, (_Mdouble_ *__x, _Mdouble_ __payload));
+
+/* Set signaling NaN payload.  */
+__MATHDECL_1 (int, setpayloadsig,, (_Mdouble_ *__x, _Mdouble_ __payload));
 #endif
 
 #if defined __USE_MISC || (defined __USE_XOPEN_EXTENDED \
diff --git a/math/libm-test.inc b/math/libm-test.inc
index 602a8e242d..81d114b04f 100644
--- a/math/libm-test.inc
+++ b/math/libm-test.inc
@@ -54,7 +54,8 @@
    modf, nearbyint, nextafter, nexttoward,
    pow, pow10, remainder, remquo, rint, lrint, llrint,
    round, lround, llround,
-   scalb, scalbn, scalbln, setpayload, signbit, sin, sincos, sinh, sqrt,
+   scalb, scalbn, scalbln, setpayload, setpayloadsig, signbit,
+   sin, sincos, sinh, sqrt,
    tan, tanh, tgamma, totalorder, totalordermag, trunc,
    y0, y1, yn, significand
 
@@ -1592,6 +1593,9 @@ struct test_Ff_b1_data
       {									\
 	COMMON_TEST_SETUP (ARG_STR);					\
 	(EXTRA_VAR) = (EXTRA_EXPECTED) == 0 ? 1 : 0;			\
+	/* Clear any exceptions from comparison involving sNaN		\
+	   EXTRA_EXPECTED.  */						\
+	feclearexcept (FE_ALL_EXCEPT);					\
 	check_bool (test_name, FUNC_TEST (FUNC_NAME) (&(EXTRA_VAR),	\
 						      (ARG)),		\
 		    EXPECTED, EXCEPTIONS);				\
@@ -12417,6 +12421,88 @@ setpayload_test (void)
 }
 
 
+static const struct test_Ff_b1_data setpayloadsig_test_data[] =
+  {
+#if HIGH_ORDER_BIT_IS_SET_FOR_SNAN
+    TEST_Ff_b1 (setpayloadsig, plus_zero, 0, snan_value_pl ("0x0"), NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED|TEST_NAN_SIGN|TEST_NAN_PAYLOAD),
+#else
+    TEST_Ff_b1 (setpayloadsig, plus_zero, 1, plus_zero, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+#endif
+    TEST_Ff_b1 (setpayloadsig, 0x1p0, 0, snan_value_pl ("0x1"), NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED|TEST_NAN_SIGN|TEST_NAN_PAYLOAD),
+    TEST_Ff_b1 (setpayloadsig, 0x2p0, 0, snan_value_pl ("0x2"), NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED|TEST_NAN_SIGN|TEST_NAN_PAYLOAD),
+    TEST_Ff_b1 (setpayloadsig, 0x3fffffp0, 0, snan_value_pl ("0x3fffff"), NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED|TEST_NAN_SIGN|TEST_NAN_PAYLOAD),
+#if PAYLOAD_DIG >= 51
+    TEST_Ff_b1 (setpayloadsig, 0x7ffffffffffffp0, 0, snan_value_pl ("0x7ffffffffffff"), NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED|TEST_NAN_SIGN|TEST_NAN_PAYLOAD),
+#else
+    TEST_Ff_b1 (setpayloadsig, 0x7ffffffffffffp0, 1, plus_zero, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+#endif
+#if PAYLOAD_DIG >= 62
+    TEST_Ff_b1 (setpayloadsig, 0x3fffffffffffffffp0, 0, snan_value_pl ("0x3fffffffffffffff"), NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED|TEST_NAN_SIGN|TEST_NAN_PAYLOAD),
+#else
+    TEST_Ff_b1 (setpayloadsig, 0x3fffffffffffffffp0, 1, plus_zero, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+#endif
+#if PAYLOAD_DIG >= 111
+    TEST_Ff_b1 (setpayloadsig, 0x7fffffffffffffffffffffffffffp0, 0, snan_value_pl ("0x7fffffffffffffffffffffffffff"), NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED|TEST_NAN_SIGN|TEST_NAN_PAYLOAD),
+#else
+    TEST_Ff_b1 (setpayloadsig, 0x7fffffffffffffffffffffffffffp0, 1, plus_zero, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+#endif
+    TEST_Ff_b1 (setpayloadsig, minus_zero, 1, plus_zero, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_Ff_b1 (setpayloadsig, -1.0, 1, plus_zero, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_Ff_b1 (setpayloadsig, -2.0, 1, plus_zero, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_Ff_b1 (setpayloadsig, 0.5, 1, plus_zero, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_Ff_b1 (setpayloadsig, -0.5, 1, plus_zero, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_Ff_b1 (setpayloadsig, max_value, 1, plus_zero, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_Ff_b1 (setpayloadsig, -max_value, 1, plus_zero, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_Ff_b1 (setpayloadsig, min_value, 1, plus_zero, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_Ff_b1 (setpayloadsig, -min_value, 1, plus_zero, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_Ff_b1 (setpayloadsig, min_subnorm_value, 1, plus_zero, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_Ff_b1 (setpayloadsig, -min_subnorm_value, 1, plus_zero, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_Ff_b1 (setpayloadsig, plus_infty, 1, plus_zero, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_Ff_b1 (setpayloadsig, minus_infty, 1, plus_zero, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_Ff_b1 (setpayloadsig, qnan_value, 1, plus_zero, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_Ff_b1 (setpayloadsig, -qnan_value, 1, plus_zero, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_Ff_b1 (setpayloadsig, snan_value, 1, plus_zero, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_Ff_b1 (setpayloadsig, -snan_value, 1, plus_zero, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_Ff_b1 (setpayloadsig, 0xffffffp-1, 1, plus_zero, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+#if MANT_DIG >= 53
+    TEST_Ff_b1 (setpayloadsig, 0x1fffffffffffffp-1, 1, plus_zero, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+#endif
+#if MANT_DIG >= 64
+    TEST_Ff_b1 (setpayloadsig, 0xffffffffffffffffp-1, 1, plus_zero, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+#endif
+#if MANT_DIG >= 106
+    TEST_Ff_b1 (setpayloadsig, 0x3ffffffffffffffffffffffffffp-1, 1, plus_zero, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+#endif
+#if MANT_DIG >= 113
+    TEST_Ff_b1 (setpayloadsig, 0x1ffffffffffffffffffffffffffffp-1, 1, plus_zero, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+#endif
+#if PAYLOAD_DIG >= 23
+    TEST_Ff_b1 (setpayloadsig, 0x1p22, 0, snan_value_pl ("0x400000"), NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED|TEST_NAN_SIGN|TEST_NAN_PAYLOAD),
+#else
+    TEST_Ff_b1 (setpayloadsig, 0x1p22, 1, plus_zero, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+#endif
+#if PAYLOAD_DIG >= 52
+    TEST_Ff_b1 (setpayloadsig, 0x1p51, 0, snan_value_pl ("0x8000000000000"), NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED|TEST_NAN_SIGN|TEST_NAN_PAYLOAD),
+#else
+    TEST_Ff_b1 (setpayloadsig, 0x1p51, 1, plus_zero, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+#endif
+#if PAYLOAD_DIG >= 63
+    TEST_Ff_b1 (setpayloadsig, 0x1p62, 0, snan_value_pl ("0x4000000000000000"), NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED|TEST_NAN_SIGN|TEST_NAN_PAYLOAD),
+#else
+    TEST_Ff_b1 (setpayloadsig, 0x1p62, 1, plus_zero, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+#endif
+    TEST_Ff_b1 (setpayloadsig, 0x1p111, 1, plus_zero, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+  };
+
+static void
+setpayloadsig_test (void)
+{
+  FLOAT x;
+
+  ALL_RM_TEST (setpayloadsig, 1, setpayloadsig_test_data, RUN_TEST_LOOP_Ff_b1, END, x);
+}
+
+
 static const struct test_f_i_data signbit_test_data[] =
   {
     TEST_f_b (signbit, 0, 0, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
@@ -13760,6 +13846,7 @@ main (int argc, char **argv)
   /* NaN functions:  */
   getpayload_test ();
   setpayload_test ();
+  setpayloadsig_test ();
 
   /* Complex functions:  */
   cabs_test ();