Linux-2.6.12-rc2
[linux-2.6.git] / arch / i386 / lib / bitops.c
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);