Where possible use compiler builtins for CountBits and FindFirstBit.

This commit is contained in:
Jonathan G Rennison
2016-09-04 18:01:38 +01:00
parent 376a45d9fc
commit 349cd8a6f0
3 changed files with 48 additions and 3 deletions

View File

@@ -1812,6 +1812,22 @@ EOL
fi fi
fi fi
log 2 "executing $cc_host $CFLAGS $LDFLAGS $STATIC_FLAGS -o tmp.config.bitmath-builtins -x c++ -"
"$cc_host" $CFLAGS $LDFLAGS $STATIC_FLAGS -o tmp.config.bitmath-builtins -x c++ - 2> /dev/null << EOL
int main() {
return __builtin_popcountll(__builtin_popcountl(__builtin_popcount(__builtin_ctz(1))));
}
EOL
ret=$?
rm -f tmp.config.bitmath-builtins
log 2 " exit code $ret"
if [ $ret -ne 0 ]; then
log 1 "checking bitmath builtins... no"
else
log 1 "checking bitmath builtins... found"
CFLAGS="$CFLAGS -DWITH_BITMATH_BUILTINS"
fi
if [ "$os" != "CYGWIN" ] && [ "$os" != "HAIKU" ] && [ "$os" != "MORPHOS" ] && [ "$os" != "OSX" ] && [ "$os" != "DOS" ] && [ "$os" != "WINCE" ] && [ "$os" != "PSP" ] && [ "$os" != "OS2" ]; then if [ "$os" != "CYGWIN" ] && [ "$os" != "HAIKU" ] && [ "$os" != "MORPHOS" ] && [ "$os" != "OSX" ] && [ "$os" != "DOS" ] && [ "$os" != "WINCE" ] && [ "$os" != "PSP" ] && [ "$os" != "OS2" ]; then
log 2 "executing $cc_host $CFLAGS $LDFLAGS $STATIC_FLAGS -o tmp.config.demangle -x c++ - -lstdc++" log 2 "executing $cc_host $CFLAGS $LDFLAGS $STATIC_FLAGS -o tmp.config.demangle -x c++ - -lstdc++"
"$cc_host" $CFLAGS $LDFLAGS $STATIC_FLAGS -o tmp.config.demangle -x c++ - -lstdc++ 2> /dev/null << EOL "$cc_host" $CFLAGS $LDFLAGS $STATIC_FLAGS -o tmp.config.demangle -x c++ - -lstdc++ 2> /dev/null << EOL

View File

@@ -14,6 +14,8 @@
#include "../safeguards.h" #include "../safeguards.h"
#ifndef WITH_BITMATH_BUILTINS
const uint8 _ffb_64[64] = { const uint8 _ffb_64[64] = {
0, 0, 1, 0, 2, 0, 1, 0, 0, 0, 1, 0, 2, 0, 1, 0,
3, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
@@ -53,6 +55,8 @@ uint8 FindFirstBit(uint32 x)
return pos; return pos;
} }
#endif
/** /**
* Search the last set bit in a 64 bit variable. * Search the last set bit in a 64 bit variable.
* *

View File

@@ -185,6 +185,18 @@ static inline T ToggleBit(T &x, const uint8 y)
return x = (T)(x ^ ((T)1U << y)); return x = (T)(x ^ ((T)1U << y));
} }
#ifdef WITH_BITMATH_BUILTINS
#define FIND_FIRST_BIT(x) FindFirstBit(x)
inline uint8 FindFirstBit(uint32 x)
{
if (x == 0) return 0;
return __builtin_ctz(x);
}
#else
/** Lookup table to check which bit is set in a 6 bit variable */ /** Lookup table to check which bit is set in a 6 bit variable */
extern const uint8 _ffb_64[64]; extern const uint8 _ffb_64[64];
@@ -201,6 +213,12 @@ extern const uint8 _ffb_64[64];
*/ */
#define FIND_FIRST_BIT(x) _ffb_64[(x)] #define FIND_FIRST_BIT(x) _ffb_64[(x)]
uint8 FindFirstBit(uint32 x);
#endif
uint8 FindLastBit(uint64 x);
/** /**
* Finds the position of the first non-zero bit in an integer. * Finds the position of the first non-zero bit in an integer.
* *
@@ -224,9 +242,6 @@ static inline uint8 FindFirstBit2x64(const int value)
} }
} }
uint8 FindFirstBit(uint32 x);
uint8 FindLastBit(uint64 x);
/** /**
* Clear the first bit in an integer. * Clear the first bit in an integer.
* *
@@ -252,6 +267,15 @@ static inline T KillFirstBit(T value)
template <typename T> template <typename T>
static inline uint CountBits(T value) static inline uint CountBits(T value)
{ {
#ifdef WITH_BITMATH_BUILTINS
if (sizeof(T) == sizeof(unsigned int)) {
return __builtin_popcount(value);
} else if (sizeof(T) == sizeof(unsigned long)) {
return __builtin_popcountl(value);
} else {
return __builtin_popcountll(value);
}
#else
uint num; uint num;
/* This loop is only called once for every bit set by clearing the lowest /* This loop is only called once for every bit set by clearing the lowest
@@ -264,6 +288,7 @@ static inline uint CountBits(T value)
} }
return num; return num;
#endif
} }
/** /**