summaryrefslogtreecommitdiff
path: root/includes/stg/SMP.h
diff options
context:
space:
mode:
authorKarel Gardas <karel.gardas@centrum.cz>2011-07-03 23:24:14 +0200
committerManuel M T Chakravarty <chak@cse.unsw.edu.au>2011-08-10 22:03:41 +1000
commite44642590550547675bffd37d395008eb978f119 (patch)
treeedd3171ac470abf15cc2ad19df5876134f99c32f /includes/stg/SMP.h
parentf0191c559d683b5bac12243c0db3b780b684799e (diff)
downloadhaskell-e44642590550547675bffd37d395008eb978f119.tar.gz
Stephen Blackheath's GHC/ARM registerised port
This is the Stephen Blackheath's GHC/ARM registerised port which is using modified version of LLVM and which provides basic registerised build functionality
Diffstat (limited to 'includes/stg/SMP.h')
-rw-r--r--includes/stg/SMP.h43
1 files changed, 43 insertions, 0 deletions
diff --git a/includes/stg/SMP.h b/includes/stg/SMP.h
index 87ec4fb242..d093439182 100644
--- a/includes/stg/SMP.h
+++ b/includes/stg/SMP.h
@@ -14,8 +14,19 @@
#ifndef SMP_H
#define SMP_H
+#if defined(__ARM_ARCH_2__) || defined(__ARM_ARCH_3__) || defined(__ARM_ARCH_3M__) || \
+ defined(__ARM_ARCH_4__) || defined(__ARM_ARCH_4T__) || defined(__ARM_ARCH_5__) || \
+ defined(__ARM_ARCH_5T__) || defined(__ARM_ARCH_5E__) || defined(__ARM_ARCH_5TE__)
+#define PRE_ARMv6
+#endif
+
#if defined(THREADED_RTS)
+#if arm_HOST_ARCH && defined(PRE_ARMv6)
+void arm_atomic_spin_lock(void);
+void arm_atomic_spin_unlock(void);
+#endif
+
/* ----------------------------------------------------------------------------
Atomic operations
------------------------------------------------------------------------- */
@@ -125,7 +136,12 @@ xchg(StgPtr p, StgWord w)
: "+r" (result), "+m" (*p)
: /* no input-only operands */
);
+#elif arm_HOST_ARCH
+ __asm__ __volatile__ ("swp %0, %1, [%2]"
+ : "=&r" (result)
+ : "r" (w), "r" (p) : "memory");
#elif !defined(WITHSMP)
+#error xchg() unimplemented on this architecture
result = *p;
*p = w;
#else
@@ -169,7 +185,32 @@ cas(StgVolatilePtr p, StgWord o, StgWord n)
: "memory"
);
return n;
+#elif arm_HOST_ARCH
+#if defined(PRE_ARMv6)
+ StgWord r;
+ arm_atomic_spin_lock();
+ r = *p;
+ if (r == o) { *p = n; }
+ arm_atomic_spin_unlock();
+ return r;
+#else
+ StgWord result,tmp;
+
+ __asm__ __volatile__(
+ "1: ldrex %1, [%2]\n"
+ " mov %0, #0\n"
+ " teq %1, %3\n"
+ " strexeq %0, %4, [%2]\n"
+ " teq %0, #1\n"
+ " beq 1b\n"
+ : "=&r"(tmp), "=&r"(result)
+ : "r"(p), "r"(o), "r"(n)
+ : "cc","memory");
+
+ return result;
+#endif
#elif !defined(WITHSMP)
+#error cas() unimplemented on this architecture
StgWord result;
result = *p;
if (result == o) {
@@ -251,6 +292,8 @@ write_barrier(void) {
#elif sparc_HOST_ARCH
/* Sparc in TSO mode does not require store/store barriers. */
__asm__ __volatile__ ("" : : : "memory");
+#elif arm_HOST_ARCH
+ __asm__ __volatile__ ("" : : : "memory");
#elif !defined(WITHSMP)
return;
#else