diff options
Diffstat (limited to 'include/asm-mips/bitops.h')
| -rw-r--r-- | include/asm-mips/bitops.h | 58 |
1 files changed, 32 insertions, 26 deletions
diff --git a/include/asm-mips/bitops.h b/include/asm-mips/bitops.h index 3b0c8aaf6e8b..8e802059fe67 100644 --- a/include/asm-mips/bitops.h +++ b/include/asm-mips/bitops.h | |||
| @@ -644,20 +644,26 @@ static inline unsigned long ffz(unsigned long word) | |||
| 644 | } | 644 | } |
| 645 | 645 | ||
| 646 | /* | 646 | /* |
| 647 | * flz - find last zero in word. | 647 | * fls - find last bit set. |
| 648 | * @word: The word to search | 648 | * @word: The word to search |
| 649 | * | 649 | * |
| 650 | * Returns 0..SZLONG-1 | 650 | * Returns 1..SZLONG |
| 651 | * Undefined if no zero exists, so code should check against ~0UL first. | 651 | * Returns 0 if no bit exists |
| 652 | */ | 652 | */ |
| 653 | static inline unsigned long flz(unsigned long word) | 653 | static inline unsigned long fls(unsigned long word) |
| 654 | { | 654 | { |
| 655 | #if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64) | ||
| 656 | return __ilog2(~word); | ||
| 657 | #else | ||
| 658 | #ifdef CONFIG_32BIT | 655 | #ifdef CONFIG_32BIT |
| 659 | int r = 31, s; | 656 | #ifdef CONFIG_CPU_MIPS32 |
| 660 | word = ~word; | 657 | __asm__ ("clz %0, %1" : "=r" (word) : "r" (word)); |
| 658 | |||
| 659 | return 32 - word; | ||
| 660 | #else | ||
| 661 | { | ||
| 662 | int r = 32, s; | ||
| 663 | |||
| 664 | if (word == 0) | ||
| 665 | return 0; | ||
| 666 | |||
| 661 | s = 16; if ((word & 0xffff0000)) s = 0; r -= s; word <<= s; | 667 | s = 16; if ((word & 0xffff0000)) s = 0; r -= s; word <<= s; |
| 662 | s = 8; if ((word & 0xff000000)) s = 0; r -= s; word <<= s; | 668 | s = 8; if ((word & 0xff000000)) s = 0; r -= s; word <<= s; |
| 663 | s = 4; if ((word & 0xf0000000)) s = 0; r -= s; word <<= s; | 669 | s = 4; if ((word & 0xf0000000)) s = 0; r -= s; word <<= s; |
| @@ -665,10 +671,23 @@ static inline unsigned long flz(unsigned long word) | |||
| 665 | s = 1; if ((word & 0x80000000)) s = 0; r -= s; | 671 | s = 1; if ((word & 0x80000000)) s = 0; r -= s; |
| 666 | 672 | ||
| 667 | return r; | 673 | return r; |
| 674 | } | ||
| 668 | #endif | 675 | #endif |
| 676 | #endif /* CONFIG_32BIT */ | ||
| 677 | |||
| 669 | #ifdef CONFIG_64BIT | 678 | #ifdef CONFIG_64BIT |
| 670 | int r = 63, s; | 679 | #ifdef CONFIG_CPU_MIPS64 |
| 671 | word = ~word; | 680 | |
| 681 | __asm__ ("dclz %0, %1" : "=r" (word) : "r" (word)); | ||
| 682 | |||
| 683 | return 64 - word; | ||
| 684 | #else | ||
| 685 | { | ||
| 686 | int r = 64, s; | ||
| 687 | |||
| 688 | if (word == 0) | ||
| 689 | return 0; | ||
| 690 | |||
| 672 | s = 32; if ((word & 0xffffffff00000000UL)) s = 0; r -= s; word <<= s; | 691 | s = 32; if ((word & 0xffffffff00000000UL)) s = 0; r -= s; word <<= s; |
| 673 | s = 16; if ((word & 0xffff000000000000UL)) s = 0; r -= s; word <<= s; | 692 | s = 16; if ((word & 0xffff000000000000UL)) s = 0; r -= s; word <<= s; |
| 674 | s = 8; if ((word & 0xff00000000000000UL)) s = 0; r -= s; word <<= s; | 693 | s = 8; if ((word & 0xff00000000000000UL)) s = 0; r -= s; word <<= s; |
| @@ -677,24 +696,11 @@ static inline unsigned long flz(unsigned long word) | |||
| 677 | s = 1; if ((word & 0x8000000000000000UL)) s = 0; r -= s; | 696 | s = 1; if ((word & 0x8000000000000000UL)) s = 0; r -= s; |
| 678 | 697 | ||
| 679 | return r; | 698 | return r; |
| 699 | } | ||
| 680 | #endif | 700 | #endif |
| 681 | #endif | 701 | #endif /* CONFIG_64BIT */ |
| 682 | } | 702 | } |
| 683 | 703 | ||
| 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 | */ | ||
| 691 | static inline unsigned long fls(unsigned long word) | ||
| 692 | { | ||
| 693 | if (word == 0) | ||
| 694 | return 0; | ||
| 695 | |||
| 696 | return flz(~word) + 1; | ||
| 697 | } | ||
| 698 | #define fls64(x) generic_fls64(x) | 704 | #define fls64(x) generic_fls64(x) |
| 699 | 705 | ||
| 700 | /* | 706 | /* |
