1
0
mirror of https://github.com/EduApps-CDG/OpenDX synced 2024-12-30 09:45:37 +01:00
OpenDX/src/util/util_bit.h
2018-07-09 13:32:43 +02:00

50 lines
999 B
C++

#pragma once
#ifndef _MSC_VER
#include <x86intrin.h>
#else
#include <intrin.h>
#endif
namespace dxvk::bit {
template<typename T>
T extract(T value, uint32_t fst, uint32_t lst) {
return (value >> fst) & ~(~T(0) << (lst - fst + 1));
}
template<typename T>
T popcnt(T value) {
return value != 0
? (value & 1) + popcnt(value >> 1)
: 0;
}
inline uint32_t tzcnt(uint32_t n) {
#if defined(_MSC_VER)
return _tzcnt_u32(n);
#elif defined(__BMI__)
return __tzcnt_u32(n);
#elif defined(__GNUC__)
uint32_t res;
uint32_t tmp;
asm (
"mov $32, %1;"
"bsf %2, %0;"
"cmovz %1, %0;"
: "=&r" (res), "=&r" (tmp)
: "r" (n));
return res;
#else
uint32_t r = 31;
n &= -n;
r -= (n & 0x0000FFFF) ? 16 : 0;
r -= (n & 0x00FF00FF) ? 8 : 0;
r -= (n & 0x0F0F0F0F) ? 4 : 0;
r -= (n & 0x33333333) ? 2 : 0;
r -= (n & 0x55555555) ? 1 : 0;
return n != 0 ? r : 32;
#endif
}
}