Skip to content

Commit

Permalink
use __has_builtin to detect available intrinsics (#846)
Browse files Browse the repository at this point in the history
  • Loading branch information
mflatt authored Jun 25, 2024
1 parent 3d1579e commit f1ad314
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 5 deletions.
4 changes: 2 additions & 2 deletions c/atomic.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
# define STORE_FENCE() __asm__ __volatile__ ("dbar 0" : : : "memory")
# define ACQUIRE_FENCE() STORE_FENCE()
# define RELEASE_FENCE() STORE_FENCE()
#elif (__GNUC__ >= 5) || defined(__clang__)
#elif (__GNUC__ >= 5) || C_COMPILER_HAS_BUILTIN(__sync_synchronize)
# define STORE_FENCE() __sync_synchronize()
# define ACQUIRE_FENCE() STORE_FENCE()
# define RELEASE_FENCE() STORE_FENCE()
Expand Down Expand Up @@ -112,7 +112,7 @@ FORCEINLINE int COMPARE_AND_SWAP_PTR(volatile void *addr, void *old_val, void *n
: "cc", "memory", "r12", "r7");
return ret;
}
#elif (__GNUC__ >= 5) || defined(__clang__)
#elif (__GNUC__ >= 5) || C_COMPILER_HAS_BUILTIN(__sync_bool_compare_and_swap)
# define COMPARE_AND_SWAP_PTR(a, old, new) __sync_bool_compare_and_swap((ptr *)(a), TO_PTR(old), TO_PTR(new))
#elif defined(__i386__) || defined(__x86_64__)
# if ptr_bits == 64
Expand Down
19 changes: 16 additions & 3 deletions c/pb.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,12 +71,25 @@ enum {

#define SIGN_FLIP(r, a, b) ((~((a ^ b) | (r ^ ~b))) >> (ptr_bits-1))

#if (__GNUC__ >= 5) || defined(__clang__)
#if C_COMPILER_HAS_BUILTIN(__builtin_add_overflow) \
&& C_COMPILER_HAS_BUILTIN(__builtin_sub_overflow) \
&& C_COMPILER_HAS_BUILTIN(__builtin_mul_overflow)
# define USE_OVERFLOW_INTRINSICS 1
#elif (__GNUC__ >= 5)
# define USE_OVERFLOW_INTRINSICS 1
#else
# define USE_OVERFLOW_INTRINSICS 0
#endif

#if C_COMPILER_HAS_BUILTIN(__builtin_bswap16) \
&& C_COMPILER_HAS_BUILTIN(__builtin_bswap32)
# define USE_BSWAP_INTRINSICS 1
#elif (__GNUC__ >= 5)
# define USE_BSWAP_INTRINSICS 1
#else
# define USE_BSWAP_INTRINSICS 0
#endif

/* Use `machine_state * RESTRICT_PTR`, because machine registers won't
be modified in any way other than through the machine-state pointer */

Expand Down Expand Up @@ -714,7 +727,7 @@ enum {
#if ptr_bits == 64
#define doi_pb_rev_op_pb_int16_pb_register(instr) \
do_pb_rev_op_pb_int16_pb_register(INSTR_dr_dest(instr), INSTR_dr_reg(instr))
# if USE_OVERFLOW_INTRINSICS
# if USE_BSWAP_INTRINSICS
/* See note below on unsigned swap. */
# define do_pb_rev_op_pb_int16_pb_register(dest, reg) \
regs[dest] = ((uptr)(((iptr)((uptr)__builtin_bswap16(regs[reg]) << 48)) >> 48))
Expand All @@ -740,7 +753,7 @@ enum {
#if ptr_bits == 64
# define doi_pb_rev_op_pb_int32_pb_register(instr) \
do_pb_rev_op_pb_int32_pb_register(INSTR_dr_dest(instr), INSTR_dr_reg(instr))
# if USE_OVERFLOW_INTRINSICS
# if USE_BSWAP_INTRINSICS
/* x86_64 GCC before 12.2 incorrectly compiles the code below to an unsigned swap.
Defeat that by using the unsigned-swap intrinsic (which is good, anyway), then
shift up and back. */
Expand Down
8 changes: 8 additions & 0 deletions c/version.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,14 @@
#define FORCEINLINE static inline
#endif

/* GCC 10 and later and all versions of Clang provide `__has_builtin` for
checking for builtins. */
#ifdef __has_builtin
# define C_COMPILER_HAS_BUILTIN(x) __has_builtin(x)
#else
# define C_COMPILER_HAS_BUILTIN(x) 0
#endif

/*****************************************/
/* Architectures */

Expand Down

0 comments on commit f1ad314

Please sign in to comment.