|
|
|
@ -41,14 +41,17 @@ static inline int |
|
|
|
|
pg_leftmost_one_pos32(uint32 word) |
|
|
|
|
{ |
|
|
|
|
#ifdef HAVE__BUILTIN_CLZ |
|
|
|
|
int bitscan_result; |
|
|
|
|
Assert(word != 0); |
|
|
|
|
|
|
|
|
|
return 31 - __builtin_clz(word); |
|
|
|
|
#elif defined(_MSC_VER) |
|
|
|
|
unsigned long bitscan_result; |
|
|
|
|
unsigned long result; |
|
|
|
|
bool non_zero; |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
#if !defined(HAVE_BITSCAN_REVERSE) || defined(USE_ASSERT_CHECKING) |
|
|
|
|
int result; |
|
|
|
|
non_zero = _BitScanReverse(&result, word); |
|
|
|
|
Assert(non_zero); |
|
|
|
|
return (int) result; |
|
|
|
|
#else |
|
|
|
|
int shift = 32 - 8; |
|
|
|
|
|
|
|
|
|
Assert(word != 0); |
|
|
|
@ -56,23 +59,8 @@ pg_leftmost_one_pos32(uint32 word) |
|
|
|
|
while ((word >> shift) == 0) |
|
|
|
|
shift -= 8; |
|
|
|
|
|
|
|
|
|
result = shift + pg_leftmost_one_pos[(word >> shift) & 255]; |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
#ifdef HAVE_BITSCAN_REVERSE |
|
|
|
|
|
|
|
|
|
#if defined(HAVE__BUILTIN_CLZ) |
|
|
|
|
bitscan_result = 31 - __builtin_clz(word); |
|
|
|
|
#elif defined(_MSC_VER) |
|
|
|
|
non_zero = _BitScanReverse(&bitscan_result, word); |
|
|
|
|
Assert(non_zero); |
|
|
|
|
#endif |
|
|
|
|
Assert(bitscan_result == result); |
|
|
|
|
return bitscan_result; |
|
|
|
|
|
|
|
|
|
#else |
|
|
|
|
return result; |
|
|
|
|
#endif /* HAVE_BITSCAN_REVERSE */ |
|
|
|
|
return shift + pg_leftmost_one_pos[(word >> shift) & 255]; |
|
|
|
|
#endif /* HAVE__BUILTIN_CLZ */ |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
@ -83,45 +71,33 @@ static inline int |
|
|
|
|
pg_leftmost_one_pos64(uint64 word) |
|
|
|
|
{ |
|
|
|
|
#ifdef HAVE__BUILTIN_CLZ |
|
|
|
|
int bitscan_result; |
|
|
|
|
#elif defined(_MSC_VER) |
|
|
|
|
unsigned long bitscan_result; |
|
|
|
|
bool non_zero; |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
#if !defined(HAVE_BITSCAN_REVERSE) || defined(USE_ASSERT_CHECKING) |
|
|
|
|
int result; |
|
|
|
|
int shift = 64 - 8; |
|
|
|
|
|
|
|
|
|
Assert(word != 0); |
|
|
|
|
|
|
|
|
|
while ((word >> shift) == 0) |
|
|
|
|
shift -= 8; |
|
|
|
|
|
|
|
|
|
result = shift + pg_leftmost_one_pos[(word >> shift) & 255]; |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
#ifdef HAVE_BITSCAN_REVERSE |
|
|
|
|
|
|
|
|
|
#if defined(HAVE__BUILTIN_CLZ) |
|
|
|
|
#if defined(HAVE_LONG_INT_64) |
|
|
|
|
bitscan_result = 63 - __builtin_clzl(word); |
|
|
|
|
return 63 - __builtin_clzl(word); |
|
|
|
|
#elif defined(HAVE_LONG_LONG_INT_64) |
|
|
|
|
bitscan_result = 63 - __builtin_clzll(word); |
|
|
|
|
return 63 - __builtin_clzll(word); |
|
|
|
|
#else |
|
|
|
|
#error must have a working 64-bit integer datatype |
|
|
|
|
#endif /* HAVE_LONG_INT_64 */ |
|
|
|
|
|
|
|
|
|
#elif defined(_MSC_VER) |
|
|
|
|
non_zero = _BitScanReverse64(&bitscan_result, word); |
|
|
|
|
Assert(non_zero); |
|
|
|
|
#endif /* HAVE__BUILTIN_CLZ */ |
|
|
|
|
Assert(bitscan_result == result); |
|
|
|
|
return bitscan_result; |
|
|
|
|
unsigned long result; |
|
|
|
|
bool non_zero; |
|
|
|
|
|
|
|
|
|
non_zero = _BitScanReverse64(&result, word); |
|
|
|
|
Assert(non_zero); |
|
|
|
|
return (int) result; |
|
|
|
|
#else |
|
|
|
|
return result; |
|
|
|
|
#endif /* HAVE_BITSCAN_REVERSE */ |
|
|
|
|
int shift = 64 - 8; |
|
|
|
|
|
|
|
|
|
Assert(word != 0); |
|
|
|
|
|
|
|
|
|
while ((word >> shift) == 0) |
|
|
|
|
shift -= 8; |
|
|
|
|
|
|
|
|
|
return shift + pg_leftmost_one_pos[(word >> shift) & 255]; |
|
|
|
|
#endif /* HAVE__BUILTIN_CLZ */ |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
@ -133,15 +109,17 @@ static inline int |
|
|
|
|
pg_rightmost_one_pos32(uint32 word) |
|
|
|
|
{ |
|
|
|
|
#ifdef HAVE__BUILTIN_CTZ |
|
|
|
|
const uint32 orig_word = word; |
|
|
|
|
int bitscan_result; |
|
|
|
|
Assert(word != 0); |
|
|
|
|
|
|
|
|
|
return __builtin_ctz(word); |
|
|
|
|
#elif defined(_MSC_VER) |
|
|
|
|
const unsigned long orig_word = word; |
|
|
|
|
unsigned long bitscan_result; |
|
|
|
|
unsigned long result; |
|
|
|
|
bool non_zero; |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
#if !defined(HAVE_BITSCAN_FORWARD) || defined(USE_ASSERT_CHECKING) |
|
|
|
|
non_zero = _BitScanForward(&result, word); |
|
|
|
|
Assert(non_zero); |
|
|
|
|
return (int) result; |
|
|
|
|
#else |
|
|
|
|
int result = 0; |
|
|
|
|
|
|
|
|
|
Assert(word != 0); |
|
|
|
@ -152,22 +130,8 @@ pg_rightmost_one_pos32(uint32 word) |
|
|
|
|
result += 8; |
|
|
|
|
} |
|
|
|
|
result += pg_rightmost_one_pos[word & 255]; |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
#ifdef HAVE_BITSCAN_FORWARD |
|
|
|
|
|
|
|
|
|
#if defined(HAVE__BUILTIN_CTZ) |
|
|
|
|
bitscan_result = __builtin_ctz(orig_word); |
|
|
|
|
#elif defined(_MSC_VER) |
|
|
|
|
non_zero = _BitScanForward(&bitscan_result, orig_word); |
|
|
|
|
Assert(non_zero); |
|
|
|
|
#endif |
|
|
|
|
Assert(bitscan_result == result); |
|
|
|
|
return bitscan_result; |
|
|
|
|
|
|
|
|
|
#else |
|
|
|
|
return result; |
|
|
|
|
#endif /* HAVE_BITSCAN_FORWARD */ |
|
|
|
|
#endif /* HAVE__BUILTIN_CTZ */ |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
@ -178,15 +142,24 @@ static inline int |
|
|
|
|
pg_rightmost_one_pos64(uint64 word) |
|
|
|
|
{ |
|
|
|
|
#ifdef HAVE__BUILTIN_CTZ |
|
|
|
|
const uint64 orig_word = word; |
|
|
|
|
int bitscan_result; |
|
|
|
|
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 |
|
|
|
|
#endif /* HAVE_LONG_INT_64 */ |
|
|
|
|
|
|
|
|
|
#elif defined(_MSC_VER) |
|
|
|
|
const unsigned __int64 orig_word = word; |
|
|
|
|
unsigned long bitscan_result; |
|
|
|
|
unsigned long result; |
|
|
|
|
bool non_zero; |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
#if !defined(HAVE_BITSCAN_FORWARD) || defined(USE_ASSERT_CHECKING) |
|
|
|
|
non_zero = _BitScanForward64(&result, word); |
|
|
|
|
Assert(non_zero); |
|
|
|
|
return (int) result; |
|
|
|
|
#else |
|
|
|
|
int result = 0; |
|
|
|
|
|
|
|
|
|
Assert(word != 0); |
|
|
|
@ -197,29 +170,8 @@ pg_rightmost_one_pos64(uint64 word) |
|
|
|
|
result += 8; |
|
|
|
|
} |
|
|
|
|
result += pg_rightmost_one_pos[word & 255]; |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
#ifdef HAVE_BITSCAN_FORWARD |
|
|
|
|
|
|
|
|
|
#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 */ |
|
|
|
|
|
|
|
|
|
#elif defined(_MSC_VER) |
|
|
|
|
non_zero = _BitScanForward64(&bitscan_result, orig_word); |
|
|
|
|
Assert(non_zero); |
|
|
|
|
#endif /* HAVE__BUILTIN_CTZ */ |
|
|
|
|
Assert(bitscan_result == result); |
|
|
|
|
return bitscan_result; |
|
|
|
|
|
|
|
|
|
#else |
|
|
|
|
return result; |
|
|
|
|
#endif /* HAVE_BITSCAN_FORWARD */ |
|
|
|
|
#endif /* HAVE__BUILTIN_CTZ */ |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|