From cc08f45304b884e88081214befc613cd8e7a85e8 Mon Sep 17 00:00:00 2001 From: "Alexandre \"kAworu\" Perrin" Date: Mon, 11 Oct 2010 21:28:05 +0200 Subject: [PATCH] test for __builtin_clz() and fallback to an inline implementation. __builtin_clz() is not defined by gcc prior to 3.4 and maybe not for some other compiler vendors. Signed-off-by: Uli Schlachter --- awesomeConfig.cmake | 11 ++++++++++- build-tests/__builtin_clz.c | 12 ++++++++++++ config.h.in | 1 + keyresolv.c | 32 +++++++++++++++++++++++++++++++- 4 files changed, 54 insertions(+), 2 deletions(-) create mode 100644 build-tests/__builtin_clz.c diff --git a/awesomeConfig.cmake b/awesomeConfig.cmake index 0bea2041..bd8dd76e 100644 --- a/awesomeConfig.cmake +++ b/awesomeConfig.cmake @@ -164,7 +164,6 @@ endmacro() a_find_library(LIB_EV ev) # GNU libc has and backtrace() stuff. If this is not available, we # need libexecinfo. -message(STATUS "checking for execinfo") try_compile(HAS_EXECINFO ${CMAKE_BINARY_DIR} ${CMAKE_SOURCE_DIR}/build-tests/execinfo.c) @@ -183,6 +182,16 @@ else() message(STATUS "checking for execinfo -- not found") endif() +# __builtin_clz is available since gcc 3.4 +try_compile(HAS___BUILTIN_CLZ + ${CMAKE_BINARY_DIR} + ${CMAKE_SOURCE_DIR}/build-tests/__builtin_clz.c) +if(HAS___BUILTIN_CLZ) + message(STATUS "checking for __builtin_clz -- yes") +else() + message(STATUS "checking for __builtin_clz -- no") +endif() + # Error check if(NOT LUA51_FOUND AND NOT LUA50_FOUND) # This is a workaround to a cmake bug message(FATAL_ERROR "lua library not found") diff --git a/build-tests/__builtin_clz.c b/build-tests/__builtin_clz.c new file mode 100644 index 00000000..42cd15af --- /dev/null +++ b/build-tests/__builtin_clz.c @@ -0,0 +1,12 @@ +/* + * build-tests/__builtin_clz.c + * + * test if the compiler has __builtin_clz(). + */ + +int +main(void) +{ + + return (__builtin_clz(42)); +} diff --git a/config.h.in b/config.h.in index f7d81fd4..46c2c31a 100644 --- a/config.h.in +++ b/config.h.in @@ -7,5 +7,6 @@ #cmakedefine WITH_DBUS #cmakedefine HAS_EXECINFO +#cmakedefine HAS___BUILTIN_CLZ #endif //_CONFIG_H_ diff --git a/keyresolv.c b/keyresolv.c index b6381390..80b1ebf5 100644 --- a/keyresolv.c +++ b/keyresolv.c @@ -346,7 +346,37 @@ static int8_t const __utf32_clz_to_len[32] = { 2, 2, 2, 2, /* 0x00000080 */ 1, 1, 1, 1, 1, 1, 1 /* 0x00000001 */ }; -#define utf8clen(c) __utf32_clz_to_len[__builtin_clz((uint32_t)(c) | 1)] + +#ifdef HAS___BUILTIN_CLZ +#define a_clz(x) __builtin_clz(x) +#else +/* + * function stolen from x264/common/osdep.h + * + * osdep.h: h264 encoder + * + * Copyright (C) 2007-2008 x264 project + * + * Authors: Loren Merritt + * Laurent Aimar + * + * GPLv2 or higher. + */ +static inline int +a_clz(uint32_t x) +{ + static uint8_t lut[16] = {4,3,2,2,1,1,1,1,0,0,0,0,0,0,0,0}; + int y, z = (((x >> 16) - 1) >> 27) & 16; + x >>= z^16; + z += y = ((x - 0x100) >> 28) & 8; + x >>= y^8; + z += y = ((x - 0x10) >> 29) & 4; + x >>= y^4; + return z + lut[x]; +} +#endif + +#define utf8clen(c) __utf32_clz_to_len[a_clz((uint32_t)(c) | 1)] static bool keysym_to_utf8(char *buf, const xcb_keysym_t ksym)