Don't use AC_REQUIRE([AC_C_BIGENDIAN]).
[gnulib.git] / m4 / isfinite.m4
1 # isfinite.m4 serial 4
2 dnl Copyright (C) 2007-2009 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_ISFINITE],
8 [
9   AC_REQUIRE([gl_MATH_H_DEFAULTS])
10   dnl Persuade glibc <math.h> to declare isfinite.
11   AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
12   AC_CHECK_DECLS([isfinite], , , [#include <math.h>])
13   if test "$ac_cv_have_decl_isfinite" = yes; then
14     gl_CHECK_MATH_LIB([ISFINITE_LIBM], [x = isfinite (x);])
15     if test "$ISFINITE_LIBM" != missing; then
16       dnl Test whether isfinite() on 'long double' works.
17       gl_ISFINITEL_WORKS
18       case "$gl_cv_func_isfinitel_works" in
19         *yes) ;;
20         *)    ISFINITE_LIBM=missing;;
21       esac
22       dnl Also, isfinite() on 'double' does not work on Linux/ia64 (because of
23       dnl signalling NaNs). But this does not have to be tested, since
24       dnl isfinite(long double) also does not work in this situation.
25     fi
26   fi
27   if test "$ac_cv_have_decl_isfinite" != yes ||
28      test "$ISFINITE_LIBM" = missing; then
29     REPLACE_ISFINITE=1
30     AC_LIBOBJ([isfinite])
31     ISFINITE_LIBM=
32   fi
33   AC_SUBST([REPLACE_ISFINITE])
34   AC_SUBST([ISFINITE_LIBM])
35 ])
36
37 dnl Test whether isfinite() on 'long double' recognizes all numbers which are
38 dnl neither finite nor infinite. This test fails e.g. on i686, x86_64, ia64,
39 dnl because of
40 dnl - pseudo-denormals on x86_64,
41 dnl - pseudo-zeroes, unnormalized numbers, and pseudo-denormals on i686,
42 dnl - pseudo-NaN, pseudo-Infinity, pseudo-zeroes, unnormalized numbers, and
43 dnl   pseudo-denormals on ia64.
44 AC_DEFUN([gl_ISFINITEL_WORKS],
45 [
46   AC_REQUIRE([AC_PROG_CC])
47   AC_REQUIRE([gl_BIGENDIAN])
48   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
49   AC_CACHE_CHECK([whether isfinite(long double) works], [gl_cv_func_isfinitel_works],
50     [
51       AC_TRY_RUN([
52 #include <float.h>
53 #include <limits.h>
54 #include <math.h>
55 #define NWORDS \
56   ((sizeof (long double) + sizeof (unsigned int) - 1) / sizeof (unsigned int))
57 typedef union { unsigned int word[NWORDS]; long double value; }
58         memory_long_double;
59 int main ()
60 {
61   memory_long_double m;
62   unsigned int i;
63
64   /* The isfinite macro should be immune against changes in the sign bit and
65      in the mantissa bits.  The xor operation twiddles a bit that can only be
66      a sign bit or a mantissa bit (since the exponent never extends to
67      bit 31).  */
68   m.value = 0.0L / 0.0L;
69   m.word[NWORDS / 2] ^= (unsigned int) 1 << (sizeof (unsigned int) * CHAR_BIT - 1);
70   for (i = 0; i < NWORDS; i++)
71     m.word[i] |= 1;
72   if (isfinite (m.value))
73     return 1;
74
75 #if ((defined __ia64 && LDBL_MANT_DIG == 64) || (defined __x86_64__ || defined __amd64__) || (defined __i386 || defined __i386__ || defined _I386 || defined _M_IX86 || defined _X86_))
76 /* Representation of an 80-bit 'long double' as an initializer for a sequence
77    of 'unsigned int' words.  */
78 # ifdef WORDS_BIGENDIAN
79 #  define LDBL80_WORDS(exponent,manthi,mantlo) \
80      { ((unsigned int) (exponent) << 16) | ((unsigned int) (manthi) >> 16), \
81        ((unsigned int) (manthi) << 16) | (unsigned int) (mantlo) >> 16),    \
82        (unsigned int) (mantlo) << 16                                        \
83      }
84 # else
85 #  define LDBL80_WORDS(exponent,manthi,mantlo) \
86      { mantlo, manthi, exponent }
87 # endif
88   { /* Quiet NaN.  */
89     static memory_long_double x =
90       { LDBL80_WORDS (0xFFFF, 0xC3333333, 0x00000000) };
91     if (isfinite (x.value))
92       return 1;
93   }
94   {
95     /* Signalling NaN.  */
96     static memory_long_double x =
97       { LDBL80_WORDS (0xFFFF, 0x83333333, 0x00000000) };
98     if (isfinite (x.value))
99       return 1;
100   }
101   /* The isfinite macro should recognize Pseudo-NaNs, Pseudo-Infinities,
102      Pseudo-Zeroes, Unnormalized Numbers, and Pseudo-Denormals, as defined in
103        Intel IA-64 Architecture Software Developer's Manual, Volume 1:
104        Application Architecture.
105        Table 5-2 "Floating-Point Register Encodings"
106        Figure 5-6 "Memory to Floating-Point Register Data Translation"
107    */
108   { /* Pseudo-NaN.  */
109     static memory_long_double x =
110       { LDBL80_WORDS (0xFFFF, 0x40000001, 0x00000000) };
111     if (isfinite (x.value))
112       return 1;
113   }
114   { /* Pseudo-Infinity.  */
115     static memory_long_double x =
116       { LDBL80_WORDS (0xFFFF, 0x00000000, 0x00000000) };
117     if (isfinite (x.value))
118       return 1;
119   }
120   { /* Pseudo-Zero.  */
121     static memory_long_double x =
122       { LDBL80_WORDS (0x4004, 0x00000000, 0x00000000) };
123     if (isfinite (x.value))
124       return 1;
125   }
126   { /* Unnormalized number.  */
127     static memory_long_double x =
128       { LDBL80_WORDS (0x4000, 0x63333333, 0x00000000) };
129     if (isfinite (x.value))
130       return 1;
131   }
132   { /* Pseudo-Denormal.  */
133     static memory_long_double x =
134       { LDBL80_WORDS (0x0000, 0x83333333, 0x00000000) };
135     if (isfinite (x.value))
136       return 1;
137   }
138 #endif
139
140   return 0;
141 }], [gl_cv_func_isfinitel_works=yes], [gl_cv_func_isfinitel_works=no],
142       [case "$host_cpu" in
143                                # Guess no on ia64, x86_64, i386.
144          ia64 | x86_64 | i*86) gl_cv_func_isnanl_works="guessing no";;
145          *)                    gl_cv_func_isnanl_works="guessing yes";;
146        esac
147       ])
148     ])
149 ])