diff mbox series

[16/37] MIPS: bitops: Use generic builtin ffs/fls; drop cpu_has_clo_clz

Message ID 20190930230806.2940505-17-paul.burton@mips.com (mailing list archive)
State Superseded
Headers show
Series MIPS: barriers & atomics cleanups | expand

Commit Message

Paul Burton Sept. 30, 2019, 11:08 p.m. UTC
The MIPS-specific implementations of __ffs(), ffs(), __fls() & fls()
make use of the MIPS clz instruction where possible. They do this via
inline asm, but in any configuration in which the kernel is built for a
MIPS32 or MIPS64 release 1 or higher instruction set we know that these
instructions are available & can be emitted using the __builtin_clz()
function & other associated builtins which are provided by all currently
supported versions of gcc.

When targeting an older instruction set GCC will generate a longer code
sequence similar to the fallback cases we have in our implementations.

As such, remove our custom implementations of these functions & use the
generic versions built atop compiler builtins. This allows us to drop a
significant chunk of code, along with the cpu_has_clo_clz feature macro
which was only used by these functions.

The only thing we lose here is the ability for kernels built to target a
pre-r1 ISA to opportunistically make use of clz when running on a CPU
that implements it. This seems like a small cost, and well worth paying
to simplify the code.

Signed-off-by: Paul Burton <paul.burton@mips.com>
---

 arch/mips/include/asm/bitops.h                | 146 +-----------------
 arch/mips/include/asm/cpu-features.h          |  10 --
 .../asm/mach-malta/cpu-feature-overrides.h    |   2 -
 3 files changed, 4 insertions(+), 154 deletions(-)
diff mbox series

Patch

diff --git a/arch/mips/include/asm/bitops.h b/arch/mips/include/asm/bitops.h
index 985d6a02f9ea..4b618afbfa5b 100644
--- a/arch/mips/include/asm/bitops.h
+++ b/arch/mips/include/asm/bitops.h
@@ -491,149 +491,11 @@  static inline void __clear_bit_unlock(unsigned long nr, volatile unsigned long *
 	nudge_writes();
 }
 
-/*
- * Return the bit position (0..63) of the most significant 1 bit in a word
- * Returns -1 if no 1 bit exists
- */
-static __always_inline unsigned long __fls(unsigned long word)
-{
-	int num;
-
-	if (BITS_PER_LONG == 32 && !__builtin_constant_p(word) &&
-	    __builtin_constant_p(cpu_has_clo_clz) && cpu_has_clo_clz) {
-		__asm__(
-		"	.set	push					\n"
-		"	.set	"MIPS_ISA_LEVEL"			\n"
-		"	clz	%0, %1					\n"
-		"	.set	pop					\n"
-		: "=r" (num)
-		: "r" (word));
-
-		return 31 - num;
-	}
-
-	if (BITS_PER_LONG == 64 && !__builtin_constant_p(word) &&
-	    __builtin_constant_p(cpu_has_mips64) && cpu_has_mips64) {
-		__asm__(
-		"	.set	push					\n"
-		"	.set	"MIPS_ISA_LEVEL"			\n"
-		"	dclz	%0, %1					\n"
-		"	.set	pop					\n"
-		: "=r" (num)
-		: "r" (word));
-
-		return 63 - num;
-	}
-
-	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;
-}
-
-/*
- * __ffs - find first bit in word.
- * @word: The word to search
- *
- * Returns 0..SZLONG-1
- * Undefined if no bit exists, so code should check against 0 first.
- */
-static __always_inline unsigned long __ffs(unsigned long word)
-{
-	return __fls(word & -word);
-}
-
-/*
- * fls - find last bit set.
- * @word: The word to search
- *
- * This is defined the same way as ffs.
- * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32.
- */
-static inline int fls(unsigned int x)
-{
-	int r;
-
-	if (!__builtin_constant_p(x) &&
-	    __builtin_constant_p(cpu_has_clo_clz) && cpu_has_clo_clz) {
-		__asm__(
-		"	.set	push					\n"
-		"	.set	"MIPS_ISA_LEVEL"			\n"
-		"	clz	%0, %1					\n"
-		"	.set	pop					\n"
-		: "=r" (x)
-		: "r" (x));
-
-		return 32 - x;
-	}
-
-	r = 32;
-	if (!x)
-		return 0;
-	if (!(x & 0xffff0000u)) {
-		x <<= 16;
-		r -= 16;
-	}
-	if (!(x & 0xff000000u)) {
-		x <<= 8;
-		r -= 8;
-	}
-	if (!(x & 0xf0000000u)) {
-		x <<= 4;
-		r -= 4;
-	}
-	if (!(x & 0xc0000000u)) {
-		x <<= 2;
-		r -= 2;
-	}
-	if (!(x & 0x80000000u)) {
-		x <<= 1;
-		r -= 1;
-	}
-	return r;
-}
-
+#include <asm-generic/bitops/builtin-__ffs.h>
+#include <asm-generic/bitops/builtin-ffs.h>
+#include <asm-generic/bitops/builtin-__fls.h>
+#include <asm-generic/bitops/builtin-fls.h>
 #include <asm-generic/bitops/fls64.h>
