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 <psychon@znc.in>
This commit is contained in:
Alexandre "kAworu" Perrin 2010-10-11 21:28:05 +02:00 committed by Uli Schlachter
parent 7c8e096a62
commit cc08f45304
4 changed files with 54 additions and 2 deletions

View File

@ -164,7 +164,6 @@ endmacro()
a_find_library(LIB_EV ev) a_find_library(LIB_EV ev)
# GNU libc has <execinfo.h> and backtrace() stuff. If this is not available, we # GNU libc has <execinfo.h> and backtrace() stuff. If this is not available, we
# need libexecinfo. # need libexecinfo.
message(STATUS "checking for execinfo")
try_compile(HAS_EXECINFO try_compile(HAS_EXECINFO
${CMAKE_BINARY_DIR} ${CMAKE_BINARY_DIR}
${CMAKE_SOURCE_DIR}/build-tests/execinfo.c) ${CMAKE_SOURCE_DIR}/build-tests/execinfo.c)
@ -183,6 +182,16 @@ else()
message(STATUS "checking for execinfo -- not found") message(STATUS "checking for execinfo -- not found")
endif() 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 # Error check
if(NOT LUA51_FOUND AND NOT LUA50_FOUND) # This is a workaround to a cmake bug if(NOT LUA51_FOUND AND NOT LUA50_FOUND) # This is a workaround to a cmake bug
message(FATAL_ERROR "lua library not found") message(FATAL_ERROR "lua library not found")

View File

@ -0,0 +1,12 @@
/*
* build-tests/__builtin_clz.c
*
* test if the compiler has __builtin_clz().
*/
int
main(void)
{
return (__builtin_clz(42));
}

View File

@ -7,5 +7,6 @@
#cmakedefine WITH_DBUS #cmakedefine WITH_DBUS
#cmakedefine HAS_EXECINFO #cmakedefine HAS_EXECINFO
#cmakedefine HAS___BUILTIN_CLZ
#endif //_CONFIG_H_ #endif //_CONFIG_H_

View File

@ -346,7 +346,37 @@ static int8_t const __utf32_clz_to_len[32] = {
2, 2, 2, 2, /* 0x00000080 */ 2, 2, 2, 2, /* 0x00000080 */
1, 1, 1, 1, 1, 1, 1 /* 0x00000001 */ 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 <lorenm@u.washington.edu>
* Laurent Aimar <fenrir@via.ecp.fr>
*
* 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 static bool
keysym_to_utf8(char *buf, const xcb_keysym_t ksym) keysym_to_utf8(char *buf, const xcb_keysym_t ksym)