[vlc-commits] include: revector bit ops
Rémi Denis-Courmont
git at videolan.org
Mon Feb 26 17:56:40 CET 2018
vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Mon Feb 26 18:43:40 2018 +0200| [924d56751b3fbf31d55dec678df0541a39bdb4ad] | committer: Rémi Denis-Courmont
include: revector bit ops
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=924d56751b3fbf31d55dec678df0541a39bdb4ad
---
include/vlc_common.h | 244 +++++++++++++++++++++------------------------------
1 file changed, 101 insertions(+), 143 deletions(-)
diff --git a/include/vlc_common.h b/include/vlc_common.h
index e641b4519f..b705887e7e 100644
--- a/include/vlc_common.h
+++ b/include/vlc_common.h
@@ -585,123 +585,97 @@ static inline uint8_t clip_uint8_vlc( int32_t a )
* \defgroup bitops Bit operations
* @{
*/
-#if defined (__GNUC__) || defined (__clang__)
-# ifndef __cplusplus
-# define clz(x) \
- _Generic((x), \
- unsigned char: (__builtin_clz(x) \
- - (sizeof (unsigned) - 1) * 8), \
- unsigned short: (__builtin_clz(x) \
- - (sizeof (unsigned) - sizeof (unsigned short)) * 8), \
- unsigned: __builtin_clz(x), \
- unsigned long: __builtin_clzl(x), \
- unsigned long long: __builtin_clzll(x))
-
-# define ctz(x) \
- _Generic((x), \
- unsigned char: __builtin_ctz(x), \
- unsigned short: __builtin_ctz(x), \
- unsigned: __builtin_ctz(x), \
- unsigned long: __builtin_ctzl(x), \
- unsigned long long: __builtin_ctzll(x))
-
-# define vlc_popcount(x) \
- _Generic((x), \
- unsigned char: __builtin_popcount(x), \
- signed char: __builtin_popcount((unsigned char)(x)), \
- unsigned short: __builtin_popcount(x), \
- signed short: __builtin_popcount((unsigned short)(x)), \
- unsigned int: __builtin_popcount(x), \
- signed int: __builtin_popcount(x), \
- unsigned long: __builtin_popcountl(x), \
- signed long: __builtin_popcountl(x), \
- unsigned long long: __builtin_popcountll(x), \
- signed long long: __builtin_popcountll(x))
-
-# define parity(x) \
- _Generic((x), \
- unsigned char: __builtin_parity(x), \
- signed char: __builtin_parity(x), \
- unsigned short: __builtin_parity(x), \
- signed short: __builtin_parity(x), \
- unsigned int: __builtin_parity(x), \
- signed int: __builtin_parity(x), \
- unsigned long: __builtin_parityl(x), \
- signed long: __builtin_parityl(x), \
- unsigned long long: __builtin_parityll(x), \
- signed long long: __builtin_parityll(x))
-# else
-VLC_USED static inline int ctz(unsigned x)
-{
- return __builtin_ctz(x);
-}
+#define VLC_INT_FUNC(basename) \
+ VLC_INT_FUNC_TYPE(basename, unsigned, ) \
+ VLC_INT_FUNC_TYPE(basename, unsigned long, l) \
+ VLC_INT_FUNC_TYPE(basename, unsigned long long, ll)
-VLC_USED static inline int ctz(unsigned long x)
-{
- return __builtin_ctzl(x);
+#if defined (__GNUC__) || defined (__clang__)
+# define VLC_INT_FUNC_TYPE(basename,type,suffix) \
+VLC_USED static inline int vlc_##basename##suffix(type x) \
+{ \
+ return __builtin_##basename##suffix(x); \
}
-VLC_USED static inline int ctz(unsigned long long x)
+VLC_INT_FUNC(clz)
+#else
+VLC_USED static inline int vlc_clzll(unsigned long long x)
{
- return __builtin_ctzll(x);
-}
+ int i = sizeof (x) * 8;
-VLC_USED static inline int vlc_popcount(unsigned char x)
-{
- return __builtin_popcount(x);
+ while (x)
+ {
+ x >>= 1;
+ i--;
+ }
+ return i;
}
-VLC_USED static inline int vlc_popcount(unsigned short x)
+VLC_USED static inline int vlc_clzl(unsigned long x)
{
- return __builtin_popcount(x);
+ return vlc_clzll(x) - ((sizeof (long long) - sizeof (long)) * 8);
}
-VLC_USED static inline int vlc_popcount(unsigned x)
+VLC_USED static inline int vlc_clz(unsigned x)
{
- return __builtin_popcount(x);
+ return vlc_clzll(x) - ((sizeof (long long) - sizeof (int)) * 8);
}
-VLC_USED static inline int vlc_popcount(unsigned long x)
+VLC_USED static inline int vlc_ctz_generic(unsigned long long x)
{
- return __builtin_popcountl(x);
-}
+ unsigned i = sizeof (x) * 8;
-VLC_USED static inline int vlc_popcount(unsigned long long x)
-{
- return __builtin_popcountll(x);
+ while (x)
+ {
+ x <<= 1;
+ i--;
+ }
+ return i;
}
-VLC_USED static inline int parity(unsigned x)
+VLC_USED static inline int vlc_parity_generic(unsigned long long x)
{
- return __builtin_parity(x);
+ for (unsigned i = 4 * sizeof (x); i > 0; i /= 2)
+ x ^= x >> i;
+ return x & 1;
}
-VLC_USED static inline int parity(unsigned long x)
+VLC_USED static inline int vlc_popcount_generic(unsigned long long x)
{
- return __builtin_parityl(x);
+ int count = 0;
+ while (x)
+ {
+ count += x & 1;
+ x = x >> 1;
+ }
+ return count;
}
-VLC_USED static inline int parity(unsigned long long x)
-{
- return __builtin_parityll(x);
+# define VLC_INT_FUNC_TYPE(basename,type,suffix) \
+VLC_USED static inline int vlc_##basename##suffix(type x) \
+{ \
+ return vlc_##basename##_generic(x); \
}
+#endif
-# endif
-#else /* __GNUC__ */
-# ifndef __cplusplus
-VLC_USED static inline int clzbits(unsigned long long x, int maxbits)
-{
- int i = maxbits;
+VLC_INT_FUNC(ctz)
+VLC_INT_FUNC(parity)
+VLC_INT_FUNC(popcount)
- while (x)
- {
- x >>= 1;
- i--;
- }
- return i;
-}
-# define clztype(x, type) clzbits(x, sizeof (type) * 8)
+#ifndef __cplusplus
+# define VLC_INT_GENERIC(func,x) \
+ _Generic((x), \
+ unsigned char: func(x), \
+ signed char: func(x), \
+ unsigned short: func(x), \
+ signed short: func(x), \
+ unsigned int: func(x), \
+ signed int: func(x), \
+ unsigned long: func##l(x), \
+ signed long: func##l(x), \
+ unsigned long long: func##ll(x), \
+ signed long long: func##ll(x))
/**
* Count leading zeroes
@@ -714,14 +688,14 @@ VLC_USED static inline int clzbits(unsigned long long x, int maxbits)
* \warning By definition, the result depends on the (width of the) type of x.
* \return The number of leading zero bits in x.
*/
-# define clz(x) \
+# define clz(x) \
_Generic((x), \
- unsigned char: clztype(x, char), \
- unsigned short: clztype(x, short), \
- unsigned: clztype(x, int), \
- unsigned long: clztype(x, long), \
- unsigned long long: clztype(x, long long))
-# endif
+ unsigned char: (vlc_clz(x) - (sizeof (unsigned) - 1) * 8), \
+ unsigned short: (vlc_clz(x) \
+ - (sizeof (unsigned) - sizeof (unsigned short)) * 8), \
+ unsigned: vlc_clz(x), \
+ unsigned long: vlc_clzl(x), \
+ unsigned long long: vlc_clzll(x))
/**
* Count trailing zeroes
@@ -733,30 +707,17 @@ VLC_USED static inline int clzbits(unsigned long long x, int maxbits)
* \note This function assumes that CHAR_BIT equals 8.
* \return The number of trailing zero bits in x.
*/
-VLC_USED static inline int ctz(unsigned long long x)
-{
- unsigned i = sizeof (x) * 8;
-
- while (x)
- {
- x <<= 1;
- i--;
- }
- return i;
-}
+# define ctz(x) VLC_INT_GENERIC(vlc_ctz, x)
-VLC_USED static inline int vlc_popcount(unsigned long long x)
-{
- int count = 0;
- while (x)
- {
- count += x & 1;
- x = x >> 1;
- }
- return count;
-}
+/**
+ * Parity
+ *
+ * This function determines the parity of an integer.
+ * \retval 0 if x has an even number of set bits.
+ * \retval 1 if x has an odd number of set bits.
+ */
+# define parity(x) VLC_INT_GENERIC(vlc_parity, x)
-# ifndef __cplusplus
/**
* Bit weight / population count
*
@@ -764,35 +725,32 @@ VLC_USED static inline int vlc_popcount(unsigned long long x)
*
* \return The count of non-zero bits.
*/
-# define vlc_popcount(x) \
+# define vlc_popcount(x) \
_Generic((x), \
- unsigned char: vlc_popcount(x), \
- signed char: vlc_popcount((unsigned char)(x)), \
- unsigned short: vlc_popcount(x), \
- signed short: vlc_popcount((unsigned short)(x)), \
- unsigned int: vlc_popcount(x), \
- signed int: vlc_popcount((unsigned int)(x)), \
- unsigned long: vlc_popcount(x), \
- signed long: vlc_popcount((unsigned long)(x)), \
- unsigned long long: vlc_popcount(x), \
- signed long long: vlc_popcount(x))
-# endif
+ signed char: vlc_popcount((unsigned char)(x)), \
+ signed short: vlc_popcount((unsigned short)(x)), \
+ default: VLC_INT_GENERIC(vlc_popcount ,x))
+#else
+VLC_USED static inline int vlc_popcount(unsigned char x)
+{
+ return vlc_popcount((unsigned)x);
+}
-/**
- * Parity
- *
- * This function determines the parity of an integer.
- * \retval 0 if x has an even number of set bits.
- * \retval 1 if x has an odd number of set bits.
- */
-VLC_USED static inline int parity(unsigned long long x)
+VLC_USED static inline int vlc_popcount(unsigned short x)
{
- for (unsigned i = 4 * sizeof (x); i > 0; i /= 2)
- x ^= x >> i;
- return x & 1;
+ return vlc_popcount((unsigned)x);
}
-#endif /* __GNUC__ */
+VLC_USED static inline int vlc_popcount(unsigned long x)
+{
+ return vlc_popcountl(x);
+}
+
+VLC_USED static inline int vlc_popcount(unsigned long long x)
+{
+ return vlc_popcountll(x);
+}
+#endif
/** Byte swap (16 bits) */
VLC_USED
More information about the vlc-commits
mailing list