diff options
author | Karel Gardas <karel.gardas@centrum.cz> | 2011-07-03 23:24:14 +0200 |
---|---|---|
committer | Manuel M T Chakravarty <chak@cse.unsw.edu.au> | 2011-08-10 22:03:41 +1000 |
commit | e44642590550547675bffd37d395008eb978f119 (patch) | |
tree | edd3171ac470abf15cc2ad19df5876134f99c32f /includes/stg/SMP.h | |
parent | f0191c559d683b5bac12243c0db3b780b684799e (diff) | |
download | haskell-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.h | 43 |
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 |