aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoseph Myers <joseph@codesourcery.com>2016-10-19 01:49:09 +0000
committerJoseph Myers <joseph@codesourcery.com>2016-10-19 01:49:09 +0000
commitf8e8b8ed9f266097b42a77359445372d82365916 (patch)
treec8193dce446027347491ba1828af41d875708636
parenta9bfffe59333fdc6785f3cc903188d1ead36539d (diff)
downloadglibc-f8e8b8ed9f266097b42a77359445372d82365916.tar.xz
glibc-f8e8b8ed9f266097b42a77359445372d82365916.zip
Add getpayload, getpayloadf, getpayloadl.
TS 18661-1 defines functions for manipulating the payloads of NaNs. This patch implements the getpayload functions for glibc; these extract the NaN payload (from an argument passed as a pointer, for which corresponding libm-test support is added) and return it in the same floating-point type. The return value of these functions is unspecified for non-NaN arguments; the patch does the simplest thing to implement, which is that the functions do not check whether the argument is a NaN and just treat the relevant bits of the representation as a payload regardless. A conversion from integer to floating-point is used to produce the required return value, except in the ldbl-128 case; as 128-bit integers are not supported for all configurations using ldbl-128, the code constructs the required floating-point representation of the return value directly instead. Tested for x86_64, x86, mips64 and powerpc. * math/bits/mathcalls.h [__GLIBC_USE (IEC_60559_BFP_EXT)] (getpayload): New declaration. * math/Versions (getpayload): New libm symbol at version GLIBC_2.25. (getpayloadf): Likewise. (getpayloadl): Likewise. * math/Makefile (libm-calls): Add s_getpayloadF. * math/libm-test.inc: Include <nan-high-order-bit.h>. (struct test_f_f_data): Add comment. (RUN_TEST_fp_f): New macro. (RUN_TEST_LOOP_fp_f): Likewise. (getpayload_test_data): New array. (getpayload_test): New function. (main): Call getpayload_test. * math/gen-libm-test.pl (parse_args): Handle 'p' in argument descriptor. * manual/arith.texi (FP Bit Twiddling): Document getpayload, getpayloadf and getpayloadl. * manual/libm-err-tab.pl: Update comment on interfaces without ulps tabulated. * sysdeps/ieee754/dbl-64/s_getpayload.c: New file. * sysdeps/ieee754/dbl-64/wordsize-64/s_getpayload.c: Likewise. * sysdeps/ieee754/flt-32/s_getpayloadf.c: Likewise. * sysdeps/ieee754/ldbl-128/s_getpayloadl.c: Likewise. * sysdeps/ieee754/ldbl-128ibm/s_getpayloadl.c: Likewise. * sysdeps/ieee754/ldbl-96/s_getpayloadl.c: 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.
-rw-r--r--ChangeLog62
-rw-r--r--NEWS2
-rw-r--r--manual/arith.texi20
-rwxr-xr-xmanual/libm-err-tab.pl7
-rw-r--r--math/Makefile3
-rw-r--r--math/Versions1
-rw-r--r--math/bits/mathcalls.h3
-rwxr-xr-xmath/gen-libm-test.pl8
-rw-r--r--math/libm-test.inc85
-rw-r--r--sysdeps/ieee754/dbl-64/s_getpayload.c37
-rw-r--r--sysdeps/ieee754/dbl-64/wordsize-64/s_getpayload.c33
-rw-r--r--sysdeps/ieee754/flt-32/s_getpayloadf.c33
-rw-r--r--sysdeps/ieee754/ldbl-128/s_getpayloadl.c57
-rw-r--r--sysdeps/ieee754/ldbl-128ibm/s_getpayloadl.c34
-rw-r--r--sysdeps/ieee754/ldbl-96/s_getpayloadl.c32
-rw-r--r--sysdeps/nacl/libm.abilist3
-rw-r--r--sysdeps/unix/sysv/linux/aarch64/libm.abilist3
-rw-r--r--sysdeps/unix/sysv/linux/alpha/libm.abilist3
-rw-r--r--sysdeps/unix/sysv/linux/arm/libm.abilist3
-rw-r--r--sysdeps/unix/sysv/linux/hppa/libm.abilist3
-rw-r--r--sysdeps/unix/sysv/linux/i386/libm.abilist3
-rw-r--r--sysdeps/unix/sysv/linux/ia64/libm.abilist3
-rw-r--r--sysdeps/unix/sysv/linux/m68k/coldfire/libm.abilist3
-rw-r--r--sysdeps/unix/sysv/linux/m68k/m680x0/libm.abilist3
-rw-r--r--sysdeps/unix/sysv/linux/microblaze/libm.abilist3
-rw-r--r--sysdeps/unix/sysv/linux/mips/mips32/libm.abilist3
-rw-r--r--sysdeps/unix/sysv/linux/mips/mips64/libm.abilist3
-rw-r--r--sysdeps/unix/sysv/linux/nios2/libm.abilist3
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libm.abilist3
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libm.abilist3
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc64/libm-le.abilist3
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc64/libm.abilist3
-rw-r--r--sysdeps/unix/sysv/linux/s390/s390-32/libm.abilist3
-rw-r--r--sysdeps/unix/sysv/linux/s390/s390-64/libm.abilist3
-rw-r--r--sysdeps/unix/sysv/linux/sh/libm.abilist3
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc32/libm.abilist3
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc64/libm.abilist3
-rw-r--r--sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libm.abilist3
-rw-r--r--sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libm.abilist3
-rw-r--r--sysdeps/unix/sysv/linux/tile/tilepro/libm.abilist3
-rw-r--r--sysdeps/unix/sysv/linux/x86_64/64/libm.abilist3
-rw-r--r--sysdeps/unix/sysv/linux/x86_64/x32/libm.abilist3
42 files changed, 491 insertions, 7 deletions
diff --git a/ChangeLog b/ChangeLog
index adc4df985d..9b226786af 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,65 @@
+2016-10-19 Joseph Myers <joseph@codesourcery.com>
+
+ * math/bits/mathcalls.h [__GLIBC_USE (IEC_60559_BFP_EXT)]
+ (getpayload): New declaration.
+ * math/Versions (getpayload): New libm symbol at version
+ GLIBC_2.25.
+ (getpayloadf): Likewise.
+ (getpayloadl): Likewise.
+ * math/Makefile (libm-calls): Add s_getpayloadF.
+ * math/libm-test.inc: Include <nan-high-order-bit.h>.
+ (struct test_f_f_data): Add comment.
+ (RUN_TEST_fp_f): New macro.
+ (RUN_TEST_LOOP_fp_f): Likewise.
+ (getpayload_test_data): New array.
+ (getpayload_test): New function.
+ (main): Call getpayload_test.
+ * math/gen-libm-test.pl (parse_args): Handle 'p' in argument
+ descriptor.
+ * manual/arith.texi (FP Bit Twiddling): Document getpayload,
+ getpayloadf and getpayloadl.
+ * manual/libm-err-tab.pl: Update comment on interfaces without
+ ulps tabulated.
+ * sysdeps/ieee754/dbl-64/s_getpayload.c: New file.
+ * sysdeps/ieee754/dbl-64/wordsize-64/s_getpayload.c: Likewise.
+ * sysdeps/ieee754/flt-32/s_getpayloadf.c: Likewise.
+ * sysdeps/ieee754/ldbl-128/s_getpayloadl.c: Likewise.
+ * sysdeps/ieee754/ldbl-128ibm/s_getpayloadl.c: Likewise.
+ * sysdeps/ieee754/ldbl-96/s_getpayloadl.c: 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.
+
2016-10-18 Adhemerval Zanella <adhemerval.zanella@linaro.org>
* sysdeps/unix/sysv/linux/Makefile [$(subdir) = math] (tests): Move
diff --git a/NEWS b/NEWS
index 5251242736..6439040a28 100644
--- a/NEWS
+++ b/NEWS
@@ -58,6 +58,8 @@ Version 2.25
- Total order functions: totalorder, totalorderf, totalorderl,
totalordermag, totalordermagf, totalordermagl.
+ - NaN functions: getpayload, getpayloadf, getpayloadl.
+
* The <sys/quota.h> header now includes the <linux/quota.h> header. Support
for the Linux quota interface which predates kernel version 2.4.22 has
been removed.
diff --git a/manual/arith.texi b/manual/arith.texi
index 282ca45e08..e53988a083 100644
--- a/manual/arith.texi
+++ b/manual/arith.texi
@@ -1854,6 +1854,26 @@ 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 double getpayload (const double *@var{x})
+@comment math.h
+@comment ISO
+@deftypefunx float getpayloadf (const float *@var{x})
+@comment math.h
+@comment ISO
+@deftypefunx {long double} getpayloadl (const long double *@var{x})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+IEEE 754 defines the @dfn{payload} of a NaN to be an integer value
+encoded in the representation of the NaN. Payloads are typically
+propagated from NaN inputs to the result of a floating-point
+operation. These functions, defined by TS 18661-1:2014, return the
+payload of the NaN pointed to by @var{x} (returned as a positive
+integer, or positive zero, represented as a floating-point number); if
+@var{x} is not a NaN, they return an unspecified value. They raise no
+floating-point exceptions even for signaling NaNs.
+@end deftypefun
+
@node FP Comparison Functions
@subsection Floating-Point Comparison Functions
@cindex unordered comparison
diff --git a/manual/libm-err-tab.pl b/manual/libm-err-tab.pl
index 102ff7b03a..59c53720b3 100755
--- a/manual/libm-err-tab.pl
+++ b/manual/libm-err-tab.pl
@@ -77,9 +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, iscanonical, isnormal, isfinite, isinf, isnan, issignaling,
-# issubnormal, iszero, signbit, iseqsig, isgreater, isgreaterequal, isless,
-# islessequal, islessgreater, isunordered, totalorder, totalordermag
+# 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) {
diff --git a/math/Makefile b/math/Makefile
index 7c378fc5c3..2aa6a344e5 100644
--- a/math/Makefile
+++ b/math/Makefile
@@ -72,7 +72,8 @@ libm-calls = \
s_fmaF s_lrintF s_llrintF s_lroundF s_llroundF e_exp10F w_log2F \
s_issignalingF $(calls:s_%=m_%) x2y2m1F \
gamma_productF lgamma_negF lgamma_productF \
- s_nextupF s_totalorderF s_totalordermagF $(gen-libm-calls)
+ s_nextupF s_totalorderF s_totalordermagF s_getpayloadF \
+ $(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 67e826a40e..a2e0d900ad 100644
--- a/math/Versions
+++ b/math/Versions
@@ -219,5 +219,6 @@ libm {
__iscanonicall; __iseqsigf; __iseqsig; __iseqsigl;
totalorder; totalorderf; totalorderl;
totalordermag; totalordermagf; totalordermagl;
+ getpayload; getpayloadf; getpayloadl;
}
}
diff --git a/math/bits/mathcalls.h b/math/bits/mathcalls.h
index 030130656c..c5853a325f 100644
--- a/math/bits/mathcalls.h
+++ b/math/bits/mathcalls.h
@@ -394,6 +394,9 @@ __MATHDECL_1 (int, totalorder,, (_Mdouble_ __x, _Mdouble_ __y))
/* Total order operation on absolute values. */
__MATHDECL_1 (int, totalordermag,, (_Mdouble_ __x, _Mdouble_ __y))
__attribute__ ((__const__));
+
+/* Get NaN payload. */
+__MATHCALL (getpayload,, (const _Mdouble_ *__x));
#endif
#if defined __USE_MISC || (defined __USE_XOPEN_EXTENDED \
diff --git a/math/gen-libm-test.pl b/math/gen-libm-test.pl
index 4d02873c6f..25e69a8998 100755
--- a/math/gen-libm-test.pl
+++ b/math/gen-libm-test.pl
@@ -229,6 +229,10 @@ sub parse_args {
++$current_arg;
next;
}
+ # Argument passed via pointer.
+ if ($descr[$i] =~ /p/) {
+ next;
+ }
# &FLOAT, &int - simplify call by not showing argument.
if ($descr[$i] =~ /F|I/) {
next;
@@ -294,8 +298,8 @@ sub parse_args {
$current_arg++;
next;
}
- # &FLOAT, &int
- if ($descr[$i] =~ /F|I/) {
+ # &FLOAT, &int, argument passed via pointer
+ if ($descr[$i] =~ /F|I|p/) {
next;
}
# complex
diff --git a/math/libm-test.inc b/math/libm-test.inc
index 91451bfa99..89e0e59638 100644
--- a/math/libm-test.inc
+++ b/math/libm-test.inc
@@ -45,7 +45,7 @@
acos, acosh, asin, asinh, atan, atan2, atanh,
cbrt, ceil, copysign, cos, cosh, drem, erf, erfc, exp, exp10, exp2, expm1,
fabs, fdim, finite, floor, fma, fmax, fmin, fmod, fpclassify,
- frexp, gamma, hypot,
+ frexp, gamma, getpayload, hypot,
ilogb, iscanonical, isfinite, isinf, isnan, isnormal, issignaling,
issubnormal, iszero, iseqsig, isless, islessequal, isgreater,
isgreaterequal, islessgreater, isunordered, j0, j1, jn,
@@ -131,6 +131,7 @@
#include <tininess.h>
#include <math-tests.h>
#include <math-tests-arch.h>
+#include <nan-high-order-bit.h>
/* This header defines func_ulps, func_real_ulps and func_imag_ulps
arrays. */
@@ -1075,6 +1076,7 @@ enable_test (int exceptions)
}
/* Structures for each kind of test. */
+/* Used for both RUN_TEST_LOOP_f_f and RUN_TEST_LOOP_fp_f. */
struct test_f_f_data
{
const char *arg_str;
@@ -1352,6 +1354,24 @@ struct test_fFF_11_data
(ARRAY)[i].RM_##ROUNDING_MODE.expected, \
(ARRAY)[i].RM_##ROUNDING_MODE.exceptions); \
ROUND_RESTORE_ ## ROUNDING_MODE
+#define RUN_TEST_fp_f(ARG_STR, FUNC_NAME, ARG, EXPECTED, \
+ EXCEPTIONS) \
+ do \
+ if (enable_test (EXCEPTIONS)) \
+ { \
+ COMMON_TEST_SETUP (ARG_STR); \
+ check_float (test_name, FUNC_TEST (FUNC_NAME) (&(ARG)), \
+ EXPECTED, EXCEPTIONS); \
+ COMMON_TEST_CLEANUP; \
+ } \
+ while (0)
+#define RUN_TEST_LOOP_fp_f(FUNC_NAME, ARRAY, ROUNDING_MODE) \
+ IF_ROUND_INIT_ ## ROUNDING_MODE \
+ for (size_t i = 0; i < sizeof (ARRAY) / sizeof (ARRAY)[0]; i++) \
+ RUN_TEST_fp_f ((ARRAY)[i].arg_str, FUNC_NAME, (ARRAY)[i].arg, \
+ (ARRAY)[i].RM_##ROUNDING_MODE.expected, \
+ (ARRAY)[i].RM_##ROUNDING_MODE.exceptions); \
+ ROUND_RESTORE_ ## ROUNDING_MODE
#define RUN_TEST_2_f(ARG_STR, FUNC_NAME, ARG1, ARG2, EXPECTED, \
EXCEPTIONS) \
do \
@@ -8046,6 +8066,66 @@ frexp_test (void)
ALL_RM_TEST (frexp, 1, frexp_test_data, RUN_TEST_LOOP_fI_f1, END, x);
}
+
+static const struct test_f_f_data getpayload_test_data[] =
+ {
+ TEST_fp_f (getpayload, plus_infty, IGNORE, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+ TEST_fp_f (getpayload, minus_infty, IGNORE, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+ TEST_fp_f (getpayload, plus_zero, IGNORE, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+ TEST_fp_f (getpayload, minus_zero, IGNORE, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+ TEST_fp_f (getpayload, 1000, IGNORE, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+ TEST_fp_f (getpayload, max_value, IGNORE, NO_I