1*8e33eff8Schristos #ifndef JEMALLOC_INTERNAL_BIT_UTIL_H 2*8e33eff8Schristos #define JEMALLOC_INTERNAL_BIT_UTIL_H 3*8e33eff8Schristos 4*8e33eff8Schristos #include "jemalloc/internal/assert.h" 5*8e33eff8Schristos 6*8e33eff8Schristos #define BIT_UTIL_INLINE static inline 7*8e33eff8Schristos 8*8e33eff8Schristos /* Sanity check. */ 9*8e33eff8Schristos #if !defined(JEMALLOC_INTERNAL_FFSLL) || !defined(JEMALLOC_INTERNAL_FFSL) \ 10*8e33eff8Schristos || !defined(JEMALLOC_INTERNAL_FFS) 11*8e33eff8Schristos # error JEMALLOC_INTERNAL_FFS{,L,LL} should have been defined by configure 12*8e33eff8Schristos #endif 13*8e33eff8Schristos 14*8e33eff8Schristos 15*8e33eff8Schristos BIT_UTIL_INLINE unsigned 16*8e33eff8Schristos ffs_llu(unsigned long long bitmap) { 17*8e33eff8Schristos return JEMALLOC_INTERNAL_FFSLL(bitmap); 18*8e33eff8Schristos } 19*8e33eff8Schristos 20*8e33eff8Schristos BIT_UTIL_INLINE unsigned 21*8e33eff8Schristos ffs_lu(unsigned long bitmap) { 22*8e33eff8Schristos return JEMALLOC_INTERNAL_FFSL(bitmap); 23*8e33eff8Schristos } 24*8e33eff8Schristos 25*8e33eff8Schristos BIT_UTIL_INLINE unsigned 26*8e33eff8Schristos ffs_u(unsigned bitmap) { 27*8e33eff8Schristos return JEMALLOC_INTERNAL_FFS(bitmap); 28*8e33eff8Schristos } 29*8e33eff8Schristos 30*8e33eff8Schristos BIT_UTIL_INLINE unsigned 31*8e33eff8Schristos ffs_zu(size_t bitmap) { 32*8e33eff8Schristos #if LG_SIZEOF_PTR == LG_SIZEOF_INT 33*8e33eff8Schristos return ffs_u(bitmap); 34*8e33eff8Schristos #elif LG_SIZEOF_PTR == LG_SIZEOF_LONG 35*8e33eff8Schristos return ffs_lu(bitmap); 36*8e33eff8Schristos #elif LG_SIZEOF_PTR == LG_SIZEOF_LONG_LONG 37*8e33eff8Schristos return ffs_llu(bitmap); 38*8e33eff8Schristos #else 39*8e33eff8Schristos #error No implementation for size_t ffs() 40*8e33eff8Schristos #endif 41*8e33eff8Schristos } 42*8e33eff8Schristos 43*8e33eff8Schristos BIT_UTIL_INLINE unsigned 44*8e33eff8Schristos ffs_u64(uint64_t bitmap) { 45*8e33eff8Schristos #if LG_SIZEOF_LONG == 3 46*8e33eff8Schristos return ffs_lu(bitmap); 47*8e33eff8Schristos #elif LG_SIZEOF_LONG_LONG == 3 48*8e33eff8Schristos return ffs_llu(bitmap); 49*8e33eff8Schristos #else 50*8e33eff8Schristos #error No implementation for 64-bit ffs() 51*8e33eff8Schristos #endif 52*8e33eff8Schristos } 53*8e33eff8Schristos 54*8e33eff8Schristos BIT_UTIL_INLINE unsigned 55*8e33eff8Schristos ffs_u32(uint32_t bitmap) { 56*8e33eff8Schristos #if LG_SIZEOF_INT == 2 57*8e33eff8Schristos return ffs_u(bitmap); 58*8e33eff8Schristos #else 59*8e33eff8Schristos #error No implementation for 32-bit ffs() 60*8e33eff8Schristos #endif 61*8e33eff8Schristos } 62*8e33eff8Schristos 63*8e33eff8Schristos BIT_UTIL_INLINE uint64_t 64*8e33eff8Schristos pow2_ceil_u64(uint64_t x) { 65*8e33eff8Schristos x--; 66*8e33eff8Schristos x |= x >> 1; 67*8e33eff8Schristos x |= x >> 2; 68*8e33eff8Schristos x |= x >> 4; 69*8e33eff8Schristos x |= x >> 8; 70*8e33eff8Schristos x |= x >> 16; 71*8e33eff8Schristos x |= x >> 32; 72*8e33eff8Schristos x++; 73*8e33eff8Schristos return x; 74*8e33eff8Schristos } 75*8e33eff8Schristos 76*8e33eff8Schristos BIT_UTIL_INLINE uint32_t 77*8e33eff8Schristos pow2_ceil_u32(uint32_t x) { 78*8e33eff8Schristos x--; 79*8e33eff8Schristos x |= x >> 1; 80*8e33eff8Schristos x |= x >> 2; 81*8e33eff8Schristos x |= x >> 4; 82*8e33eff8Schristos x |= x >> 8; 83*8e33eff8Schristos x |= x >> 16; 84*8e33eff8Schristos x++; 85*8e33eff8Schristos return x; 86*8e33eff8Schristos } 87*8e33eff8Schristos 88*8e33eff8Schristos /* Compute the smallest power of 2 that is >= x. */ 89*8e33eff8Schristos BIT_UTIL_INLINE size_t 90*8e33eff8Schristos pow2_ceil_zu(size_t x) { 91*8e33eff8Schristos #if (LG_SIZEOF_PTR == 3) 92*8e33eff8Schristos return pow2_ceil_u64(x); 93*8e33eff8Schristos #else 94*8e33eff8Schristos return pow2_ceil_u32(x); 95*8e33eff8Schristos #endif 96*8e33eff8Schristos } 97*8e33eff8Schristos 98*8e33eff8Schristos #if (defined(__i386__) || defined(__amd64__) || defined(__x86_64__)) 99*8e33eff8Schristos BIT_UTIL_INLINE unsigned 100*8e33eff8Schristos lg_floor(size_t x) { 101*8e33eff8Schristos size_t ret; 102*8e33eff8Schristos assert(x != 0); 103*8e33eff8Schristos 104*8e33eff8Schristos asm ("bsr %1, %0" 105*8e33eff8Schristos : "=r"(ret) // Outputs. 106*8e33eff8Schristos : "r"(x) // Inputs. 107*8e33eff8Schristos ); 108*8e33eff8Schristos assert(ret < UINT_MAX); 109*8e33eff8Schristos return (unsigned)ret; 110*8e33eff8Schristos } 111*8e33eff8Schristos #elif (defined(_MSC_VER)) 112*8e33eff8Schristos BIT_UTIL_INLINE unsigned 113*8e33eff8Schristos lg_floor(size_t x) { 114*8e33eff8Schristos unsigned long ret; 115*8e33eff8Schristos 116*8e33eff8Schristos assert(x != 0); 117*8e33eff8Schristos 118*8e33eff8Schristos #if (LG_SIZEOF_PTR == 3) 119*8e33eff8Schristos _BitScanReverse64(&ret, x); 120*8e33eff8Schristos #elif (LG_SIZEOF_PTR == 2) 121*8e33eff8Schristos _BitScanReverse(&ret, x); 122*8e33eff8Schristos #else 123*8e33eff8Schristos # error "Unsupported type size for lg_floor()" 124*8e33eff8Schristos #endif 125*8e33eff8Schristos assert(ret < UINT_MAX); 126*8e33eff8Schristos return (unsigned)ret; 127*8e33eff8Schristos } 128*8e33eff8Schristos #elif (defined(JEMALLOC_HAVE_BUILTIN_CLZ)) 129*8e33eff8Schristos BIT_UTIL_INLINE unsigned 130*8e33eff8Schristos lg_floor(size_t x) { 131*8e33eff8Schristos assert(x != 0); 132*8e33eff8Schristos 133*8e33eff8Schristos #if (LG_SIZEOF_PTR == LG_SIZEOF_INT) 134*8e33eff8Schristos return ((8 << LG_SIZEOF_PTR) - 1) - __builtin_clz(x); 135*8e33eff8Schristos #elif (LG_SIZEOF_PTR == LG_SIZEOF_LONG) 136*8e33eff8Schristos return ((8 << LG_SIZEOF_PTR) - 1) - __builtin_clzl(x); 137*8e33eff8Schristos #else 138*8e33eff8Schristos # error "Unsupported type size for lg_floor()" 139*8e33eff8Schristos #endif 140*8e33eff8Schristos } 141*8e33eff8Schristos #else 142*8e33eff8Schristos BIT_UTIL_INLINE unsigned 143*8e33eff8Schristos lg_floor(size_t x) { 144*8e33eff8Schristos assert(x != 0); 145*8e33eff8Schristos 146*8e33eff8Schristos x |= (x >> 1); 147*8e33eff8Schristos x |= (x >> 2); 148*8e33eff8Schristos x |= (x >> 4); 149*8e33eff8Schristos x |= (x >> 8); 150*8e33eff8Schristos x |= (x >> 16); 151*8e33eff8Schristos #if (LG_SIZEOF_PTR == 3) 152*8e33eff8Schristos x |= (x >> 32); 153*8e33eff8Schristos #endif 154*8e33eff8Schristos if (x == SIZE_T_MAX) { 155*8e33eff8Schristos return (8 << LG_SIZEOF_PTR) - 1; 156*8e33eff8Schristos } 157*8e33eff8Schristos x++; 158*8e33eff8Schristos return ffs_zu(x) - 2; 159*8e33eff8Schristos } 160*8e33eff8Schristos #endif 161*8e33eff8Schristos 162*8e33eff8Schristos #undef BIT_UTIL_INLINE 163*8e33eff8Schristos 164*8e33eff8Schristos #endif /* JEMALLOC_INTERNAL_BIT_UTIL_H */ 165