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