#include #include #include #define CPU_FEATURE_YES 1 #define CPU_FEATURE_NO -1 #define CPU_FEATURE_UNKNOWN 0 static int cpu_supports_popcnt = CPU_FEATURE_UNKNOWN; static int check_popcnt_support() { int d[4]; __cpuid(d, 0x00000001); return (d[2] & 0x800000) ? CPU_FEATURE_YES : CPU_FEATURE_NO; } int b_popcountl(long v) { if (cpu_supports_popcnt == CPU_FEATURE_UNKNOWN) { cpu_supports_popcnt = check_popcnt_support(); } if (cpu_supports_popcnt == CPU_FEATURE_YES) { #if _M_AMD64 == 100 return __popcnt64(v); #else return __popcnt(v); #endif } assert(0 && "CPU does not support popcount!"); return 0; } int b_ctzl(long v) { unsigned long trailing_zero = 0; #if _M_AMD64 == 100 int x = _BitScanForward64(&trailing_zero, v); #else int x = _BitScanForward(&trailing_zero, v); #endif if (x) { return trailing_zero; } else { return 64; } } int b_clzl(long v) { unsigned long leading_zero = 0; #if _M_AMD64 == 100 int x = _BitScanReverse64(&leading_zero, v); #else int x = _BitScanReverse(&leading_zero, v); #endif if (x) { return 64 - leading_zero; } else { // Same remarks as above return 64; } }