diff options
-rw-r--r-- | src/include/port/pg_bitutils.h | 150 |
1 files changed, 51 insertions, 99 deletions
diff --git a/src/include/port/pg_bitutils.h b/src/include/port/pg_bitutils.h index 9150789aaf5..158ef73a2b2 100644 --- a/src/include/port/pg_bitutils.h +++ b/src/include/port/pg_bitutils.h @@ -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 */ } /* |