@@ -844,32 +844,58 @@ static inline size_t mi_ctz(uintptr_t x) {
844844}
845845
846846#else
847- static inline size_t mi_ctz32 (uint32_t x) {
848- // de Bruijn multiplication, see <http://supertech.csail.mit.edu/papers/debruijn.pdf>
849- static const unsigned char debruijn[32 ] = {
847+ static inline size_t mi_ctz_generic32 (uint32_t x) {
848+ static const uint8_t debruijn[32 ] = {
850849 0 , 1 , 28 , 2 , 29 , 14 , 24 , 3 , 30 , 22 , 20 , 15 , 25 , 17 , 4 , 8 ,
851850 31 , 27 , 13 , 23 , 21 , 19 , 16 , 7 , 26 , 12 , 18 , 6 , 11 , 5 , 10 , 9
852851 };
853- if (x==0 ) return 32 ;
854- return debruijn[(uint32_t )(((x & -(int32_t )x) * 0x077CB531UL ) >> 27 ) & 31 ];
855-
852+ if (x == 0 ) return 32 ;
853+ return debruijn[(uint32_t )((x & -(int32_t )x) * (uint32_t )(0x077CB531U )) >> 27 ];
856854}
857- static inline size_t mi_clz32 ( uint32_t x) {
858- // de Bruijn multiplication, see <http://supertech.csail.mit.edu/papers/debruijn.pdf>
855+
856+ static inline size_t mi_clz_generic32 ( uint32_t x) {
859857 static const uint8_t debruijn[32 ] = {
860858 31 , 22 , 30 , 21 , 18 , 10 , 29 , 2 , 20 , 17 , 15 , 13 , 9 , 6 , 28 , 1 ,
861859 23 , 19 , 11 , 3 , 16 , 14 , 7 , 24 , 12 , 4 , 8 , 25 , 5 , 26 , 27 , 0
862860 };
863- if (x== 0 ) return 32 ;
861+ if (x == 0 ) return 32 ;
864862 x |= x >> 1 ;
865863 x |= x >> 2 ;
866864 x |= x >> 4 ;
867865 x |= x >> 8 ;
868866 x |= x >> 16 ;
869- return debruijn[(uint32_t )(x * 0x07C4ACDDUL >> 27 ) & 31 ];
867+ return debruijn[(uint32_t )(x * (uint32_t )(0x07C4ACDDU )) >> 27 ];
868+ }
870869
870+ static inline size_t mi_ctz (size_t x) {
871+ if (x == 0 ) return MI_SIZE_BITS;
872+ #if (MI_SIZE_BITS <= 32)
873+ return mi_ctz_generic32 ((uint32_t )x);
874+ #else
875+ const uint32_t lo = (uint32_t )x;
876+ if (lo != 0 ) {
877+ return mi_ctz_generic32 (lo);
878+ } else {
879+ return 32 + mi_ctz_generic32 ((uint32_t )(x >> 32 ));
880+ }
881+ #endif
871882}
872883
884+ static inline size_t mi_clz (size_t x) {
885+ if (x == 0 ) return MI_SIZE_BITS;
886+ #if (MI_SIZE_BITS <= 32)
887+ return mi_clz_generic32 ((uint32_t )x);
888+ #else
889+ const uint32_t hi = (uint32_t )(x >> 32 );
890+ if (hi != 0 ) {
891+ return mi_clz_generic32 (hi);
892+ } else {
893+ return 32 + mi_clz_generic32 ((uint32_t )x);
894+ }
895+ #endif
896+ }
897+
898+
873899static inline size_t mi_clz (uintptr_t x) {
874900 if (x==0 ) return MI_INTPTR_BITS;
875901#if (MI_INTPTR_BITS <= 32)
0 commit comments