1# isnanf.m4 serial 14
2dnl Copyright (C) 2007-2012 Free Software Foundation, Inc.
3dnl This file is free software; the Free Software Foundation
4dnl gives unlimited permission to copy and/or distribute it,
5dnl with or without modifications, as long as this notice is preserved.
6
7dnl Check how to get or define isnanf().
8
9AC_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  fi
37  AC_SUBST([ISNANF_LIBM])
38])
39
40dnl Check how to get or define isnanf() without linking with libm.
41
42AC_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    gl_func_isnanf_no_libm=yes
55    AC_DEFINE([HAVE_ISNANF_IN_LIBC], [1],
56      [Define if the isnan(float) function is available in libc.])
57  else
58    gl_func_isnanf_no_libm=no
59  fi
60])
61
62dnl Prerequisites of replacement isnanf definition. It does not need -lm.
63AC_DEFUN([gl_PREREQ_ISNANF],
64[
65  gl_FLOAT_EXPONENT_LOCATION
66])
67
68dnl Test whether isnanf() can be used without libm.
69AC_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_LINK_IFELSE(
75        [AC_LANG_PROGRAM(
76           [[#include <math.h>
77             #if __GNUC__ >= 4
78             # undef isnanf
79             # define isnanf(x) __builtin_isnanf ((float)(x))
80             #elif defined isnan
81             # undef isnanf
82             # define isnanf(x) isnan ((float)(x))
83             #endif
84             float x;]],
85           [[return isnanf (x);]])],
86        [gl_cv_func_isnanf_no_libm=yes],
87        [gl_cv_func_isnanf_no_libm=no])
88    ])
89])
90
91dnl Test whether isnanf() can be used with libm.
92AC_DEFUN([gl_HAVE_ISNANF_IN_LIBM],
93[
94  AC_CACHE_CHECK([whether isnan(float) can be used with libm],
95    [gl_cv_func_isnanf_in_libm],
96    [
97      save_LIBS="$LIBS"
98      LIBS="$LIBS -lm"
99      AC_LINK_IFELSE(
100        [AC_LANG_PROGRAM(
101           [[#include <math.h>
102             #if __GNUC__ >= 4
103             # undef isnanf
104             # define isnanf(x) __builtin_isnanf ((float)(x))
105             #elif defined isnan
106             # undef isnanf
107             # define isnanf(x) isnan ((float)(x))
108             #endif
109             float x;]],
110           [[return isnanf (x);]])],
111        [gl_cv_func_isnanf_in_libm=yes],
112        [gl_cv_func_isnanf_in_libm=no])
113      LIBS="$save_LIBS"
114    ])
115])
116
117dnl Test whether isnanf() rejects Infinity (this fails on Solaris 2.5.1),
118dnl recognizes a NaN (this fails on IRIX 6.5 with cc), and recognizes a NaN
119dnl with in-memory representation 0x7fbfffff (this fails on IRIX 6.5).
120AC_DEFUN([gl_ISNANF_WORKS],
121[
122  AC_REQUIRE([AC_PROG_CC])
123  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
124  AC_REQUIRE([gl_FLOAT_EXPONENT_LOCATION])
125  AC_CACHE_CHECK([whether isnan(float) works], [gl_cv_func_isnanf_works],
126    [
127      AC_RUN_IFELSE(
128        [AC_LANG_SOURCE([[
129#include <math.h>
130#if __GNUC__ >= 4
131# undef isnanf
132# define isnanf(x) __builtin_isnanf ((float)(x))
133#elif defined isnan
134# undef isnanf
135# define isnanf(x) isnan ((float)(x))
136#endif
137/* The Compaq (ex-DEC) C 6.4 compiler chokes on the expression 0.0 / 0.0.  */
138#ifdef __DECC
139static float
140NaN ()
141{
142  static float zero = 0.0f;
143  return zero / zero;
144}
145#else
146# define NaN() (0.0f / 0.0f)
147#endif
148#define NWORDS \
149  ((sizeof (float) + sizeof (unsigned int) - 1) / sizeof (unsigned int))
150typedef union { unsigned int word[NWORDS]; float value; } memory_float;
151int main()
152{
153  int result = 0;
154
155  if (isnanf (1.0f / 0.0f))
156    result |= 1;
157
158  if (!isnanf (NaN ()))
159    result |= 2;
160
161#if defined FLT_EXPBIT0_WORD && defined FLT_EXPBIT0_BIT
162  /* The isnanf function should be immune against changes in the sign bit and
163     in the mantissa bits.  The xor operation twiddles a bit that can only be
164     a sign bit or a mantissa bit.  */
165  if (FLT_EXPBIT0_WORD == 0 && FLT_EXPBIT0_BIT > 0)
166    {
167      memory_float m;
168
169      m.value = NaN ();
170      /* Set the bits below the exponent to 01111...111.  */
171      m.word[0] &= -1U << FLT_EXPBIT0_BIT;
172      m.word[0] |= 1U << (FLT_EXPBIT0_BIT - 1) - 1;
173      if (!isnanf (m.value))
174        result |= 4;
175    }
176#endif
177
178  return result;
179}]])],
180        [gl_cv_func_isnanf_works=yes],
181        [gl_cv_func_isnanf_works=no],
182        [case "$host_os" in
183           irix* | solaris*) gl_cv_func_isnanf_works="guessing no";;
184           *)                gl_cv_func_isnanf_works="guessing yes";;
185         esac
186        ])
187    ])
188])
189