diff options
Diffstat (limited to 'include/linux/bitops.h')
-rw-r--r-- | include/linux/bitops.h | 159 |
1 files changed, 159 insertions, 0 deletions
diff --git a/include/linux/bitops.h b/include/linux/bitops.h new file mode 100644 index 000000000000..cb3c3ef50f50 --- /dev/null +++ b/include/linux/bitops.h | |||
@@ -0,0 +1,159 @@ | |||
1 | #ifndef _LINUX_BITOPS_H | ||
2 | #define _LINUX_BITOPS_H | ||
3 | #include <asm/types.h> | ||
4 | |||
5 | /* | ||
6 | * ffs: find first bit set. This is defined the same way as | ||
7 | * the libc and compiler builtin ffs routines, therefore | ||
8 | * differs in spirit from the above ffz (man ffs). | ||
9 | */ | ||
10 | |||
11 | static inline int generic_ffs(int x) | ||
12 | { | ||
13 | int r = 1; | ||
14 | |||
15 | if (!x) | ||
16 | return 0; | ||
17 | if (!(x & 0xffff)) { | ||
18 | x >>= 16; | ||
19 | r += 16; | ||
20 | } | ||
21 | if (!(x & 0xff)) { | ||
22 | x >>= 8; | ||
23 | r += 8; | ||
24 | } | ||
25 | if (!(x & 0xf)) { | ||
26 | x >>= 4; | ||
27 | r += 4; | ||
28 | } | ||
29 | if (!(x & 3)) { | ||
30 | x >>= 2; | ||
31 | r += 2; | ||
32 | } | ||
33 | if (!(x & 1)) { | ||
34 | x >>= 1; | ||
35 | r += 1; | ||
36 | } | ||
37 | return r; | ||
38 | } | ||
39 | |||
40 | /* | ||
41 | * fls: find last bit set. | ||
42 | */ | ||
43 | |||
44 | static __inline__ int generic_fls(int x) | ||
45 | { | ||
46 | int r = 32; | ||
47 | |||
48 | if (!x) | ||
49 | return 0; | ||
50 | if (!(x & 0xffff0000u)) { | ||
51 | x <<= 16; | ||
52 | r -= 16; | ||
53 | } | ||
54 | if (!(x & 0xff000000u)) { | ||
55 | x <<= 8; | ||
56 | r -= 8; | ||
57 | } | ||
58 | if (!(x & 0xf0000000u)) { | ||
59 | x <<= 4; | ||
60 | r -= 4; | ||
61 | } | ||
62 | if (!(x & 0xc0000000u)) { | ||
63 | x <<= 2; | ||
64 | r -= 2; | ||
65 | } | ||
66 | if (!(x & 0x80000000u)) { | ||
67 | x <<= 1; | ||
68 | r -= 1; | ||
69 | } | ||
70 | return r; | ||
71 | } | ||
72 | |||
73 | /* | ||
74 | * Include this here because some architectures need generic_ffs/fls in | ||
75 | * scope | ||
76 | */ | ||
77 | #include <asm/bitops.h> | ||
78 | |||
79 | static __inline__ int get_bitmask_order(unsigned int count) | ||
80 | { | ||
81 | int order; | ||
82 | |||
83 | order = fls(count); | ||
84 | return order; /* We could be slightly more clever with -1 here... */ | ||
85 | } | ||
86 | |||
87 | /* | ||
88 | * hweightN: returns the hamming weight (i.e. the number | ||
89 | * of bits set) of a N-bit word | ||
90 | */ | ||
91 | |||
92 | static inline unsigned int generic_hweight32(unsigned int w) | ||
93 | { | ||
94 | unsigned int res = (w & 0x55555555) + ((w >> 1) & 0x55555555); | ||
95 | res = (res & 0x33333333) + ((res >> 2) & 0x33333333); | ||
96 | res = (res & 0x0F0F0F0F) + ((res >> 4) & 0x0F0F0F0F); | ||
97 | res = (res & 0x00FF00FF) + ((res >> 8) & 0x00FF00FF); | ||
98 | return (res & 0x0000FFFF) + ((res >> 16) & 0x0000FFFF); | ||
99 | } | ||
100 | |||
101 | static inline unsigned int generic_hweight16(unsigned int w) | ||
102 | { | ||
103 | unsigned int res = (w & 0x5555) + ((w >> 1) & 0x5555); | ||
104 | res = (res & 0x3333) + ((res >> 2) & 0x3333); | ||
105 | res = (res & 0x0F0F) + ((res >> 4) & 0x0F0F); | ||
106 | return (res & 0x00FF) + ((res >> 8) & 0x00FF); | ||
107 | } | ||
108 | |||
109 | static inline unsigned int generic_hweight8(unsigned int w) | ||
110 | { | ||
111 | unsigned int res = (w & 0x55) + ((w >> 1) & 0x55); | ||
112 | res = (res & 0x33) + ((res >> 2) & 0x33); | ||
113 | return (res & 0x0F) + ((res >> 4) & 0x0F); | ||
114 | } | ||
115 | |||
116 | static inline unsigned long generic_hweight64(__u64 w) | ||
117 | { | ||
118 | #if BITS_PER_LONG < 64 | ||
119 | return generic_hweight32((unsigned int)(w >> 32)) + | ||
120 | generic_hweight32((unsigned int)w); | ||
121 | #else | ||
122 | u64 res; | ||
123 | res = (w & 0x5555555555555555ul) + ((w >> 1) & 0x5555555555555555ul); | ||
124 | res = (res & 0x3333333333333333ul) + ((res >> 2) & 0x3333333333333333ul); | ||
125 | res = (res & 0x0F0F0F0F0F0F0F0Ful) + ((res >> 4) & 0x0F0F0F0F0F0F0F0Ful); | ||
126 | res = (res & 0x00FF00FF00FF00FFul) + ((res >> 8) & 0x00FF00FF00FF00FFul); | ||
127 | res = (res & 0x0000FFFF0000FFFFul) + ((res >> 16) & 0x0000FFFF0000FFFFul); | ||
128 | return (res & 0x00000000FFFFFFFFul) + ((res >> 32) & 0x00000000FFFFFFFFul); | ||
129 | #endif | ||
130 | } | ||
131 | |||
132 | static inline unsigned long hweight_long(unsigned long w) | ||
133 | { | ||
134 | return sizeof(w) == 4 ? generic_hweight32(w) : generic_hweight64(w); | ||
135 | } | ||
136 | |||
137 | /* | ||
138 | * rol32 - rotate a 32-bit value left | ||
139 | * | ||
140 | * @word: value to rotate | ||
141 | * @shift: bits to roll | ||
142 | */ | ||
143 | static inline __u32 rol32(__u32 word, unsigned int shift) | ||
144 | { | ||
145 | return (word << shift) | (word >> (32 - shift)); | ||
146 | } | ||
147 | |||
148 | /* | ||
149 | * ror32 - rotate a 32-bit value right | ||
150 | * | ||
151 | * @word: value to rotate | ||
152 | * @shift: bits to roll | ||
153 | */ | ||
154 | static inline __u32 ror32(__u32 word, unsigned int shift) | ||
155 | { | ||
156 | return (word >> shift) | (word << (32 - shift)); | ||
157 | } | ||
158 | |||
159 | #endif | ||