Merge branch 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux...
[linux-2.6] / include / asm-x86 / bitops_64.h
1 #ifndef _X86_64_BITOPS_H
2 #define _X86_64_BITOPS_H
3
4 /*
5  * Copyright 1992, Linus Torvalds.
6  */
7
8 #ifndef _LINUX_BITOPS_H
9 #error only <linux/bitops.h> can be included directly
10 #endif
11
12 #include <asm/alternative.h>
13
14 #if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 1)
15 /* Technically wrong, but this avoids compilation errors on some gcc
16    versions. */
17 #define ADDR "=m" (*(volatile long *) addr)
18 #else
19 #define ADDR "+m" (*(volatile long *) addr)
20 #endif
21
22 /**
23  * set_bit - Atomically set a bit in memory
24  * @nr: the bit to set
25  * @addr: the address to start counting from
26  *
27  * This function is atomic and may not be reordered.  See __set_bit()
28  * if you do not require the atomic guarantees.
29  * Note that @nr may be almost arbitrarily large; this function is not
30  * restricted to acting on a single-word quantity.
31  */
32 static __inline__ void set_bit(int nr, volatile void * addr)
33 {
34         __asm__ __volatile__( LOCK_PREFIX
35                 "btsl %1,%0"
36                 :ADDR
37                 :"dIr" (nr) : "memory");
38 }
39
40 /**
41  * __set_bit - Set a bit in memory
42  * @nr: the bit to set
43  * @addr: the address to start counting from
44  *
45  * Unlike set_bit(), this function is non-atomic and may be reordered.
46  * If it's called on the same region of memory simultaneously, the effect
47  * may be that only one operation succeeds.
48  */
49 static __inline__ void __set_bit(int nr, volatile void * addr)
50 {
51         __asm__ volatile(
52                 "btsl %1,%0"
53                 :ADDR
54                 :"dIr" (nr) : "memory");
55 }
56
57 /**
58  * clear_bit - Clears a bit in memory
59  * @nr: Bit to clear
60  * @addr: Address to start counting from
61  *
62  * clear_bit() is atomic and may not be reordered.  However, it does
63  * not contain a memory barrier, so if it is used for locking purposes,
64  * you should call smp_mb__before_clear_bit() and/or smp_mb__after_clear_bit()
65  * in order to ensure changes are visible on other processors.
66  */
67 static __inline__ void clear_bit(int nr, volatile void * addr)
68 {
69         __asm__ __volatile__( LOCK_PREFIX
70                 "btrl %1,%0"
71                 :ADDR
72                 :"dIr" (nr));
73 }
74
75 static __inline__ void __clear_bit(int nr, volatile void * addr)
76 {
77         __asm__ __volatile__(
78                 "btrl %1,%0"
79                 :ADDR
80                 :"dIr" (nr));
81 }
82
83 #define smp_mb__before_clear_bit()      barrier()
84 #define smp_mb__after_clear_bit()       barrier()
85
86 /**
87  * __change_bit - Toggle a bit in memory
88  * @nr: the bit to change
89  * @addr: the address to start counting from
90  *
91  * Unlike change_bit(), this function is non-atomic and may be reordered.
92  * If it's called on the same region of memory simultaneously, the effect
93  * may be that only one operation succeeds.
94  */
95 static __inline__ void __change_bit(int nr, volatile void * addr)
96 {
97         __asm__ __volatile__(
98                 "btcl %1,%0"
99                 :ADDR
100                 :"dIr" (nr));
101 }
102
103 /**
104  * change_bit - Toggle a bit in memory
105  * @nr: Bit to change
106  * @addr: Address to start counting from
107  *
108  * change_bit() is atomic and may not be reordered.
109  * Note that @nr may be almost arbitrarily large; this function is not
110  * restricted to acting on a single-word quantity.
111  */
112 static __inline__ void change_bit(int nr, volatile void * addr)
113 {
114         __asm__ __volatile__( LOCK_PREFIX
115                 "btcl %1,%0"
116                 :ADDR
117                 :"dIr" (nr));
118 }
119
120 /**
121  * test_and_set_bit - Set a bit and return its old value
122  * @nr: Bit to set
123  * @addr: Address to count from
124  *
125  * This operation is atomic and cannot be reordered.  
126  * It also implies a memory barrier.
127  */
128 static __inline__ int test_and_set_bit(int nr, volatile void * addr)
129 {
130         int oldbit;
131
132         __asm__ __volatile__( LOCK_PREFIX
133                 "btsl %2,%1\n\tsbbl %0,%0"
134                 :"=r" (oldbit),ADDR
135                 :"dIr" (nr) : "memory");
136         return oldbit;
137 }
138
139 /**
140  * __test_and_set_bit - Set a bit and return its old value
141  * @nr: Bit to set
142  * @addr: Address to count from
143  *
144  * This operation is non-atomic and can be reordered.  
145  * If two examples of this operation race, one can appear to succeed
146  * but actually fail.  You must protect multiple accesses with a lock.
147  */
148 static __inline__ int __test_and_set_bit(int nr, volatile void * addr)
149 {
150         int oldbit;
151
152         __asm__(
153                 "btsl %2,%1\n\tsbbl %0,%0"
154                 :"=r" (oldbit),ADDR
155                 :"dIr" (nr));
156         return oldbit;
157 }
158
159 /**
160  * test_and_clear_bit - Clear a bit and return its old value
161  * @nr: Bit to clear
162  * @addr: Address to count from
163  *
164  * This operation is atomic and cannot be reordered.  
165  * It also implies a memory barrier.
166  */
167 static __inline__ int test_and_clear_bit(int nr, volatile void * addr)
168 {
169         int oldbit;
170
171         __asm__ __volatile__( LOCK_PREFIX
172                 "btrl %2,%1\n\tsbbl %0,%0"
173                 :"=r" (oldbit),ADDR
174                 :"dIr" (nr) : "memory");
175         return oldbit;
176 }
177
178 /**
179  * __test_and_clear_bit - Clear a bit and return its old value
180  * @nr: Bit to clear
181  * @addr: Address to count from
182  *
183  * This operation is non-atomic and can be reordered.  
184  * If two examples of this operation race, one can appear to succeed
185  * but actually fail.  You must protect multiple accesses with a lock.
186  */
187 static __inline__ int __test_and_clear_bit(int nr, volatile void * addr)
188 {
189         int oldbit;
190
191         __asm__(
192                 "btrl %2,%1\n\tsbbl %0,%0"
193                 :"=r" (oldbit),ADDR
194                 :"dIr" (nr));
195         return oldbit;
196 }
197
198 /* WARNING: non atomic and it can be reordered! */
199 static __inline__ int __test_and_change_bit(int nr, volatile void * addr)
200 {
201         int oldbit;
202
203         __asm__ __volatile__(
204                 "btcl %2,%1\n\tsbbl %0,%0"
205                 :"=r" (oldbit),ADDR
206                 :"dIr" (nr) : "memory");
207         return oldbit;
208 }
209
210 /**
211  * test_and_change_bit - Change a bit and return its old value
212  * @nr: Bit to change
213  * @addr: Address to count from
214  *
215  * This operation is atomic and cannot be reordered.  
216  * It also implies a memory barrier.
217  */
218 static __inline__ int test_and_change_bit(int nr, volatile void * addr)
219 {
220         int oldbit;
221
222         __asm__ __volatile__( LOCK_PREFIX
223                 "btcl %2,%1\n\tsbbl %0,%0"
224                 :"=r" (oldbit),ADDR
225                 :"dIr" (nr) : "memory");
226         return oldbit;
227 }
228
229 #if 0 /* Fool kernel-doc since it doesn't do macros yet */
230 /**
231  * test_bit - Determine whether a bit is set
232  * @nr: bit number to test
233  * @addr: Address to start counting from
234  */
235 static int test_bit(int nr, const volatile void * addr);
236 #endif
237
238 static __inline__ int constant_test_bit(int nr, const volatile void * addr)
239 {
240         return ((1UL << (nr & 31)) & (((const volatile unsigned int *) addr)[nr >> 5])) != 0;
241 }
242
243 static __inline__ int variable_test_bit(int nr, volatile const void * addr)
244 {
245         int oldbit;
246
247         __asm__ __volatile__(
248                 "btl %2,%1\n\tsbbl %0,%0"
249                 :"=r" (oldbit)
250                 :"m" (*(volatile long *)addr),"dIr" (nr));
251         return oldbit;
252 }
253
254 #define test_bit(nr,addr) \
255 (__builtin_constant_p(nr) ? \
256  constant_test_bit((nr),(addr)) : \
257  variable_test_bit((nr),(addr)))
258
259 #undef ADDR
260
261 extern long find_first_zero_bit(const unsigned long * addr, unsigned long size);
262 extern long find_next_zero_bit (const unsigned long * addr, long size, long offset);
263 extern long find_first_bit(const unsigned long * addr, unsigned long size);
264 extern long find_next_bit(const unsigned long * addr, long size, long offset);
265
266 /* return index of first bet set in val or max when no bit is set */
267 static inline long __scanbit(unsigned long val, unsigned long max)
268 {
269         asm("bsfq %1,%0 ; cmovz %2,%0" : "=&r" (val) : "r" (val), "r" (max));
270         return val;
271 }
272
273 #define find_first_bit(addr,size) \
274 ((__builtin_constant_p(size) && (size) <= BITS_PER_LONG ? \
275   (__scanbit(*(unsigned long *)addr,(size))) : \
276   find_first_bit(addr,size)))
277
278 #define find_next_bit(addr,size,off) \
279 ((__builtin_constant_p(size) && (size) <= BITS_PER_LONG ?         \
280   ((off) + (__scanbit((*(unsigned long *)addr) >> (off),(size)-(off)))) : \
281         find_next_bit(addr,size,off)))
282
283 #define find_first_zero_bit(addr,size) \
284 ((__builtin_constant_p(size) && (size) <= BITS_PER_LONG ? \
285   (__scanbit(~*(unsigned long *)addr,(size))) : \
286         find_first_zero_bit(addr,size)))
287         
288 #define find_next_zero_bit(addr,size,off) \
289 ((__builtin_constant_p(size) && (size) <= BITS_PER_LONG ?         \
290   ((off)+(__scanbit(~(((*(unsigned long *)addr)) >> (off)),(size)-(off)))) : \
291         find_next_zero_bit(addr,size,off)))
292
293 /* 
294  * Find string of zero bits in a bitmap. -1 when not found.
295  */ 
296 extern unsigned long 
297 find_next_zero_string(unsigned long *bitmap, long start, long nbits, int len);
298
299 static inline void set_bit_string(unsigned long *bitmap, unsigned long i, 
300                                   int len) 
301
302         unsigned long end = i + len; 
303         while (i < end) {
304                 __set_bit(i, bitmap); 
305                 i++;
306         }
307
308
309 static inline void __clear_bit_string(unsigned long *bitmap, unsigned long i, 
310                                     int len) 
311
312         unsigned long end = i + len; 
313         while (i < end) {
314                 __clear_bit(i, bitmap); 
315                 i++;
316         }
317
318
319 /**
320  * ffz - find first zero in word.
321  * @word: The word to search
322  *
323  * Undefined if no zero exists, so code should check against ~0UL first.
324  */
325 static __inline__ unsigned long ffz(unsigned long word)
326 {
327         __asm__("bsfq %1,%0"
328                 :"=r" (word)
329                 :"r" (~word));
330         return word;
331 }
332
333 /**
334  * __ffs - find first bit in word.
335  * @word: The word to search
336  *
337  * Undefined if no bit exists, so code should check against 0 first.
338  */
339 static __inline__ unsigned long __ffs(unsigned long word)
340 {
341         __asm__("bsfq %1,%0"
342                 :"=r" (word)
343                 :"rm" (word));
344         return word;
345 }
346
347 /*
348  * __fls: find last bit set.
349  * @word: The word to search
350  *
351  * Undefined if no zero exists, so code should check against ~0UL first.
352  */
353 static __inline__ unsigned long __fls(unsigned long word)
354 {
355         __asm__("bsrq %1,%0"
356                 :"=r" (word)
357                 :"rm" (word));
358         return word;
359 }
360
361 #ifdef __KERNEL__
362
363 #include <asm-generic/bitops/sched.h>
364
365 /**
366  * ffs - find first bit set
367  * @x: the word to search
368  *
369  * This is defined the same way as
370  * the libc and compiler builtin ffs routines, therefore
371  * differs in spirit from the above ffz (man ffs).
372  */
373 static __inline__ int ffs(int x)
374 {
375         int r;
376
377         __asm__("bsfl %1,%0\n\t"
378                 "cmovzl %2,%0" 
379                 : "=r" (r) : "rm" (x), "r" (-1));
380         return r+1;
381 }
382
383 /**
384  * fls64 - find last bit set in 64 bit word
385  * @x: the word to search
386  *
387  * This is defined the same way as fls.
388  */
389 static __inline__ int fls64(__u64 x)
390 {
391         if (x == 0)
392                 return 0;
393         return __fls(x) + 1;
394 }
395
396 /**
397  * fls - find last bit set
398  * @x: the word to search
399  *
400  * This is defined the same way as ffs.
401  */
402 static __inline__ int fls(int x)
403 {
404         int r;
405
406         __asm__("bsrl %1,%0\n\t"
407                 "cmovzl %2,%0"
408                 : "=&r" (r) : "rm" (x), "rm" (-1));
409         return r+1;
410 }
411
412 #define ARCH_HAS_FAST_MULTIPLIER 1
413
414 #include <asm-generic/bitops/hweight.h>
415 #include <asm-generic/bitops/lock.h>
416
417 #endif /* __KERNEL__ */
418
419 #ifdef __KERNEL__
420
421 #include <asm-generic/bitops/ext2-non-atomic.h>
422
423 #define ext2_set_bit_atomic(lock,nr,addr) \
424                 test_and_set_bit((nr),(unsigned long*)addr)
425 #define ext2_clear_bit_atomic(lock,nr,addr) \
426                 test_and_clear_bit((nr),(unsigned long*)addr)
427
428 #include <asm-generic/bitops/minix.h>
429
430 #endif /* __KERNEL__ */
431
432 #endif /* _X86_64_BITOPS_H */