]> Savannah Git Hosting - gnulib.git/commitdiff
snan: Add more info for mips-based platforms.
authorBruno Haible <bruno@clisp.org>
Mon, 6 Nov 2023 23:52:14 +0000 (00:52 +0100)
committerBruno Haible <bruno@clisp.org>
Mon, 6 Nov 2023 23:52:14 +0000 (00:52 +0100)
* 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.

ChangeLog
lib/snan.h
m4/nan-mips.m4 [new file with mode: 0644]
m4/snan.m4
modules/snan

index df89d30c93494ca5ff99cff29777503e86b04be0..d065d20be5b17ec602b55144c0cc8a2b3f66e0e9 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+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.
+
 2023-11-06  Bruno Haible  <bruno@clisp.org>
 
        fenv-exceptions-state-c99: Update doc regarding Minix.
index b89f13a8de71463f7906677084866dfbcb749af8..8b4de127c4a884fe82770ccb950326bdb90edcc4 100644 (file)
    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 (file)
index 0000000..5a40f18
--- /dev/null
@@ -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
+])
index 2b072dcb264278e4a0c6c751d4c5d0032648e352..21dfb9921b98fd009d2b4fe451fd97e55cbbbf1e 100644 (file)
@@ -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
index 26988bec33cbcba055e5d503b2d33dd80cea28d1..ed2f3f32193e2dd408b272893c1d0bedab36281f 100644 (file)
@@ -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