Linux Audio

Check our new training course

Loading...
v3.1
  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 - 1997, 99, 2000, 06, 07  Ralf Baechle (ralf@linux-mips.org)
  7 * Copyright (c) 1999, 2000  Silicon Graphics, Inc.
  8 */
  9#ifndef _ASM_BITOPS_H
 10#define _ASM_BITOPS_H
 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/irqflags.h>
 18#include <linux/types.h>
 
 19#include <asm/barrier.h>
 20#include <asm/bug.h>
 21#include <asm/byteorder.h>		/* sigh ... */
 
 22#include <asm/cpu-features.h>
 23#include <asm/sgidefs.h>
 24#include <asm/war.h>
 25
 26#if _MIPS_SZLONG == 32
 27#define SZLONG_LOG 5
 28#define SZLONG_MASK 31UL
 29#define __LL		"ll	"
 30#define __SC		"sc	"
 31#define __INS		"ins    "
 32#define __EXT		"ext    "
 33#elif _MIPS_SZLONG == 64
 34#define SZLONG_LOG 6
 35#define SZLONG_MASK 63UL
 36#define __LL		"lld	"
 37#define __SC		"scd	"
 38#define __INS		"dins    "
 39#define __EXT		"dext    "
 40#endif
 41
 42/*
 43 * clear_bit() doesn't provide any barrier for the compiler.
 44 */
 45#define smp_mb__before_clear_bit()	smp_mb__before_llsc()
 46#define smp_mb__after_clear_bit()	smp_llsc_mb()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 47
 48/*
 49 * set_bit - Atomically set a bit in memory
 50 * @nr: the bit to set
 51 * @addr: the address to start counting from
 52 *
 53 * This function is atomic and may not be reordered.  See __set_bit()
 54 * if you do not require the atomic guarantees.
 55 * Note that @nr may be almost arbitrarily large; this function is not
 56 * restricted to acting on a single-word quantity.
 57 */
 58static inline void set_bit(unsigned long nr, volatile unsigned long *addr)
 59{
 60	unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
 61	unsigned short bit = nr & SZLONG_MASK;
 62	unsigned long temp;
 63
 64	if (kernel_uses_llsc && R10000_LLSC_WAR) {
 65		__asm__ __volatile__(
 66		"	.set	mips3					\n"
 67		"1:	" __LL "%0, %1			# set_bit	\n"
 68		"	or	%0, %2					\n"
 69		"	" __SC	"%0, %1					\n"
 70		"	beqzl	%0, 1b					\n"
 71		"	.set	mips0					\n"
 72		: "=&r" (temp), "=m" (*m)
 73		: "ir" (1UL << bit), "m" (*m));
 74#ifdef CONFIG_CPU_MIPSR2
 75	} else if (kernel_uses_llsc && __builtin_constant_p(bit)) {
 76		do {
 77			__asm__ __volatile__(
 78			"	" __LL "%0, %1		# set_bit	\n"
 79			"	" __INS "%0, %3, %2, 1			\n"
 80			"	" __SC "%0, %1				\n"
 81			: "=&r" (temp), "+m" (*m)
 82			: "ir" (bit), "r" (~0));
 83		} while (unlikely(!temp));
 84#endif /* CONFIG_CPU_MIPSR2 */
 85	} else if (kernel_uses_llsc) {
 86		do {
 87			__asm__ __volatile__(
 88			"	.set	mips3				\n"
 89			"	" __LL "%0, %1		# set_bit	\n"
 90			"	or	%0, %2				\n"
 91			"	" __SC	"%0, %1				\n"
 92			"	.set	mips0				\n"
 93			: "=&r" (temp), "+m" (*m)
 94			: "ir" (1UL << bit));
 95		} while (unlikely(!temp));
 96	} else {
 97		volatile unsigned long *a = addr;
 98		unsigned long mask;
 99		unsigned long flags;
100
101		a += nr >> SZLONG_LOG;
102		mask = 1UL << bit;
103		raw_local_irq_save(flags);
104		*a |= mask;
105		raw_local_irq_restore(flags);
106	}
 
 
107}
108
109/*
110 * clear_bit - Clears a bit in memory
111 * @nr: Bit to clear
112 * @addr: Address to start counting from
113 *
114 * clear_bit() is atomic and may not be reordered.  However, it does
115 * not contain a memory barrier, so if it is used for locking purposes,
116 * you should call smp_mb__before_clear_bit() and/or smp_mb__after_clear_bit()
117 * in order to ensure changes are visible on other processors.
118 */
119static inline void clear_bit(unsigned long nr, volatile unsigned long *addr)
120{
121	unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
122	unsigned short bit = nr & SZLONG_MASK;
123	unsigned long temp;
124
125	if (kernel_uses_llsc && R10000_LLSC_WAR) {
126		__asm__ __volatile__(
127		"	.set	mips3					\n"
128		"1:	" __LL "%0, %1			# clear_bit	\n"
129		"	and	%0, %2					\n"
130		"	" __SC "%0, %1					\n"
131		"	beqzl	%0, 1b					\n"
132		"	.set	mips0					\n"
133		: "=&r" (temp), "+m" (*m)
134		: "ir" (~(1UL << bit)));
135#ifdef CONFIG_CPU_MIPSR2
136	} else if (kernel_uses_llsc && __builtin_constant_p(bit)) {
137		do {
138			__asm__ __volatile__(
139			"	" __LL "%0, %1		# clear_bit	\n"
140			"	" __INS "%0, $0, %2, 1			\n"
141			"	" __SC "%0, %1				\n"
142			: "=&r" (temp), "+m" (*m)
143			: "ir" (bit));
144		} while (unlikely(!temp));
145#endif /* CONFIG_CPU_MIPSR2 */
146	} else if (kernel_uses_llsc) {
147		do {
148			__asm__ __volatile__(
149			"	.set	mips3				\n"
150			"	" __LL "%0, %1		# clear_bit	\n"
151			"	and	%0, %2				\n"
152			"	" __SC "%0, %1				\n"
153			"	.set	mips0				\n"
154			: "=&r" (temp), "+m" (*m)
155			: "ir" (~(1UL << bit)));
156		} while (unlikely(!temp));
157	} else {
158		volatile unsigned long *a = addr;
159		unsigned long mask;
160		unsigned long flags;
161
162		a += nr >> SZLONG_LOG;
163		mask = 1UL << bit;
164		raw_local_irq_save(flags);
165		*a &= ~mask;
166		raw_local_irq_restore(flags);
167	}
 
 
168}
169
170/*
171 * clear_bit_unlock - Clears a bit in memory
172 * @nr: Bit to clear
173 * @addr: Address to start counting from
174 *
175 * clear_bit() is atomic and implies release semantics before the memory
176 * operation. It can be used for an unlock.
177 */
178static inline void clear_bit_unlock(unsigned long nr, volatile unsigned long *addr)
179{
180	smp_mb__before_clear_bit();
181	clear_bit(nr, addr);
182}
183
184/*
185 * change_bit - Toggle a bit in memory
186 * @nr: Bit to change
187 * @addr: Address to start counting from
188 *
189 * change_bit() is atomic and may not be reordered.
190 * Note that @nr may be almost arbitrarily large; this function is not
191 * restricted to acting on a single-word quantity.
192 */
193static inline void change_bit(unsigned long nr, volatile unsigned long *addr)
194{
195	unsigned short bit = nr & SZLONG_MASK;
 
196
197	if (kernel_uses_llsc && R10000_LLSC_WAR) {
198		unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
199		unsigned long temp;
200
201		__asm__ __volatile__(
202		"	.set	mips3				\n"
203		"1:	" __LL "%0, %1		# change_bit	\n"
204		"	xor	%0, %2				\n"
205		"	" __SC	"%0, %1				\n"
206		"	beqzl	%0, 1b				\n"
207		"	.set	mips0				\n"
208		: "=&r" (temp), "+m" (*m)
209		: "ir" (1UL << bit));
210	} else if (kernel_uses_llsc) {
211		unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
212		unsigned long temp;
213
214		do {
215			__asm__ __volatile__(
216			"	.set	mips3				\n"
217			"	" __LL "%0, %1		# change_bit	\n"
218			"	xor	%0, %2				\n"
219			"	" __SC	"%0, %1				\n"
220			"	.set	mips0				\n"
221			: "=&r" (temp), "+m" (*m)
222			: "ir" (1UL << bit));
223		} while (unlikely(!temp));
224	} else {
225		volatile unsigned long *a = addr;
226		unsigned long mask;
227		unsigned long flags;
228
229		a += nr >> SZLONG_LOG;
230		mask = 1UL << bit;
231		raw_local_irq_save(flags);
232		*a ^= mask;
233		raw_local_irq_restore(flags);
234	}
 
 
235}
236
237/*
238 * test_and_set_bit - Set a bit and return its old value
239 * @nr: Bit to set
240 * @addr: Address to count from
241 *
242 * This operation is atomic and cannot be reordered.
243 * It also implies a memory barrier.
244 */
245static inline int test_and_set_bit(unsigned long nr,
246	volatile unsigned long *addr)
247{
248	unsigned short bit = nr & SZLONG_MASK;
249	unsigned long res;
250
251	smp_mb__before_llsc();
252
253	if (kernel_uses_llsc && R10000_LLSC_WAR) {
254		unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
255		unsigned long temp;
256
257		__asm__ __volatile__(
258		"	.set	mips3					\n"
259		"1:	" __LL "%0, %1		# test_and_set_bit	\n"
260		"	or	%2, %0, %3				\n"
261		"	" __SC	"%2, %1					\n"
262		"	beqzl	%2, 1b					\n"
263		"	and	%2, %0, %3				\n"
264		"	.set	mips0					\n"
265		: "=&r" (temp), "+m" (*m), "=&r" (res)
266		: "r" (1UL << bit)
267		: "memory");
268	} else if (kernel_uses_llsc) {
269		unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
270		unsigned long temp;
271
272		do {
273			__asm__ __volatile__(
274			"	.set	mips3				\n"
275			"	" __LL "%0, %1	# test_and_set_bit	\n"
276			"	or	%2, %0, %3			\n"
277			"	" __SC	"%2, %1				\n"
278			"	.set	mips0				\n"
279			: "=&r" (temp), "+m" (*m), "=&r" (res)
280			: "r" (1UL << bit)
281			: "memory");
282		} while (unlikely(!res));
283
284		res = temp & (1UL << bit);
 
285	} else {
286		volatile unsigned long *a = addr;
287		unsigned long mask;
288		unsigned long flags;
289
290		a += nr >> SZLONG_LOG;
291		mask = 1UL << bit;
292		raw_local_irq_save(flags);
293		res = (mask & *a);
294		*a |= mask;
295		raw_local_irq_restore(flags);
296	}
297
298	smp_llsc_mb();
299
300	return res != 0;
301}
302
303/*
304 * test_and_set_bit_lock - Set a bit and return its old value
305 * @nr: Bit to set
306 * @addr: Address to count from
307 *
308 * This operation is atomic and implies acquire ordering semantics
309 * after the memory operation.
310 */
311static inline int test_and_set_bit_lock(unsigned long nr,
312	volatile unsigned long *addr)
313{
314	unsigned short bit = nr & SZLONG_MASK;
315	unsigned long res;
316
317	if (kernel_uses_llsc && R10000_LLSC_WAR) {
318		unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
319		unsigned long temp;
320
321		__asm__ __volatile__(
322		"	.set	mips3					\n"
323		"1:	" __LL "%0, %1		# test_and_set_bit	\n"
324		"	or	%2, %0, %3				\n"
325		"	" __SC	"%2, %1					\n"
326		"	beqzl	%2, 1b					\n"
327		"	and	%2, %0, %3				\n"
328		"	.set	mips0					\n"
329		: "=&r" (temp), "+m" (*m), "=&r" (res)
330		: "r" (1UL << bit)
331		: "memory");
332	} else if (kernel_uses_llsc) {
333		unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
334		unsigned long temp;
335
336		do {
337			__asm__ __volatile__(
338			"	.set	mips3				\n"
339			"	" __LL "%0, %1	# test_and_set_bit	\n"
340			"	or	%2, %0, %3			\n"
341			"	" __SC	"%2, %1				\n"
342			"	.set	mips0				\n"
343			: "=&r" (temp), "+m" (*m), "=&r" (res)
344			: "r" (1UL << bit)
345			: "memory");
346		} while (unlikely(!res));
347
348		res = temp & (1UL << bit);
349	} else {
350		volatile unsigned long *a = addr;
351		unsigned long mask;
352		unsigned long flags;
353
354		a += nr >> SZLONG_LOG;
355		mask = 1UL << bit;
356		raw_local_irq_save(flags);
357		res = (mask & *a);
358		*a |= mask;
359		raw_local_irq_restore(flags);
360	}
361
362	smp_llsc_mb();
363
364	return res != 0;
365}
 
