summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/atomic_ops/sysdeps/gcc/aarch64.h35
-rw-r--r--src/atomic_ops/sysdeps/gcc/generic.h7
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)
{