Commit 279a0164 authored by Heiko Carstens's avatar Heiko Carstens Committed by Vasily Gorbik
Browse files

s390/atomic_ops: Make use of flag output constraint



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: default avatarJuergen Christ <jchrist@linux.ibm.com>
Signed-off-by: default avatarHeiko Carstens <hca@linux.ibm.com>
Signed-off-by: default avatarVasily Gorbik <gor@linux.ibm.com>
parent ee19370c
Loading
Loading
Loading
Loading
+37 −7
Original line number Diff line number Diff line
@@ -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__  */