366/*
367 * test_and_clear_bit - Clear a bit and return its old value
368 * @nr: Bit to clear
369 * @addr: Address to count from
370 *
371 * This operation is atomic and cannot be reordered.
372 * It also implies a memory barrier.
373 */
374static inline int test_and_clear_bit(unsigned long nr,
375	volatile unsigned long *addr)
376{
377	unsigned short bit = nr & SZLONG_MASK;
378	unsigned long res;
379
380	smp_mb__before_llsc();
381
382	if (kernel_uses_llsc && R10000_LLSC_WAR) {
383		unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
384		unsigned long temp;
385
386		__asm__ __volatile__(
387		"	.set	mips3					\n"
388		"1:	" __LL	"%0, %1		# test_and_clear_bit	\n"
389		"	or	%2, %0, %3				\n"
390		"	xor	%2, %3					\n"
391		"	" __SC 	"%2, %1					\n"
392		"	beqzl	%2, 1b					\n"
393		"	and	%2, %0, %3				\n"
394		"	.set	mips0					\n"
395		: "=&r" (temp), "+m" (*m), "=&r" (res)
396		: "r" (1UL << bit)
397		: "memory");
398#ifdef CONFIG_CPU_MIPSR2
399	} else if (kernel_uses_llsc && __builtin_constant_p(nr)) {
400		unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
401		unsigned long temp;
402
403		do {
404			__asm__ __volatile__(
405			"	" __LL	"%0, %1	# test_and_clear_bit	\n"
406			"	" __EXT "%2, %0, %3, 1			\n"
407			"	" __INS	"%0, $0, %3, 1			\n"
408			"	" __SC 	"%0, %1				\n"
409			: "=&r" (temp), "+m" (*m), "=&r" (res)
410			: "ir" (bit)
411			: "memory");
412		} while (unlikely(!temp));
413#endif
414	} else if (kernel_uses_llsc) {
415		unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
416		unsigned long temp;
417
418		do {
419			__asm__ __volatile__(
420			"	.set	mips3				\n"
421			"	" __LL	"%0, %1	# test_and_clear_bit	\n"
422			"	or	%2, %0, %3			\n"
423			"	xor	%2, %3				\n"
424			"	" __SC 	"%2, %1				\n"
425			"	.set	mips0				\n"
426			: "=&r" (temp), "+m" (*m), "=&r" (res)
427			: "r" (1UL << bit)
428			: "memory");
429		} while (unlikely(!res));
430
431		res = temp & (1UL << bit);
432	} else {
433		volatile unsigned long *a = addr;
434		unsigned long mask;
435		unsigned long flags;
436
437		a += nr >> SZLONG_LOG;
438		mask = 1UL << bit;
439		raw_local_irq_save(flags);
440		res = (mask & *a);
441		*a &= ~mask;
442		raw_local_irq_restore(flags);
443	}
444
445	smp_llsc_mb();
446
447	return res != 0;
448}
449
450/*
451 * test_and_change_bit - Change a bit and return its old value
452 * @nr: Bit to change
453 * @addr: Address to count from
454 *
455 * This operation is atomic and cannot be reordered.
456 * It also implies a memory barrier.
457 */
458static inline int test_and_change_bit(unsigned long nr,
459	volatile unsigned long *addr)
460{
461	unsigned short bit = nr & SZLONG_MASK;
462	unsigned long res;
 
463
464	smp_mb__before_llsc();
465
466	if (kernel_uses_llsc && R10000_LLSC_WAR) {
467		unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
468		unsigned long temp;
469
470		__asm__ __volatile__(
471		"	.set	mips3					\n"
472		"1:	" __LL	"%0, %1		# test_and_change_bit	\n"
473		"	xor	%2, %0, %3				\n"
474		"	" __SC	"%2, %1					\n"
475		"	beqzl	%2, 1b					\n"
476		"	and	%2, %0, %3				\n"
477		"	.set	mips0					\n"
478		: "=&r" (temp), "+m" (*m), "=&r" (res)
479		: "r" (1UL << bit)
480		: "memory");
481	} else if (kernel_uses_llsc) {
482		unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
483		unsigned long temp;
484
485		do {
486			__asm__ __volatile__(
487			"	.set	mips3				\n"
488			"	" __LL	"%0, %1	# test_and_change_bit	\n"
489			"	xor	%2, %0, %3			\n"
490			"	" __SC	"\t%2, %1			\n"
491			"	.set	mips0				\n"
492			: "=&r" (temp), "+m" (*m), "=&r" (res)
493			: "r" (1UL << bit)
494			: "memory");
495		} while (unlikely(!res));
496
497		res = temp & (1UL << bit);
 
 
 
498	} else {
499		volatile unsigned long *a = addr;
500		unsigned long mask;
501		unsigned long flags;
502
503		a += nr >> SZLONG_LOG;
504		mask = 1UL << bit;
505		raw_local_irq_save(flags);
506		res = (mask & *a);
507		*a ^= mask;
508		raw_local_irq_restore(flags);
509	}
510
511	smp_llsc_mb();
512
513	return res != 0;
514}
515
 
 
 
