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