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