patch-2_6_7-vs1_9_1_12
[linux-2.6.git] / include / asm-ppc64 / bitops.h
1 /*
2  * PowerPC64 atomic bit operations.
3  * Dave Engebretsen, Todd Inglett, Don Reed, Pat McCarthy, Peter Bergner,
4  * Anton Blanchard
5  *
6  * Originally taken from the 32b PPC code.  Modified to use 64b values for
7  * the various counters & memory references.
8  *
9  * Bitops are odd when viewed on big-endian systems.  They were designed
10  * on little endian so the size of the bitset doesn't matter (low order bytes
11  * come first) as long as the bit in question is valid.
12  *
13  * Bits are "tested" often using the C expression (val & (1<<nr)) so we do
14  * our best to stay compatible with that.  The assumption is that val will
15  * be unsigned long for such tests.  As such, we assume the bits are stored
16  * as an array of unsigned long (the usual case is a single unsigned long,
17  * of course).  Here's an example bitset with bit numbering:
18  *
19  *   |63..........0|127........64|195.......128|255.......196|
20  *
21  * This leads to a problem. If an int, short or char is passed as a bitset
22  * it will be a bad memory reference since we want to store in chunks
23  * of unsigned long (64 bits here) size.
24  *
25  * This program is free software; you can redistribute it and/or
26  * modify it under the terms of the GNU General Public License
27  * as published by the Free Software Foundation; either version
28  * 2 of the License, or (at your option) any later version.
29  */
30
31 #ifndef _PPC64_BITOPS_H
32 #define _PPC64_BITOPS_H
33
34 #ifdef __KERNEL__
35
36 #include <asm/memory.h>
37
38 /*
39  * clear_bit doesn't imply a memory barrier
40  */
41 #define smp_mb__before_clear_bit()      smp_mb()
42 #define smp_mb__after_clear_bit()       smp_mb()
43
44 static __inline__ int test_bit(unsigned long nr, __const__ volatile unsigned long *addr)
45 {
46         return (1UL & (addr[nr >> 6] >> (nr & 63)));
47 }
48
49 static __inline__ void set_bit(unsigned long nr, volatile unsigned long *addr)
50 {
51         unsigned long old;
52         unsigned long mask = 1UL << (nr & 0x3f);
53         unsigned long *p = ((unsigned long *)addr) + (nr >> 6);
54
55         __asm__ __volatile__(
56 "1:     ldarx   %0,0,%3         # set_bit\n\
57         or      %0,%0,%2\n\
58         stdcx.  %0,0,%3\n\
59         bne-    1b"
60         : "=&r" (old), "=m" (*p)
61         : "r" (mask), "r" (p), "m" (*p)
62         : "cc");
63 }
64
65 static __inline__ void clear_bit(unsigned long nr, volatile unsigned long *addr)
66 {
67         unsigned long old;
68         unsigned long mask = 1UL << (nr & 0x3f);
69         unsigned long *p = ((unsigned long *)addr) + (nr >> 6);
70
71         __asm__ __volatile__(
72 "1:     ldarx   %0,0,%3         # clear_bit\n\
73         andc    %0,%0,%2\n\
74         stdcx.  %0,0,%3\n\
75         bne-    1b"
76         : "=&r" (old), "=m" (*p)
77         : "r" (mask), "r" (p), "m" (*p)
78         : "cc");
79 }
80
81 static __inline__ void change_bit(unsigned long nr, volatile unsigned long *addr)
82 {
83         unsigned long old;
84         unsigned long mask = 1UL << (nr & 0x3f);
85         unsigned long *p = ((unsigned long *)addr) + (nr >> 6);
86
87         __asm__ __volatile__(
88 "1:     ldarx   %0,0,%3         # change_bit\n\
89         xor     %0,%0,%2\n\
90         stdcx.  %0,0,%3\n\
91         bne-    1b"
92         : "=&r" (old), "=m" (*p)
93         : "r" (mask), "r" (p), "m" (*p)
94         : "cc");
95 }
96
97 static __inline__ int test_and_set_bit(unsigned long nr, volatile unsigned long *addr)
98 {
99         unsigned long old, t;
100         unsigned long mask = 1UL << (nr & 0x3f);
101         unsigned long *p = ((unsigned long *)addr) + (nr >> 6);
102
103         __asm__ __volatile__(
104         EIEIO_ON_SMP
105 "1:     ldarx   %0,0,%3         # test_and_set_bit\n\
106         or      %1,%0,%2 \n\
107         stdcx.  %1,0,%3 \n\
108         bne-    1b"
109         ISYNC_ON_SMP
110         : "=&r" (old), "=&r" (t)
111         : "r" (mask), "r" (p)
112         : "cc", "memory");
113
114         return (old & mask) != 0;
115 }
116
117 static __inline__ int test_and_clear_bit(unsigned long nr, volatile unsigned long *addr)
118 {
119         unsigned long old, t;
120         unsigned long mask = 1UL << (nr & 0x3f);
121         unsigned long *p = ((unsigned long *)addr) + (nr >> 6);
122
123         __asm__ __volatile__(
124         EIEIO_ON_SMP
125 "1:     ldarx   %0,0,%3         # test_and_clear_bit\n\
126         andc    %1,%0,%2\n\
127         stdcx.  %1,0,%3\n\
128         bne-    1b"
129         ISYNC_ON_SMP
130         : "=&r" (old), "=&r" (t)
131         : "r" (mask), "r" (p)
132         : "cc", "memory");
133
134         return (old & mask) != 0;
135 }
136
137 static __inline__ int test_and_change_bit(unsigned long nr, volatile unsigned long *addr)
138 {
139         unsigned long old, t;
140         unsigned long mask = 1UL << (nr & 0x3f);
141         unsigned long *p = ((unsigned long *)addr) + (nr >> 6);
142
143         __asm__ __volatile__(
144         EIEIO_ON_SMP
145 "1:     ldarx   %0,0,%3         # test_and_change_bit\n\
146         xor     %1,%0,%2\n\
147         stdcx.  %1,0,%3\n\
148         bne-    1b"
149         ISYNC_ON_SMP
150         : "=&r" (old), "=&r" (t)
151         : "r" (mask), "r" (p)
152         : "cc", "memory");
153
154         return (old & mask) != 0;
155 }
156
157 static __inline__ void set_bits(unsigned long mask, unsigned long *addr)
158 {
159         unsigned long old;
160
161         __asm__ __volatile__(
162 "1:     ldarx   %0,0,%3         # set_bit\n\
163         or      %0,%0,%2\n\
164         stdcx.  %0,0,%3\n\
165         bne-    1b"
166         : "=&r" (old), "=m" (*addr)
167         : "r" (mask), "r" (addr), "m" (*addr)
168         : "cc");
169 }
170
171 /*
172  * non-atomic versions
173  */
174 static __inline__ void __set_bit(unsigned long nr, volatile unsigned long *addr)
175 {
176         unsigned long mask = 1UL << (nr & 0x3f);
177         unsigned long *p = ((unsigned long *)addr) + (nr >> 6);
178
179         *p |= mask;
180 }
181
182 static __inline__ void __clear_bit(unsigned long nr, volatile unsigned long *addr)
183 {
184         unsigned long mask = 1UL << (nr & 0x3f);
185         unsigned long *p = ((unsigned long *)addr) + (nr >> 6);
186
187         *p &= ~mask;
188 }
189
190 static __inline__ void __change_bit(unsigned long nr, volatile unsigned long *addr)
191 {
192         unsigned long mask = 1UL << (nr & 0x3f);
193         unsigned long *p = ((unsigned long *)addr) + (nr >> 6);
194
195         *p ^= mask;
196 }
197
198 static __inline__ int __test_and_set_bit(unsigned long nr, volatile unsigned long *addr)
199 {
200         unsigned long mask = 1UL << (nr & 0x3f);
201         unsigned long *p = ((unsigned long *)addr) + (nr >> 6);
202         unsigned long old = *p;
203
204         *p = old | mask;
205         return (old & mask) != 0;
206 }
207
208 static __inline__ int __test_and_clear_bit(unsigned long nr, volatile unsigned long *addr)
209 {
210         unsigned long mask = 1UL << (nr & 0x3f);
211         unsigned long *p = ((unsigned long *)addr) + (nr >> 6);
212         unsigned long old = *p;
213
214         *p = old & ~mask;
215         return (old & mask) != 0;
216 }
217
218 static __inline__ int __test_and_change_bit(unsigned long nr, volatile unsigned long *addr)
219 {
220         unsigned long mask = 1UL << (nr & 0x3f);
221         unsigned long *p = ((unsigned long *)addr) + (nr >> 6);
222         unsigned long old = *p;
223
224         *p = old ^ mask;
225         return (old & mask) != 0;
226 }
227
228 /*
229  * Return the zero-based bit position (from RIGHT TO LEFT, 63 -> 0) of the
230  * most significant (left-most) 1-bit in a double word.
231  */
232 static __inline__ int __ilog2(unsigned long x)
233 {
234         int lz;
235
236         asm ("cntlzd %0,%1" : "=r" (lz) : "r" (x));
237         return 63 - lz;
238 }
239
240 /*
241  * Determines the bit position of the least significant (rightmost) 0 bit
242  * in the specified double word. The returned bit position will be zero-based,
243  * starting from the right side (63 - 0).
244  */
245 static __inline__ unsigned long ffz(unsigned long x)
246 {
247         /* no zero exists anywhere in the 8 byte area. */
248         if ((x = ~x) == 0)
249                 return 64;
250
251         /*
252          * Calculate the bit position of the least signficant '1' bit in x
253          * (since x has been changed this will actually be the least signficant
254          * '0' bit in * the original x).  Note: (x & -x) gives us a mask that
255          * is the least significant * (RIGHT-most) 1-bit of the value in x.
256          */
257         return __ilog2(x & -x);
258 }
259
260 static __inline__ int __ffs(unsigned long x)
261 {
262         return __ilog2(x & -x);
263 }
264
265 /*
266  * ffs: find first bit set. This is defined the same way as
267  * the libc and compiler builtin ffs routines, therefore
268  * differs in spirit from the above ffz (man ffs).
269  */
270 static __inline__ int ffs(int x)
271 {
272         unsigned long i = (unsigned long)x;
273         return __ilog2(i & -i) + 1;
274 }
275
276 /*
277  * fls: find last (most-significant) bit set.
278  * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32.
279  */
280 #define fls(x) generic_fls(x)
281
282 /*
283  * hweightN: returns the hamming weight (i.e. the number
284  * of bits set) of a N-bit word
285  */
286 #define hweight64(x) generic_hweight64(x)
287 #define hweight32(x) generic_hweight32(x)
288 #define hweight16(x) generic_hweight16(x)
289 #define hweight8(x) generic_hweight8(x)
290
291 extern unsigned long find_next_zero_bit(unsigned long *addr, unsigned long size, unsigned long offset);
292 #define find_first_zero_bit(addr, size) \
293         find_next_zero_bit((addr), (size), 0)
294
295 extern unsigned long find_next_bit(unsigned long *addr, unsigned long size, unsigned long offset);
296 #define find_first_bit(addr, size) \
297         find_next_bit((addr), (size), 0)
298
299 extern unsigned long find_next_zero_le_bit(unsigned long *addr, unsigned long size, unsigned long offset);
300 #define find_first_zero_le_bit(addr, size) \
301         find_next_zero_le_bit((addr), (size), 0)
302
303 static __inline__ int test_le_bit(unsigned long nr, __const__ unsigned long * addr)
304 {
305         __const__ unsigned char *ADDR = (__const__ unsigned char *) addr;
306         return (ADDR[nr >> 3] >> (nr & 7)) & 1;
307 }
308
309 /*
310  * non-atomic versions
311  */
312 static __inline__ void __set_le_bit(unsigned long nr, unsigned long *addr)
313 {
314         unsigned char *ADDR = (unsigned char *)addr;
315
316         ADDR += nr >> 3;
317         *ADDR |= 1 << (nr & 0x07);
318 }
319
320 static __inline__ void __clear_le_bit(unsigned long nr, unsigned long *addr)
321 {
322         unsigned char *ADDR = (unsigned char *)addr;
323
324         ADDR += nr >> 3;
325         *ADDR &= ~(1 << (nr & 0x07));
326 }
327
328 static __inline__ int __test_and_set_le_bit(unsigned long nr, unsigned long *addr)
329 {
330         int mask, retval;
331         unsigned char *ADDR = (unsigned char *)addr;
332
333         ADDR += nr >> 3;
334         mask = 1 << (nr & 0x07);
335         retval = (mask & *ADDR) != 0;
336         *ADDR |= mask;
337         return retval;
338 }
339
340 static __inline__ int __test_and_clear_le_bit(unsigned long nr, unsigned long *addr)
341 {
342         int mask, retval;
343         unsigned char *ADDR = (unsigned char *)addr;
344
345         ADDR += nr >> 3;
346         mask = 1 << (nr & 0x07);
347         retval = (mask & *ADDR) != 0;
348         *ADDR &= ~mask;
349         return retval;
350 }
351
352 #define ext2_set_bit(nr,addr) \
353         __test_and_set_le_bit((nr),(unsigned long*)addr)
354 #define ext2_clear_bit(nr, addr) \
355         __test_and_clear_le_bit((nr),(unsigned long*)addr)
356
357 #define ext2_set_bit_atomic(lock, nr, addr)             \
358         ({                                              \
359                 int ret;                                \
360                 spin_lock(lock);                        \
361                 ret = ext2_set_bit((nr), (addr));       \
362                 spin_unlock(lock);                      \
363                 ret;                                    \
364         })
365
366 #define ext2_clear_bit_atomic(lock, nr, addr)           \
367         ({                                              \
368                 int ret;                                \
369                 spin_lock(lock);                        \
370                 ret = ext2_clear_bit((nr), (addr));     \
371                 spin_unlock(lock);                      \
372                 ret;                                    \
373         })
374
375 #define ext2_test_bit(nr, addr)      test_le_bit((nr),(unsigned long*)addr)
376 #define ext2_find_first_zero_bit(addr, size) \
377         find_first_zero_le_bit((unsigned long*)addr, size)
378 #define ext2_find_next_zero_bit(addr, size, off) \
379         find_next_zero_le_bit((unsigned long*)addr, size, off)
380
381 #define minix_test_and_set_bit(nr,addr)         test_and_set_bit(nr,addr)
382 #define minix_set_bit(nr,addr)                  set_bit(nr,addr)
383 #define minix_test_and_clear_bit(nr,addr)       test_and_clear_bit(nr,addr)
384 #define minix_test_bit(nr,addr)                 test_bit(nr,addr)
385 #define minix_find_first_zero_bit(addr,size)    find_first_zero_bit(addr,size)
386
387 #endif /* __KERNEL__ */
388 #endif /* _PPC64_BITOPS_H */