2024-11-14 16:56:12 +00:00
|
|
|
#include <blue/core/bitop.h>
|
|
|
|
|
#include <intrin.h>
|
|
|
|
|
#include <assert.h>
|
|
|
|
|
|
|
|
|
|
#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) {
|
2024-12-06 15:10:41 +00:00
|
|
|
#if _M_AMD64 == 100
|
2024-11-14 16:56:12 +00:00
|
|
|
return __popcnt64(v);
|
2024-12-06 15:10:41 +00:00
|
|
|
#else
|
|
|
|
|
return __popcnt(v);
|
|
|
|
|
#endif
|
2024-11-14 16:56:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
assert(0 && "CPU does not support popcount!");
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int b_ctzl(long v)
|
|
|
|
|
{
|
|
|
|
|
unsigned long trailing_zero = 0;
|
|
|
|
|
|
2024-12-06 15:10:41 +00:00
|
|
|
#if _M_AMD64 == 100
|
|
|
|
|
int x = _BitScanForward64(&trailing_zero, v);
|
|
|
|
|
#else
|
|
|
|
|
int x = _BitScanForward(&trailing_zero, v);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
if (x) {
|
2024-11-14 16:56:12 +00:00
|
|
|
return trailing_zero;
|
|
|
|
|
} else {
|
|
|
|
|
return 64;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int b_clzl(long v)
|
|
|
|
|
{
|
|
|
|
|
unsigned long leading_zero = 0;
|
|
|
|
|
|
2024-12-06 15:10:41 +00:00
|
|
|
#if _M_AMD64 == 100
|
|
|
|
|
int x = _BitScanReverse64(&leading_zero, v);
|
|
|
|
|
#else
|
|
|
|
|
int x = _BitScanReverse(&leading_zero, v);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
if (x) {
|
2024-11-14 16:56:12 +00:00
|
|
|
return 64 - leading_zero;
|
|
|
|
|
} else {
|
|
|
|
|
// Same remarks as above
|
|
|
|
|
return 64;
|
|
|
|
|
}
|
|
|
|
|
}
|