From f4f09dd7cdb8a90690f81d1b4c1305532bcefb02 Mon Sep 17 00:00:00 2001 From: Jakob Olesen Date: Wed, 8 May 2019 15:46:07 -0700 Subject: [PATCH] toolchain: Define a HAS_BUILTIN(x) macro in toolchain.h. Compilers based on Clang provide a __has_builtin(x) macro which can be used to detect in the preprocessor if a given builtin function is supported by the compiler. For other compilers (notably GCC), we provide an alternative definition of HAS_BUILTIN(x) that depends on the toolchain-specific header file to declare which builtin functions are supported based on the current compiler version. Signed-off-by: Jakob Olesen --- include/toolchain.h | 18 ++++++++++++++++++ include/toolchain/gcc.h | 16 ++++++++++++++++ 2 files changed, 34 insertions(+) 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 */