[PATCH 5/5] x86 long double: Add tests for pseudo normal numbers
Siddhesh Poyarekar
siddhesh@sourceware.org
Tue Dec 15 14:13:39 GMT 2020
Add some tests for fpclassify, isnanl, isinfl and issignaling.
---
sysdeps/x86/fpu/Makefile | 3 +-
sysdeps/x86/fpu/test-unnormal.c | 196 ++++++++++++++++++++++++++++++++
2 files changed, 198 insertions(+), 1 deletion(-)
create mode 100644 sysdeps/x86/fpu/test-unnormal.c
diff --git a/sysdeps/x86/fpu/Makefile b/sysdeps/x86/fpu/Makefile
index 600e42c3db..e77de56d14 100644
--- a/sysdeps/x86/fpu/Makefile
+++ b/sysdeps/x86/fpu/Makefile
@@ -4,11 +4,12 @@ CPPFLAGS += -I../soft-fp
libm-support += powl_helper
tests += test-fenv-sse test-fenv-clear-sse test-fenv-x87 test-fenv-sse-2 \
- test-flt-eval-method-387 test-flt-eval-method-sse
+ test-flt-eval-method-387 test-flt-eval-method-sse test-unnormal
CFLAGS-test-fenv-sse.c += -msse2 -mfpmath=sse
CFLAGS-test-fenv-clear-sse.c += -msse2 -mfpmath=sse
CFLAGS-test-fenv-sse-2.c += -msse2 -mfpmath=sse
CFLAGS-test-flt-eval-method-387.c += -fexcess-precision=standard -mfpmath=387
CFLAGS-test-flt-eval-method-sse.c += -fexcess-precision=standard -msse2 \
-mfpmath=sse
+CFLAGS-test-unnormal.c += -fsignaling-nans -std=c2x
endif
diff --git a/sysdeps/x86/fpu/test-unnormal.c b/sysdeps/x86/fpu/test-unnormal.c
new file mode 100644
index 0000000000..fc65d9290f
--- /dev/null
+++ b/sysdeps/x86/fpu/test-unnormal.c
@@ -0,0 +1,196 @@
+/* Test long double classification with x86 pseudo normal numbers.
+ Copyright (C) 2020 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
+ <https://www.gnu.org/licenses/>. */
+
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+
+struct tests
+{
+ const char *val;
+ int class;
+} inputs[] = {
+ /* Normal. */
+ {"\x00\x04\x00\x00\x00\x00\x00\x00\x00\x04", FP_NAN},
+ {"\x00\x04\x00\x00\x00\x00\x00\xf0\x00\x04", FP_NORMAL},
+ /* Pseudo-infinite. */
+ {"\x00\x00\x00\x00\x00\x00\x00\x00\xff\x7f", FP_NAN},
+ {"\x00\x00\x00\x00\x00\x00\x00\x80\xff\x7f", FP_INFINITE},
+ /* Pseudo-zero. */
+ {"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01", FP_NAN},
+ {"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", FP_ZERO},
+};
+
+const char *classes[5];
+#define stringify(N) #N
+
+static void
+initialize (void)
+{
+ classes[FP_NAN] = stringify(FP_NAN);
+ classes[FP_INFINITE] = stringify(FP_INFINITY);
+ classes[FP_ZERO] = stringify(FP_ZERO);
+ classes[FP_SUBNORMAL] = stringify(FP_SUBNORMAL);
+ classes[FP_NORMAL] = stringify(FP_NORMAL);
+}
+
+static void
+unnormal_str (const char *val, char *ret)
+{
+ for (int i = 9; i >= 0; i--)
+ {
+ if (i == 7 || i == 3)
+ *ret++ = ' ';
+ snprintf(ret, 3, "%02x", (unsigned char) val[i]);
+ ret += 2;
+ }
+}
+
+static int
+test_fpclassify (void)
+{
+ int ret = 0;
+
+ printf ("* fpclassify tests:\n");
+ for (int i = 0; i < sizeof (inputs)/sizeof (struct tests); i++)
+ {
+ long double value;
+ char buf[22];
+
+ memcpy (&value, inputs[i].val, 10);
+ unnormal_str(inputs[i].val, buf);
+ int class = fpclassify(value);
+
+ if (class != inputs[i].class)
+ {
+ printf ("0x%s: got %s, expected %s\n", buf,
+ classes[fpclassify(value)],
+ classes[inputs[i].class]);
+ ret |= 1;
+ }
+ else
+ printf ("0x%s: OK\n", buf);
+ }
+ return ret;
+}
+
+static int
+test_isinf (void)
+{
+ int ret = 0;
+
+ printf ("* isinfl tests:\n");
+ for (int i = 0; i < sizeof (inputs)/sizeof (struct tests); i++)
+ {
+ long double value;
+ char buf[22];
+
+ memcpy (&value, inputs[i].val, 10);
+ unnormal_str(inputs[i].val, buf);
+ int inf = isinf (value);
+
+ if ((inputs[i].class == FP_INFINITE && inf)
+ || (inputs[i].class != FP_INFINITE && !inf))
+ printf ("0x%s: OK\n", buf);
+ else
+ {
+ printf ("0x%s: got %s, expected %s\n", buf,
+ inf ? "INFINITE" : "NOT INFINITE",
+ classes[inputs[i].class]);
+ ret |= 1;
+ }
+ }
+
+ return ret;
+}
+
+static int
+test_isnan (void)
+{
+ int ret = 0;
+
+ printf ("* isnanl tests:\n");
+ for (int i = 0; i < sizeof (inputs)/sizeof (struct tests); i++)
+ {
+ long double value;
+ char buf[22];
+
+ memcpy (&value, inputs[i].val, 10);
+ unnormal_str(inputs[i].val, buf);
+ int nan = isnan (value);
+
+ if ((inputs[i].class == FP_NAN && nan)
+ || (inputs[i].class != FP_NAN && !nan))
+ printf ("0x%s: OK\n", buf);
+ else
+ {
+ printf ("0x%s: got %s, expected %s\n", buf,
+ nan ? "NAN" : "NOT NAN",
+ classes[inputs[i].class]);
+ ret |= 1;
+ }
+ }
+ return ret;
+}
+
+static int
+test_issignaling (void)
+{
+ int ret = 0;
+
+ printf ("* issignaling tests:\n");
+ for (int i = 0; i < sizeof (inputs)/sizeof (struct tests); i++)
+ {
+ long double value;
+ char buf[22];
+
+ memcpy (&value, inputs[i].val, 10);
+ unnormal_str(inputs[i].val, buf);
+ int signaling = issignaling (value);
+
+ if ((inputs[i].class == FP_NAN && signaling)
+ || (inputs[i].class != FP_NAN && !signaling))
+ printf ("0x%s: OK\n", buf);
+ else
+ {
+ printf ("0x%s: got %s, expected %s\n", buf,
+ signaling ? "SIGNALING" : "NOT SIGNALING",
+ classes[inputs[i].class]);
+ ret |= 1;
+ }
+ }
+ return ret;
+}
+
+int
+do_test (void)
+{
+ int ret = 0;
+
+ initialize ();
+
+ ret |= test_fpclassify ();
+ ret |= test_isinf ();
+ ret |= test_isnan ();
+ ret |= test_issignaling ();
+
+ return ret;
+}
+
+#include <support/test-driver.c>
--
2.29.2
More information about the Libc-alpha
mailing list