]>
Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | #include <linux/bitops.h> |
2 | #include <linux/module.h> | |
3 | ||
4 | /** | |
5 | * find_next_bit - find the first set bit in a memory region | |
6 | * @addr: The address to base the search on | |
7 | * @offset: The bitnumber to start searching at | |
8 | * @size: The maximum size to search | |
9 | */ | |
10 | int find_next_bit(const unsigned long *addr, int size, int offset) | |
11 | { | |
12 | const unsigned long *p = addr + (offset >> 5); | |
13 | int set = 0, bit = offset & 31, res; | |
14 | ||
15 | if (bit) { | |
16 | /* | |
17 | * Look for nonzero in the first 32 bits: | |
18 | */ | |
19 | __asm__("bsfl %1,%0\n\t" | |
20 | "jne 1f\n\t" | |
21 | "movl $32, %0\n" | |
22 | "1:" | |
23 | : "=r" (set) | |
24 | : "r" (*p >> bit)); | |
25 | if (set < (32 - bit)) | |
26 | return set + offset; | |
27 | set = 32 - bit; | |
28 | p++; | |
29 | } | |
30 | /* | |
31 | * No set bit yet, search remaining full words for a bit | |
32 | */ | |
33 | res = find_first_bit (p, size - 32 * (p - addr)); | |
34 | return (offset + set + res); | |
35 | } | |
36 | EXPORT_SYMBOL(find_next_bit); | |
37 | ||
38 | /** | |
39 | * find_next_zero_bit - find the first zero bit in a memory region | |
40 | * @addr: The address to base the search on | |
41 | * @offset: The bitnumber to start searching at | |
42 | * @size: The maximum size to search | |
43 | */ | |
44 | int find_next_zero_bit(const unsigned long *addr, int size, int offset) | |
45 | { | |
46 | unsigned long * p = ((unsigned long *) addr) + (offset >> 5); | |
47 | int set = 0, bit = offset & 31, res; | |
48 | ||
49 | if (bit) { | |
50 | /* | |
51 | * Look for zero in the first 32 bits. | |
52 | */ | |
53 | __asm__("bsfl %1,%0\n\t" | |
54 | "jne 1f\n\t" | |
55 | "movl $32, %0\n" | |
56 | "1:" | |
57 | : "=r" (set) | |
58 | : "r" (~(*p >> bit))); | |
59 | if (set < (32 - bit)) | |
60 | return set + offset; | |
61 | set = 32 - bit; | |
62 | p++; | |
63 | } | |
64 | /* | |
65 | * No zero yet, search remaining full bytes for a zero | |
66 | */ | |
67 | res = find_first_zero_bit (p, size - 32 * (p - (unsigned long *) addr)); | |
68 | return (offset + set + res); | |
69 | } | |
70 | EXPORT_SYMBOL(find_next_zero_bit); |