signbit.m4 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366
  1. # signbit.m4 serial 13
  2. dnl Copyright (C) 2007-2017 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_SIGNBIT],
  7. [
  8. AC_REQUIRE([gl_MATH_H_DEFAULTS])
  9. AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
  10. AC_CACHE_CHECK([for signbit macro], [gl_cv_func_signbit],
  11. [
  12. AC_RUN_IFELSE(
  13. [AC_LANG_SOURCE([[
  14. #include <math.h>
  15. /* If signbit is defined as a function, don't use it, since calling it for
  16. 'float' or 'long double' arguments would involve conversions.
  17. If signbit is not declared at all but exists as a library function, don't
  18. use it, since the prototype may not match.
  19. If signbit is not declared at all but exists as a compiler built-in, don't
  20. use it, since it's preferable to use __builtin_signbit* (no warnings,
  21. no conversions). */
  22. #ifndef signbit
  23. # error "signbit should be a macro"
  24. #endif
  25. #include <string.h>
  26. ]gl_SIGNBIT_TEST_PROGRAM
  27. ])],
  28. [gl_cv_func_signbit=yes],
  29. [gl_cv_func_signbit=no],
  30. [case "$host_os" in
  31. # Guess yes on glibc systems.
  32. *-gnu*) gl_cv_func_signbit="guessing yes" ;;
  33. # If we don't know, assume the worst.
  34. *) gl_cv_func_signbit="guessing no" ;;
  35. esac
  36. ])
  37. ])
  38. dnl GCC 4.0 and newer provides three built-ins for signbit.
  39. dnl They can be used without warnings, also in C++, regardless of <math.h>.
  40. dnl But they may expand to calls to functions, which may or may not be in
  41. dnl libc.
  42. AC_CACHE_CHECK([for signbit compiler built-ins], [gl_cv_func_signbit_gcc],
  43. [
  44. AC_RUN_IFELSE(
  45. [AC_LANG_SOURCE([[
  46. #if __GNUC__ >= 4
  47. # define signbit(x) \
  48. (sizeof (x) == sizeof (long double) ? __builtin_signbitl (x) : \
  49. sizeof (x) == sizeof (double) ? __builtin_signbit (x) : \
  50. __builtin_signbitf (x))
  51. #else
  52. # error "signbit should be three compiler built-ins"
  53. #endif
  54. #include <string.h>
  55. ]gl_SIGNBIT_TEST_PROGRAM
  56. ])],
  57. [gl_cv_func_signbit_gcc=yes],
  58. [gl_cv_func_signbit_gcc=no],
  59. [case "$host_os" in
  60. # Guess yes on glibc systems.
  61. *-gnu*) gl_cv_func_signbit_gcc="guessing yes" ;;
  62. # If we don't know, assume the worst.
  63. *) gl_cv_func_signbit_gcc="guessing no" ;;
  64. esac
  65. ])
  66. ])
  67. dnl Use the compiler built-ins whenever possible, because they are more
  68. dnl efficient than the system library functions (if they exist).
  69. case "$gl_cv_func_signbit_gcc" in
  70. *yes)
  71. REPLACE_SIGNBIT_USING_GCC=1
  72. ;;
  73. *)
  74. case "$gl_cv_func_signbit" in
  75. *yes) ;;
  76. *)
  77. dnl REPLACE_SIGNBIT=1 makes sure the signbit[fdl] functions get built.
  78. REPLACE_SIGNBIT=1
  79. gl_FLOAT_SIGN_LOCATION
  80. gl_DOUBLE_SIGN_LOCATION
  81. gl_LONG_DOUBLE_SIGN_LOCATION
  82. if test "$gl_cv_cc_float_signbit" = unknown; then
  83. dnl Test whether copysignf() is declared.
  84. AC_CHECK_DECLS([copysignf], , , [[#include <math.h>]])
  85. if test "$ac_cv_have_decl_copysignf" = yes; then
  86. dnl Test whether copysignf() can be used without libm.
  87. AC_CACHE_CHECK([whether copysignf can be used without linking with libm],
  88. [gl_cv_func_copysignf_no_libm],
  89. [
  90. AC_LINK_IFELSE(
  91. [AC_LANG_PROGRAM(
  92. [[#include <math.h>
  93. float x, y;]],
  94. [[return copysignf (x, y) < 0;]])],
  95. [gl_cv_func_copysignf_no_libm=yes],
  96. [gl_cv_func_copysignf_no_libm=no])
  97. ])
  98. if test $gl_cv_func_copysignf_no_libm = yes; then
  99. AC_DEFINE([HAVE_COPYSIGNF_IN_LIBC], [1],
  100. [Define if the copysignf function is declared in <math.h> and available in libc.])
  101. fi
  102. fi
  103. fi
  104. if test "$gl_cv_cc_double_signbit" = unknown; then
  105. dnl Test whether copysign() is declared.
  106. AC_CHECK_DECLS([copysign], , , [[#include <math.h>]])
  107. if test "$ac_cv_have_decl_copysign" = yes; then
  108. dnl Test whether copysign() can be used without libm.
  109. AC_CACHE_CHECK([whether copysign can be used without linking with libm],
  110. [gl_cv_func_copysign_no_libm],
  111. [
  112. AC_LINK_IFELSE(
  113. [AC_LANG_PROGRAM(
  114. [[#include <math.h>
  115. double x, y;]],
  116. [[return copysign (x, y) < 0;]])],
  117. [gl_cv_func_copysign_no_libm=yes],
  118. [gl_cv_func_copysign_no_libm=no])
  119. ])
  120. if test $gl_cv_func_copysign_no_libm = yes; then
  121. AC_DEFINE([HAVE_COPYSIGN_IN_LIBC], [1],
  122. [Define if the copysign function is declared in <math.h> and available in libc.])
  123. fi
  124. fi
  125. fi
  126. if test "$gl_cv_cc_long_double_signbit" = unknown; then
  127. dnl Test whether copysignl() is declared.
  128. AC_CHECK_DECLS([copysignl], , , [[#include <math.h>]])
  129. if test "$ac_cv_have_decl_copysignl" = yes; then
  130. dnl Test whether copysignl() can be used without libm.
  131. AC_CACHE_CHECK([whether copysignl can be used without linking with libm],
  132. [gl_cv_func_copysignl_no_libm],
  133. [
  134. AC_LINK_IFELSE(
  135. [AC_LANG_PROGRAM(
  136. [[#include <math.h>
  137. long double x, y;]],
  138. [[return copysignl (x, y) < 0;]])],
  139. [gl_cv_func_copysignl_no_libm=yes],
  140. [gl_cv_func_copysignl_no_libm=no])
  141. ])
  142. if test $gl_cv_func_copysignl_no_libm = yes; then
  143. AC_DEFINE([HAVE_COPYSIGNL_IN_LIBC], [1],
  144. [Define if the copysignl function is declared in <math.h> and available in libc.])
  145. fi
  146. fi
  147. fi
  148. ;;
  149. esac
  150. ;;
  151. esac
  152. ])
  153. AC_DEFUN([gl_SIGNBIT_TEST_PROGRAM], [[
  154. /* Global variables.
  155. Needed because GCC 4 constant-folds __builtin_signbitl (literal)
  156. but cannot constant-fold __builtin_signbitl (variable). */
  157. float vf;
  158. double vd;
  159. long double vl;
  160. int main ()
  161. {
  162. /* HP cc on HP-UX 10.20 has a bug with the constant expression -0.0.
  163. So we use -p0f and -p0d instead. */
  164. float p0f = 0.0f;
  165. float m0f = -p0f;
  166. double p0d = 0.0;
  167. double m0d = -p0d;
  168. /* On HP-UX 10.20, negating 0.0L does not yield -0.0L.
  169. So we use another constant expression instead.
  170. But that expression does not work on other platforms, such as when
  171. cross-compiling to PowerPC on Mac OS X 10.5. */
  172. long double p0l = 0.0L;
  173. #if defined __hpux || defined __sgi
  174. long double m0l = -LDBL_MIN * LDBL_MIN;
  175. #else
  176. long double m0l = -p0l;
  177. #endif
  178. int result = 0;
  179. if (signbit (vf)) /* link check */
  180. vf++;
  181. {
  182. float plus_inf = 1.0f / p0f;
  183. float minus_inf = -1.0f / p0f;
  184. if (!(!signbit (255.0f)
  185. && signbit (-255.0f)
  186. && !signbit (p0f)
  187. && (memcmp (&m0f, &p0f, sizeof (float)) == 0 || signbit (m0f))
  188. && !signbit (plus_inf)
  189. && signbit (minus_inf)))
  190. result |= 1;
  191. }
  192. if (signbit (vd)) /* link check */
  193. vd++;
  194. {
  195. double plus_inf = 1.0 / p0d;
  196. double minus_inf = -1.0 / p0d;
  197. if (!(!signbit (255.0)
  198. && signbit (-255.0)
  199. && !signbit (p0d)
  200. && (memcmp (&m0d, &p0d, sizeof (double)) == 0 || signbit (m0d))
  201. && !signbit (plus_inf)
  202. && signbit (minus_inf)))
  203. result |= 2;
  204. }
  205. if (signbit (vl)) /* link check */
  206. vl++;
  207. {
  208. long double plus_inf = 1.0L / p0l;
  209. long double minus_inf = -1.0L / p0l;
  210. if (signbit (255.0L))
  211. result |= 4;
  212. if (!signbit (-255.0L))
  213. result |= 4;
  214. if (signbit (p0l))
  215. result |= 8;
  216. if (!(memcmp (&m0l, &p0l, sizeof (long double)) == 0 || signbit (m0l)))
  217. result |= 16;
  218. if (signbit (plus_inf))
  219. result |= 32;
  220. if (!signbit (minus_inf))
  221. result |= 64;
  222. }
  223. return result;
  224. }
  225. ]])
  226. AC_DEFUN([gl_FLOAT_SIGN_LOCATION],
  227. [
  228. gl_FLOATTYPE_SIGN_LOCATION([float], [gl_cv_cc_float_signbit], [f], [FLT])
  229. ])
  230. AC_DEFUN([gl_DOUBLE_SIGN_LOCATION],
  231. [
  232. gl_FLOATTYPE_SIGN_LOCATION([double], [gl_cv_cc_double_signbit], [], [DBL])
  233. ])
  234. AC_DEFUN([gl_LONG_DOUBLE_SIGN_LOCATION],
  235. [
  236. gl_FLOATTYPE_SIGN_LOCATION([long double], [gl_cv_cc_long_double_signbit], [L], [LDBL])
  237. ])
  238. AC_DEFUN([gl_FLOATTYPE_SIGN_LOCATION],
  239. [
  240. AC_CACHE_CHECK([where to find the sign bit in a '$1'],
  241. [$2],
  242. [
  243. AC_RUN_IFELSE(
  244. [AC_LANG_SOURCE([[
  245. #include <stddef.h>
  246. #include <stdio.h>
  247. #define NWORDS \
  248. ((sizeof ($1) + sizeof (unsigned int) - 1) / sizeof (unsigned int))
  249. typedef union { $1 value; unsigned int word[NWORDS]; }
  250. memory_float;
  251. static memory_float plus = { 1.0$3 };
  252. static memory_float minus = { -1.0$3 };
  253. int main ()
  254. {
  255. size_t j, k, i;
  256. unsigned int m;
  257. FILE *fp = fopen ("conftest.out", "w");
  258. if (fp == NULL)
  259. return 1;
  260. /* Find the different bit. */
  261. k = 0; m = 0;
  262. for (j = 0; j < NWORDS; j++)
  263. {
  264. unsigned int x = plus.word[j] ^ minus.word[j];
  265. if ((x & (x - 1)) || (x && m))
  266. {
  267. /* More than one bit difference. */
  268. fprintf (fp, "unknown");
  269. return 2;
  270. }
  271. if (x)
  272. {
  273. k = j;
  274. m = x;
  275. }
  276. }
  277. if (m == 0)
  278. {
  279. /* No difference. */
  280. fprintf (fp, "unknown");
  281. return 3;
  282. }
  283. /* Now m = plus.word[k] ^ ~minus.word[k]. */
  284. if (plus.word[k] & ~minus.word[k])
  285. {
  286. /* Oh? The sign bit is set in the positive and cleared in the negative
  287. numbers? */
  288. fprintf (fp, "unknown");
  289. return 4;
  290. }
  291. for (i = 0; ; i++)
  292. if ((m >> i) & 1)
  293. break;
  294. fprintf (fp, "word %d bit %d", (int) k, (int) i);
  295. if (fclose (fp) != 0)
  296. return 5;
  297. return 0;
  298. }
  299. ]])],
  300. [$2=`cat conftest.out`],
  301. [$2="unknown"],
  302. [
  303. dnl When cross-compiling, we don't know. It depends on the
  304. dnl ABI and compiler version. There are too many cases.
  305. $2="unknown"
  306. ])
  307. rm -f conftest.out
  308. ])
  309. case "$]$2[" in
  310. word*bit*)
  311. word=`echo "$]$2[" | sed -e 's/word //' -e 's/ bit.*//'`
  312. bit=`echo "$]$2[" | sed -e 's/word.*bit //'`
  313. AC_DEFINE_UNQUOTED([$4][_SIGNBIT_WORD], [$word],
  314. [Define as the word index where to find the sign of '$1'.])
  315. AC_DEFINE_UNQUOTED([$4][_SIGNBIT_BIT], [$bit],
  316. [Define as the bit index in the word where to find the sign of '$1'.])
  317. ;;
  318. esac
  319. ])
  320. # Expands to code that defines a function signbitf(float).
  321. # It extracts the sign bit of a non-NaN value.
  322. AC_DEFUN([gl_FLOAT_SIGNBIT_CODE],
  323. [
  324. gl_FLOATTYPE_SIGNBIT_CODE([float], [f], [f])
  325. ])
  326. # Expands to code that defines a function signbitd(double).
  327. # It extracts the sign bit of a non-NaN value.
  328. AC_DEFUN([gl_DOUBLE_SIGNBIT_CODE],
  329. [
  330. gl_FLOATTYPE_SIGNBIT_CODE([double], [d], [])
  331. ])
  332. # Expands to code that defines a function signbitl(long double).
  333. # It extracts the sign bit of a non-NaN value.
  334. AC_DEFUN([gl_LONG_DOUBLE_SIGNBIT_CODE],
  335. [
  336. gl_FLOATTYPE_SIGNBIT_CODE([long double], [l], [L])
  337. ])
  338. AC_DEFUN([gl_FLOATTYPE_SIGNBIT_CODE],
  339. [[
  340. static int
  341. signbit$2 ($1 value)
  342. {
  343. typedef union { $1 f; unsigned char b[sizeof ($1)]; } float_union;
  344. static float_union plus_one = { 1.0$3 }; /* unused bits are zero here */
  345. static float_union minus_one = { -1.0$3 }; /* unused bits are zero here */
  346. /* Compute the sign bit mask as the XOR of plus_one and minus_one. */
  347. float_union u;
  348. unsigned int i;
  349. u.f = value;
  350. for (i = 0; i < sizeof ($1); i++)
  351. if (u.b[i] & (plus_one.b[i] ^ minus_one.b[i]))
  352. return 1;
  353. return 0;
  354. }
  355. ]])