diff mbox

[kvm-unit-tests,v2,08/12] bitops: add fls

Message ID 20180117104005.29211-9-drjones@redhat.com (mailing list archive)
State New, archived
Headers show

Commit Message

Andrew Jones Jan. 17, 2018, 10:40 a.m. UTC
Signed-off-by: Andrew Jones <drjones@redhat.com>
---
 lib/arm/asm/bitops.h   |  2 ++
 lib/arm64/asm/bitops.h |  2 ++
 lib/bitops.h           | 38 ++++++++++++++++++++++++++++++++++++++
 lib/ppc64/asm/bitops.h |  2 ++
 lib/s390x/asm/bitops.h | 10 ++++++++++
 lib/x86/asm/bitops.h   |  2 ++
 6 files changed, 56 insertions(+)
 create mode 100644 lib/s390x/asm/bitops.h
diff mbox

Patch

diff --git a/lib/arm/asm/bitops.h b/lib/arm/asm/bitops.h
index 1d9148d2ba15..79cf4ec65a29 100644
--- a/lib/arm/asm/bitops.h
+++ b/lib/arm/asm/bitops.h
@@ -15,6 +15,8 @@ 
 
 #define BITS_PER_LONG	32
 
+#define HAVE_BUILTIN_FLS 1
+
 #define ATOMIC_BITOP(insn, mask, word)				\
 ({								\
 	unsigned long tmp1, tmp2;				\
diff --git a/lib/arm64/asm/bitops.h b/lib/arm64/asm/bitops.h
index 1b076b6a8f03..91b4bd94372f 100644
--- a/lib/arm64/asm/bitops.h
+++ b/lib/arm64/asm/bitops.h
@@ -15,6 +15,8 @@ 
 
 #define BITS_PER_LONG	64
 
+#define HAVE_BUILTIN_FLS 1
+
 #define ATOMIC_BITOP(insn, mask, word)				\
 ({								\
 	unsigned long tmp1, tmp2;				\
diff --git a/lib/bitops.h b/lib/bitops.h
index 185c5d361fea..636064c0fa85 100644
--- a/lib/bitops.h
+++ b/lib/bitops.h
@@ -33,4 +33,42 @@ 
 #define GENMASK_ULL(h, l) \
 	(((~0ULL) << (l)) & (~0ULL >> (BITS_PER_LONG_LONG - 1 - (h))))
 
+#ifndef HAVE_BUILTIN_FLS
+static inline unsigned long fls(unsigned long word)
+{
+	int num = BITS_PER_LONG - 1;
+
+#if BITS_PER_LONG == 64
+	if (!(word & (~0ul << 32))) {
+		num -= 32;
+		word <<= 32;
+	}
+#endif
+	if (!(word & (~0ul << (BITS_PER_LONG-16)))) {
+		num -= 16;
+		word <<= 16;
+	}
+	if (!(word & (~0ul << (BITS_PER_LONG-8)))) {
+		num -= 8;
+		word <<= 8;
+	}
+	if (!(word & (~0ul << (BITS_PER_LONG-4)))) {
+		num -= 4;
+		word <<= 4;
+	}
+	if (!(word & (~0ul << (BITS_PER_LONG-2)))) {
+		num -= 2;
+		word <<= 2;
+	}
+	if (!(word & (~0ul << (BITS_PER_LONG-1))))
+		num -= 1;
+	return num;
+}
+#else
+static inline unsigned long fls(unsigned long word)
+{
+	return BITS_PER_LONG - __builtin_clzl(word) - 1;
+}
+#endif
+
 #endif
diff --git a/lib/ppc64/asm/bitops.h b/lib/ppc64/asm/bitops.h
index 34624b4bfca3..c93d64bb9005 100644
--- a/lib/ppc64/asm/bitops.h
+++ b/lib/ppc64/asm/bitops.h
@@ -7,4 +7,6 @@ 
 
 #define BITS_PER_LONG	64
 
+#define HAVE_BUILTIN_FLS 1
+
 #endif
diff --git a/lib/s390x/asm/bitops.h b/lib/s390x/asm/bitops.h
new file mode 100644
index 000000000000..e7cdda920d68
--- /dev/null
+++ b/lib/s390x/asm/bitops.h
@@ -0,0 +1,10 @@ 
+#ifndef _ASMS390X_BITOPS_H_
+#define _ASMS390X_BITOPS_H_
+
+#ifndef _BITOPS_H_
+#error only <bitops.h> can be included directly
+#endif
+
+#define BITS_PER_LONG	64
+
+#endif
diff --git a/lib/x86/asm/bitops.h b/lib/x86/asm/bitops.h
index eb4aaa9fb29a..13a25ec9853d 100644
--- a/lib/x86/asm/bitops.h
+++ b/lib/x86/asm/bitops.h
@@ -11,4 +11,6 @@ 
 #define BITS_PER_LONG	32
 #endif
 
+#define HAVE_BUILTIN_FLS 1
+
 #endif