Index: src/compiler-intrinsics.h |
=================================================================== |
--- src/compiler-intrinsics.h (revision 11426) |
+++ src/compiler-intrinsics.h (working copy) |
@@ -40,6 +40,9 @@ |
// Returns number of zero bits following most significant 1 bit. |
// Undefined for zero value. |
INLINE(static int CountLeadingZeros(uint32_t value)); |
+ |
+ // Returns the number of bits set. |
+ INLINE(static int CountSetBits(uint32_t value)); |
}; |
#ifdef __GNUC__ |
@@ -51,6 +54,10 @@ |
return __builtin_clz(value); |
} |
+int CompilerIntrinsics::CountSetBits(uint32_t value) { |
+ return __builtin_popcount(value); |
+} |
+ |
#elif defined(_MSC_VER) |
#pragma intrinsic(_BitScanForward) |
@@ -68,7 +75,24 @@ |
return 31 - static_cast<int>(result); |
} |
+int CompilerIntrinsics::CountSetBits(uint32_t value) { |
+ // __popcnt is only supported from VS2008. |
+#define _MSC_VER_VS2008 1500 |
+#if _MSC_VER >= _MSC_VER_VS2008 |
+ return __popcnt(value); |
#else |
+ // Manually count set bits. |
+ 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 |
+#undef _MSC_VER_VS2008 |
+} |
+ |
+#else |
#error Unsupported compiler |
#endif |