diff options
Diffstat (limited to 'tools/lib/hweight.c')
-rw-r--r-- | tools/lib/hweight.c | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/tools/lib/hweight.c b/tools/lib/hweight.c new file mode 100644 index 000000000000..0b859b884339 --- /dev/null +++ b/tools/lib/hweight.c | |||
@@ -0,0 +1,62 @@ | |||
1 | #include <linux/bitops.h> | ||
2 | #include <asm/types.h> | ||
3 | |||
4 | /** | ||
5 | * hweightN - returns the hamming weight of a N-bit word | ||
6 | * @x: the word to weigh | ||
7 | * | ||
8 | * The Hamming Weight of a number is the total number of bits set in it. | ||
9 | */ | ||
10 | |||
11 | unsigned int __sw_hweight32(unsigned int w) | ||
12 | { | ||
13 | #ifdef CONFIG_ARCH_HAS_FAST_MULTIPLIER | ||
14 | w -= (w >> 1) & 0x55555555; | ||
15 | w = (w & 0x33333333) + ((w >> 2) & 0x33333333); | ||
16 | w = (w + (w >> 4)) & 0x0f0f0f0f; | ||
17 | return (w * 0x01010101) >> 24; | ||
18 | #else | ||
19 | unsigned int res = w - ((w >> 1) & 0x55555555); | ||
20 | res = (res & 0x33333333) + ((res >> 2) & 0x33333333); | ||
21 | res = (res + (res >> 4)) & 0x0F0F0F0F; | ||
22 | res = res + (res >> 8); | ||
23 | return (res + (res >> 16)) & 0x000000FF; | ||
24 | #endif | ||
25 | } | ||
26 | |||
27 | unsigned int __sw_hweight16(unsigned int w) | ||
28 | { | ||
29 | unsigned int res = w - ((w >> 1) & 0x5555); | ||
30 | res = (res & 0x3333) + ((res >> 2) & 0x3333); | ||
31 | res = (res + (res >> 4)) & 0x0F0F; | ||
32 | return (res + (res >> 8)) & 0x00FF; | ||
33 | } | ||
34 | |||
35 | unsigned int __sw_hweight8(unsigned int w) | ||
36 | { | ||
37 | unsigned int res = w - ((w >> 1) & 0x55); | ||
38 | res = (res & 0x33) + ((res >> 2) & 0x33); | ||
39 | return (res + (res >> 4)) & 0x0F; | ||
40 | } | ||
41 | |||
42 | unsigned long __sw_hweight64(__u64 w) | ||
43 | { | ||
44 | #if BITS_PER_LONG == 32 | ||
45 | return __sw_hweight32((unsigned int)(w >> 32)) + | ||
46 | __sw_hweight32((unsigned int)w); | ||
47 | #elif BITS_PER_LONG == 64 | ||
48 | #ifdef CONFIG_ARCH_HAS_FAST_MULTIPLIER | ||
49 | w -= (w >> 1) & 0x5555555555555555ul; | ||
50 | w = (w & 0x3333333333333333ul) + ((w >> 2) & 0x3333333333333333ul); | ||
51 | w = (w + (w >> 4)) & 0x0f0f0f0f0f0f0f0ful; | ||
52 | return (w * 0x0101010101010101ul) >> 56; | ||
53 | #else | ||
54 | __u64 res = w - ((w >> 1) & 0x5555555555555555ul); | ||
55 | res = (res & 0x3333333333333333ul) + ((res >> 2) & 0x3333333333333333ul); | ||
56 | res = (res + (res >> 4)) & 0x0F0F0F0F0F0F0F0Ful; | ||
57 | res = res + (res >> 8); | ||
58 | res = res + (res >> 16); | ||
59 | return (res + (res >> 32)) & 0x00000000000000FFul; | ||
60 | #endif | ||
61 | #endif | ||
62 | } | ||