1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
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
40
41#define smp_mb__before_clear_bit() smp_mb()
42#define smp_mb__after_clear_bit() smp_mb()
43
44static __inline__ int test_bit(unsigned long nr, __const__ volatile unsigned long *addr)
45{
46 return (1UL & (addr[nr >> 6] >> (nr & 63)));
47}
48
49static __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
65static __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
81static __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
97static __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
117static __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
137static __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
157static __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
173
174static __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
182static __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
190static __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
198static __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
208static __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
218static __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
230
231
232static __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
242
243
244
245static __inline__ unsigned long ffz(unsigned long x)
246{
247
248 if ((x = ~x) == 0)
249 return 64;
250
251
252
253
254
255
256
257 return __ilog2(x & -x);
258}
259
260static __inline__ int __ffs(unsigned long x)
261{
262 return __ilog2(x & -x);
263}
264
265
266
267
268
269
270static __inline__ int ffs(int x)
271{
272 unsigned long i = (unsigned long)x;
273 return __ilog2(i & -i) + 1;
274}
275
276
277
278
279
280#define fls(x) generic_fls(x)
281
282
283
284
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
291extern unsigned long find_next_zero_bit(const 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
295extern unsigned long find_next_bit(const unsigned long *addr, unsigned long size, unsigned long offset);
296#define find_first_bit(addr, size) \
297 find_next_bit((addr), (size), 0)
298
299extern unsigned long find_next_zero_le_bit(const 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
303static __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
311
312static __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
320static __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
328static __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
340static __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
388#endif
389