summaryrefslogtreecommitdiffstats
path: root/include/asm-frv/bitops.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/asm-frv/bitops.h')
-rw-r--r--include/asm-frv/bitops.h44
1 files changed, 44 insertions, 0 deletions
diff --git a/include/asm-frv/bitops.h b/include/asm-frv/bitops.h
index 1f70d47148bd..f8560edf59ff 100644
--- a/include/asm-frv/bitops.h
+++ b/include/asm-frv/bitops.h
@@ -256,6 +256,50 @@ int __ffs(unsigned long x)
return 31 - bit;
}
+/*
+ * special slimline version of fls() for calculating ilog2_u32()
+ * - note: no protection against n == 0
+ */
+#define ARCH_HAS_ILOG2_U32
+static inline __attribute__((const))
+int __ilog2_u32(u32 n)
+{
+ int bit;
+ asm("scan %1,gr0,%0" : "=r"(bit) : "r"(n));
+ return 31 - bit;
+}
+
+/*
+ * special slimline version of fls64() for calculating ilog2_u64()
+ * - note: no protection against n == 0
+ */
+#define ARCH_HAS_ILOG2_U64
+static inline __attribute__((const))
+int __ilog2_u64(u64 n)
+{
+ union {
+ u64 ll;
+ struct { u32 h, l; };
+ } _;
+ int bit, x, y;
+
+ _.ll = n;
+
+ asm(" subcc %3,gr0,gr0,icc0 \n"
+ " ckeq icc0,cc4 \n"
+ " cscan.p %3,gr0,%0 ,cc4,0 \n"
+ " setlos #63,%1 \n"
+ " cscan.p %4,gr0,%0 ,cc4,1 \n"
+ " setlos #31,%2 \n"
+ " csub.p %1,%0,%0 ,cc4,0 \n"
+ " csub %2,%0,%0 ,cc4,1 \n"
+ : "=&r"(bit), "=r"(x), "=r"(y)
+ : "0r"(_.h), "r"(_.l)
+ : "icc0", "cc4"
+ );
+ return bit;
+}
+
#include <asm-generic/bitops/sched.h>
#include <asm-generic/bitops/hweight.h>