diff options
author | Peter Trommler <ptrommler@acm.org> | 2016-05-16 15:19:09 +0200 |
---|---|---|
committer | Ben Gamari <ben@smart-cactus.org> | 2016-05-16 15:21:10 +0200 |
commit | 563a4857abcee4a6e43c68323274309c58f42aa0 (patch) | |
tree | 165b86961df9d70d8aa0c3fb2741cc210d8c1ffb /includes | |
parent | 2dbdc79bb9e2760394ebfe630908813b630146c7 (diff) | |
download | haskell-563a4857abcee4a6e43c68323274309c58f42aa0.tar.gz |
PPC: Implement SMP primitives using gcc built-ins
The SMP primitives were missing appropriate memory barriers
(sync, isync instructions) on all PowerPCs.
Use the built-ins _sync_* provided by gcc and clang. This
reduces code size significantly.
Remove broken mark for concprog001 on powerpc64. The referenced
ticket number (11259) was wrong.
Test Plan: validate on powerpc and ARM
Reviewers: erikd, austin, simonmar, bgamari, hvr
Reviewed By: bgamari, hvr
Subscribers: thomie
Differential Revision: https://phabricator.haskell.org/D2225
GHC Trac Issues: #12070
Diffstat (limited to 'includes')
-rw-r--r-- | includes/stg/SMP.h | 73 |
1 files changed, 9 insertions, 64 deletions
diff --git a/includes/stg/SMP.h b/includes/stg/SMP.h index 21f05edad3..fabc540169 100644 --- a/includes/stg/SMP.h +++ b/includes/stg/SMP.h @@ -119,31 +119,8 @@ xchg(StgPtr p, StgWord w) :"+r" (result), "+m" (*p) : /* no input-only operands */ ); -#elif powerpc_HOST_ARCH - __asm__ __volatile__ ( -# if aix_HOST_OS - /* IBM's assembler doesn't seem to support local labels so we use - * explicit relative numeric offsets to workaround this limitation - */ - " lwarx %0, 0, %2\n" - " stwcx. %1, 0, %2\n" - " bne- $-8" -# else // aix_HOST_OS - "1: lwarx %0, 0, %2\n" - " stwcx. %1, 0, %2\n" - " bne- 1b" -# endif - :"=&r" (result) - :"r" (w), "r" (p) - ); -#elif powerpc64_HOST_ARCH || powerpc64le_HOST_ARCH - __asm__ __volatile__ ( - "1: ldarx %0, 0, %2\n" - " stdcx. %1, 0, %2\n" - " bne- 1b" - :"=&r" (result) - :"r" (w), "r" (p) - ); +#elif powerpc_HOST_ARCH || powerpc64_HOST_ARCH || powerpc64le_HOST_ARCH + result = __sync_lock_test_and_set(p, w); #elif sparc_HOST_ARCH result = w; __asm__ __volatile__ ( @@ -211,45 +188,8 @@ cas(StgVolatilePtr p, StgWord o, StgWord n) :"=a"(o), "+m" (*(volatile unsigned int *)p) :"0" (o), "r" (n)); return o; -#elif powerpc_HOST_ARCH - StgWord result; - __asm__ __volatile__ ( -# if aix_HOST_OS - /* IBM's assembler doesn't seem to support local labels so we use - * explicit relative numeric offsets to workaround this limitation - */ - " lwarx %0, 0, %3\n" - " cmpw %0, %1\n" - " bne $+12\n" - " stwcx. %2, 0, %3\n" - " bne- $-16\n" -# else // aix_HOST_OS - "1: lwarx %0, 0, %3\n" - " cmpw %0, %1\n" - " bne 2f\n" - " stwcx. %2, 0, %3\n" - " bne- 1b\n" - "2:" -# endif // !aix_HOST_OS - :"=&r" (result) - :"r" (o), "r" (n), "r" (p) - :"cc", "memory" - ); - return result; -#elif powerpc64_HOST_ARCH || powerpc64le_HOST_ARCH - StgWord result; - __asm__ __volatile__ ( - "1: ldarx %0, 0, %3\n" - " cmpd %0, %1\n" - " bne 2f\n" - " stdcx. %2, 0, %3\n" - " bne- 1b\n" - "2:" - :"=&r" (result) - :"r" (o), "r" (n), "r" (p) - :"cc", "memory" - ); - return result; +#elif powerpc_HOST_ARCH || powerpc64_HOST_ARCH || powerpc64le_HOST_ARCH + return __sync_val_compare_and_swap(p, o, n); #elif sparc_HOST_ARCH __asm__ __volatile__ ( "cas [%1], %2, %0" @@ -310,6 +250,7 @@ cas(StgVolatilePtr p, StgWord o, StgWord n) // RRN: Generalized to arbitrary increments to enable fetch-and-add in // Haskell code (fetchAddIntArray#). +// PT: add-and-fetch, returns new value EXTERN_INLINE StgWord atomic_inc(StgVolatilePtr p, StgWord incr) { @@ -321,6 +262,8 @@ atomic_inc(StgVolatilePtr p, StgWord incr) "+r" (r), "+m" (*p): ); return r + incr; +#elif powerpc_HOST_ARCH || powerpc64_HOST_ARCH || powerpc64le_HOST_ARCH + return __sync_add_and_fetch(p, incr); #else StgWord old, new_; do { @@ -342,6 +285,8 @@ atomic_dec(StgVolatilePtr p) "+r" (r), "+m" (*p): ); return r-1; +#elif powerpc_HOST_ARCH || powerpc64_HOST_ARCH || powerpc64le_HOST_ARCH + return __sync_sub_and_fetch(p, (StgWord) 1); #else StgWord old, new_; do { |