+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.
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
--- /dev/null
+# 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
+])