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_TYPES_COMPATIBLE
217# -----------------------
218# Check if the C compiler understands __builtin_types_compatible_p,
219# and define HAVE__BUILTIN_TYPES_COMPATIBLE_P if so.
220#
221# We check usage with __typeof__, though it's unlikely any compiler would
222# have the former and not the latter.
223AC_DEFUN([PGAC_C_TYPES_COMPATIBLE],
224[AC_CACHE_CHECK(for __builtin_types_compatible_p, pgac_cv__types_compatible,
225[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],
226[[ int x; static int y[__builtin_types_compatible_p(__typeof__(x), int)]; ]])],
227[pgac_cv__types_compatible=yes],
228[pgac_cv__types_compatible=no])])
229if test x"$pgac_cv__types_compatible" = xyes ; then
230AC_DEFINE(HAVE__BUILTIN_TYPES_COMPATIBLE_P, 1,
231          [Define to 1 if your compiler understands __builtin_types_compatible_p.])
232fi])# PGAC_C_TYPES_COMPATIBLE
233
234
235
236# PGAC_C_BUILTIN_BSWAP32
237# -------------------------
238# Check if the C compiler understands __builtin_bswap32(),
239# and define HAVE__BUILTIN_BSWAP32 if so.
240AC_DEFUN([PGAC_C_BUILTIN_BSWAP32],
241[AC_CACHE_CHECK(for __builtin_bswap32, pgac_cv__builtin_bswap32,
242[AC_COMPILE_IFELSE([AC_LANG_SOURCE(
243[static unsigned long int x = __builtin_bswap32(0xaabbccdd);]
244)],
245[pgac_cv__builtin_bswap32=yes],
246[pgac_cv__builtin_bswap32=no])])
247if test x"$pgac_cv__builtin_bswap32" = xyes ; then
248AC_DEFINE(HAVE__BUILTIN_BSWAP32, 1,
249          [Define to 1 if your compiler understands __builtin_bswap32.])
250fi])# PGAC_C_BUILTIN_BSWAP32
251
252
253
254# PGAC_C_BUILTIN_BSWAP64
255# -------------------------
256# Check if the C compiler understands __builtin_bswap64(),
257# and define HAVE__BUILTIN_BSWAP64 if so.
258AC_DEFUN([PGAC_C_BUILTIN_BSWAP64],
259[AC_CACHE_CHECK(for __builtin_bswap64, pgac_cv__builtin_bswap64,
260[AC_COMPILE_IFELSE([AC_LANG_SOURCE(
261[static unsigned long int x = __builtin_bswap64(0xaabbccddeeff0011);]
262)],
263[pgac_cv__builtin_bswap64=yes],
264[pgac_cv__builtin_bswap64=no])])
265if test x"$pgac_cv__builtin_bswap64" = xyes ; then
266AC_DEFINE(HAVE__BUILTIN_BSWAP64, 1,
267          [Define to 1 if your compiler understands __builtin_bswap64.])
268fi])# PGAC_C_BUILTIN_BSWAP64
269
270
271
272# PGAC_C_BUILTIN_CONSTANT_P
273# -------------------------
274# Check if the C compiler understands __builtin_constant_p(),
275# and define HAVE__BUILTIN_CONSTANT_P if so.
276AC_DEFUN([PGAC_C_BUILTIN_CONSTANT_P],
277[AC_CACHE_CHECK(for __builtin_constant_p, pgac_cv__builtin_constant_p,
278[AC_COMPILE_IFELSE([AC_LANG_SOURCE(
279[[static int x; static int y[__builtin_constant_p(x) ? x : 1];]]
280)],
281[pgac_cv__builtin_constant_p=yes],
282[pgac_cv__builtin_constant_p=no])])
283if test x"$pgac_cv__builtin_constant_p" = xyes ; then
284AC_DEFINE(HAVE__BUILTIN_CONSTANT_P, 1,
285          [Define to 1 if your compiler understands __builtin_constant_p.])
286fi])# PGAC_C_BUILTIN_CONSTANT_P
287
288
289
290# PGAC_C_BUILTIN_UNREACHABLE
291# --------------------------
292# Check if the C compiler understands __builtin_unreachable(),
293# and define HAVE__BUILTIN_UNREACHABLE if so.
294#
295# NB: Don't get the idea of putting a for(;;); or such before the
296# __builtin_unreachable() call.  Some compilers would remove it before linking
297# and only a warning instead of an error would be produced.
298AC_DEFUN([PGAC_C_BUILTIN_UNREACHABLE],
299[AC_CACHE_CHECK(for __builtin_unreachable, pgac_cv__builtin_unreachable,
300[AC_LINK_IFELSE([AC_LANG_PROGRAM([],
301[__builtin_unreachable();])],
302[pgac_cv__builtin_unreachable=yes],
303[pgac_cv__builtin_unreachable=no])])
304if test x"$pgac_cv__builtin_unreachable" = xyes ; then
305AC_DEFINE(HAVE__BUILTIN_UNREACHABLE, 1,
306          [Define to 1 if your compiler understands __builtin_unreachable.])
307fi])# PGAC_C_BUILTIN_UNREACHABLE
308
309
310
311# PGAC_C_VA_ARGS
312# --------------
313# Check if the C compiler understands C99-style variadic macros,
314# and define HAVE__VA_ARGS if so.
315AC_DEFUN([PGAC_C_VA_ARGS],
316[AC_CACHE_CHECK(for __VA_ARGS__, pgac_cv__va_args,
317[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include <stdio.h>],
318[#define debug(...) fprintf(stderr, __VA_ARGS__)
319debug("%s", "blarg");
320])],
321[pgac_cv__va_args=yes],
322[pgac_cv__va_args=no])])
323if test x"$pgac_cv__va_args" = xyes ; then
324AC_DEFINE(HAVE__VA_ARGS, 1,
325          [Define to 1 if your compiler understands __VA_ARGS__ in macros.])
326fi])# PGAC_C_VA_ARGS
327
328
329
330# PGAC_PROG_CC_CFLAGS_OPT
331# -----------------------
332# Given a string, check if the compiler supports the string as a
333# command-line option. If it does, add the string to CFLAGS.
334AC_DEFUN([PGAC_PROG_CC_CFLAGS_OPT],
335[define([Ac_cachevar], [AS_TR_SH([pgac_cv_prog_cc_cflags_$1])])dnl
336AC_CACHE_CHECK([whether $CC supports $1], [Ac_cachevar],
337[pgac_save_CFLAGS=$CFLAGS
338CFLAGS="$pgac_save_CFLAGS $1"
339ac_save_c_werror_flag=$ac_c_werror_flag
340ac_c_werror_flag=yes
341_AC_COMPILE_IFELSE([AC_LANG_PROGRAM()],
342                   [Ac_cachevar=yes],
343                   [Ac_cachevar=no])
344ac_c_werror_flag=$ac_save_c_werror_flag
345CFLAGS="$pgac_save_CFLAGS"])
346if test x"$Ac_cachevar" = x"yes"; then
347  CFLAGS="$CFLAGS $1"
348fi
349undefine([Ac_cachevar])dnl
350])# PGAC_PROG_CC_CFLAGS_OPT
351
352
353
354# PGAC_PROG_CC_VAR_OPT
355# -----------------------
356# Given a variable name and a string, check if the compiler supports
357# the string as a command-line option. If it does, add the string to
358# the given variable.
359AC_DEFUN([PGAC_PROG_CC_VAR_OPT],
360[define([Ac_cachevar], [AS_TR_SH([pgac_cv_prog_cc_cflags_$2])])dnl
361AC_CACHE_CHECK([whether $CC supports $2], [Ac_cachevar],
362[pgac_save_CFLAGS=$CFLAGS
363CFLAGS="$pgac_save_CFLAGS $2"
364ac_save_c_werror_flag=$ac_c_werror_flag
365ac_c_werror_flag=yes
366_AC_COMPILE_IFELSE([AC_LANG_PROGRAM()],
367                   [Ac_cachevar=yes],
368                   [Ac_cachevar=no])
369ac_c_werror_flag=$ac_save_c_werror_flag
370CFLAGS="$pgac_save_CFLAGS"])
371if test x"$Ac_cachevar" = x"yes"; then
372  $1="${$1} $2"
373fi
374undefine([Ac_cachevar])dnl
375])# PGAC_PROG_CC_VAR_OPT
376
377
378
379# PGAC_PROG_CC_LDFLAGS_OPT
380# ------------------------
381# Given a string, check if the compiler supports the string as a
382# command-line option. If it does, add the string to LDFLAGS.
383# For reasons you'd really rather not know about, this checks whether
384# you can link to a particular function, not just whether you can link.
385# In fact, we must actually check that the resulting program runs :-(
386AC_DEFUN([PGAC_PROG_CC_LDFLAGS_OPT],
387[define([Ac_cachevar], [AS_TR_SH([pgac_cv_prog_cc_ldflags_$1])])dnl
388AC_CACHE_CHECK([whether $CC supports $1], [Ac_cachevar],
389[pgac_save_LDFLAGS=$LDFLAGS
390LDFLAGS="$pgac_save_LDFLAGS $1"
391AC_RUN_IFELSE([AC_LANG_PROGRAM([extern void $2 (); void (*fptr) () = $2;],[])],
392              [Ac_cachevar=yes],
393              [Ac_cachevar=no],
394              [Ac_cachevar="assuming no"])
395LDFLAGS="$pgac_save_LDFLAGS"])
396if test x"$Ac_cachevar" = x"yes"; then
397  LDFLAGS="$LDFLAGS $1"
398fi
399undefine([Ac_cachevar])dnl
400])# PGAC_PROG_CC_LDFLAGS_OPT
401
402# PGAC_HAVE_GCC__SYNC_CHAR_TAS
403# -------------------------
404# Check if the C compiler understands __sync_lock_test_and_set(char),
405# and define HAVE_GCC__SYNC_CHAR_TAS
406#
407# NB: There are platforms where test_and_set is available but compare_and_swap
408# is not, so test this separately.
409# NB: Some platforms only do 32bit tas, others only do 8bit tas. Test both.
410AC_DEFUN([PGAC_HAVE_GCC__SYNC_CHAR_TAS],
411[AC_CACHE_CHECK(for builtin __sync char locking functions, pgac_cv_gcc_sync_char_tas,
412[AC_LINK_IFELSE([AC_LANG_PROGRAM([],
413  [char lock = 0;
414   __sync_lock_test_and_set(&lock, 1);
415   __sync_lock_release(&lock);])],
416  [pgac_cv_gcc_sync_char_tas="yes"],
417  [pgac_cv_gcc_sync_char_tas="no"])])
418if test x"$pgac_cv_gcc_sync_char_tas" = x"yes"; then
419  AC_DEFINE(HAVE_GCC__SYNC_CHAR_TAS, 1, [Define to 1 if you have __sync_lock_test_and_set(char *) and friends.])
420fi])# PGAC_HAVE_GCC__SYNC_CHAR_TAS
421
422# PGAC_HAVE_GCC__SYNC_INT32_TAS
423# -------------------------
424# Check if the C compiler understands __sync_lock_test_and_set(),
425# and define HAVE_GCC__SYNC_INT32_TAS
426AC_DEFUN([PGAC_HAVE_GCC__SYNC_INT32_TAS],
427[AC_CACHE_CHECK(for builtin __sync int32 locking functions, pgac_cv_gcc_sync_int32_tas,
428[AC_LINK_IFELSE([AC_LANG_PROGRAM([],
429  [int lock = 0;
430   __sync_lock_test_and_set(&lock, 1);
431   __sync_lock_release(&lock);])],
432  [pgac_cv_gcc_sync_int32_tas="yes"],
433  [pgac_cv_gcc_sync_int32_tas="no"])])
434if test x"$pgac_cv_gcc_sync_int32_tas" = x"yes"; then
435  AC_DEFINE(HAVE_GCC__SYNC_INT32_TAS, 1, [Define to 1 if you have __sync_lock_test_and_set(int *) and friends.])
436fi])# PGAC_HAVE_GCC__SYNC_INT32_TAS
437
438# PGAC_HAVE_GCC__SYNC_INT32_CAS
439# -------------------------
440# Check if the C compiler understands __sync_compare_and_swap() for 32bit
441# types, and define HAVE_GCC__SYNC_INT32_CAS if so.
442AC_DEFUN([PGAC_HAVE_GCC__SYNC_INT32_CAS],
443[AC_CACHE_CHECK(for builtin __sync int32 atomic operations, pgac_cv_gcc_sync_int32_cas,
444[AC_LINK_IFELSE([AC_LANG_PROGRAM([],
445  [int val = 0;
446   __sync_val_compare_and_swap(&val, 0, 37);])],
447  [pgac_cv_gcc_sync_int32_cas="yes"],
448  [pgac_cv_gcc_sync_int32_cas="no"])])
449if test x"$pgac_cv_gcc_sync_int32_cas" = x"yes"; then
450  AC_DEFINE(HAVE_GCC__SYNC_INT32_CAS, 1, [Define to 1 if you have __sync_val_compare_and_swap(int *, int, int).])
451fi])# PGAC_HAVE_GCC__SYNC_INT32_CAS
452
453# PGAC_HAVE_GCC__SYNC_INT64_CAS
454# -------------------------
455# Check if the C compiler understands __sync_compare_and_swap() for 64bit
456# types, and define HAVE_GCC__SYNC_INT64_CAS if so.
457AC_DEFUN([PGAC_HAVE_GCC__SYNC_INT64_CAS],
458[AC_CACHE_CHECK(for builtin __sync int64 atomic operations, pgac_cv_gcc_sync_int64_cas,
459[AC_LINK_IFELSE([AC_LANG_PROGRAM([],
460  [PG_INT64_TYPE lock = 0;
461   __sync_val_compare_and_swap(&lock, 0, (PG_INT64_TYPE) 37);])],
462  [pgac_cv_gcc_sync_int64_cas="yes"],
463  [pgac_cv_gcc_sync_int64_cas="no"])])
464if test x"$pgac_cv_gcc_sync_int64_cas" = x"yes"; then
465  AC_DEFINE(HAVE_GCC__SYNC_INT64_CAS, 1, [Define to 1 if you have __sync_val_compare_and_swap(int64 *, int64, int64).])
466fi])# PGAC_HAVE_GCC__SYNC_INT64_CAS
467
468# PGAC_HAVE_GCC__ATOMIC_INT32_CAS
469# -------------------------
470# Check if the C compiler understands __atomic_compare_exchange_n() for 32bit
471# types, and define HAVE_GCC__ATOMIC_INT32_CAS if so.
472AC_DEFUN([PGAC_HAVE_GCC__ATOMIC_INT32_CAS],
473[AC_CACHE_CHECK(for builtin __atomic int32 atomic operations, pgac_cv_gcc_atomic_int32_cas,
474[AC_LINK_IFELSE([AC_LANG_PROGRAM([],
475  [int val = 0;
476   int expect = 0;
477   __atomic_compare_exchange_n(&val, &expect, 37, 0, __ATOMIC_SEQ_CST, __ATOMIC_RELAXED);])],
478  [pgac_cv_gcc_atomic_int32_cas="yes"],
479  [pgac_cv_gcc_atomic_int32_cas="no"])])
480if test x"$pgac_cv_gcc_atomic_int32_cas" = x"yes"; then
481  AC_DEFINE(HAVE_GCC__ATOMIC_INT32_CAS, 1, [Define to 1 if you have __atomic_compare_exchange_n(int *, int *, int).])
482fi])# PGAC_HAVE_GCC__ATOMIC_INT32_CAS
483
484# PGAC_HAVE_GCC__ATOMIC_INT64_CAS
485# -------------------------
486# Check if the C compiler understands __atomic_compare_exchange_n() for 64bit
487# types, and define HAVE_GCC__ATOMIC_INT64_CAS if so.
488AC_DEFUN([PGAC_HAVE_GCC__ATOMIC_INT64_CAS],
489[AC_CACHE_CHECK(for builtin __atomic int64 atomic operations, pgac_cv_gcc_atomic_int64_cas,
490[AC_LINK_IFELSE([AC_LANG_PROGRAM([],
491  [PG_INT64_TYPE val = 0;
492   PG_INT64_TYPE expect = 0;
493   __atomic_compare_exchange_n(&val, &expect, 37, 0, __ATOMIC_SEQ_CST, __ATOMIC_RELAXED);])],
494  [pgac_cv_gcc_atomic_int64_cas="yes"],
495  [pgac_cv_gcc_atomic_int64_cas="no"])])
496if test x"$pgac_cv_gcc_atomic_int64_cas" = x"yes"; then
497  AC_DEFINE(HAVE_GCC__ATOMIC_INT64_CAS, 1, [Define to 1 if you have __atomic_compare_exchange_n(int64 *, int64 *, int64).])
498fi])# PGAC_HAVE_GCC__ATOMIC_INT64_CAS
499
500# PGAC_SSE42_CRC32_INTRINSICS
501# -----------------------
502# Check if the compiler supports the x86 CRC instructions added in SSE 4.2,
503# using the _mm_crc32_u8 and _mm_crc32_u32 intrinsic functions. (We don't
504# test the 8-byte variant, _mm_crc32_u64, but it is assumed to be present if
505# the other ones are, on x86-64 platforms)
506#
507# An optional compiler flag can be passed as argument (e.g. -msse4.2). If the
508# intrinsics are supported, sets pgac_sse42_crc32_intrinsics, and CFLAGS_SSE42.
509AC_DEFUN([PGAC_SSE42_CRC32_INTRINSICS],
510[define([Ac_cachevar], [AS_TR_SH([pgac_cv_sse42_crc32_intrinsics_$1])])dnl
511AC_CACHE_CHECK([for _mm_crc32_u8 and _mm_crc32_u32 with CFLAGS=$1], [Ac_cachevar],
512[pgac_save_CFLAGS=$CFLAGS
513CFLAGS="$pgac_save_CFLAGS $1"
514AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <nmmintrin.h>],
515  [unsigned int crc = 0;
516   crc = _mm_crc32_u8(crc, 0);
517   crc = _mm_crc32_u32(crc, 0);
518   /* return computed value, to prevent the above being optimized away */
519   return crc == 0;])],
520  [Ac_cachevar=yes],
521  [Ac_cachevar=no])
522CFLAGS="$pgac_save_CFLAGS"])
523if test x"$Ac_cachevar" = x"yes"; then
524  CFLAGS_SSE42="$1"
525  pgac_sse42_crc32_intrinsics=yes
526fi
527undefine([Ac_cachevar])dnl
528])# PGAC_SSE42_CRC32_INTRINSICS
529