Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
bitops.h
Go to the documentation of this file.
1 #ifndef _ASM_IA64_BITOPS_H
2 #define _ASM_IA64_BITOPS_H
3 
4 /*
5  * Copyright (C) 1998-2003 Hewlett-Packard Co
6  * David Mosberger-Tang <[email protected]>
7  *
8  * 02/06/02 find_next_bit() and find_first_bit() added from Erich Focht's ia64
9  * O(1) scheduler patch
10  */
11 
12 #ifndef _LINUX_BITOPS_H
13 #error only <linux/bitops.h> can be included directly
14 #endif
15 
16 #include <linux/compiler.h>
17 #include <linux/types.h>
18 #include <asm/intrinsics.h>
19 
37 static __inline__ void
38 set_bit (int nr, volatile void *addr)
39 {
40  __u32 bit, old, new;
41  volatile __u32 *m;
43 
44  m = (volatile __u32 *) addr + (nr >> 5);
45  bit = 1 << (nr & 31);
46  do {
48  old = *m;
49  new = old | bit;
50  } while (cmpxchg_acq(m, old, new) != old);
51 }
52 
62 static __inline__ void
63 __set_bit (int nr, volatile void *addr)
64 {
65  *((__u32 *) addr + (nr >> 5)) |= (1 << (nr & 31));
66 }
67 
68 /*
69  * clear_bit() has "acquire" semantics.
70  */
71 #define smp_mb__before_clear_bit() smp_mb()
72 #define smp_mb__after_clear_bit() do { /* skip */; } while (0)
73 
84 static __inline__ void
85 clear_bit (int nr, volatile void *addr)
86 {
87  __u32 mask, old, new;
88  volatile __u32 *m;
90 
91  m = (volatile __u32 *) addr + (nr >> 5);
92  mask = ~(1 << (nr & 31));
93  do {
95  old = *m;
96  new = old & mask;
97  } while (cmpxchg_acq(m, old, new) != old);
98 }
99 
108 static __inline__ void
109 clear_bit_unlock (int nr, volatile void *addr)
110 {
111  __u32 mask, old, new;
112  volatile __u32 *m;
114 
115  m = (volatile __u32 *) addr + (nr >> 5);
116  mask = ~(1 << (nr & 31));
117  do {
118  CMPXCHG_BUGCHECK(m);
119  old = *m;
120  new = old & mask;
121  } while (cmpxchg_rel(m, old, new) != old);
122 }
123 
132 static __inline__ void
133 __clear_bit_unlock(int nr, void *addr)
134 {
135  __u32 * const m = (__u32 *) addr + (nr >> 5);
136  __u32 const new = *m & ~(1 << (nr & 31));
137 
138  ia64_st4_rel_nta(m, new);
139 }
140 
150 static __inline__ void
151 __clear_bit (int nr, volatile void *addr)
152 {
153  *((__u32 *) addr + (nr >> 5)) &= ~(1 << (nr & 31));
154 }
155 
165 static __inline__ void
166 change_bit (int nr, volatile void *addr)
167 {
168  __u32 bit, old, new;
169  volatile __u32 *m;
171 
172  m = (volatile __u32 *) addr + (nr >> 5);
173  bit = (1 << (nr & 31));
174  do {
175  CMPXCHG_BUGCHECK(m);
176  old = *m;
177  new = old ^ bit;
178  } while (cmpxchg_acq(m, old, new) != old);
179 }
180 
190 static __inline__ void
191 __change_bit (int nr, volatile void *addr)
192 {
193  *((__u32 *) addr + (nr >> 5)) ^= (1 << (nr & 31));
194 }
195 
204 static __inline__ int
205 test_and_set_bit (int nr, volatile void *addr)
206 {
207  __u32 bit, old, new;
208  volatile __u32 *m;
210 
211  m = (volatile __u32 *) addr + (nr >> 5);
212  bit = 1 << (nr & 31);
213  do {
214  CMPXCHG_BUGCHECK(m);
215  old = *m;
216  new = old | bit;
217  } while (cmpxchg_acq(m, old, new) != old);
218  return (old & bit) != 0;
219 }
220 
228 #define test_and_set_bit_lock test_and_set_bit
229 
239 static __inline__ int
240 __test_and_set_bit (int nr, volatile void *addr)
241 {
242  __u32 *p = (__u32 *) addr + (nr >> 5);
243  __u32 m = 1 << (nr & 31);
244  int oldbitset = (*p & m) != 0;
245 
246  *p |= m;
247  return oldbitset;
248 }
249 
258 static __inline__ int
259 test_and_clear_bit (int nr, volatile void *addr)
260 {
261  __u32 mask, old, new;
262  volatile __u32 *m;
264 
265  m = (volatile __u32 *) addr + (nr >> 5);
266  mask = ~(1 << (nr & 31));
267  do {
268  CMPXCHG_BUGCHECK(m);
269  old = *m;
270  new = old & mask;
271  } while (cmpxchg_acq(m, old, new) != old);
272  return (old & ~mask) != 0;
273 }
274 
284 static __inline__ int
285 __test_and_clear_bit(int nr, volatile void * addr)
286 {
287  __u32 *p = (__u32 *) addr + (nr >> 5);
288  __u32 m = 1 << (nr & 31);
289  int oldbitset = (*p & m) != 0;
290 
291  *p &= ~m;
292  return oldbitset;
293 }
294 
303 static __inline__ int
304 test_and_change_bit (int nr, volatile void *addr)
305 {
306  __u32 bit, old, new;
307  volatile __u32 *m;
309 
310  m = (volatile __u32 *) addr + (nr >> 5);
311  bit = (1 << (nr & 31));
312  do {
313  CMPXCHG_BUGCHECK(m);
314  old = *m;
315  new = old ^ bit;
316  } while (cmpxchg_acq(m, old, new) != old);
317  return (old & bit) != 0;
318 }
319 
327 static __inline__ int
328 __test_and_change_bit (int nr, void *addr)
329 {
330  __u32 old, bit = (1 << (nr & 31));
331  __u32 *m = (__u32 *) addr + (nr >> 5);
332 
333  old = *m;
334  *m = old ^ bit;
335  return (old & bit) != 0;
336 }
337 
338 static __inline__ int
339 test_bit (int nr, const volatile void *addr)
340 {
341  return 1 & (((const volatile __u32 *) addr)[nr >> 5] >> (nr & 31));
342 }
343 
351 static inline unsigned long
352 ffz (unsigned long x)
353 {
354  unsigned long result;
355 
356  result = ia64_popcnt(x & (~x - 1));
357  return result;
358 }
359 
366 static __inline__ unsigned long
367 __ffs (unsigned long x)
368 {
369  unsigned long result;
370 
371  result = ia64_popcnt((x-1) & ~x);
372  return result;
373 }
374 
375 #ifdef __KERNEL__
376 
377 /*
378  * Return bit number of last (most-significant) bit set. Undefined
379  * for x==0. Bits are numbered from 0..63 (e.g., ia64_fls(9) == 3).
380  */
381 static inline unsigned long
382 ia64_fls (unsigned long x)
383 {
384  long double d = x;
385  long exp;
386 
387  exp = ia64_getf_exp(d);
388  return exp - 0xffff;
389 }
390 
391 /*
392  * Find the last (most significant) bit set. Returns 0 for x==0 and
393  * bits are numbered from 1..32 (e.g., fls(9) == 4).
394  */
395 static inline int
396 fls (int t)
397 {
398  unsigned long x = t & 0xffffffffu;
399 
400  if (!x)
401  return 0;
402  x |= x >> 1;
403  x |= x >> 2;
404  x |= x >> 4;
405  x |= x >> 8;
406  x |= x >> 16;
407  return ia64_popcnt(x);
408 }
409 
410 /*
411  * Find the last (most significant) bit set. Undefined for x==0.
412  * Bits are numbered from 0..63 (e.g., __fls(9) == 3).
413  */
414 static inline unsigned long
415 __fls (unsigned long x)
416 {
417  x |= x >> 1;
418  x |= x >> 2;
419  x |= x >> 4;
420  x |= x >> 8;
421  x |= x >> 16;
422  x |= x >> 32;
423  return ia64_popcnt(x) - 1;
424 }
425 
427 
428 /*
429  * ffs: find first bit set. This is defined the same way as the libc and
430  * compiler builtin ffs routines, therefore differs in spirit from the above
431  * ffz (man ffs): it operates on "int" values only and the result value is the
432  * bit number + 1. ffs(0) is defined to return zero.
433  */
434 #define ffs(x) __builtin_ffs(x)
435 
436 /*
437  * hweightN: returns the hamming weight (i.e. the number
438  * of bits set) of a N-bit word
439  */
440 static __inline__ unsigned long __arch_hweight64(unsigned long x)
441 {
442  unsigned long result;
443  result = ia64_popcnt(x);
444  return result;
445 }
446 
447 #define __arch_hweight32(x) ((unsigned int) __arch_hweight64((x) & 0xfffffffful))
448 #define __arch_hweight16(x) ((unsigned int) __arch_hweight64((x) & 0xfffful))
449 #define __arch_hweight8(x) ((unsigned int) __arch_hweight64((x) & 0xfful))
450 
452 
453 #endif /* __KERNEL__ */
454 
455 #include <asm-generic/bitops/find.h>
456 
457 #ifdef __KERNEL__
458 
459 #include <asm-generic/bitops/le.h>
460 
462 
464 
465 #endif /* __KERNEL__ */
466 
467 #endif /* _ASM_IA64_BITOPS_H */