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