diff --git a/src/include/port/pg_bitutils.h b/src/include/port/pg_bitutils.h index 9150789aaf..158ef73a2b 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; -#elif defined(_MSC_VER) - unsigned long bitscan_result; - bool non_zero; -#endif + Assert(word != 0); -#if !defined(HAVE_BITSCAN_REVERSE) || defined(USE_ASSERT_CHECKING) - int result; + return 31 - __builtin_clz(word); +#elif defined(_MSC_VER) + unsigned long result; + bool non_zero; + + 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,14 +71,24 @@ 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 + Assert(word != 0); -#if !defined(HAVE_BITSCAN_REVERSE) || defined(USE_ASSERT_CHECKING) - int result; +#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 +#endif /* HAVE_LONG_INT_64 */ + +#elif defined(_MSC_VER) + unsigned long result; + bool non_zero; + + non_zero = _BitScanReverse64(&result, word); + Assert(non_zero); + return (int) result; +#else int shift = 64 - 8; Assert(word != 0); @@ -98,30 +96,8 @@ pg_leftmost_one_pos64(uint64 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) -#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 */ - -#elif defined(_MSC_VER) - non_zero = _BitScanReverse64(&bitscan_result, word); - Assert(non_zero); + return shift + pg_leftmost_one_pos[(word >> shift) & 255]; #endif /* HAVE__BUILTIN_CLZ */ - Assert(bitscan_result == result); - return bitscan_result; - -#else - return result; -#endif /* HAVE_BITSCAN_REVERSE */ } /* @@ -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; -#elif defined(_MSC_VER) - const unsigned long orig_word = word; - unsigned long bitscan_result; - bool non_zero; -#endif + Assert(word != 0); -#if !defined(HAVE_BITSCAN_FORWARD) || defined(USE_ASSERT_CHECKING) + return __builtin_ctz(word); +#elif defined(_MSC_VER) + unsigned long result; + bool non_zero; + + 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; -#elif defined(_MSC_VER) - const unsigned __int64 orig_word = word; - unsigned long bitscan_result; - bool non_zero; -#endif + Assert(word != 0); -#if !defined(HAVE_BITSCAN_FORWARD) || defined(USE_ASSERT_CHECKING) +#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) + unsigned long result; + bool non_zero; + + 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 */ } /*