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