From 96fdf1efbd1b048f4df468c07c5e5134a061265c Mon Sep 17 00:00:00 2001 From: Paul Khuong Date: Thu, 17 Apr 2014 16:25:10 -0400 Subject: [PATCH] ck_cc: new bitwise ops GCC and compatible compilers support ffs/ctz/clz/popcount. Expose that in ck_cc and default to slow but portable software emulation. --- include/ck_cc.h | 68 ++++++++++++++++++++++++++++++++++++++++++++- include/gcc/ck_cc.h | 39 +++++++++++++++++++++++++- 2 files changed, 105 insertions(+), 2 deletions(-) diff --git a/include/ck_cc.h b/include/ck_cc.h index c85176d..a4baaa5 100644 --- a/include/ck_cc.h +++ b/include/ck_cc.h @@ -1,5 +1,6 @@ /* * Copyright 2009-2014 Samy Al Bahra. + * Copyright 2014 Paul Khuong. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -85,5 +86,70 @@ #define CK_CC_UNLIKELY(x) x #endif -#endif /* _CK_CC_H */ +#ifndef CK_F_CC_FFS +#define CK_F_CC_FFS +CK_CC_INLINE static int +ck_cc_ffs(unsigned int x) +{ + unsigned int i; + + if (x == 0) + return 0; + + for (i = 1; (x & 1) == 0; i++, x >>= 1); + + return i; +} +#endif + +#ifndef CK_F_CC_CLZ +#define CK_F_CC_CLZ +#include + +CK_CC_INLINE static int +ck_cc_clz(unsigned int x) +{ + unsigned int count, i; + + for (count = 0, i = sizeof(unsigned int) * CHAR_BIT; i > 0; count++) { + unsigned int bit = 1U << --i; + + if (x & bit) + break; + } + + return count; +} +#endif + +#ifndef CK_F_CC_CTZ +#define CK_F_CC_CTZ +CK_CC_INLINE static int +ck_cc_ctz(unsigned int x) +{ + unsigned int i; + + if (x == 0) + return 0; + + for (i = 0; (x & 1) == 0; i++, x >>= 1); + + return i; +} +#endif +#ifndef CK_F_CC_POPCOUNT +#define CK_F_CC_POPCOUNT +CK_CC_INLINE static int +ck_cc_popcount(unsigned int x) +{ + unsigned int acc; + + for (acc = 0; x != 0; x >>= 1) + acc += x & 1; + + return acc; +} +#endif + +#endif /* _CK_CC_H */ diff --git a/include/gcc/ck_cc.h b/include/gcc/ck_cc.h index 7a98c94..084e7bf 100644 --- a/include/gcc/ck_cc.h +++ b/include/gcc/ck_cc.h @@ -1,5 +1,6 @@ /* * Copyright 2009-2014 Samy Al Bahra. + * Copyright 2014 Paul Khuong. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -96,5 +97,41 @@ */ #define CK_CC_ALIASED __attribute__((__may_alias__)) -#endif /* _CK_GCC_CC_H */ +/* + * Portability wrappers for bitwise ops. + */ + +#define CK_F_CC_FFS +#define CK_F_CC_CLZ +#define CK_F_CC_CTZ +#define CK_F_CC_POPCOUNT + +CK_CC_INLINE static int +ck_cc_ffs(unsigned int x) +{ + + return __builtin_ffs(x); +} + +CK_CC_INLINE static int +ck_cc_clz(unsigned int x) +{ + return __builtin_clz(x); +} + +CK_CC_INLINE static int +ck_cc_ctz(unsigned int x) +{ + + return __builtin_ctz(x); +} + +CK_CC_INLINE static int +ck_cc_popcount(unsigned int x) +{ + + return __builtin_popcount(x); +} + +#endif /* _CK_GCC_CC_H */