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
6 * Copyright (c) 1994 - 1997, 99, 2000, 06, 07 Ralf Baechle (ralf@linux-mips.org)
7 * Copyright (c) 1999, 2000 Silicon Graphics, Inc.
12 #ifndef _LINUX_BITOPS_H
13 #error only <linux/bitops.h> can be included directly
16 #include <linux/compiler.h>
17 #include <linux/types.h>
18 #include <asm/barrier.h>
19 #include <asm/byteorder.h> /* sigh ... */
20 #include <asm/cpu-features.h>
21 #include <asm/sgidefs.h>
24 #if _MIPS_SZLONG == 32
26 #define SZLONG_MASK 31UL
31 #elif _MIPS_SZLONG == 64
33 #define SZLONG_MASK 63UL
41 * clear_bit() doesn't provide any barrier for the compiler.
43 #define smp_mb__before_clear_bit() smp_mb__before_llsc()
44 #define smp_mb__after_clear_bit() smp_llsc_mb()
48 * These are the "slower" versions of the functions and are in bitops.c.
49 * These functions call raw_local_irq_{save,restore}().
51 void __mips_set_bit(unsigned long nr
, volatile unsigned long *addr
);
52 void __mips_clear_bit(unsigned long nr
, volatile unsigned long *addr
);
53 void __mips_change_bit(unsigned long nr
, volatile unsigned long *addr
);
54 int __mips_test_and_set_bit(unsigned long nr
,
55 volatile unsigned long *addr
);
56 int __mips_test_and_set_bit_lock(unsigned long nr
,
57 volatile unsigned long *addr
);
58 int __mips_test_and_clear_bit(unsigned long nr
,
59 volatile unsigned long *addr
);
60 int __mips_test_and_change_bit(unsigned long nr
,
61 volatile unsigned long *addr
);
65 * set_bit - Atomically set a bit in memory
67 * @addr: the address to start counting from
69 * This function is atomic and may not be reordered. See __set_bit()
70 * if you do not require the atomic guarantees.
71 * Note that @nr may be almost arbitrarily large; this function is not
72 * restricted to acting on a single-word quantity.
74 static inline void set_bit(unsigned long nr
, volatile unsigned long *addr
)
76 unsigned long *m
= ((unsigned long *) addr
) + (nr
>> SZLONG_LOG
);
77 int bit
= nr
& SZLONG_MASK
;
80 if (kernel_uses_llsc
&& R10000_LLSC_WAR
) {
83 "1: " __LL
"%0, %1 # set_bit \n"
88 : "=&r" (temp
), "=m" (*m
)
89 : "ir" (1UL << bit
), "m" (*m
));
90 #ifdef CONFIG_CPU_MIPSR2
91 } else if (kernel_uses_llsc
&& __builtin_constant_p(bit
)) {
94 " " __LL
"%0, %1 # set_bit \n"
95 " " __INS
"%0, %3, %2, 1 \n"
97 : "=&r" (temp
), "+m" (*m
)
98 : "ir" (bit
), "r" (~0));
99 } while (unlikely(!temp
));
100 #endif /* CONFIG_CPU_MIPSR2 */
101 } else if (kernel_uses_llsc
) {
103 __asm__
__volatile__(
105 " " __LL
"%0, %1 # set_bit \n"
109 : "=&r" (temp
), "+m" (*m
)
110 : "ir" (1UL << bit
));
111 } while (unlikely(!temp
));
113 __mips_set_bit(nr
, addr
);
117 * clear_bit - Clears a bit in memory
119 * @addr: Address to start counting from
121 * clear_bit() is atomic and may not be reordered. However, it does
122 * not contain a memory barrier, so if it is used for locking purposes,
123 * you should call smp_mb__before_clear_bit() and/or smp_mb__after_clear_bit()
124 * in order to ensure changes are visible on other processors.
126 static inline void clear_bit(unsigned long nr
, volatile unsigned long *addr
)
128 unsigned long *m
= ((unsigned long *) addr
) + (nr
>> SZLONG_LOG
);
129 int bit
= nr
& SZLONG_MASK
;
132 if (kernel_uses_llsc
&& R10000_LLSC_WAR
) {
133 __asm__
__volatile__(
135 "1: " __LL
"%0, %1 # clear_bit \n"
140 : "=&r" (temp
), "+m" (*m
)
141 : "ir" (~(1UL << bit
)));
142 #ifdef CONFIG_CPU_MIPSR2
143 } else if (kernel_uses_llsc
&& __builtin_constant_p(bit
)) {
145 __asm__
__volatile__(
146 " " __LL
"%0, %1 # clear_bit \n"
147 " " __INS
"%0, $0, %2, 1 \n"
149 : "=&r" (temp
), "+m" (*m
)
151 } while (unlikely(!temp
));
152 #endif /* CONFIG_CPU_MIPSR2 */
153 } else if (kernel_uses_llsc
) {
155 __asm__
__volatile__(
157 " " __LL
"%0, %1 # clear_bit \n"
161 : "=&r" (temp
), "+m" (*m
)
162 : "ir" (~(1UL << bit
)));
163 } while (unlikely(!temp
));
165 __mips_clear_bit(nr
, addr
);
169 * clear_bit_unlock - Clears a bit in memory
171 * @addr: Address to start counting from
173 * clear_bit() is atomic and implies release semantics before the memory
174 * operation. It can be used for an unlock.
176 static inline void clear_bit_unlock(unsigned long nr
, volatile unsigned long *addr
)
178 smp_mb__before_clear_bit();
183 * change_bit - Toggle a bit in memory
185 * @addr: Address to start counting from
187 * change_bit() is atomic and may not be reordered.
188 * Note that @nr may be almost arbitrarily large; this function is not
189 * restricted to acting on a single-word quantity.
191 static inline void change_bit(unsigned long nr
, volatile unsigned long *addr
)
193 int bit
= nr
& SZLONG_MASK
;
195 if (kernel_uses_llsc
&& R10000_LLSC_WAR
) {
196 unsigned long *m
= ((unsigned long *) addr
) + (nr
>> SZLONG_LOG
);
199 __asm__
__volatile__(
201 "1: " __LL
"%0, %1 # change_bit \n"
206 : "=&r" (temp
), "+m" (*m
)
207 : "ir" (1UL << bit
));
208 } else if (kernel_uses_llsc
) {
209 unsigned long *m
= ((unsigned long *) addr
) + (nr
>> SZLONG_LOG
);
213 __asm__
__volatile__(
215 " " __LL
"%0, %1 # change_bit \n"
219 : "=&r" (temp
), "+m" (*m
)
220 : "ir" (1UL << bit
));
221 } while (unlikely(!temp
));
223 __mips_change_bit(nr
, addr
);
227 * test_and_set_bit - Set a bit and return its old value
229 * @addr: Address to count from
231 * This operation is atomic and cannot be reordered.
232 * It also implies a memory barrier.
234 static inline int test_and_set_bit(unsigned long nr
,
235 volatile unsigned long *addr
)
237 int bit
= nr
& SZLONG_MASK
;
240 smp_mb__before_llsc();
242 if (kernel_uses_llsc
&& R10000_LLSC_WAR
) {
243 unsigned long *m
= ((unsigned long *) addr
) + (nr
>> SZLONG_LOG
);
246 __asm__
__volatile__(
248 "1: " __LL
"%0, %1 # test_and_set_bit \n"
254 : "=&r" (temp
), "+m" (*m
), "=&r" (res
)
257 } else if (kernel_uses_llsc
) {
258 unsigned long *m
= ((unsigned long *) addr
) + (nr
>> SZLONG_LOG
);
262 __asm__
__volatile__(
264 " " __LL
"%0, %1 # test_and_set_bit \n"
268 : "=&r" (temp
), "+m" (*m
), "=&r" (res
)
271 } while (unlikely(!res
));
273 res
= temp
& (1UL << bit
);
275 res
= __mips_test_and_set_bit(nr
, addr
);
283 * test_and_set_bit_lock - Set a bit and return its old value
285 * @addr: Address to count from
287 * This operation is atomic and implies acquire ordering semantics
288 * after the memory operation.
290 static inline int test_and_set_bit_lock(unsigned long nr
,
291 volatile unsigned long *addr
)
293 int bit
= nr
& SZLONG_MASK
;
296 if (kernel_uses_llsc
&& R10000_LLSC_WAR
) {
297 unsigned long *m
= ((unsigned long *) addr
) + (nr
>> SZLONG_LOG
);
300 __asm__
__volatile__(
302 "1: " __LL
"%0, %1 # test_and_set_bit \n"
308 : "=&r" (temp
), "+m" (*m
), "=&r" (res
)
311 } else if (kernel_uses_llsc
) {
312 unsigned long *m
= ((unsigned long *) addr
) + (nr
>> SZLONG_LOG
);
316 __asm__
__volatile__(
318 " " __LL
"%0, %1 # test_and_set_bit \n"
322 : "=&r" (temp
), "+m" (*m
), "=&r" (res
)
325 } while (unlikely(!res
));
327 res
= temp
& (1UL << bit
);
329 res
= __mips_test_and_set_bit_lock(nr
, addr
);
336 * test_and_clear_bit - Clear a bit and return its old value
338 * @addr: Address to count from
340 * This operation is atomic and cannot be reordered.
341 * It also implies a memory barrier.
343 static inline int test_and_clear_bit(unsigned long nr
,
344 volatile unsigned long *addr
)
346 int bit
= nr
& SZLONG_MASK
;
349 smp_mb__before_llsc();
351 if (kernel_uses_llsc
&& R10000_LLSC_WAR
) {
352 unsigned long *m
= ((unsigned long *) addr
) + (nr
>> SZLONG_LOG
);
355 __asm__
__volatile__(
357 "1: " __LL
"%0, %1 # test_and_clear_bit \n"
364 : "=&r" (temp
), "+m" (*m
), "=&r" (res
)
367 #ifdef CONFIG_CPU_MIPSR2
368 } else if (kernel_uses_llsc
&& __builtin_constant_p(nr
)) {
369 unsigned long *m
= ((unsigned long *) addr
) + (nr
>> SZLONG_LOG
);
373 __asm__
__volatile__(
374 " " __LL
"%0, %1 # test_and_clear_bit \n"
375 " " __EXT
"%2, %0, %3, 1 \n"
376 " " __INS
"%0, $0, %3, 1 \n"
378 : "=&r" (temp
), "+m" (*m
), "=&r" (res
)
381 } while (unlikely(!temp
));
383 } else if (kernel_uses_llsc
) {
384 unsigned long *m
= ((unsigned long *) addr
) + (nr
>> SZLONG_LOG
);
388 __asm__
__volatile__(
390 " " __LL
"%0, %1 # test_and_clear_bit \n"
395 : "=&r" (temp
), "+m" (*m
), "=&r" (res
)
398 } while (unlikely(!res
));
400 res
= temp
& (1UL << bit
);
402 res
= __mips_test_and_clear_bit(nr
, addr
);
410 * test_and_change_bit - Change a bit and return its old value
412 * @addr: Address to count from
414 * This operation is atomic and cannot be reordered.
415 * It also implies a memory barrier.
417 static inline int test_and_change_bit(unsigned long nr
,
418 volatile unsigned long *addr
)
420 int bit
= nr
& SZLONG_MASK
;
423 smp_mb__before_llsc();
425 if (kernel_uses_llsc
&& R10000_LLSC_WAR
) {
426 unsigned long *m
= ((unsigned long *) addr
) + (nr
>> SZLONG_LOG
);
429 __asm__
__volatile__(
431 "1: " __LL
"%0, %1 # test_and_change_bit \n"
437 : "=&r" (temp
), "+m" (*m
), "=&r" (res
)
440 } else if (kernel_uses_llsc
) {
441 unsigned long *m
= ((unsigned long *) addr
) + (nr
>> SZLONG_LOG
);
445 __asm__
__volatile__(
447 " " __LL
"%0, %1 # test_and_change_bit \n"
449 " " __SC
"\t%2, %1 \n"
451 : "=&r" (temp
), "+m" (*m
), "=&r" (res
)
454 } while (unlikely(!res
));
456 res
= temp
& (1UL << bit
);
458 res
= __mips_test_and_change_bit(nr
, addr
);
465 #include <asm-generic/bitops/non-atomic.h>
468 * __clear_bit_unlock - Clears a bit in memory
470 * @addr: Address to start counting from
472 * __clear_bit() is non-atomic and implies release semantics before the memory
473 * operation. It can be used for an unlock if no other CPUs can concurrently
474 * modify other bits in the word.
476 static inline void __clear_bit_unlock(unsigned long nr
, volatile unsigned long *addr
)
479 __clear_bit(nr
, addr
);
483 * Return the bit position (0..63) of the most significant 1 bit in a word
484 * Returns -1 if no 1 bit exists
486 static inline unsigned long __fls(unsigned long word
)
490 if (BITS_PER_LONG
== 32 &&
491 __builtin_constant_p(cpu_has_clo_clz
) && cpu_has_clo_clz
) {
503 if (BITS_PER_LONG
== 64 &&
504 __builtin_constant_p(cpu_has_mips64
) && cpu_has_mips64
) {
516 num
= BITS_PER_LONG
- 1;
518 #if BITS_PER_LONG == 64
519 if (!(word
& (~0ul << 32))) {
524 if (!(word
& (~0ul << (BITS_PER_LONG
-16)))) {
528 if (!(word
& (~0ul << (BITS_PER_LONG
-8)))) {
532 if (!(word
& (~0ul << (BITS_PER_LONG
-4)))) {
536 if (!(word
& (~0ul << (BITS_PER_LONG
-2)))) {
540 if (!(word
& (~0ul << (BITS_PER_LONG
-1))))
546 * __ffs - find first bit in word.
547 * @word: The word to search
549 * Returns 0..SZLONG-1
550 * Undefined if no bit exists, so code should check against 0 first.
552 static inline unsigned long __ffs(unsigned long word
)
554 return __fls(word
& -word
);
558 * fls - find last bit set.
559 * @word: The word to search
561 * This is defined the same way as ffs.
562 * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32.
564 static inline int fls(int x
)
568 if (__builtin_constant_p(cpu_has_clo_clz
) && cpu_has_clo_clz
) {
569 __asm__("clz %0, %1" : "=r" (x
) : "r" (x
));
577 if (!(x
& 0xffff0000u
)) {
581 if (!(x
& 0xff000000u
)) {
585 if (!(x
& 0xf0000000u
)) {
589 if (!(x
& 0xc0000000u
)) {
593 if (!(x
& 0x80000000u
)) {
600 #include <asm-generic/bitops/fls64.h>
603 * ffs - find first bit set.
604 * @word: The word to search
606 * This is defined the same way as
607 * the libc and compiler builtin ffs routines, therefore
608 * differs in spirit from the above ffz (man ffs).
610 static inline int ffs(int word
)
615 return fls(word
& -word
);
618 #include <asm-generic/bitops/ffz.h>
619 #include <asm-generic/bitops/find.h>
623 #include <asm-generic/bitops/sched.h>
625 #include <asm/arch_hweight.h>
626 #include <asm-generic/bitops/const_hweight.h>
628 #include <asm-generic/bitops/le.h>
629 #include <asm-generic/bitops/ext2-atomic.h>
631 #endif /* __KERNEL__ */
633 #endif /* _ASM_BITOPS_H */