From c2edeab8dc0931ccc219da1831895d7d0f44c38b Mon Sep 17 00:00:00 2001 From: Tobias Leich Date: Thu, 10 Nov 2016 09:02:56 +0100 Subject: [PATCH] Implement fetch-CAS for s390[x] (gcc) * src/atomic_ops/sysdeps/gcc/s390.h (AO_compare_and_swap_full): Do not define if AO_GENERALIZE_ASM_BOOL_CAS. * src/atomic_ops/sysdeps/gcc/s390.h (AO_fetch_compare_and_swap_full): Implement; remove TODO item. --- src/atomic_ops/sysdeps/gcc/s390.h | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/atomic_ops/sysdeps/gcc/s390.h b/src/atomic_ops/sysdeps/gcc/s390.h index 36efbac..31886e2 100644 --- a/src/atomic_ops/sysdeps/gcc/s390.h +++ b/src/atomic_ops/sysdeps/gcc/s390.h @@ -41,6 +41,7 @@ /* It appears that certain BCR instructions have that effect. */ /* Presumably they're cheaper than CS? */ +#ifndef AO_GENERALIZE_ASM_BOOL_CAS AO_INLINE int AO_compare_and_swap_full(volatile AO_t *addr, AO_t old, AO_t new_val) { @@ -59,7 +60,23 @@ AO_INLINE int AO_compare_and_swap_full(volatile AO_t *addr, return retval == 0; } #define AO_HAVE_compare_and_swap_full +#endif /* !AO_GENERALIZE_ASM_BOOL_CAS */ -/* TODO: implement AO_fetch_compare_and_swap. */ +AO_INLINE AO_t +AO_fetch_compare_and_swap_full(volatile AO_t *addr, + AO_t old, AO_t new_val) +{ + __asm__ __volatile__ ( +# ifndef __s390x__ + " cs %0,%2,%1\n" +# else + " csg %0,%2,%1\n" +# endif + : "+d" (old), "=Q" (*addr) + : "d" (new_val), "m" (*addr) + : "cc", "memory"); + return old; +} +#define AO_HAVE_fetch_compare_and_swap_full /* TODO: Add double-wide operations for 32-bit executables. */ -- 2.40.0