diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2006-02-07 10:10:09 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-02-07 10:10:09 -0800 |
commit | e8a82fd030c2e0ba4d4169cc4257ef174ff6f6b4 (patch) | |
tree | 0515ffe68d9a88eda2d16f45e6391b05475fd9d1 /include/asm-mips/bitops.h | |
parent | e1a8e6c9b757c09249ab29fc6da12d9ab64567e1 (diff) | |
parent | b38c73995f63fe205c0068cb0ce3131895244068 (diff) |
Merge branch 'upstream' of git://ftp.linux-mips.org/pub/scm/upstream-linus
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 3b0c8aaf6e8..8e802059fe6 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) } /* - * flz - find last zero in word. + * fls - find last bit set. * @word: The word to search * - * Returns 0..SZLONG-1 - * Undefined if no zero exists, so code should check against ~0UL first. + * Returns 1..SZLONG + * Returns 0 if no bit exists */ -static inline unsigned long flz(unsigned long word) +static inline unsigned long fls(unsigned long word) { -#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64) - return __ilog2(~word); -#else #ifdef CONFIG_32BIT - int r = 31, s; - word = ~word; +#ifdef CONFIG_CPU_MIPS32 + __asm__ ("clz %0, %1" : "=r" (word) : "r" (word)); + + return 32 - word; +#else + { + int r = 32, s; + + if (word == 0) + return 0; + s = 16; if ((word & 0xffff0000)) s = 0; r -= s; word <<= s; s = 8; if ((word & 0xff000000)) s = 0; r -= s; word <<= s; s = 4; if ((word & 0xf0000000)) s = 0; r -= s; word <<= s; @@ -665,10 +671,23 @@ static inline unsigned long flz(unsigned long word) s = 1; if ((word & 0x80000000)) s = 0; r -= s; return r; + } #endif +#endif /* CONFIG_32BIT */ + #ifdef CONFIG_64BIT - int r = 63, s; - word = ~word; +#ifdef CONFIG_CPU_MIPS64 + + __asm__ ("dclz %0, %1" : "=r" (word) : "r" (word)); + + return 64 - word; +#else + { + int r = 64, s; + + if (word == 0) + return 0; + s = 32; if ((word & 0xffffffff00000000UL)) s = 0; r -= s; word <<= s; s = 16; if ((word & 0xffff000000000000UL)) s = 0; r -= s; word <<= s; s = 8; if ((word & 0xff00000000000000UL)) s = 0; r -= s; word <<= s; @@ -677,24 +696,11 @@ static inline unsigned long flz(unsigned long word) s = 1; if ((word & 0x8000000000000000UL)) s = 0; r -= s; return r; + } #endif -#endif +#endif /* CONFIG_64BIT */ } -/* - * fls - find last bit set. - * @word: The word to search - * - * Returns 1..SZLONG - * Returns 0 if no bit exists - */ -static inline unsigned long fls(unsigned long word) -{ - if (word == 0) - return 0; - - return flz(~word) + 1; -} #define fls64(x) generic_fls64(x) /* |