Index: src/base/bits.h |
diff --git a/src/base/bits.h b/src/base/bits.h |
index ec0f5517a9d34d5ae593432749199b5ab9ec308f..129bf6268c677ae0a562630565508e24f54853a3 100644 |
--- a/src/base/bits.h |
+++ b/src/base/bits.h |
@@ -6,6 +6,9 @@ |
#define V8_BASE_BITS_H_ |
#include "include/v8stdint.h" |
+#if V8_CC_MSVC |
+#include <intrin.h> |
+#endif |
#if V8_OS_WIN32 |
#include "src/base/win32-headers.h" |
#endif |
@@ -14,6 +17,61 @@ namespace v8 { |
namespace base { |
namespace bits { |
+// CountSetBits32(value) returns the number of bits set in |value|. |
+inline uint32_t CountSetBits32(uint32_t value) { |
+#if V8_HAS_BUILTIN_POPCOUNT |
+ return __builtin_popcount(value); |
+#else |
+ value = ((value >> 1) & 0x55555555) + (value & 0x55555555); |
+ value = ((value >> 2) & 0x33333333) + (value & 0x33333333); |
+ value = ((value >> 4) & 0x0f0f0f0f) + (value & 0x0f0f0f0f); |
+ value = ((value >> 8) & 0x00ff00ff) + (value & 0x00ff00ff); |
+ value = ((value >> 16) & 0x0000ffff) + (value & 0x0000ffff); |
+ return value; |
+#endif |
+} |
+ |
+ |
+// CountLeadingZeros32(value) returns the number of zero bits following the most |
+// significant 1 bit in |value| if |value| is non-zero, otherwise it returns 32. |
+inline uint32_t CountLeadingZeros32(uint32_t value) { |
+#if V8_HAS_BUILTIN_CLZ |
+ return value ? __builtin_clz(value) : 32; |
+#elif V8_CC_MSVC |
+ unsigned long result; // NOLINT(runtime/int) |
+ if (!_BitScanReverse(&result, value)) return 32; |
+ return static_cast<uint32_t>(31 - result); |
+#else |
+ value = value | (value >> 1); |
+ value = value | (value >> 2); |
+ value = value | (value >> 4); |
+ value = value | (value >> 8); |
+ value = value | (value >> 16); |
+ return CountSetBits32(~value); |
+#endif |
+} |
+ |
+ |
+// CountTrailingZeros32(value) returns the number of zero bits preceding the |
+// least significant 1 bit in |value| if |value| is non-zero, otherwise it |
+// returns 32. |
+inline uint32_t CountTrailingZeros32(uint32_t value) { |
+#if V8_HAS_BUILTIN_CTZ |
+ return value ? __builtin_ctz(value) : 32; |
+#elif V8_CC_MSVC |
+ unsigned long result; // NOLINT(runtime/int) |
+ if (!_BitScanForward(&result, value)) return 32; |
+ return static_cast<uint32_t>(result); |
+#else |
+ if (value == 0) return 32; |
+ unsigned count = 0; |
+ for (value ^= value - 1; value >>= 1; ++count) |
+ ; |
+ return count; |
+#endif |
+} |
+ |
+ |
inline uint32_t RotateRight32(uint32_t value, uint32_t shift) { |
if (shift == 0) return value; |
return (value >> shift) | (value << (32 - shift)); |