-
-/*
- * ffs - find first bit set.
- * @word: The word to search
- *
- * 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 int ffs(int word)
-{
-	if (!word)
-		return 0;
-
-	return fls(word & -word);
-}
-
 #include <asm-generic/bitops/ffz.h>
 #include <asm-generic/bitops/find.h>
 
diff --git a/arch/mips/include/asm/cpu-features.h b/arch/mips/include/asm/cpu-features.h
index 983a6a7f43a1..274a35ae15af 100644
--- a/arch/mips/include/asm/cpu-features.h
+++ b/arch/mips/include/asm/cpu-features.h
@@ -362,16 +362,6 @@ 
 })
 #endif
 
-/*
- * MIPS32, MIPS64, VR5500, IDT32332, IDT32334 and maybe a few other
- * pre-MIPS32/MIPS64 processors have CLO, CLZ.	The IDT RC64574 is 64-bit and
- * has CLO and CLZ but not DCLO nor DCLZ.  For 64-bit kernels
- * cpu_has_clo_clz also indicates the availability of DCLO and DCLZ.
- */
-#ifndef cpu_has_clo_clz
-#define cpu_has_clo_clz	cpu_has_mips_r
-#endif
-
 /*
  * MIPS32 R2, MIPS64 R2, Loongson 3A and Octeon have WSBH.
  * MIPS64 R2, Loongson 3A and Octeon have WSBH, DSBH and DSHD.
diff --git a/arch/mips/include/asm/mach-malta/cpu-feature-overrides.h b/arch/mips/include/asm/mach-malta/cpu-feature-overrides.h
index de3b66a3723e..193c0912d38e 100644
--- a/arch/mips/include/asm/mach-malta/cpu-feature-overrides.h
+++ b/arch/mips/include/asm/mach-malta/cpu-feature-overrides.h
@@ -32,7 +32,6 @@ 
 /* #define cpu_has_vtag_icache	? */
 /* #define cpu_has_dc_aliases	? */
 /* #define cpu_has_ic_fills_f_dc ? */
-#define cpu_has_clo_clz		1
 #define cpu_has_nofpuex		0
 /* #define cpu_has_64bits	? */
 /* #define cpu_has_64bit_zero_reg ? */
@@ -59,7 +58,6 @@ 
 /* #define cpu_has_vtag_icache	? */
 /* #define cpu_has_dc_aliases	? */
 /* #define cpu_has_ic_fills_f_dc ? */
-#define cpu_has_clo_clz		1
 #define cpu_has_nofpuex		0
 /* #define cpu_has_64bits	? */
 /* #define cpu_has_64bit_zero_reg ? */