Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | #ifndef _I386_BITOPS_H |
2 | #define _I386_BITOPS_H | |
3 | ||
4 | /* | |
5 | * Copyright 1992, Linus Torvalds. | |
6 | */ | |
7 | ||
1da177e4 LT |
8 | /** |
9 | * find_first_zero_bit - find the first zero bit in a memory region | |
10 | * @addr: The address to start the search at | |
11 | * @size: The maximum size to search | |
12 | * | |
ec12fa5c | 13 | * Returns the bit number of the first zero bit, not the number of the byte |
1da177e4 LT |
14 | * containing a bit. |
15 | */ | |
16 | static inline int find_first_zero_bit(const unsigned long *addr, unsigned size) | |
17 | { | |
18 | int d0, d1, d2; | |
19 | int res; | |
20 | ||
21 | if (!size) | |
22 | return 0; | |
fd591acd JP |
23 | /* This looks at memory. |
24 | * Mark it volatile to tell gcc not to move it around | |
25 | */ | |
26 | asm volatile("movl $-1,%%eax\n\t" | |
27 | "xorl %%edx,%%edx\n\t" | |
28 | "repe; scasl\n\t" | |
29 | "je 1f\n\t" | |
30 | "xorl -4(%%edi),%%eax\n\t" | |
31 | "subl $4,%%edi\n\t" | |
32 | "bsfl %%eax,%%edx\n" | |
33 | "1:\tsubl %%ebx,%%edi\n\t" | |
34 | "shll $3,%%edi\n\t" | |
35 | "addl %%edi,%%edx" | |
36 | : "=d" (res), "=&c" (d0), "=&D" (d1), "=&a" (d2) | |
37 | : "1" ((size + 31) >> 5), "2" (addr), | |
38 | "b" (addr) : "memory"); | |
1da177e4 LT |
39 | return res; |
40 | } | |
41 | ||
cd85c8b4 SR |
42 | /** |
43 | * __ffs - find first bit in word. | |
44 | * @word: The word to search | |
45 | * | |
46 | * Undefined if no bit exists, so code should check against 0 first. | |
47 | */ | |
48 | static inline unsigned long __ffs(unsigned long word) | |
49 | { | |
50 | __asm__("bsfl %1,%0" | |
51 | :"=r" (word) | |
52 | :"rm" (word)); | |
53 | return word; | |
54 | } | |
55 | ||
1da177e4 LT |
56 | /** |
57 | * find_first_bit - find the first set bit in a memory region | |
58 | * @addr: The address to start the search at | |
59 | * @size: The maximum size to search | |
60 | * | |
ec12fa5c | 61 | * Returns the bit number of the first set bit, not the number of the byte |
1da177e4 LT |
62 | * containing a bit. |
63 | */ | |
d89c145c | 64 | static inline unsigned find_first_bit(const unsigned long *addr, unsigned size) |
1da177e4 | 65 | { |
d89c145c | 66 | unsigned x = 0; |
d6d2a2ab LT |
67 | |
68 | while (x < size) { | |
69 | unsigned long val = *addr++; | |
70 | if (val) | |
71 | return __ffs(val) + x; | |
fd591acd | 72 | x += sizeof(*addr) << 3; |
d6d2a2ab | 73 | } |
cd85c8b4 | 74 | return x; |
1da177e4 LT |
75 | } |
76 | ||
1da177e4 LT |
77 | /** |
78 | * ffz - find first zero in word. | |
79 | * @word: The word to search | |
80 | * | |
81 | * Undefined if no zero exists, so code should check against ~0UL first. | |
82 | */ | |
83 | static inline unsigned long ffz(unsigned long word) | |
84 | { | |
85 | __asm__("bsfl %1,%0" | |
86 | :"=r" (word) | |
87 | :"r" (~word)); | |
88 | return word; | |
89 | } | |
90 | ||
1da177e4 LT |
91 | #ifdef __KERNEL__ |
92 | ||
1cc2b994 | 93 | #include <asm-generic/bitops/sched.h> |
1da177e4 LT |
94 | |
95 | /** | |
96 | * ffs - find first bit set | |
97 | * @x: the word to search | |
98 | * | |
99 | * This is defined the same way as | |
100 | * the libc and compiler builtin ffs routines, therefore | |
72fd4a35 | 101 | * differs in spirit from the above ffz() (man ffs). |
1da177e4 LT |
102 | */ |
103 | static inline int ffs(int x) | |
104 | { | |
105 | int r; | |
106 | ||
107 | __asm__("bsfl %1,%0\n\t" | |
108 | "jnz 1f\n\t" | |
109 | "movl $-1,%0\n" | |
110 | "1:" : "=r" (r) : "rm" (x)); | |
111 | return r+1; | |
112 | } | |
113 | ||
d832245d SH |
114 | /** |
115 | * fls - find last bit set | |
116 | * @x: the word to search | |
117 | * | |
72fd4a35 | 118 | * This is defined the same way as ffs(). |
d832245d SH |
119 | */ |
120 | static inline int fls(int x) | |
121 | { | |
122 | int r; | |
123 | ||
124 | __asm__("bsrl %1,%0\n\t" | |
125 | "jnz 1f\n\t" | |
126 | "movl $-1,%0\n" | |
127 | "1:" : "=r" (r) : "rm" (x)); | |
128 | return r+1; | |
129 | } | |
130 | ||
1cc2b994 | 131 | #include <asm-generic/bitops/hweight.h> |
1da177e4 LT |
132 | |
133 | #endif /* __KERNEL__ */ | |
134 | ||
1cc2b994 AM |
135 | #include <asm-generic/bitops/fls64.h> |
136 | ||
1da177e4 LT |
137 | #ifdef __KERNEL__ |
138 | ||
1cc2b994 AM |
139 | #include <asm-generic/bitops/ext2-non-atomic.h> |
140 | ||
fd591acd JP |
141 | #define ext2_set_bit_atomic(lock, nr, addr) \ |
142 | test_and_set_bit((nr), (unsigned long *)(addr)) | |
143 | #define ext2_clear_bit_atomic(lock, nr, addr) \ | |
144 | test_and_clear_bit((nr), (unsigned long *)(addr)) | |
1cc2b994 AM |
145 | |
146 | #include <asm-generic/bitops/minix.h> | |
1da177e4 LT |
147 | |
148 | #endif /* __KERNEL__ */ | |
149 | ||
150 | #endif /* _I386_BITOPS_H */ |