Add atomics for Watcom/x86 as inline asm
authorOzkan Sezer <sezeroz@gmail.com>
Fri, 18 Aug 2017 16:35:55 -0400
changeset 1131806fd8421e8f6
parent 11317 f57e81db97b5
child 11319 86b1fde471c6
Add atomics for Watcom/x86 as inline asm

Partially fixes Bugzilla #3758.
include/SDL_atomic.h
src/atomic/SDL_atomic.c
src/atomic/SDL_spinlock.c
     1.1 --- a/include/SDL_atomic.h	Thu Aug 17 21:35:46 2017 -0400
     1.2 +++ b/include/SDL_atomic.h	Fri Aug 18 16:35:55 2017 -0400
     1.3 @@ -125,6 +125,9 @@
     1.4  #elif (defined(__GNUC__) && !defined(__EMSCRIPTEN__)) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x5120))
     1.5  /* This is correct for all CPUs when using GCC or Solaris Studio 12.1+. */
     1.6  #define SDL_CompilerBarrier()   __asm__ __volatile__ ("" : : : "memory")
     1.7 +#elif defined(__WATCOMC__)
     1.8 +extern _inline void SDL_CompilerBarrier (void);
     1.9 +#pragma aux SDL_CompilerBarrier = "" parm [] modify exact [];
    1.10  #else
    1.11  #define SDL_CompilerBarrier()   \
    1.12  { SDL_SpinLock _tmp = 0; SDL_AtomicLock(&_tmp); SDL_AtomicUnlock(&_tmp); }
     2.1 --- a/src/atomic/SDL_atomic.c	Thu Aug 17 21:35:46 2017 -0400
     2.2 +++ b/src/atomic/SDL_atomic.c	Fri Aug 18 16:35:55 2017 -0400
     2.3 @@ -52,6 +52,31 @@
     2.4  # endif
     2.5  #endif
     2.6  
     2.7 +#if defined(__WATCOMC__) && defined(__386__)
     2.8 +#define HAVE_WATCOM_ATOMICS
     2.9 +extern _inline int _SDL_xchg_watcom(volatile int *a, int v);
    2.10 +#pragma aux _SDL_xchg_watcom = \
    2.11 +  "xchg [ecx], eax" \
    2.12 +  parm [ecx] [eax] \
    2.13 +  value [eax] \
    2.14 +  modify exact [eax];
    2.15 +
    2.16 +extern _inline unsigned char _SDL_cmpxchg_watcom(volatile int *a, int newval, int oldval);
    2.17 +#pragma aux _SDL_cmpxchg_watcom = \
    2.18 +  "lock cmpxchg [edx], ecx" \
    2.19 +  "setz al" \
    2.20 +  parm [edx] [ecx] [eax] \
    2.21 +  value [al] \
    2.22 +  modify exact [eax];
    2.23 +
    2.24 +extern _inline int _SDL_xadd_watcom(volatile int *a, int v);
    2.25 +#pragma aux _SDL_xadd_watcom = \
    2.26 +  "lock xadd [ecx], eax" \
    2.27 +  parm [ecx] [eax] \
    2.28 +  value [eax] \
    2.29 +  modify exact [eax];
    2.30 +#endif /* __WATCOMC__ && __386__ */
    2.31 +
    2.32  /*
    2.33    If any of the operations are not provided then we must emulate some
    2.34    of them. That means we need a nice implementation of spin locks
    2.35 @@ -75,7 +100,7 @@
    2.36    Contributed by Bob Pendleton, bob@pendleton.com
    2.37  */
    2.38  
    2.39 -#if !defined(HAVE_MSC_ATOMICS) && !defined(HAVE_GCC_ATOMICS) && !defined(__MACOSX__) && !defined(__SOLARIS__)
    2.40 +#if !defined(HAVE_MSC_ATOMICS) && !defined(HAVE_GCC_ATOMICS) && !defined(__MACOSX__) && !defined(__SOLARIS__) && !defined(HAVE_WATCOM_ATOMICS)
    2.41  #define EMULATE_CAS 1
    2.42  #endif
    2.43  
    2.44 @@ -105,6 +130,8 @@
    2.45  {
    2.46  #ifdef HAVE_MSC_ATOMICS
    2.47      return (_InterlockedCompareExchange((long*)&a->value, (long)newval, (long)oldval) == (long)oldval);
    2.48 +#elif defined(HAVE_WATCOM_ATOMICS)
    2.49 +    return (SDL_bool) _SDL_cmpxchg_watcom(&a->value, newval, oldval);
    2.50  #elif defined(HAVE_GCC_ATOMICS)
    2.51      return (SDL_bool) __sync_bool_compare_and_swap(&a->value, oldval, newval);
    2.52  #elif defined(__MACOSX__)  /* this is deprecated in 10.12 sdk; favor gcc atomics. */
    2.53 @@ -136,6 +163,8 @@
    2.54      return (_InterlockedCompareExchange((long*)a, (long)newval, (long)oldval) == (long)oldval);
    2.55  #elif defined(HAVE_MSC_ATOMICS) && (!_M_IX86)
    2.56      return (_InterlockedCompareExchangePointer(a, newval, oldval) == oldval);
    2.57 +#elif defined(HAVE_WATCOM_ATOMICS)
    2.58 +    return (SDL_bool) _SDL_cmpxchg_watcom((int *)a, (long)newval, (long)oldval);
    2.59  #elif defined(HAVE_GCC_ATOMICS)
    2.60      return __sync_bool_compare_and_swap(a, oldval, newval);
    2.61  #elif defined(__MACOSX__) && defined(__LP64__)  /* this is deprecated in 10.12 sdk; favor gcc atomics. */
    2.62 @@ -165,6 +194,8 @@
    2.63  {
    2.64  #ifdef HAVE_MSC_ATOMICS
    2.65      return _InterlockedExchange((long*)&a->value, v);
    2.66 +#elif defined(HAVE_WATCOM_ATOMICS)
    2.67 +    return _SDL_xchg_watcom(&a->value, v);
    2.68  #elif defined(HAVE_GCC_ATOMICS)
    2.69      return __sync_lock_test_and_set(&a->value, v);
    2.70  #elif defined(__SOLARIS__) && defined(_LP64)
    2.71 @@ -187,6 +218,8 @@
    2.72      return (void *) _InterlockedExchange((long *)a, (long) v);
    2.73  #elif defined(HAVE_MSC_ATOMICS) && (!_M_IX86)
    2.74      return _InterlockedExchangePointer(a, v);
    2.75 +#elif defined(HAVE_WATCOM_ATOMICS)
    2.76 +    return (void *) _SDL_xchg_watcom((int *)a, (long)v);
    2.77  #elif defined(HAVE_GCC_ATOMICS)
    2.78      return __sync_lock_test_and_set(a, v);
    2.79  #elif defined(__SOLARIS__)
    2.80 @@ -205,6 +238,8 @@
    2.81  {
    2.82  #ifdef HAVE_MSC_ATOMICS
    2.83      return _InterlockedExchangeAdd((long*)&a->value, v);
    2.84 +#elif defined(HAVE_WATCOM_ATOMICS)
    2.85 +    return _SDL_xadd_watcom(&a->value, v);
    2.86  #elif defined(HAVE_GCC_ATOMICS)
    2.87      return __sync_fetch_and_add(&a->value, v);
    2.88  #elif defined(__SOLARIS__)
     3.1 --- a/src/atomic/SDL_spinlock.c	Thu Aug 17 21:35:46 2017 -0400
     3.2 +++ b/src/atomic/SDL_spinlock.c	Fri Aug 18 16:35:55 2017 -0400
     3.3 @@ -32,6 +32,16 @@
     3.4  #include <atomic.h>
     3.5  #endif
     3.6  
     3.7 +#if defined(__WATCOMC__) && defined(__386__)
     3.8 +SDL_COMPILE_TIME_ASSERT(locksize, 4==sizeof(SDL_SpinLock));
     3.9 +extern _inline int _SDL_xchg_watcom(volatile int *a, int v);
    3.10 +#pragma aux _SDL_xchg_watcom = \
    3.11 +  "xchg [ecx], eax" \
    3.12 +  parm [ecx] [eax] \
    3.13 +  value [eax] \
    3.14 +  modify exact [eax];
    3.15 +#endif /* __WATCOMC__ && __386__ */
    3.16 +
    3.17  /* This function is where all the magic happens... */
    3.18  SDL_bool
    3.19  SDL_AtomicTryLock(SDL_SpinLock *lock)
    3.20 @@ -58,6 +68,9 @@
    3.21      SDL_COMPILE_TIME_ASSERT(locksize, sizeof(*lock) == sizeof(long));
    3.22      return (InterlockedExchange((long*)lock, 1) == 0);
    3.23  
    3.24 +#elif defined(__WATCOMC__) && defined(__386__)
    3.25 +    return _SDL_xchg_watcom(lock, 1) == 0;
    3.26 +
    3.27  #elif HAVE_GCC_ATOMICS || HAVE_GCC_SYNC_LOCK_TEST_AND_SET
    3.28      return (__sync_lock_test_and_set(lock, 1) == 0);
    3.29  
    3.30 @@ -119,6 +132,10 @@
    3.31      _ReadWriteBarrier();
    3.32      *lock = 0;
    3.33  
    3.34 +#elif defined(__WATCOMC__) && defined(__386__)
    3.35 +    SDL_CompilerBarrier ();
    3.36 +    *lock = 0;
    3.37 +
    3.38  #elif HAVE_GCC_ATOMICS || HAVE_GCC_SYNC_LOCK_TEST_AND_SET
    3.39      __sync_lock_release(lock);
    3.40