|
|
|
@ -26,10 +26,11 @@ static inline int |
|
|
|
|
pg_leftmost_one_pos32(uint32 word) |
|
|
|
|
{ |
|
|
|
|
#ifdef HAVE__BUILTIN_CLZ |
|
|
|
|
Assert(word != 0); |
|
|
|
|
int bitscan_result; |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
return 31 - __builtin_clz(word); |
|
|
|
|
#else |
|
|
|
|
#if !defined(HAVE__BUILTIN_CLZ) || defined(USE_ASSERT_CHECKING) |
|
|
|
|
int result; |
|
|
|
|
int shift = 32 - 8; |
|
|
|
|
|
|
|
|
|
Assert(word != 0); |
|
|
|
@ -37,7 +38,15 @@ pg_leftmost_one_pos32(uint32 word) |
|
|
|
|
while ((word >> shift) == 0) |
|
|
|
|
shift -= 8; |
|
|
|
|
|
|
|
|
|
return shift + pg_leftmost_one_pos[(word >> shift) & 255]; |
|
|
|
|
result = shift + pg_leftmost_one_pos[(word >> shift) & 255]; |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
#if defined(HAVE__BUILTIN_CLZ) |
|
|
|
|
bitscan_result = 31 - __builtin_clz(word); |
|
|
|
|
Assert(bitscan_result == result); |
|
|
|
|
return bitscan_result; |
|
|
|
|
#else |
|
|
|
|
return result; |
|
|
|
|
#endif /* HAVE__BUILTIN_CLZ */ |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -49,16 +58,11 @@ static inline int |
|
|
|
|
pg_leftmost_one_pos64(uint64 word) |
|
|
|
|
{ |
|
|
|
|
#ifdef HAVE__BUILTIN_CLZ |
|
|
|
|
Assert(word != 0); |
|
|
|
|
|
|
|
|
|
#if defined(HAVE_LONG_INT_64) |
|
|
|
|
return 63 - __builtin_clzl(word); |
|
|
|
|
#elif defined(HAVE_LONG_LONG_INT_64) |
|
|
|
|
return 63 - __builtin_clzll(word); |
|
|
|
|
#else |
|
|
|
|
#error must have a working 64-bit integer datatype |
|
|
|
|
int bitscan_result; |
|
|
|
|
#endif |
|
|
|
|
#else /* !HAVE__BUILTIN_CLZ */ |
|
|
|
|
|
|
|
|
|
#if !defined(HAVE__BUILTIN_CLZ) || defined(USE_ASSERT_CHECKING) |
|
|
|
|
int result; |
|
|
|
|
int shift = 64 - 8; |
|
|
|
|
|
|
|
|
|
Assert(word != 0); |
|
|
|
@ -66,7 +70,21 @@ pg_leftmost_one_pos64(uint64 word) |
|
|
|
|
while ((word >> shift) == 0) |
|
|
|
|
shift -= 8; |
|
|
|
|
|
|
|
|
|
return shift + pg_leftmost_one_pos[(word >> shift) & 255]; |
|
|
|
|
result = shift + pg_leftmost_one_pos[(word >> shift) & 255]; |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
#if defined(HAVE__BUILTIN_CLZ) |
|
|
|
|
#if defined(HAVE_LONG_INT_64) |
|
|
|
|
bitscan_result = 63 - __builtin_clzl(word); |
|
|
|
|
#elif defined(HAVE_LONG_LONG_INT_64) |
|
|
|
|
bitscan_result = 63 - __builtin_clzll(word); |
|
|
|
|
#else |
|
|
|
|
#error must have a working 64-bit integer datatype |
|
|
|
|
#endif /* HAVE_LONG_INT_64 */ |
|
|
|
|
Assert(bitscan_result == result); |
|
|
|
|
return bitscan_result; |
|
|
|
|
#else |
|
|
|
|
return result; |
|
|
|
|
#endif /* HAVE__BUILTIN_CLZ */ |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -79,10 +97,11 @@ static inline int |
|
|
|
|
pg_rightmost_one_pos32(uint32 word) |
|
|
|
|
{ |
|
|
|
|
#ifdef HAVE__BUILTIN_CTZ |
|
|
|
|
Assert(word != 0); |
|
|
|
|
const uint32 orig_word = word; |
|
|
|
|
int bitscan_result; |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
return __builtin_ctz(word); |
|
|
|
|
#else |
|
|
|
|
#if !defined(HAVE__BUILTIN_CTZ) || defined(USE_ASSERT_CHECKING) |
|
|
|
|
int result = 0; |
|
|
|
|
|
|
|
|
|
Assert(word != 0); |
|
|
|
@ -93,6 +112,13 @@ pg_rightmost_one_pos32(uint32 word) |
|
|
|
|
result += 8; |
|
|
|
|
} |
|
|
|
|
result += pg_rightmost_one_pos[word & 255]; |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
#if defined(HAVE__BUILTIN_CTZ) |
|
|
|
|
bitscan_result = __builtin_ctz(orig_word); |
|
|
|
|
Assert(bitscan_result == result); |
|
|
|
|
return bitscan_result; |
|
|
|
|
#else |
|
|
|
|
return result; |
|
|
|
|
#endif /* HAVE__BUILTIN_CTZ */ |
|
|
|
|
} |
|
|
|
@ -105,16 +131,11 @@ static inline int |
|
|
|
|
pg_rightmost_one_pos64(uint64 word) |
|
|
|
|
{ |
|
|
|
|
#ifdef HAVE__BUILTIN_CTZ |
|
|
|
|
Assert(word != 0); |
|
|
|
|
|
|
|
|
|
#if defined(HAVE_LONG_INT_64) |
|
|
|
|
return __builtin_ctzl(word); |
|
|
|
|
#elif defined(HAVE_LONG_LONG_INT_64) |
|
|
|
|
return __builtin_ctzll(word); |
|
|
|
|
#else |
|
|
|
|
#error must have a working 64-bit integer datatype |
|
|
|
|
const uint64 orig_word = word; |
|
|
|
|
int bitscan_result; |
|
|
|
|
#endif |
|
|
|
|
#else /* !HAVE__BUILTIN_CTZ */ |
|
|
|
|
|
|
|
|
|
#if !defined(HAVE__BUILTIN_CTZ) || defined(USE_ASSERT_CHECKING) |
|
|
|
|
int result = 0; |
|
|
|
|
|
|
|
|
|
Assert(word != 0); |
|
|
|
@ -125,6 +146,19 @@ pg_rightmost_one_pos64(uint64 word) |
|
|
|
|
result += 8; |
|
|
|
|
} |
|
|
|
|
result += pg_rightmost_one_pos[word & 255]; |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
#if defined(HAVE__BUILTIN_CTZ) |
|
|
|
|
#if defined(HAVE_LONG_INT_64) |
|
|
|
|
bitscan_result = __builtin_ctzl(orig_word); |
|
|
|
|
#elif defined(HAVE_LONG_LONG_INT_64) |
|
|
|
|
bitscan_result = __builtin_ctzll(orig_word); |
|
|
|
|
#else |
|
|
|
|
#error must have a working 64-bit integer datatype |
|
|
|
|
#endif /* HAVE_LONG_INT_64 */ |
|
|
|
|
Assert(bitscan_result == result); |
|
|
|
|
return bitscan_result; |
|
|
|
|
#else |
|
|
|
|
return result; |
|
|
|
|
#endif /* HAVE__BUILTIN_CTZ */ |
|
|
|
|
} |
|
|
|
|