diff options
author | Tobias Leich <email@froggs.de> | 2016-11-10 09:02:56 +0100 |
---|---|---|
committer | Ivan Maidanski <ivmai@mail.ru> | 2016-11-10 12:34:53 +0300 |
commit | c2edeab8dc0931ccc219da1831895d7d0f44c38b (patch) | |
tree | 9734459464ec79d8e008253861270a9dd0f0c6d1 | |
parent | 033e273ff2e40868256fa3ed231798a998c7699e (diff) | |
download | libatomic_ops-c2edeab8dc0931ccc219da1831895d7d0f44c38b.tar.gz |
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.
-rw-r--r-- | src/atomic_ops/sysdeps/gcc/s390.h | 19 |
1 files changed, 18 insertions, 1 deletions
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. */ |