Where possible use compiler builtins for CountBits and FindFirstBit.
This commit is contained in:
16
config.lib
16
config.lib
@@ -1812,6 +1812,22 @@ EOL
|
||||
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
|
||||
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
|
||||
|
@@ -14,6 +14,8 @@
|
||||
|
||||
#include "../safeguards.h"
|
||||
|
||||
#ifndef WITH_BITMATH_BUILTINS
|
||||
|
||||
const uint8 _ffb_64[64] = {
|
||||
0, 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;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Search the last set bit in a 64 bit variable.
|
||||
*
|
||||
|
@@ -185,6 +185,18 @@ static inline T ToggleBit(T &x, const uint8 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 */
|
||||
extern const uint8 _ffb_64[64];
|
||||
@@ -201,6 +213,12 @@ extern const uint8 _ffb_64[64];
|
||||
*/
|
||||
#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.
|
||||
*
|
||||
@@ -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.
|
||||
*
|
||||
@@ -252,6 +267,15 @@ static inline T KillFirstBit(T value)
|
||||
template <typename T>
|
||||
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;
|
||||
|
||||
/* 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;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
Reference in New Issue
Block a user