]> granicus.if.org Git - libatomic_ops/commitdiff
Code refactoring of Clang double-wide intrinsic workarounds (gcc/x86)
authorIvan Maidanski <ivmai@mail.ru>
Wed, 23 Nov 2016 10:55:00 +0000 (13:55 +0300)
committerIvan Maidanski <ivmai@mail.ru>
Thu, 24 Nov 2016 11:19:04 +0000 (14:19 +0300)
(fix commits 9803386f6a1b68eb6d4fd)

* 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.

src/atomic_ops/sysdeps/gcc/generic.h
src/atomic_ops/sysdeps/gcc/x86.h

index 69116f43381952563e2aa729c545da736a863b67..ba82e0d293cdb54716888148f11785aa4ae91db9 100644 (file)
 #   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)
     {
 #   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)
     {
index 041b75a51eede04a878a6599d356a01c4916db02..166e353fdb12ca09be0dc0ddc2247634339e609d 100644 (file)
     && !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