summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIvan Maidanski <ivmai@mail.ru>2016-11-23 13:55:00 +0300
committerIvan Maidanski <ivmai@mail.ru>2016-11-24 14:19:04 +0300
commitf82a19e191b4515f04b3e57b9bab3e73e4c02ca7 (patch)
tree9f4b80f5cf0810ffae8509d932c3bebf564e2e89
parent8e4213ff4329d5bcbbb76644084ccf3c76c3ef25 (diff)
downloadlibatomic_ops-f82a19e191b4515f04b3e57b9bab3e73e4c02ca7.tar.gz
Code refactoring of Clang double-wide intrinsic workarounds (gcc/x86)
(fix commits 9803386, f6a1b68, eb6d4fd) * src/atomic_ops/sysdeps/gcc/generic.h [AO_HAVE_DOUBLE_PTR_STORAGE && !AO_HAVE_double_store] (AO_double_store): Do not define if AO_SKIPATOMIC_double_store. * src/atomic_ops/sysdeps/gcc/generic.h [AO_HAVE_DOUBLE_PTR_STORAGE && !AO_HAVE_double_store_release] (AO_double_store_release): Do not define if AO_SKIPATOMIC_double_load. * src/atomic_ops/sysdeps/gcc/x86.h [AO_GCC_ATOMIC_TEST_AND_SET && __clang__ && !__x86_64__ && !__APPLE_CC__ && !__CYGWIN__ && !AO_PREFER_BUILTIN_ATOMICS] (AO_SKIPATOMIC_double_load, AO_SKIPATOMIC_double_load_acquire, AO_SKIPATOMIC_double_store, AO_SKIPATOMIC_double_store_release): Define internal macro (undefined at the end of file). * src/atomic_ops/sysdeps/gcc/x86.h [AO_GCC_ATOMIC_TEST_AND_SET && (__clang__ && !__x86_64__ && !__APPLE_CC__ && !__CYGWIN__ && !AO_PREFER_BUILTIN_ATOMICS) || (__APPLE_CC__ && __x86_64__))] (AO_SKIPATOMIC_double_compare_and_swap_ANY): Move definition here (remove at other places in this file); undefine at the end of the file. * src/atomic_ops/sysdeps/gcc/x86.h [AO_GCC_ATOMIC_TEST_AND_SET]: Check AO_SKIPATOMIC_double_compare_and_swap_ANY instead of checking multiple macros to detect whether a workaround for the CAS (and others) double-wide operations is needed.
-rw-r--r--src/atomic_ops/sysdeps/gcc/generic.h5
-rw-r--r--src/atomic_ops/sysdeps/gcc/x86.h52
2 files changed, 29 insertions, 28 deletions
diff --git a/src/atomic_ops/sysdeps/gcc/generic.h b/src/atomic_ops/sysdeps/gcc/generic.h
index 69116f4..ba82e0d 100644
--- a/src/atomic_ops/sysdeps/gcc/generic.h
+++ b/src/atomic_ops/sysdeps/gcc/generic.h
@@ -142,7 +142,7 @@
# define AO_HAVE_double_load_acquire
# endif
-# ifndef AO_HAVE_double_store
+# if !defined(AO_HAVE_double_store) && !defined(AO_SKIPATOMIC_double_store)
AO_INLINE void
AO_double_store(volatile AO_double_t *addr, AO_double_t value)
{
@@ -151,7 +151,8 @@
# define AO_HAVE_double_store
# endif
-# ifndef AO_HAVE_double_store_release
+# if !defined(AO_HAVE_double_store_release) \
+ && !defined(AO_SKIPATOMIC_double_store_release)
AO_INLINE void
AO_double_store_release(volatile AO_double_t *addr, AO_double_t value)
{
diff --git a/src/atomic_ops/sysdeps/gcc/x86.h b/src/atomic_ops/sysdeps/gcc/x86.h
index 041b75a..166e353 100644
--- a/src/atomic_ops/sysdeps/gcc/x86.h
+++ b/src/atomic_ops/sysdeps/gcc/x86.h
@@ -23,6 +23,24 @@
&& !defined(AO_DISABLE_GCC_ATOMICS)
# define AO_GCC_ATOMIC_TEST_AND_SET
+/* TODO: Refine for newer clang releases. */
+# if defined(__clang__) \
+ && !(defined(__x86_64__) || defined(__APPLE_CC__) \
+ || defined(__CYGWIN__) || defined(AO_PREFER_BUILTIN_ATOMICS))
+ /* As of clang-3.8 i686 (NDK r11c), it requires -latomic for all */
+ /* the double-wide operations. For now, we fall back to the */
+ /* non-intrinsic implementation by default. */
+# define AO_SKIPATOMIC_double_compare_and_swap_ANY
+# define AO_SKIPATOMIC_double_load
+# define AO_SKIPATOMIC_double_load_acquire
+# define AO_SKIPATOMIC_double_store
+# define AO_SKIPATOMIC_double_store_release
+# elif defined(__APPLE_CC__) && defined(__x86_64__)
+ /* As of Apple clang-600 (based on LLVM 3.5svn), it has some bug in */
+ /* double-wide CAS implementation for x64 target. */
+# define AO_SKIPATOMIC_double_compare_and_swap_ANY
+# endif
+
#else /* AO_DISABLE_GCC_ATOMICS */
/* The following really assume we have a 486 or better. Unfortunately */
@@ -291,18 +309,8 @@ AO_fetch_compare_and_swap_full(volatile AO_t *addr, AO_t old_val,
#endif /* AO_DISABLE_GCC_ATOMICS */
-#if (defined(AO_PREFER_BUILTIN_ATOMICS) || !defined(__clang__) \
- || defined(__x86_64__) || defined(__APPLE_CC__) || defined(__CYGWIN__)) \
- && defined(AO_GCC_ATOMIC_TEST_AND_SET) \
- && !(defined(__APPLE_CC__) && defined(__x86_64__) && !defined(__ILP32__) \
- && defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16))
-
- /* As of clang-3.8 i686 (NDK r11c), it requires -latomic for all the */
- /* double-wide operations. For now, we fall back to the */
- /* non-intrinsic implementation if clang/x86. */
- /* As of Apple clang-600 (based on LLVM 3.5svn), it has some bug in */
- /* double-wide CAS implementation for x64 target. */
- /* TODO: Refine for newer clang releases. */
+#if defined(AO_GCC_ATOMIC_TEST_AND_SET) \
+ && !defined(AO_SKIPATOMIC_double_compare_and_swap_ANY)
# if defined(__ILP32__) || !defined(__x86_64__) /* 32-bit AO_t */ \
|| defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16) /* 64-bit AO_t */
@@ -319,18 +327,6 @@ AO_fetch_compare_and_swap_full(volatile AO_t *addr, AO_t old_val,
# define AO_ACCESS_double_CHECK_ALIGNED
# include "../loadstore/double_atomic_load_store.h"
-# ifdef AO_GCC_ATOMIC_TEST_AND_SET
- /* Double-wide loads and stores are ordered. */
-# define AO_double_load_acquire(addr) AO_double_load_read(addr)
-# define AO_HAVE_double_load_acquire
-
-# define AO_double_store_release(addr, val) \
- (AO_nop_write(), AO_double_store(addr, val))
-# define AO_HAVE_double_store_release
-
-# define AO_SKIPATOMIC_double_compare_and_swap_ANY
-# endif /* AO_GCC_ATOMIC_TEST_AND_SET */
-
/* Returns nonzero if the comparison succeeded. */
/* Really requires at least a Pentium. */
AO_INLINE int
@@ -440,8 +436,6 @@ AO_fetch_compare_and_swap_full(volatile AO_t *addr, AO_t old_val,
/* doesn't work. And the emulation is unsafe by our usual rules. */
/* However both are clearly useful in certain cases. */
-# define AO_SKIPATOMIC_double_compare_and_swap_ANY
-
AO_INLINE int
AO_compare_double_and_swap_double_full(volatile AO_double_t *addr,
AO_t old_val1, AO_t old_val2,
@@ -483,3 +477,9 @@ AO_fetch_compare_and_swap_full(volatile AO_t *addr, AO_t old_val,
#ifdef AO_GCC_ATOMIC_TEST_AND_SET
# include "generic.h"
#endif
+
+#undef AO_SKIPATOMIC_double_compare_and_swap_ANY
+#undef AO_SKIPATOMIC_double_load
+#undef AO_SKIPATOMIC_double_load_acquire
+#undef AO_SKIPATOMIC_double_store
+#undef AO_SKIPATOMIC_double_store_release