1#ifndef _I386_BITOPS_H
2#define _I386_BITOPS_H
3
4
5
6
7
8#include <linux/config.h>
9#include <linux/compiler.h>
10
11
12
13
14
15
16
17
18
19#ifdef CONFIG_SMP
20#define LOCK_PREFIX "lock ; "
21#else
22#define LOCK_PREFIX ""
23#endif
24
25#define ADDR (*(volatile long *) addr)
26
27
28
29
30
31
32
33
34
35
36
37static inline void set_bit(int nr, volatile unsigned long * addr)
38{
39 __asm__ __volatile__( LOCK_PREFIX
40 "btsl %1,%0"
41 :"=m" (ADDR)
42 :"Ir" (nr));
43}
44
45
46
47
48
49
50
51
52
53
54static inline void __set_bit(int nr, volatile unsigned long * addr)
55{
56 __asm__(
57 "btsl %1,%0"
58 :"=m" (ADDR)
59 :"Ir" (nr));
60}
61
62
63
64
65
66
67
68
69
70
71
72static inline void clear_bit(int nr, volatile unsigned long * addr)
73{
74 __asm__ __volatile__( LOCK_PREFIX
75 "btrl %1,%0"
76 :"=m" (ADDR)
77 :"Ir" (nr));
78}
79
80static inline void __clear_bit(int nr, volatile unsigned long * addr)
81{
82 __asm__ __volatile__(
83 "btrl %1,%0"
84 :"=m" (ADDR)
85 :"Ir" (nr));
86}
87#define smp_mb__before_clear_bit() barrier()
88#define smp_mb__after_clear_bit() barrier()
89
90
91
92
93
94
95
96
97
98
99static inline void __change_bit(int nr, volatile unsigned long * addr)
100{
101 __asm__ __volatile__(
102 "btcl %1,%0"
103 :"=m" (ADDR)
104 :"Ir" (nr));
105}
106
107
108
109
110
111
112
113
114
115
116static inline void change_bit(int nr, volatile unsigned long * addr)
117{
118 __asm__ __volatile__( LOCK_PREFIX
119 "btcl %1,%0"
120 :"=m" (ADDR)
121 :"Ir" (nr));
122}
123
124
125
126
127
128
129
130
131
132static inline int test_and_set_bit(int nr, volatile unsigned long * addr)
133{
134 int oldbit;
135
136 __asm__ __volatile__( LOCK_PREFIX
137 "btsl %2,%1\n\tsbbl %0,%0"
138 :"=r" (oldbit),"=m" (ADDR)
139 :"Ir" (nr) : "memory");
140 return oldbit;
141}
142
143
144
145
146
147
148
149
150
151
152static inline int __test_and_set_bit(int nr, volatile unsigned long * addr)
153{
154 int oldbit;
155
156 __asm__(
157 "btsl %2,%1\n\tsbbl %0,%0"
158 :"=r" (oldbit),"=m" (ADDR)
159 :"Ir" (nr));
160 return oldbit;
161}
162
163
164
165
166
167
168
169
170
171static inline int test_and_clear_bit(int nr, volatile unsigned long * addr)
172{
173 int oldbit;
174
175 __asm__ __volatile__( LOCK_PREFIX
176 "btrl %2,%1\n\tsbbl %0,%0"
177 :"=r" (oldbit),"=m" (ADDR)
178 :"Ir" (nr) : "memory");
179 return oldbit;
180}
181
182
183
184
185
186
187
188
189
190
191static inline int __test_and_clear_bit(int nr, volatile unsigned long *addr)
192{
193 int oldbit;
194
195 __asm__(
196 "btrl %2,%1\n\tsbbl %0,%0"
197 :"=r" (oldbit),"=m" (ADDR)
198 :"Ir" (nr));
199 return oldbit;
200}
201
202
203static inline int __test_and_change_bit(int nr, volatile unsigned long *addr)
204{
205 int oldbit;
206
207 __asm__ __volatile__(
208 "btcl %2,%1\n\tsbbl %0,%0"
209 :"=r" (oldbit),"=m" (ADDR)
210 :"Ir" (nr) : "memory");
211 return oldbit;
212}
213
214
215
216
217
218
219
220
221
222static inline int test_and_change_bit(int nr, volatile unsigned long* addr)
223{
224 int oldbit;
225
226 __asm__ __volatile__( LOCK_PREFIX
227 "btcl %2,%1\n\tsbbl %0,%0"
228 :"=r" (oldbit),"=m" (ADDR)
229 :"Ir" (nr) : "memory");
230 return oldbit;
231}
232
233#if 0
234
235
236
237
238
239static int test_bit(int nr, const volatile void * addr);
240#endif
241
242static inline int constant_test_bit(int nr, const volatile unsigned long *addr)
243{
244 return ((1UL << (nr & 31)) & (addr[nr >> 5])) != 0;
245}
246
247static inline int variable_test_bit(int nr, const volatile unsigned long * addr)
248{
249 int oldbit;
250
251 __asm__ __volatile__(
252 "btl %2,%1\n\tsbbl %0,%0"
253 :"=r" (oldbit)
254 :"m" (ADDR),"Ir" (nr));
255 return oldbit;
256}
257
258#define test_bit(nr,addr) \
259(__builtin_constant_p(nr) ? \
260 constant_test_bit((nr),(addr)) : \
261 variable_test_bit((nr),(addr)))
262
263#undef ADDR
264
265
266
267
268
269
270
271
272
273static inline int find_first_zero_bit(const unsigned long *addr, unsigned size)
274{
275 int d0, d1, d2;
276 int res;
277
278 if (!size)
279 return 0;
280
281 __asm__ __volatile__(
282 "movl $-1,%%eax\n\t"
283 "xorl %%edx,%%edx\n\t"
284 "repe; scasl\n\t"
285 "je 1f\n\t"
286 "xorl -4(%%edi),%%eax\n\t"
287 "subl $4,%%edi\n\t"
288 "bsfl %%eax,%%edx\n"
289 "1:\tsubl %%ebx,%%edi\n\t"
290 "shll $3,%%edi\n\t"
291 "addl %%edi,%%edx"
292 :"=d" (res), "=&c" (d0), "=&D" (d1), "=&a" (d2)
293 :"1" ((size + 31) >> 5), "2" (addr), "b" (addr) : "memory");
294 return res;
295}
296
297
298
299
300
301
302
303int find_next_zero_bit(const unsigned long *addr, int size, int offset);
304
305
306
307
308
309
310
311
312
313static inline int find_first_bit(const unsigned long *addr, unsigned size)
314{
315 int d0, d1;
316 int res;
317
318
319 __asm__ __volatile__(
320 "xorl %%eax,%%eax\n\t"
321 "repe; scasl\n\t"
322 "jz 1f\n\t"
323 "leal -4(%%edi),%%edi\n\t"
324 "bsfl (%%edi),%%eax\n"
325 "1:\tsubl %%ebx,%%edi\n\t"
326 "shll $3,%%edi\n\t"
327 "addl %%edi,%%eax"
328 :"=a" (res), "=&c" (d0), "=&D" (d1)
329 :"1" ((size + 31) >> 5), "2" (addr), "b" (addr) : "memory");
330 return res;
331}
332
333
334
335
336
337
338
339int find_next_bit(const unsigned long *addr, int size, int offset);
340
341
342
343
344
345
346
347static inline unsigned long ffz(unsigned long word)
348{
349 __asm__("bsfl %1,%0"
350 :"=r" (word)
351 :"r" (~word));
352 return word;
353}
354
355
356
357
358
359
360
361static inline unsigned long __ffs(unsigned long word)
362{
363 __asm__("bsfl %1,%0"
364 :"=r" (word)
365 :"rm" (word));
366 return word;
367}
368
369
370
371
372
373#define fls(x) generic_fls(x)
374
375#ifdef __KERNEL__
376
377
378
379
380
381
382
383static inline int sched_find_first_bit(const unsigned long *b)
384{
385 if (unlikely(b[0]))
386 return __ffs(b[0]);
387 if (unlikely(b[1]))
388 return __ffs(b[1]) + 32;
389 if (unlikely(b[2]))
390 return __ffs(b[2]) + 64;
391 if (b[3])
392 return __ffs(b[3]) + 96;
393 return __ffs(b[4]) + 128;
394}
395
396
397
398
399
400
401
402
403
404static inline int ffs(int x)
405{
406 int r;
407
408 __asm__("bsfl %1,%0\n\t"
409 "jnz 1f\n\t"
410 "movl $-1,%0\n"
411 "1:" : "=r" (r) : "rm" (x));
412 return r+1;
413}
414
415
416
417
418
419
420
421
422#define hweight32(x) generic_hweight32(x)
423#define hweight16(x) generic_hweight16(x)
424#define hweight8(x) generic_hweight8(x)
425
426#endif
427
428#ifdef __KERNEL__
429
430#define ext2_set_bit(nr,addr) \
431 __test_and_set_bit((nr),(unsigned long*)addr)
432#define ext2_set_bit_atomic(lock,nr,addr) \
433 test_and_set_bit((nr),(unsigned long*)addr)
434#define ext2_clear_bit(nr, addr) \
435 __test_and_clear_bit((nr),(unsigned long*)addr)
436#define ext2_clear_bit_atomic(lock,nr, addr) \
437 test_and_clear_bit((nr),(unsigned long*)addr)
438#define ext2_test_bit(nr, addr) test_bit((nr),(unsigned long*)addr)
439#define ext2_find_first_zero_bit(addr, size) \
440 find_first_zero_bit((unsigned long*)addr, size)
441#define ext2_find_next_zero_bit(addr, size, off) \
442 find_next_zero_bit((unsigned long*)addr, size, off)
443
444
445#define minix_test_and_set_bit(nr,addr) __test_and_set_bit(nr,(void*)addr)
446#define minix_set_bit(nr,addr) __set_bit(nr,(void*)addr)
447#define minix_test_and_clear_bit(nr,addr) __test_and_clear_bit(nr,(void*)addr)
448#define minix_test_bit(nr,addr) test_bit(nr,(void*)addr)
449#define minix_find_first_zero_bit(addr,size) \
450 find_first_zero_bit((void*)addr,size)
451
452#endif
453
454#endif
455