summaryrefslogtreecommitdiff
path: root/m4/isnand.m4
diff options
context:
space:
mode:
authorBruno Haible <bruno@clisp.org>2008-01-26 15:17:58 +0100
committerBruno Haible <bruno@clisp.org>2008-01-26 15:17:58 +0100
commitb17d7ac7df62c7c7f56fe857ed28151d8b0e4e28 (patch)
treee475661f13bd1c4d0e9aa603f244ecdb967d870f /m4/isnand.m4
parentce8675631414567e50a77fdd43196f5882172ca7 (diff)
downloadgnulib-b17d7ac7df62c7c7f56fe857ed28151d8b0e4e28.tar.gz
Rename isnan, applicable to 'double' only, to isnand.
Diffstat (limited to 'm4/isnand.m4')
-rw-r--r--m4/isnand.m4137
1 files changed, 137 insertions, 0 deletions
diff --git a/m4/isnand.m4 b/m4/isnand.m4
new file mode 100644
index 0000000000..4f747eae0d
--- /dev/null
+++ b/m4/isnand.m4
@@ -0,0 +1,137 @@
+# isnand.m4 serial 1
+dnl Copyright (C) 2007-2008 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.
+
+dnl Check how to get or define isnand() without linking with libm.
+
+AC_DEFUN([gl_FUNC_ISNAND_NO_LIBM],
+[
+ AC_CACHE_CHECK([whether isnan(double) can be used without linking with libm],
+ [gl_cv_func_isnand_no_libm],
+ [
+ AC_TRY_LINK([#include <math.h>
+ double x;],
+ [return isnan (x);],
+ [gl_cv_func_isnand_no_libm=yes],
+ [gl_cv_func_isnand_no_libm=no])
+ ])
+ if test $gl_cv_func_isnand_no_libm = yes; then
+ AC_DEFINE([HAVE_ISNAND_IN_LIBC], 1,
+ [Define if the isnan(double) function is available in libc.])
+ else
+ AC_LIBOBJ([isnand])
+ gl_DOUBLE_EXPONENT_LOCATION
+ fi
+])
+
+AC_DEFUN([gl_DOUBLE_EXPONENT_LOCATION],
+[
+ AC_CACHE_CHECK([where to find the exponent in a 'double'],
+ [gl_cv_cc_double_expbit0],
+ [
+ AC_TRY_RUN([
+#include <float.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <string.h>
+#define NWORDS \
+ ((sizeof (double) + sizeof (unsigned int) - 1) / sizeof (unsigned int))
+typedef union { double value; unsigned int word[NWORDS]; } memory_double;
+static unsigned int ored_words[NWORDS];
+static unsigned int anded_words[NWORDS];
+static void add_to_ored_words (double x)
+{
+ memory_double m;
+ size_t i;
+ /* Clear it first, in case sizeof (double) < sizeof (memory_double). */
+ memset (&m, 0, sizeof (memory_double));
+ m.value = x;
+ for (i = 0; i < NWORDS; i++)
+ {
+ ored_words[i] |= m.word[i];
+ anded_words[i] &= m.word[i];
+ }
+}
+int main ()
+{
+ size_t j;
+ FILE *fp = fopen ("conftest.out", "w");
+ if (fp == NULL)
+ return 1;
+ for (j = 0; j < NWORDS; j++)
+ anded_words[j] = ~ (unsigned int) 0;
+ add_to_ored_words (0.25);
+ add_to_ored_words (0.5);
+ add_to_ored_words (1.0);
+ add_to_ored_words (2.0);
+ add_to_ored_words (4.0);
+ /* Remove bits that are common (e.g. if representation of the first mantissa
+ bit is explicit). */
+ for (j = 0; j < NWORDS; j++)
+ ored_words[j] &= ~anded_words[j];
+ /* Now find the nonzero word. */
+ for (j = 0; j < NWORDS; j++)
+ if (ored_words[j] != 0)
+ break;
+ if (j < NWORDS)
+ {
+ size_t i;
+ for (i = j + 1; i < NWORDS; i++)
+ if (ored_words[i] != 0)
+ {
+ fprintf (fp, "unknown");
+ return (fclose (fp) != 0);
+ }
+ for (i = 0; ; i++)
+ if ((ored_words[j] >> i) & 1)
+ {
+ fprintf (fp, "word %d bit %d", (int) j, (int) i);
+ return (fclose (fp) != 0);
+ }
+ }
+ fprintf (fp, "unknown");
+ return (fclose (fp) != 0);
+}
+ ],
+ [gl_cv_cc_double_expbit0=`cat conftest.out`],
+ [gl_cv_cc_double_expbit0="unknown"],
+ [
+ dnl On ARM, there are two 'double' floating-point formats, used by
+ dnl different sets of instructions: The older FPA instructions assume
+ dnl that they are stored in big-endian word order, while the words
+ dnl (like integer types) are stored in little-endian byte order.
+ dnl The newer VFP instructions assume little-endian order consistenly.
+ AC_EGREP_CPP([mixed_endianness], [
+#if defined arm || defined __arm || defined __arm__
+ mixed_endianness
+#endif
+ ],
+ [gl_cv_cc_double_expbit0="unknown"],
+ [
+ pushdef([AC_MSG_CHECKING],[:])dnl
+ pushdef([AC_MSG_RESULT],[:])dnl
+ pushdef([AC_MSG_RESULT_UNQUOTED],[:])dnl
+ AC_C_BIGENDIAN(
+ [gl_cv_cc_double_expbit0="word 0 bit 20"],
+ [gl_cv_cc_double_expbit0="word 1 bit 20"],
+ [gl_cv_cc_double_expbit0="unknown"])
+ popdef([AC_MSG_RESULT_UNQUOTED])dnl
+ popdef([AC_MSG_RESULT])dnl
+ popdef([AC_MSG_CHECKING])dnl
+ ])
+ ])
+ rm -f conftest.out
+ ])
+ case "$gl_cv_cc_double_expbit0" in
+ word*bit*)
+ word=`echo "$gl_cv_cc_double_expbit0" | sed -e 's/word //' -e 's/ bit.*//'`
+ bit=`echo "$gl_cv_cc_double_expbit0" | sed -e 's/word.*bit //'`
+ AC_DEFINE_UNQUOTED([DBL_EXPBIT0_WORD], [$word],
+ [Define as the word index where to find the exponent of 'double'.])
+ AC_DEFINE_UNQUOTED([DBL_EXPBIT0_BIT], [$bit],
+ [Define as the bit index in the word where to find bit 0 of the exponent of 'double'.])
+ ;;
+ esac
+])