1#ifndef _ALPHA_BITOPS_H
2#define _ALPHA_BITOPS_H
3
4#ifndef _LINUX_BITOPS_H
5#error only <linux/bitops.h> can be included directly
6#endif
7
8#include <asm/compiler.h>
9#include <asm/barrier.h>
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27static inline void
28set_bit(unsigned long nr, volatile void * addr)
29{
30 unsigned long temp;
31 int *m = ((int *) addr) + (nr >> 5);
32
33 __asm__ __volatile__(
34 "1: ldl_l %0,%3\n"
35 " bis %0,%2,%0\n"
36 " stl_c %0,%1\n"
37 " beq %0,2f\n"
38 ".subsection 2\n"
39 "2: br 1b\n"
40 ".previous"
41 :"=&r" (temp), "=m" (*m)
42 :"Ir" (1UL << (nr & 31)), "m" (*m));
43}
44
45
46
47
48static inline void
49__set_bit(unsigned long nr, volatile void * addr)
50{
51 int *m = ((int *) addr) + (nr >> 5);
52
53 *m |= 1 << (nr & 31);
54}
55
56static inline void
57clear_bit(unsigned long nr, volatile void * addr)
58{
59 unsigned long temp;
60 int *m = ((int *) addr) + (nr >> 5);
61
62 __asm__ __volatile__(
63 "1: ldl_l %0,%3\n"
64 " bic %0,%2,%0\n"
65 " stl_c %0,%1\n"
66 " beq %0,2f\n"
67 ".subsection 2\n"
68 "2: br 1b\n"
69 ".previous"
70 :"=&r" (temp), "=m" (*m)
71 :"Ir" (1UL << (nr & 31)), "m" (*m));
72}
73
74static inline void
75clear_bit_unlock(unsigned long nr, volatile void * addr)
76{
77 smp_mb();
78 clear_bit(nr, addr);
79}
80
81
82
83
84static __inline__ void
85__clear_bit(unsigned long nr, volatile void * addr)
86{
87 int *m = ((int *) addr) + (nr >> 5);
88
89 *m &= ~(1 << (nr & 31));
90}
91
92static inline void
93__clear_bit_unlock(unsigned long nr, volatile void * addr)
94{
95 smp_mb();
96 __clear_bit(nr, addr);
97}
98
99static inline void
100change_bit(unsigned long nr, volatile void * addr)
101{
102 unsigned long temp;
103 int *m = ((int *) addr) + (nr >> 5);
104
105 __asm__ __volatile__(
106 "1: ldl_l %0,%3\n"
107 " xor %0,%2,%0\n"
108 " stl_c %0,%1\n"
109 " beq %0,2f\n"
110 ".subsection 2\n"
111 "2: br 1b\n"
112 ".previous"
113 :"=&r" (temp), "=m" (*m)
114 :"Ir" (1UL << (nr & 31)), "m" (*m));
115}
116
117
118
119
120static __inline__ void
121__change_bit(unsigned long nr, volatile void * addr)
122{
123 int *m = ((int *) addr) + (nr >> 5);
124
125 *m ^= 1 << (nr & 31);
126}
127
128static inline int
129test_and_set_bit(unsigned long nr, volatile void *addr)
130{
131 unsigned long oldbit;
132 unsigned long temp;
133 int *m = ((int *) addr) + (nr >> 5);
134
135 __asm__ __volatile__(
136#ifdef CONFIG_SMP
137 " mb\n"
138#endif
139 "1: ldl_l %0,%4\n"
140 " and %0,%3,%2\n"
141 " bne %2,2f\n"
142 " xor %0,%3,%0\n"
143 " stl_c %0,%1\n"
144 " beq %0,3f\n"
145 "2:\n"
146#ifdef CONFIG_SMP
147 " mb\n"
148#endif
149 ".subsection 2\n"
150 "3: br 1b\n"
151 ".previous"
152 :"=&r" (temp), "=m" (*m), "=&r" (oldbit)
153 :"Ir" (1UL << (nr & 31)), "m" (*m) : "memory");
154
155 return oldbit != 0;
156}
157
158static inline int
159test_and_set_bit_lock(unsigned long nr, volatile void *addr)
160{
161 unsigned long oldbit;
162 unsigned long temp;
163 int *m = ((int *) addr) + (nr >> 5);
164
165 __asm__ __volatile__(
166 "1: ldl_l %0,%4\n"
167 " and %0,%3,%2\n"
168 " bne %2,2f\n"
169 " xor %0,%3,%0\n"
170 " stl_c %0,%1\n"
171 " beq %0,3f\n"
172 "2:\n"
173#ifdef CONFIG_SMP
174 " mb\n"
175#endif
176 ".subsection 2\n"
177 "3: br 1b\n"
178 ".previous"
179 :"=&r" (temp), "=m" (*m), "=&r" (oldbit)
180 :"Ir" (1UL << (nr & 31)), "m" (*m) : "memory");
181
182 return oldbit != 0;
183}
184
185
186
187
188static inline int
189__test_and_set_bit(unsigned long nr, volatile void * addr)
190{
191 unsigned long mask = 1 << (nr & 0x1f);
192 int *m = ((int *) addr) + (nr >> 5);
193 int old = *m;
194
195 *m = old | mask;
196 return (old & mask) != 0;
197}
198
199static inline int
200test_and_clear_bit(unsigned long nr, volatile void * addr)
201{
202 unsigned long oldbit;
203 unsigned long temp;
204 int *m = ((int *) addr) + (nr >> 5);
205
206 __asm__ __volatile__(
207#ifdef CONFIG_SMP
208 " mb\n"
209#endif
210 "1: ldl_l %0,%4\n"
211 " and %0,%3,%2\n"
212 " beq %2,2f\n"
213 " xor %0,%3,%0\n"
214 " stl_c %0,%1\n"
215 " beq %0,3f\n"
216 "2:\n"
217#ifdef CONFIG_SMP
218 " mb\n"
219#endif
220 ".subsection 2\n"
221 "3: br 1b\n"
222 ".previous"
223 :"=&r" (temp), "=m" (*m), "=&r" (oldbit)
224 :"Ir" (1UL << (nr & 31)), "m" (*m) : "memory");
225
226 return oldbit != 0;
227}
228
229
230
231
232static inline int
233__test_and_clear_bit(unsigned long nr, volatile void * addr)
234{
235 unsigned long mask = 1 << (nr & 0x1f);
236 int *m = ((int *) addr) + (nr >> 5);
237 int old = *m;
238
239 *m = old & ~mask;
240 return (old & mask) != 0;
241}
242
243static inline int
244test_and_change_bit(unsigned long nr, volatile void * addr)
245{
246 unsigned long oldbit;
247 unsigned long temp;
248 int *m = ((int *) addr) + (nr >> 5);
249
250 __asm__ __volatile__(
251#ifdef CONFIG_SMP
252 " mb\n"
253#endif
254 "1: ldl_l %0,%4\n"
255 " and %0,%3,%2\n"
256 " xor %0,%3,%0\n"
257 " stl_c %0,%1\n"
258 " beq %0,3f\n"
259#ifdef CONFIG_SMP
260 " mb\n"
261#endif
262 ".subsection 2\n"
263 "3: br 1b\n"
264 ".previous"
265 :"=&r" (temp), "=m" (*m), "=&r" (oldbit)
266 :"Ir" (1UL << (nr & 31)), "m" (*m) : "memory");
267
268 return oldbit != 0;
269}
270
271
272
273
274static __inline__ int
275__test_and_change_bit(unsigned long nr, volatile void * addr)
276{
277 unsigned long mask = 1 << (nr & 0x1f);
278 int *m = ((int *) addr) + (nr >> 5);
279 int old = *m;
280
281 *m = old ^ mask;
282 return (old & mask) != 0;
283}
284
285static inline int
286test_bit(int nr, const volatile void * addr)
287{
288 return (1UL & (((const int *) addr)[nr >> 5] >> (nr & 31))) != 0UL;
289}
290
291
292
293
294
295
296
297
298static inline unsigned long ffz_b(unsigned long x)
299{
300 unsigned long sum, x1, x2, x4;
301
302 x = ~x & -~x;
303 x1 = x & 0xAA;
304 x2 = x & 0xCC;
305 x4 = x & 0xF0;
306 sum = x2 ? 2 : 0;
307 sum += (x4 != 0) * 4;
308 sum += (x1 != 0);
309
310 return sum;
311}
312
313static inline unsigned long ffz(unsigned long word)
314{
315#if defined(CONFIG_ALPHA_EV6) && defined(CONFIG_ALPHA_EV67)
316
317 return __kernel_cttz(~word);
318#else
319 unsigned long bits, qofs, bofs;
320
321 bits = __kernel_cmpbge(word, ~0UL);
322 qofs = ffz_b(bits);
323 bits = __kernel_extbl(word, qofs);
324 bofs = ffz_b(bits);
325
326 return qofs*8 + bofs;
327#endif
328}
329
330
331
332
333static inline unsigned long __ffs(unsigned long word)
334{
335#if defined(CONFIG_ALPHA_EV6) && defined(CONFIG_ALPHA_EV67)
336
337 return __kernel_cttz(word);
338#else
339 unsigned long bits, qofs, bofs;
340
341 bits = __kernel_cmpbge(0, word);
342 qofs = ffz_b(bits);
343 bits = __kernel_extbl(word, qofs);
344 bofs = ffz_b(~bits);
345
346 return qofs*8 + bofs;
347#endif
348}
349
350#ifdef __KERNEL__
351
352
353
354
355
356
357
358static inline int ffs(int word)
359{
360 int result = __ffs(word) + 1;
361 return word ? result : 0;
362}
363
364
365
366
367#if defined(CONFIG_ALPHA_EV6) && defined(CONFIG_ALPHA_EV67)
368static inline int fls64(unsigned long word)
369{
370 return 64 - __kernel_ctlz(word);
371}
372#else
373extern const unsigned char __flsm1_tab[256];
374
375static inline int fls64(unsigned long x)
376{
377 unsigned long t, a, r;
378
379 t = __kernel_cmpbge (x, 0x0101010101010101UL);
380 a = __flsm1_tab[t];
381 t = __kernel_extbl (x, a);
382 r = a*8 + __flsm1_tab[t] + (x != 0);
383
384 return r;
385}
386#endif
387
388static inline unsigned long __fls(unsigned long x)
389{
390 return fls64(x) - 1;
391}
392
393static inline int fls(int x)
394{
395 return fls64((unsigned int) x);
396}
397
398
399
400
401
402
403#if defined(CONFIG_ALPHA_EV6) && defined(CONFIG_ALPHA_EV67)
404
405static inline unsigned long __arch_hweight64(unsigned long w)
406{
407 return __kernel_ctpop(w);
408}
409
410static inline unsigned int __arch_hweight32(unsigned int w)
411{
412 return __arch_hweight64(w);
413}
414
415static inline unsigned int __arch_hweight16(unsigned int w)
416{
417 return __arch_hweight64(w & 0xffff);
418}
419
420static inline unsigned int __arch_hweight8(unsigned int w)
421{
422 return __arch_hweight64(w & 0xff);
423}
424#else
425#include <asm-generic/bitops/arch_hweight.h>
426#endif
427
428#include <asm-generic/bitops/const_hweight.h>
429
430#endif
431
432#include <asm-generic/bitops/find.h>
433
434#ifdef __KERNEL__
435
436
437
438
439
440
441static inline unsigned long
442sched_find_first_bit(const unsigned long b[2])
443{
444 unsigned long b0, b1, ofs, tmp;
445
446 b0 = b[0];
447 b1 = b[1];
448 ofs = (b0 ? 0 : 64);
449 tmp = (b0 ? b0 : b1);
450
451 return __ffs(tmp) + ofs;
452}
453
454#include <asm-generic/bitops/le.h>
455
456#include <asm-generic/bitops/ext2-atomic-setbit.h>
457
458#endif
459
460#endif
461