104 lines
3.0 KiB
C
104 lines
3.0 KiB
C
/*
|
|
* 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__ */
|