Added PowerPC and ARM versions of the memory barrier functions.
authorSam Lantinga <slouken@libsdl.org>
Wed, 10 Jul 2013 20:17:20 -0700
changeset 739438dc4961ab15
parent 7393 358696c354a8
child 7395 c1b80390a820
Added PowerPC and ARM versions of the memory barrier functions.
include/SDL_atomic.h
src/atomic/SDL_atomic.c
     1.1 --- a/include/SDL_atomic.h	Wed Jul 10 18:31:17 2013 -0700
     1.2 +++ b/include/SDL_atomic.h	Wed Jul 10 20:17:20 2013 -0700
     1.3 @@ -155,11 +155,31 @@
     1.4   * For more information on these semantics, take a look at the blog post:
     1.5   * http://preshing.com/20120913/acquire-and-release-semantics
     1.6   */
     1.7 -/* FIXME: This is correct for x86 and x64 but not other CPUs
     1.8 -   For PPC we need the lwsync instruction, and on ARM some variant of dmb
     1.9 - */
    1.10 +#if defined(__GNUC__) && (defined(__powerpc__) || defined(__ppc__))
    1.11 +#define SDL_MemoryBarrierRelease()   __asm__ __volatile__ ("lwsync" : : : "memory")
    1.12 +#define SDL_MemoryBarrierAcquire()   __asm__ __volatile__ ("lwsync" : : : "memory")
    1.13 +#elif defined(__GNUC__) && defined(__arm__)
    1.14 +#if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7EM__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7S__)
    1.15 +#define SDL_MemoryBarrierRelease()   __asm__ __volatile__ ("dmb ish" : : : "memory")
    1.16 +#define SDL_MemoryBarrierAcquire()   __asm__ __volatile__ ("dmb ish" : : : "memory")
    1.17 +#elif defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6T2__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__)
    1.18 +#ifdef __thumb__
    1.19 +/* The mcr instruction isn't available in thumb mode, use real functions */
    1.20 +extern DECLSPEC void SDLCALL SDL_MemoryBarrierRelease();
    1.21 +extern DECLSPEC void SDLCALL SDL_MemoryBarrierAcquire();
    1.22 +#else
    1.23 +#define SDL_MemoryBarrierRelease()   __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 5" : : "r"(0) : "memory")
    1.24 +#define SDL_MemoryBarrierAcquire()   __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 5" : : "r"(0) : "memory")
    1.25 +#endif /* __thumb__ */
    1.26 +#else
    1.27 +#define SDL_MemoryBarrierRelease()   __asm__ __volatile__ ("" : : : "memory")
    1.28 +#define SDL_MemoryBarrierAcquire()   __asm__ __volatile__ ("" : : : "memory")
    1.29 +#endif /* __GNUC__ && __arm__ */
    1.30 +#else
    1.31 +/* This is correct for the x86 and x64 CPUs, and we'll expand this over time. */
    1.32  #define SDL_MemoryBarrierRelease()  SDL_CompilerBarrier()
    1.33  #define SDL_MemoryBarrierAcquire()  SDL_CompilerBarrier()
    1.34 +#endif
    1.35  
    1.36  
    1.37  /* Platform specific optimized versions of the atomic functions,
     2.1 --- a/src/atomic/SDL_atomic.c	Wed Jul 10 18:31:17 2013 -0700
     2.2 +++ b/src/atomic/SDL_atomic.c	Wed Jul 10 20:17:20 2013 -0700
     2.3 @@ -101,4 +101,18 @@
     2.4      return retval;
     2.5  }
     2.6  
     2.7 +#if defined(__GNUC__) && defined(__arm__) && \
     2.8 +   (defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6T2__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__))
     2.9 +__asm__(
    2.10 +"   .align 2\n"
    2.11 +"   .globl _SDL_MemoryBarrierRelease\n"
    2.12 +"   .globl _SDL_MemoryBarrierAcquire\n"
    2.13 +"_SDL_MemoryBarrierRelease:\n"
    2.14 +"_SDL_MemoryBarrierAcquire:\n"
    2.15 +"   mov r0, #0\n"
    2.16 +"   mcr p15, 0, r0, c7, c10, 5\n"
    2.17 +"   bx lr\n"
    2.18 +);
    2.19 +#endif /* __GNUC__ && __arm__ && ARMV6 */
    2.20 +
    2.21  /* vi: set ts=4 sw=4 expandtab: */