diff options
-rw-r--r-- | src/atomic_ops/sysdeps/gcc/aarch64.h | 35 | ||||
-rw-r--r-- | src/atomic_ops/sysdeps/gcc/generic.h | 7 |
2 files changed, 25 insertions, 17 deletions
diff --git a/src/atomic_ops/sysdeps/gcc/aarch64.h b/src/atomic_ops/sysdeps/gcc/aarch64.h index b7f2ef0..612bc18 100644 --- a/src/atomic_ops/sysdeps/gcc/aarch64.h +++ b/src/atomic_ops/sysdeps/gcc/aarch64.h @@ -19,18 +19,23 @@ #include "../standard_ao_double_t.h" -#ifndef AO_UNIPROCESSOR - AO_INLINE void - AO_nop_write(void) - { - /* TODO: Use C++11 primitive. */ - __asm__ __volatile__("dmb ishst" : : : "memory"); - } -# define AO_HAVE_nop_write -#endif - -/* TODO: Adjust version check on fixing double-wide AO support in GCC. */ -#if __GNUC__ >= 4 +#ifdef AO_PREFER_BUILTIN_ATOMICS + /* As of clang 3.6 (and gcc 5.0), load atomics for double word are */ + /* translated to incorrect code lacking STXP (see the note below). */ +# define AO_SKIPATOMIC_double_load +# define AO_SKIPATOMIC_double_load_acquire +#else + + /* As of clang 3.6 (and gcc 4.9), __atomic_thread_fence is always */ + /* translated to DMB (which is inefficient for AO_nop_write). */ +# ifndef AO_UNIPROCESSOR + AO_INLINE void + AO_nop_write(void) + { + __asm__ __volatile__("dmb ishst" : : : "memory"); + } +# define AO_HAVE_nop_write +# endif AO_INLINE AO_double_t AO_double_load(const volatile AO_double_t *addr) @@ -68,6 +73,9 @@ } # define AO_HAVE_double_load_acquire + /* As of gcc 5.0, all built-in store and CAS atomics for double */ + /* word require -latomic, so use asm-based implementation by default. */ + AO_INLINE void AO_double_store(volatile AO_double_t *addr, AO_double_t value) { @@ -195,6 +203,7 @@ return !result; } # define AO_HAVE_double_compare_and_swap_full -#endif /* __GNUC__ >= 4 */ + +#endif /* !AO_PREFER_BUILTIN_ATOMICS */ #include "generic.h" diff --git a/src/atomic_ops/sysdeps/gcc/generic.h b/src/atomic_ops/sysdeps/gcc/generic.h index de79edb..1df2914 100644 --- a/src/atomic_ops/sysdeps/gcc/generic.h +++ b/src/atomic_ops/sysdeps/gcc/generic.h @@ -19,8 +19,6 @@ /* For the details, see GNU Manual, chapter 6.52 (Built-in functions */ /* for memory model aware atomic operations). */ -/* TODO: Include this file for other targets if gcc 4.7+ */ - #ifdef AO_UNIPROCESSOR /* If only a single processor (core) is used, AO_UNIPROCESSOR could */ /* be defined by the client to avoid unnecessary memory barrier. */ @@ -93,7 +91,7 @@ #ifdef AO_HAVE_DOUBLE_PTR_STORAGE -# ifndef AO_HAVE_double_load +# if !defined(AO_HAVE_double_load) && !defined(AO_SKIPATOMIC_double_load) AO_INLINE AO_double_t AO_double_load(const volatile AO_double_t *addr) { @@ -105,7 +103,8 @@ # define AO_HAVE_double_load # endif -# ifndef AO_HAVE_double_load_acquire +# if !defined(AO_HAVE_double_load_acquire) \ + && !defined(AO_SKIPATOMIC_double_load_acquire) AO_INLINE AO_double_t AO_double_load_acquire(const volatile AO_double_t *addr) { |