File: /usr/src/linux/include/asm-ia64/bitops.h
1 #ifndef _ASM_IA64_BITOPS_H
2 #define _ASM_IA64_BITOPS_H
3
4 /*
5 * Copyright (C) 1998-2001 Hewlett-Packard Co
6 * Copyright (C) 1998-2001 David Mosberger-Tang <davidm@hpl.hp.com>
7 */
8
9 #include <asm/system.h>
10
11 /**
12 * set_bit - Atomically set a bit in memory
13 * @nr: the bit to set
14 * @addr: the address to start counting from
15 *
16 * This function is atomic and may not be reordered. See __set_bit()
17 * if you do not require the atomic guarantees.
18 * Note that @nr may be almost arbitrarily large; this function is not
19 * restricted to acting on a single-word quantity.
20 *
21 * The address must be (at least) "long" aligned.
22 * Note that there are driver (e.g., eepro100) which use these operations to operate on
23 * hw-defined data-structures, so we can't easily change these operations to force a
24 * bigger alignment.
25 *
26 * bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1).
27 */
28 static __inline__ void
29 set_bit (int nr, volatile void *addr)
30 {
31 __u32 bit, old, new;
32 volatile __u32 *m;
33 CMPXCHG_BUGCHECK_DECL
34
35 m = (volatile __u32 *) addr + (nr >> 5);
36 bit = 1 << (nr & 31);
37 do {
38 CMPXCHG_BUGCHECK(m);
39 old = *m;
40 new = old | bit;
41 } while (cmpxchg_acq(m, old, new) != old);
42 }
43
44 /**
45 * __set_bit - Set a bit in memory
46 * @nr: the bit to set
47 * @addr: the address to start counting from
48 *
49 * Unlike set_bit(), this function is non-atomic and may be reordered.
50 * If it's called on the same region of memory simultaneously, the effect
51 * may be that only one operation succeeds.
52 */
53 static __inline__ void
54 __set_bit (int nr, volatile void *addr)
55 {
56 *((__u32 *) addr + (nr >> 5)) |= (1 << (nr & 31));
57 }
58
59 /*
60 * clear_bit() doesn't provide any barrier for the compiler.
61 */
62 #define smp_mb__before_clear_bit() smp_mb()
63 #define smp_mb__after_clear_bit() smp_mb()
64
65 /**
66 * clear_bit - Clears a bit in memory
67 * @nr: Bit to clear
68 * @addr: Address to start counting from
69 *
70 * clear_bit() is atomic and may not be reordered. However, it does
71 * not contain a memory barrier, so if it is used for locking purposes,
72 * you should call smp_mb__before_clear_bit() and/or smp_mb__after_clear_bit()
73 * in order to ensure changes are visible on other processors.
74 */
75 static __inline__ void
76 clear_bit (int nr, volatile void *addr)
77 {
78 __u32 mask, old, new;
79 volatile __u32 *m;
80 CMPXCHG_BUGCHECK_DECL
81
82 m = (volatile __u32 *) addr + (nr >> 5);
83 mask = ~(1 << (nr & 31));
84 do {
85 CMPXCHG_BUGCHECK(m);
86 old = *m;
87 new = old & mask;
88 } while (cmpxchg_acq(m, old, new) != old);
89 }
90
91 /**
92 * change_bit - Toggle a bit in memory
93 * @nr: Bit to clear
94 * @addr: Address to start counting from
95 *
96 * change_bit() is atomic and may not be reordered.
97 * Note that @nr may be almost arbitrarily large; this function is not
98 * restricted to acting on a single-word quantity.
99 */
100 static __inline__ void
101 change_bit (int nr, volatile void *addr)
102 {
103 __u32 bit, old, new;
104 volatile __u32 *m;
105 CMPXCHG_BUGCHECK_DECL
106
107 m = (volatile __u32 *) addr + (nr >> 5);
108 bit = (1 << (nr & 31));
109 do {
110 CMPXCHG_BUGCHECK(m);
111 old = *m;
112 new = old ^ bit;
113 } while (cmpxchg_acq(m, old, new) != old);
114 }
115
116 /**
117 * __change_bit - Toggle a bit in memory
118 * @nr: the bit to set
119 * @addr: the address to start counting from
120 *
121 * Unlike change_bit(), this function is non-atomic and may be reordered.
122 * If it's called on the same region of memory simultaneously, the effect
123 * may be that only one operation succeeds.
124 */
125 static __inline__ void
126 __change_bit (int nr, volatile void *addr)
127 {
128 *((__u32 *) addr + (nr >> 5)) ^= (1 << (nr & 31));
129 }
130
131 /**
132 * test_and_set_bit - Set a bit and return its old value
133 * @nr: Bit to set
134 * @addr: Address to count from
135 *
136 * This operation is atomic and cannot be reordered.
137 * It also implies a memory barrier.
138 */
139 static __inline__ int
140 test_and_set_bit (int nr, volatile void *addr)
141 {
142 __u32 bit, old, new;
143 volatile __u32 *m;
144 CMPXCHG_BUGCHECK_DECL
145
146 m = (volatile __u32 *) addr + (nr >> 5);
147 bit = 1 << (nr & 31);
148 do {
149 CMPXCHG_BUGCHECK(m);
150 old = *m;
151 new = old | bit;
152 } while (cmpxchg_acq(m, old, new) != old);
153 return (old & bit) != 0;
154 }
155
156 /**
157 * __test_and_set_bit - Set a bit and return its old value
158 * @nr: Bit to set
159 * @addr: Address to count from
160 *
161 * This operation is non-atomic and can be reordered.
162 * If two examples of this operation race, one can appear to succeed
163 * but actually fail. You must protect multiple accesses with a lock.
164 */
165 static __inline__ int
166 __test_and_set_bit (int nr, volatile void *addr)
167 {
168 __u32 *p = (__u32 *) addr + (nr >> 5);
169 __u32 m = 1 << (nr & 31);
170 int oldbitset = (*p & m) != 0;
171
172 *p |= m;
173 return oldbitset;
174 }
175
176 /**
177 * test_and_clear_bit - Clear a bit and return its old value
178 * @nr: Bit to set
179 * @addr: Address to count from
180 *
181 * This operation is atomic and cannot be reordered.
182 * It also implies a memory barrier.
183 */
184 static __inline__ int
185 test_and_clear_bit (int nr, volatile void *addr)
186 {
187 __u32 mask, old, new;
188 volatile __u32 *m;
189 CMPXCHG_BUGCHECK_DECL
190
191 m = (volatile __u32 *) addr + (nr >> 5);
192 mask = ~(1 << (nr & 31));
193 do {
194 CMPXCHG_BUGCHECK(m);
195 old = *m;
196 new = old & mask;
197 } while (cmpxchg_acq(m, old, new) != old);
198 return (old & ~mask) != 0;
199 }
200
201 /**
202 * __test_and_clear_bit - Clear a bit and return its old value
203 * @nr: Bit to set
204 * @addr: Address to count from
205 *
206 * This operation is non-atomic and can be reordered.
207 * If two examples of this operation race, one can appear to succeed
208 * but actually fail. You must protect multiple accesses with a lock.
209 */
210 static __inline__ int
211 __test_and_clear_bit(int nr, volatile void * addr)
212 {
213 __u32 *p = (__u32 *) addr + (nr >> 5);
214 __u32 m = 1 << (nr & 31);
215 int oldbitset = *p & m;
216
217 *p &= ~m;
218 return oldbitset;
219 }
220
221 /**
222 * test_and_change_bit - Change a bit and return its new value
223 * @nr: Bit to set
224 * @addr: Address to count from
225 *
226 * This operation is atomic and cannot be reordered.
227 * It also implies a memory barrier.
228 */
229 static __inline__ int
230 test_and_change_bit (int nr, volatile void *addr)
231 {
232 __u32 bit, old, new;
233 volatile __u32 *m;
234 CMPXCHG_BUGCHECK_DECL
235
236 m = (volatile __u32 *) addr + (nr >> 5);
237 bit = (1 << (nr & 31));
238 do {
239 CMPXCHG_BUGCHECK(m);
240 old = *m;
241 new = old ^ bit;
242 } while (cmpxchg_acq(m, old, new) != old);
243 return (old & bit) != 0;
244 }
245
246 /*
247 * WARNING: non atomic version.
248 */
249 static __inline__ int
250 __test_and_change_bit (int nr, void *addr)
251 {
252 __u32 old, bit = (1 << (nr & 31));
253 __u32 *m = (__u32 *) addr + (nr >> 5);
254
255 old = *m;
256 *m = old ^ bit;
257 return (old & bit) != 0;
258 }
259
260 static __inline__ int
261 test_bit (int nr, volatile void *addr)
262 {
263 return 1 & (((const volatile __u32 *) addr)[nr >> 5] >> (nr & 31));
264 }
265
266 /**
267 * ffz - find the first zero bit in a memory region
268 * @x: The address to start the search at
269 *
270 * Returns the bit-number (0..63) of the first (least significant) zero bit, not
271 * the number of the byte containing a bit. Undefined if no zero exists, so
272 * code should check against ~0UL first...
273 */
274 static inline unsigned long
275 ffz (unsigned long x)
276 {
277 unsigned long result;
278
279 __asm__ ("popcnt %0=%1" : "=r" (result) : "r" (x & (~x - 1)));
280 return result;
281 }
282
283 #ifdef __KERNEL__
284
285 /*
286 * find_last_zero_bit - find the last zero bit in a 64 bit quantity
287 * @x: The value to search
288 */
289 static inline unsigned long
290 ia64_fls (unsigned long x)
291 {
292 double d = x;
293 long exp;
294
295 __asm__ ("getf.exp %0=%1" : "=r"(exp) : "f"(d));
296 return exp - 0xffff;
297 }
298
299 /*
300 * ffs: find first bit set. This is defined the same way as the libc and compiler builtin
301 * ffs routines, therefore differs in spirit from the above ffz (man ffs): it operates on
302 * "int" values only and the result value is the bit number + 1. ffs(0) is defined to
303 * return zero.
304 */
305 #define ffs(x) __builtin_ffs(x)
306
307 /*
308 * hweightN: returns the hamming weight (i.e. the number
309 * of bits set) of a N-bit word
310 */
311 static __inline__ unsigned long
312 hweight64 (unsigned long x)
313 {
314 unsigned long result;
315 __asm__ ("popcnt %0=%1" : "=r" (result) : "r" (x));
316 return result;
317 }
318
319 #define hweight32(x) hweight64 ((x) & 0xfffffffful)
320 #define hweight16(x) hweight64 ((x) & 0xfffful)
321 #define hweight8(x) hweight64 ((x) & 0xfful)
322
323 #endif /* __KERNEL__ */
324
325 /*
326 * Find next zero bit in a bitmap reasonably efficiently..
327 */
328 static inline int
329 find_next_zero_bit (void *addr, unsigned long size, unsigned long offset)
330 {
331 unsigned long *p = ((unsigned long *) addr) + (offset >> 6);
332 unsigned long result = offset & ~63UL;
333 unsigned long tmp;
334
335 if (offset >= size)
336 return size;
337 size -= result;
338 offset &= 63UL;
339 if (offset) {
340 tmp = *(p++);
341 tmp |= ~0UL >> (64-offset);
342 if (size < 64)
343 goto found_first;
344 if (~tmp)
345 goto found_middle;
346 size -= 64;
347 result += 64;
348 }
349 while (size & ~63UL) {
350 if (~(tmp = *(p++)))
351 goto found_middle;
352 result += 64;
353 size -= 64;
354 }
355 if (!size)
356 return result;
357 tmp = *p;
358 found_first:
359 tmp |= ~0UL << size;
360 found_middle:
361 return result + ffz(tmp);
362 }
363
364 /*
365 * The optimizer actually does good code for this case..
366 */
367 #define find_first_zero_bit(addr, size) find_next_zero_bit((addr), (size), 0)
368
369 #ifdef __KERNEL__
370
371 #define ext2_set_bit test_and_set_bit
372 #define ext2_clear_bit test_and_clear_bit
373 #define ext2_test_bit test_bit
374 #define ext2_find_first_zero_bit find_first_zero_bit
375 #define ext2_find_next_zero_bit find_next_zero_bit
376
377 /* Bitmap functions for the minix filesystem. */
378 #define minix_test_and_set_bit(nr,addr) test_and_set_bit(nr,addr)
379 #define minix_set_bit(nr,addr) set_bit(nr,addr)
380 #define minix_test_and_clear_bit(nr,addr) test_and_clear_bit(nr,addr)
381 #define minix_test_bit(nr,addr) test_bit(nr,addr)
382 #define minix_find_first_zero_bit(addr,size) find_first_zero_bit(addr,size)
383
384 #endif /* __KERNEL__ */
385
386 #endif /* _ASM_IA64_BITOPS_H */
387