diff --git a/include/toolchain.h b/include/toolchain.h index 5d0ac3907aa..88cedb0fb3b 100644 --- a/include/toolchain.h +++ b/include/toolchain.h @@ -15,6 +15,24 @@ #ifndef ZEPHYR_INCLUDE_TOOLCHAIN_H_ #define ZEPHYR_INCLUDE_TOOLCHAIN_H_ +/** + * @def HAS_BUILTIN(x) + * @brief Check if the compiler supports the built-in function \a x. + * + * This macro is for use with conditional compilation to enable code using a + * builtin function that may not be available in every compiler. + */ +#ifdef __has_builtin +#define HAS_BUILTIN(x) __has_builtin(x) +#else +/* + * The compiler doesn't provide the __has_builtin() macro, so instead we depend + * on the toolchain-specific headers to define HAS_BUILTIN_x for the builtins + * supported. + */ +#define HAS_BUILTIN(x) HAS_BUILTIN_##x +#endif + #if defined(__XCC__) #include #elif defined(__GNUC__) || (defined(_LINKER) && defined(__GCC_LINKER_CMD__)) diff --git a/include/toolchain/gcc.h b/include/toolchain/gcc.h index 0c455597673..b45e5b2cfd3 100644 --- a/include/toolchain/gcc.h +++ b/include/toolchain/gcc.h @@ -152,6 +152,22 @@ do { \ #endif #define __unused __attribute__((__unused__)) +/* Builtins with availability that depend on the compiler version. */ +#if __GNUC__ >= 5 +#define HAS_BUILTIN___builtin_add_overflow 1 +#define HAS_BUILTIN___builtin_sub_overflow 1 +#define HAS_BUILTIN___builtin_mul_overflow 1 +#define HAS_BUILTIN___builtin_div_overflow 1 +#endif +#if __GNUC__ >= 4 +#define HAS_BUILTIN___builtin_clz 1 +#define HAS_BUILTIN___builtin_clzl 1 +#define HAS_BUILTIN___builtin_clzll 1 +#define HAS_BUILTIN___builtin_ctz 1 +#define HAS_BUILTIN___builtin_ctzl 1 +#define HAS_BUILTIN___builtin_ctzll 1 +#endif + /* Be *very* careful with this, you cannot filter out with -wno-deprecated, * which has implications for -Werror */