blob: 96f1f657fdf8bca3e4253421b1e7948495705365 [file] [log] [blame]
/*
* bitops.h : macros and functions for bit operations.
* (C) 2002 - Willy Tarreau - willy@ant-computing.com
*
*/
#ifndef __BITOPS_H__
#define __BITOPS_H__
/* how many bits are needed to code the size of an int (eg: 32bits -> 5) */
#define LONGSHIFT 5
#define LLONGSHIFT 6
#define LONGBITS 32
#define LLONGBITS 64
/* very fast FFS function : returns the position of the lowest 1 */
#define __ffs_fast32(___a) ({ \
register int ___x, ___bits = 32; \
if (___a) { \
___x = (___a); \
___bits--; \
if (___x & 0x0000ffff) { ___x &= 0x0000ffff; ___bits -= 16;} \
if (___x & 0x00ff00ff) { ___x &= 0x00ff00ff; ___bits -= 8;} \
if (___x & 0x0f0f0f0f) { ___x &= 0x0f0f0f0f; ___bits -= 4;} \
if (___x & 0x33333333) { ___x &= 0x33333333; ___bits -= 2;} \
if (___x & 0x55555555) { ___x &= 0x55555555; ___bits -= 1;} \
}\
___bits; \
})
/* very fast FLS function : returns the position of the highest 1 */
#define __fls_fast32(___a) ({ \
register int ___x, ___bits = 0; \
if (___a) { \
___x = (___a); \
if (___x & 0xffff0000) { ___x &= 0xffff0000; ___bits += 16;} \
if (___x & 0xff00ff00) { ___x &= 0xff00ff00; ___bits += 8;} \
if (___x & 0xf0f0f0f0) { ___x &= 0xf0f0f0f0; ___bits += 4;} \
if (___x & 0xcccccccc) { ___x &= 0xcccccccc; ___bits += 2;} \
if (___x & 0xaaaaaaaa) { ___x &= 0xaaaaaaaa; ___bits += 1;} \
} else { \
___bits = 32; \
} \
___bits; \
})
/* very fast FFS function working on 64 bits */
#define __ffs_fast64(___a) ({ \
register int ___bits = 64; \
register unsigned long ___x = ((___a) >> 32); \
if ((___a) & 0xffffffffUL) { \
___x = (___a) & 0xffffffffUL; \
___bits -= 32; \
} \
if (___x) { \
___bits--; \
if (___x & 0x0000ffff) { ___x &= 0x0000ffff; ___bits -= 16;} \
if (___x & 0x00ff00ff) { ___x &= 0x00ff00ff; ___bits -= 8;} \
if (___x & 0x0f0f0f0f) { ___x &= 0x0f0f0f0f; ___bits -= 4;} \
if (___x & 0x33333333) { ___x &= 0x33333333; ___bits -= 2;} \
if (___x & 0x55555555) { ___x &= 0x55555555; ___bits -= 1;} \
}\
___bits; \
})
/* very fast FLS function working on 64 bits */
#define __fls_fast64(___a) ({ \
register int ___bits = 0; \
register unsigned long ___x = (___a); \
if (((unsigned long long)(___a)) >> 32) { \
___x = ((unsigned long long)(___a)) >> 32; \
___bits += 32; \
} \
if (___x) { \
if (___x & 0xffff0000) { ___x &= 0xffff0000; ___bits += 16;} \
if (___x & 0xff00ff00) { ___x &= 0xff00ff00; ___bits += 8;} \
if (___x & 0xf0f0f0f0) { ___x &= 0xf0f0f0f0; ___bits += 4;} \
if (___x & 0xcccccccc) { ___x &= 0xcccccccc; ___bits += 2;} \
if (___x & 0xaaaaaaaa) { ___x &= 0xaaaaaaaa; ___bits += 1;} \
} else { \
___bits += 32; \
} \
___bits; \
})
static int ffs_fast32(register unsigned long a) {
return __ffs_fast32(a);
}
static int fls_fast32(unsigned long a) {
return __fls_fast32(a);
}
static int ffs_fast64(unsigned long long a) {
return __ffs_fast64(a);
}
static int fls_fast64(unsigned long long a) {
return __fls_fast64(a);
}
#endif /* __BITOPS_H__ */