516#include <asm-generic/bitops/non-atomic.h>
517
518/*
519 * __clear_bit_unlock - Clears a bit in memory
520 * @nr: Bit to clear
521 * @addr: Address to start counting from
522 *
523 * __clear_bit() is non-atomic and implies release semantics before the memory
524 * operation. It can be used for an unlock if no other CPUs can concurrently
525 * modify other bits in the word.
526 */
527static inline void __clear_bit_unlock(unsigned long nr, volatile unsigned long *addr)
528{
529	smp_mb();
530	__clear_bit(nr, addr);
 
531}
532
533/*
534 * Return the bit position (0..63) of the most significant 1 bit in a word
535 * Returns -1 if no 1 bit exists
536 */
537static inline unsigned long __fls(unsigned long word)
538{
539	int num;
540
541	if (BITS_PER_LONG == 32 &&
542	    __builtin_constant_p(cpu_has_clo_clz) && cpu_has_clo_clz) {
543		__asm__(
544		"	.set	push					\n"
545		"	.set	mips32					\n"
546		"	clz	%0, %1					\n"
547		"	.set	pop					\n"
548		: "=r" (num)
549		: "r" (word));
550
551		return 31 - num;
552	}
553
554	if (BITS_PER_LONG == 64 &&
555	    __builtin_constant_p(cpu_has_mips64) && cpu_has_mips64) {
556		__asm__(
557		"	.set	push					\n"
558		"	.set	mips64					\n"
559		"	dclz	%0, %1					\n"
560		"	.set	pop					\n"
561		: "=r" (num)
562		: "r" (word));
563
564		return 63 - num;
565	}
566
567	num = BITS_PER_LONG - 1;
568
569#if BITS_PER_LONG == 64
570	if (!(word & (~0ul << 32))) {
571		num -= 32;
572		word <<= 32;
573	}
574#endif
575	if (!(word & (~0ul << (BITS_PER_LONG-16)))) {
576		num -= 16;
577		word <<= 16;
578	}
579	if (!(word & (~0ul << (BITS_PER_LONG-8)))) {
580		num -= 8;
581		word <<= 8;
582	}
583	if (!(word & (~0ul << (BITS_PER_LONG-4)))) {
584		num -= 4;
585		word <<= 4;
586	}
587	if (!(word & (~0ul << (BITS_PER_LONG-2)))) {
588		num -= 2;
589		word <<= 2;
590	}
591	if (!(word & (~0ul << (BITS_PER_LONG-1))))
592		num -= 1;
593	return num;
594}
595
596/*
597 * __ffs - find first bit in word.
598 * @word: The word to search
599 *
600 * Returns 0..SZLONG-1
601 * Undefined if no bit exists, so code should check against 0 first.
602 */
603static inline unsigned long __ffs(unsigned long word)
604{
605	return __fls(word & -word);
606}
607
608/*
609 * fls - find last bit set.
610 * @word: The word to search
611 *
612 * This is defined the same way as ffs.
613 * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32.
614 */
615static inline int fls(int x)
616{
617	int r;
618
619	if (__builtin_constant_p(cpu_has_clo_clz) && cpu_has_clo_clz) {
620		__asm__("clz %0, %1" : "=r" (x) : "r" (x));
 
 
 
 
 
 
 
621
622		return 32 - x;
623	}
624
625	r = 32;
626	if (!x)
627		return 0;
628	if (!(x & 0xffff0000u)) {
629		x <<= 16;
630		r -= 16;
631	}
632	if (!(x & 0xff000000u)) {
633		x <<= 8;
634		r -= 8;
635	}
636	if (!(x & 0xf0000000u)) {
637		x <<= 4;
638		r -= 4;
639	}
640	if (!(x & 0xc0000000u)) {
641		x <<= 2;
642		r -= 2;
643	}
644	if (!(x & 0x80000000u)) {
645		x <<= 1;
646		r -= 1;
647	}
648	return r;
649}
650
651#include <asm-generic/bitops/fls64.h>
652
653/*
654 * ffs - find first bit set.
655 * @word: The word to search
656 *
657 * This is defined the same way as
658 * the libc and compiler builtin ffs routines, therefore
659 * differs in spirit from the above ffz (man ffs).
660 */
661static inline int ffs(int word)
662{
663	if (!word)
664		return 0;
665
666	return fls(word & -word);
667}
668
669#include <asm-generic/bitops/ffz.h>
670#include <asm-generic/bitops/find.h>
671
672#ifdef __KERNEL__
673
674#include <asm-generic/bitops/sched.h>
675
676#include <asm/arch_hweight.h>
677#include <asm-generic/bitops/const_hweight.h>
678
679#include <asm-generic/bitops/le.h>
680#include <asm-generic/bitops/ext2-atomic.h>
681
682#endif /* __KERNEL__ */
683
684#endif /* _ASM_BITOPS_H */
v6.9.4
  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 - 1997, 99, 2000, 06, 07  Ralf Baechle (ralf@linux-mips.org)
  7 * Copyright (c) 1999, 2000  Silicon Graphics, Inc.
  8 */
  9#ifndef _ASM_BITOPS_H
 10#define _ASM_BITOPS_H
 11
 12#ifndef _LINUX_BITOPS_H
 13#error only <linux/bitops.h> can be included directly
 14#endif
 15
 16#include <linux/bits.h>
 17#include <linux/compiler.h>
 
 18#include <linux/types.h>
 19#include <asm/asm.h>
 20#include <asm/barrier.h>
 
 21#include <asm/byteorder.h>		/* sigh ... */
 22#include <asm/compiler.h>
 23#include <asm/cpu-features.h>
 24#include <asm/sgidefs.h>
 
 25
 26#define __bit_op(mem, insn, inputs...) do {			\
 27	unsigned long __temp;					\
 28								\
 29	asm volatile(						\
 30	"	.set		push			\n"	\
 31	"	.set		" MIPS_ISA_LEVEL "	\n"	\
 32	"	" __SYNC(full, loongson3_war) "		\n"	\
 33	"1:	" __stringify(LONG_LL)	"	%0, %1	\n"	\
 34	"	" insn		"			\n"	\
 35	"	" __stringify(LONG_SC)	"	%0, %1	\n"	\
 36	"	" __stringify(SC_BEQZ)	"	%0, 1b	\n"	\
 37	"	.set		pop			\n"	\
 38	: "=&r"(__temp), "+" GCC_OFF_SMALL_ASM()(mem)		\
 39	: inputs						\
 40	: __LLSC_CLOBBER);					\
 41} while (0)
 42
 43#define __test_bit_op(mem, ll_dst, insn, inputs...) ({		\
 44	unsigned long __orig, __temp;				\
 45								\
 46	asm volatile(						\
 47	"	.set		push			\n"	\
 48	"	.set		" MIPS_ISA_LEVEL "	\n"	\
 49	"	" __SYNC(full, loongson3_war) "		\n"	\
 50	"1:	" __stringify(LONG_LL) " "	ll_dst ", %2\n"	\
 51	"	" insn		"			\n"	\
 52	"	" __stringify(LONG_SC)	"	%1, %2	\n"	\
 53	"	" __stringify(SC_BEQZ)	"	%1, 1b	\n"	\
 54	"	.set		pop			\n"	\
 55	: "=&r"(__orig), "=&r"(__temp),				\
 56	  "+" GCC_OFF_SMALL_ASM()(mem)				\
 57	: inputs						\
 58	: __LLSC_CLOBBER);					\
 59								\
 60	__orig;							\
 61})
 62
 63/*
 64 * These are the "slower" versions of the functions and are in bitops.c.
 65 * These functions call raw_local_irq_{save,restore}().
 66 */
 67void __mips_set_bit(unsigned long nr, volatile unsigned long *addr);
 68void __mips_clear_bit(unsigned long nr, volatile unsigned long *addr);
 69void __mips_change_bit(unsigned long nr, volatile unsigned long *addr);
 70int __mips_test_and_set_bit_lock(unsigned long nr,
 71				 volatile unsigned long *addr);
 72int __mips_test_and_clear_bit(unsigned long nr,
 73			      volatile unsigned long *addr);
 74int __mips_test_and_change_bit(unsigned long nr,
 75			       volatile unsigned long *addr);
 76bool __mips_xor_is_negative_byte(unsigned long mask,
 77		volatile unsigned long *addr);
 78
 79/*
 80 * set_bit - Atomically set a bit in memory
 81 * @nr: the bit to set
 82 * @addr: the address to start counting from
 83 *
 84 * This function is atomic and may not be reordered.  See __set_bit()
 85 * if you do not require the atomic guarantees.
 86 * Note that @nr may be almost arbitrarily large; this function is not
 87 * restricted to acting on a single-word quantity.
 88 */
 89static inline void set_bit(unsigned long nr, volatile unsigned long *addr)
 90{
 91	volatile unsigned long *m = &addr[BIT_WORD(nr)];
 92	int bit = nr % BITS_PER_LONG;
 93
 94	if (!kernel_uses_llsc) {
 95		__mips_set_bit(nr, addr);
 96		return;
 97	}
 98
 99	if ((MIPS_ISA_REV >= 2) && __builtin_constant_p(bit) && (bit >= 16)) {
100		__bit_op(*m, __stringify(LONG_INS) " %0, %3, %2, 1", "i"(bit), "r"(~0));
101		return;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
102	}
103
104	__bit_op(*m, "or\t%0, %2", "ir"(BIT(bit)));
105}
106
107/*
108 * clear_bit - Clears a bit in memory
109 * @nr: Bit to clear
110 * @addr: Address to start counting from
111 *
112 * clear_bit() is atomic and may not be reordered.  However, it does
113 * not contain a memory barrier, so if it is used for locking purposes,
114 * you should call smp_mb__before_atomic() and/or smp_mb__after_atomic()
115 * in order to ensure changes are visible on other processors.
116 */
117static inline void clear_bit(unsigned long nr, volatile unsigned long *addr)
118{
119	volatile unsigned long *m = &addr[BIT_WORD(nr)];
120	int bit = nr % BITS_PER_LONG;
121
122	if (!kernel_uses_llsc) {
123		__mips_clear_bit(nr, addr);
124		return;
125	}
126
127	if ((MIPS_ISA_REV >= 2) && __builtin_constant_p(bit)) {
128		__bit_op(*m, __stringify(LONG_INS) " %0, $0, %2, 1", "i"(bit));
129		return;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
130	}
131
132	__bit_op(*m, "and\t%0, %2", "ir"(~BIT(bit)));
133}
134
135/*
136 * clear_bit_unlock - Clears a bit in memory
137 * @nr: Bit to clear
138 * @addr: Address to start counting from
139 *
140 * clear_bit() is atomic and implies release semantics before the memory
141 * operation. It can be used for an unlock.
142 */
143static inline void clear_bit_unlock(unsigned long nr, volatile unsigned long *addr)
144{
145	smp_mb__before_atomic();
146	clear_bit(nr, addr);
147}
148
149/*
150 * change_bit - Toggle a bit in memory
151 * @nr: Bit to change
152 * @addr: Address to start counting from
153 *
154 * change_bit() is atomic and may not be reordered.
155 * Note that @nr may be almost arbitrarily large; this function is not
156 * restricted to acting on a single-word quantity.
157 */
158static inline void change_bit(unsigned long nr, volatile unsigned long *addr)
159{
160	volatile unsigned long *m = &addr[BIT_WORD(nr)];
161	int bit = nr % BITS_PER_LONG;
162
163	if (!kernel_uses_llsc) {
164		__mips_change_bit(nr, addr);
165		return;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
166	}
167
168	__bit_op(*m, "xor\t%0, %2", "ir"(BIT(bit)));
169}
170
171/*
172 * test_and_set_bit_lock - Set a bit and return its old value
173 * @nr: Bit to set
174 * @addr: Address to count from
175 *
176 * This operation is atomic and implies acquire ordering semantics
177 * after the memory operation.
178 */
179static inline int test_and_set_bit_lock(unsigned long nr,
180	volatile unsigned long *addr)
181{
182	volatile unsigned long *m = &addr[BIT_WORD(nr)];
183	int bit = nr % BITS_PER_LONG;
184	unsigned long res, orig;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
185
186	if (!kernel_uses_llsc) {
187		res = __mips_test_and_set_bit_lock(nr, addr);
188	} else {
189		orig = __test_bit_op(*m, "%0",
190				     "or\t%1, %0, %3",
191				     "ir"(BIT(bit)));
192		res = (orig & BIT(bit)) != 0;
 
 
 
 
 
 
193	}
194
195	smp_llsc_mb();
196
197	return res;
198}
199
200/*
201 * test_and_set_bit - Set a bit and return its old value
202 * @nr: Bit to set
203 * @addr: Address to count from
204 *
205 * This operation is atomic and cannot be reordered.
206 * It also implies a memory barrier.
207 */
208static inline int test_and_set_bit(unsigned long nr,
209	volatile unsigned long *addr)
210{
211	smp_mb__before_atomic();
212	return test_and_set_bit_lock(nr, addr);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
213}
214
215/*
216 * test_and_clear_bit - Clear a bit and return its old value
217 * @nr: Bit to clear
218 * @addr: Address to count from
219 *
220 * This operation is atomic and cannot be reordered.
221 * It also implies a memory barrier.
222 */
223static inline int test_and_clear_bit(unsigned long nr,
224	volatile unsigned long *addr)
225{
226	volatile unsigned long *m = &addr[BIT_WORD(nr)];
227	int bit = nr % BITS_PER_LONG;
228	unsigned long res, orig;
229
230	smp_mb__before_atomic();
231
232	if (!kernel_uses_llsc) {
233		res = __mips_test_and_clear_bit(nr, addr);
234	} else if ((MIPS_ISA_REV >= 2) && __builtin_constant_p(nr)) {
235		res = __test_bit_op(*m, "%1",
236				    __stringify(LONG_EXT) " %0, %1, %3, 1;"
237				    __stringify(LONG_INS) " %1, $0, %3, 1",
238				    "i"(bit));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
239	} else {
240		orig = __test_bit_op(*m, "%0",
241				     "or\t%1, %0, %3;"
242				     "xor\t%1, %1, %3",
243				     "ir"(BIT(bit)));
244		res = (orig & BIT(bit)) != 0;
 
 
 
 
 
245	}
246
247	smp_llsc_mb();
248
249	return res;
250}
251
252/*
253 * test_and_change_bit - Change a bit and return its old value
254 * @nr: Bit to change
255 * @addr: Address to count from
256 *
257 * This operation is atomic and cannot be reordered.
258 * It also implies a memory barrier.
259 */
260static inline int test_and_change_bit(unsigned long nr,
261	volatile unsigned long *addr)
262{
263	volatile unsigned long *m = &addr[BIT_WORD(nr)];
264	int bit = nr % BITS_PER_LONG;
265	unsigned long res, orig;
266
267	smp_mb__before_atomic();
268
269	if (!kernel_uses_llsc) {
270		res = __mips_test_and_change_bit(nr, addr);
271	} else {
272		orig = __test_bit_op(*m, "%0",
273				     "xor\t%1, %0, %3",
274				     "ir"(BIT(bit)));
275		res = (orig & BIT(bit)) != 0;
276	}
277
278	smp_llsc_mb();
279
280	return res;
281}
282
283static inline bool xor_unlock_is_negative_byte(unsigned long mask,
284		volatile unsigned long *p)
285{
286	unsigned long orig;
287	bool res;
 
 
 
 
 
 
 
 
 
 
 
288
289	smp_mb__before_atomic();
290
291	if (!kernel_uses_llsc) {
292		res = __mips_xor_is_negative_byte(mask, p);
293	} else {
294		orig = __test_bit_op(*p, "%0",
295				     "xor\t%1, %0, %3",
296				     "ir"(mask));
297		res = (orig & BIT(7)) != 0;
 
 
 
 
 
 
298	}
299
300	smp_llsc_mb();
301
302	return res;
303}
304
305#undef __bit_op
306#undef __test_bit_op
307
308#include <asm-generic/bitops/non-atomic.h>
309
310/*
311 * __clear_bit_unlock - Clears a bit in memory
312 * @nr: Bit to clear
313 * @addr: Address to start counting from
314 *
315 * __clear_bit() is non-atomic and implies release semantics before the memory
316 * operation. It can be used for an unlock if no other CPUs can concurrently
317 * modify other bits in the word.
318 */
319static inline void __clear_bit_unlock(unsigned long nr, volatile unsigned long *addr)
320{
321	smp_mb__before_llsc();
322	__clear_bit(nr, addr);
323	nudge_writes();
324}
325
326/*
327 * Return the bit position (0..63) of the most significant 1 bit in a word
328 * Returns -1 if no 1 bit exists
329 */
330static __always_inline unsigned long __fls(unsigned long word)
331{
332	int num;
333
334	if (BITS_PER_LONG == 32 && !__builtin_constant_p(word) &&
335	    __builtin_constant_p(cpu_has_clo_clz) && cpu_has_clo_clz) {
336		__asm__(
337		"	.set	push					\n"
338		"	.set	"MIPS_ISA_LEVEL"			\n"
339		"	clz	%0, %1					\n"
340		"	.set	pop					\n"
341		: "=r" (num)
342		: "r" (word));
343
344		return 31 - num;
345	}
346
347	if (BITS_PER_LONG == 64 && !__builtin_constant_p(word) &&
348	    __builtin_constant_p(cpu_has_mips64) && cpu_has_mips64) {
349		__asm__(
350		"	.set	push					\n"
351		"	.set	"MIPS_ISA_LEVEL"			\n"
352		"	dclz	%0, %1					\n"
353		"	.set	pop					\n"
354		: "=r" (num)
355		: "r" (word));
356
357		return 63 - num;
358	}
359
360	num = BITS_PER_LONG - 1;
361
362#if BITS_PER_LONG == 64
363	if (!(word & (~0ul << 32))) {
364		num -= 32;
365		word <<= 32;
366	}
367#endif
368	if (!(word & (~0ul << (BITS_PER_LONG-16)))) {
369		num -= 16;
370		word <<= 16;
371	}
372	if (!(word & (~0ul << (BITS_PER_LONG-8)))) {
373		num -= 8;
374		word <<= 8;
375	}
376	if (!(word & (~0ul << (BITS_PER_LONG-4)))) {
377		num -= 4;
378		word <<= 4;
379	}
380	if (!(word & (~0ul << (BITS_PER_LONG-2)))) {
381		num -= 2;
382		word <<= 2;
383	}
384	if (!(word & (~0ul << (BITS_PER_LONG-1))))
385		num -= 1;
386	return num;
387}
388
389/*
390 * __ffs - find first bit in word.
391 * @word: The word to search
392 *
393 * Returns 0..SZLONG-1
394 * Undefined if no bit exists, so code should check against 0 first.
395 */
396static __always_inline unsigned long __ffs(unsigned long word)
397{
398	return __fls(word & -word);
399}
400
401/*
402 * fls - find last bit set.
403 * @word: The word to search
404 *
405 * This is defined the same way as ffs.
406 * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32.
407 */
408static inline int fls(unsigned int x)
409{
410	int r;
411
412	if (!__builtin_constant_p(x) &&
413	    __builtin_constant_p(cpu_has_clo_clz) && cpu_has_clo_clz) {
414		__asm__(
415		"	.set	push					\n"
416		"	.set	"MIPS_ISA_LEVEL"			\n"
417		"	clz	%0, %1					\n"
418		"	.set	pop					\n"
419		: "=r" (x)
420		: "r" (x));
421
422		return 32 - x;
423	}
424
425	r = 32;
426	if (!x)
427		return 0;
428	if (!(x & 0xffff0000u)) {
429		x <<= 16;
430		r -= 16;
431	}
432	if (!(x & 0xff000000u)) {
433		x <<= 8;
434		r -= 8;
435	}
436	if (!(x & 0xf0000000u)) {
437		x <<= 4;
438		r -= 4;
439	}
440	if (!(x & 0xc0000000u)) {
441		x <<= 2;
442		r -= 2;
443	}
444	if (!(x & 0x80000000u)) {
445		x <<= 1;
446		r -= 1;
447	}
448	return r;
449}
450
451#include <asm-generic/bitops/fls64.h>
452
453/*
454 * ffs - find first bit set.
455 * @word: The word to search
456 *
457 * This is defined the same way as
458 * the libc and compiler builtin ffs routines, therefore
459 * differs in spirit from the below ffz (man ffs).
460 */
461static inline int ffs(int word)
462{
463	if (!word)
464		return 0;
465
466	return fls(word & -word);
467}
468
469#include <asm-generic/bitops/ffz.h>
 
470
471#ifdef __KERNEL__
472
473#include <asm-generic/bitops/sched.h>
474
475#include <asm/arch_hweight.h>
476#include <asm-generic/bitops/const_hweight.h>
477
478#include <asm-generic/bitops/le.h>
479#include <asm-generic/bitops/ext2-atomic.h>
480
481#endif /* __KERNEL__ */
482
483#endif /* _ASM_BITOPS_H */