File: /usr/src/linux/include/asm-mips64/bitops.h
1 /*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (c) 1994, 95, 96, 97, 98, 99, 2000 Ralf Baechle
7 * Copyright (c) 1999, 2000 Silicon Graphics, Inc.
8 */
9 #ifndef _ASM_BITOPS_H
10 #define _ASM_BITOPS_H
11
12 #include <linux/types.h>
13 #include <linux/byteorder/swab.h> /* sigh ... */
14
15 #ifndef __KERNEL__
16 #error "Don't do this, sucker ..."
17 #endif
18
19 #include <asm/system.h>
20 #include <asm/sgidefs.h>
21 #include <asm/mipsregs.h>
22
23 /*
24 * set_bit - Atomically set a bit in memory
25 * @nr: the bit to set
26 * @addr: the address to start counting from
27 *
28 * This function is atomic and may not be reordered. See __set_bit()
29 * if you do not require the atomic guarantees.
30 * Note that @nr may be almost arbitrarily large; this function is not
31 * restricted to acting on a single-word quantity.
32 */
33 extern __inline__ void
34 set_bit(unsigned long nr, volatile void *addr)
35 {
36 unsigned long *m = ((unsigned long *) addr) + (nr >> 6);
37 unsigned long temp;
38
39 __asm__ __volatile__(
40 "1:\tlld\t%0, %1\t\t# set_bit\n\t"
41 "or\t%0, %2\n\t"
42 "scd\t%0, %1\n\t"
43 "beqz\t%0, 1b"
44 : "=&r" (temp), "=m" (*m)
45 : "ir" (1UL << (nr & 0x3f)), "m" (*m)
46 : "memory");
47 }
48
49 /*
50 * __set_bit - Set a bit in memory
51 * @nr: the bit to set
52 * @addr: the address to start counting from
53 *
54 * Unlike set_bit(), this function is non-atomic and may be reordered.
55 * If it's called on the same region of memory simultaneously, the effect
56 * may be that only one operation succeeds.
57 */
58 extern __inline__ void __set_bit(int nr, volatile void * addr)
59 {
60 unsigned long * m = ((unsigned long *) addr) + (nr >> 6);
61
62 *m |= 1UL << (nr & 0x3f);
63 }
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 extern __inline__ void
76 clear_bit(unsigned long nr, volatile void *addr)
77 {
78 unsigned long *m = ((unsigned long *) addr) + (nr >> 6);
79 unsigned long temp;
80
81 __asm__ __volatile__(
82 "1:\tlld\t%0, %1\t\t# clear_bit\n\t"
83 "and\t%0, %2\n\t"
84 "scd\t%0, %1\n\t"
85 "beqz\t%0, 1b\n\t"
86 : "=&r" (temp), "=m" (*m)
87 : "ir" (~(1UL << (nr & 0x3f))), "m" (*m));
88 }
89
90 #define smp_mb__before_clear_bit() barrier()
91 #define smp_mb__after_clear_bit() barrier()
92
93 /*
94 * change_bit - Toggle a bit in memory
95 * @nr: Bit to clear
96 * @addr: Address to start counting from
97 *
98 * change_bit() is atomic and may not be reordered.
99 * Note that @nr may be almost arbitrarily large; this function is not
100 * restricted to acting on a single-word quantity.
101 */
102 extern __inline__ void
103 change_bit(unsigned long nr, volatile void *addr)
104 {
105 unsigned long *m = ((unsigned long *) addr) + (nr >> 6);
106 unsigned long temp;
107
108 __asm__ __volatile__(
109 "1:\tlld\t%0, %1\t\t# change_bit\n\t"
110 "xor\t%0, %2\n\t"
111 "scd\t%0, %1\n\t"
112 "beqz\t%0, 1b"
113 :"=&r" (temp), "=m" (*m)
114 :"ir" (1UL << (nr & 0x3f)), "m" (*m));
115 }
116
117 /*
118 * __change_bit - Toggle a bit in memory
119 * @nr: the bit to set
120 * @addr: the address to start counting from
121 *
122 * Unlike change_bit(), this function is non-atomic and may be reordered.
123 * If it's called on the same region of memory simultaneously, the effect
124 * may be that only one operation succeeds.
125 */
126 extern __inline__ void __change_bit(int nr, volatile void * addr)
127 {
128 unsigned long * m = ((unsigned long *) addr) + (nr >> 6);
129
130 *m ^= 1UL << (nr & 0x3f);
131 }
132
133 /*
134 * test_and_set_bit - Set a bit and return its old value
135 * @nr: Bit to set
136 * @addr: Address to count from
137 *
138 * This operation is atomic and cannot be reordered.
139 * It also implies a memory barrier.
140 */
141 extern __inline__ unsigned long
142 test_and_set_bit(unsigned long nr, volatile void *addr)
143 {
144 unsigned long *m = ((unsigned long *) addr) + (nr >> 6);
145 unsigned long temp, res;
146
147 __asm__ __volatile__(
148 ".set\tnoreorder\t\t# test_and_set_bit\n"
149 "1:\tlld\t%0, %1\n\t"
150 "or\t%2, %0, %3\n\t"
151 "scd\t%2, %1\n\t"
152 "beqz\t%2, 1b\n\t"
153 " and\t%2, %0, %3\n\t"
154 ".set\treorder"
155 : "=&r" (temp), "=m" (*m), "=&r" (res)
156 : "r" (1UL << (nr & 0x3f)), "m" (*m)
157 : "memory");
158
159 return res != 0;
160 }
161
162 /*
163 * __test_and_set_bit - Set a bit and return its old value
164 * @nr: Bit to set
165 * @addr: Address to count from
166 *
167 * This operation is non-atomic and can be reordered.
168 * If two examples of this operation race, one can appear to succeed
169 * but actually fail. You must protect multiple accesses with a lock.
170 */
171 extern __inline__ int
172 __test_and_set_bit(int nr, volatile void * addr)
173 {
174 unsigned long mask, retval;
175 long *a = (unsigned long *) addr;
176
177 a += (nr >> 6);
178 mask = 1UL << (nr & 0x3f);
179 retval = ((mask & *a) != 0);
180 *a |= mask;
181
182 return retval;
183 }
184
185 /*
186 * test_and_clear_bit - Clear a bit and return its old value
187 * @nr: Bit to set
188 * @addr: Address to count from
189 *
190 * This operation is atomic and cannot be reordered.
191 * It also implies a memory barrier.
192 */
193 extern __inline__ unsigned long
194 test_and_clear_bit(unsigned long nr, volatile void *addr)
195 {
196 unsigned long *m = ((unsigned long *) addr) + (nr >> 6);
197 unsigned long temp, res;
198
199 __asm__ __volatile__(
200 ".set\tnoreorder\t\t# test_and_clear_bit\n"
201 "1:\tlld\t%0, %1\n\t"
202 "or\t%2, %0, %3\n\t"
203 "xor\t%2, %3\n\t"
204 "scd\t%2, %1\n\t"
205 "beqz\t%2, 1b\n\t"
206 " and\t%2, %0, %3\n\t"
207 ".set\treorder"
208 : "=&r" (temp), "=m" (*m), "=&r" (res)
209 : "r" (1UL << (nr & 0x3f)), "m" (*m)
210 : "memory");
211
212 return res != 0;
213 }
214
215 /*
216 * __test_and_clear_bit - Clear a bit and return its old value
217 * @nr: Bit to set
218 * @addr: Address to count from
219 *
220 * This operation is non-atomic and can be reordered.
221 * If two examples of this operation race, one can appear to succeed
222 * but actually fail. You must protect multiple accesses with a lock.
223 */
224 extern __inline__ int
225 __test_and_clear_bit(int nr, volatile void * addr)
226 {
227 unsigned long mask, retval;
228 unsigned long *a = (unsigned long *) addr;
229
230 a += (nr >> 6);
231 mask = 1UL << (nr & 0x3f);
232 retval = ((mask & *a) != 0);
233 *a &= ~mask;
234
235 return retval;
236 }
237
238 /*
239 * test_and_change_bit - Change a bit and return its new value
240 * @nr: Bit to set
241 * @addr: Address to count from
242 *
243 * This operation is atomic and cannot be reordered.
244 * It also implies a memory barrier.
245 */
246 extern __inline__ unsigned long
247 test_and_change_bit(unsigned long nr, volatile void *addr)
248 {
249 unsigned long *m = ((unsigned long *) addr) + (nr >> 6);
250 unsigned long temp, res;
251
252 __asm__ __volatile__(
253 ".set\tnoreorder\t\t# test_and_change_bit\n"
254 "1:\tlld\t%0, %1\n\t"
255 "xor\t%2, %0, %3\n\t"
256 "scd\t%2, %1\n\t"
257 "beqz\t%2, 1b\n\t"
258 " and\t%2, %0, %3\n\t"
259 ".set\treorder"
260 : "=&r" (temp), "=m" (*m), "=&r" (res)
261 : "r" (1UL << (nr & 0x3f)), "m" (*m)
262 : "memory");
263
264 return res != 0;
265 }
266
267 /*
268 * __test_and_change_bit - Change a bit and return its old value
269 * @nr: Bit to set
270 * @addr: Address to count from
271 *
272 * This operation is non-atomic and can be reordered.
273 * If two examples of this operation race, one can appear to succeed
274 * but actually fail. You must protect multiple accesses with a lock.
275 */
276 extern __inline__ int
277 __test_and_change_bit(int nr, volatile void * addr)
278 {
279 unsigned long mask, retval;
280 unsigned long *a = (unsigned long *) addr;
281
282 a += (nr >> 6);
283 mask = 1UL << (nr & 0x3f);
284 retval = ((mask & *a) != 0);
285 *a ^= mask;
286
287 return retval;
288 }
289 /*
290 * test_bit - Determine whether a bit is set
291 * @nr: bit number to test
292 * @addr: Address to start counting from
293 */
294 extern __inline__ unsigned long
295 test_bit(int nr, volatile void * addr)
296 {
297 return 1UL & (((volatile unsigned long *) addr)[nr >> 6] >> (nr & 0x3f));
298 }
299
300 #ifndef __MIPSEB__
301
302 /* Little endian versions. */
303
304 /*
305 * find_first_zero_bit - find the first zero bit in a memory region
306 * @addr: The address to start the search at
307 * @size: The maximum size to search
308 *
309 * Returns the bit-number of the first zero bit, not the number of the byte
310 * containing a bit.
311 */
312 extern __inline__ int
313 find_first_zero_bit (void *addr, unsigned size)
314 {
315 unsigned long dummy;
316 int res;
317
318 if (!size)
319 return 0;
320
321 __asm__ (".set\tnoreorder\n\t"
322 ".set\tnoat\n"
323 "1:\tsubu\t$1,%6,%0\n\t"
324 "blez\t$1,2f\n\t"
325 "lw\t$1,(%5)\n\t"
326 "addiu\t%5,4\n\t"
327 #if (_MIPS_ISA == _MIPS_ISA_MIPS2 ) || (_MIPS_ISA == _MIPS_ISA_MIPS3 ) || \
328 (_MIPS_ISA == _MIPS_ISA_MIPS4 ) || (_MIPS_ISA == _MIPS_ISA_MIPS5 ) || \
329 (_MIPS_ISA == _MIPS_ISA_MIPS32) || (_MIPS_ISA == _MIPS_ISA_MIPS64)
330 "beql\t%1,$1,1b\n\t"
331 "addiu\t%0,32\n\t"
332 #else
333 "addiu\t%0,32\n\t"
334 "beq\t%1,$1,1b\n\t"
335 "nop\n\t"
336 "subu\t%0,32\n\t"
337 #endif
338 "li\t%1,1\n"
339 "1:\tand\t%2,$1,%1\n\t"
340 "beqz\t%2,2f\n\t"
341 "sll\t%1,%1,1\n\t"
342 "bnez\t%1,1b\n\t"
343 "add\t%0,%0,1\n\t"
344 ".set\tat\n\t"
345 ".set\treorder\n"
346 "2:"
347 : "=r" (res), "=r" (dummy), "=r" (addr)
348 : "0" ((signed int) 0), "1" ((unsigned int) 0xffffffff),
349 "2" (addr), "r" (size)
350 : "$1");
351
352 return res;
353 }
354
355 /*
356 * find_next_zero_bit - find the first zero bit in a memory region
357 * @addr: The address to base the search on
358 * @offset: The bitnumber to start searching at
359 * @size: The maximum size to search
360 */
361 extern __inline__ int
362 find_next_zero_bit (void * addr, int size, int offset)
363 {
364 unsigned int *p = ((unsigned int *) addr) + (offset >> 5);
365 int set = 0, bit = offset & 31, res;
366 unsigned long dummy;
367
368 if (bit) {
369 /*
370 * Look for zero in first byte
371 */
372 __asm__(".set\tnoreorder\n\t"
373 ".set\tnoat\n"
374 "1:\tand\t$1,%4,%1\n\t"
375 "beqz\t$1,1f\n\t"
376 "sll\t%1,%1,1\n\t"
377 "bnez\t%1,1b\n\t"
378 "addiu\t%0,1\n\t"
379 ".set\tat\n\t"
380 ".set\treorder\n"
381 "1:"
382 : "=r" (set), "=r" (dummy)
383 : "0" (0), "1" (1 << bit), "r" (*p)
384 : "$1");
385 if (set < (32 - bit))
386 return set + offset;
387 set = 32 - bit;
388 p++;
389 }
390 /*
391 * No zero yet, search remaining full bytes for a zero
392 */
393 res = find_first_zero_bit(p, size - 32 * (p - (unsigned int *) addr));
394 return offset + set + res;
395 }
396
397 #endif /* !(__MIPSEB__) */
398
399 /*
400 * ffz - find first zero in word.
401 * @word: The word to search
402 *
403 * Undefined if no zero exists, so code should check against ~0UL first.
404 */
405 extern __inline__ unsigned long ffz(unsigned long word)
406 {
407 unsigned long k;
408
409 word = ~word;
410 k = 63;
411 if (word & 0x00000000ffffffffUL) { k -= 32; word <<= 32; }
412 if (word & 0x0000ffff00000000UL) { k -= 16; word <<= 16; }
413 if (word & 0x00ff000000000000UL) { k -= 8; word <<= 8; }
414 if (word & 0x0f00000000000000UL) { k -= 4; word <<= 4; }
415 if (word & 0x3000000000000000UL) { k -= 2; word <<= 2; }
416 if (word & 0x4000000000000000UL) { k -= 1; }
417
418 return k;
419 }
420
421 #ifdef __KERNEL__
422
423
424 /*
425 * ffs - find first bit set
426 * @x: the word to search
427 *
428 * This is defined the same way as
429 * the libc and compiler builtin ffs routines, therefore
430 * differs in spirit from the above ffz (man ffs).
431 */
432
433 #define ffs(x) generic_ffs(x)
434
435 /*
436 * hweightN - returns the hamming weight of a N-bit word
437 * @x: the word to weigh
438 *
439 * The Hamming Weight of a number is the total number of bits set in it.
440 */
441
442 #define hweight32(x) generic_hweight32(x)
443 #define hweight16(x) generic_hweight16(x)
444 #define hweight8(x) generic_hweight8(x)
445
446 #endif /* __KERNEL__ */
447
448 #ifdef __MIPSEB__
449
450 /*
451 * find_next_zero_bit - find the first zero bit in a memory region
452 * @addr: The address to base the search on
453 * @offset: The bitnumber to start searching at
454 * @size: The maximum size to search
455 */
456 extern __inline__ unsigned long
457 find_next_zero_bit(void *addr, unsigned long size, unsigned long offset)
458 {
459 unsigned long *p = ((unsigned long *) addr) + (offset >> 6);
460 unsigned long result = offset & ~63UL;
461 unsigned long tmp;
462
463 if (offset >= size)
464 return size;
465 size -= result;
466 offset &= 63UL;
467 if (offset) {
468 tmp = *(p++);
469 tmp |= ~0UL >> (64-offset);
470 if (size < 64)
471 goto found_first;
472 if (~tmp)
473 goto found_middle;
474 size -= 64;
475 result += 64;
476 }
477 while (size & ~63UL) {
478 if (~(tmp = *(p++)))
479 goto found_middle;
480 result += 64;
481 size -= 64;
482 }
483 if (!size)
484 return result;
485 tmp = *p;
486
487 found_first:
488 tmp |= ~0UL << size;
489 found_middle:
490 return result + ffz(tmp);
491 }
492
493 #define find_first_zero_bit(addr, size) \
494 find_next_zero_bit((addr), (size), 0)
495
496 #endif /* (__MIPSEB__) */
497
498 #ifdef __KERNEL__
499
500 /* Now for the ext2 filesystem bit operations and helper routines. */
501
502 #ifdef __MIPSEB__
503
504 extern inline int
505 ext2_set_bit(int nr,void * addr)
506 {
507 int mask, retval, flags;
508 unsigned char *ADDR = (unsigned char *) addr;
509
510 ADDR += nr >> 3;
511 mask = 1 << (nr & 0x07);
512 save_and_cli(flags);
513 retval = (mask & *ADDR) != 0;
514 *ADDR |= mask;
515 restore_flags(flags);
516 return retval;
517 }
518
519 extern inline int
520 ext2_clear_bit(int nr, void * addr)
521 {
522 int mask, retval, flags;
523 unsigned char *ADDR = (unsigned char *) addr;
524
525 ADDR += nr >> 3;
526 mask = 1 << (nr & 0x07);
527 save_and_cli(flags);
528 retval = (mask & *ADDR) != 0;
529 *ADDR &= ~mask;
530 restore_flags(flags);
531 return retval;
532 }
533
534 extern inline int
535 ext2_test_bit(int nr, const void * addr)
536 {
537 int mask;
538 const unsigned char *ADDR = (const unsigned char *) addr;
539
540 ADDR += nr >> 3;
541 mask = 1 << (nr & 0x07);
542 return ((mask & *ADDR) != 0);
543 }
544
545 #define ext2_find_first_zero_bit(addr, size) \
546 ext2_find_next_zero_bit((addr), (size), 0)
547
548 extern inline unsigned int
549 ext2_find_next_zero_bit(void *addr, unsigned long size, unsigned long offset)
550 {
551 unsigned int *p = ((unsigned int *) addr) + (offset >> 5);
552 unsigned int result = offset & ~31UL;
553 unsigned int tmp;
554
555 if (offset >= size)
556 return size;
557 size -= result;
558 offset &= 31UL;
559 if(offset) {
560 /* We hold the little endian value in tmp, but then the
561 * shift is illegal. So we could keep a big endian value
562 * in tmp, like this:
563 *
564 * tmp = __swab32(*(p++));
565 * tmp |= ~0UL >> (32-offset);
566 *
567 * but this would decrease preformance, so we change the
568 * shift:
569 */
570 tmp = *(p++);
571 tmp |= __swab32(~0UL >> (32-offset));
572 if(size < 32)
573 goto found_first;
574 if(~tmp)
575 goto found_middle;
576 size -= 32;
577 result += 32;
578 }
579 while(size & ~31UL) {
580 if(~(tmp = *(p++)))
581 goto found_middle;
582 result += 32;
583 size -= 32;
584 }
585 if(!size)
586 return result;
587 tmp = *p;
588
589 found_first:
590 /* tmp is little endian, so we would have to swab the shift,
591 * see above. But then we have to swab tmp below for ffz, so
592 * we might as well do this here.
593 */
594 return result + ffz(__swab32(tmp) | (~0UL << size));
595 found_middle:
596 return result + ffz(__swab32(tmp));
597 }
598 #else /* !(__MIPSEB__) */
599
600 /* Native ext2 byte ordering, just collapse using defines. */
601 #define ext2_set_bit(nr, addr) test_and_set_bit((nr), (addr))
602 #define ext2_clear_bit(nr, addr) test_and_clear_bit((nr), (addr))
603 #define ext2_test_bit(nr, addr) test_bit((nr), (addr))
604 #define ext2_find_first_zero_bit(addr, size) find_first_zero_bit((addr), (size))
605 #define ext2_find_next_zero_bit(addr, size, offset) \
606 find_next_zero_bit((addr), (size), (offset))
607
608 #endif /* !(__MIPSEB__) */
609
610 /*
611 * Bitmap functions for the minix filesystem.
612 * FIXME: These assume that Minix uses the native byte/bitorder.
613 * This limits the Minix filesystem's value for data exchange very much.
614 */
615 #define minix_test_and_set_bit(nr,addr) test_and_set_bit(nr,addr)
616 #define minix_set_bit(nr,addr) set_bit(nr,addr)
617 #define minix_test_and_clear_bit(nr,addr) test_and_clear_bit(nr,addr)
618 #define minix_test_bit(nr,addr) test_bit(nr,addr)
619 #define minix_find_first_zero_bit(addr,size) find_first_zero_bit(addr,size)
620
621 #endif /* __KERNEL__ */
622
623 #endif /* _ASM_BITOPS_H */
624