diff options
Diffstat (limited to 'lib/hweight.c')
| -rw-r--r-- | lib/hweight.c | 10 |
1 files changed, 8 insertions, 2 deletions
diff --git a/lib/hweight.c b/lib/hweight.c index 438257671708..360556a7803d 100644 --- a/lib/hweight.c +++ b/lib/hweight.c | |||
| @@ -1,5 +1,6 @@ | |||
| 1 | #include <linux/module.h> | 1 | #include <linux/module.h> |
| 2 | #include <asm/types.h> | 2 | #include <asm/types.h> |
| 3 | #include <asm/bitops.h> | ||
| 3 | 4 | ||
| 4 | /** | 5 | /** |
| 5 | * hweightN - returns the hamming weight of a N-bit word | 6 | * hweightN - returns the hamming weight of a N-bit word |
| @@ -40,14 +41,19 @@ unsigned long hweight64(__u64 w) | |||
| 40 | #if BITS_PER_LONG == 32 | 41 | #if BITS_PER_LONG == 32 |
| 41 | return hweight32((unsigned int)(w >> 32)) + hweight32((unsigned int)w); | 42 | return hweight32((unsigned int)(w >> 32)) + hweight32((unsigned int)w); |
| 42 | #elif BITS_PER_LONG == 64 | 43 | #elif BITS_PER_LONG == 64 |
| 44 | #ifdef ARCH_HAS_FAST_MULTIPLIER | ||
| 45 | w -= (w >> 1) & 0x5555555555555555ul; | ||
| 46 | w = (w & 0x3333333333333333ul) + ((w >> 2) & 0x3333333333333333ul); | ||
| 47 | w = (w + (w >> 4)) & 0x0f0f0f0f0f0f0f0ful; | ||
| 48 | return (w * 0x0101010101010101ul) >> 56; | ||
| 49 | #else | ||
| 43 | __u64 res = w - ((w >> 1) & 0x5555555555555555ul); | 50 | __u64 res = w - ((w >> 1) & 0x5555555555555555ul); |
| 44 | res = (res & 0x3333333333333333ul) + ((res >> 2) & 0x3333333333333333ul); | 51 | res = (res & 0x3333333333333333ul) + ((res >> 2) & 0x3333333333333333ul); |
| 45 | res = (res + (res >> 4)) & 0x0F0F0F0F0F0F0F0Ful; | 52 | res = (res + (res >> 4)) & 0x0F0F0F0F0F0F0F0Ful; |
| 46 | res = res + (res >> 8); | 53 | res = res + (res >> 8); |
| 47 | res = res + (res >> 16); | 54 | res = res + (res >> 16); |
| 48 | return (res + (res >> 32)) & 0x00000000000000FFul; | 55 | return (res + (res >> 32)) & 0x00000000000000FFul; |
| 49 | #else | 56 | #endif |
| 50 | #error BITS_PER_LONG not defined | ||
| 51 | #endif | 57 | #endif |
| 52 | } | 58 | } |
| 53 | EXPORT_SYMBOL(hweight64); | 59 | EXPORT_SYMBOL(hweight64); |
