Use GCC atomic intrinsics for PowerPC 32/64 (GCC 4.8+ and clang 3.8+)
authorIvan Maidanski <ivmai@mail.ru>
Fri, 5 Aug 2016 19:03:12 +0000 (22:03 +0300)
committerIvan Maidanski <ivmai@mail.ru>
Sat, 15 Apr 2017 06:41:44 +0000 (09:41 +0300)
(Cherry-pick commit 8e62b6f from 'ppc-gcc-atomics' branch.)

* src/atomic_ops/sysdeps/gcc/powerpc.h: Include generic.h and do not
include all_aligned_atomic_load_store.h, test_and_set_t_is_ao_t.h if
GCC 4.8+ or clang 3.8+ unless AO_DISABLE_GCC_ATOMICS.
* src/atomic_ops/sysdeps/gcc/powerpc.h (AO_nop_full, AO_lwsync,
AO_nop_write, AO_nop_read, AO_load_acquire, AO_store_release,
AO_test_and_set, AO_test_and_set_release, AO_test_and_set_full,
AO_compare_and_swap, AO_compare_and_swap_acquire,
AO_compare_and_swap_release, AO_compare_and_swap_full,
AO_fetch_compare_and_swap, AO_fetch_compare_and_swap_acquire,
AO_fetch_compare_and_swap_release, AO_fetch_compare_and_swap_full,
AO_fetch_and_add, AO_fetch_and_add_acquire, AO_fetch_and_add_release,
AO_fetch_and_add_full, AO_T_IS_INT): Do not define if generic.h is
included.

src/atomic_ops/sysdeps/gcc/powerpc.h

index 6650338..edbbeb8 100644 (file)
 /* http://www-106.ibm.com/developerworks/eserver/articles/powerpc.html. */
 /* There appears to be no implicit ordering between any kind of         */
 /* independent memory references.                                       */
+
+/* TODO: Implement double-wide operations if available. */
+
+#if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) \
+     || __clang_major__ > 3 \
+     || (__clang_major__ == 3 && __clang_minor__ >= 8)) \
+    && !defined(AO_DISABLE_GCC_ATOMICS)
+  /* Probably, it could be enabled even for earlier gcc/clang versions. */
+
+  /* TODO: As of clang-3.8.1, it emits lwsync in AO_load_acquire        */
+  /* (i.e., the code is less efficient than the one given below).       */
+
+# include "generic.h"
+
+#else /* AO_DISABLE_GCC_ATOMICS */
+
 /* Architecture enforces some ordering based on control dependence.     */
 /* I don't know if that could help.                                     */
 /* Data-dependent loads are always ordered.                             */
@@ -323,8 +339,6 @@ AO_fetch_and_add_full(volatile AO_t *addr, AO_t incr) {
 #define AO_HAVE_fetch_and_add_full
 #endif /* !AO_PREFER_GENERALIZED */
 
-/* TODO: Implement double-wide operations if available. */
-
 #undef AO_PPC_BR_A
 #undef AO_PPC_CMPx
 #undef AO_PPC_L
@@ -332,3 +346,5 @@ AO_fetch_and_add_full(volatile AO_t *addr, AO_t incr) {
 #undef AO_PPC_LOAD_CLOBBER
 #undef AO_PPC_LxARX
 #undef AO_PPC_STxCXd
+
+#endif /* AO_DISABLE_GCC_ATOMICS */