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