Last active
January 15, 2024 01:20
-
-
Save pps83/3210a2f980fd02bb2ba2e5a1fc4a2ef0 to your computer and use it in GitHub Desktop.
__builtin_ctz (ctzl, ctzll) and __builtin_clz (clzl, clzll) for Visual Studio
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifdef _MSC_VER | |
#include <intrin.h> | |
static inline int __builtin_ctz(unsigned x) | |
{ | |
return (int)_tzcnt_u32(x); | |
} | |
static inline int __builtin_ctzll(unsigned long long x) | |
{ | |
#ifdef _WIN64 | |
return (int)_tzcnt_u64(x); | |
#else | |
return !!unsigned(x) ? __builtin_ctz((unsigned)x) : 32 + __builtin_ctz((unsigned)(x >> 32)); | |
#endif | |
} | |
static inline int __builtin_ctzl(unsigned long x) | |
{ | |
return sizeof(x) == 8 ? __builtin_ctzll(x) : __builtin_ctz((unsigned)x); | |
} | |
static inline int __builtin_clz(unsigned x) | |
{ | |
return (int)_lzcnt_u32(x); | |
} | |
static inline int __builtin_clzll(unsigned long long x) | |
{ | |
#ifdef _WIN64 | |
return (int)_lzcnt_u64(x); | |
#else | |
return !!unsigned(x >> 32) ? __builtin_clz((unsigned)(x >> 32)) : 32 + __builtin_clz((unsigned)x); | |
#endif | |
} | |
static inline int __builtin_clzl(unsigned long x) | |
{ | |
return sizeof(x) == 8 ? __builtin_clzll(x) : __builtin_clz((unsigned)x); | |
} | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@pps83 thanks see my updates too, still digging up between targets ; that's funny or not, this simple thing is @$##^&&% to get right ; just for getting a
bit_width
, all I want that's a portablebit_width
operator jeez ; soft emulation takes no ROM ; maybe with a small lookup table I could shrink down the number of ops... whatever just want bit_width, can I get that easy... it seems not. ICC have _lzcnt_u64, _lzcnt_u32 and IBM XL __cntlz4, __cntlz8, but they have now a clang front-end so ; clang forever. ```update ARMCC has __rbit() and __clz() however that's a clang fork so... just logging for posterity.For a soft emulation fallback (according to my CPU benchmarks) the following is the best
player: