]> granicus.if.org Git - postgresql/blob - config/c-compiler.m4
Extend configure's __int128 test to check for a known gcc bug.
[postgresql] / config / c-compiler.m4
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.
8 AC_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])])
14 if test x"$pgac_cv_c_signed" = xno ; then
15   AC_DEFINE(signed,, [Define to empty if the C compiler does not understand signed types.])
16 fi])# 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.
26 AC_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
29 ac_c_werror_flag=yes
30 AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
31 [extern int
32 pgac_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])
36 ac_c_werror_flag=$ac_save_c_werror_flag])
37 AC_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.
46 AC_DEFUN([PGAC_TYPE_64BIT_INT],
47 [define([Ac_define], [translit([have_$1_64], [a-z *], [A-Z_P])])dnl
48 define([Ac_cachevar], [translit([pgac_cv_type_$1_64], [ *], [_p])])dnl
49 AC_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  */
57 ac_int64 a = 20000001;
58 ac_int64 b = 40000005;
59
60 int 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
75 int
76 main() {
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.
83 AC_COMPILE_IFELSE([AC_LANG_BOOL_COMPILE_TRY([], [sizeof($1) == 8])],
84                   Ac_cachevar=yes,
85                   Ac_cachevar=no)])])
86
87 Ac_define=$Ac_cachevar
88 if test x"$Ac_cachevar" = xyes ; then
89   AC_DEFINE(Ac_define, 1, [Define to 1 if `]$1[' works and is 64 bits.])
90 fi
91 undefine([Ac_define])dnl
92 undefine([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.
107 AC_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;
122 a = (a << 12) + 1; /* 200000000001 */
123 b = (b << 12) + 5; /* 400000000005 */
124 /* try the most relevant arithmetic ops */
125 c = a * b;
126 d = (c + b) / b;
127 /* must use the results, else compiler may optimize arithmetic away */
128 if (d != a+1)
129   return 1;
130 ])],
131 [pgac_cv__128bit_int=yes],
132 [pgac_cv__128bit_int=no])])
133 if 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
144 typedef __int128 int128a
145 #if defined(pg_attribute_aligned)
146 pg_attribute_aligned(8)
147 #endif
148 ;
149 int128a holder;
150 void pass_by_val(void *buffer, int128a par) { holder = par; }
151 ],[
152 long int i64 = 97656225L << 12;
153 int128a q;
154 pass_by_val(main, (int128a) i64);
155 q = (int128a) i64;
156 if (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
166 fi])# 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.
173 AC_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])])
179 if test x"$pgac_cv_funcname_func_support" = xyes ; then
180 AC_DEFINE(HAVE_FUNCNAME__FUNC, 1,
181           [Define to 1 if your compiler understands __func__.])
182 else
183 AC_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])])
188 if test x"$pgac_cv_funcname_function_support" = xyes ; then
189 AC_DEFINE(HAVE_FUNCNAME__FUNCTION, 1,
190           [Define to 1 if your compiler understands __FUNCTION__.])
191 fi
192 fi])# 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.
203 AC_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])])
209 if test x"$pgac_cv__static_assert" = xyes ; then
210 AC_DEFINE(HAVE__STATIC_ASSERT, 1,
211           [Define to 1 if your compiler understands _Static_assert.])
212 fi])# 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 #
221 AC_DEFUN([PGAC_C_TYPEOF],
222 [AC_CACHE_CHECK(for typeof, pgac_cv_c_typeof,
223 [pgac_cv_c_typeof=no
224 for pgac_kw in typeof __typeof__ decltype; do
225   AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],
226 [int x = 0;
227 $pgac_kw(x) y;
228 y = x;
229 return y;])],
230 [pgac_cv_c_typeof=$pgac_kw])
231   test "$pgac_cv_c_typeof" != no && break
232 done])
233 if 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
239 fi])# 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.
250 AC_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])])
256 if test x"$pgac_cv__types_compatible" = xyes ; then
257 AC_DEFINE(HAVE__BUILTIN_TYPES_COMPATIBLE_P, 1,
258           [Define to 1 if your compiler understands __builtin_types_compatible_p.])
259 fi])# 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.
266 AC_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])])
273 if test x"$pgac_cv__builtin_bswap16" = xyes ; then
274 AC_DEFINE(HAVE__BUILTIN_BSWAP16, 1,
275           [Define to 1 if your compiler understands __builtin_bswap16.])
276 fi])# 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.
284 AC_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])])
291 if test x"$pgac_cv__builtin_bswap32" = xyes ; then
292 AC_DEFINE(HAVE__BUILTIN_BSWAP32, 1,
293           [Define to 1 if your compiler understands __builtin_bswap32.])
294 fi])# 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.
302 AC_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])])
309 if test x"$pgac_cv__builtin_bswap64" = xyes ; then
310 AC_DEFINE(HAVE__BUILTIN_BSWAP64, 1,
311           [Define to 1 if your compiler understands __builtin_bswap64.])
312 fi])# 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.
322 AC_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])])
332 if test x"$pgac_cv__builtin_constant_p" = xyes ; then
333 AC_DEFINE(HAVE__BUILTIN_CONSTANT_P, 1,
334           [Define to 1 if your compiler understands __builtin_constant_p.])
335 fi])# 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.
349 AC_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([
352 PG_INT64_TYPE a = 1;
353 PG_INT64_TYPE b = 1;
354 PG_INT64_TYPE result;
355 int oflo;
356 ],
357 [oflo = __builtin_mul_overflow(a, b, &result);])],
358 [pgac_cv__builtin_op_overflow=yes],
359 [pgac_cv__builtin_op_overflow=no])])
360 if test x"$pgac_cv__builtin_op_overflow" = xyes ; then
361 AC_DEFINE(HAVE__BUILTIN_OP_OVERFLOW, 1,
362           [Define to 1 if your compiler understands __builtin_$op_overflow.])
363 fi])# 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.
375 AC_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])])
381 if test x"$pgac_cv__builtin_unreachable" = xyes ; then
382 AC_DEFINE(HAVE__BUILTIN_UNREACHABLE, 1,
383           [Define to 1 if your compiler understands __builtin_unreachable.])
384 fi])# 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.
395 AC_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])])
405 if test x"$pgac_cv_computed_goto" = xyes ; then
406 AC_DEFINE(HAVE_COMPUTED_GOTO, 1,
407           [Define to 1 if your compiler handles computed gotos.])
408 fi])# 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.
416 AC_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__)
420 debug("%s", "blarg");
421 ])],
422 [pgac_cv__va_args=yes],
423 [pgac_cv__va_args=no])])
424 if test x"$pgac_cv__va_args" = xyes ; then
425 AC_DEFINE(HAVE__VA_ARGS, 1,
426           [Define to 1 if your compiler understands __VA_ARGS__ in macros.])
427 fi])# PGAC_C_VA_ARGS
428
429
430
431 # PGAC_PROG_CC_CFLAGS_OPT
432 # -----------------------
433 # Given a string, check if the compiler supports the string as a
434 # command-line option. If it does, add the string to CFLAGS.
435 AC_DEFUN([PGAC_PROG_CC_CFLAGS_OPT],
436 [define([Ac_cachevar], [AS_TR_SH([pgac_cv_prog_cc_cflags_$1])])dnl
437 AC_CACHE_CHECK([whether $CC supports $1], [Ac_cachevar],
438 [pgac_save_CFLAGS=$CFLAGS
439 CFLAGS="$pgac_save_CFLAGS $1"
440 ac_save_c_werror_flag=$ac_c_werror_flag
441 ac_c_werror_flag=yes
442 _AC_COMPILE_IFELSE([AC_LANG_PROGRAM()],
443                    [Ac_cachevar=yes],
444                    [Ac_cachevar=no])
445 ac_c_werror_flag=$ac_save_c_werror_flag
446 CFLAGS="$pgac_save_CFLAGS"])
447 if test x"$Ac_cachevar" = x"yes"; then
448   CFLAGS="$CFLAGS $1"
449 fi
450 undefine([Ac_cachevar])dnl
451 ])# PGAC_PROG_CC_CFLAGS_OPT
452
453
454
455 # PGAC_PROG_CC_VAR_OPT
456 # -----------------------
457 # Given a variable name and a string, check if the compiler supports
458 # the string as a command-line option. If it does, add the string to
459 # the given variable.
460 AC_DEFUN([PGAC_PROG_CC_VAR_OPT],
461 [define([Ac_cachevar], [AS_TR_SH([pgac_cv_prog_cc_cflags_$2])])dnl
462 AC_CACHE_CHECK([whether $CC supports $2], [Ac_cachevar],
463 [pgac_save_CFLAGS=$CFLAGS
464 CFLAGS="$pgac_save_CFLAGS $2"
465 ac_save_c_werror_flag=$ac_c_werror_flag
466 ac_c_werror_flag=yes
467 _AC_COMPILE_IFELSE([AC_LANG_PROGRAM()],
468                    [Ac_cachevar=yes],
469                    [Ac_cachevar=no])
470 ac_c_werror_flag=$ac_save_c_werror_flag
471 CFLAGS="$pgac_save_CFLAGS"])
472 if test x"$Ac_cachevar" = x"yes"; then
473   $1="${$1} $2"
474 fi
475 undefine([Ac_cachevar])dnl
476 ])# PGAC_PROG_CC_VAR_OPT
477
478
479
480 # PGAC_PROG_CC_LDFLAGS_OPT
481 # ------------------------
482 # Given a string, check if the compiler supports the string as a
483 # command-line option. If it does, add the string to LDFLAGS.
484 # For reasons you'd really rather not know about, this checks whether
485 # you can link to a particular function, not just whether you can link.
486 # In fact, we must actually check that the resulting program runs :-(
487 AC_DEFUN([PGAC_PROG_CC_LDFLAGS_OPT],
488 [define([Ac_cachevar], [AS_TR_SH([pgac_cv_prog_cc_ldflags_$1])])dnl
489 AC_CACHE_CHECK([whether $CC supports $1], [Ac_cachevar],
490 [pgac_save_LDFLAGS=$LDFLAGS
491 LDFLAGS="$pgac_save_LDFLAGS $1"
492 AC_RUN_IFELSE([AC_LANG_PROGRAM([extern void $2 (); void (*fptr) () = $2;],[])],
493               [Ac_cachevar=yes],
494               [Ac_cachevar=no],
495               [Ac_cachevar="assuming no"])
496 LDFLAGS="$pgac_save_LDFLAGS"])
497 if test x"$Ac_cachevar" = x"yes"; then
498   LDFLAGS="$LDFLAGS $1"
499 fi
500 undefine([Ac_cachevar])dnl
501 ])# PGAC_PROG_CC_LDFLAGS_OPT
502
503 # PGAC_HAVE_GCC__SYNC_CHAR_TAS
504 # -------------------------
505 # Check if the C compiler understands __sync_lock_test_and_set(char),
506 # and define HAVE_GCC__SYNC_CHAR_TAS
507 #
508 # NB: There are platforms where test_and_set is available but compare_and_swap
509 # is not, so test this separately.
510 # NB: Some platforms only do 32bit tas, others only do 8bit tas. Test both.
511 AC_DEFUN([PGAC_HAVE_GCC__SYNC_CHAR_TAS],
512 [AC_CACHE_CHECK(for builtin __sync char locking functions, pgac_cv_gcc_sync_char_tas,
513 [AC_LINK_IFELSE([AC_LANG_PROGRAM([],
514   [char lock = 0;
515    __sync_lock_test_and_set(&lock, 1);
516    __sync_lock_release(&lock);])],
517   [pgac_cv_gcc_sync_char_tas="yes"],
518   [pgac_cv_gcc_sync_char_tas="no"])])
519 if test x"$pgac_cv_gcc_sync_char_tas" = x"yes"; then
520   AC_DEFINE(HAVE_GCC__SYNC_CHAR_TAS, 1, [Define to 1 if you have __sync_lock_test_and_set(char *) and friends.])
521 fi])# PGAC_HAVE_GCC__SYNC_CHAR_TAS
522
523 # PGAC_HAVE_GCC__SYNC_INT32_TAS
524 # -------------------------
525 # Check if the C compiler understands __sync_lock_test_and_set(),
526 # and define HAVE_GCC__SYNC_INT32_TAS
527 AC_DEFUN([PGAC_HAVE_GCC__SYNC_INT32_TAS],
528 [AC_CACHE_CHECK(for builtin __sync int32 locking functions, pgac_cv_gcc_sync_int32_tas,
529 [AC_LINK_IFELSE([AC_LANG_PROGRAM([],
530   [int lock = 0;
531    __sync_lock_test_and_set(&lock, 1);
532    __sync_lock_release(&lock);])],
533   [pgac_cv_gcc_sync_int32_tas="yes"],
534   [pgac_cv_gcc_sync_int32_tas="no"])])
535 if test x"$pgac_cv_gcc_sync_int32_tas" = x"yes"; then
536   AC_DEFINE(HAVE_GCC__SYNC_INT32_TAS, 1, [Define to 1 if you have __sync_lock_test_and_set(int *) and friends.])
537 fi])# PGAC_HAVE_GCC__SYNC_INT32_TAS
538
539 # PGAC_HAVE_GCC__SYNC_INT32_CAS
540 # -------------------------
541 # Check if the C compiler understands __sync_compare_and_swap() for 32bit
542 # types, and define HAVE_GCC__SYNC_INT32_CAS if so.
543 AC_DEFUN([PGAC_HAVE_GCC__SYNC_INT32_CAS],
544 [AC_CACHE_CHECK(for builtin __sync int32 atomic operations, pgac_cv_gcc_sync_int32_cas,
545 [AC_LINK_IFELSE([AC_LANG_PROGRAM([],
546   [int val = 0;
547    __sync_val_compare_and_swap(&val, 0, 37);])],
548   [pgac_cv_gcc_sync_int32_cas="yes"],
549   [pgac_cv_gcc_sync_int32_cas="no"])])
550 if test x"$pgac_cv_gcc_sync_int32_cas" = x"yes"; then
551   AC_DEFINE(HAVE_GCC__SYNC_INT32_CAS, 1, [Define to 1 if you have __sync_compare_and_swap(int *, int, int).])
552 fi])# PGAC_HAVE_GCC__SYNC_INT32_CAS
553
554 # PGAC_HAVE_GCC__SYNC_INT64_CAS
555 # -------------------------
556 # Check if the C compiler understands __sync_compare_and_swap() for 64bit
557 # types, and define HAVE_GCC__SYNC_INT64_CAS if so.
558 AC_DEFUN([PGAC_HAVE_GCC__SYNC_INT64_CAS],
559 [AC_CACHE_CHECK(for builtin __sync int64 atomic operations, pgac_cv_gcc_sync_int64_cas,
560 [AC_LINK_IFELSE([AC_LANG_PROGRAM([],
561   [PG_INT64_TYPE lock = 0;
562    __sync_val_compare_and_swap(&lock, 0, (PG_INT64_TYPE) 37);])],
563   [pgac_cv_gcc_sync_int64_cas="yes"],
564   [pgac_cv_gcc_sync_int64_cas="no"])])
565 if test x"$pgac_cv_gcc_sync_int64_cas" = x"yes"; then
566   AC_DEFINE(HAVE_GCC__SYNC_INT64_CAS, 1, [Define to 1 if you have __sync_compare_and_swap(int64 *, int64, int64).])
567 fi])# PGAC_HAVE_GCC__SYNC_INT64_CAS
568
569 # PGAC_HAVE_GCC__ATOMIC_INT32_CAS
570 # -------------------------
571 # Check if the C compiler understands __atomic_compare_exchange_n() for 32bit
572 # types, and define HAVE_GCC__ATOMIC_INT32_CAS if so.
573 AC_DEFUN([PGAC_HAVE_GCC__ATOMIC_INT32_CAS],
574 [AC_CACHE_CHECK(for builtin __atomic int32 atomic operations, pgac_cv_gcc_atomic_int32_cas,
575 [AC_LINK_IFELSE([AC_LANG_PROGRAM([],
576   [int val = 0;
577    int expect = 0;
578    __atomic_compare_exchange_n(&val, &expect, 37, 0, __ATOMIC_SEQ_CST, __ATOMIC_RELAXED);])],
579   [pgac_cv_gcc_atomic_int32_cas="yes"],
580   [pgac_cv_gcc_atomic_int32_cas="no"])])
581 if test x"$pgac_cv_gcc_atomic_int32_cas" = x"yes"; then
582   AC_DEFINE(HAVE_GCC__ATOMIC_INT32_CAS, 1, [Define to 1 if you have __atomic_compare_exchange_n(int *, int *, int).])
583 fi])# PGAC_HAVE_GCC__ATOMIC_INT32_CAS
584
585 # PGAC_HAVE_GCC__ATOMIC_INT64_CAS
586 # -------------------------
587 # Check if the C compiler understands __atomic_compare_exchange_n() for 64bit
588 # types, and define HAVE_GCC__ATOMIC_INT64_CAS if so.
589 AC_DEFUN([PGAC_HAVE_GCC__ATOMIC_INT64_CAS],
590 [AC_CACHE_CHECK(for builtin __atomic int64 atomic operations, pgac_cv_gcc_atomic_int64_cas,
591 [AC_LINK_IFELSE([AC_LANG_PROGRAM([],
592   [PG_INT64_TYPE val = 0;
593    PG_INT64_TYPE expect = 0;
594    __atomic_compare_exchange_n(&val, &expect, 37, 0, __ATOMIC_SEQ_CST, __ATOMIC_RELAXED);])],
595   [pgac_cv_gcc_atomic_int64_cas="yes"],
596   [pgac_cv_gcc_atomic_int64_cas="no"])])
597 if test x"$pgac_cv_gcc_atomic_int64_cas" = x"yes"; then
598   AC_DEFINE(HAVE_GCC__ATOMIC_INT64_CAS, 1, [Define to 1 if you have __atomic_compare_exchange_n(int64 *, int *, int64).])
599 fi])# PGAC_HAVE_GCC__ATOMIC_INT64_CAS
600
601 # PGAC_SSE42_CRC32_INTRINSICS
602 # -----------------------
603 # Check if the compiler supports the x86 CRC instructions added in SSE 4.2,
604 # using the _mm_crc32_u8 and _mm_crc32_u32 intrinsic functions. (We don't
605 # test the 8-byte variant, _mm_crc32_u64, but it is assumed to be present if
606 # the other ones are, on x86-64 platforms)
607 #
608 # An optional compiler flag can be passed as argument (e.g. -msse4.2). If the
609 # intrinsics are supported, sets pgac_sse42_crc32_intrinsics, and CFLAGS_SSE42.
610 AC_DEFUN([PGAC_SSE42_CRC32_INTRINSICS],
611 [define([Ac_cachevar], [AS_TR_SH([pgac_cv_sse42_crc32_intrinsics_$1])])dnl
612 AC_CACHE_CHECK([for _mm_crc32_u8 and _mm_crc32_u32 with CFLAGS=$1], [Ac_cachevar],
613 [pgac_save_CFLAGS=$CFLAGS
614 CFLAGS="$pgac_save_CFLAGS $1"
615 AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <nmmintrin.h>],
616   [unsigned int crc = 0;
617    crc = _mm_crc32_u8(crc, 0);
618    crc = _mm_crc32_u32(crc, 0);
619    /* return computed value, to prevent the above being optimized away */
620    return crc == 0;])],
621   [Ac_cachevar=yes],
622   [Ac_cachevar=no])
623 CFLAGS="$pgac_save_CFLAGS"])
624 if test x"$Ac_cachevar" = x"yes"; then
625   CFLAGS_SSE42="$1"
626   pgac_sse42_crc32_intrinsics=yes
627 fi
628 undefine([Ac_cachevar])dnl
629 ])# PGAC_SSE42_CRC32_INTRINSICS