aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2005-07-12 08:50:30 -0400
committerRalf Baechle <ralf@linux-mips.org>2005-10-29 14:31:43 -0400
commit6590326505e3f7b4b57793e84760e9920c3c56b4 (patch)
tree920ab56cb70895393e57b356c28d6eb37932c63f
parente5de3b468795e4c58a9f0702630d28707b3ae011 (diff)
Use clz / dclz on MIPS32 / MIPS64 processors.
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
-rw-r--r--include/asm-mips/bitops.h137
1 files changed, 115 insertions, 22 deletions
diff --git a/include/asm-mips/bitops.h b/include/asm-mips/bitops.h
index d9c02bd0b18e..2ba20730a3e5 100644
--- a/include/asm-mips/bitops.h
+++ b/include/asm-mips/bitops.h
@@ -546,17 +546,60 @@ static inline int test_bit(unsigned long nr, const volatile unsigned long *addr)
546 return 1UL & (addr[nr >> SZLONG_LOG] >> (nr & SZLONG_MASK)); 546 return 1UL & (addr[nr >> SZLONG_LOG] >> (nr & SZLONG_MASK));
547} 547}
548 548
549#ifdef CONFIG_CPU_MIPS32_R1
549/* 550/*
550 * ffz - find first zero in word. 551 * Return the bit position (0..31) of the most significant 1 bit in a word
552 * Returns -1 if no 1 bit exists
553 */
554static __inline__ int __ilog2(unsigned long x)
555{
556 int lz;
557
558 __asm__ (
559 " .set push \n"
560 " .set mips32 \n"
561 " clz %0, %1 \n"
562 " .set pop \n"
563 : "=r" (lz)
564 : "r" (x));
565
566 return 31 - lz;
567}
568#elif defined(CONFIG_CPU_MIPS64_R1)
569/*
570 * Return the bit position (0..63) of the most significant 1 bit in a word
571 * Returns -1 if no 1 bit exists
572 */
573static __inline__ int __ilog2(unsigned long x)
574{
575 int lz;
576
577 __asm__ (
578 " .set push \n"
579 " .set mips64 \n"
580 " dclz %0, %1 \n"
581 " .set pop \n"
582 : "=r" (lz)
583 : "r" (x));
584
585 return 63 - lz;
586}
587#endif
588
589/*
590 * __ffs - find first bit in word.
551 * @word: The word to search 591 * @word: The word to search
552 * 592 *
553 * Undefined if no zero exists, so code should check against ~0UL first. 593 * Returns 0..SZLONG-1
594 * Undefined if no bit exists, so code should check against 0 first.
554 */ 595 */
555static inline unsigned long ffz(unsigned long word) 596static inline unsigned long __ffs(unsigned long word)
556{ 597{
598#if defined(CONFIG_CPU_MIPS32_R1) || defined(CONFIG_CPU_MIPS64_R1)
599 return __ilog2(word & -word);
600#else
557 int b = 0, s; 601 int b = 0, s;
558 602
559 word = ~word;
560#ifdef CONFIG_32BIT 603#ifdef CONFIG_32BIT
561 s = 16; if (word << 16 != 0) s = 0; b += s; word >>= s; 604 s = 16; if (word << 16 != 0) s = 0; b += s; word >>= s;
562 s = 8; if (word << 24 != 0) s = 0; b += s; word >>= s; 605 s = 8; if (word << 24 != 0) s = 0; b += s; word >>= s;
@@ -572,26 +615,87 @@ static inline unsigned long ffz(unsigned long word)
572 s = 2; if (word << 62 != 0) s = 0; b += s; word >>= s; 615 s = 2; if (word << 62 != 0) s = 0; b += s; word >>= s;
573 s = 1; if (word << 63 != 0) s = 0; b += s; 616 s = 1; if (word << 63 != 0) s = 0; b += s;
574#endif 617#endif
575
576 return b; 618 return b;
619#endif
577} 620}
578 621
579/* 622/*
580 * __ffs - find first bit in word. 623 * ffs - find first bit set.
581 * @word: The word to search 624 * @word: The word to search
582 * 625 *
583 * Undefined if no bit exists, so code should check against 0 first. 626 * Returns 1..SZLONG
627 * Returns 0 if no bit exists
584 */ 628 */
585static inline unsigned long __ffs(unsigned long word) 629
630static inline unsigned long ffs(unsigned long word)
586{ 631{
587 return ffz(~word); 632 if (!word)
633 return 0;
634
635 return __ffs(word) + 1;
588} 636}
589 637
590/* 638/*
591 * fls: find last bit set. 639 * ffz - find first zero in word.
640 * @word: The word to search
641 *
642 * Undefined if no zero exists, so code should check against ~0UL first.
592 */ 643 */
644static inline unsigned long ffz(unsigned long word)
645{
646 return __ffs (~word);
647}
648
649/*
650 * flz - find last zero in word.
651 * @word: The word to search
652 *
653 * Returns 0..SZLONG-1
654 * Undefined if no zero exists, so code should check against ~0UL first.
655 */
656static inline unsigned long flz(unsigned long word)
657{
658#if defined(CONFIG_CPU_MIPS32_R1) || defined(CONFIG_CPU_MIPS64_R1)
659 return __ilog2(~word);
660#else
661#if defined(CONFIG_32BIT)
662 int r = 31, s;
663 word = ~word;
664 s = 16; if ((word & 0xffff0000)) s = 0; r -= s; word <<= s;
665 s = 8; if ((word & 0xff000000)) s = 0; r -= s; word <<= s;
666 s = 4; if ((word & 0xf0000000)) s = 0; r -= s; word <<= s;
667 s = 2; if ((word & 0xc0000000)) s = 0; r -= s; word <<= s;
668 s = 1; if ((word & 0x80000000)) s = 0; r -= s;
669#endif
670#if defined(CONFIG_64BIT)
671 int r = 63, s;
672 word = ~word;
673 s = 32; if ((word & 0xffffffff00000000UL)) s = 0; r -= s; word <<= s;
674 s = 16; if ((word & 0xffff000000000000UL)) s = 0; r -= s; word <<= s;
675 s = 8; if ((word & 0xff00000000000000UL)) s = 0; r -= s; word <<= s;
676 s = 4; if ((word & 0xf000000000000000UL)) s = 0; r -= s; word <<= s;
677 s = 2; if ((word & 0xc000000000000000UL)) s = 0; r -= s; word <<= s;
678 s = 1; if ((word & 0x8000000000000000UL)) s = 0; r -= s;
679#endif
680 return r;
681#endif
682}
683
684/*
685 * fls - find last bit set.
686 * @word: The word to search
687 *
688 * Returns 1..SZLONG
689 * Returns 0 if no bit exists
690 */
691static inline unsigned long fls(unsigned long word)
692{
693 if (word == 0)
694 return 0;
695
696 return flz(~word) + 1;
697}
593 698
594#define fls(x) generic_fls(x)
595 699
596/* 700/*
597 * find_next_zero_bit - find the first zero bit in a memory region 701 * find_next_zero_bit - find the first zero bit in a memory region
@@ -728,17 +832,6 @@ static inline int sched_find_first_bit(const unsigned long *b)
728} 832}
729 833
730/* 834/*
731 * ffs - find first bit set
732 * @x: the word to search
733 *
734 * This is defined the same way as
735 * the libc and compiler builtin ffs routines, therefore
736 * differs in spirit from the above ffz (man ffs).
737 */
738
739#define ffs(x) generic_ffs(x)
740
741/*
742 * hweightN - returns the hamming weight of a N-bit word 835 * hweightN - returns the hamming weight of a N-bit word
743 * @x: the word to weigh 836 * @x: the word to weigh
744 * 837 *