1# Macros to detect C compiler features
2# config/c-compiler.m4
3
4
5# PGAC_C_SIGNED
6# -------------
7# Check if the C compiler understands signed types.
8AC_DEFUN([PGAC_C_SIGNED],
9[AC_CACHE_CHECK(for signed types, pgac_cv_c_signed,
10[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],
11[signed char c; signed short s; signed int i;])],
12[pgac_cv_c_signed=yes],
13[pgac_cv_c_signed=no])])
14if test x"$pgac_cv_c_signed" = xno ; then
15  AC_DEFINE(signed,, [Define to empty if the C compiler does not understand signed types.])
16fi])# PGAC_C_SIGNED
17
18
19
20# PGAC_C_PRINTF_ARCHETYPE
21# -----------------------
22# Set the format archetype used by gcc to check printf type functions.  We
23# prefer "gnu_printf", which includes what glibc uses, such as %m for error
24# strings and %lld for 64 bit long longs.  GCC 4.4 introduced it.  It makes a
25# dramatic difference on Windows.
26AC_DEFUN([PGAC_PRINTF_ARCHETYPE],
27[AC_CACHE_CHECK([for printf format archetype], pgac_cv_printf_archetype,
28[ac_save_c_werror_flag=$ac_c_werror_flag
29ac_c_werror_flag=yes
30AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
31[extern int
32pgac_write(int ignore, const char *fmt,...)
33__attribute__((format(gnu_printf, 2, 3)));], [])],
34                  [pgac_cv_printf_archetype=gnu_printf],
35                  [pgac_cv_printf_archetype=printf])
36ac_c_werror_flag=$ac_save_c_werror_flag])
37AC_DEFINE_UNQUOTED([PG_PRINTF_ATTRIBUTE], [$pgac_cv_printf_archetype],
38                   [Define to gnu_printf if compiler supports it, else printf.])
39])# PGAC_PRINTF_ARCHETYPE
40
41
42# PGAC_TYPE_64BIT_INT(TYPE)
43# -------------------------
44# Check if TYPE is a working 64 bit integer type. Set HAVE_TYPE_64 to
45# yes or no respectively, and define HAVE_TYPE_64 if yes.
46AC_DEFUN([PGAC_TYPE_64BIT_INT],
47[define([Ac_define], [translit([have_$1_64], [a-z *], [A-Z_P])])dnl
48define([Ac_cachevar], [translit([pgac_cv_type_$1_64], [ *], [_p])])dnl
49AC_CACHE_CHECK([whether $1 is 64 bits], [Ac_cachevar],
50[AC_RUN_IFELSE([AC_LANG_SOURCE(
51[typedef $1 ac_int64;
52
53/*
54 * These are globals to discourage the compiler from folding all the
55 * arithmetic tests down to compile-time constants.
56 */
57ac_int64 a = 20000001;
58ac_int64 b = 40000005;
59
60int does_int64_work()
61{
62  ac_int64 c,d;
63
64  if (sizeof(ac_int64) != 8)
65    return 0;			/* definitely not the right size */
66
67  /* Do perfunctory checks to see if 64-bit arithmetic seems to work */
68  c = a * b;
69  d = (c + b) / b;
70  if (d != a+1)
71    return 0;
72  return 1;
73}
74
75int
76main() {
77  return (! does_int64_work());
78}])],
79[Ac_cachevar=yes],
80[Ac_cachevar=no],
81[# If cross-compiling, check the size reported by the compiler and
82# trust that the arithmetic works.
83AC_COMPILE_IFELSE([AC_LANG_BOOL_COMPILE_TRY([], [sizeof($1) == 8])],
84                  Ac_cachevar=yes,
85                  Ac_cachevar=no)])])
86
87Ac_define=$Ac_cachevar
88if test x"$Ac_cachevar" = xyes ; then
89  AC_DEFINE(Ac_define, 1, [Define to 1 if `]$1[' works and is 64 bits.])
90fi
91undefine([Ac_define])dnl
92undefine([Ac_cachevar])dnl
93])# PGAC_TYPE_64BIT_INT
94
95
96# PGAC_TYPE_128BIT_INT
97# ---------------------
98# Check if __int128 is a working 128 bit integer type, and if so
99# define PG_INT128_TYPE to that typename, and define ALIGNOF_PG_INT128_TYPE
100# as its alignment requirement.
101#
102# This currently only detects a GCC/clang extension, but support for other
103# environments may be added in the future.
104#
105# For the moment we only test for support for 128bit math; support for
106# 128bit literals and snprintf is not required.
107AC_DEFUN([PGAC_TYPE_128BIT_INT],
108[AC_CACHE_CHECK([for __int128], [pgac_cv__128bit_int],
109[AC_LINK_IFELSE([AC_LANG_PROGRAM([
110/*
111 * We don't actually run this test, just link it to verify that any support
112 * functions needed for __int128 are present.
113 *
114 * These are globals to discourage the compiler from folding all the
115 * arithmetic tests down to compile-time constants.  We do not have
116 * convenient support for 128bit literals at this point...
117 */
118__int128 a = 48828125;
119__int128 b = 97656250;
120],[
121__int128 c,d;
122a = (a << 12) + 1; /* 200000000001 */
123b = (b << 12) + 5; /* 400000000005 */
124/* try the most relevant arithmetic ops */
125c = a * b;
126d = (c + b) / b;
127/* must use the results, else compiler may optimize arithmetic away */
128if (d != a+1)
129  return 1;
130])],
131[pgac_cv__128bit_int=yes],
132[pgac_cv__128bit_int=no])])
133if test x"$pgac_cv__128bit_int" = xyes ; then
134  # Use of non-default alignment with __int128 tickles bugs in some compilers.
135  # If not cross-compiling, we can test for bugs and disable use of __int128
136  # with buggy compilers.  If cross-compiling, hope for the best.
137  # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83925
138  AC_CACHE_CHECK([for __int128 alignment bug], [pgac_cv__128bit_int_bug],
139  [AC_RUN_IFELSE([AC_LANG_PROGRAM([
140/* This must match the corresponding code in c.h: */
141#if defined(__GNUC__) || defined(__SUNPRO_C) || defined(__IBMC__)
142#define pg_attribute_aligned(a) __attribute__((aligned(a)))
143#endif
144typedef __int128 int128a
145#if defined(pg_attribute_aligned)
146pg_attribute_aligned(8)
147#endif
148;
149int128a holder;
150void pass_by_val(void *buffer, int128a par) { holder = par; }
151],[
152long int i64 = 97656225L << 12;
153int128a q;
154pass_by_val(main, (int128a) i64);
155q = (int128a) i64;
156if (q != holder)
157  return 1;
158])],
159  [pgac_cv__128bit_int_bug=ok],
160  [pgac_cv__128bit_int_bug=broken],
161  [pgac_cv__128bit_int_bug="assuming ok"])])
162  if test x"$pgac_cv__128bit_int_bug" != xbroken ; then
163    AC_DEFINE(PG_INT128_TYPE, __int128, [Define to the name of a signed 128-bit integer type.])
164    AC_CHECK_ALIGNOF(PG_INT128_TYPE)
165  fi
166fi])# PGAC_TYPE_128BIT_INT
167
168
169# PGAC_C_FUNCNAME_SUPPORT
170# -----------------------
171# Check if the C compiler understands __func__ (C99) or __FUNCTION__ (gcc).
172# Define HAVE_FUNCNAME__FUNC or HAVE_FUNCNAME__FUNCTION accordingly.
173AC_DEFUN([PGAC_C_FUNCNAME_SUPPORT],
174[AC_CACHE_CHECK(for __func__, pgac_cv_funcname_func_support,
175[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include <stdio.h>],
176[printf("%s\n", __func__);])],
177[pgac_cv_funcname_func_support=yes],
178[pgac_cv_funcname_func_support=no])])
179if test x"$pgac_cv_funcname_func_support" = xyes ; then
180AC_DEFINE(HAVE_FUNCNAME__FUNC, 1,
181          [Define to 1 if your compiler understands __func__.])
182else
183AC_CACHE_CHECK(for __FUNCTION__, pgac_cv_funcname_function_support,
184[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include <stdio.h>],
185[printf("%s\n", __FUNCTION__);])],
186[pgac_cv_funcname_function_support=yes],
187[pgac_cv_funcname_function_support=no])])
188if test x"$pgac_cv_funcname_function_support" = xyes ; then
189AC_DEFINE(HAVE_FUNCNAME__FUNCTION, 1,
190          [Define to 1 if your compiler understands __FUNCTION__.])
191fi
192fi])# PGAC_C_FUNCNAME_SUPPORT
193
194
195
196# PGAC_C_STATIC_ASSERT
197# --------------------
198# Check if the C compiler understands _Static_assert(),
199# and define HAVE__STATIC_ASSERT if so.
200#
201# We actually check the syntax ({ _Static_assert(...) }), because we need
202# gcc-style compound expressions to be able to wrap the thing into macros.
203AC_DEFUN([PGAC_C_STATIC_ASSERT],
204[AC_CACHE_CHECK(for _Static_assert, pgac_cv__static_assert,
205[AC_LINK_IFELSE([AC_LANG_PROGRAM([],
206[({ _Static_assert(1, "foo"); })])],
207[pgac_cv__static_assert=yes],
208[pgac_cv__static_assert=no])])
209if test x"$pgac_cv__static_assert" = xyes ; then
210AC_DEFINE(HAVE__STATIC_ASSERT, 1,
211          [Define to 1 if your compiler understands _Static_assert.])
212fi])# PGAC_C_STATIC_ASSERT
213
214
215
216# PGAC_C_TYPEOF
217# -------------
218# Check if the C compiler understands typeof or a variant.  Define
219# HAVE_TYPEOF if so, and define 'typeof' to the actual key word.
220#
221AC_DEFUN([PGAC_C_TYPEOF],
222[AC_CACHE_CHECK(for typeof, pgac_cv_c_typeof,
223[pgac_cv_c_typeof=no
224for pgac_kw in typeof __typeof__ decltype; do
225  AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],
226[int x = 0;
227$pgac_kw(x) y;
228y = x;
229return y;])],
230[pgac_cv_c_typeof=$pgac_kw])
231  test "$pgac_cv_c_typeof" != no && break
232done])
233if test "$pgac_cv_c_typeof" != no; then
234  AC_DEFINE(HAVE_TYPEOF, 1,
235            [Define to 1 if your compiler understands `typeof' or something similar.])
236  if test "$pgac_cv_c_typeof" != typeof; then
237    AC_DEFINE_UNQUOTED(typeof, $pgac_cv_c_typeof, [Define to how the compiler spells `typeof'.])
238  fi
239fi])# PGAC_C_TYPEOF
240
241
242
243# PGAC_C_TYPES_COMPATIBLE
244# -----------------------
245# Check if the C compiler understands __builtin_types_compatible_p,
246# and define HAVE__BUILTIN_TYPES_COMPATIBLE_P if so.
247#
248# We check usage with __typeof__, though it's unlikely any compiler would
249# have the former and not the latter.
250AC_DEFUN([PGAC_C_TYPES_COMPATIBLE],
251[AC_CACHE_CHECK(for __builtin_types_compatible_p, pgac_cv__types_compatible,
252[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],
253[[ int x; static int y[__builtin_types_compatible_p(__typeof__(x), int)]; ]])],
254[pgac_cv__types_compatible=yes],
255[pgac_cv__types_compatible=no])])
256if test x"$pgac_cv__types_compatible" = xyes ; then
257AC_DEFINE(HAVE__BUILTIN_TYPES_COMPATIBLE_P, 1,
258          [Define to 1 if your compiler understands __builtin_types_compatible_p.])
259fi])# PGAC_C_TYPES_COMPATIBLE
260
261
262# PGAC_C_BUILTIN_BSWAP16
263# -------------------------
264# Check if the C compiler understands __builtin_bswap16(),
265# and define HAVE__BUILTIN_BSWAP16 if so.
266AC_DEFUN([PGAC_C_BUILTIN_BSWAP16],
267[AC_CACHE_CHECK(for __builtin_bswap16, pgac_cv__builtin_bswap16,
268[AC_COMPILE_IFELSE([AC_LANG_SOURCE(
269[static unsigned long int x = __builtin_bswap16(0xaabb);]
270)],
271[pgac_cv__builtin_bswap16=yes],
272[pgac_cv__builtin_bswap16=no])])
273if test x"$pgac_cv__builtin_bswap16" = xyes ; then
274AC_DEFINE(HAVE__BUILTIN_BSWAP16, 1,
275          [Define to 1 if your compiler understands __builtin_bswap16.])
276fi])# PGAC_C_BUILTIN_BSWAP16
277
278
279
280# PGAC_C_BUILTIN_BSWAP32
281# -------------------------
282# Check if the C compiler understands __builtin_bswap32(),
283# and define HAVE__BUILTIN_BSWAP32 if so.
284AC_DEFUN([PGAC_C_BUILTIN_BSWAP32],
285[AC_CACHE_CHECK(for __builtin_bswap32, pgac_cv__builtin_bswap32,
286[AC_COMPILE_IFELSE([AC_LANG_SOURCE(
287[static unsigned long int x = __builtin_bswap32(0xaabbccdd);]
288)],
289[pgac_cv__builtin_bswap32=yes],
290[pgac_cv__builtin_bswap32=no])])
291if test x"$pgac_cv__builtin_bswap32" = xyes ; then
292AC_DEFINE(HAVE__BUILTIN_BSWAP32, 1,
293          [Define to 1 if your compiler understands __builtin_bswap32.])
294fi])# PGAC_C_BUILTIN_BSWAP32
295
296
297
298# PGAC_C_BUILTIN_BSWAP64
299# -------------------------
300# Check if the C compiler understands __builtin_bswap64(),
301# and define HAVE__BUILTIN_BSWAP64 if so.
302AC_DEFUN([PGAC_C_BUILTIN_BSWAP64],
303[AC_CACHE_CHECK(for __builtin_bswap64, pgac_cv__builtin_bswap64,
304[AC_COMPILE_IFELSE([AC_LANG_SOURCE(
305[static unsigned long int x = __builtin_bswap64(0xaabbccddeeff0011);]
306)],
307[pgac_cv__builtin_bswap64=yes],
308[pgac_cv__builtin_bswap64=no])])
309if test x"$pgac_cv__builtin_bswap64" = xyes ; then
310AC_DEFINE(HAVE__BUILTIN_BSWAP64, 1,
311          [Define to 1 if your compiler understands __builtin_bswap64.])
312fi])# PGAC_C_BUILTIN_BSWAP64
313
314
315
316# PGAC_C_BUILTIN_CONSTANT_P
317# -------------------------
318# Check if the C compiler understands __builtin_constant_p(),
319# and define HAVE__BUILTIN_CONSTANT_P if so.
320# We need __builtin_constant_p("string literal") to be true, but some older
321# compilers don't think that, so test for that case explicitly.
322AC_DEFUN([PGAC_C_BUILTIN_CONSTANT_P],
323[AC_CACHE_CHECK(for __builtin_constant_p, pgac_cv__builtin_constant_p,
324[AC_COMPILE_IFELSE([AC_LANG_SOURCE(
325[[static int x;
326  static int y[__builtin_constant_p(x) ? x : 1];
327  static int z[__builtin_constant_p("string literal") ? 1 : x];
328]]
329)],
330[pgac_cv__builtin_constant_p=yes],
331[pgac_cv__builtin_constant_p=no])])
332if test x"$pgac_cv__builtin_constant_p" = xyes ; then
333AC_DEFINE(HAVE__BUILTIN_CONSTANT_P, 1,
334          [Define to 1 if your compiler understands __builtin_constant_p.])
335fi])# PGAC_C_BUILTIN_CONSTANT_P
336
337
338
339# PGAC_C_BUILTIN_OP_OVERFLOW
340# -------------------------
341# Check if the C compiler understands __builtin_$op_overflow(),
342# and define HAVE__BUILTIN_OP_OVERFLOW if so.
343#
344# Check for the most complicated case, 64 bit multiplication, as a
345# proxy for all of the operations.  To detect the case where the compiler
346# knows the function but library support is missing, we must link not just
347# compile, and store the results in global variables so the compiler doesn't
348# optimize away the call.
349AC_DEFUN([PGAC_C_BUILTIN_OP_OVERFLOW],
350[AC_CACHE_CHECK(for __builtin_mul_overflow, pgac_cv__builtin_op_overflow,
351[AC_LINK_IFELSE([AC_LANG_PROGRAM([
352PG_INT64_TYPE a = 1;
353PG_INT64_TYPE b = 1;
354PG_INT64_TYPE result;
355int oflo;
356],
357[oflo = __builtin_mul_overflow(a, b, &result);])],
358[pgac_cv__builtin_op_overflow=yes],
359[pgac_cv__builtin_op_overflow=no])])
360if test x"$pgac_cv__builtin_op_overflow" = xyes ; then
361AC_DEFINE(HAVE__BUILTIN_OP_OVERFLOW, 1,
362          [Define to 1 if your compiler understands __builtin_$op_overflow.])
363fi])# PGAC_C_BUILTIN_OP_OVERFLOW
364
365
366
367# PGAC_C_BUILTIN_UNREACHABLE
368# --------------------------
369# Check if the C compiler understands __builtin_unreachable(),
370# and define HAVE__BUILTIN_UNREACHABLE if so.
371#
372# NB: Don't get the idea of putting a for(;;); or such before the
373# __builtin_unreachable() call.  Some compilers would remove it before linking
374# and only a warning instead of an error would be produced.
375AC_DEFUN([PGAC_C_BUILTIN_UNREACHABLE],
376[AC_CACHE_CHECK(for __builtin_unreachable, pgac_cv__builtin_unreachable,
377[AC_LINK_IFELSE([AC_LANG_PROGRAM([],
378[__builtin_unreachable();])],
379[pgac_cv__builtin_unreachable=yes],
380[pgac_cv__builtin_unreachable=no])])
381if test x"$pgac_cv__builtin_unreachable" = xyes ; then
382AC_DEFINE(HAVE__BUILTIN_UNREACHABLE, 1,
383          [Define to 1 if your compiler understands __builtin_unreachable.])
384fi])# PGAC_C_BUILTIN_UNREACHABLE
385
386
387
388# PGAC_C_COMPUTED_GOTO
389# -----------------------
390# Check if the C compiler knows computed gotos (gcc extension, also
391# available in at least clang).  If so, define HAVE_COMPUTED_GOTO.
392#
393# Checking whether computed gotos are supported syntax-wise ought to
394# be enough, as the syntax is otherwise illegal.
395AC_DEFUN([PGAC_C_COMPUTED_GOTO],
396[AC_CACHE_CHECK(for computed goto support, pgac_cv_computed_goto,
397[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],
398[[void *labeladdrs[] = {&&my_label};
399  goto *labeladdrs[0];
400  my_label:
401  return 1;
402]])],
403[pgac_cv_computed_goto=yes],
404[pgac_cv_computed_goto=no])])
405if test x"$pgac_cv_computed_goto" = xyes ; then
406AC_DEFINE(HAVE_COMPUTED_GOTO, 1,
407          [Define to 1 if your compiler handles computed gotos.])
408fi])# PGAC_C_COMPUTED_GOTO
409
410
411
412# PGAC_C_VA_ARGS
413# --------------
414# Check if the C compiler understands C99-style variadic macros,
415# and define HAVE__VA_ARGS if so.
416AC_DEFUN([PGAC_C_VA_ARGS],
417[AC_CACHE_CHECK(for __VA_ARGS__, pgac_cv__va_args,
418[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include <stdio.h>],
419[#define debug(...) fprintf(stderr, __VA_ARGS__)
420debug("%s", "blarg");
421])],
422[pgac_cv__va_args=yes],
423[pgac_cv__va_args=no])])
424if test x"$pgac_cv__va_args" = xyes ; then
425AC_DEFINE(HAVE__VA_ARGS, 1,
426          [Define to 1 if your compiler understands __VA_ARGS__ in macros.])
427fi])# PGAC_C_VA_ARGS
428
429
430
431# PGAC_PROG_VARCC_VARFLAGS_OPT
432# -----------------------
433# Given a compiler, variable name and a string, check if the compiler
434# supports the string as a command-line option. If it does, add the
435# string to the given variable.
436AC_DEFUN([PGAC_PROG_VARCC_VARFLAGS_OPT],
437[define([Ac_cachevar], [AS_TR_SH([pgac_cv_prog_$1_cflags_$3])])dnl
438AC_CACHE_CHECK([whether ${$1} supports $3, for $2], [Ac_cachevar],
439[pgac_save_CFLAGS=$CFLAGS
440pgac_save_CC=$CC
441CC=${$1}
442CFLAGS="${$2} $3"
443ac_save_c_werror_flag=$ac_c_werror_flag
444ac_c_werror_flag=yes
445_AC_COMPILE_IFELSE([AC_LANG_PROGRAM()],
446                   [Ac_cachevar=yes],
447                   [Ac_cachevar=no])
448ac_c_werror_flag=$ac_save_c_werror_flag
449CFLAGS="$pgac_save_CFLAGS"
450CC="$pgac_save_CC"])
451if test x"$Ac_cachevar" = x"yes"; then
452  $2="${$2} $3"
453fi
454undefine([Ac_cachevar])dnl
455])# PGAC_PROG_VARCC_VARFLAGS_OPT
456
457
458
459# PGAC_PROG_CC_CFLAGS_OPT
460# -----------------------
461# Given a string, check if the compiler supports the string as a
462# command-line option. If it does, add the string to CFLAGS.
463AC_DEFUN([PGAC_PROG_CC_CFLAGS_OPT], [
464PGAC_PROG_VARCC_VARFLAGS_OPT(CC, CFLAGS, $1)
465])# PGAC_PROG_CC_CFLAGS_OPT
466
467
468
469# PGAC_PROG_CC_VAR_OPT
470# -----------------------
471# Given a variable name and a string, check if the compiler supports
472# the string as a command-line option. If it does, add the string to
473# the given variable.
474AC_DEFUN([PGAC_PROG_CC_VAR_OPT],
475[PGAC_PROG_VARCC_VARFLAGS_OPT(CC, $1, $2)
476])# PGAC_PROG_CC_VAR_OPT
477
478
479
480# PGAC_PROG_VARCXX_VARFLAGS_OPT
481# -----------------------
482# Given a compiler, variable name and a string, check if the compiler
483# supports the string as a command-line option. If it does, add the
484# string to the given variable.
485AC_DEFUN([PGAC_PROG_VARCXX_VARFLAGS_OPT],
486[define([Ac_cachevar], [AS_TR_SH([pgac_cv_prog_$1_cxxflags_$3])])dnl
487AC_CACHE_CHECK([whether ${$1} supports $3, for $2], [Ac_cachevar],
488[pgac_save_CXXFLAGS=$CXXFLAGS
489pgac_save_CXX=$CXX
490CXX=${$1}
491CXXFLAGS="${$2} $3"
492ac_save_cxx_werror_flag=$ac_cxx_werror_flag
493ac_cxx_werror_flag=yes
494AC_LANG_PUSH(C++)
495_AC_COMPILE_IFELSE([AC_LANG_PROGRAM()],
496                   [Ac_cachevar=yes],
497                   [Ac_cachevar=no])
498AC_LANG_POP([])
499ac_cxx_werror_flag=$ac_save_cxx_werror_flag
500CXXFLAGS="$pgac_save_CXXFLAGS"
501CXX="$pgac_save_CXX"])
502if test x"$Ac_cachevar" = x"yes"; then
503  $2="${$2} $3"
504fi
505undefine([Ac_cachevar])dnl
506])# PGAC_PROG_VARCXX_VARFLAGS_OPT
507
508
509
510# PGAC_PROG_CXX_CFLAGS_OPT
511# -----------------------
512# Given a string, check if the compiler supports the string as a
513# command-line option. If it does, add the string to CXXFLAGS.
514AC_DEFUN([PGAC_PROG_CXX_CFLAGS_OPT],
515[PGAC_PROG_VARCXX_VARFLAGS_OPT(CXX, CXXFLAGS, $1)
516])# PGAC_PROG_CXX_VAR_OPT
517
518
519
520# PGAC_PROG_CC_LDFLAGS_OPT
521# ------------------------
522# Given a string, check if the compiler supports the string as a
523# command-line option. If it does, add the string to LDFLAGS.
524# For reasons you'd really rather not know about, this checks whether
525# you can link to a particular function, not just whether you can link.
526# In fact, we must actually check that the resulting program runs :-(
527AC_DEFUN([PGAC_PROG_CC_LDFLAGS_OPT],
528[define([Ac_cachevar], [AS_TR_SH([pgac_cv_prog_cc_ldflags_$1])])dnl
529AC_CACHE_CHECK([whether $CC supports $1], [Ac_cachevar],
530[pgac_save_LDFLAGS=$LDFLAGS
531LDFLAGS="$pgac_save_LDFLAGS $1"
532AC_RUN_IFELSE([AC_LANG_PROGRAM([extern void $2 (); void (*fptr) () = $2;],[])],
533              [Ac_cachevar=yes],
534              [Ac_cachevar=no],
535              [Ac_cachevar="assuming no"])
536LDFLAGS="$pgac_save_LDFLAGS"])
537if test x"$Ac_cachevar" = x"yes"; then
538  LDFLAGS="$LDFLAGS $1"
539fi
540undefine([Ac_cachevar])dnl
541])# PGAC_PROG_CC_LDFLAGS_OPT
542
543# PGAC_HAVE_GCC__SYNC_CHAR_TAS
544# -------------------------
545# Check if the C compiler understands __sync_lock_test_and_set(char),
546# and define HAVE_GCC__SYNC_CHAR_TAS
547#
548# NB: There are platforms where test_and_set is available but compare_and_swap
549# is not, so test this separately.
550# NB: Some platforms only do 32bit tas, others only do 8bit tas. Test both.
551AC_DEFUN([PGAC_HAVE_GCC__SYNC_CHAR_TAS],
552[AC_CACHE_CHECK(for builtin __sync char locking functions, pgac_cv_gcc_sync_char_tas,
553[AC_LINK_IFELSE([AC_LANG_PROGRAM([],
554  [char lock = 0;
555   __sync_lock_test_and_set(&lock, 1);
556   __sync_lock_release(&lock);])],
557  [pgac_cv_gcc_sync_char_tas="yes"],
558  [pgac_cv_gcc_sync_char_tas="no"])])
559if test x"$pgac_cv_gcc_sync_char_tas" = x"yes"; then
560  AC_DEFINE(HAVE_GCC__SYNC_CHAR_TAS, 1, [Define to 1 if you have __sync_lock_test_and_set(char *) and friends.])
561fi])# PGAC_HAVE_GCC__SYNC_CHAR_TAS
562
563# PGAC_HAVE_GCC__SYNC_INT32_TAS
564# -------------------------
565# Check if the C compiler understands __sync_lock_test_and_set(),
566# and define HAVE_GCC__SYNC_INT32_TAS
567AC_DEFUN([PGAC_HAVE_GCC__SYNC_INT32_TAS],
568[AC_CACHE_CHECK(for builtin __sync int32 locking functions, pgac_cv_gcc_sync_int32_tas,
569[AC_LINK_IFELSE([AC_LANG_PROGRAM([],
570  [int lock = 0;
571   __sync_lock_test_and_set(&lock, 1);
572   __sync_lock_release(&lock);])],
573  [pgac_cv_gcc_sync_int32_tas="yes"],
574  [pgac_cv_gcc_sync_int32_tas="no"])])
575if test x"$pgac_cv_gcc_sync_int32_tas" = x"yes"; then
576  AC_DEFINE(HAVE_GCC__SYNC_INT32_TAS, 1, [Define to 1 if you have __sync_lock_test_and_set(int *) and friends.])
577fi])# PGAC_HAVE_GCC__SYNC_INT32_TAS
578
579# PGAC_HAVE_GCC__SYNC_INT32_CAS
580# -------------------------
581# Check if the C compiler understands __sync_compare_and_swap() for 32bit
582# types, and define HAVE_GCC__SYNC_INT32_CAS if so.
583AC_DEFUN([PGAC_HAVE_GCC__SYNC_INT32_CAS],
584[AC_CACHE_CHECK(for builtin __sync int32 atomic operations, pgac_cv_gcc_sync_int32_cas,
585[AC_LINK_IFELSE([AC_LANG_PROGRAM([],
586  [int val = 0;
587   __sync_val_compare_and_swap(&val, 0, 37);])],
588  [pgac_cv_gcc_sync_int32_cas="yes"],
589  [pgac_cv_gcc_sync_int32_cas="no"])])
590if test x"$pgac_cv_gcc_sync_int32_cas" = x"yes"; then
591  AC_DEFINE(HAVE_GCC__SYNC_INT32_CAS, 1, [Define to 1 if you have __sync_val_compare_and_swap(int *, int, int).])
592fi])# PGAC_HAVE_GCC__SYNC_INT32_CAS
593
594# PGAC_HAVE_GCC__SYNC_INT64_CAS
595# -------------------------
596# Check if the C compiler understands __sync_compare_and_swap() for 64bit
597# types, and define HAVE_GCC__SYNC_INT64_CAS if so.
598AC_DEFUN([PGAC_HAVE_GCC__SYNC_INT64_CAS],
599[AC_CACHE_CHECK(for builtin __sync int64 atomic operations, pgac_cv_gcc_sync_int64_cas,
600[AC_LINK_IFELSE([AC_LANG_PROGRAM([],
601  [PG_INT64_TYPE lock = 0;
602   __sync_val_compare_and_swap(&lock, 0, (PG_INT64_TYPE) 37);])],
603  [pgac_cv_gcc_sync_int64_cas="yes"],
604  [pgac_cv_gcc_sync_int64_cas="no"])])
605if test x"$pgac_cv_gcc_sync_int64_cas" = x"yes"; then
606  AC_DEFINE(HAVE_GCC__SYNC_INT64_CAS, 1, [Define to 1 if you have __sync_val_compare_and_swap(int64 *, int64, int64).])
607fi])# PGAC_HAVE_GCC__SYNC_INT64_CAS
608
609# PGAC_HAVE_GCC__ATOMIC_INT32_CAS
610# -------------------------
611# Check if the C compiler understands __atomic_compare_exchange_n() for 32bit
612# types, and define HAVE_GCC__ATOMIC_INT32_CAS if so.
613AC_DEFUN([PGAC_HAVE_GCC__ATOMIC_INT32_CAS],
614[AC_CACHE_CHECK(for builtin __atomic int32 atomic operations, pgac_cv_gcc_atomic_int32_cas,
615[AC_LINK_IFELSE([AC_LANG_PROGRAM([],
616  [int val = 0;
617   int expect = 0;
618   __atomic_compare_exchange_n(&val, &expect, 37, 0, __ATOMIC_SEQ_CST, __ATOMIC_RELAXED);])],
619  [pgac_cv_gcc_atomic_int32_cas="yes"],
620  [pgac_cv_gcc_atomic_int32_cas="no"])])
621if test x"$pgac_cv_gcc_atomic_int32_cas" = x"yes"; then
622  AC_DEFINE(HAVE_GCC__ATOMIC_INT32_CAS, 1, [Define to 1 if you have __atomic_compare_exchange_n(int *, int *, int).])
623fi])# PGAC_HAVE_GCC__ATOMIC_INT32_CAS
624
625# PGAC_HAVE_GCC__ATOMIC_INT64_CAS
626# -------------------------
627# Check if the C compiler understands __atomic_compare_exchange_n() for 64bit
628# types, and define HAVE_GCC__ATOMIC_INT64_CAS if so.
629AC_DEFUN([PGAC_HAVE_GCC__ATOMIC_INT64_CAS],
630[AC_CACHE_CHECK(for builtin __atomic int64 atomic operations, pgac_cv_gcc_atomic_int64_cas,
631[AC_LINK_IFELSE([AC_LANG_PROGRAM([],
632  [PG_INT64_TYPE val = 0;
633   PG_INT64_TYPE expect = 0;
634   __atomic_compare_exchange_n(&val, &expect, 37, 0, __ATOMIC_SEQ_CST, __ATOMIC_RELAXED);])],
635  [pgac_cv_gcc_atomic_int64_cas="yes"],
636  [pgac_cv_gcc_atomic_int64_cas="no"])])
637if test x"$pgac_cv_gcc_atomic_int64_cas" = x"yes"; then
638  AC_DEFINE(HAVE_GCC__ATOMIC_INT64_CAS, 1, [Define to 1 if you have __atomic_compare_exchange_n(int64 *, int64 *, int64).])
639fi])# PGAC_HAVE_GCC__ATOMIC_INT64_CAS
640
641# PGAC_SSE42_CRC32_INTRINSICS
642# -----------------------
643# Check if the compiler supports the x86 CRC instructions added in SSE 4.2,
644# using the _mm_crc32_u8 and _mm_crc32_u32 intrinsic functions. (We don't
645# test the 8-byte variant, _mm_crc32_u64, but it is assumed to be present if
646# the other ones are, on x86-64 platforms)
647#
648# An optional compiler flag can be passed as argument (e.g. -msse4.2). If the
649# intrinsics are supported, sets pgac_sse42_crc32_intrinsics, and CFLAGS_SSE42.
650AC_DEFUN([PGAC_SSE42_CRC32_INTRINSICS],
651[define([Ac_cachevar], [AS_TR_SH([pgac_cv_sse42_crc32_intrinsics_$1])])dnl
652AC_CACHE_CHECK([for _mm_crc32_u8 and _mm_crc32_u32 with CFLAGS=$1], [Ac_cachevar],
653[pgac_save_CFLAGS=$CFLAGS
654CFLAGS="$pgac_save_CFLAGS $1"
655AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <nmmintrin.h>],
656  [unsigned int crc = 0;
657   crc = _mm_crc32_u8(crc, 0);
658   crc = _mm_crc32_u32(crc, 0);
659   /* return computed value, to prevent the above being optimized away */
660   return crc == 0;])],
661  [Ac_cachevar=yes],
662  [Ac_cachevar=no])
663CFLAGS="$pgac_save_CFLAGS"])
664if test x"$Ac_cachevar" = x"yes"; then
665  CFLAGS_SSE42="$1"
666  pgac_sse42_crc32_intrinsics=yes
667fi
668undefine([Ac_cachevar])dnl
669])# PGAC_SSE42_CRC32_INTRINSICS
670
671
672# PGAC_ARMV8_CRC32C_INTRINSICS
673# -----------------------
674# Check if the compiler supports the CRC32C instructions using the __crc32cb,
675# __crc32ch, __crc32cw, and __crc32cd intrinsic functions. These instructions
676# were first introduced in ARMv8 in the optional CRC Extension, and became
677# mandatory in ARMv8.1.
678#
679# An optional compiler flag can be passed as argument (e.g.
680# -march=armv8-a+crc). If the intrinsics are supported, sets
681# pgac_armv8_crc32c_intrinsics, and CFLAGS_ARMV8_CRC32C.
682AC_DEFUN([PGAC_ARMV8_CRC32C_INTRINSICS],
683[define([Ac_cachevar], [AS_TR_SH([pgac_cv_armv8_crc32c_intrinsics_$1])])dnl
684AC_CACHE_CHECK([for __crc32cb, __crc32ch, __crc32cw, and __crc32cd with CFLAGS=$1], [Ac_cachevar],
685[pgac_save_CFLAGS=$CFLAGS
686CFLAGS="$pgac_save_CFLAGS $1"
687AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <arm_acle.h>],
688  [unsigned int crc = 0;
689   crc = __crc32cb(crc, 0);
690   crc = __crc32ch(crc, 0);
691   crc = __crc32cw(crc, 0);
692   crc = __crc32cd(crc, 0);
693   /* return computed value, to prevent the above being optimized away */
694   return crc == 0;])],
695  [Ac_cachevar=yes],
696  [Ac_cachevar=no])
697CFLAGS="$pgac_save_CFLAGS"])
698if test x"$Ac_cachevar" = x"yes"; then
699  CFLAGS_ARMV8_CRC32C="$1"
700  pgac_armv8_crc32c_intrinsics=yes
701fi
702undefine([Ac_cachevar])dnl
703])# PGAC_ARMV8_CRC32C_INTRINSICS
704