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