linux-mips
[Top] [All Lists]

[PATCH] fix bitops for MIPS32/MIPS64 CPUs

To: linux-mips@linux-mips.org
Subject: [PATCH] fix bitops for MIPS32/MIPS64 CPUs
From: Atsushi Nemoto <anemo@mba.ocn.ne.jp>
Date: Mon, 17 Apr 2006 21:19:12 +0900 (JST)
Cc: ralf@linux-mips.org, mita@miraclelinux.com
Original-recipient: rfc822;linux-mips@linux-mips.org
Sender: linux-mips-bounce@linux-mips.org
With recent rewrite for generic bitops, fls() for 32bit kernel with
MIPS64_CPU is broken.  Also, ffs(), fls() should be defined the same
way as the libc and compiler built-in routines (returns int instead of
unsigned long).

Signed-off-by: Atsushi Nemoto <anemo@mba.ocn.ne.jp>

diff --git a/include/asm-mips/bitops.h b/include/asm-mips/bitops.h
index a1728f8..d2f4445 100644
--- a/include/asm-mips/bitops.h
+++ b/include/asm-mips/bitops.h
@@ -467,64 +467,56 @@ static inline unsigned long __ffs(unsign
 }
 
 /*
- * ffs - find first bit set.
+ * fls - find last bit set.
  * @word: The word to search
  *
- * Returns 1..SZLONG
- * Returns 0 if no bit exists
+ * This is defined the same way as ffs.
+ * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32.
  */
-
-static inline unsigned long ffs(unsigned long word)
+static inline int fls(int word)
 {
-       if (!word)
-               return 0;
+       __asm__ ("clz %0, %1" : "=r" (word) : "r" (word));
 
-       return __ffs(word) + 1;
+       return 32 - word;
 }
 
-/*
- * ffz - find first zero in word.
- * @word: The word to search
- *
- * Undefined if no zero exists, so code should check against ~0UL first.
- */
-static inline unsigned long ffz(unsigned long word)
+#if defined(CONFIG_64BIT) && defined(CONFIG_CPU_MIPS64)
+static inline int fls64(__u64 word)
 {
-       return __ffs (~word);
+       __asm__ ("dclz %0, %1" : "=r" (word) : "r" (word));
+
+       return 64 - word;
 }
+#else
+#include <asm-generic/bitops/fls64.h>
+#endif
 
 /*
- * fls - find last bit set.
+ * ffs - find first bit set.
  * @word: The word to search
  *
- * Returns 1..SZLONG
- * Returns 0 if no bit exists
+ * This is defined the same way as
+ * the libc and compiler builtin ffs routines, therefore
+ * differs in spirit from the above ffz (man ffs).
  */
-static inline unsigned long fls(unsigned long word)
+static inline int ffs(int word)
 {
-#ifdef CONFIG_CPU_MIPS32
-       __asm__ ("clz %0, %1" : "=r" (word) : "r" (word));
-
-       return 32 - word;
-#endif
-
-#ifdef CONFIG_CPU_MIPS64
-       __asm__ ("dclz %0, %1" : "=r" (word) : "r" (word));
+       if (!word)
+               return 0;
 
-       return 64 - word;
-#endif
+       return fls(word & -word);
 }
 
 #else
 
 #include <asm-generic/bitops/__ffs.h>
 #include <asm-generic/bitops/ffs.h>
-#include <asm-generic/bitops/ffz.h>
 #include <asm-generic/bitops/fls.h>
+#include <asm-generic/bitops/fls64.h>
 
 #endif /*defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64) */
 
-#include <asm-generic/bitops/fls64.h>
+#include <asm-generic/bitops/ffz.h>
 #include <asm-generic/bitops/find.h>
 
 #ifdef __KERNEL__

<Prev in Thread] Current Thread [Next in Thread>
  • [PATCH] fix bitops for MIPS32/MIPS64 CPUs, Atsushi Nemoto <=