Home | History | Annotate | Download | only in m4
      1 # isnanf.m4 serial 14
      2 dnl Copyright (C) 2007-2012 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   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     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 
     62 dnl Prerequisites of replacement isnanf definition. It does not need -lm.
     63 AC_DEFUN([gl_PREREQ_ISNANF],
     64 [
     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_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 
     91 dnl Test whether isnanf() can be used with libm.
     92 AC_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 
    117 dnl Test whether isnanf() rejects Infinity (this fails on Solaris 2.5.1),
    118 dnl recognizes a NaN (this fails on IRIX 6.5 with cc), and recognizes a NaN
    119 dnl with in-memory representation 0x7fbfffff (this fails on IRIX 6.5).
    120 AC_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
    139 static float
    140 NaN ()
    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))
    150 typedef union { unsigned int word[NWORDS]; float value; } memory_float;
    151 int 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