* added 0.99 linux version
[mascara-docs.git] / i386 / linux / linux-2.3.21 / include / asm-sh / bitops.h
blob9808789c75bcec76bf5eb3de46a71b3f02043734
1 #ifndef __ASM_SH_BITOPS_H
2 #define __ASM_SH_BITOPS_H
4 #ifdef __KERNEL__
5 #include <asm/system.h>
6 /* For __swab32 */
7 #include <asm/byteorder.h>
9 extern __inline__ void set_bit(int nr, void * addr)
11 int mask;
12 unsigned int *a = addr;
13 unsigned long flags;
15 a += nr >> 5;
16 mask = 1 << (nr & 0x1f);
17 save_flags(flags);
18 cli();
19 *a |= mask;
20 restore_flags(flags);
23 extern __inline__ void clear_bit(int nr, void * addr)
25 int mask;
26 unsigned int *a = addr;
27 unsigned long flags;
29 a += nr >> 5;
30 mask = 1 << (nr & 0x1f);
31 save_flags(flags);
32 cli();
33 *a &= ~mask;
34 restore_flags(flags);
37 extern __inline__ void change_bit(int nr, void * addr)
39 int mask;
40 unsigned int *a = addr;
41 unsigned long flags;
43 a += nr >> 5;
44 mask = 1 << (nr & 0x1f);
45 save_flags(flags);
46 cli();
47 *a ^= mask;
48 restore_flags(flags);
51 extern __inline__ int test_and_set_bit(int nr, void * addr)
53 int mask, retval;
54 unsigned int *a = addr;
55 unsigned long flags;
57 a += nr >> 5;
58 mask = 1 << (nr & 0x1f);
59 save_flags(flags);
60 cli();
61 retval = (mask & *a) != 0;
62 *a |= mask;
63 restore_flags(flags);
65 return retval;
68 extern __inline__ int test_and_clear_bit(int nr, void * addr)
70 int mask, retval;
71 unsigned int *a = addr;
72 unsigned long flags;
74 a += nr >> 5;
75 mask = 1 << (nr & 0x1f);
76 save_flags(flags);
77 cli();
78 retval = (mask & *a) != 0;
79 *a &= ~mask;
80 restore_flags(flags);
82 return retval;
85 extern __inline__ int test_and_change_bit(int nr, void * addr)
87 int mask, retval;
88 unsigned int *a = addr;
89 unsigned long flags;
91 a += nr >> 5;
92 mask = 1 << (nr & 0x1f);
93 save_flags(flags);
94 cli();
95 retval = (mask & *a) != 0;
96 *a ^= mask;
97 restore_flags(flags);
99 return retval;
103 extern __inline__ int test_bit(int nr, const void *addr)
105 return 1UL & (((const int *) addr)[nr >> 5] >> (nr & 31));
108 extern __inline__ unsigned long ffz(unsigned long word)
110 unsigned long result;
112 __asm__("1:\n"
113 "shlr %1\n\t"
114 "bt/s 1b\n\t"
115 "add #1, %0"
116 : "=r" (result)
117 : "r" (word), "0" (~0L));
118 return result;
121 extern __inline__ int find_next_zero_bit(void *addr, int size, int offset)
123 unsigned long *p = ((unsigned long *) addr) + (offset >> 5);
124 unsigned long result = offset & ~31UL;
125 unsigned long tmp;
127 if (offset >= size)
128 return size;
129 size -= result;
130 offset &= 31UL;
131 if (offset) {
132 tmp = *(p++);
133 tmp |= ~0UL >> (32-offset);
134 if (size < 32)
135 goto found_first;
136 if (~tmp)
137 goto found_middle;
138 size -= 32;
139 result += 32;
141 while (size & ~31UL) {
142 if (~(tmp = *(p++)))
143 goto found_middle;
144 result += 32;
145 size -= 32;
147 if (!size)
148 return result;
149 tmp = *p;
151 found_first:
152 tmp |= ~0UL << size;
153 found_middle:
154 return result + ffz(tmp);
157 #define find_first_zero_bit(addr, size) \
158 find_next_zero_bit((addr), (size), 0)
160 extern __inline__ int ext2_set_bit(int nr,void * addr)
162 int mask, retval;
163 unsigned long flags;
164 unsigned char *ADDR = (unsigned char *) addr;
166 ADDR += nr >> 3;
167 mask = 1 << (nr & 0x07);
168 save_flags(flags); cli();
169 retval = (mask & *ADDR) != 0;
170 *ADDR |= mask;
171 restore_flags(flags);
172 return retval;
175 extern __inline__ int ext2_clear_bit(int nr, void * addr)
177 int mask, retval;
178 unsigned long flags;
179 unsigned char *ADDR = (unsigned char *) addr;
181 ADDR += nr >> 3;
182 mask = 1 << (nr & 0x07);
183 save_flags(flags); cli();
184 retval = (mask & *ADDR) != 0;
185 *ADDR &= ~mask;
186 restore_flags(flags);
187 return retval;
190 extern __inline__ int ext2_test_bit(int nr, const void * addr)
192 int mask;
193 const unsigned char *ADDR = (const unsigned char *) addr;
195 ADDR += nr >> 3;
196 mask = 1 << (nr & 0x07);
197 return ((mask & *ADDR) != 0);
200 #define ext2_find_first_zero_bit(addr, size) \
201 ext2_find_next_zero_bit((addr), (size), 0)
203 extern __inline__ unsigned long ext2_find_next_zero_bit(void *addr, unsigned long size, unsigned long offset)
205 unsigned long *p = ((unsigned long *) addr) + (offset >> 5);
206 unsigned long result = offset & ~31UL;
207 unsigned long tmp;
209 if (offset >= size)
210 return size;
211 size -= result;
212 offset &= 31UL;
213 if(offset) {
214 /* We hold the little endian value in tmp, but then the
215 * shift is illegal. So we could keep a big endian value
216 * in tmp, like this:
218 * tmp = __swab32(*(p++));
219 * tmp |= ~0UL >> (32-offset);
221 * but this would decrease preformance, so we change the
222 * shift:
224 tmp = *(p++);
225 tmp |= __swab32(~0UL >> (32-offset));
226 if(size < 32)
227 goto found_first;
228 if(~tmp)
229 goto found_middle;
230 size -= 32;
231 result += 32;
233 while(size & ~31UL) {
234 if(~(tmp = *(p++)))
235 goto found_middle;
236 result += 32;
237 size -= 32;
239 if(!size)
240 return result;
241 tmp = *p;
243 found_first:
244 /* tmp is little endian, so we would have to swab the shift,
245 * see above. But then we have to swab tmp below for ffz, so
246 * we might as well do this here.
248 return result + ffz(__swab32(tmp) | (~0UL << size));
249 found_middle:
250 return result + ffz(__swab32(tmp));
253 /* Bitmap functions for the minix filesystem. */
254 #define minix_set_bit(nr,addr) test_and_set_bit(nr,addr)
255 #define minix_clear_bit(nr,addr) test_and_clear_bit(nr,addr)
256 #define minix_test_bit(nr,addr) test_bit(nr,addr)
257 #define minix_find_first_zero_bit(addr,size) find_first_zero_bit(addr,size)
259 #endif /* __KERNEL__ */
261 #endif /* __ASM_SH_BITOPS_H */