aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/asm-mips/bitops.h58
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)
/*