Use GCC atomic intrinsics for MIPS (GCC 4.9+ and clang 3.5+)
authorIvan Maidanski <ivmai@mail.ru>
Mon, 4 Apr 2016 21:27:50 +0000 (00:27 +0300)
committerIvan Maidanski <ivmai@mail.ru>
Fri, 8 Apr 2016 20:30:52 +0000 (23:30 +0300)
* src/atomic_ops/sysdeps/gcc/mips.h: Include generic.h and do not
include all_aligned_atomic_load_store.h if AO_PREFER_BUILTIN_ATOMICS or
GCC 4.9+ or clang 3.5+ unless AO_DISABLE_GCC_ATOMICS.
* src/atomic_ops/sysdeps/gcc/mips.h (AO_MIPS_SET_ISA, AO_MIPS_LL_1,
AO_MIPS_SC, AO_MIPS_LL, AO_nop_full, AO_fetch_and_add, AO_test_and_set,
AO_compare_and_swap, AO_fetch_compare_and_swap): Do not define if
generic.h included.

src/atomic_ops/sysdeps/gcc/mips.h

index 73ca551..9cfc337 100644 (file)
  * consistent.  This is really aimed at modern embedded implementations.
  */
 
-#include "../all_aligned_atomic_load_store.h"
-
-#include "../test_and_set_t_is_ao_t.h"
-
 /* Data dependence does not imply read ordering.  */
 #define AO_NO_DD_ORDERING
 
-#if defined(_ABI64) && (_MIPS_SIM == _ABI64)
-# define AO_MIPS_SET_ISA    "       .set mips3\n"
-# define AO_MIPS_LL_1(args) "       lld " args "\n"
-# define AO_MIPS_SC(args)   "       scd " args "\n"
-#else
-# define AO_MIPS_SET_ISA    "       .set mips2\n"
-# define AO_MIPS_LL_1(args) "       ll " args "\n"
-# define AO_MIPS_SC(args)   "       sc " args "\n"
+#if !defined(_ABI64) || _MIPS_SIM != _ABI64
 # define AO_T_IS_INT
 #endif
 
+/* #include "../standard_ao_double_t.h" */
+/* TODO: Implement double-wide operations if available. */
+
+#if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9) \
+     || __clang_major__ > 3 \
+     || (__clang_major__ == 3 && __clang_minor__ >= 5) \
+     || (defined(AO_PREFER_BUILTIN_ATOMICS) \
+         && __GNUC__ == 4 && __GNUC_MINOR__ >= 2)) \
+    && !defined(AO_DISABLE_GCC_ATOMICS)
+  /* Probably, it could be enabled even for earlier gcc/clang versions. */
+
+# define AO_GCC_ATOMIC_TEST_AND_SET
+# include "../test_and_set_t_is_ao_t.h"
+
+  /* As of clang-3.6/mips[64], __GCC_HAVE_SYNC_COMPARE_AND_SWAP_n missing. */
+# if defined(__clang__)
+#   define AO_GCC_FORCE_HAVE_CAS
+# endif
+
+# include "generic.h"
+
+#else /* AO_DISABLE_GCC_ATOMICS */
+
+# include "../test_and_set_t_is_ao_t.h"
+# include "../all_aligned_atomic_load_store.h"
+
+# ifdef AO_T_IS_INT
+#   define AO_MIPS_SET_ISA    "       .set mips2\n"
+#   define AO_MIPS_LL_1(args) "       ll " args "\n"
+#   define AO_MIPS_SC(args)   "       sc " args "\n"
+# else
+#   define AO_MIPS_SET_ISA    "       .set mips3\n"
+#   define AO_MIPS_LL_1(args) "       lld " args "\n"
+#   define AO_MIPS_SC(args)   "       scd " args "\n"
+# endif
+
 #ifdef AO_ICE9A1_LLSC_WAR
   /* ICE9 rev A1 chip (used in very few systems) is reported to */
   /* have a low-frequency bug that causes LL to fail.           */
@@ -168,8 +193,7 @@ AO_fetch_compare_and_swap(volatile AO_t *addr, AO_t old, AO_t new_val)
 }
 #define AO_HAVE_fetch_compare_and_swap
 
-/* #include "../standard_ao_double_t.h" */
-/* TODO: Implement double-wide operations if available. */
+#endif /* AO_DISABLE_GCC_ATOMICS */
 
 /* CAS primitives with acquire, release and full semantics are  */
 /* generated automatically (and AO_int_... primitives are       */