1#ifndef _ASM_IA64_BITOPS_H
2#define _ASM_IA64_BITOPS_H
3
4
5
6
7
8
9#include <linux/types.h>
10
11#include <asm/intrinsics.h>
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30static __inline__ void
31set_bit (int nr, volatile void *addr)
32{
33 __u32 bit, old, new;
34 volatile __u32 *m;
35 CMPXCHG_BUGCHECK_DECL
36
37 m = (volatile __u32 *) addr + (nr >> 5);
38 bit = 1 << (nr & 31);
39 do {
40 CMPXCHG_BUGCHECK(m);
41 old = *m;
42 new = old | bit;
43 } while (cmpxchg_acq(m, old, new) != old);
44}
45
46
47
48
49
50
51
52
53
54
55static __inline__ void
56__set_bit (int nr, volatile void *addr)
57{
58 *((__u32 *) addr + (nr >> 5)) |= (1 << (nr & 31));
59}
60
61
62
63
64#define smp_mb__before_clear_bit() smp_mb()
65#define smp_mb__after_clear_bit() do { ; } while (0)
66
67
68
69
70
71
72
73
74
75
76
77static __inline__ void
78clear_bit (int nr, volatile void *addr)
79{
80 __u32 mask, old, new;
81 volatile __u32 *m;
82 CMPXCHG_BUGCHECK_DECL
83
84 m = (volatile __u32 *) addr + (nr >> 5);
85 mask = ~(1 << (nr & 31));
86 do {
87 CMPXCHG_BUGCHECK(m);
88 old = *m;
89 new = old & mask;
90 } while (cmpxchg_acq(m, old, new) != old);
91}
92
93
94
95
96
97
98
99
100
101
102static __inline__ void
103change_bit (int nr, volatile void *addr)
104{
105 __u32 bit, old, new;
106 volatile __u32 *m;
107 CMPXCHG_BUGCHECK_DECL
108
109 m = (volatile __u32 *) addr + (nr >> 5);
110 bit = (1 << (nr & 31));
111 do {
112 CMPXCHG_BUGCHECK(m);
113 old = *m;
114 new = old ^ bit;
115 } while (cmpxchg_acq(m, old, new) != old);
116}
117
118
119
120
121
122
123
124
125
126
127static __inline__ void
128__change_bit (int nr, volatile void *addr)
129{
130 *((__u32 *) addr + (nr >> 5)) ^= (1 << (nr & 31));
131}
132
133
134
135
136
137
138
139
140
141static __inline__ int
142test_and_set_bit (int nr, volatile void *addr)
143{
144 __u32 bit, old, new;
145 volatile __u32 *m;
146 CMPXCHG_BUGCHECK_DECL
147
148 m = (volatile __u32 *) addr + (nr >> 5);
149 bit = 1 << (nr & 31);
150 do {
151 CMPXCHG_BUGCHECK(m);
152 old = *m;
153 new = old | bit;
154 } while (cmpxchg_acq(m, old, new) != old);
155 return (old & bit) != 0;
156}
157
158
159
160
161
162
163
164
165
166
167static __inline__ int
168__test_and_set_bit (int nr, volatile void *addr)
169{
170 __u32 *p = (__u32 *) addr + (nr >> 5);
171 __u32 m = 1 << (nr & 31);
172 int oldbitset = (*p & m) != 0;
173
174 *p |= m;
175 return oldbitset;
176}
177
178
179
180
181
182
183
184
185
186static __inline__ int
187test_and_clear_bit (int nr, volatile void *addr)
188{
189 __u32 mask, old, new;
190 volatile __u32 *m;
191 CMPXCHG_BUGCHECK_DECL
192
193 m = (volatile __u32 *) addr + (nr >> 5);
194 mask = ~(1 << (nr & 31));
195 do {
196 CMPXCHG_BUGCHECK(m);
197 old = *m;
198 new = old & mask;
199 } while (cmpxchg_acq(m, old, new) != old);
200 return (old & ~mask) != 0;
201}
202
203
204
205
206
207
208
209
210
211
212static __inline__ int
213__test_and_clear_bit(int nr, volatile void * addr)
214{
215 __u32 *p = (__u32 *) addr + (nr >> 5);
216 __u32 m = 1 << (nr & 31);
217 int oldbitset = *p & m;
218
219 *p &= ~m;
220 return oldbitset;
221}
222
223
224
225
226
227
228
229
230
231static __inline__ int
232test_and_change_bit (int nr, volatile void *addr)
233{
234 __u32 bit, old, new;
235 volatile __u32 *m;
236 CMPXCHG_BUGCHECK_DECL
237
238 m = (volatile __u32 *) addr + (nr >> 5);
239 bit = (1 << (nr & 31));
240 do {
241 CMPXCHG_BUGCHECK(m);
242 old = *m;
243 new = old ^ bit;
244 } while (cmpxchg_acq(m, old, new) != old);
245 return (old & bit) != 0;
246}
247
248
249
250
251static __inline__ int
252__test_and_change_bit (int nr, void *addr)
253{
254 __u32 old, bit = (1 << (nr & 31));
255 __u32 *m = (__u32 *) addr + (nr >> 5);
256
257 old = *m;
258 *m = old ^ bit;
259 return (old & bit) != 0;
260}
261
262static __inline__ int
263test_bit (int nr, const volatile void *addr)
264{
265 return 1 & (((const volatile __u32 *) addr)[nr >> 5] >> (nr & 31));
266}
267
268
269
270
271
272
273
274
275
276static inline unsigned long
277ffz (unsigned long x)
278{
279 unsigned long result;
280
281 __asm__ ("popcnt %0=%1" : "=r" (result) : "r" (x & (~x - 1)));
282 return result;
283}
284
285
286
287
288
289
290
291static __inline__ unsigned long
292__ffs (unsigned long x)
293{
294 unsigned long result;
295
296 __asm__ ("popcnt %0=%1" : "=r" (result) : "r" ((x - 1) & ~x));
297 return result;
298}
299
300#ifdef __KERNEL__
301
302
303
304
305
306static inline unsigned long
307ia64_fls (unsigned long x)
308{
309 long double d = x;
310 long exp;
311
312 __asm__ ("getf.exp %0=%1" : "=r"(exp) : "f"(d));
313 return exp - 0xffff;
314}
315
316
317
318
319
320
321
322#define ffs(x) __builtin_ffs(x)
323
324
325
326
327
328static __inline__ unsigned long
329hweight64 (unsigned long x)
330{
331 unsigned long result;
332 __asm__ ("popcnt %0=%1" : "=r" (result) : "r" (x));
333 return result;
334}
335
336#define hweight32(x) hweight64 ((x) & 0xfffffffful)
337#define hweight16(x) hweight64 ((x) & 0xfffful)
338#define hweight8(x) hweight64 ((x) & 0xfful)
339
340#endif
341
342
343
344
345static inline unsigned long
346find_next_zero_bit (void *addr, unsigned long size, unsigned long offset)
347{
348 unsigned long *p = ((unsigned long *) addr) + (offset >> 6);
349 unsigned long result = offset & ~63UL;
350 unsigned long tmp;
351
352 if (offset >= size)
353 return size;
354 size -= result;
355 offset &= 63UL;
356 if (offset) {
357 tmp = *(p++);
358 tmp |= ~0UL >> (64-offset);
359 if (size < 64)
360 goto found_first;
361 if (~tmp)
362 goto found_middle;
363 size -= 64;
364 result += 64;
365 }
366 while (size & ~63UL) {
367 if (~(tmp = *(p++)))
368 goto found_middle;
369 result += 64;
370 size -= 64;
371 }
372 if (!size)
373 return result;
374 tmp = *p;
375found_first:
376 tmp |= ~0UL << size;
377 if (tmp == ~0UL)
378 return result + size;
379found_middle:
380 return result + ffz(tmp);
381}
382
383
384
385
386#define find_first_zero_bit(addr, size) find_next_zero_bit((addr), (size), 0)
387
388#ifdef __KERNEL__
389
390#define ext2_set_bit test_and_set_bit
391#define ext2_clear_bit test_and_clear_bit
392#define ext2_test_bit test_bit
393#define ext2_find_first_zero_bit find_first_zero_bit
394#define ext2_find_next_zero_bit find_next_zero_bit
395
396
397#define minix_test_and_set_bit(nr,addr) test_and_set_bit(nr,addr)
398#define minix_set_bit(nr,addr) set_bit(nr,addr)
399#define minix_test_and_clear_bit(nr,addr) test_and_clear_bit(nr,addr)
400#define minix_test_bit(nr,addr) test_bit(nr,addr)
401#define minix_find_first_zero_bit(addr,size) find_first_zero_bit(addr,size)
402
403#endif
404
405#endif
406