/* * 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__ */