summaryrefslogtreecommitdiff
path: root/erts/include/internal/gcc/ethr_membar.h
diff options
context:
space:
mode:
Diffstat (limited to 'erts/include/internal/gcc/ethr_membar.h')
-rw-r--r--erts/include/internal/gcc/ethr_membar.h46
1 files changed, 43 insertions, 3 deletions
diff --git a/erts/include/internal/gcc/ethr_membar.h b/erts/include/internal/gcc/ethr_membar.h
index 643b243683..4e1eb1117e 100644
--- a/erts/include/internal/gcc/ethr_membar.h
+++ b/erts/include/internal/gcc/ethr_membar.h
@@ -149,14 +149,51 @@ ethr_full_fence__(void)
__asm__ __volatile__("dmb sy" : : : "memory");
}
+#if ETHR_HAVE_GCC_ASM_ARM_DMB_ST_INSTRUCTION
static __inline__ __attribute__((__always_inline__)) void
ethr_store_fence__(void)
{
+ /* StoreStore */
__asm__ __volatile__("dmb st" : : : "memory");
}
+#endif
+
+#if ETHR_HAVE_GCC_ASM_ARM_DMB_LD_INSTRUCTION
+static __inline__ __attribute__((__always_inline__)) void
+ethr_load_fence__(void)
+{
+ /* LoadLoad and LoadStore */
+ __asm__ __volatile__("dmb ld" : : : "memory");
+}
+#endif
-#define ETHR_MEMBAR(B) \
- ETHR_CHOOSE_EXPR((B) == ETHR_StoreStore, ethr_store_fence__(), ethr_full_fence__())
+#if ETHR_HAVE_GCC_ASM_ARM_DMB_ST_INSTRUCTION && ETHR_HAVE_GCC_ASM_ARM_DMB_LD_INSTRUCTION
+/* sy, st & ld */
+#define ETHR_MEMBAR(B) \
+ ETHR_CHOOSE_EXPR((B) == ETHR_StoreStore, \
+ ethr_store_fence__(), \
+ ETHR_CHOOSE_EXPR((B) & (ETHR_StoreStore \
+ | ETHR_StoreLoad), \
+ ethr_full_fence__(), \
+ ethr_load_fence__()))
+#elif ETHR_HAVE_GCC_ASM_ARM_DMB_ST_INSTRUCTION
+/* sy & st */
+#define ETHR_MEMBAR(B) \
+ ETHR_CHOOSE_EXPR((B) == ETHR_StoreStore, \
+ ethr_store_fence__(), \
+ ethr_full_fence__())
+#elif ETHR_HAVE_GCC_ASM_ARM_DMB_LD_INSTRUCTION
+/* sy & ld */
+#define ETHR_MEMBAR(B) \
+ ETHR_CHOOSE_EXPR((B) & (ETHR_StoreStore \
+ | ETHR_StoreLoad), \
+ ethr_full_fence__(), \
+ ethr_load_fence__())
+#else
+/* sy */
+#define ETHR_MEMBAR(B) \
+ ethr_full_fence__()
+#endif
#elif ETHR_HAVE___sync_synchronize
@@ -205,9 +242,12 @@ ethr_full_fence__(void)
/*
* Define ETHR_READ_DEPEND_MEMORY_BARRIER for all architechtures
* not known to order data dependent loads
+ *
+ * This is a bit too conservative, but better safe than sorry...
+ * Add more archs as needed...
*/
-#if !defined(__ia64__) && !defined(__arm__)
+#if !defined(__ia64__) && !defined(__arm__) && !defined(__arm64__)
# define ETHR_READ_DEPEND_MEMORY_BARRIER ETHR_MEMBAR(ETHR_LoadLoad)
#endif