From 519ee688760c1bc7d76e04acc6239c3b667f272a Mon Sep 17 00:00:00 2001 From: Florian Albrechtskirchinger Date: Thu, 16 Jun 2022 15:06:31 +0200 Subject: [PATCH] Add _glfw_ffs returning 1-based index of lsb set to one --- src/init.c | 35 +++++++++++++++++++++++++++++++++++ src/internal.h | 1 + 2 files changed, 36 insertions(+) diff --git a/src/init.c b/src/init.c index d07a492e..d84c13f6 100644 --- a/src/init.c +++ b/src/init.c @@ -266,6 +266,41 @@ float _glfw_fmaxf(float a, float b) return b; } +int _glfw_ffs(int i) +{ +#if defined(__GNUC__) || defined(__clang__) + return __builtin_ffs(i); +#elif defined(_MSC_VER) + unsigned long n, u = i; + return _BitScanForward(&n, u) ? n + 1 : 0; +#else + // https://en.wikipedia.org/wiki/Find_first_set#CTZ + unsigned int u = i; + int n = 1; + if (!u) return 0; + if (!(u & 0x0000FFFF)) { + n += 16; + u >>= 16; + } + if (!(u & 0x000000FF)) { + n += 8; + u >>= 8; + } + if (!(u & 0x0000000F)) { + n += 4; + u >>= 4; + } + if (!(u & 0x00000003)) { + n += 2; + u >>= 2; + } + if (!(u & 0x00000001)) { + n += 1; + } + return n; +#endif +} + void* _glfw_calloc(size_t count, size_t size) { if (count && size) diff --git a/src/internal.h b/src/internal.h index 5abf6de2..24be9c53 100644 --- a/src/internal.h +++ b/src/internal.h @@ -1015,6 +1015,7 @@ int _glfw_min(int a, int b); int _glfw_max(int a, int b); float _glfw_fminf(float a, float b); float _glfw_fmaxf(float a, float b); +int _glfw_ffs(int i); void* _glfw_calloc(size_t count, size_t size); void* _glfw_realloc(void* pointer, size_t size);