Files
bluelib/core/sys/windows/bitop.c

54 lines
950 B
C
Raw Normal View History

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) {
return __popcnt64(v);
}
assert(0 && "CPU does not support popcount!");
return 0;
}
int b_ctzl(long v)
{
unsigned long trailing_zero = 0;
if (_BitScanForward64(&trailing_zero, v)) {
return trailing_zero;
} else {
return 64;
}
}
int b_clzl(long v)
{
unsigned long leading_zero = 0;
if (_BitScanReverse64(&leading_zero, v)) {
return 64 - leading_zero;
} else {
// Same remarks as above
return 64;
}
}