diff options
author | Heiko Carstens <hca@linux.ibm.com> | 2024-12-13 13:27:34 +0100 |
---|---|---|
committer | Alexander Gordeev <agordeev@linux.ibm.com> | 2025-01-13 09:50:19 +0100 |
commit | b2bc1b1a77c0ffc2f51e90b1112d7f5530e4d15c (patch) | |
tree | 1704e4b4dab0499b80f6b43f07e79d6cea5254b4 /arch/s390/include | |
parent | 8cae8e0afb2f1f6879efa6899b6323171c3bd990 (diff) |
s390/bitops: Provide optimized arch_test_bit()
Provide an optimized arch_test_bit() implementation which makes use of
flag output constraint. This generates slightly better code:
bloat-o-meter:
add/remove: 51/19 grow/shrink: 450/2444 up/down: 25198/-49136 (-23938)
Acked-by: Alexander Gordeev <agordeev@linux.ibm.com>
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com>
Diffstat (limited to 'arch/s390/include')
-rw-r--r-- | arch/s390/include/asm/bitops.h | 34 |
1 files changed, 33 insertions, 1 deletions
diff --git a/arch/s390/include/asm/bitops.h b/arch/s390/include/asm/bitops.h index 1e790c351daa..15aa64e3020e 100644 --- a/arch/s390/include/asm/bitops.h +++ b/arch/s390/include/asm/bitops.h @@ -36,8 +36,40 @@ #include <linux/typecheck.h> #include <linux/compiler.h> #include <linux/types.h> +#include <asm/asm.h> + +#define arch___set_bit generic___set_bit +#define arch___clear_bit generic___clear_bit +#define arch___change_bit generic___change_bit +#define arch___test_and_set_bit generic___test_and_set_bit +#define arch___test_and_clear_bit generic___test_and_clear_bit +#define arch___test_and_change_bit generic___test_and_change_bit +#define arch_test_bit_acquire generic_test_bit_acquire + +static __always_inline bool arch_test_bit(unsigned long nr, const volatile unsigned long *ptr) +{ +#ifdef __HAVE_ASM_FLAG_OUTPUTS__ + const volatile unsigned char *addr; + unsigned long mask; + int cc; + + if (__builtin_constant_p(nr)) { + addr = (const volatile unsigned char *)ptr; + addr += (nr ^ (BITS_PER_LONG - BITS_PER_BYTE)) / BITS_PER_BYTE; + mask = 1UL << (nr & (BITS_PER_BYTE - 1)); + asm volatile( + " tm %[addr],%[mask]\n" + : "=@cc" (cc) + : [addr] "R" (*addr), [mask] "I" (mask) + ); + return cc == 3; + } +#endif + return generic_test_bit(nr, ptr); +} + #include <asm-generic/bitops/atomic.h> -#include <asm-generic/bitops/non-atomic.h> +#include <asm-generic/bitops/non-instrumented-non-atomic.h> #include <asm-generic/bitops/lock.h> /* |