xref: /netbsd-src/external/lgpl3/mpfr/dist/acinclude.m4 (revision 867d70fc718005c0918b8b8b2f9d7f2d52d0a0db)
1dnl  MPFR specific autoconf macros
2
3dnl  Copyright 2000, 2002-2020 Free Software Foundation, Inc.
4dnl  Contributed by the AriC and Caramba projects, INRIA.
5dnl
6dnl  This file is part of the GNU MPFR Library.
7dnl
8dnl  The GNU MPFR Library is free software; you can redistribute it and/or modify
9dnl  it under the terms of the GNU Lesser General Public License as published
10dnl  by the Free Software Foundation; either version 3 of the License, or (at
11dnl  your option) any later version.
12dnl
13dnl  The GNU MPFR Library is distributed in the hope that it will be useful, but
14dnl  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15dnl  or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
16dnl  License for more details.
17dnl
18dnl  You should have received a copy of the GNU Lesser General Public License
19dnl  along with the GNU MPFR Library; see the file COPYING.LESSER.  If not, see
20dnl  https://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
21dnl  51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
22
23dnl  autoconf 2.60 is necessary because of the use of AC_PROG_SED.
24dnl  The following line allows the autoconf wrapper (when installed)
25dnl  to work as expected.
26dnl  If you change the required version, please update README.dev too!
27AC_PREREQ(2.60)
28
29dnl ------------------------------------------------------------
30dnl You must put in MPFR_CONFIGS everything that configures MPFR except:
31dnl   - Everything dealing with CC and CFLAGS in particular the ABI
32dnl     but the IEEE-754 specific flags must be set here.
33dnl   - Tests that depend on gmp.h (see MPFR_CHECK_DBL2INT_BUG as an example:
34dnl     a function needs to be defined and called in configure.ac).
35dnl   - GMP's linkage.
36dnl   - Libtool stuff.
37dnl   - Handling of special arguments of MPFR's configure.
38AC_DEFUN([MPFR_CONFIGS],
39[
40AC_REQUIRE([AC_OBJEXT])
41AC_REQUIRE([MPFR_CHECK_LIBM])
42AC_REQUIRE([MPFR_CHECK_LIBQUADMATH])
43AC_REQUIRE([AC_HEADER_TIME])
44AC_REQUIRE([AC_CANONICAL_HOST])
45
46dnl Features for the MPFR shared cache. This needs to be done
47dnl quite early since this may change CC, CFLAGS and LIBS, which
48dnl may affect the other tests.
49
50if test "$enable_shared_cache" = yes; then
51
52dnl Prefer ISO C11 threads (as in mpfr-thread.h).
53  MPFR_CHECK_C11_THREAD()
54
55  if test "$mpfr_c11_thread_ok" != yes; then
56dnl Check for POSIX threads. Since the AX_PTHREAD macro is not standard
57dnl (it is provided by autoconf-archive), we need to detect whether it
58dnl is left unexpanded, otherwise the configure script won't fail and
59dnl "make distcheck" won't give any error, yielding buggy tarballs!
60dnl The \b is necessary to avoid an error with recent ax_pthread.m4
61dnl (such as with Debian's autoconf-archive 20160320-1), which contains
62dnl AX_PTHREAD_ZOS_MISSING, etc. It is not documented, but see:
63dnl   https://lists.gnu.org/archive/html/autoconf/2015-03/msg00011.html
64dnl
65dnl Note: each time a change is done in m4_pattern_forbid, autogen.sh
66dnl should be tested with and without ax_pthread.m4 availability (in
67dnl the latter case, there should be an error).
68    m4_pattern_forbid([AX_PTHREAD\b])
69    AX_PTHREAD([])
70    if test "$ax_pthread_ok" = yes; then
71      CC="$PTHREAD_CC"
72      CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
73      LIBS="$LIBS $PTHREAD_LIBS"
74dnl Do a compilation test, as this is currently not done by AX_PTHREAD.
75dnl Moreover, MPFR needs pthread_rwlock_t, which is conditionally defined
76dnl in glibc's bits/pthreadtypes.h (via <pthread.h>), not sure why...
77      AC_MSG_CHECKING([for pthread_rwlock_t])
78      AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
79#include <pthread.h>
80]], [[
81pthread_rwlock_t lock; (void) lock;
82]])],
83        [AC_MSG_RESULT([yes])
84         mpfr_pthread_ok=yes],
85        [AC_MSG_RESULT([no])
86         mpfr_pthread_ok=no])
87    else
88      mpfr_pthread_ok=no
89    fi
90  fi
91
92  AC_MSG_CHECKING(if shared cache can be supported)
93  if test "$mpfr_c11_thread_ok" = yes; then
94    AC_MSG_RESULT([yes, with ISO C11 threads])
95  elif test "$mpfr_pthread_ok" = yes; then
96    AC_MSG_RESULT([yes, with pthread])
97  else
98    AC_MSG_RESULT(no)
99    AC_MSG_ERROR([shared cache needs C11 threads or pthread support])
100  fi
101
102fi
103
104dnl End of features for the MPFR shared cache.
105
106AC_CHECK_HEADER([limits.h],, AC_MSG_ERROR([limits.h not found]))
107AC_CHECK_HEADER([float.h],,  AC_MSG_ERROR([float.h not found]))
108AC_CHECK_HEADER([string.h],, AC_MSG_ERROR([string.h not found]))
109
110dnl Check for locales
111AC_CHECK_HEADERS([locale.h])
112
113dnl Check for wide characters (wchar_t and wint_t)
114AC_CHECK_HEADERS([wchar.h])
115
116dnl Check for stdargs
117AC_CHECK_HEADER([stdarg.h],[AC_DEFINE([HAVE_STDARG],1,[Define if stdarg])],
118  [AC_CHECK_HEADER([varargs.h],,
119    AC_MSG_ERROR([stdarg.h or varargs.h not found]))])
120
121dnl sys/fpu.h - MIPS specific
122AC_CHECK_HEADERS([sys/time.h sys/fpu.h])
123
124dnl Android has a <locale.h>, but not the following members.
125AC_CHECK_MEMBERS([struct lconv.decimal_point, struct lconv.thousands_sep],,,
126  [#include <locale.h>])
127
128dnl Check how to get `alloca'
129AC_FUNC_ALLOCA
130
131dnl Define uintptr_t if not available.
132AC_TYPE_UINTPTR_T
133
134dnl va_copy macro
135AC_MSG_CHECKING([how to copy va_list])
136AC_LINK_IFELSE([AC_LANG_PROGRAM([[
137#include <stdarg.h>
138]], [[
139   va_list ap1, ap2;
140   va_copy(ap1, ap2);
141]])], [
142   AC_MSG_RESULT([va_copy])
143   AC_DEFINE(HAVE_VA_COPY)
144], [AC_LINK_IFELSE([AC_LANG_PROGRAM([[
145#include <stdarg.h>
146]], [[
147   va_list ap1, ap2;
148   __va_copy(ap1, ap2);
149]])], [AC_DEFINE([HAVE___VA_COPY]) AC_MSG_RESULT([__va_copy])],
150   [AC_MSG_RESULT([memcpy])])])
151
152dnl Options like -Werror can yield a failure as AC_CHECK_FUNCS uses some
153dnl fixed prototype for function detection, generally incompatible with
154dnl the standard one. For instance, with GCC, if the function is defined
155dnl as a builtin, one can get a "conflicting types for built-in function"
156dnl error [-Werror=builtin-declaration-mismatch], even though the header
157dnl is not included; when these functions were tested, this occurred with
158dnl memmove and memset. Even though no failures are known with the tested
159dnl functions at this time, let's remove options starting with "-Werror"
160dnl since failures may still be possible.
161dnl
162dnl The gettimeofday function is not defined with MinGW.
163saved_CFLAGS="$CFLAGS"
164CFLAGS=`[echo " $CFLAGS" | $SED 's/ -Werror[^ ]*//g']`
165AC_CHECK_FUNCS([setlocale gettimeofday signal])
166CFLAGS="$saved_CFLAGS"
167
168dnl We cannot use AC_CHECK_FUNCS on sigaction, because while this
169dnl function may be provided by the C library, its prototype and
170dnl associated structure may not be available, e.g. when compiling
171dnl with "gcc -std=c99".
172AC_MSG_CHECKING(for sigaction and its associated structure)
173AC_LINK_IFELSE([AC_LANG_PROGRAM([[
174#include <signal.h>
175static int f (int (*func)(int, const struct sigaction *, struct sigaction *))
176{ return 0; }
177]], [[
178 return f(sigaction);
179]])], [
180   AC_MSG_RESULT(yes)
181   AC_DEFINE(HAVE_SIGACTION, 1,
182    [Define if you have a working sigaction function.])
183],[AC_MSG_RESULT(no)])
184
185dnl check for long long
186AC_CHECK_TYPE([long long int],
187   AC_DEFINE(HAVE_LONG_LONG, 1, [Define if compiler supports long long]),,)
188
189dnl intmax_t is C99
190AC_CHECK_TYPES([intmax_t])
191if test "$ac_cv_type_intmax_t" = yes; then
192  AC_CACHE_CHECK([for working INTMAX_MAX], mpfr_cv_have_intmax_max, [
193    saved_CPPFLAGS="$CPPFLAGS"
194    CPPFLAGS="$CPPFLAGS -I$srcdir/src -DMPFR_NEED_INTMAX_H"
195    AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
196        [[#include "mpfr-intmax.h"]],
197        [[intmax_t x = INTMAX_MAX; (void) x;]]
198      )],
199      mpfr_cv_have_intmax_max=yes, mpfr_cv_have_intmax_max=no)
200    CPPFLAGS="$saved_CPPFLAGS"
201  ])
202  if test "$mpfr_cv_have_intmax_max" = "yes"; then
203    AC_DEFINE(MPFR_HAVE_INTMAX_MAX,1,[Define if you have a working INTMAX_MAX.])
204  fi
205fi
206
207AC_CHECK_TYPE( [union fpc_csr],
208   AC_DEFINE(HAVE_FPC_CSR,1,[Define if union fpc_csr is available]), ,
209[
210#if HAVE_SYS_FPU_H
211#  include <sys/fpu.h>
212#endif
213])
214
215dnl Check for _Noreturn function specifier (ISO C11)
216AC_CACHE_CHECK([for _Noreturn], mpfr_cv_have_noreturn, [
217  AC_COMPILE_IFELSE([AC_LANG_SOURCE([[_Noreturn void foo(int);]])],
218    mpfr_cv_have_noreturn=yes, mpfr_cv_have_noreturn=no)
219])
220if test "$mpfr_cv_have_noreturn" = "yes"; then
221  AC_DEFINE(MPFR_HAVE_NORETURN,1,[Define if the _Noreturn function specifier is supported.])
222fi
223
224dnl Check for __builtin_unreachable
225AC_CACHE_CHECK([for __builtin_unreachable], mpfr_cv_have_builtin_unreachable,
226[
227  AC_LINK_IFELSE([AC_LANG_PROGRAM(
228      [[int x;]],
229      [[if (x) __builtin_unreachable(); ]]
230    )],
231    mpfr_cv_have_builtin_unreachable=yes,
232    mpfr_cv_have_builtin_unreachable=no)
233])
234if test "$mpfr_cv_have_builtin_unreachable" = "yes"; then
235  AC_DEFINE(MPFR_HAVE_BUILTIN_UNREACHABLE, 1,
236   [Define if the __builtin_unreachable GCC built-in is supported.])
237fi
238
239dnl Check for attribute constructor and destructor
240MPFR_CHECK_CONSTRUCTOR_ATTR()
241
242dnl Check for fesetround
243AC_CACHE_CHECK([for fesetround], mpfr_cv_have_fesetround, [
244saved_LIBS="$LIBS"
245LIBS="$LIBS $MPFR_LIBM"
246AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <fenv.h>]], [[fesetround(FE_TONEAREST);]])],
247  mpfr_cv_have_fesetround=yes, mpfr_cv_have_fesetround=no)
248LIBS="$saved_LIBS"
249])
250if test "$mpfr_cv_have_fesetround" = "yes"; then
251  AC_DEFINE(MPFR_HAVE_FESETROUND,1,[Define if you have the `fesetround' function via the <fenv.h> header file.])
252fi
253
254dnl Check for gcc float-conversion bug; if need be, -ffloat-store is used to
255dnl force the conversion to the destination type when a value is stored to
256dnl a variable (see ISO C99 standard 5.1.2.3#13, 6.3.1.5#2, 6.3.1.8#2). This
257dnl is important concerning the exponent range. Note that this doesn't solve
258dnl the double-rounding problem.
259if test -n "$GCC"; then
260  AC_CACHE_CHECK([for gcc float-conversion bug], mpfr_cv_gcc_floatconv_bug, [
261  saved_LIBS="$LIBS"
262  LIBS="$LIBS $MPFR_LIBM"
263  AC_RUN_IFELSE([AC_LANG_SOURCE([[
264#include <float.h>
265#ifdef MPFR_HAVE_FESETROUND
266#include <fenv.h>
267#endif
268static double get_max (void);
269int main (void) {
270  double x = 0.5;
271  double y;
272  int i;
273  for (i = 1; i <= 11; i++)
274    x *= x;
275  if (x != 0)
276    return 1;
277#ifdef MPFR_HAVE_FESETROUND
278  /* Useful test for the G4 PowerPC */
279  fesetround(FE_TOWARDZERO);
280  x = y = get_max ();
281  x *= 2.0;
282  if (x != y)
283    return 1;
284#endif
285  return 0;
286}
287static double get_max (void) { static volatile double d = DBL_MAX; return d; }
288  ]])],
289     [mpfr_cv_gcc_floatconv_bug="no"],
290     [mpfr_cv_gcc_floatconv_bug="yes, use -ffloat-store"],
291     [mpfr_cv_gcc_floatconv_bug="cannot test, use -ffloat-store"])
292  LIBS="$saved_LIBS"
293  ])
294  if test "$mpfr_cv_gcc_floatconv_bug" != "no"; then
295    CFLAGS="$CFLAGS -ffloat-store"
296  fi
297fi
298
299dnl Check if subnormal numbers are supported.
300dnl for the binary64 format, the smallest normal number is 2^(-1022)
301dnl for the binary32 format, the smallest normal number is 2^(-126)
302dnl Note: One could double-check with the value of the macros
303dnl DBL_HAS_SUBNORM and FLT_HAS_SUBNORM, when defined (C2x), but
304dnl neither tests would be reliable on implementations with partial
305dnl subnormal support. Anyway, this check is useful only for the
306dnl tests. Thus in doubt, assume that subnormals are not supported,
307dnl in order to disable the corresponding tests (which could fail).
308AC_CACHE_CHECK([for subnormal double-precision numbers],
309mpfr_cv_have_subnorm_dbl, [
310AC_RUN_IFELSE([AC_LANG_SOURCE([[
311#include <stdio.h>
312int main (void) {
313  double x = 2.22507385850720138309e-308;
314  fprintf (stderr, "%e\n", x / 2.0);
315  return 2.0 * (double) (x / 2.0) != x;
316}
317]])],
318   [mpfr_cv_have_subnorm_dbl="yes"],
319   [mpfr_cv_have_subnorm_dbl="no"],
320   [mpfr_cv_have_subnorm_dbl="cannot test, assume no"])
321])
322if test "$mpfr_cv_have_subnorm_dbl" = "yes"; then
323  AC_DEFINE(HAVE_SUBNORM_DBL, 1,
324   [Define if the double type fully supports subnormals.])
325fi
326AC_CACHE_CHECK([for subnormal single-precision numbers],
327mpfr_cv_have_subnorm_flt, [
328AC_RUN_IFELSE([AC_LANG_SOURCE([[
329#include <stdio.h>
330int main (void) {
331  float x = 1.17549435082229e-38;
332  fprintf (stderr, "%e\n", x / 2.0);
333  return 2.0 * (float) (x / 2.0) != x;
334}
335]])],
336   [mpfr_cv_have_subnorm_flt="yes"],
337   [mpfr_cv_have_subnorm_flt="no"],
338   [mpfr_cv_have_subnorm_flt="cannot test, assume no"])
339])
340if test "$mpfr_cv_have_subnorm_flt" = "yes"; then
341  AC_DEFINE(HAVE_SUBNORM_FLT, 1,
342   [Define if the float type fully supports subnormals.])
343fi
344
345dnl Check if signed zeros are supported. Note: the test will fail
346dnl if the division by 0 generates a trap.
347AC_CACHE_CHECK([for signed zeros], mpfr_cv_have_signedz, [
348AC_RUN_IFELSE([AC_LANG_SOURCE([[
349int main (void) {
350  return 1.0 / 0.0 == 1.0 / -0.0;
351}
352]])],
353   [mpfr_cv_have_signedz="yes"],
354   [mpfr_cv_have_signedz="no"],
355   [mpfr_cv_have_signedz="cannot test, assume no"])
356])
357if test "$mpfr_cv_have_signedz" = "yes"; then
358  AC_DEFINE(HAVE_SIGNEDZ,1,[Define if signed zeros are supported.])
359fi
360
361dnl Check the FP division by 0 fails (e.g. on a non-IEEE-754 platform).
362dnl In such a case, MPFR_ERRDIVZERO is defined to disable the tests
363dnl involving a FP division by 0.
364dnl For the developers: to check whether all these tests are disabled,
365dnl configure MPFR with "-DMPFR_TESTS_FPE_DIV -DMPFR_ERRDIVZERO".
366AC_CACHE_CHECK([if the FP division by 0 fails], mpfr_cv_errdivzero, [
367AC_RUN_IFELSE([AC_LANG_SOURCE([[
368int main (void) {
369  volatile double d = 0.0, x;
370  x = 0.0 / d;
371  x = 1.0 / d;
372  (void) x;
373  return 0;
374}
375]])],
376   [mpfr_cv_errdivzero="no"],
377   [mpfr_cv_errdivzero="yes"],
378   [mpfr_cv_errdivzero="cannot test, assume no"])
379])
380if test "$mpfr_cv_errdivzero" = "yes"; then
381  AC_DEFINE(MPFR_ERRDIVZERO,1,[Define if the FP division by 0 fails.])
382  AC_MSG_WARN([The floating-point division by 0 fails instead of])
383  AC_MSG_WARN([returning a special value: NaN or infinity. Tests])
384  AC_MSG_WARN([involving a FP division by 0 will be disabled.])
385fi
386
387dnl Check whether NAN != NAN (as required by the IEEE-754 standard,
388dnl but not by the ISO C standard). For instance, this is false with
389dnl MIPSpro 7.3.1.3m under IRIX64. By default, assume this is true.
390AC_CACHE_CHECK([if NAN == NAN], mpfr_cv_nanisnan, [
391AC_RUN_IFELSE([AC_LANG_SOURCE([[
392#include <stdio.h>
393#include <math.h>
394#ifndef NAN
395# define NAN (0.0/0.0)
396#endif
397int main (void) {
398  double d;
399  d = NAN;
400  return d != d;
401}
402]])],
403   [mpfr_cv_nanisnan="yes"],
404   [mpfr_cv_nanisnan="no"],
405   [mpfr_cv_nanisnan="cannot test, assume no"])
406])
407if test "$mpfr_cv_nanisnan" = "yes"; then
408  AC_DEFINE(MPFR_NANISNAN,1,[Define if NAN == NAN.])
409  AC_MSG_WARN([The test NAN != NAN is false. The probable reason is that])
410  AC_MSG_WARN([your compiler optimizes floating-point expressions in an])
411  AC_MSG_WARN([unsafe way because some option, such as -ffast-math or])
412  AC_MSG_WARN([-fast (depending on the compiler), has been used.  You])
413  AC_MSG_WARN([should NOT use such an option, otherwise MPFR functions])
414  AC_MSG_WARN([such as mpfr_get_d and mpfr_set_d may return incorrect])
415  AC_MSG_WARN([results on special FP numbers (e.g. NaN or signed zeros).])
416  AC_MSG_WARN([If you did not use such an option, please send us a bug])
417  AC_MSG_WARN([report so that we can try to find a workaround for your])
418  AC_MSG_WARN([platform and/or document the behavior.])
419fi
420
421dnl Check if the chars '0' to '9', 'a' to 'z', and 'A' to 'Z' are
422dnl consecutive values.
423dnl The const is necessary with GCC's "-Wwrite-strings -Werror".
424AC_MSG_CHECKING([if charset has consecutive values])
425AC_RUN_IFELSE([AC_LANG_PROGRAM([[
426const char *number = "0123456789";
427const char *lower  = "abcdefghijklmnopqrstuvwxyz";
428const char *upper  = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
429]],[[
430 int i;
431 unsigned char *p;
432 for (p = (unsigned char*) number, i = 0; i < 9; i++)
433   if ( (*p)+1 != *(p+1) ) return 1;
434 for (p = (unsigned char*) lower, i = 0; i < 25; i++)
435   if ( (*p)+1 != *(p+1) ) return 1;
436 for (p = (unsigned char*) upper, i = 0; i < 25; i++)
437   if ( (*p)+1 != *(p+1) ) return 1;
438]])], [AC_MSG_RESULT(yes)],[
439 AC_MSG_RESULT(no)
440 AC_DEFINE(MPFR_NO_CONSECUTIVE_CHARSET,1,[Charset is not consecutive])
441], [AC_MSG_RESULT(cannot test)])
442
443dnl Must be checked with the LIBM
444dnl but we don't want to add the LIBM to MPFR dependency.
445dnl Can't use AC_CHECK_FUNCS since the function may be in LIBM but
446dnl not exported in math.h
447saved_LIBS="$LIBS"
448LIBS="$LIBS $MPFR_LIBM"
449dnl AC_CHECK_FUNCS([round trunc floor ceil nearbyint])
450AC_MSG_CHECKING(for math/round)
451AC_LINK_IFELSE([AC_LANG_PROGRAM([[
452#include <math.h>
453static int f (double (*func)(double)) { return 0; }
454]], [[
455 return f(round);
456]])], [
457   AC_MSG_RESULT(yes)
458   AC_DEFINE(HAVE_ROUND, 1,[Have ISO C99 round function])
459],[AC_MSG_RESULT(no)])
460
461AC_MSG_CHECKING(for math/trunc)
462AC_LINK_IFELSE([AC_LANG_PROGRAM([[
463#include <math.h>
464static int f (double (*func)(double)) { return 0; }
465]], [[
466 return f(trunc);
467]])], [
468   AC_MSG_RESULT(yes)
469   AC_DEFINE(HAVE_TRUNC, 1,[Have ISO C99 trunc function])
470],[AC_MSG_RESULT(no)])
471
472AC_MSG_CHECKING(for math/floor)
473AC_LINK_IFELSE([AC_LANG_PROGRAM([[
474#include <math.h>
475static int f (double (*func)(double)) { return 0; }
476]], [[
477 return f(floor);
478]])], [
479   AC_MSG_RESULT(yes)
480   AC_DEFINE(HAVE_FLOOR, 1,[Have ISO C99 floor function])
481],[AC_MSG_RESULT(no)])
482
483AC_MSG_CHECKING(for math/ceil)
484AC_LINK_IFELSE([AC_LANG_PROGRAM([[
485#include <math.h>
486static int f (double (*func)(double)) { return 0; }
487]], [[
488 return f(ceil);
489]])], [
490   AC_MSG_RESULT(yes)
491   AC_DEFINE(HAVE_CEIL, 1,[Have ISO C99 ceil function])
492],[AC_MSG_RESULT(no)])
493
494AC_MSG_CHECKING(for math/nearbyint)
495AC_LINK_IFELSE([AC_LANG_PROGRAM([[
496#include <math.h>
497static int f (double (*func)(double)) { return 0; }
498]], [[
499 return f(nearbyint);
500]])], [
501   AC_MSG_RESULT(yes)
502   AC_DEFINE(HAVE_NEARBYINT, 1,[Have ISO C99 nearbyint function])
503],[AC_MSG_RESULT(no)])
504
505dnl Check if _mulx_u64 is provided
506dnl Note: This intrinsic is not standard. We need a run because
507dnl it may be provided but not working as expected (with ICC 15,
508dnl one gets an "Illegal instruction").
509AC_MSG_CHECKING([for _mulx_u64])
510AC_RUN_IFELSE([AC_LANG_PROGRAM([[
511#include <immintrin.h>
512]], [[
513 unsigned long long h1, h2;
514 _mulx_u64(17, 42, &h1);
515 _mulx_u64(-1, -1, &h2);
516 return h1 == 0 && h2 == -2 ? 0 : 1;
517]])],
518  [AC_MSG_RESULT(yes)
519   AC_DEFINE(HAVE_MULX_U64, 1,[Have a working _mulx_u64 function])
520  ],
521  [AC_MSG_RESULT(no)
522  ],
523  [AC_MSG_RESULT([cannot test, assume no])
524  ])
525
526LIBS="$saved_LIBS"
527
528dnl Try to determine the format of double
529MPFR_C_REALFP_FORMAT(double,)
530case $mpfr_cv_c_double_format in
531  "IEEE double, big endian"*)
532    AC_DEFINE(HAVE_DOUBLE_IEEE_BIG_ENDIAN, 1)
533    ;;
534  "IEEE double, little endian"*)
535    AC_DEFINE(HAVE_DOUBLE_IEEE_LITTLE_ENDIAN, 1)
536    ;;
537  unknown*)
538    ;;
539  *)
540    AC_MSG_WARN([format of `double' unsupported or not recognized: $mpfr_cv_c_double_format])
541    ;;
542esac
543
544dnl Now try to determine the format of long double
545MPFR_C_REALFP_FORMAT(long double,L)
546case $mpfr_cv_c_long_double_format in
547  "IEEE double, big endian"*)
548    AC_DEFINE(HAVE_LDOUBLE_IS_DOUBLE, 1)
549    ;;
550  "IEEE double, little endian"*)
551    AC_DEFINE(HAVE_LDOUBLE_IS_DOUBLE, 1)
552    ;;
553  "IEEE extended, little endian"*)
554    AC_DEFINE(HAVE_LDOUBLE_IEEE_EXT_LITTLE, 1)
555    ;;
556  "IEEE extended, big endian"*)
557    AC_DEFINE(HAVE_LDOUBLE_IEEE_EXT_BIG, 1)
558    ;;
559  "IEEE quad, big endian"*)
560    AC_DEFINE(HAVE_LDOUBLE_IEEE_QUAD_BIG, 1)
561    ;;
562  "IEEE quad, little endian"*)
563    AC_DEFINE(HAVE_LDOUBLE_IEEE_QUAD_LITTLE, 1)
564    ;;
565  "possibly double-double, big endian"*)
566    AC_MSG_WARN([This format is known on GCC/PowerPC platforms,])
567    AC_MSG_WARN([but due to GCC PR26374, we can't test further.])
568    AC_MSG_WARN([You can safely ignore this warning, though.])
569    AC_DEFINE(HAVE_LDOUBLE_MAYBE_DOUBLE_DOUBLE, 1)
570    ;;
571  "possibly double-double, little endian"*)
572    AC_MSG_WARN([This format is known on GCC/PowerPC platforms,])
573    AC_MSG_WARN([but due to GCC PR26374, we can't test further.])
574    AC_MSG_WARN([You can safely ignore this warning, though.])
575    AC_DEFINE(HAVE_LDOUBLE_MAYBE_DOUBLE_DOUBLE, 1)
576    ;;
577  unknown*)
578    ;;
579  *)
580    AC_MSG_WARN([format of `long double' unsupported or not recognized: $mpfr_cv_c_long_double_format])
581    ;;
582esac
583
584dnl Check if thread-local variables are supported.
585dnl At least two problems can occur in practice:
586dnl 1. The compilation fails, e.g. because the compiler doesn't know
587dnl    about the __thread keyword.
588dnl 2. The compilation succeeds, but the system doesn't support TLS or
589dnl    there is some ld configuration problem. One of the effects can
590dnl    be that thread-local variables always evaluate to 0. So, it is
591dnl    important to run the test below.
592if test "$enable_thread_safe" != no; then
593AC_MSG_CHECKING(for TLS support using C11)
594saved_CPPFLAGS="$CPPFLAGS"
595CPPFLAGS="$CPPFLAGS -I$srcdir/src"
596AC_RUN_IFELSE([AC_LANG_SOURCE([[
597#define MPFR_USE_THREAD_SAFE 1
598#define MPFR_USE_C11_THREAD_SAFE 1
599#include "mpfr-thread.h"
600MPFR_THREAD_ATTR int x = 17;
601int main (void) {
602  return x != 17;
603}
604  ]])],
605     [AC_MSG_RESULT(yes)
606      AC_DEFINE([MPFR_USE_THREAD_SAFE],1,[Build MPFR as thread safe])
607      AC_DEFINE([MPFR_USE_C11_THREAD_SAFE],1,[Build MPFR as thread safe using C11])
608      tls_c11_support=yes
609      enable_thread_safe=yes
610     ],
611     [AC_MSG_RESULT(no)
612     ],
613     [AC_MSG_RESULT([cannot test, assume no])
614     ])
615CPPFLAGS="$saved_CPPFLAGS"
616
617if test "$tls_c11_support" != "yes"
618then
619
620 AC_MSG_CHECKING(for TLS support)
621 saved_CPPFLAGS="$CPPFLAGS"
622 CPPFLAGS="$CPPFLAGS -I$srcdir/src"
623 AC_RUN_IFELSE([AC_LANG_SOURCE([[
624 #define MPFR_USE_THREAD_SAFE 1
625 #include "mpfr-thread.h"
626 MPFR_THREAD_ATTR int x = 17;
627 int main (void) {
628   return x != 17;
629 }
630   ]])],
631      [AC_MSG_RESULT(yes)
632       AC_DEFINE([MPFR_USE_THREAD_SAFE],1,[Build MPFR as thread safe])
633       enable_thread_safe=yes
634      ],
635      [AC_MSG_RESULT(no)
636       if test "$enable_thread_safe" = yes; then
637         AC_MSG_ERROR([please configure with --disable-thread-safe])
638       fi
639      ],
640      [if test "$enable_thread_safe" = yes; then
641         AC_MSG_RESULT([cannot test, assume yes])
642         AC_DEFINE([MPFR_USE_THREAD_SAFE],1,[Build MPFR as thread safe])
643       else
644         AC_MSG_RESULT([cannot test, assume no])
645       fi
646      ])
647 CPPFLAGS="$saved_CPPFLAGS"
648 fi
649fi
650
651if test "$enable_decimal_float" != no; then
652
653dnl Check if decimal floats are available.
654dnl For the different cases, we try to use values that will not be returned
655dnl by build tools. For instance, 1 must not be used as it can be returned
656dnl by gcc or by ld in case of link failure.
657dnl Note: We currently reread the 64-bit data memory as a double and compare
658dnl it with constants. However, if there is any issue with double, such as
659dnl the use of an extended precision, this may fail. Possible solutions:
660dnl   1. Use the hex format for the double constants (this format should be
661dnl      supported if _Decimal64 is).
662dnl   2. Use more precision in the double constants (more decimal digits),
663dnl      just in case.
664dnl   3. Use uint64_t (or unsigned long long, though this type might not be
665dnl      on 64 bits) instead of or in addition to the test on double.
666dnl   4. Use an array of 8 unsigned char's instead of or in addition to the
667dnl      test on double, considering the 2 practical cases of endianness.
668  AC_MSG_CHECKING(if compiler knows _Decimal64)
669  AC_COMPILE_IFELSE(
670    [AC_LANG_PROGRAM([[_Decimal64 x;]])],
671    [AC_MSG_RESULT(yes)
672     AC_MSG_CHECKING(decimal float format)
673     AC_RUN_IFELSE([AC_LANG_PROGRAM([[
674#include <stdlib.h>
675]], [[
676volatile _Decimal64 x = 1;
677union { double d; _Decimal64 d64; } y;
678if (x != x) return 83;
679y.d64 = 1234567890123456.0dd;
680return y.d == 0.14894469406741037E-123 ? 80 :
681       y.d == 0.59075095508629822E-68  ? 81 : 82;
682]])], [AC_MSG_RESULT(internal error)
683       AC_MSG_FAILURE(unexpected exit status 0)],
684      [d64_exit_status=$?
685       case "$d64_exit_status" in
686         80) AC_MSG_RESULT(DPD)
687             if test "$enable_decimal_float" = bid; then
688               AC_MSG_ERROR([encoding mismatch (BID requested).])
689             fi
690             if test "$enable_decimal_float" != generic; then
691               enable_decimal_float=dpd
692             fi ;;
693         81) AC_MSG_RESULT(BID)
694             if test "$enable_decimal_float" = dpd; then
695               AC_MSG_ERROR([encoding mismatch (DPD requested).])
696             fi
697             if test "$enable_decimal_float" != generic; then
698               enable_decimal_float=bid
699             fi ;;
700         82) AC_MSG_RESULT(neither DPD nor BID)
701             if test "$enable_decimal_float" = dpd; then
702               AC_MSG_ERROR([encoding mismatch (DPD requested).])
703             fi
704             if test "$enable_decimal_float" = bid; then
705               AC_MSG_ERROR([encoding mismatch (BID requested).])
706             fi
707             enable_decimal_float=generic
708  AC_MSG_WARN([The _Decimal64 encoding is non-standard or there was an])
709  AC_MSG_WARN([issue with its detection.  The generic code will be used.])
710  AC_MSG_WARN([Please do not forget to test with `make check'.])
711  AC_MSG_WARN([In case of failure of a decimal test, you should rebuild])
712  AC_MSG_WARN([MPFR without --enable-decimal-float.]) ;;
713         *)  AC_MSG_RESULT(error (exit status $d64_exit_status))
714             case "$enable_decimal_float" in
715               yes|bid|dpd|generic) AC_MSG_FAILURE([internal or link error.
716Please build MPFR without --enable-decimal-float.]) ;;
717               *) enable_decimal_float=no ;;
718             esac ;;
719       esac],
720      [AC_MSG_RESULT(cannot test)
721       dnl Since the _Decimal64 type exists, we assume that it is correctly
722       dnl supported. The detection of the encoding may still be done at
723       dnl compile time. We do not add a configure test for it so that this
724       dnl can be done on platforms where configure cannot be used.
725       enable_decimal_float=compile-time])
726    ],
727    [AC_MSG_RESULT(no)
728     case "$enable_decimal_float" in
729       yes|bid|dpd|generic)
730         AC_MSG_FAILURE([compiler doesn't know _Decimal64 (ISO/IEC TR 24732).
731Please use another compiler or build MPFR without --enable-decimal-float.]) ;;
732       *) enable_decimal_float=no ;;
733     esac])
734  if test "$enable_decimal_float" != no; then
735    AC_DEFINE([MPFR_WANT_DECIMAL_FLOATS],1,
736              [Build decimal float functions])
737    case "$enable_decimal_float" in
738      dpd) AC_DEFINE([DECIMAL_DPD_FORMAT],1,[]) ;;
739      bid) AC_DEFINE([DECIMAL_BID_FORMAT],1,[]) ;;
740      generic) AC_DEFINE([DECIMAL_GENERIC_CODE],1,[]) ;;
741      compile-time) ;;
742      *) AC_MSG_ERROR(internal error) ;;
743    esac
744  fi
745
746dnl Check the bit-field ordering for _Decimal128.
747dnl Little endian: sig=0 comb=49400 t0=0 t1=0 t2=0 t3=10
748dnl Big endian: sig=0 comb=8 t0=0 t1=0 t2=0 t3=570933248
749dnl Note: If the compilation fails, the compiler should exit with
750dnl an exit status less than 80.
751  AC_MSG_CHECKING(bit-field ordering for _Decimal128)
752  AC_RUN_IFELSE([AC_LANG_PROGRAM([[
753  ]], [[
754    union ieee_decimal128
755    {
756      struct
757      {
758        unsigned int t3:32;
759        unsigned int t2:32;
760        unsigned int t1:32;
761        unsigned int t0:14;
762        unsigned int comb:17;
763        unsigned int sig:1;
764      } s;
765      _Decimal128 d128;
766    } x;
767
768    x.d128 = 1.0dl;
769    if (x.s.sig == 0 && x.s.comb == 49400 &&
770        x.s.t0 == 0 && x.s.t1 == 0 && x.s.t2 == 0 && x.s.t3 == 10)
771       return 80; /* little endian */
772    else if (x.s.sig == 0 && x.s.comb == 8 &&
773             x.s.t0 == 0 && x.s.t1 == 0 && x.s.t2 == 0 && x.s.t3 == 570933248)
774       return 81; /* big endian */
775    else
776       return 82; /* unknown encoding */
777  ]])], [AC_MSG_RESULT(internal error)],
778        [d128_exit_status=$?
779         case "$d128_exit_status" in
780           80) AC_MSG_RESULT(little endian)
781               AC_DEFINE([HAVE_DECIMAL128_IEEE_LITTLE_ENDIAN],1) ;;
782           81) AC_MSG_RESULT(big endian)
783               AC_DEFINE([HAVE_DECIMAL128_IEEE_BIG_ENDIAN],1) ;;
784           *)  AC_MSG_RESULT(unavailable or unknown) ;;
785         esac],
786        [AC_MSG_RESULT(cannot test)])
787
788fi
789# End of decimal float checks
790
791dnl Check if _Float128 or __float128 is available. We also require the
792dnl compiler to support hex constants with the f128 or q suffix (this
793dnl prevents the _Float128 support with GCC's -std=c90, but who cares?).
794dnl Note: We use AC_LINK_IFELSE instead of AC_COMPILE_IFELSE since an
795dnl error may occur only at link time, such as under NetBSD:
796dnl   https://mail-index.netbsd.org/pkgsrc-users/2018/02/02/msg026220.html
797dnl   https://mail-index.netbsd.org/pkgsrc-users/2018/02/05/msg026238.html
798dnl By using volatile and making the exit code depend on the value of
799dnl this variable, we also make sure that optimization doesn't make
800dnl the "undefined reference" error disappear.
801if test "$enable_float128" != no; then
802   AC_MSG_CHECKING(if _Float128 with hex constants is supported)
803   AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[
804volatile _Float128 x = 0x1.fp+16383f128;
805return x == 0;
806]])],
807      [AC_MSG_RESULT(yes)
808       AC_DEFINE([MPFR_WANT_FLOAT128],1,[Build float128 functions])],
809      [AC_MSG_RESULT(no)
810       AC_MSG_CHECKING(if __float128 can be used as a fallback)
811dnl Use the q suffix in this case.
812       AC_LINK_IFELSE([AC_LANG_PROGRAM([[
813#define _Float128 __float128
814]], [[
815volatile _Float128 x = 0x1.fp+16383q;
816return x == 0;
817]])],
818          [AC_MSG_RESULT(yes)
819           AC_DEFINE([MPFR_WANT_FLOAT128],2,
820                     [Build float128 functions with float128 fallback])
821           AC_DEFINE([_Float128],[__float128],[__float128 fallback])],
822          [AC_MSG_RESULT(no)
823           if test "$enable_float128" = yes; then
824              AC_MSG_ERROR(
825[compiler doesn't know _Float128 or __float128 with hex constants.
826Please use another compiler or build MPFR without --enable-float128.])
827       fi])
828      ])
829fi
830
831dnl Check if Static Assertions are supported.
832AC_MSG_CHECKING(for Static Assertion support)
833saved_CPPFLAGS="$CPPFLAGS"
834CPPFLAGS="$CPPFLAGS -I$srcdir/src"
835AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
836#define MPFR_USE_STATIC_ASSERT 1
837#include "mpfr-sassert.h"
838
839/* Test if Static Assertions work */
840
841int main (void) {
842  int x;
843  (void) (x = 1);  /* cast to void: avoid a warning, at least with GCC */
844  /* Test of the macro after a declaraction and a statement. */
845  MPFR_STAT_STATIC_ASSERT(sizeof(short) <= sizeof(int));
846  return 0;
847}
848  ]])],
849     [AC_MSG_RESULT(yes)
850      AC_DEFINE([MPFR_USE_STATIC_ASSERT],1,[Build MPFR with Static Assertions])
851     ],
852     [AC_MSG_RESULT(no)
853     ])
854CPPFLAGS="$saved_CPPFLAGS"
855
856if test "$enable_lto" = "yes" ; then
857   MPFR_LTO
858fi
859
860dnl Logging support needs nested functions and the 'cleanup' attribute.
861dnl This is checked at the end because the change of CC and/or CFLAGS that
862dnl could occur before may have an influence on this test. The tested code
863dnl is very similar to what is used in MPFR (mpfr-impl.h).
864if test "$enable_logging" = yes; then
865AC_MSG_CHECKING(for nested functions and 'cleanup' attribute)
866AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
867int main (void) {
868  auto void f_cleanup (int *p);
869  void f_cleanup (int *p) { int v = *p; (void) v; }
870  int v __attribute__ ((cleanup (f_cleanup)));
871  v = 0;
872  return 0;
873}
874  ]])],
875     [AC_MSG_RESULT(yes)],
876     [AC_MSG_RESULT(no)
877      AC_MSG_ERROR([logging support needs nested functions and the 'cleanup' attribute])
878     ])
879fi
880
881])
882dnl end of MPFR_CONFIGS
883
884
885dnl MPFR_CHECK_GMP
886dnl --------------
887dnl Check GMP library vs header. Useful if the user provides --with-gmp
888dnl with a directory containing a GMP version that doesn't have the
889dnl correct ABI: the previous tests won't trigger the error if the same
890dnl GMP version with the right ABI is installed on the system, as this
891dnl library is automatically selected by the linker, while the header
892dnl (which depends on the ABI) of the --with-gmp include directory is
893dnl used.
894dnl Note: if the error is changed to a warning due to that fact that
895dnl libtool is not used, then the same thing should be done for the
896dnl other tests based on GMP.
897AC_DEFUN([MPFR_CHECK_GMP], [
898AC_REQUIRE([MPFR_CONFIGS])dnl
899AC_CACHE_CHECK([for GMP library vs header correctness], mpfr_cv_check_gmp, [
900AC_RUN_IFELSE([AC_LANG_PROGRAM([[
901#include <stdio.h>
902#include <limits.h>
903#include <gmp.h>
904]], [[
905  fprintf (stderr, "GMP_NAIL_BITS     = %d\n", (int) GMP_NAIL_BITS);
906  fprintf (stderr, "GMP_NUMB_BITS     = %d\n", (int) GMP_NUMB_BITS);
907  fprintf (stderr, "mp_bits_per_limb  = %d\n", (int) mp_bits_per_limb);
908  fprintf (stderr, "sizeof(mp_limb_t) = %d\n", (int) sizeof(mp_limb_t));
909  if (GMP_NAIL_BITS != 0)
910    {
911      fprintf (stderr, "GMP_NAIL_BITS != 0\n");
912      return 81;
913    }
914  if (GMP_NUMB_BITS != mp_bits_per_limb)
915    {
916      fprintf (stderr, "GMP_NUMB_BITS != mp_bits_per_limb\n");
917      return 82;
918    }
919  if (GMP_NUMB_BITS != sizeof(mp_limb_t) * CHAR_BIT)
920    {
921      fprintf (stderr, "GMP_NUMB_BITS != sizeof(mp_limb_t) * CHAR_BIT\n");
922      return 83;
923    }
924  return 0;
925]])], [mpfr_cv_check_gmp="yes"],
926      [mpfr_cv_check_gmp="no (exit status is $?)"],
927      [mpfr_cv_check_gmp="cannot test, assume yes"])
928])
929case $mpfr_cv_check_gmp in
930no*)
931  AC_MSG_ERROR([bad GMP library or header - ABI problem?
932See 'config.log' for details.]) ;;
933esac
934])
935
936
937dnl MPFR_CHECK_DBL2INT_BUG
938dnl ----------------------
939dnl Check for double-to-integer conversion bug
940dnl https://gforge.inria.fr/tracker/index.php?func=detail&aid=14435
941dnl The following problem has been seen under Solaris in config.log,
942dnl i.e. the failure to link with libgmp wasn't detected in the first
943dnl test:
944dnl   configure: checking if gmp.h version and libgmp version are the same
945dnl   configure: gcc -o conftest -Wall -Wmissing-prototypes [...]
946dnl   configure: $? = 0
947dnl   configure: ./conftest
948dnl   ld.so.1: conftest: fatal: libgmp.so.10: open failed: No such file [...]
949dnl   configure: $? = 0
950dnl   configure: result: yes
951dnl   configure: checking for double-to-integer conversion bug
952dnl   configure: gcc -o conftest -Wall -Wmissing-prototypes [...]
953dnl   configure: $? = 0
954dnl   configure: ./conftest
955dnl   ld.so.1: conftest: fatal: libgmp.so.10: open failed: No such file [...]
956dnl   ./configure[1680]: eval: line 1: 1971: Killed
957dnl   configure: $? = 9
958dnl   configure: program exited with status 9
959AC_DEFUN([MPFR_CHECK_DBL2INT_BUG], [
960AC_REQUIRE([MPFR_CONFIGS])dnl
961AC_CACHE_CHECK([for double-to-integer conversion bug], mpfr_cv_dbl_int_bug, [
962AC_RUN_IFELSE([AC_LANG_PROGRAM([[
963#include <stdio.h>
964#include <gmp.h>
965]], [[
966  double d;
967  mp_limb_t u;
968  int i;
969
970  d = 1.0;
971  for (i = 0; i < GMP_NUMB_BITS - 1; i++)
972    d = d + d;
973  u = (mp_limb_t) d;
974  for (; i > 0; i--)
975    {
976      if (u & 1)
977        break;
978      u = u >> 1;
979    }
980  if (i == 0 && u == 1UL)
981    return 0;
982  fprintf (stderr, "Failure: i = %d, (unsigned long) u = %lu\n",
983           i, (unsigned long) u);
984  return 1;
985]])], [mpfr_cv_dbl_int_bug="no"],
986      [mpfr_cv_dbl_int_bug="yes or failed to exec (exit status is $?)"],
987      [mpfr_cv_dbl_int_bug="cannot test, assume not present"])
988])
989case $mpfr_cv_dbl_int_bug in
990yes*)
991  AC_MSG_ERROR([double-to-integer conversion is incorrect.
992You need to use another compiler (or lower the optimization level).]) ;;
993esac
994])
995
996dnl MPFR_CHECK_MP_LIMB_T_VS_LONG
997dnl ----------------------------
998dnl Check whether a long fits in mp_limb_t.
999dnl If static assertions are not supported, one gets "no" even though a long
1000dnl fits in mp_limb_t. Therefore, code without MPFR_LONG_WITHIN_LIMB defined
1001dnl needs to be portable.
1002dnl According to the GMP developers, a limb is always as large as a long,
1003dnl except when __GMP_SHORT_LIMB is defined. It is currently never defined:
1004dnl https://gmplib.org/list-archives/gmp-discuss/2018-February/006190.html
1005dnl but it is not clear whether this could change in the future.
1006AC_DEFUN([MPFR_CHECK_MP_LIMB_T_VS_LONG], [
1007AC_REQUIRE([MPFR_CONFIGS])
1008AC_CACHE_CHECK([for long to fit in mp_limb_t], mpfr_cv_long_within_limb, [
1009saved_CPPFLAGS="$CPPFLAGS"
1010CPPFLAGS="$CPPFLAGS -I$srcdir/src"
1011dnl AC_LINK_IFELSE is safer than AC_COMPILE_IFELSE, as it will detect
1012dnl undefined function-like macros (which otherwise may be regarded
1013dnl as valid function calls with AC_COMPILE_IFELSE since prototypes
1014dnl are not required by the C standard).
1015AC_LINK_IFELSE([AC_LANG_PROGRAM([[
1016#include <gmp.h>
1017/* Make sure that a static assertion is used (not MPFR_ASSERTN). */
1018#undef MPFR_USE_STATIC_ASSERT
1019#define MPFR_USE_STATIC_ASSERT 1
1020#include "mpfr-sassert.h"
1021]], [[
1022  MPFR_STAT_STATIC_ASSERT ((mp_limb_t) -1 >= (unsigned long) -1);
1023  return 0;
1024]])], [mpfr_cv_long_within_limb="yes"],
1025      [mpfr_cv_long_within_limb="no"])
1026])
1027case $mpfr_cv_long_within_limb in
1028yes*)
1029      AC_DEFINE([MPFR_LONG_WITHIN_LIMB],1,[long can be stored in mp_limb_t]) ;;
1030esac
1031CPPFLAGS="$saved_CPPFLAGS"
1032])
1033
1034dnl MPFR_CHECK_MP_LIMB_T_VS_INTMAX
1035dnl ------------------------------
1036dnl Check that an intmax_t can fit in a mp_limb_t.
1037AC_DEFUN([MPFR_CHECK_MP_LIMB_T_VS_INTMAX], [
1038AC_REQUIRE([MPFR_CONFIGS])
1039if test "$ac_cv_type_intmax_t" = yes; then
1040AC_CACHE_CHECK([for intmax_t to fit in mp_limb_t], mpfr_cv_intmax_within_limb, [
1041saved_CPPFLAGS="$CPPFLAGS"
1042CPPFLAGS="$CPPFLAGS -I$srcdir/src -DMPFR_NEED_INTMAX_H"
1043dnl AC_LINK_IFELSE is safer than AC_COMPILE_IFELSE, as it will detect
1044dnl undefined function-like macros (which otherwise may be regarded
1045dnl as valid function calls with AC_COMPILE_IFELSE since prototypes
1046dnl are not required by the C standard).
1047AC_LINK_IFELSE([AC_LANG_PROGRAM([[
1048#include <gmp.h>
1049/* Make sure that a static assertion is used (not MPFR_ASSERTN). */
1050#undef MPFR_USE_STATIC_ASSERT
1051#define MPFR_USE_STATIC_ASSERT 1
1052#include "mpfr-sassert.h"
1053#include "mpfr-intmax.h"
1054]], [[
1055  MPFR_STAT_STATIC_ASSERT ((mp_limb_t) -1 >= (uintmax_t) -1);
1056  return 0;
1057]])], [mpfr_cv_intmax_within_limb="yes"],
1058      [mpfr_cv_intmax_within_limb="no"])
1059])
1060case $mpfr_cv_intmax_within_limb in
1061yes*)
1062      AC_DEFINE([MPFR_INTMAX_WITHIN_LIMB],1,[intmax_t can be stored in mp_limb_t]) ;;
1063esac
1064CPPFLAGS="$saved_CPPFLAGS"
1065fi
1066])
1067
1068dnl MPFR_PARSE_DIRECTORY
1069dnl Input:  $1 = a string to a relative or absolute directory
1070dnl Output: $2 = the variable to set with the absolute directory
1071AC_DEFUN([MPFR_PARSE_DIRECTORY],
1072[
1073 dnl Check if argument is a directory
1074 if test -d $1 ; then
1075    dnl Get the absolute path of the directory in case of relative directory
1076    dnl with the realpath command. If the output is empty, the cause may be
1077    dnl that this command has not been found, and we do an alternate test,
1078    dnl the same as what autoconf does for the generated configure script to
1079    dnl determine whether a pathname is absolute or relative.
1080    local_tmp=`realpath $1 2>/dev/null`
1081    if test "$local_tmp" != "" ; then
1082       if test -d "$local_tmp" ; then
1083           $2="$local_tmp"
1084       else
1085           $2=$1
1086       fi
1087    else
1088       dnl The quadrigraphs @<:@, @:>@ and @:}@ produce [, ] and )
1089       dnl respectively (see Autoconf manual). We cannot use quoting here
1090       dnl as the result depends on the context in which this macro is
1091       dnl invoked! To detect that, one needs to look at every instance
1092       dnl of the macro expansion in the generated configure script.
1093       case $1 in
1094         @<:@\\/@:>@* | ?:@<:@\\/@:>@* @:}@ $2=$1 ;;
1095         *@:}@ $2="$PWD"/$1 ;;
1096       esac
1097    fi
1098    dnl Check for space in the directory
1099    if test `echo $1|cut -d' ' -f1` != $1 ; then
1100        AC_MSG_ERROR($1 directory shall not contain any space.)
1101    fi
1102 else
1103    AC_MSG_ERROR($1 shall be a valid directory)
1104 fi
1105])
1106
1107
1108dnl MPFR_C_REALFP_FORMAT
1109dnl --------------------
1110dnl Determine the format of a real floating type (first argument),
1111dnl actually either double or long double. The second argument is
1112dnl the printf length modifier.
1113dnl
1114dnl The object file is grepped, so as to work when cross-compiling.
1115dnl Start and end sequences are included to avoid false matches, and
1116dnl allowance is made for the desired data crossing an "od -b" line
1117dnl boundary.  The test number is a small integer so it should appear
1118dnl exactly, without rounding or truncation, etc.
1119dnl
1120dnl "od -b" is supported even by Unix V7, and the awk script used doesn't
1121dnl have functions or anything, so even an "old" awk should suffice.
1122dnl
1123dnl Concerning long double: The 10-byte IEEE extended format is generally
1124dnl padded with null bytes to either 12 or 16 bytes for alignment purposes.
1125dnl The SVR4 i386 ABI is 12 bytes, or i386 gcc -m128bit-long-double selects
1126dnl 16 bytes. IA-64 is 16 bytes in LP64 mode, or 12 bytes in ILP32 mode.
1127dnl The relevant part in all cases (big and little endian) consists of the
1128dnl first 10 bytes.
1129dnl
1130dnl We compile and link (with "-o conftest$EXEEXT") instead of just
1131dnl compiling (with "-c"), so that this test works with GCC's and
1132dnl clang's LTO (-flto). If we just compile with LTO, the generated
1133dnl object file does not contain the structure as is. This new test
1134dnl is inspired by the one used by GMP for the double type:
1135dnl   https://gmplib.org/repo/gmp/rev/33eb0998a052
1136dnl   https://gmplib.org/repo/gmp/rev/cbc6dbf95a10
1137dnl "$EXEEXT" had to be added, otherwise the test was failing on
1138dnl MS-Windows (see Autoconf manual).
1139
1140AC_DEFUN([MPFR_C_REALFP_FORMAT],
1141[AC_REQUIRE([AC_PROG_CC])
1142AC_REQUIRE([AC_PROG_AWK])
1143AC_REQUIRE([AC_OBJEXT])
1144AS_VAR_PUSHDEF([my_Type_var], [mpfr_cv_c_$1_format])dnl
1145AC_CACHE_CHECK([format of floating-point type `$1'],
1146                my_Type_var,
1147[my_Type_var=unknown
1148 cat >conftest.c <<\EOF
1149[
1150#include <stdio.h>
1151/* "before" is 16 bytes to ensure there's no padding between it and "x".
1152   We're not expecting any type bigger than 16 bytes or with
1153   alignment requirements stricter than 16 bytes.  */
1154typedef struct {
1155  char         before[16];
1156  $1           x;
1157  char         after[8];
1158} foo_t;
1159
1160foo_t foo = {
1161  { '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
1162    '\001', '\043', '\105', '\147', '\211', '\253', '\315', '\357' },
1163  -123456789.0,
1164  { '\376', '\334', '\272', '\230', '\166', '\124', '\062', '\020' }
1165};
1166
1167int main (void) {
1168  int i;
1169  for (i = 0; i < 8; i++)
1170    printf ("%d %$2f\n", foo.before[i] + foo.after[i], foo.x);
1171  return 0;
1172}
1173]
1174EOF
1175 mpfr_compile="$CC $CFLAGS $CPPFLAGS $LDFLAGS conftest.c -o conftest$EXEEXT >&AS_MESSAGE_LOG_FD 2>&1"
1176 if AC_TRY_EVAL(mpfr_compile); then
1177   cat >conftest.awk <<\EOF
1178[
1179BEGIN {
1180  found = 0
1181}
1182
1183# got[] holds a sliding window of bytes read the input.  got[0] is the most
1184# recent byte read, and got[31] the oldest byte read, so when looking to
1185# match some data the indices are "reversed".
1186#
1187{
1188  for (f = 2; f <= NF; f++)
1189    {
1190      # new byte, shift others up
1191      for (i = 31; i >= 0; i--)
1192        got[i+1] = got[i];
1193      got[0] = $f;
1194
1195      # end sequence
1196      if (got[7] != "376") continue
1197      if (got[6] != "334") continue
1198      if (got[5] != "272") continue
1199      if (got[4] != "230") continue
1200      if (got[3] != "166") continue
1201      if (got[2] != "124") continue
1202      if (got[1] != "062") continue
1203      if (got[0] != "020") continue
1204
1205      # start sequence, with 8-byte body
1206      if (got[23] == "001" && \
1207          got[22] == "043" && \
1208          got[21] == "105" && \
1209          got[20] == "147" && \
1210          got[19] == "211" && \
1211          got[18] == "253" && \
1212          got[17] == "315" && \
1213          got[16] == "357")
1214        {
1215          saw = " (" got[15] \
1216                 " " got[14] \
1217                 " " got[13] \
1218                 " " got[12] \
1219                 " " got[11] \
1220                 " " got[10] \
1221                 " " got[9]  \
1222                 " " got[8] ")"
1223
1224          if (got[15] == "301" && \
1225              got[14] == "235" && \
1226              got[13] == "157" && \
1227              got[12] == "064" && \
1228              got[11] == "124" && \
1229              got[10] == "000" && \
1230              got[9] ==  "000" && \
1231              got[8] ==  "000")
1232            {
1233              print "IEEE double, big endian"
1234              found = 1
1235              exit
1236            }
1237
1238          if (got[15] == "000" && \
1239              got[14] == "000" && \
1240              got[13] == "000" && \
1241              got[12] == "124" && \
1242              got[11] == "064" && \
1243              got[10] == "157" && \
1244              got[9] ==  "235" && \
1245              got[8] ==  "301")
1246            {
1247              print "IEEE double, little endian"
1248              found = 1
1249              exit
1250            }
1251        }
1252
1253      # start sequence, with 12-byte body
1254      if (got[27] == "001" && \
1255          got[26] == "043" && \
1256          got[25] == "105" && \
1257          got[24] == "147" && \
1258          got[23] == "211" && \
1259          got[22] == "253" && \
1260          got[21] == "315" && \
1261          got[20] == "357")
1262        {
1263          saw = " (" got[19] \
1264                 " " got[18] \
1265                 " " got[17] \
1266                 " " got[16] \
1267                 " " got[15] \
1268                 " " got[14] \
1269                 " " got[13] \
1270                 " " got[12] \
1271                 " " got[11] \
1272                 " " got[10] \
1273                 " " got[9]  \
1274                 " " got[8] ")"
1275
1276          if (got[19] == "000" && \
1277              got[18] == "000" && \
1278              got[17] == "000" && \
1279              got[16] == "000" && \
1280              got[15] == "240" && \
1281              got[14] == "242" && \
1282              got[13] == "171" && \
1283              got[12] == "353" && \
1284              got[11] == "031" && \
1285              got[10] == "300")
1286            {
1287              print "IEEE extended, little endian (12 bytes)"
1288              found = 1
1289              exit
1290            }
1291
1292          if (got[19] == "300" && \
1293              got[18] == "031" && \
1294              got[17] == "000" && \
1295              got[16] == "000" && \
1296              got[15] == "353" && \
1297              got[14] == "171" && \
1298              got[13] == "242" && \
1299              got[12] == "240" && \
1300              got[11] == "000" && \
1301              got[10] == "000" && \
1302              got[09] == "000" && \
1303              got[08] == "000")
1304            {
1305              # format found on m68k
1306              print "IEEE extended, big endian (12 bytes)"
1307              found = 1
1308              exit
1309            }
1310        }
1311
1312      # start sequence, with 16-byte body
1313      if (got[31] == "001" && \
1314          got[30] == "043" && \
1315          got[29] == "105" && \
1316          got[28] == "147" && \
1317          got[27] == "211" && \
1318          got[26] == "253" && \
1319          got[25] == "315" && \
1320          got[24] == "357")
1321        {
1322          saw = " (" got[23] \
1323                 " " got[22] \
1324                 " " got[21] \
1325                 " " got[20] \
1326                 " " got[19] \
1327                 " " got[18] \
1328                 " " got[17] \
1329                 " " got[16] \
1330                 " " got[15] \
1331                 " " got[14] \
1332                 " " got[13] \
1333                 " " got[12] \
1334                 " " got[11] \
1335                 " " got[10] \
1336                 " " got[9]  \
1337                 " " got[8] ")"
1338
1339          if (got[23] == "000" && \
1340              got[22] == "000" && \
1341              got[21] == "000" && \
1342              got[20] == "000" && \
1343              got[19] == "240" && \
1344              got[18] == "242" && \
1345              got[17] == "171" && \
1346              got[16] == "353" && \
1347              got[15] == "031" && \
1348              got[14] == "300")
1349            {
1350              print "IEEE extended, little endian (16 bytes)"
1351              found = 1
1352              exit
1353            }
1354
1355          if (got[23] == "300" && \
1356              got[22] == "031" && \
1357              got[21] == "326" && \
1358              got[20] == "363" && \
1359              got[19] == "105" && \
1360              got[18] == "100" && \
1361              got[17] == "000" && \
1362              got[16] == "000" && \
1363              got[15] == "000" && \
1364              got[14] == "000" && \
1365              got[13] == "000" && \
1366              got[12] == "000" && \
1367              got[11] == "000" && \
1368              got[10] == "000" && \
1369              got[9]  == "000" && \
1370              got[8]  == "000")
1371            {
1372              # format used on HP 9000/785 under HP-UX
1373              print "IEEE quad, big endian"
1374              found = 1
1375              exit
1376            }
1377
1378          if (got[23] == "000" && \
1379              got[22] == "000" && \
1380              got[21] == "000" && \
1381              got[20] == "000" && \
1382              got[19] == "000" && \
1383              got[18] == "000" && \
1384              got[17] == "000" && \
1385              got[16] == "000" && \
1386              got[15] == "000" && \
1387              got[14] == "000" && \
1388              got[13] == "100" && \
1389              got[12] == "105" && \
1390              got[11] == "363" && \
1391              got[10] == "326" && \
1392              got[9]  == "031" && \
1393	      got[8]  == "300")
1394            {
1395              print "IEEE quad, little endian"
1396              found = 1
1397              exit
1398            }
1399
1400          if (got[23] == "301" && \
1401              got[22] == "235" && \
1402              got[21] == "157" && \
1403              got[20] == "064" && \
1404              got[19] == "124" && \
1405              got[18] == "000" && \
1406              got[17] == "000" && \
1407              got[16] == "000" && \
1408              got[15] == "000" && \
1409              got[14] == "000" && \
1410              got[13] == "000" && \
1411              got[12] == "000" && \
1412              got[11] == "000" && \
1413              got[10] == "000" && \
1414              got[9]  == "000" && \
1415              got[8]  == "000")
1416            {
1417              # format used on 32-bit PowerPC (Mac OS X and Debian GNU/Linux)
1418              print "possibly double-double, big endian"
1419              found = 1
1420              exit
1421            }
1422
1423          if (got[23] == "000" && \
1424              got[22] == "000" && \
1425              got[21] == "000" && \
1426              got[20] == "124" && \
1427              got[19] == "064" && \
1428              got[18] == "157" && \
1429              got[17] == "235" && \
1430              got[16] == "301" && \
1431              got[15] == "000" && \
1432              got[14] == "000" && \
1433              got[13] == "000" && \
1434              got[12] == "000" && \
1435              got[11] == "000" && \
1436              got[10] == "000" && \
1437              got[9]  == "000" && \
1438              got[8]  == "000")
1439            {
1440              # format used on ppc64le
1441              print "possibly double-double, little endian"
1442              found = 1
1443              exit
1444            }
1445        }
1446    }
1447}
1448
1449END {
1450  if (! found)
1451    print "unknown", saw
1452}
1453]
1454EOF
1455   my_Type_var=`od -b conftest$EXEEXT | $AWK -f conftest.awk`
1456   case $my_Type_var in
1457   unknown*)
1458     echo "cannot match anything, conftest$EXEEXT contains" >&AS_MESSAGE_LOG_FD
1459     od -b conftest$EXEEXT >&AS_MESSAGE_LOG_FD
1460     ;;
1461   esac
1462 else
1463   AC_MSG_WARN([oops, cannot compile test program])
1464 fi
1465 rm -f conftest*
1466])])
1467
1468dnl  MPFR_CHECK_LIBM
1469dnl  ---------------
1470dnl  Determine a math library -lm to use.
1471
1472AC_DEFUN([MPFR_CHECK_LIBM],
1473[AC_REQUIRE([AC_CANONICAL_HOST])
1474AC_SUBST(MPFR_LIBM,'')
1475case $host in
1476  *-*-beos* | *-*-cygwin* | *-*-pw32*)
1477    # According to libtool AC CHECK LIBM, these systems don't have libm
1478    ;;
1479  *-*-solaris*)
1480    # On Solaris the math functions new in C99 are in -lm9x.
1481    # FIXME: Do we need -lm9x as well as -lm, or just instead of?
1482    AC_CHECK_LIB(m9x, main, MPFR_LIBM="-lm9x")
1483    AC_CHECK_LIB(m,   main, MPFR_LIBM="$MPFR_LIBM -lm")
1484    ;;
1485  *-ncr-sysv4.3*)
1486    # FIXME: What does -lmw mean?  Libtool AC CHECK LIBM does it this way.
1487    AC_CHECK_LIB(mw, _mwvalidcheckl, MPFR_LIBM="-lmw")
1488    AC_CHECK_LIB(m, main, MPFR_LIBM="$MPFR_LIBM -lm")
1489    ;;
1490  *)
1491    AC_CHECK_LIB(m, main, MPFR_LIBM="-lm")
1492    ;;
1493esac
1494])
1495
1496dnl  MPFR_CHECK_LIBQUADMATH
1497dnl  ---------------
1498dnl  Determine a math library -lquadmath to use.
1499AC_DEFUN([MPFR_CHECK_LIBQUADMATH],
1500[AC_REQUIRE([AC_CANONICAL_HOST])
1501AC_SUBST(MPFR_LIBQUADMATH,'')
1502case $host in
1503  *)
1504    AC_CHECK_LIB(quadmath, main, MPFR_LIBQUADMATH="-lquadmath")
1505    ;;
1506esac
1507])
1508
1509dnl  MPFR_LD_SEARCH_PATHS_FIRST
1510dnl  --------------------------
1511
1512AC_DEFUN([MPFR_LD_SEARCH_PATHS_FIRST],
1513[case "$LD $LDFLAGS" in
1514  *-Wl,-search_paths_first*) ;;
1515  *) AC_MSG_CHECKING([if the compiler understands -Wl,-search_paths_first])
1516     saved_LDFLAGS="$LDFLAGS"
1517     LDFLAGS="-Wl,-search_paths_first $LDFLAGS"
1518     AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
1519       [AC_MSG_RESULT(yes)],
1520       [AC_MSG_RESULT(no)]
1521        LDFLAGS="$saved_LDFLAGS")
1522     ;;
1523 esac
1524])
1525
1526
1527dnl  GMP_C_ATTRIBUTE_MODE
1528dnl  --------------------
1529dnl  Introduced in gcc 2.2, but perhaps not in all Apple derived versions.
1530dnl  Needed for mpfr-longlong.h; this is currently necessary for s390.
1531dnl
1532dnl  TODO: Replace this with a cleaner type size detection, as this
1533dnl  solution only works with gcc and assumes CHAR_BIT == 8. Probably use
1534dnl  <stdint.h>, and <https://gcc.gnu.org/viewcvs/gcc/trunk/config/stdint.m4>
1535dnl  as a fallback.
1536
1537AC_DEFUN([GMP_C_ATTRIBUTE_MODE],
1538[AC_CACHE_CHECK([whether gcc __attribute__ ((mode (XX))) works],
1539               gmp_cv_c_attribute_mode,
1540[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[typedef int SItype __attribute__ ((mode (SI)));]], [[]])],
1541 gmp_cv_c_attribute_mode=yes, gmp_cv_c_attribute_mode=no)
1542])
1543if test $gmp_cv_c_attribute_mode = yes; then
1544 AC_DEFINE(HAVE_ATTRIBUTE_MODE, 1,
1545 [Define to 1 if the compiler accepts gcc style __attribute__ ((mode (XX)))])
1546fi
1547])
1548
1549
1550dnl  MPFR_FUNC_GMP_PRINTF_SPEC
1551dnl  ------------------------------------
1552dnl  MPFR_FUNC_GMP_PRINTF_SPEC(spec, type, [includes], [if-true], [if-false])
1553dnl  Check if sprintf and gmp_sprintf support the conversion specifier 'spec'
1554dnl  with type 'type'.
1555dnl  Expand 'if-true' if printf supports 'spec', 'if-false' otherwise.
1556
1557AC_DEFUN([MPFR_FUNC_GMP_PRINTF_SPEC],[
1558AC_MSG_CHECKING(if gmp_printf supports "%$1")
1559AC_RUN_IFELSE([AC_LANG_PROGRAM([[
1560#include <stdio.h>
1561#include <string.h>
1562$3
1563#include <gmp.h>
1564]], [[
1565  char s[256];
1566  $2 a = 17;
1567
1568  /* Contrary to the gmp_sprintf test, do not use the 0 flag with the
1569     precision, as -Werror=format yields an error, even though this
1570     flag is allowed by the ISO C standard (it is just ignored).
1571     https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70813 */
1572  if (sprintf (s, "(%.0$1)(%d)", a, 42) != 8 ||
1573      strcmp (s, "(17)(42)") != 0)
1574    return 1;
1575
1576  if (gmp_sprintf (s, "(%0.0$1)(%d)", a, 42) == -1 ||
1577      strcmp (s, "(17)(42)") != 0)
1578    return 1;
1579
1580  return 0;
1581]])],
1582  [AC_MSG_RESULT(yes)
1583  $4],
1584  [AC_MSG_RESULT(no)
1585  $5],
1586  [AC_MSG_RESULT(cross-compiling, assuming yes)
1587  $4])
1588])
1589
1590
1591dnl MPFR_CHECK_PRINTF_SPEC
1592dnl ----------------------
1593dnl Check if gmp_printf supports some optional length modifiers.
1594dnl Defined symbols are negative to shorten the gcc command line.
1595
1596AC_DEFUN([MPFR_CHECK_PRINTF_SPEC], [
1597AC_REQUIRE([MPFR_CONFIGS])dnl
1598if test "$ac_cv_type_intmax_t" = yes; then
1599 MPFR_FUNC_GMP_PRINTF_SPEC([jd], [intmax_t], [
1600#ifdef HAVE_INTTYPES_H
1601# include <inttypes.h>
1602#endif
1603#ifdef HAVE_STDINT_H
1604# include <stdint.h>
1605#endif
1606         ],,
1607         [AC_DEFINE([NPRINTF_J], 1, [printf/gmp_printf cannot read intmax_t])])
1608fi
1609
1610MPFR_FUNC_GMP_PRINTF_SPEC([hhd], [char], [
1611#include <gmp.h>
1612         ],,
1613         [AC_DEFINE([NPRINTF_HH], 1, [printf/gmp_printf cannot use `hh' length modifier])])
1614
1615MPFR_FUNC_GMP_PRINTF_SPEC([lld], [long long int], [
1616#include <gmp.h>
1617         ],,
1618         [AC_DEFINE([NPRINTF_LL], 1, [printf/gmp_printf cannot read long long int])])
1619
1620MPFR_FUNC_GMP_PRINTF_SPEC([Lf], [long double], [
1621#include <gmp.h>
1622         ],
1623         [AC_DEFINE([PRINTF_L], 1, [printf/gmp_printf can read long double])],
1624         [AC_DEFINE([NPRINTF_L], 1, [printf/gmp_printf cannot read long double])])
1625
1626MPFR_FUNC_GMP_PRINTF_SPEC([td], [ptrdiff_t], [
1627#if defined (__cplusplus)
1628#include <cstddef>
1629#else
1630#include <stddef.h>
1631#endif
1632#include <gmp.h>
1633    ],
1634    [AC_DEFINE([PRINTF_T], 1, [printf/gmp_printf can read ptrdiff_t])],
1635    [AC_DEFINE([NPRINTF_T], 1, [printf/gmp_printf cannot read ptrdiff_t])])
1636])
1637
1638dnl MPFR_CHECK_PRINTF_GROUPFLAG
1639dnl ---------------------------
1640dnl Check the support of the group flag for native integers, which is
1641dnl a Single UNIX Specification extension.
1642dnl This will be used to enable some tests, as the implementation of
1643dnl the P length modifier for mpfr_*printf relies on this support.
1644
1645AC_DEFUN([MPFR_CHECK_PRINTF_GROUPFLAG], [
1646AC_MSG_CHECKING(if gmp_printf supports the ' group flag)
1647AC_RUN_IFELSE([AC_LANG_PROGRAM([[
1648#include <string.h>
1649#include <gmp.h>
1650]], [[
1651  char s[256];
1652
1653  if (gmp_sprintf (s, "%'d", 17) == -1) return 1;
1654  return (strcmp (s, "17") != 0);
1655]])],
1656  [AC_MSG_RESULT(yes)
1657   AC_DEFINE([PRINTF_GROUPFLAG], 1, [Define if gmp_printf supports the ' group flag])],
1658  [AC_MSG_RESULT(no)],
1659  [AC_MSG_RESULT(cannot test, assume no)])
1660])
1661])
1662
1663dnl MPFR_LTO
1664dnl --------
1665dnl To be representative, we need:
1666dnl * to compile a source,
1667dnl * to generate a library archive,
1668dnl * to generate a program with this archive.
1669AC_DEFUN([MPFR_LTO],[
1670dnl Check for -flto support
1671CFLAGS="$CFLAGS -flto"
1672
1673AC_MSG_CHECKING([if Link Time Optimisation flag '-flto' is supported...])
1674AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
1675int main(void) { return 0; }
1676  ]])],
1677     [AC_MSG_RESULT(yes)
1678     ],
1679     [AC_MSG_RESULT(no)
1680      AC_MSG_ERROR([Link Time Optimisation flag '-flto' is not supported.])
1681     ])
1682
1683dnl Check if it works...
1684mpfr_compile_and_link()
1685{
1686   echo "int f(int); int f(int n) { return n; }" > conftest-f.c
1687   echo "int f(int); int main() { return f(0); }" > conftest-m.c
1688   echo "$CC $CFLAGS -c -o conftest-f.o conftest-f.c" >&2
1689   $CC $CFLAGS -c -o conftest-f.o conftest-f.c || return 1
1690   echo "$AR cru conftest-lib.a conftest-f.o" >&2
1691   $AR cru conftest-lib.a conftest-f.o || return 1
1692   echo "$RANLIB conftest-lib.a" >&2
1693   $RANLIB conftest-lib.a || return 1
1694   echo "$CC $CFLAGS conftest-m.c conftest-lib.a" >&2
1695   $CC $CFLAGS conftest-m.c conftest-lib.a || return 1
1696   return 0
1697}
1698   AC_MSG_CHECKING([if Link Time Optimisation works with AR=$AR])
1699   if mpfr_compile_and_link 2> conftest-log1.txt ; then
1700      cat conftest-log1.txt >&AS_MESSAGE_LOG_FD
1701      AC_MSG_RESULT(yes)
1702   else
1703      cat conftest-log1.txt >&AS_MESSAGE_LOG_FD
1704      AC_MSG_RESULT(no)
1705      AR=gcc-ar
1706      RANLIB=gcc-ranlib
1707      AC_MSG_CHECKING([if Link Time Optimisation works with AR=$AR])
1708      if mpfr_compile_and_link 2> conftest-log2.txt; then
1709         cat conftest-log2.txt >&AS_MESSAGE_LOG_FD
1710         AC_MSG_RESULT(yes)
1711      else
1712        cat conftest-log2.txt >&AS_MESSAGE_LOG_FD
1713        AC_MSG_RESULT(no)
1714        AC_MSG_ERROR([Link Time Optimisation is not supported (see config.log for details).])
1715      fi
1716   fi
1717rm -f conftest*
1718])
1719
1720dnl MPFR_CHECK_CONSTRUCTOR_ATTR
1721dnl ---------------------------
1722dnl Check for constructor/destructor attributes to function.
1723dnl Output: Define
1724dnl  * MPFR_HAVE_CONSTRUCTOR_ATTR C define
1725dnl  * mpfr_have_constructor_destructor_attributes shell variable to yes
1726dnl if supported.
1727AC_DEFUN([MPFR_CHECK_CONSTRUCTOR_ATTR], [
1728AC_MSG_CHECKING([for constructor and destructor attributes])
1729AC_LINK_IFELSE([AC_LANG_PROGRAM([[
1730#include <stdlib.h>
1731int x = 0;
1732__attribute__((constructor)) static void
1733call_f(void) { x = 1742; }
1734__attribute__((destructor)) static void
1735call_g(void) { x = 1448; }
1736]], [[
1737    return (x == 1742) ? 0 : 1;
1738]])], [AC_MSG_RESULT(yes)
1739       mpfr_have_constructor_destructor_attributes=yes ],
1740      [AC_MSG_RESULT(no)]
1741)
1742
1743if test "$mpfr_have_constructor_destructor_attributes" = "yes"; then
1744  AC_DEFINE(MPFR_HAVE_CONSTRUCTOR_ATTR, 1,
1745   [Define if the constructor/destructor GCC attributes are supported.])
1746fi
1747])
1748
1749dnl MPFR_CHECK_C11_THREAD
1750dnl ---------------------
1751dnl Check for C11 thread support
1752dnl Output: Define
1753dnl  * MPFR_HAVE_C11_LOCK C define
1754dnl  * mpfr_c11_thread_ok shell variable to yes
1755dnl if supported.
1756dnl We don't check for __STDC_NO_THREADS__ define variable but rather try to mimic our usage.
1757AC_DEFUN([MPFR_CHECK_C11_THREAD], [
1758AC_MSG_CHECKING([for ISO C11 thread support])
1759AC_LINK_IFELSE([AC_LANG_PROGRAM([[
1760#include <assert.h>
1761#include <threads.h>
1762 mtx_t lock;
1763 once_flag once = ONCE_FLAG_INIT;
1764 thrd_t thd_idx;
1765 int x = 0;
1766 void once_call (void) { x = 1; }
1767]], [[
1768    int err;
1769    err = mtx_init(&lock, mtx_plain);
1770    assert(err == thrd_success);
1771    err = mtx_lock(&lock);
1772    assert(err == thrd_success);
1773    err = mtx_unlock(&lock);
1774    assert(err == thrd_success);
1775    mtx_destroy(&lock);
1776    once_call(&once, once_call);
1777    return x == 1 ? 0 : -1;
1778]])], [AC_MSG_RESULT(yes)
1779       mpfr_c11_thread_ok=yes ],
1780      [AC_MSG_RESULT(no)]
1781)
1782
1783if test "$mpfr_c11_thread_ok" = "yes"; then
1784  AC_DEFINE(MPFR_HAVE_C11_LOCK, 1,
1785   [Define if the ISO C11 Thread is supported.])
1786fi
1787])
1788
1789
1790