summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIvan Maidanski <ivmai@mail.ru>2016-04-05 00:27:50 +0300
committerIvan Maidanski <ivmai@mail.ru>2016-04-08 23:30:52 +0300
commit2317eaf48d677d30e2b34e46517c72fa004e8a54 (patch)
treee7e2d4a97431a884c70bc66e6dc5138de35e69e5
parent73d83212c4ed9cd4e91a9ac8e649f30239077292 (diff)
downloadlibatomic_ops-2317eaf48d677d30e2b34e46517c72fa004e8a54.tar.gz
Use GCC atomic intrinsics for MIPS (GCC 4.9+ and clang 3.5+)
* 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.
-rw-r--r--src/atomic_ops/sysdeps/gcc/mips.h52
1 files changed, 38 insertions, 14 deletions
diff --git a/src/atomic_ops/sysdeps/gcc/mips.h b/src/atomic_ops/sysdeps/gcc/mips.h
index 73ca551..9cfc337 100644
--- a/src/atomic_ops/sysdeps/gcc/mips.h
+++ b/src/atomic_ops/sysdeps/gcc/mips.h
@@ -17,24 +17,49 @@
* 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 */