summaryrefslogtreecommitdiffstats
path: root/include/asm-sh
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2007-11-11 17:28:18 +0900
committerPaul Mundt <lethal@linux-sh.org>2008-01-28 13:18:45 +0900
commit63e2c803326babe74033b3cbe6e8c550037c554f (patch)
tree9a08d857d6d7f8fd8a73f3c5f600a2db90d2875c /include/asm-sh
parent079060c6ff6edd32955c3e511024578db89a717b (diff)
downloadlinux-63e2c803326babe74033b3cbe6e8c550037c554f.tar.bz2
sh: Plug in SH-5 ffz()/__ffs() bitops.
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'include/asm-sh')
-rw-r--r--include/asm-sh/bitops.h26
1 files changed, 26 insertions, 0 deletions
diff --git a/include/asm-sh/bitops.h b/include/asm-sh/bitops.h
index df805f20b267..a7bd81a7f064 100644
--- a/include/asm-sh/bitops.h
+++ b/include/asm-sh/bitops.h
@@ -105,6 +105,7 @@ static inline int test_and_change_bit(int nr, volatile void * addr)
#include <asm-generic/bitops/non-atomic.h>
+#ifdef CONFIG_SUPERH32
static inline unsigned long ffz(unsigned long word)
{
unsigned long result;
@@ -138,6 +139,31 @@ static inline unsigned long __ffs(unsigned long word)
: "t");
return result;
}
+#else
+static inline unsigned long ffz(unsigned long word)
+{
+ unsigned long result, __d2, __d3;
+
+ __asm__("gettr tr0, %2\n\t"
+ "pta $+32, tr0\n\t"
+ "andi %1, 1, %3\n\t"
+ "beq %3, r63, tr0\n\t"
+ "pta $+4, tr0\n"
+ "0:\n\t"
+ "shlri.l %1, 1, %1\n\t"
+ "addi %0, 1, %0\n\t"
+ "andi %1, 1, %3\n\t"
+ "beqi %3, 1, tr0\n"
+ "1:\n\t"
+ "ptabs %2, tr0\n\t"
+ : "=r" (result), "=r" (word), "=r" (__d2), "=r" (__d3)
+ : "0" (0L), "1" (word));
+
+ return result;
+}
+
+#include <asm-generic/bitops/__ffs.h>
+#endif
#include <asm-generic/bitops/find.h>
#include <asm-generic/bitops/ffs.h>