[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
snan: Add more info for mips-based platforms
|
From: |
Bruno Haible |
|
Subject: |
snan: Add more info for mips-based platforms |
|
Date: |
Tue, 07 Nov 2023 01:31:44 +0100 |
While porting the fenv* modules to OpenBSD/mips64, I noticed some test
failures in the 'nan' and 'snan' tests:
FAIL: test-nan-1
================
../../gltests/test-nan-1.c:65: assertion '!fetestexcept (FE_INVALID)' failed
Abort trap (core dumped)
FAIL test-nan-1 (exit status: 134)
FAIL: test-nan-2
================
Floating point exception (core dumped)
FAIL test-nan-2 (exit status: 136)
FAIL: test-snan-1
=================
../../gltests/test-snan-1.c:75: assertion 'fetestexcept (FE_INVALID)' failed
Abort trap (core dumped)
FAIL test-snan-1 (exit status: 134)
FAIL: test-snan-2.sh
====================
Use of SNaNf() did not signal.
FAIL test-snan-2.sh (exit status: 1)
So, we need to understand the quiet NaN vs. signalling NaN business on mips
better. With the patch below, the configuration prints some insights:
checking whether the NaN float encoding is IEEE 754-2008 compliant... no
checking whether the NaN double encoding is IEEE 754-2008 compliant... no
checking whether the NaN long double encoding is IEEE 754-2008 compliant...
yes
This is surprising, but the explanation is that the 'long double' operations
are implemented by a software library, not by the hardware.
2023-11-06 Bruno Haible <bruno@clisp.org>
snan: Add more info for mips-based platforms.
* m4/nan-mips.m4: New file.
* lib/snan.h: Add comments regarding mips.
* modules/snan (Files): Add m4/nan-mips.m4.
(configure.ac): Invoke gl_NAN_MIPS.
* m4/snan.m4: Update comment.
diff --git a/lib/snan.h b/lib/snan.h
index b89f13a8de..8b4de127c4 100644
--- a/lib/snan.h
+++ b/lib/snan.h
@@ -32,13 +32,27 @@
This bit is
* == 0 to indicate a quiet NaN or Infinity,
== 1 to indicate a signalling NaN,
- on these CPUs: hppa, mips, sh4.
+ on these CPUs: hppa, mips (*), sh4.
* == 1 to indicate a quiet NaN,
== 0 to indicate a signalling NaN or Infinity,
on all other CPUs.
On these platforms, additionally a signalling NaN must have some other
mantissa bit == 1, because when all exponent bits are == 1 and all
- mantissa bits are == 0, the number denotes ±Infinity. */
+ mantissa bits are == 0, the number denotes ±Infinity.
+ This NaN encoding is specified by IEEE 754-2008 § 6.2.1.
+
+ (*) On mips CPUs, it depends on the CPU model. The classical behaviour is
+ as indicated above. On some newer models, it's like on the other CPUs.
+ On some (but not all!) models this meta-info can be determined from two
+ special CPU registers: If the "Floating Point Implementation Register" (fir)
+ bit 23, also known as Has2008 bit, is set, the "Floating Point Control and
+ Status Register" (fcsr) bit 18, also known as the NAN2008 bit, has the value
+ - 0 for the classical behaviour,
+ - 1 for like on the other CPUs.
+ Both of these bits are read-only.
+ This module has determined the behaviour at configure time and defines the
+ C macros MIPS_NAN2008_FLOAT, MIPS_NAN2008_DOUBLE, MIPS_NAN2008_LONG_DOUBLE
+ accordingly. */
/* 'float' = IEEE 754 single-precision
diff --git a/m4/nan-mips.m4 b/m4/nan-mips.m4
new file mode 100644
index 0000000000..5a40f189fa
--- /dev/null
+++ b/m4/nan-mips.m4
@@ -0,0 +1,89 @@
+# nan-mips.m4 serial 1
+dnl Copyright (C) 2023 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+# Extra meta-info mentioned by lib/snan.h.
+AC_DEFUN_ONCE([gl_NAN_MIPS],
+[
+ AC_REQUIRE([AC_CANONICAL_HOST])
+ case "$host_cpu" in
+ mips*)
+ AC_CACHE_CHECK([whether the NaN float encoding is IEEE 754-2008
compliant],
+ [gl_cv_nan2008_f],
+ [AC_RUN_IFELSE(
+ [AC_LANG_PROGRAM([[
+ float volatile zero;
+ /* Assume 'float' has 32 bits, i.e. IEEE single-float. */
+ union { float value; unsigned int word; } qnan;
+ ]],
+ [[qnan.value = zero / zero;
+ return !((qnan.word >> 22) & 1);
+ ]])
+ ],
+ [gl_cv_nan2008_f=yes],
+ [gl_cv_nan2008_f=no],
+ [gl_cv_nan2008_f="guessing no"])
+ ])
+ case "$gl_cv_nan2008_f" in
+ *yes) gl_mips_nan2008_f=1 ;;
+ *) gl_mips_nan2008_f=0 ;;
+ esac
+ AC_DEFINE_UNQUOTED([MIPS_NAN2008_FLOAT], [$gl_mips_nan2008_f],
+ [Define to 1 if the encoding of NaN 'float's is as in IEEE 754-2008 §
6.2.1.])
+
+ AC_CACHE_CHECK([whether the NaN double encoding is IEEE 754-2008
compliant],
+ [gl_cv_nan2008_d],
+ [AC_RUN_IFELSE(
+ [AC_LANG_PROGRAM([[
+ double volatile zero;
+ /* Assume 'double' has 64 bits, i.e. IEEE double-float. */
+ union { double value; unsigned long long word; } qnan;
+ ]],
+ [[qnan.value = zero / zero;
+ return !((qnan.word >> 51) & 1);
+ ]])
+ ],
+ [gl_cv_nan2008_d=yes],
+ [gl_cv_nan2008_d=no],
+ [gl_cv_nan2008_d="guessing no"])
+ ])
+ case "$gl_cv_nan2008_d" in
+ *yes) gl_mips_nan2008_d=1 ;;
+ *) gl_mips_nan2008_d=0 ;;
+ esac
+ AC_DEFINE_UNQUOTED([MIPS_NAN2008_DOUBLE], [$gl_mips_nan2008_d],
+ [Define to 1 if the encoding of NaN 'double's is as in IEEE 754-2008 §
6.2.1.])
+
+ AC_CACHE_CHECK([whether the NaN long double encoding is IEEE 754-2008
compliant],
+ [gl_cv_nan2008_l],
+ [AC_RUN_IFELSE(
+ [AC_LANG_PROGRAM([[
+ #include <float.h>
+ long double volatile zero;
+ #define NWORDS \
+ ((sizeof (long double) + sizeof (unsigned int) - 1) / sizeof
(unsigned int))
+ union { long double value; unsigned int word[NWORDS]; } qnan;
+ ]],
+ [[qnan.value = zero / zero;
+ #if defined _MIPSEB /* equivalent: __BYTE_ORDER__ ==
__ORDER_BIG_ENDIAN__ */
+ return !((qnan.word[0] >> ((LDBL_MANT_DIG - 2) % 32)) & 1);
+ #else
+ return !((qnan.word[NWORDS - 1] >> ((LDBL_MANT_DIG - 2) % 32))
& 1);
+ #endif
+ ]])
+ ],
+ [gl_cv_nan2008_l=yes],
+ [gl_cv_nan2008_l=no],
+ [gl_cv_nan2008_l="guessing no"])
+ ])
+ case "$gl_cv_nan2008_l" in
+ *yes) gl_mips_nan2008_l=1 ;;
+ *) gl_mips_nan2008_l=0 ;;
+ esac
+ AC_DEFINE_UNQUOTED([MIPS_NAN2008_LONG_DOUBLE], [$gl_mips_nan2008_l],
+ [Define to 1 if the encoding of NaN 'long double's is as in IEEE
754-2008 § 6.2.1.])
+ ;;
+ esac
+])
diff --git a/m4/snan.m4 b/m4/snan.m4
index 2b072dcb26..21dfb9921b 100644
--- a/m4/snan.m4
+++ b/m4/snan.m4
@@ -1,10 +1,10 @@
-# snan.m4 serial 2
+# snan.m4 serial 3
dnl Copyright (C) 2023 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
-# Prerequisites for tests/snan.h.
+# Prerequisites for lib/snan.h.
AC_DEFUN_ONCE([gl_SNAN],
[
gl_FLOAT_EXPONENT_LOCATION
diff --git a/modules/snan b/modules/snan
index 26988bec33..ed2f3f3219 100644
--- a/modules/snan
+++ b/modules/snan
@@ -8,12 +8,14 @@ m4/exponentf.m4
m4/exponentd.m4
m4/exponentl.m4
m4/math_h.m4
+m4/nan-mips.m4
Depends-on:
nan
configure.ac:
gl_SNAN
+gl_NAN_MIPS
Makefile.am:
lib_SOURCES += snan.h
| [Prev in Thread] |
Current Thread |
[Next in Thread] |
- snan: Add more info for mips-based platforms,
Bruno Haible <=