]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
s390/atomic_ops: Make use of flag output constraint
authorHeiko Carstens <hca@linux.ibm.com>
Mon, 1 Jul 2024 15:04:58 +0000 (17:04 +0200)
committerVasily Gorbik <gor@linux.ibm.com>
Wed, 10 Jul 2024 17:50:44 +0000 (19:50 +0200)
With gcc 14.1.0 support for flag output constraint was added for
s390. Use this for __atomic_cmpxchg_bool(). This allows for slightly
better code, since the compiler can generate code depending on the
condition code which is the result of an inline assembly.

The size of the kernel image is reduced by ~12kb.

Reviewed-by: Juergen Christ <jchrist@linux.ibm.com>
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
arch/s390/include/asm/atomic_ops.h

index b028c5309befb8a96fe5c192d1caa78449817bae..2b379d1d9046b9b927f3858481ae6003452b0193 100644 (file)
@@ -178,26 +178,54 @@ static __always_inline int __atomic_cmpxchg(int *ptr, int old, int new)
        return old;
 }
 
+static __always_inline long __atomic64_cmpxchg(long *ptr, long old, long new)
+{
+       asm volatile(
+               "       csg     %[old],%[new],%[ptr]"
+               : [old] "+d" (old), [ptr] "+QS" (*ptr)
+               : [new] "d" (new)
+               : "cc", "memory");
+       return old;
+}
+
+#ifdef __GCC_ASM_FLAG_OUTPUTS__
+
 static __always_inline bool __atomic_cmpxchg_bool(int *ptr, int old, int new)
 {
-       int old_expected = old;
+       int cc;
 
        asm volatile(
                "       cs      %[old],%[new],%[ptr]"
-               : [old] "+d" (old), [ptr] "+Q" (*ptr)
+               : [old] "+d" (old), [ptr] "+Q" (*ptr), "=@cc" (cc)
                : [new] "d" (new)
-               : "cc", "memory");
-       return old == old_expected;
+               : "memory");
+       return cc == 0;
 }
 
-static __always_inline long __atomic64_cmpxchg(long *ptr, long old, long new)
+static __always_inline bool __atomic64_cmpxchg_bool(long *ptr, long old, long new)
 {
+       int cc;
+
        asm volatile(
                "       csg     %[old],%[new],%[ptr]"
-               : [old] "+d" (old), [ptr] "+QS" (*ptr)
+               : [old] "+d" (old), [ptr] "+QS" (*ptr), "=@cc" (cc)
+               : [new] "d" (new)
+               : "memory");
+       return cc == 0;
+}
+
+#else /* __GCC_ASM_FLAG_OUTPUTS__ */
+
+static __always_inline bool __atomic_cmpxchg_bool(int *ptr, int old, int new)
+{
+       int old_expected = old;
+
+       asm volatile(
+               "       cs      %[old],%[new],%[ptr]"
+               : [old] "+d" (old), [ptr] "+Q" (*ptr)
                : [new] "d" (new)
                : "cc", "memory");
-       return old;
+       return old == old_expected;
 }
 
 static __always_inline bool __atomic64_cmpxchg_bool(long *ptr, long old, long new)
@@ -212,4 +240,6 @@ static __always_inline bool __atomic64_cmpxchg_bool(long *ptr, long old, long ne
        return old == old_expected;
 }
 
+#endif /* __GCC_ASM_FLAG_OUTPUTS__ */
+
 #endif /* __ARCH_S390_ATOMIC_OPS__  */