diff options
author | Karel Gardas <karel.gardas@centrum.cz> | 2011-07-05 20:10:18 +0200 |
---|---|---|
committer | Manuel M T Chakravarty <chak@cse.unsw.edu.au> | 2011-08-10 22:03:41 +1000 |
commit | 330dff34ddc45eb0adc8d098a55f491cce0ea108 (patch) | |
tree | abb6c649cda480eb52bf48e55bf8a9261b505250 /includes/stg/SMP.h | |
parent | e44642590550547675bffd37d395008eb978f119 (diff) | |
download | haskell-330dff34ddc45eb0adc8d098a55f491cce0ea108.tar.gz |
implement ARMv6/7 specific xchg function
Diffstat (limited to 'includes/stg/SMP.h')
-rw-r--r-- | includes/stg/SMP.h | 20 |
1 files changed, 18 insertions, 2 deletions
diff --git a/includes/stg/SMP.h b/includes/stg/SMP.h index d093439182..0b7592d690 100644 --- a/includes/stg/SMP.h +++ b/includes/stg/SMP.h @@ -1,6 +1,6 @@ /* ---------------------------------------------------------------------------- * - * (c) The GHC Team, 2005-2009 + * (c) The GHC Team, 2005-2011 * * Macros for multi-CPU support * @@ -136,10 +136,26 @@ xchg(StgPtr p, StgWord w) : "+r" (result), "+m" (*p) : /* no input-only operands */ ); -#elif arm_HOST_ARCH +#elif arm_HOST_ARCH && defined(PRE_ARMv6) __asm__ __volatile__ ("swp %0, %1, [%2]" : "=&r" (result) : "r" (w), "r" (p) : "memory"); +#elif arm_HOST_ARCH && !defined(PRE_ARMv6) + // swp instruction which is used in PRE_ARMv6 code above + // is deprecated in AMRv6 and later. ARM, Ltd. *highly* recommends + // to use ldrex/strex instruction pair for the same purpose + // see chapter: Synchronization and semaphores in ARM Architecture + // Reference manual + StgWord tmp; + __asm__ __volatile__ ( + "1: ldrex %0, [%3]\n" + " strex %1, %2, [%3]\n" + " teq %1, #1\n" + " beq 1b\n" + : "=&r" (result), "=&r" (tmp) + : "r" (w), "r" (p) + : "memory" + ); #elif !defined(WITHSMP) #error xchg() unimplemented on this architecture result = *p; |