s390/bitops: Provide optimized arch_test_bit()
authorHeiko Carstens <hca@linux.ibm.com>
Fri, 13 Dec 2024 12:27:34 +0000 (13:27 +0100)
committerAlexander Gordeev <agordeev@linux.ibm.com>
Mon, 13 Jan 2025 08:50:19 +0000 (09:50 +0100)
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>
arch/s390/include/asm/bitops.h

index 1e790c351daab8e2a60952a193593474fa41dcb0..15aa64e3020e5c61d4f173d42021e7a5cd51998c 100644 (file)
 #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>
 
 /*