Linux-2.6.12-rc2
[linux-2.6.git] / arch / ia64 / lib / bitop.c
1 #include <linux/compiler.h>
2 #include <linux/types.h>
3 #include <asm/intrinsics.h>
4 #include <linux/module.h>
5 #include <linux/bitops.h>
6
7 /*
8  * Find next zero bit in a bitmap reasonably efficiently..
9  */
10
11 int __find_next_zero_bit (const void *addr, unsigned long size, unsigned long offset)
12 {
13         unsigned long *p = ((unsigned long *) addr) + (offset >> 6);
14         unsigned long result = offset & ~63UL;
15         unsigned long tmp;
16
17         if (offset >= size)
18                 return size;
19         size -= result;
20         offset &= 63UL;
21         if (offset) {
22                 tmp = *(p++);
23                 tmp |= ~0UL >> (64-offset);
24                 if (size < 64)
25                         goto found_first;
26                 if (~tmp)
27                         goto found_middle;
28                 size -= 64;
29                 result += 64;
30         }
31         while (size & ~63UL) {
32                 if (~(tmp = *(p++)))
33                         goto found_middle;
34                 result += 64;
35                 size -= 64;
36         }
37         if (!size)
38                 return result;
39         tmp = *p;
40 found_first:
41         tmp |= ~0UL << size;
42         if (tmp == ~0UL)                /* any bits zero? */
43                 return result + size;   /* nope */
44 found_middle:
45         return result + ffz(tmp);
46 }
47 EXPORT_SYMBOL(__find_next_zero_bit);
48
49 /*
50  * Find next bit in a bitmap reasonably efficiently..
51  */
52 int __find_next_bit(const void *addr, unsigned long size, unsigned long offset)
53 {
54         unsigned long *p = ((unsigned long *) addr) + (offset >> 6);
55         unsigned long result = offset & ~63UL;
56         unsigned long tmp;
57
58         if (offset >= size)
59                 return size;
60         size -= result;
61         offset &= 63UL;
62         if (offset) {
63                 tmp = *(p++);
64                 tmp &= ~0UL << offset;
65                 if (size < 64)
66                         goto found_first;
67                 if (tmp)
68                         goto found_middle;
69                 size -= 64;
70                 result += 64;
71         }
72         while (size & ~63UL) {
73                 if ((tmp = *(p++)))
74                         goto found_middle;
75                 result += 64;
76                 size -= 64;
77         }
78         if (!size)
79                 return result;
80         tmp = *p;
81   found_first:
82         tmp &= ~0UL >> (64-size);
83         if (tmp == 0UL)         /* Are any bits set? */
84                 return result + size; /* Nope. */
85   found_middle:
86         return result + __ffs(tmp);
87 }
88 EXPORT_SYMBOL(__find_next_bit);