1 1.1 christos # exponentl.m4 serial 5 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 AC_DEFUN([gl_LONG_DOUBLE_EXPONENT_LOCATION], 7 1.1 christos [ 8 1.1 christos AC_REQUIRE([gl_BIGENDIAN]) 9 1.1 christos AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles 10 1.1 christos AC_CACHE_CHECK([where to find the exponent in a 'long double'], 11 1.1 christos [gl_cv_cc_long_double_expbit0], 12 1.1 christos [ 13 1.1 christos AC_RUN_IFELSE( 14 1.1 christos [AC_LANG_SOURCE([[ 15 1.1 christos #include <float.h> 16 1.1 christos #include <stddef.h> 17 1.1 christos #include <stdio.h> 18 1.1 christos #include <string.h> 19 1.1 christos #define NWORDS \ 20 1.1 christos ((sizeof (long double) + sizeof (unsigned int) - 1) / sizeof (unsigned int)) 21 1.1 christos typedef union { long double value; unsigned int word[NWORDS]; } 22 1.1 christos memory_long_double; 23 1.1 christos static unsigned int ored_words[NWORDS]; 24 1.1 christos static unsigned int anded_words[NWORDS]; 25 1.1 christos static void add_to_ored_words (long double *x) 26 1.1 christos { 27 1.1 christos memory_long_double m; 28 1.1 christos size_t i; 29 1.1 christos /* Clear it first, in case 30 1.1 christos sizeof (long double) < sizeof (memory_long_double). */ 31 1.1 christos memset (&m, 0, sizeof (memory_long_double)); 32 1.1 christos m.value = *x; 33 1.1 christos for (i = 0; i < NWORDS; i++) 34 1.1 christos { 35 1.1 christos ored_words[i] |= m.word[i]; 36 1.1 christos anded_words[i] &= m.word[i]; 37 1.1 christos } 38 1.1 christos } 39 1.1 christos int main () 40 1.1 christos { 41 1.1 christos static long double samples[5] = { 0.25L, 0.5L, 1.0L, 2.0L, 4.0L }; 42 1.1 christos size_t j; 43 1.1 christos FILE *fp = fopen ("conftest.out", "w"); 44 1.1 christos if (fp == NULL) 45 1.1 christos return 1; 46 1.1 christos for (j = 0; j < NWORDS; j++) 47 1.1 christos anded_words[j] = ~ (unsigned int) 0; 48 1.1 christos for (j = 0; j < 5; j++) 49 1.1 christos add_to_ored_words (&samples[j]); 50 1.1 christos /* Remove bits that are common (e.g. if representation of the first mantissa 51 1.1 christos bit is explicit). */ 52 1.1 christos for (j = 0; j < NWORDS; j++) 53 1.1 christos ored_words[j] &= ~anded_words[j]; 54 1.1 christos /* Now find the nonzero word. */ 55 1.1 christos for (j = 0; j < NWORDS; j++) 56 1.1 christos if (ored_words[j] != 0) 57 1.1 christos break; 58 1.1 christos if (j < NWORDS) 59 1.1 christos { 60 1.1 christos size_t i; 61 1.1 christos for (i = j + 1; i < NWORDS; i++) 62 1.1 christos if (ored_words[i] != 0) 63 1.1 christos { 64 1.1 christos fprintf (fp, "unknown"); 65 1.1 christos return (fclose (fp) != 0); 66 1.1 christos } 67 1.1 christos for (i = 0; ; i++) 68 1.1 christos if ((ored_words[j] >> i) & 1) 69 1.1 christos { 70 1.1 christos fprintf (fp, "word %d bit %d", (int) j, (int) i); 71 1.1 christos return (fclose (fp) != 0); 72 1.1 christos } 73 1.1 christos } 74 1.1 christos fprintf (fp, "unknown"); 75 1.1 christos return (fclose (fp) != 0); 76 1.1 christos } 77 1.1 christos ]])], 78 1.1 christos [gl_cv_cc_long_double_expbit0=`cat conftest.out`], 79 1.1 christos [gl_cv_cc_long_double_expbit0="unknown"], 80 1.1 christos [ 81 1.1 christos dnl When cross-compiling, in general we don't know. It depends on the 82 1.1 christos dnl ABI and compiler version. There are too many cases. 83 1.1 christos gl_cv_cc_long_double_expbit0="unknown" 84 1.1 christos case "$host_os" in 85 1.1 christos mingw*) # On native Windows (little-endian), we know the result 86 1.1 christos # in two cases: mingw, MSVC. 87 1.1 christos AC_EGREP_CPP([Known], [ 88 1.1 christos #ifdef __MINGW32__ 89 1.1 christos Known 90 1.1 christos #endif 91 1.1 christos ], [gl_cv_cc_long_double_expbit0="word 2 bit 0"]) 92 1.1 christos AC_EGREP_CPP([Known], [ 93 1.1 christos #ifdef _MSC_VER 94 1.1 christos Known 95 1.1 christos #endif 96 1.1 christos ], [gl_cv_cc_long_double_expbit0="word 1 bit 20"]) 97 1.1 christos ;; 98 1.1 christos esac 99 1.1 christos ]) 100 1.1 christos rm -f conftest.out 101 1.1 christos ]) 102 1.1 christos case "$gl_cv_cc_long_double_expbit0" in 103 1.1 christos word*bit*) 104 1.1 christos word=`echo "$gl_cv_cc_long_double_expbit0" | sed -e 's/word //' -e 's/ bit.*//'` 105 1.1 christos bit=`echo "$gl_cv_cc_long_double_expbit0" | sed -e 's/word.*bit //'` 106 1.1 christos AC_DEFINE_UNQUOTED([LDBL_EXPBIT0_WORD], [$word], 107 1.1 christos [Define as the word index where to find the exponent of 'long double'.]) 108 1.1 christos AC_DEFINE_UNQUOTED([LDBL_EXPBIT0_BIT], [$bit], 109 1.1 christos [Define as the bit index in the word where to find bit 0 of the exponent of 'long double'.]) 110 1.1 christos ;; 111 1.1 christos esac 112 1.1 christos ]) 113