exponentl.m4 3.6 KB

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