Signed-off-by: Andrew Jones <drjones@xxxxxxxxxx> --- 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 --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 -- 2.13.6