1# isnanl.m4 serial 17 2dnl Copyright (C) 2007-2012 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 #if __GNUC__ >= 4 72 # undef isnanl 73 # define isnanl(x) __builtin_isnanl ((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 85dnl Test whether isnanl() can be used with libm. 86AC_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 97 # undef isnanl 98 # define isnanl(x) __builtin_isnanl ((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 111dnl Test whether isnanl() recognizes all numbers which are neither finite nor 112dnl infinite. This test fails e.g. on NetBSD/i386 and on glibc/ia64. 113dnl Also, the GCC >= 4.0 built-in __builtin_isnanl does not pass the tests 114dnl - for pseudo-denormals on i686 and x86_64, 115dnl - for pseudo-zeroes, unnormalized numbers, and pseudo-denormals on ia64. 116AC_DEFUN([gl_FUNC_ISNANL_WORKS], 117[ 118 AC_REQUIRE([AC_PROG_CC]) 119 AC_REQUIRE([gl_BIGENDIAN]) 120 AC_REQUIRE([gl_LONG_DOUBLE_VS_DOUBLE]) 121 AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles 122 AC_CACHE_CHECK([whether isnanl works], [gl_cv_func_isnanl_works], 123 [ 124 AC_RUN_IFELSE( 125 [AC_LANG_SOURCE([[ 126#include <float.h> 127#include <limits.h> 128#include <math.h> 129#if __GNUC__ >= 4 130# undef isnanl 131# define isnanl(x) __builtin_isnanl ((long double)(x)) 132#elif defined isnan 133# undef isnanl 134# define isnanl(x) isnan ((long double)(x)) 135#endif 136#define NWORDS \ 137 ((sizeof (long double) + sizeof (unsigned int) - 1) / sizeof (unsigned int)) 138typedef union { unsigned int word[NWORDS]; long double value; } 139 memory_long_double; 140/* On Irix 6.5, gcc 3.4.3 can't compute compile-time NaN, and needs the 141 runtime type conversion. */ 142#ifdef __sgi 143static long double NaNl () 144{ 145 double zero = 0.0; 146 return zero / zero; 147} 148#else 149# define NaNl() (0.0L / 0.0L) 150#endif 151int main () 152{ 153 int result = 0; 154 155 if (!isnanl (NaNl ())) 156 result |= 1; 157 158 { 159 memory_long_double m; 160 unsigned int i; 161 162 /* The isnanl 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 (since the exponent never extends to 165 bit 31). */ 166 m.value = NaNl (); 167 m.word[NWORDS / 2] ^= (unsigned int) 1 << (sizeof (unsigned int) * CHAR_BIT - 1); 168 for (i = 0; i < NWORDS; i++) 169 m.word[i] |= 1; 170 if (!isnanl (m.value)) 171 result |= 1; 172 } 173 174#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 175/* Representation of an 80-bit 'long double' as an initializer for a sequence 176 of 'unsigned int' words. */ 177# ifdef WORDS_BIGENDIAN 178# define LDBL80_WORDS(exponent,manthi,mantlo) \ 179 { ((unsigned int) (exponent) << 16) | ((unsigned int) (manthi) >> 16), \ 180 ((unsigned int) (manthi) << 16) | (unsigned int) (mantlo) >> 16), \ 181 (unsigned int) (mantlo) << 16 \ 182 } 183# else 184# define LDBL80_WORDS(exponent,manthi,mantlo) \ 185 { mantlo, manthi, exponent } 186# endif 187 { /* Quiet NaN. */ 188 static memory_long_double x = 189 { LDBL80_WORDS (0xFFFF, 0xC3333333, 0x00000000) }; 190 if (!isnanl (x.value)) 191 result |= 2; 192 } 193 { 194 /* Signalling NaN. */ 195 static memory_long_double x = 196 { LDBL80_WORDS (0xFFFF, 0x83333333, 0x00000000) }; 197 if (!isnanl (x.value)) 198 result |= 2; 199 } 200 /* The isnanl function should recognize Pseudo-NaNs, Pseudo-Infinities, 201 Pseudo-Zeroes, Unnormalized Numbers, and Pseudo-Denormals, as defined in 202 Intel IA-64 Architecture Software Developer's Manual, Volume 1: 203 Application Architecture. 204 Table 5-2 "Floating-Point Register Encodings" 205 Figure 5-6 "Memory to Floating-Point Register Data Translation" 206 */ 207 { /* Pseudo-NaN. */ 208 static memory_long_double x = 209 { LDBL80_WORDS (0xFFFF, 0x40000001, 0x00000000) }; 210 if (!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)) 217 result |= 8; 218 } 219 { /* Pseudo-Zero. */ 220 static memory_long_double x = 221 { LDBL80_WORDS (0x4004, 0x00000000, 0x00000000) }; 222 if (!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)) 229 result |= 32; 230 } 231 { /* Pseudo-Denormal. */ 232 static memory_long_double x = 233 { LDBL80_WORDS (0x0000, 0x83333333, 0x00000000) }; 234 if (!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_cpu" in 244 # Guess no on ia64, x86_64, i386. 245 ia64 | x86_64 | i*86) gl_cv_func_isnanl_works="guessing no";; 246 *) 247 case "$host_os" in 248 netbsd*) gl_cv_func_isnanl_works="guessing no";; 249 *) gl_cv_func_isnanl_works="guessing yes";; 250 esac 251 ;; 252 esac 253 ]) 254 ]) 255]) 256