From 3a92c3527045b7922e12131d248b6d57ea646de9 Mon Sep 17 00:00:00 2001 From: daanx Date: Mon, 9 Dec 2024 20:25:22 -0800 Subject: [PATCH] improve generic ctz/clz --- src/libc.c | 38 +++++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/src/libc.c b/src/libc.c index 2b28bd25..15d4d2a7 100644 --- a/src/libc.c +++ b/src/libc.c @@ -289,7 +289,7 @@ static size_t mi_ctz_generic32(uint32_t x) { 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9 }; if (x==0) return 32; - return debruijn[((x & -(int32_t)x) * (uint32_t)(0x077CB531U)) >> 27]; + return debruijn[(uint32_t)((x & -(int32_t)x) * (uint32_t)(0x077CB531U)) >> 27]; } static size_t mi_clz_generic32(uint32_t x) { @@ -307,25 +307,33 @@ static size_t mi_clz_generic32(uint32_t x) { return debruijn[(uint32_t)(x * (uint32_t)(0x07C4ACDDU)) >> 27]; } -size_t _mi_clz_generic(size_t x) { - if (x==0) return MI_SIZE_BITS; - #if (MI_SIZE_BITS <= 32) - return mi_clz_generic32((uint32_t)x); - #else - const size_t count = mi_clz_generic32((uint32_t)(x >> 32)); - if (count < 32) return count; - return (32 + mi_clz_generic32((uint32_t)x)); - #endif -} - size_t _mi_ctz_generic(size_t x) { if (x==0) return MI_SIZE_BITS; #if (MI_SIZE_BITS <= 32) return mi_ctz_generic32((uint32_t)x); #else - const size_t count = mi_ctz_generic32((uint32_t)x); - if (count < 32) return count; - return (32 + mi_ctz_generic32((uint32_t)(x>>32))); + const uint32_t lo = (uint32_t)x; + if (lo != 0) { + return mi_ctz_generic32(lo); + } + else { + return (32 + mi_ctz_generic32((uint32_t)(x>>32))); + } + #endif +} + +size_t _mi_clz_generic(size_t x) { + if (x==0) return MI_SIZE_BITS; + #if (MI_SIZE_BITS <= 32) + return mi_clz_generic32((uint32_t)x); + #else + const uint32_t hi = (uint32_t)(x>>32); + if (hi != 0) { + return mi_clz_generic32(hi); + } + else { + return 32 + mi_clz_generic32((uint32_t)x); + } #endif }