diff options
-rw-r--r-- | arch/frv/Kconfig | 4 | ||||
-rw-r--r-- | include/asm-frv/bitops.h | 170 |
2 files changed, 13 insertions, 161 deletions
diff --git a/arch/frv/Kconfig b/arch/frv/Kconfig index e08383712370..95a3892b8d1b 100644 --- a/arch/frv/Kconfig +++ b/arch/frv/Kconfig | |||
@@ -17,6 +17,10 @@ config GENERIC_FIND_NEXT_BIT | |||
17 | bool | 17 | bool |
18 | default y | 18 | default y |
19 | 19 | ||
20 | config GENERIC_HWEIGHT | ||
21 | bool | ||
22 | default y | ||
23 | |||
20 | config GENERIC_CALIBRATE_DELAY | 24 | config GENERIC_CALIBRATE_DELAY |
21 | bool | 25 | bool |
22 | default n | 26 | default n |
diff --git a/include/asm-frv/bitops.h b/include/asm-frv/bitops.h index 9c5db5c34c1b..6344d06390b9 100644 --- a/include/asm-frv/bitops.h +++ b/include/asm-frv/bitops.h | |||
@@ -22,20 +22,7 @@ | |||
22 | 22 | ||
23 | #ifdef __KERNEL__ | 23 | #ifdef __KERNEL__ |
24 | 24 | ||
25 | /* | 25 | #include <asm-generic/bitops/ffz.h> |
26 | * ffz = Find First Zero in word. Undefined if no zero exists, | ||
27 | * so code should check against ~0UL first.. | ||
28 | */ | ||
29 | static inline unsigned long ffz(unsigned long word) | ||
30 | { | ||
31 | unsigned long result = 0; | ||
32 | |||
33 | while (word & 1) { | ||
34 | result++; | ||
35 | word >>= 1; | ||
36 | } | ||
37 | return result; | ||
38 | } | ||
39 | 26 | ||
40 | /* | 27 | /* |
41 | * clear_bit() doesn't provide any barrier for the compiler. | 28 | * clear_bit() doesn't provide any barrier for the compiler. |
@@ -171,51 +158,9 @@ static inline int __test_bit(int nr, const volatile void * addr) | |||
171 | __constant_test_bit((nr),(addr)) : \ | 158 | __constant_test_bit((nr),(addr)) : \ |
172 | __test_bit((nr),(addr))) | 159 | __test_bit((nr),(addr))) |
173 | 160 | ||
174 | extern int find_next_bit(const unsigned long *addr, int size, int offset); | 161 | #include <asm-generic/bitops/ffs.h> |
175 | 162 | #include <asm-generic/bitops/__ffs.h> | |
176 | #define find_first_bit(addr, size) find_next_bit(addr, size, 0) | 163 | #include <asm-generic/bitops/find.h> |
177 | |||
178 | #define find_first_zero_bit(addr, size) \ | ||
179 | find_next_zero_bit((addr), (size), 0) | ||
180 | |||
181 | static inline int find_next_zero_bit(const void *addr, int size, int offset) | ||
182 | { | ||
183 | const unsigned long *p = ((const unsigned long *) addr) + (offset >> 5); | ||
184 | unsigned long result = offset & ~31UL; | ||
185 | unsigned long tmp; | ||
186 | |||
187 | if (offset >= size) | ||
188 | return size; | ||
189 | size -= result; | ||
190 | offset &= 31UL; | ||
191 | if (offset) { | ||
192 | tmp = *(p++); | ||
193 | tmp |= ~0UL >> (32-offset); | ||
194 | if (size < 32) | ||
195 | goto found_first; | ||
196 | if (~tmp) | ||
197 | goto found_middle; | ||
198 | size -= 32; | ||
199 | result += 32; | ||
200 | } | ||
201 | while (size & ~31UL) { | ||
202 | if (~(tmp = *(p++))) | ||
203 | goto found_middle; | ||
204 | result += 32; | ||
205 | size -= 32; | ||
206 | } | ||
207 | if (!size) | ||
208 | return result; | ||
209 | tmp = *p; | ||
210 | |||
211 | found_first: | ||
212 | tmp |= ~0UL << size; | ||
213 | found_middle: | ||
214 | return result + ffz(tmp); | ||
215 | } | ||
216 | |||
217 | #define ffs(x) generic_ffs(x) | ||
218 | #define __ffs(x) (ffs(x) - 1) | ||
219 | 164 | ||
220 | /* | 165 | /* |
221 | * fls: find last bit set. | 166 | * fls: find last bit set. |
@@ -228,114 +173,17 @@ found_middle: | |||
228 | \ | 173 | \ |
229 | bit ? 33 - bit : bit; \ | 174 | bit ? 33 - bit : bit; \ |
230 | }) | 175 | }) |
231 | #define fls64(x) generic_fls64(x) | ||
232 | 176 | ||
233 | /* | 177 | #include <asm-generic/bitops/fls64.h> |
234 | * Every architecture must define this function. It's the fastest | 178 | #include <asm-generic/bitops/sched.h> |
235 | * way of searching a 140-bit bitmap where the first 100 bits are | 179 | #include <asm-generic/bitops/hweight.h> |
236 | * unlikely to be set. It's guaranteed that at least one of the 140 | ||
237 | * bits is cleared. | ||
238 | */ | ||
239 | static inline int sched_find_first_bit(const unsigned long *b) | ||
240 | { | ||
241 | if (unlikely(b[0])) | ||
242 | return __ffs(b[0]); | ||
243 | if (unlikely(b[1])) | ||
244 | return __ffs(b[1]) + 32; | ||
245 | if (unlikely(b[2])) | ||
246 | return __ffs(b[2]) + 64; | ||
247 | if (b[3]) | ||
248 | return __ffs(b[3]) + 96; | ||
249 | return __ffs(b[4]) + 128; | ||
250 | } | ||
251 | 180 | ||
252 | 181 | #include <asm-generic/bitops/ext2-non-atomic.h> | |
253 | /* | ||
254 | * hweightN: returns the hamming weight (i.e. the number | ||
255 | * of bits set) of a N-bit word | ||
256 | */ | ||
257 | |||
258 | #define hweight32(x) generic_hweight32(x) | ||
259 | #define hweight16(x) generic_hweight16(x) | ||
260 | #define hweight8(x) generic_hweight8(x) | ||
261 | |||
262 | #define ext2_set_bit(nr, addr) __test_and_set_bit ((nr) ^ 0x18, (addr)) | ||
263 | #define ext2_clear_bit(nr, addr) __test_and_clear_bit((nr) ^ 0x18, (addr)) | ||
264 | 182 | ||
265 | #define ext2_set_bit_atomic(lock,nr,addr) test_and_set_bit ((nr) ^ 0x18, (addr)) | 183 | #define ext2_set_bit_atomic(lock,nr,addr) test_and_set_bit ((nr) ^ 0x18, (addr)) |
266 | #define ext2_clear_bit_atomic(lock,nr,addr) test_and_clear_bit((nr) ^ 0x18, (addr)) | 184 | #define ext2_clear_bit_atomic(lock,nr,addr) test_and_clear_bit((nr) ^ 0x18, (addr)) |
267 | 185 | ||
268 | static inline int ext2_test_bit(int nr, const volatile void * addr) | 186 | #include <asm-generic/bitops/minix-le.h> |
269 | { | ||
270 | const volatile unsigned char *ADDR = (const unsigned char *) addr; | ||
271 | int mask; | ||
272 | |||
273 | ADDR += nr >> 3; | ||
274 | mask = 1 << (nr & 0x07); | ||
275 | return ((mask & *ADDR) != 0); | ||
276 | } | ||
277 | |||
278 | #define ext2_find_first_zero_bit(addr, size) \ | ||
279 | ext2_find_next_zero_bit((addr), (size), 0) | ||
280 | |||
281 | static inline unsigned long ext2_find_next_zero_bit(const void *addr, | ||
282 | unsigned long size, | ||
283 | unsigned long offset) | ||
284 | { | ||
285 | const unsigned long *p = ((const unsigned long *) addr) + (offset >> 5); | ||
286 | unsigned long result = offset & ~31UL; | ||
287 | unsigned long tmp; | ||
288 | |||
289 | if (offset >= size) | ||
290 | return size; | ||
291 | size -= result; | ||
292 | offset &= 31UL; | ||
293 | if(offset) { | ||
294 | /* We hold the little endian value in tmp, but then the | ||
295 | * shift is illegal. So we could keep a big endian value | ||
296 | * in tmp, like this: | ||
297 | * | ||
298 | * tmp = __swab32(*(p++)); | ||
299 | * tmp |= ~0UL >> (32-offset); | ||
300 | * | ||
301 | * but this would decrease preformance, so we change the | ||
302 | * shift: | ||
303 | */ | ||
304 | tmp = *(p++); | ||
305 | tmp |= __swab32(~0UL >> (32-offset)); | ||
306 | if(size < 32) | ||
307 | goto found_first; | ||
308 | if(~tmp) | ||
309 | goto found_middle; | ||
310 | size -= 32; | ||
311 | result += 32; | ||
312 | } | ||
313 | while(size & ~31UL) { | ||
314 | if(~(tmp = *(p++))) | ||
315 | goto found_middle; | ||
316 | result += 32; | ||
317 | size -= 32; | ||
318 | } | ||
319 | if(!size) | ||
320 | return result; | ||
321 | tmp = *p; | ||
322 | |||
323 | found_first: | ||
324 | /* tmp is little endian, so we would have to swab the shift, | ||
325 | * see above. But then we have to swab tmp below for ffz, so | ||
326 | * we might as well do this here. | ||
327 | */ | ||
328 | return result + ffz(__swab32(tmp) | (~0UL << size)); | ||
329 | found_middle: | ||
330 | return result + ffz(__swab32(tmp)); | ||
331 | } | ||
332 | |||
333 | /* Bitmap functions for the minix filesystem. */ | ||
334 | #define minix_test_and_set_bit(nr,addr) __test_and_set_bit ((nr) ^ 0x18, (addr)) | ||
335 | #define minix_set_bit(nr,addr) __set_bit((nr) ^ 0x18, (addr)) | ||
336 | #define minix_test_and_clear_bit(nr,addr) __test_and_clear_bit((nr) ^ 0x18, (addr)) | ||
337 | #define minix_test_bit(nr,addr) ext2_test_bit(nr,addr) | ||
338 | #define minix_find_first_zero_bit(addr,size) ext2_find_first_zero_bit(addr,size) | ||
339 | 187 | ||
340 | #endif /* __KERNEL__ */ | 188 | #endif /* __KERNEL__ */ |
341 | 189 | ||