1509fb4432c78d8293e2b90e03fc539a95f809c3
[debian/gzip] / m4 / isnanf.m4
1 # isnanf.m4 serial 10
2 dnl Copyright (C) 2007-2010 Free Software Foundation, Inc.
3 dnl This file is free software; the Free Software Foundation
4 dnl gives unlimited permission to copy and/or distribute it,
5 dnl with or without modifications, as long as this notice is preserved.
6
7 dnl Check how to get or define isnanf().
8
9 AC_DEFUN([gl_FUNC_ISNANF],
10 [
11   AC_REQUIRE([gl_MATH_H_DEFAULTS])
12   ISNANF_LIBM=
13   gl_HAVE_ISNANF_NO_LIBM
14   if test $gl_cv_func_isnanf_no_libm = no; then
15     gl_HAVE_ISNANF_IN_LIBM
16     if test $gl_cv_func_isnanf_in_libm = yes; then
17       ISNANF_LIBM=-lm
18     fi
19   fi
20   if test $gl_cv_func_isnanf_no_libm = yes \
21      || test $gl_cv_func_isnanf_in_libm = yes; then
22     save_LIBS="$LIBS"
23     LIBS="$LIBS $ISNANF_LIBM"
24     gl_ISNANF_WORKS
25     LIBS="$save_LIBS"
26     case "$gl_cv_func_isnanf_works" in
27       *yes) gl_func_isnanf=yes ;;
28       *)    gl_func_isnanf=no; ISNANF_LIBM= ;;
29     esac
30   else
31     gl_func_isnanf=no
32   fi
33   if test $gl_func_isnanf != yes; then
34     HAVE_ISNANF=0
35     gl_BUILD_ISNANF
36   fi
37   AC_SUBST([ISNANF_LIBM])
38 ])
39
40 dnl Check how to get or define isnanf() without linking with libm.
41
42 AC_DEFUN([gl_FUNC_ISNANF_NO_LIBM],
43 [
44   gl_HAVE_ISNANF_NO_LIBM
45   if test $gl_cv_func_isnanf_no_libm = yes; then
46     gl_ISNANF_WORKS
47   fi
48   if test $gl_cv_func_isnanf_no_libm = yes \
49      && { case "$gl_cv_func_isnanf_works" in
50             *yes) true;;
51             *) false;;
52           esac
53         }; then
54     AC_DEFINE([HAVE_ISNANF_IN_LIBC], [1],
55       [Define if the isnan(float) function is available in libc.])
56   else
57     gl_BUILD_ISNANF
58   fi
59 ])
60
61 dnl Pull in replacement isnanf definition. It does not need -lm.
62 AC_DEFUN([gl_BUILD_ISNANF],
63 [
64   AC_LIBOBJ([isnanf])
65   gl_FLOAT_EXPONENT_LOCATION
66 ])
67
68 dnl Test whether isnanf() can be used without libm.
69 AC_DEFUN([gl_HAVE_ISNANF_NO_LIBM],
70 [
71   AC_CACHE_CHECK([whether isnan(float) can be used without linking with libm],
72     [gl_cv_func_isnanf_no_libm],
73     [
74       AC_TRY_LINK([#include <math.h>
75                    #if __GNUC__ >= 4
76                    # undef isnanf
77                    # define isnanf(x) __builtin_isnanf ((float)(x))
78                    #elif defined isnan
79                    # undef isnanf
80                    # define isnanf(x) isnan ((float)(x))
81                    #endif
82                    float x;],
83                   [return isnanf (x);],
84         [gl_cv_func_isnanf_no_libm=yes],
85         [gl_cv_func_isnanf_no_libm=no])
86     ])
87 ])
88
89 dnl Test whether isnanf() can be used with libm.
90 AC_DEFUN([gl_HAVE_ISNANF_IN_LIBM],
91 [
92   AC_CACHE_CHECK([whether isnan(float) can be used with libm],
93     [gl_cv_func_isnanf_in_libm],
94     [
95       save_LIBS="$LIBS"
96       LIBS="$LIBS -lm"
97       AC_TRY_LINK([#include <math.h>
98                    #if __GNUC__ >= 4
99                    # undef isnanf
100                    # define isnanf(x) __builtin_isnanf ((float)(x))
101                    #elif defined isnan
102                    # undef isnanf
103                    # define isnanf(x) isnan ((float)(x))
104                    #endif
105                    float x;],
106                   [return isnanf (x);],
107         [gl_cv_func_isnanf_in_libm=yes],
108         [gl_cv_func_isnanf_in_libm=no])
109       LIBS="$save_LIBS"
110     ])
111 ])
112
113 dnl Test whether isnanf() rejects Infinity (this fails on Solaris 2.5.1),
114 dnl recognizes a NaN (this fails on IRIX 6.5 with cc), and recognizes a NaN
115 dnl with in-memory representation 0x7fbfffff (this fails on IRIX 6.5).
116 AC_DEFUN([gl_ISNANF_WORKS],
117 [
118   AC_REQUIRE([AC_PROG_CC])
119   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
120   AC_REQUIRE([gl_FLOAT_EXPONENT_LOCATION])
121   AC_CACHE_CHECK([whether isnan(float) works], [gl_cv_func_isnanf_works],
122     [
123       AC_TRY_RUN([
124 #include <math.h>
125 #if __GNUC__ >= 4
126 # undef isnanf
127 # define isnanf(x) __builtin_isnanf ((float)(x))
128 #elif defined isnan
129 # undef isnanf
130 # define isnanf(x) isnan ((float)(x))
131 #endif
132 /* The Compaq (ex-DEC) C 6.4 compiler chokes on the expression 0.0 / 0.0.  */
133 #ifdef __DECC
134 static float
135 NaN ()
136 {
137   static float zero = 0.0f;
138   return zero / zero;
139 }
140 #else
141 # define NaN() (0.0f / 0.0f)
142 #endif
143 #define NWORDS \
144   ((sizeof (float) + sizeof (unsigned int) - 1) / sizeof (unsigned int))
145 typedef union { unsigned int word[NWORDS]; float value; } memory_float;
146 int main()
147 {
148   memory_float m;
149
150   if (isnanf (1.0f / 0.0f))
151     return 1;
152
153   if (!isnanf (NaN ()))
154     return 1;
155
156 #if defined FLT_EXPBIT0_WORD && defined FLT_EXPBIT0_BIT
157   /* The isnanf function should be immune against changes in the sign bit and
158      in the mantissa bits.  The xor operation twiddles a bit that can only be
159      a sign bit or a mantissa bit.  */
160   if (FLT_EXPBIT0_WORD == 0 && FLT_EXPBIT0_BIT > 0)
161     {
162       m.value = NaN ();
163       /* Set the bits below the exponent to 01111...111.  */
164       m.word[0] &= -1U << FLT_EXPBIT0_BIT;
165       m.word[0] |= 1U << (FLT_EXPBIT0_BIT - 1) - 1;
166       if (!isnanf (m.value))
167         return 1;
168     }
169 #endif
170
171   return 0;
172 }], [gl_cv_func_isnanf_works=yes], [gl_cv_func_isnanf_works=no],
173         [case "$host_os" in
174            irix* | solaris*) gl_cv_func_isnanf_works="guessing no";;
175            *)                gl_cv_func_isnanf_works="guessing yes";;
176          esac
177         ])
178     ])
179 ])