mirror of
https://github.com/brl/mutter.git
synced 2025-06-14 01:09:30 +00:00
Move POPCOUNTL to cogl-util
This moves the POPCOUNTL macro from cogl-winsys-glx to cogl-util and renames it to _cogl_util_popcountl so that it can be used in more places. The fallback function for when the GCC builtin is not available has been replaced with an 8-bit lookup table because the HAKMEM implementation doesn't look like it would work when longs are 64-bit so it's not suitable for a general purpose function on 64-bit architectures. Some of the pages regarding population counts seem to suggest that using a lookup table is the fastest method anyway. Reviewed-by: Robert Bragg <robert@linux.intel.com>
This commit is contained in:
@ -100,6 +100,12 @@ _cogl_util_one_at_a_time_hash (unsigned int hash,
|
||||
unsigned int
|
||||
_cogl_util_one_at_a_time_mix (unsigned int hash);
|
||||
|
||||
/* These two builtins are available since GCC 3.4 */
|
||||
#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
|
||||
#define COGL_UTIL_HAVE_BUILTIN_FFSL
|
||||
#define COGL_UTIL_HAVE_BUILTIN_POPCOUNTL
|
||||
#endif
|
||||
|
||||
/* The 'ffs' function is part of C99 so it isn't always available */
|
||||
#ifdef HAVE_FFS
|
||||
#define _cogl_util_ffs ffs
|
||||
@ -110,9 +116,8 @@ _cogl_util_ffs (int num);
|
||||
|
||||
/* The 'ffsl' function is non-standard but GCC has a builtin for it
|
||||
since 3.4 which we can use */
|
||||
#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
|
||||
#ifdef COGL_UTIL_HAVE_BUILTIN_FFSL
|
||||
#define _cogl_util_ffsl __builtin_ffsl
|
||||
#define COGL_UTIL_HAVE_BUILTIN_FFSL
|
||||
#else
|
||||
/* If ints and longs are the same size we can just use ffs. Hopefully
|
||||
the compiler will optimise away this conditional */
|
||||
@ -121,7 +126,30 @@ _cogl_util_ffs (int num);
|
||||
_cogl_util_ffsl_wrapper (x))
|
||||
int
|
||||
_cogl_util_ffsl_wrapper (long int num);
|
||||
#endif
|
||||
#endif /* COGL_UTIL_HAVE_BUILTIN_FFSL */
|
||||
|
||||
#ifdef COGL_UTIL_HAVE_BUILTIN_POPCOUNTL
|
||||
#define _cogl_util_popcountl __builtin_popcountl
|
||||
#else
|
||||
extern const unsigned char _cogl_util_popcount_table[256];
|
||||
|
||||
/* There are many ways of doing popcount but doing a table lookup
|
||||
seems to be the most robust against different sizes for long. Some
|
||||
pages seem to claim it's the fastest method anyway. */
|
||||
static inline int
|
||||
_cogl_util_popcountl (unsigned long num)
|
||||
{
|
||||
int i;
|
||||
int sum = 0;
|
||||
|
||||
/* Let's hope GCC will unroll this loop.. */
|
||||
for (i = 0; i < sizeof (num); i++)
|
||||
sum += _cogl_util_popcount_table[(num >> (i * 8)) & 0xff];
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
#endif /* COGL_UTIL_HAVE_BUILTIN_POPCOUNTL */
|
||||
|
||||
#ifdef COGL_HAS_GLIB_SUPPORT
|
||||
#define _COGL_RETURN_IF_FAIL(EXPR) g_return_if_fail(EXPR)
|
||||
|
Reference in New Issue
Block a user