maint.mk: relax the default _gl_TS_function_match regexp
[gnulib.git] / m4 / isnanl.m4
1 # isnanl.m4 serial 16
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 AC_DEFUN([gl_FUNC_ISNANL],
8 [
9   AC_REQUIRE([gl_MATH_H_DEFAULTS])
10   ISNANL_LIBM=
11   gl_HAVE_ISNANL_NO_LIBM
12   if test $gl_cv_func_isnanl_no_libm = no; then
13     gl_HAVE_ISNANL_IN_LIBM
14     if test $gl_cv_func_isnanl_in_libm = yes; then
15       ISNANL_LIBM=-lm
16     fi
17   fi
18   dnl The variable gl_func_isnanl set here is used by isnan.m4.
19   if test $gl_cv_func_isnanl_no_libm = yes \
20      || test $gl_cv_func_isnanl_in_libm = yes; then
21     save_LIBS="$LIBS"
22     LIBS="$LIBS $ISNANL_LIBM"
23     gl_FUNC_ISNANL_WORKS
24     LIBS="$save_LIBS"
25     case "$gl_cv_func_isnanl_works" in
26       *yes) gl_func_isnanl=yes ;;
27       *)    gl_func_isnanl=no; ISNANL_LIBM= ;;
28     esac
29   else
30     gl_func_isnanl=no
31   fi
32   if test $gl_func_isnanl != yes; then
33     HAVE_ISNANL=0
34   fi
35   AC_SUBST([ISNANL_LIBM])
36 ])
37
38 AC_DEFUN([gl_FUNC_ISNANL_NO_LIBM],
39 [
40   gl_HAVE_ISNANL_NO_LIBM
41   gl_func_isnanl_no_libm=$gl_cv_func_isnanl_no_libm
42   if test $gl_func_isnanl_no_libm = yes; then
43     gl_FUNC_ISNANL_WORKS
44     case "$gl_cv_func_isnanl_works" in
45       *yes) ;;
46       *)    gl_func_isnanl_no_libm=no ;;
47     esac
48   fi
49   if test $gl_func_isnanl_no_libm = yes; then
50     AC_DEFINE([HAVE_ISNANL_IN_LIBC], [1],
51       [Define if the isnan(long double) function is available in libc.])
52   fi
53 ])
54
55 dnl Prerequisites of replacement isnanl definition. It does not need -lm.
56 AC_DEFUN([gl_PREREQ_ISNANL],
57 [
58   gl_LONG_DOUBLE_EXPONENT_LOCATION
59 ])
60
61 dnl Test whether isnanl() can be used without libm.
62 AC_DEFUN([gl_HAVE_ISNANL_NO_LIBM],
63 [
64   AC_CACHE_CHECK([whether isnan(long double) can be used without linking with libm],
65     [gl_cv_func_isnanl_no_libm],
66     [
67       AC_LINK_IFELSE(
68         [AC_LANG_PROGRAM(
69            [[#include <math.h>
70              #if __GNUC__ >= 4
71              # undef isnanl
72              # define isnanl(x) __builtin_isnanl ((long double)(x))
73              #elif defined isnan
74              # undef isnanl
75              # define isnanl(x) isnan ((long double)(x))
76              #endif
77              long double x;]],
78            [[return isnanl (x);]])],
79         [gl_cv_func_isnanl_no_libm=yes],
80         [gl_cv_func_isnanl_no_libm=no])
81     ])
82 ])
83
84 dnl Test whether isnanl() can be used with libm.
85 AC_DEFUN([gl_HAVE_ISNANL_IN_LIBM],
86 [
87   AC_CACHE_CHECK([whether isnan(long double) can be used with libm],
88     [gl_cv_func_isnanl_in_libm],
89     [
90       save_LIBS="$LIBS"
91       LIBS="$LIBS -lm"
92       AC_LINK_IFELSE(
93         [AC_LANG_PROGRAM(
94            [[#include <math.h>
95              #if __GNUC__ >= 4
96              # undef isnanl
97              # define isnanl(x) __builtin_isnanl ((long double)(x))
98              #elif defined isnan
99              # undef isnanl
100              # define isnanl(x) isnan ((long double)(x))
101              #endif
102              long double x;]],
103            [[return isnanl (x);]])],
104         [gl_cv_func_isnanl_in_libm=yes],
105         [gl_cv_func_isnanl_in_libm=no])
106       LIBS="$save_LIBS"
107     ])
108 ])
109
110 dnl Test whether isnanl() recognizes all numbers which are neither finite nor
111 dnl infinite. This test fails e.g. on NetBSD/i386 and on glibc/ia64.
112 dnl Also, the GCC >= 4.0 built-in __builtin_isnanl does not pass the tests
113 dnl - for pseudo-denormals on i686 and x86_64,
114 dnl - for pseudo-zeroes, unnormalized numbers, and pseudo-denormals on ia64.
115 AC_DEFUN([gl_FUNC_ISNANL_WORKS],
116 [
117   AC_REQUIRE([AC_PROG_CC])
118   AC_REQUIRE([gl_BIGENDIAN])
119   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
120   AC_CACHE_CHECK([whether isnanl works], [gl_cv_func_isnanl_works],
121     [
122       AC_RUN_IFELSE(
123         [AC_LANG_SOURCE([[
124 #include <float.h>
125 #include <limits.h>
126 #include <math.h>
127 #if __GNUC__ >= 4
128 # undef isnanl
129 # define isnanl(x) __builtin_isnanl ((long double)(x))
130 #elif defined isnan
131 # undef isnanl
132 # define isnanl(x) isnan ((long double)(x))
133 #endif
134 #define NWORDS \
135   ((sizeof (long double) + sizeof (unsigned int) - 1) / sizeof (unsigned int))
136 typedef union { unsigned int word[NWORDS]; long double value; }
137         memory_long_double;
138 /* On Irix 6.5, gcc 3.4.3 can't compute compile-time NaN, and needs the
139    runtime type conversion.  */
140 #ifdef __sgi
141 static long double NaNl ()
142 {
143   double zero = 0.0;
144   return zero / zero;
145 }
146 #else
147 # define NaNl() (0.0L / 0.0L)
148 #endif
149 int main ()
150 {
151   int result = 0;
152
153   if (!isnanl (NaNl ()))
154     result |= 1;
155
156   {
157     memory_long_double m;
158     unsigned int i;
159
160     /* The isnanl function should be immune against changes in the sign bit and
161        in the mantissa bits.  The xor operation twiddles a bit that can only be
162        a sign bit or a mantissa bit (since the exponent never extends to
163        bit 31).  */
164     m.value = NaNl ();
165     m.word[NWORDS / 2] ^= (unsigned int) 1 << (sizeof (unsigned int) * CHAR_BIT - 1);
166     for (i = 0; i < NWORDS; i++)
167       m.word[i] |= 1;
168     if (!isnanl (m.value))
169       result |= 1;
170   }
171
172 #if ((defined __ia64 && LDBL_MANT_DIG == 64) || (defined __x86_64__ || defined __amd64__) || (defined __i386 || defined __i386__ || defined _I386 || defined _M_IX86 || defined _X86_))
173 /* Representation of an 80-bit 'long double' as an initializer for a sequence
174    of 'unsigned int' words.  */
175 # ifdef WORDS_BIGENDIAN
176 #  define LDBL80_WORDS(exponent,manthi,mantlo) \
177      { ((unsigned int) (exponent) << 16) | ((unsigned int) (manthi) >> 16), \
178        ((unsigned int) (manthi) << 16) | (unsigned int) (mantlo) >> 16),    \
179        (unsigned int) (mantlo) << 16                                        \
180      }
181 # else
182 #  define LDBL80_WORDS(exponent,manthi,mantlo) \
183      { mantlo, manthi, exponent }
184 # endif
185   { /* Quiet NaN.  */
186     static memory_long_double x =
187       { LDBL80_WORDS (0xFFFF, 0xC3333333, 0x00000000) };
188     if (!isnanl (x.value))
189       result |= 2;
190   }
191   {
192     /* Signalling NaN.  */
193     static memory_long_double x =
194       { LDBL80_WORDS (0xFFFF, 0x83333333, 0x00000000) };
195     if (!isnanl (x.value))
196       result |= 2;
197   }
198   /* The isnanl function should recognize Pseudo-NaNs, Pseudo-Infinities,
199      Pseudo-Zeroes, Unnormalized Numbers, and Pseudo-Denormals, as defined in
200        Intel IA-64 Architecture Software Developer's Manual, Volume 1:
201        Application Architecture.
202        Table 5-2 "Floating-Point Register Encodings"
203        Figure 5-6 "Memory to Floating-Point Register Data Translation"
204    */
205   { /* Pseudo-NaN.  */
206     static memory_long_double x =
207       { LDBL80_WORDS (0xFFFF, 0x40000001, 0x00000000) };
208     if (!isnanl (x.value))
209       result |= 4;
210   }
211   { /* Pseudo-Infinity.  */
212     static memory_long_double x =
213       { LDBL80_WORDS (0xFFFF, 0x00000000, 0x00000000) };
214     if (!isnanl (x.value))
215       result |= 8;
216   }
217   { /* Pseudo-Zero.  */
218     static memory_long_double x =
219       { LDBL80_WORDS (0x4004, 0x00000000, 0x00000000) };
220     if (!isnanl (x.value))
221       result |= 16;
222   }
223   { /* Unnormalized number.  */
224     static memory_long_double x =
225       { LDBL80_WORDS (0x4000, 0x63333333, 0x00000000) };
226     if (!isnanl (x.value))
227       result |= 32;
228   }
229   { /* Pseudo-Denormal.  */
230     static memory_long_double x =
231       { LDBL80_WORDS (0x0000, 0x83333333, 0x00000000) };
232     if (!isnanl (x.value))
233       result |= 64;
234   }
235 #endif
236
237   return result;
238 }]])],
239         [gl_cv_func_isnanl_works=yes],
240         [gl_cv_func_isnanl_works=no],
241         [case "$host_cpu" in
242                                  # Guess no on ia64, x86_64, i386.
243            ia64 | x86_64 | i*86) gl_cv_func_isnanl_works="guessing no";;
244            *)
245              case "$host_os" in
246                netbsd*) gl_cv_func_isnanl_works="guessing no";;
247                *)       gl_cv_func_isnanl_works="guessing yes";;
248              esac
249              ;;
250          esac
251         ])
252     ])
253 ])