__builtin_ctzll, __builtin_clzll for Win32

extensions
Volodymyr Shymanskyy 5 years ago
parent f4d9154def
commit afd82dbf6f

@ -19,7 +19,6 @@
#include <intrin.h>
#define __builtin_popcount __popcnt
#define __builtin_popcountll __popcnt64
static inline
int __builtin_ctz(uint32_t x) {
@ -29,27 +28,58 @@ int __builtin_ctz(uint32_t x) {
}
static inline
int __builtin_ctzll(unsigned long long x) {
int __builtin_clz(uint32_t x) {
unsigned long ret;
_BitScanForward64(&ret, x);
return (int)ret;
_BitScanReverse(&ret, x);
return (int)(31 ^ ret);
}
#ifdef _WIN64
#define __builtin_popcountll __popcnt64
static inline
int __builtin_clz(uint32_t x) {
int __builtin_ctzll(uint64_t value) {
unsigned long ret;
_BitScanReverse(&ret, x);
return (int)(31 ^ ret);
_BitScanForward64(&ret, value);
return (int)ret;
}
static inline
int __builtin_clzll(unsigned long long x) {
int __builtin_clzll(uint64_t value) {
unsigned long ret;
_BitScanReverse64(&ret, x);
_BitScanReverse64(&ret, value);
return (int)(63 ^ ret);
}
#endif
#else // _WIN64
#define __builtin_popcountll(x) (__popcnt((x) & 0xFFFFFFFF) + __popcnt((x) >> 32))
static inline
int __builtin_ctzll(uint64_t value) {
if (value == 0) return 64;
uint32_t msh = (uint32_t)(value >> 32);
uint32_t lsh = (uint32_t)(value & 0xFFFFFFFF);
if (lsh != 0) return __builtin_ctz(lsh);
return 32 + __builtin_ctz(msh);
}
static inline
int __builtin_clzll(uint64_t value) {
if (value == 0) return 64;
uint32_t msh = (uint32_t)(value >> 32);
uint32_t lsh = (uint32_t)(value & 0xFFFFFFFF);
if (msh != 0) return __builtin_clz(msh);
return 32 + __builtin_clz(lsh);
}
#endif // _WIN64
#endif // defined(M3_COMPILER_MSVC)
// TODO: not sure why, signbit is actually defined in math.h
#if defined(ESP8266)

Loading…
Cancel
Save