dotgnu-pnet-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[dotgnu-pnet-commits] [SCM] DotGNU Portable.NET engine, compilers and to


From: Klaus Treichel
Subject: [dotgnu-pnet-commits] [SCM] DotGNU Portable.NET engine, compilers and tools (pnet) branch, master, updated. 86384a46716a3defd4866339df1423fef667e9ee
Date: Sun, 11 Oct 2009 19:23:38 +0000

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "DotGNU Portable.NET engine, compilers and tools (pnet)".

The branch, master has been updated
       via  86384a46716a3defd4866339df1423fef667e9ee (commit)
      from  304af73dcfdf26e127f331b0a3147b82118189fb (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://git.savannah.gnu.org/cgit/pnet.git/commit/?id=86384a46716a3defd4866339df1423fef667e9ee

commit 86384a46716a3defd4866339df1423fef667e9ee
Author: Klaus Treichel <address@hidden>
Date:   Sun Oct 11 21:23:03 2009 +0200

    Add interlocked functions with acquire, release and full memory semantics.
    Add native interlocked functions for 32 bit powerpc.

diff --git a/ChangeLog b/ChangeLog
index 23ec8c6..de47ac1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,29 @@
+2009-10-11  Klaus Treichel  <address@hidden>
+
+       * support/Makefile.am: add interlocked_arm.h and interlocked_ppc.h to
+       the sources.
+
+       * support/interlocked.h: Add notes ablut the now available relaxed,
+       acquire, release and full memory order semantics of the available
+       interlocked functions.
+       Include interlocked_ppc.h.
+
+       * support/interlocked_any.h: Add alternative implementations for the
+       interlocked functions if no native implementation is available.
+
+       * support/interlocked_arm.h: Add definitions for the interlocked
+       functions with acquire, release and full semantics.
+
+       * support/interlocked_x86.h: Append _Full to all interlocked functions
+       because lock prefixed functions are a full memory barrier.
+
+       * support/interlocked_ppc.h: Add native interlocked functions for
+       32 bit powerpc.
+
+       * tests/test_thread.c: Add tests for interlocked load and store.
+       Change the interlocked functions in the thrash tests to acquire and
+       release.
+
 2009-09-13  Klaus Treichel  <address@hidden>
 
        * support/interlocked.h: Add note about the interlocked functions
diff --git a/support/Makefile.am b/support/Makefile.am
index 7677011..7be03ec 100644
--- a/support/Makefile.am
+++ b/support/Makefile.am
@@ -33,6 +33,8 @@ libILSupport_a_SOURCES = aes.c \
                                                 hb_gc.c \
                                                 interlocked.h \
                                                 interlocked_any.h \
+                                                interlocked_arm.h \
+                                                interlocked_ppc.h \
                                                 interlocked_x86.h \
                                                 intern.c \
                                                 interrupt.c \
diff --git a/support/interlocked.h b/support/interlocked.h
index ff8c2d0..fce4f2c 100644
--- a/support/interlocked.h
+++ b/support/interlocked.h
@@ -34,53 +34,115 @@
 #endif
 
 /*
+ * Semantics:
+ * All Functions without one of the siffixes _Acquire, _Release or
+ * _Full have a relaxed memory access order constraint. This means it is not
+ * guaranteed that the operation is visible to the public at the point where
+ * the source code states with respect to preceding and following loads or
+ * stores. This can happen because of possible processor load / store
+ * reordering.
+ *
+ * _Acquire Suffix: Operations with this suffix guarantee that no operations
+ * following this instruction are moved before this instruction.
+ *
+ * _Release Suffix: Operations with this suffix guarantee that no operations
+ * preceeding this instruction are moved after this instruction.
+ *
+ * _Full suffix: The rules for _Acquire and _Release apply.
+ *
  * NOTE: The identifier after define: has to be defined if an arch specific
  * version of this function is available.
  *
  * Implemented functions:
  *
- * Flush cache and set a memory barrier.
+ * Full memory barrier.
  * define: IL_HAVE_INTERLOCKED_MEMORYBARRIER
  *
  * void ILInterlockedMemoryBarrier(void)
  *
+ * Load a 32 bit value from a location.
+ * Returns the 32 bit value from the location specified.
+ * define: IL_HAVE_INTERLOCKED_LOAD
+ * define: IL_HAVE_INTERLOCKED_LOAD_ACQUIRE
+ *
+ * ILInt32 ILInterlockedLoad(const volatile ILInt32 *dest)
+ *
+ * Load a pointer value from a location.
+ * Returns the pointer value from the location specified.
+ * define: IL_HAVE_INTERLOCKED_LOADPOINTER
+ * define: IL_HAVE_INTERLOCKED_LOADPOINTER_ACQUIRE
+ *
+ * void * ILInterlockedLoadPointer(void * const volatile *dest)
+ *
+ * Store a 32 bit value to a location.
+ * define: IL_HAVE_INTERLOCKED_STORE
+ * define: IL_HAVE_INTERLOCKED_STORE_RELEASE
+ *
+ * void ILInterlockedStore(volatile ILInt32 *dest, ILInt32 value)
+ *
+ * Store a pointer value to a location.
+ * define: IL_HAVE_INTERLOCKED_STOREPOINTER
+ * define: IL_HAVE_INTERLOCKED_STOREPOINTER_RELEASE
+ *
+ * void ILInterlockedStorePointer(void * volatile *dest, void *value)
+ *
  * Exchange integers.
  * Returns the original value at *dest.
  * define: IL_HAVE_INTERLOCKED_EXCHANGE
+ * define: IL_HAVE_INTERLOCKED_EXCHANGE_ACQUIRE
+ * define: IL_HAVE_INTERLOCKED_EXCHANGE_RELEASE
+ * define: IL_HAVE_INTERLOCKED_EXCHANGE_FULL
  *
- * ILInt32 ILInterlockedExchange(ILInt32 *dest, ILInt32 value)
+ * ILInt32 ILInterlockedExchange(volatile ILInt32 *dest, ILInt32 value)
  *
  * Exchange pointers.
  * Returns the original value at *dest 
  * define: IL_HAVE_INTERLOCKED_EXCHANGEPOINTERS
+ * define: IL_HAVE_INTERLOCKED_EXCHANGEPOINTERS_ACQUIRE
+ * define: IL_HAVE_INTERLOCKED_EXCHANGEPOINTERS_RELEASE
+ * define: IL_HAVE_INTERLOCKED_EXCHANGEPOINTERS_FULL
  *
- * void *ILInterlockedExchangePointers(void **dest, void *value)
+ * void *ILInterlockedExchangePointers(void * volatile *dest, void *value)
  *
  * Compare and exchange two 32bit integers.
  * Returns the original value at *dest 
  * define: IL_HAVE_INTERLOCKED_COMPAREANDEXCHANGE
+ * define: IL_HAVE_INTERLOCKED_COMPAREANDEXCHANGE_ACQUIRE
+ * define: IL_HAVE_INTERLOCKED_COMPAREANDEXCHANGE_RELEASE
+ * define: IL_HAVE_INTERLOCKED_COMPAREANDEXCHANGE_FULL
  *
- * ILInt32 ILInterlockedCompareAndExchange(ILInt32 *dest, ILInt32 value,
+ * ILInt32 ILInterlockedCompareAndExchange(volatile ILInt32 *dest,
+ *                                                                             
   ILInt32 value,
  *                                                                             
   ILInt32 comparand)
  *
  * Compare and exchange two pointers.
  * Returns the original value at *dest 
  * define: IL_HAVE_INTERLOCKED_COMPAREANDEXCHANGEPOINTERS
+ * define: IL_HAVE_INTERLOCKED_COMPAREANDEXCHANGEPOINTERS_ACQUIRE
+ * define: IL_HAVE_INTERLOCKED_COMPAREANDEXCHANGEPOINTERS_RELEASE
+ * define: IL_HAVE_INTERLOCKED_COMPAREANDEXCHANGEPOINTERS_FULL
  * 
- * void *ILInterlockedCompareAndExchangePointers(void **dest, void *value,
+ * void *ILInterlockedCompareAndExchangePointers(void * volatile *dest,
+ *                                                                             
                 void *value,
  *                                                                             
                 void *comparand)
  *
  * Add the 32 bit values *dest and value and store the result at *dest.
  * Returns the result od the addition (new value at *dest)
  * define: IL_HAVE_INTERLOCKED_ADD
+ * define: IL_HAVE_INTERLOCKED_ADD_ACQUIRE
+ * define: IL_HAVE_INTERLOCKED_ADD_RELEASE
+ * define: IL_HAVE_INTERLOCKED_ADD_FULL
  *
- * ILInt32 ILInterlockedAdd(ILInt32 *dest, ILInt32 value)
+ * ILInt32 ILInterlockedAdd(volatile ILInt32 *dest, ILInt32 value)
  *
  * Substract the 32 bit values *dest and value and store the result at *dest.
  * Returns the result od the subtraction (new value at *dest)
  * define: IL_HAVE_INTERLOCKED_SUB
+ * define: IL_HAVE_INTERLOCKED_SUB_ACQUIRE
+ * define: IL_HAVE_INTERLOCKED_SUB_RELEASE
+ * define: IL_HAVE_INTERLOCKED_SUB_FULL
  *
- * ILInt32 ILInterlockedSub(ILInt32 *dest, ILInt32 value)
+ * ILInt32 ILInterlockedSub(volatile ILInt32 *dest, ILInt32 value)
  *
  * NOTE: If not defined by the arch specific definition it is a implemented
  * by a macro that is using ILInterlockedAdd with value negated.
@@ -89,8 +151,11 @@
  * Increment a 32bit integer.
  * Returns the value of the incremented integer.
  * define: IL_HAVE_INTERLOCKED_INCREMENT
+ * define: IL_HAVE_INTERLOCKED_INCREMENT_ACQUIRE
+ * define: IL_HAVE_INTERLOCKED_INCREMENT_RELEASE
+ * define: IL_HAVE_INTERLOCKED_INCREMENT_FULL
  *
- * ILInt32 ILInterlockedIncrement(ILInt32 *dest)
+ * ILInt32 ILInterlockedIncrement(volatile ILInt32 *dest)
  *
  * NOTE: If not defined by the arch specific definition it is a implemented
  * by a macro that is using ILInterlockedAdd with a value of 1.
@@ -99,8 +164,11 @@
  * Decrement a 32bit integer.
  * Returns the value of the decremented integer.
  * define: IL_HAVE_INTERLOCKED_DECREMENT
+ * define: IL_HAVE_INTERLOCKED_DECREMENT_ACQUIRE
+ * define: IL_HAVE_INTERLOCKED_DECREMENT_RELEASE
+ * define: IL_HAVE_INTERLOCKED_DECREMENT_FULL
  *
- * ILInt32 ILInterlockedDecrement(ILInt32 *dest)
+ * ILInt32 ILInterlockedDecrement(volatile ILInt32 *dest)
  *
  * NOTE: If not defined by the arch specific definition it is a implemented
  * by a macro that is using ILInterlockedSub with a value of 1.
@@ -108,13 +176,22 @@
  *
  * Bitwise AND of *dest and value and the result is stored at *dest
  * define: IL_HAVE_INTERLOCKED_AND
+ * define: IL_HAVE_INTERLOCKED_AND_ACQUIRE
+ * define: IL_HAVE_INTERLOCKED_AND_RELEASE
+ * define: IL_HAVE_INTERLOCKED_AND_FULL
  *
  * void ILInterlockedAnd(volatile ILUInt32 *dest, ILUInt32 value)
  *
  * Bitwise OR of *dest and value and the result is stored at *dest
  * define: IL_HAVE_INTERLOCKED_OR
+ * define: IL_HAVE_INTERLOCKED_OR_ACQUIRE
+ * define: IL_HAVE_INTERLOCKED_OR_RELEASE
+ * define: IL_HAVE_INTERLOCKED_OR_FULL
  *
- * void ILInterlockedAnd(volatile ILUInt32 *dest, ILUInt32 value)
+ * void ILInterlockedOr(volatile ILUInt32 *dest, ILUInt32 value)
+ *
+ * NOTE: If archdependent versions with the _Aquire or _Release suffix
+ * are not defined they will be mapped to the version with the _Full suffix.
  *
  * NOTE: The versions using a mutex to protect the value are generally
  * available with the same name and a leading underscore.
@@ -123,10 +200,21 @@
  * consistent availability of more than one interlocked function.
  */
 
+/*
+ * Define a barrier for the used compiler to prevent that the operation
+ * in question is moved around by the compiler's optimizer.
+ */
+#if defined(__GNUC__)
+#define ILInterlockedCompilerBarrier   __asm__ __volatile__ ("" : : : "memory")
+#else
+#define ILInterlockedCompilerBarrier
+#endif
+
 /* TODO: implement native interlocked functions for other processors */
 
 #include "interlocked_x86.h"
 #include "interlocked_arm.h"
+#include "interlocked_ppc.h"
 #include "interlocked_any.h"
 
 #endif /* _INTERLOCKED_H_ */
diff --git a/support/interlocked_any.h b/support/interlocked_any.h
index 9392931..87c011e 100644
--- a/support/interlocked_any.h
+++ b/support/interlocked_any.h
@@ -32,6 +32,127 @@ static IL_INLINE void ILInterlockedMemoryBarrier()
 #endif /* !defined(IL_HAVE_INTERLOCKED_MEMORYBARRIER) */
 
 /*
+ * Load a 32 bit value from a location.
+ */
+static IL_INLINE ILInt32 _ILInterlockedLoad(const volatile ILInt32 *dest)
+{
+       /*
+        * Cast away the volatile because gcc will generate code with acquire
+        * semantics on IA64 otherwise.
+        */
+       return *(ILInt32 *)dest;
+}
+#if !defined(IL_HAVE_INTERLOCKED_LOAD)
+#define ILInterlockedLoad(dest)        _ILInterlockedLoad((dest))
+#endif /* !defined(IL_HAVE_INTERLOCKED_LOAD) */
+
+/*
+ * Load a 32 bit value from a location with acquire semantics.
+ */
+static IL_INLINE ILInt32 _ILInterlockedLoad_Acquire(const volatile ILInt32 
*dest)
+{
+       ILInt32 value;
+
+       value = *dest;
+       ILInterlockedCompilerBarrier;
+       return value;
+}
+#if !defined(IL_HAVE_INTERLOCKED_LOAD_ACQUIRE)
+#define ILInterlockedLoad_Acquire(dest)        
_ILInterlockedLoad_Acquire((dest))
+#endif /* !defined(IL_HAVE_INTERLOCKED_LOAD_ACQUIRE) */
+
+/*
+ * Load a pointer value from a location.
+ */
+static IL_INLINE void * _ILInterlockedLoadPointer(void * const volatile *dest)
+{
+       /*
+        * Cast away the volatile because gcc will generate code with acquire
+        * semantics on IA64 otherwise.
+        */
+       return *(void **)dest;
+}
+#if !defined(IL_HAVE_INTERLOCKED_LOADPOINTER)
+#define ILInterlockedLoadPointer(dest) _ILInterlockedLoadPointer((dest))
+#endif /* !defined(IL_HAVE_INTERLOCKED_LOADPOINTER) */
+
+/*
+ * Load a pointer value from a location with acquire semantics.
+ */
+static IL_INLINE void *_ILInterlockedLoadPointer_Acquire(void * const volatile 
*dest)
+{
+       void *value;
+
+       value = *dest;
+       ILInterlockedCompilerBarrier;
+       return value;
+}
+#if !defined(IL_HAVE_INTERLOCKED_LOADPOINTER_ACQUIRE)
+#define ILInterlockedLoadPointer_Acquire(dest) 
_ILInterlockedLoadPointer_Acquire((dest))
+#endif /* !defined(IL_HAVE_INTERLOCKED_LOADPOINTER_ACQUIRE) */
+
+/*
+ * Store a 32 bit value to a location.
+ */
+static IL_INLINE void _ILInterlockedStore(volatile ILInt32 *dest,
+                                                                               
  ILInt32 value)
+{
+       /*
+        * Cast away the volatile because gcc will generate code with release
+        * semantics on IA64 otherwise.
+        */
+       *(ILInt32 *)dest = value;
+}
+#if !defined(IL_HAVE_INTERLOCKED_STORE)
+#define ILInterlockedStore(dest, value)        _ILInterlockedStore((dest), 
(value))
+#endif /* !defined(IL_HAVE_INTERLOCKED_STORE) */
+
+/*
+ * Store a 32 bit value to a location with release semantics.
+ */
+static IL_INLINE void _ILInterlockedStore_Release(volatile ILInt32 *dest,
+                                                                               
                  ILInt32 value)
+{
+       ILInterlockedCompilerBarrier;
+       *dest = value;
+}
+#if !defined(IL_HAVE_INTERLOCKED_STORE_RELEASE)
+#define ILInterlockedStore_Release(dest, value) \
+               _ILInterlockedStore_Release((dest), (value))
+#endif /* !defined(IL_HAVE_INTERLOCKED_STORE_RELEASE) */
+
+/*
+ * Store a pointer value to a location.
+ */
+static IL_INLINE void _ILInterlockedStorePointer(void * volatile *dest,
+                                                                               
                 void *value)
+{
+       /*
+        * Cast away the volatile because gcc will generate code with release
+        * semantics on IA64 otherwise.
+        */
+       *(void **)dest = value;
+}
+#if !defined(IL_HAVE_INTERLOCKED_STOREPOINTER)
+#define ILInterlockedStorePointer(dest, value) \
+               _ILInterlockedStorePointer((dest), (value))
+#endif /* !defined(IL_HAVE_INTERLOCKED_STOREPOINTER) */
+
+/*
+ * Store a pointer value to a location with release semantics.
+ */
+static IL_INLINE void _ILInterlockedStorePointer_Release(void * volatile *dest,
+                                                                               
                                 void *value)
+{
+       ILInterlockedCompilerBarrier;
+       *dest = value;
+}
+#if !defined(IL_HAVE_INTERLOCKED_STOREPOINTER_RELEASE)
+#define ILInterlockedStorePointer_Release(dest, value) \
+               _ILInterlockedStorePointer_Release((dest), (value))
+#endif /* !defined(IL_HAVE_INTERLOCKED_STOREPOINTER_RELEASE) */
+
+/*
  * Exchange integers.
  */
 static IL_INLINE ILInt32 _ILInterlockedExchange(volatile ILInt32 *dest,
@@ -48,10 +169,48 @@ static IL_INLINE ILInt32 _ILInterlockedExchange(volatile 
ILInt32 *dest,
 
        return retval;
 }
+#if defined(IL_HAVE_INTERLOCKED_EXCHANGE_FULL)
+#if !defined(IL_HAVE_INTERLOCKED_EXCHANGE_ACQUIRE)
+#define ILInterlockedExchange_Acquire(dest, value) \
+               ILInterlockedExchange_Full((dest), (value))
+#define IL_HAVE_INTERLOCKED_EXCHANGE_ACQUIRE 1
+#endif /* !defined(IL_HAVE_INTERLOCKED_EXCHANGE_ACQUIRE) */
+#if !defined(IL_HAVE_INTERLOCKED_EXCHANGE_RELEASE)
+#define ILInterlockedExchange_Release(dest, value) \
+               ILInterlockedExchange_Full((dest), (value))
+#define IL_HAVE_INTERLOCKED_EXCHANGE_RELEASE 1
+#endif /* !defined(IL_HAVE_INTERLOCKED_EXCHANGE_RELEASE) */
+#endif /* defined(IL_HAVE_INTERLOCKED_EXCHANGE_FULL) */
 #if !defined(IL_HAVE_INTERLOCKED_EXCHANGE)
+#if defined(IL_HAVE_INTERLOCKED_EXCHANGE_ACQUIRE)
+#define ILInterlockedExchange(dest, value) \
+               ILInterlockedExchange_Acquire((dest), (value))
+#define IL_HAVE_INTERLOCKED_EXCHANGE 1
+#elif defined(IL_HAVE_INTERLOCKED_EXCHANGE_RELEASE)
+#define ILInterlockedExchange(dest, value) \
+               ILInterlockedExchange_Release((dest), (value))
+#define IL_HAVE_INTERLOCKED_EXCHANGE 1
+#elif defined(IL_HAVE_INTERLOCKED_EXCHANGE_FULL)
+#define ILInterlockedExchange(dest, value) \
+               ILInterlockedExchange_Full((dest), (value))
+#define IL_HAVE_INTERLOCKED_EXCHANGE 1
+#else /* !defined(IL_HAVE_INTERLOCKED_EXCHANGE_FULL) */
 #define ILInterlockedExchange(dest, value) \
                _ILInterlockedExchange((dest), (value))
+#endif /* !defined(IL_HAVE_INTERLOCKED_EXCHANGE_FULL) */
 #endif /* !defined(IL_HAVE_INTERLOCKED_EXCHANGE) */
+#if !defined(IL_HAVE_INTERLOCKED_EXCHANGE_ACQUIRE)
+#define ILInterlockedExchange_Acquire(dest, value) \
+               _ILInterlockedExchange((dest), (value))
+#endif /* !defined(IL_HAVE_INTERLOCKED_EXCHANGE_ACQUIRE) */
+#if !defined(IL_HAVE_INTERLOCKED_EXCHANGE_RELEASE)
+#define ILInterlockedExchange_Release(dest, value) \
+               _ILInterlockedExchange((dest), (value))
+#endif /* !defined(IL_HAVE_INTERLOCKED_EXCHANGE_RELEASE) */
+#if !defined(IL_HAVE_INTERLOCKED_EXCHANGE_FULL)
+#define ILInterlockedExchange_Full(dest, value) \
+               _ILInterlockedExchange((dest), (value))
+#endif /* !defined(IL_HAVE_INTERLOCKED_EXCHANGE_FULL) */
 
 /*
  * Exchange pointers.
@@ -70,10 +229,48 @@ static IL_INLINE void *_ILInterlockedExchangePointers(void 
* volatile *dest,
        
        return retval;
 }
+#if defined(IL_HAVE_INTERLOCKED_EXCHANGEPOINTERS_FULL)
+#if !defined(IL_HAVE_INTERLOCKED_EXCHANGEPOINTERS_ACQUIRE)
+#define ILInterlockedExchangePointers_Acquire(dest, value) \
+               ILInterlockedExchangePointers_Full((dest), (value))
+#define IL_HAVE_INTERLOCKED_EXCHANGEPOINTERS_ACQUIRE 1
+#endif /* !defined(IL_HAVE_INTERLOCKED_EXCHANGEPOINTERS_ACQUIRE) */
+#if !defined(IL_HAVE_INTERLOCKED_EXCHANGEPOINTERS_RELEASE)
+#define ILInterlockedExchangePointers_Release(dest, value) \
+               ILInterlockedExchangePointers_Full((dest), (value))
+#define IL_HAVE_INTERLOCKED_EXCHANGEPOINTERS_RELEASE 1
+#endif /* !defined(IL_HAVE_INTERLOCKED_EXCHANGEPOINTERS_RELEASE) */
+#endif /* defined(IL_HAVE_INTERLOCKED_EXCHANGEPOINTERS_FULL) */
 #if !defined(IL_HAVE_INTERLOCKED_EXCHANGEPOINTERS)
+#if defined(IL_HAVE_INTERLOCKED_EXCHANGEPOINTERS_ACQUIRE)
+#define ILInterlockedExchangePointers(dest, value) \
+               ILInterlockedExchangePointers_Acquire((dest), (value))
+#define IL_HAVE_INTERLOCKED_EXCHANGEPOINTERS 1
+#elif defined(IL_HAVE_INTERLOCKED_EXCHANGEPOINTERS_RELEASE)
+#define ILInterlockedExchangePointers(dest, value) \
+               ILInterlockedExchangePointers_Release((dest), (value))
+#define IL_HAVE_INTERLOCKED_EXCHANGEPOINTERS 1
+#elif defined(IL_HAVE_INTERLOCKED_EXCHANGEPOINTERS_FULL)
+#define ILInterlockedExchangePointers(dest, value) \
+               ILInterlockedExchangePointers_Full((dest), (value))
+#define IL_HAVE_INTERLOCKED_EXCHANGE 1
+#else /* !defined(IL_HAVE_INTERLOCKED_EXCHANGEPOINTERS_FULL) */
 #define ILInterlockedExchangePointers(dest, value) \
                _ILInterlockedExchangePointers((dest), (value))
+#endif /* !defined(IL_HAVE_INTERLOCKED_EXCHANGEPOINTERS_FULL) */
 #endif /* !defined(IL_HAVE_INTERLOCKED_EXCHANGEPOINTERS) */
+#if !defined(IL_HAVE_INTERLOCKED_EXCHANGEPOINTERS_ACQUIRE)
+#define ILInterlockedExchangePointers_Acquire(dest, value) \
+               _ILInterlockedExchangePointers((dest), (value))
+#endif /* !defined(IL_HAVE_INTERLOCKED_EXCHANGEPOINTERS_ACQUIRE) */
+#if !defined(IL_HAVE_INTERLOCKED_EXCHANGEPOINTERS_RELEASE)
+#define ILInterlockedExchangePointers_Release(dest, value) \
+               _ILInterlockedExchangePointers((dest), (value))
+#endif /* !defined(IL_HAVE_INTERLOCKED_EXCHANGEPOINTERS_RELEASE) */
+#if !defined(IL_HAVE_INTERLOCKED_EXCHANGEPOINTERS_FULL)
+#define ILInterlockedExchangePointers_Full(dest, value) \
+               _ILInterlockedExchangePointers((dest), (value))
+#endif /* !defined(IL_HAVE_INTERLOCKED_EXCHANGE_FULL) */
 
 /*
  * Compare and exchange two 32bit integers.
@@ -97,10 +294,48 @@ static IL_INLINE ILInt32 
_ILInterlockedCompareAndExchange(volatile ILInt32 *dest
        
        return retval;
 }
+#if defined(IL_HAVE_INTERLOCKED_COMPAREANDEXCHANGE_FULL)
+#if !defined(IL_HAVE_INTERLOCKED_COMPAREANDEXCHANGE_ACQUIRE)
+#define ILInterlockedCompareAndExchange_Acquire(dest, value, comparand) \
+               ILInterlockedCompareAndExchange_Full((dest), (value), 
(comparand))
+#define IL_HAVE_INTERLOCKED_COMPAREANDEXCHANGE_ACQUIRE 1
+#endif /* !defined(IL_HAVE_INTERLOCKED_COMPAREANDEXCHANGE_ACQUIRE) */
+#if !defined(IL_HAVE_INTERLOCKED_COMPAREANDEXCHANGE_RELEASE)
+#define ILInterlockedCompareAndExchange_Release(dest, value, comparand) \
+               ILInterlockedCompareAndExchange_Full((dest), (value), 
(comparand))
+#define IL_HAVE_INTERLOCKED_COMPAREANDEXCHANGE_RELEASE 1
+#endif /* !defined(IL_HAVE_INTERLOCKED_COMPAREANDEXCHANGE_RELEASE) */
+#endif /* defined(IL_HAVE_INTERLOCKED_COMPAREANDEXCHANGE_FULL) */
 #if !defined(IL_HAVE_INTERLOCKED_COMPAREANDEXCHANGE)
+#if defined(IL_HAVE_INTERLOCKED_COMPAREANDEXCHANGE_ACQUIRE)
+#define ILInterlockedCompareAndExchange(dest, value, comparand) \
+               ILInterlockedCompareAndExchange_Acquire((dest), (value), 
(comparand))
+#define IL_HAVE_INTERLOCKED_COMPAREANDEXCHANGE 1
+#elif defined(IL_HAVE_INTERLOCKED_COMPAREANDEXCHANGE_RELEASE)
+#define ILInterlockedCompareAndExchange(dest, value, comparand) \
+               ILInterlockedCompareAndExchange_Release((dest), (value), 
(comparand))
+#define IL_HAVE_INTERLOCKED_COMPAREANDEXCHANGE 1
+#elif defined(IL_HAVE_INTERLOCKED_COMPAREANDEXCHANGE_FULL)
+#define ILInterlockedCompareAndExchange(dest, value, comparand) \
+               ILInterlockedCompareAndExchange_Full((dest), (value), 
(comparand))
+#define IL_HAVE_INTERLOCKED_COMPAREANDEXCHANGE 1
+#else /* !defined(IL_HAVE_INTERLOCKED_COMPAREANDEXCHANGE_FULL) */
 #define ILInterlockedCompareAndExchange(dest, value, comparand) \
                _ILInterlockedCompareAndExchange((dest), (value), (comparand))
+#endif /* !defined(IL_HAVE_INTERLOCKED_COMPAREANDEXCHANGE_FULL) */
 #endif /* !defined(IL_HAVE_INTERLOCKED_COMPAREANDEXCHANGE) */
+#if !defined(IL_HAVE_INTERLOCKED_COMPAREANDEXCHANGE_ACQUIRE)
+#define ILInterlockedCompareAndExchange_Acquire(dest, value, comparand) \
+               _ILInterlockedCompareAndExchange((dest), (value), (comparand))
+#endif /* !defined(IL_HAVE_INTERLOCKED_COMPAREANDEXCHANGE_ACQUIRE) */
+#if !defined(IL_HAVE_INTERLOCKED_COMPAREANDEXCHANGE_RELEASE)
+#define ILInterlockedCompareAndExchange_Release(dest, value, comparand) \
+               _ILInterlockedCompareAndExchange((dest), (value), (comparand))
+#endif /* !defined(IL_HAVE_INTERLOCKED_COMPAREANDEXCHANGE_RELEASE) */
+#if !defined(IL_HAVE_INTERLOCKED_COMPAREANDEXCHANGE_FULL)
+#define ILInterlockedCompareAndExchange_Full(dest, value, comparand) \
+               _ILInterlockedCompareAndExchange((dest), (value), (comparand))
+#endif /* !defined(IL_HAVE_INTERLOCKED_COMPAREANDEXCHANGE_FULL) */
 
 /*
  * Compare and exchange two pointers.
@@ -124,10 +359,48 @@ static IL_INLINE void 
*_ILInterlockedCompareAndExchangePointers(void * volatile
        
        return retval;
 }
+#if defined(IL_HAVE_INTERLOCKED_COMPAREANDEXCHANGEPOINTERS_FULL)
+#if !defined(IL_HAVE_INTERLOCKED_COMPAREANDEXCHANGEPOINTERS_ACQUIRE)
+#define ILInterlockedCompareAndExchangePointers_Acquire(dest, value, 
comparand) \
+               ILInterlockedCompareAndExchangePointers_Full((dest), (value), 
(comparand))
+#define IL_HAVE_INTERLOCKED_COMPAREANDEXCHANGEPOINTERS_ACQUIRE 1
+#endif /* !defined(IL_HAVE_INTERLOCKED_COMPAREANDEXCHANGEPOINTERS_ACQUIRE) */
+#if !defined(IL_HAVE_INTERLOCKED_COMPAREANDEXCHANGEPOINTERS_RELEASE)
+#define ILInterlockedCompareAndExchangePointers_Release(dest, value, 
comparand) \
+               ILInterlockedCompareAndExchangePointers_Full((dest), (value), 
(comparand))
+#define IL_HAVE_INTERLOCKED_COMPAREANDEXCHANGEPOINTERS_RELEASE 1
+#endif /* !defined(IL_HAVE_INTERLOCKED_COMPAREANDEXCHANGEPOINTERS_RELEASE) */
+#endif /* defined(IL_HAVE_INTERLOCKED_COMPAREANDEXCHANGEPOINTERS_FULL) */
 #if !defined(IL_HAVE_INTERLOCKED_COMPAREANDEXCHANGEPOINTERS)
+#if defined(IL_HAVE_INTERLOCKED_COMPAREANDEXCHANGEPOINTERS_ACQUIRE)
+#define ILInterlockedCompareAndExchangePointers(dest, value, comparand) \
+               ILInterlockedCompareAndExchangePointers_Acquire((dest), 
(value), (comparand))
+#define IL_HAVE_INTERLOCKED_COMPAREANDEXCHANGEPOINTERS 1
+#elif defined(IL_HAVE_INTERLOCKED_COMPAREANDEXCHANGEPOINTERS_RELEASE)
+#define ILInterlockedCompareAndExchangePointers(dest, value, comparand) \
+               ILInterlockedCompareAndExchangePointers_Release((dest), 
(value), (comparand))
+#define IL_HAVE_INTERLOCKED_COMPAREANDEXCHANGEPOINTERS 1
+#elif defined(IL_HAVE_INTERLOCKED_COMPAREANDEXCHANGEPOINTERS_FULL)
+#define ILInterlockedCompareAndExchangePointers(dest, value, comparand) \
+               ILInterlockedCompareAndExchangePointers_Full((dest), (value), 
(comparand))
+#define IL_HAVE_INTERLOCKED_COMPAREANDEXCHANGEPOINTERS 1
+#else /* !defined(IL_HAVE_INTERLOCKED_COMPAREANDEXCHANGEPOINTERS_FULL) */
 #define ILInterlockedCompareAndExchangePointers(dest, value, comparand) \
                _ILInterlockedCompareAndExchangePointers((dest), (value), 
(comparand))
+#endif /* !defined(IL_HAVE_INTERLOCKED_COMPAREANDEXCHANGEPOINTERS_FULL) */
 #endif /* !defined(IL_HAVE_INTERLOCKED_COMPAREANDEXCHANGEPOINTERS) */
+#if !defined(IL_HAVE_INTERLOCKED_COMPAREANDEXCHANGEPOINTERS_ACQUIRE)
+#define ILInterlockedCompareAndExchangePointers_Acquire(dest, value, 
comparand) \
+               _ILInterlockedCompareAndExchangePointers((dest), (value), 
(comparand))
+#endif /* !defined(IL_HAVE_INTERLOCKED_COMPAREANDEXCHANGEPOINTERS_ACQUIRE) */
+#if !defined(IL_HAVE_INTERLOCKED_COMPAREANDEXCHANGEPOINTERS_RELEASE)
+#define ILInterlockedCompareAndExchangePointers_Release(dest, value, 
comparand) \
+               _ILInterlockedCompareAndExchangePointers((dest), (value), 
(comparand))
+#endif /* !defined(IL_HAVE_INTERLOCKED_COMPAREANDEXCHANGEPOINTERS_RELEASE) */
+#if !defined(IL_HAVE_INTERLOCKED_COMPAREANDEXCHANGEPOINTERS_FULL)
+#define ILInterlockedCompareAndExchangePointers_Full(dest, value, comparand) \
+               _ILInterlockedCompareAndExchangePointers((dest), (value), 
(comparand))
+#endif /* !defined(IL_HAVE_INTERLOCKED_COMPAREANDEXCHANGEPOINTERS_FULL) */
 
 /*
  * Add the two 32bit integers *dest and value and store the result at *dest.
@@ -146,48 +419,275 @@ static IL_INLINE ILInt32 _ILInterlockedAdd(volatile 
ILInt32 *dest,
 
        return retval;  
 }
+#if defined(IL_HAVE_INTERLOCKED_ADD_FULL)
+#if !defined(IL_HAVE_INTERLOCKED_ADD_ACQUIRE)
+#define ILInterlockedAdd_Acquire(dest, value) \
+               ILInterlockedAdd_Full((dest), (value))
+#define IL_HAVE_INTERLOCKED_ADD_ACQUIRE 1
+#endif /* !defined(IL_HAVE_INTERLOCKED_ADD_ACQUIRE) */
+#if !defined(IL_HAVE_INTERLOCKED_ADD_RELEASE)
+#define ILInterlockedAdd_Release(dest, value) \
+               ILInterlockedAdd_Full((dest), (value))
+#define IL_HAVE_INTERLOCKED_ADD_RELEASE 1
+#endif /* !defined(IL_HAVE_INTERLOCKED_ADD_RELEASE) */
+#endif /* defined(IL_HAVE_INTERLOCKED_ADD_FULL) */
+#if !defined(IL_HAVE_INTERLOCKED_ADD)
+#if defined(IL_HAVE_INTERLOCKED_ADD_ACQUIRE)
+#define ILInterlockedAdd(dest, value) \
+               ILInterlockedAdd_Acquire((dest), (value))
+#define IL_HAVE_INTERLOCKED_ADD 1
+#elif defined(IL_HAVE_INTERLOCKED_ADD_RELEASE)
+#define ILInterlockedAdd(dest, value) \
+               ILInterlockedAdd_Release((dest), (value))
+#define IL_HAVE_INTERLOCKED_ADD 1
+#elif defined(IL_HAVE_INTERLOCKED_ADD_FULL)
+#define ILInterlockedAdd(dest, value) \
+               ILInterlockedAdd_Full((dest), (value))
+#define IL_HAVE_INTERLOCKED_ADD 1
+#endif /* defined(IL_HAVE_INTERLOCKED_ADD_FULL) */
+#endif /* !defined(IL_HAVE_INTERLOCKED_ADD) */
+#if !defined(IL_HAVE_INTERLOCKED_ADD) && \
+       defined(IL_HAVE_INTERLOCKED_COMPAREANDEXCHANGE)
+static IL_INLINE ILInt32 ILInterlockedAdd(volatile ILInt32 *dest,
+                                                                               
  ILInt32 value)
+{
+       ILInt32 oldval;
+       ILInt32 retval;
+
+       do
+       {
+               oldval = ILInterlockedLoad(dest);
+               retval = oldval + value;
+       } while(ILInterlockedCompareAndExchange(dest, retval, oldval) != 
oldVal);
+
+       return retval;  
+}
+#define IL_HAVE_INTERLOCKED_ADD 1
+#endif /* !defined(IL_HAVE_INTERLOCKED_ADD) */
+#if !defined(IL_HAVE_INTERLOCKED_ADD_ACQUIRE) && \
+       defined(IL_HAVE_INTERLOCKED_COMPAREANDEXCHANGE_ACQUIRE)
+static IL_INLINE ILInt32 ILInterlockedAdd_Acquire(volatile ILInt32 *dest,
+                                                                               
                  ILInt32 value)
+{
+       ILInt32 oldval;
+       ILInt32 retval;
+
+       do
+       {
+               oldval = ILInterlockedLoad(dest);
+               retval = oldval + value;
+       } while(ILInterlockedCompareAndExchange_Acquire(dest, retval, oldval) 
!= oldval);
+
+       return retval;  
+}
+#define IL_HAVE_INTERLOCKED_ADD_ACQUIRE 1
+#endif /* !defined(IL_HAVE_INTERLOCKED_ADD_ACQUIRE) */
+#if !defined(IL_HAVE_INTERLOCKED_ADD_RELEASE) && \
+       defined(IL_HAVE_INTERLOCKED_COMPAREANDEXCHANGE_RELEASE)
+static IL_INLINE ILInt32 ILInterlockedAdd_Release(volatile ILInt32 *dest,
+                                                                               
                  ILInt32 value)
+{
+       ILInt32 oldval;
+       ILInt32 retval;
+
+       do
+       {
+               oldval = ILInterlockedLoad(dest);
+               retval = oldval + value;
+       } while(ILInterlockedCompareAndExchange_Release(dest, retval, oldval) 
!= oldval);
+
+       return retval;  
+}
+#define IL_HAVE_INTERLOCKED_ADD_RELEASE 1
+#endif /* !defined(IL_HAVE_INTERLOCKED_ADD_RELEASE) */
+#if !defined(IL_HAVE_INTERLOCKED_ADD_FULL) && \
+       defined(IL_HAVE_INTERLOCKED_COMPAREANDEXCHANGE_FULL)
+static IL_INLINE ILInt32 ILInterlockedAdd_Full(volatile ILInt32 *dest,
+                                                                               
           ILInt32 value)
+{
+       ILInt32 oldval;
+       ILInt32 retval;
+
+       do
+       {
+               oldval = ILInterlockedLoad(dest);
+               retval = oldval + value;
+       } while(ILInterlockedCompareAndExchange_Full(dest, retval, oldval) != 
oldval);
+
+       return retval;  
+}
+#define IL_HAVE_INTERLOCKED_ADD_RELEASE 1
+#endif /* !defined(IL_HAVE_INTERLOCKED_ADD_RELEASE) */
 #if !defined(IL_HAVE_INTERLOCKED_ADD)
 #define ILInterlockedAdd(dest, value)  _ILInterlockedAdd((dest), (value))
 #endif /* !defined(IL_HAVE_INTERLOCKED_ADD) */
+#if !defined(IL_HAVE_INTERLOCKED_ADD_ACQUIRE)
+#define ILInterlockedAdd_Acquire(dest, value)  _ILInterlockedAdd((dest), 
(value))
+#endif /* !defined(IL_HAVE_INTERLOCKED_ADD_ACQUIRE) */
+#if !defined(IL_HAVE_INTERLOCKED_ADD_RELEASE)
+#define ILInterlockedAdd_Release(dest, value)  _ILInterlockedAdd((dest), 
(value))
+#endif /* !defined(IL_HAVE_INTERLOCKED_ADD_RELEASE) */
+#if !defined(IL_HAVE_INTERLOCKED_ADD_FULL)
+#define ILInterlockedAdd_Full(dest, value)     _ILInterlockedAdd((dest), 
(value))
+#endif /* !defined(IL_HAVE_INTERLOCKED_ADD_FULL) */
 
 /*
  * Subtract value from *dest and store the result at *dest.
  */
 #define _ILInterlockedSub(dest, value) _ILInterlockedAdd((dest), -(value))
-#if !defined(IL_HAVE_INTERLOCKED_SUB)
-#if defined(IL_HAVE_INTERLOCKED_ADD)
+#if defined(IL_HAVE_INTERLOCKED_SUB_FULL)
+#if !defined(IL_HAVE_INTERLOCKED_SUB_ACQUIRE)
+#define ILInterlockedSub_Acquire(dest, value) \
+               ILInterlockedSub_Full((dest), (value))
+#define IL_HAVE_INTERLOCKED_SUB_ACQUIRE 1
+#endif /* !defined(IL_HAVE_INTERLOCKED_ADD_ACQUIRE) */
+#if !defined(IL_HAVE_INTERLOCKED_SUB_RELEASE)
+#define ILInterlockedSub_Release(dest, value) \
+               ILInterlockedSub_Full((dest), (value))
+#define IL_HAVE_INTERLOCKED_SUB_RELEASE 1
+#endif /* !defined(IL_HAVE_INTERLOCKED_SUB_RELEASE) */
+#endif /* defined(IL_HAVE_INTERLOCKED_SUB_FULL) */
+#if !defined(IL_HAVE_INTERLOCKED_SUB) && \
+       defined(IL_HAVE_INTERLOCKED_ADD)
 #define ILInterlockedSub(dest, value)  ILInterlockedAdd((dest), -(value))
 #define IL_HAVE_INTERLOCKED_SUB 1
-#else
-#define ILInterlockedSub(dest, value)  _ILInterlockedSub((dest), (value))
 #endif
+#if !defined(IL_HAVE_INTERLOCKED_SUB_ACQUIRE) && \
+       defined(IL_HAVE_INTERLOCKED_ADD_ACQUIRE)
+#define ILInterlockedSub_Acquire(dest, value) \
+               ILInterlockedAdd_Acquire((dest), -(value))
+#define IL_HAVE_INTERLOCKED_SUB_ACQUIRE 1
+#endif
+#if !defined(IL_HAVE_INTERLOCKED_SUB_RELEASE) && \
+       defined(IL_HAVE_INTERLOCKED_ADD_RELEASE)
+#define ILInterlockedSub_Release(dest, value) \
+               ILInterlockedAdd_Release((dest), -(value))
+#define IL_HAVE_INTERLOCKED_SUB_RELEASE 1
+#endif
+#if !defined(IL_HAVE_INTERLOCKED_SUB_FULL) && \
+       defined(IL_HAVE_INTERLOCKED_ADD_FULL)
+#define ILInterlockedSub_Full(dest, value) \
+               ILInterlockedAdd_Full((dest), -(value))
+#define IL_HAVE_INTERLOCKED_SUB_FULL 1
+#endif
+#if !defined(IL_HAVE_INTERLOCKED_SUB)
+#define ILInterlockedSub(dest, value)  _ILInterlockedSub((dest), (value))
 #endif /* !defined(IL_HAVE_INTERLOCKED_SUB) */
+#if !defined(IL_HAVE_INTERLOCKED_SUB_ACQUIRE)
+#define ILInterlockedSub_Acquire(dest, value) \
+               _ILInterlockedSub((dest), (value))
+#endif /* !defined(IL_HAVE_INTERLOCKED_SUB_ACQUIRE) */
+#if !defined(IL_HAVE_INTERLOCKED_SUB_RELEASE)
+#define ILInterlockedSub_Release(dest, value) \
+               _ILInterlockedSub((dest), (value))
+#endif /* !defined(IL_HAVE_INTERLOCKED_SUB_RELEASE) */
+#if !defined(IL_HAVE_INTERLOCKED_SUB_FULL)
+#define ILInterlockedSub_Full(dest, value)     _ILInterlockedSub((dest), 
(value))
+#endif /* !defined(IL_HAVE_INTERLOCKED_SUB_FULL) */
 
 /*
  * Increment a 32bit integer.
  */
 #define _ILInterlockedIncrement(dest)  _ILInterlockedAdd((dest), 1)
-#if !defined(IL_HAVE_INTERLOCKED_INCREMENT)
-#if defined(IL_HAVE_INTERLOCKED_ADD)
+#if defined(IL_HAVE_INTERLOCKED_INCREMENT_FULL)
+#if !defined(IL_HAVE_INTERLOCKED_INCREMENT_ACQUIRE)
+#define ILInterlockedIncrement_Acquire(dest) \
+               ILInterlockedIncrement_Full((dest))
+#define IL_HAVE_INTERLOCKED_INCREMENT_ACQUIRE 1
+#endif /* !defined(IL_HAVE_INTERLOCKED_INCREMENT_ACQUIRE) */
+#if !defined(IL_HAVE_INTERLOCKED_INCREMENT_RELEASE)
+#define ILInterlockedIncrement_Release(dest) \
+               ILInterlockedIncrement_Full((dest))
+#define IL_HAVE_INTERLOCKED_INCREMENT_RELEASE 1
+#endif /* !defined(IL_HAVE_INTERLOCKED_INCREMENT_RELEASE) */
+#endif /* defined(IL_HAVE_INTERLOCKED_INCREMENT_FULL) */
+#if !defined(IL_HAVE_INTERLOCKED_INCREMENT) && \
+       defined(IL_HAVE_INTERLOCKED_ADD)
 #define ILInterlockedIncrement(dest)   ILInterlockedAdd((dest), 1)
 #define IL_HAVE_INTERLOCKED_INCREMENT 1
-#else
-#define ILInterlockedIncrement(dest)   _ILInterlockedIncrement((dest))
 #endif
+#if !defined(IL_HAVE_INTERLOCKED_INCREMENT_ACQUIRE) && \
+       defined(IL_HAVE_INTERLOCKED_ADD_ACQUIRE)
+#define ILInterlockedIncrement_Acquire(dest) \
+               ILInterlockedAdd_Acquire((dest), 1)
+#define IL_HAVE_INTERLOCKED_INCREMENT_ACQUIRE 1
+#endif
+#if !defined(IL_HAVE_INTERLOCKED_INCREMENT_RELEASE) && \
+       defined(IL_HAVE_INTERLOCKED_ADD_RELEASE)
+#define ILInterlockedIncrement_Release(dest) \
+               ILInterlockedAdd_Release((dest), 1)
+#define IL_HAVE_INTERLOCKED_INCREMENT_RELEASE 1
+#endif
+#if !defined(IL_HAVE_INTERLOCKED_INCREMENT_FULL) && \
+       defined(IL_HAVE_INTERLOCKED_ADD_FULL)
+#define ILInterlockedIncrement_Full(dest) \
+               ILInterlockedAdd_Full((dest), 1)
+#define IL_HAVE_INTERLOCKED_INCREMENT_FULL 1
+#endif
+#if !defined(IL_HAVE_INTERLOCKED_INCREMENT)
+#define ILInterlockedIncrement(dest)   _ILInterlockedIncrement((dest))
 #endif /* !defined(IL_HAVE_INTERLOCKED_INCREMENT) */
+#if !defined(IL_HAVE_INTERLOCKED_INCREMENT_ACQUIRE)
+#define ILInterlockedIncrement_Acquire(dest)   _ILInterlockedIncrement((dest))
+#endif /* !defined(IL_HAVE_INTERLOCKED_INCREMENT_ACQUIRE) */
+#if !defined(IL_HAVE_INTERLOCKED_INCREMENT_RELEASE)
+#define ILInterlockedIncrement_Release(dest)   _ILInterlockedIncrement((dest))
+#endif /* !defined(IL_HAVE_INTERLOCKED_INCREMENT_RELEASE) */
+#if !defined(IL_HAVE_INTERLOCKED_INCREMENT_FULL)
+#define ILInterlockedIncrement_Full(dest)      _ILInterlockedIncrement((dest))
+#endif /* !defined(IL_HAVE_INTERLOCKED_INCREMENT_FULL) */
 
 /*
  * Decrement a 32bit integer.
  */
 #define _ILInterlockedDecrement(dest)  _ILInterlockedSub((dest), 1)
-#if !defined(IL_HAVE_INTERLOCKED_DECREMENT)
-#if defined(IL_HAVE_INTERLOCKED_SUB)
+#if defined(IL_HAVE_INTERLOCKED_DECREMENT_FULL)
+#if !defined(IL_HAVE_INTERLOCKED_DECREMENT_ACQUIRE)
+#define ILInterlockedDecrement_Acquire(dest) \
+               ILInterlockedDecrement_Full((dest))
+#define IL_HAVE_INTERLOCKED_DECREMENT_ACQUIRE 1
+#endif /* !defined(IL_HAVE_INTERLOCKED_DECREMENT_ACQUIRE) */
+#if !defined(IL_HAVE_INTERLOCKED_DECREMENT_RELEASE)
+#define ILInterlockedDecrement_Release(dest) \
+               ILInterlockedDecrement_Full((dest))
+#define IL_HAVE_INTERLOCKED_DECREMENT_RELEASE 1
+#endif /* !defined(IL_HAVE_INTERLOCKED_DECREMENT_RELEASE) */
+#endif /* defined(IL_HAVE_INTERLOCKED_DECREMENT_FULL) */
+#if !defined(IL_HAVE_INTERLOCKED_DECREMENT) && \
+       defined(IL_HAVE_INTERLOCKED_SUB)
 #define ILInterlockedDecrement(dest)   ILInterlockedSub((dest), 1)
 #define IL_HAVE_INTERLOCKED_DECREMENT 1
-#else
-#define ILInterlockedDecrement(dest)   _ILInterlockedDecrement((dest))
 #endif
+#if !defined(IL_HAVE_INTERLOCKED_DECREMENT_ACQUIRE) && \
+       defined(IL_HAVE_INTERLOCKED_SUB_ACQUIRE)
+#define ILInterlockedDecrement_Acquire(dest) \
+               ILInterlockedSub_Acquire((dest), 1)
+#define IL_HAVE_INTERLOCKED_DECREMENT_ACQUIRE 1
+#endif
+#if !defined(IL_HAVE_INTERLOCKED_DECREMENT_RELEASE) && \
+       defined(IL_HAVE_INTERLOCKED_SUB_RELEASE)
+#define ILInterlockedDecrement_Release(dest) \
+               ILInterlockedSub_Release((dest), 1)
+#define IL_HAVE_INTERLOCKED_DECREMENT_RELEASE 1
+#endif
+#if !defined(IL_HAVE_INTERLOCKED_DECREMENT_FULL) && \
+       defined(IL_HAVE_INTERLOCKED_SUB_FULL)
+#define ILInterlockedDecrement_Full(dest) \
+               ILInterlockedSub_Full((dest), 1)
+#define IL_HAVE_INTERLOCKED_DECREMENT_FULL 1
+#endif
+#if !defined(IL_HAVE_INTERLOCKED_DECREMENT)
+#define ILInterlockedDecrement(dest)   _ILInterlockedDecrement((dest))
 #endif /* !defined(IL_HAVE_INTERLOCKED_DECREMENT) */
+#if !defined(IL_HAVE_INTERLOCKED_DECREMENT_ACQUIRE)
+#define ILInterlockedDecrement_Acquire(dest)   _ILInterlockedDecrement((dest))
+#endif /* !defined(IL_HAVE_INTERLOCKED_DECREMENT_ACQUIRE) */
+#if !defined(IL_HAVE_INTERLOCKED_DECREMENT_RELEASE)
+#define ILInterlockedDecrement_Release(dest)   _ILInterlockedDecrement((dest))
+#endif /* !defined(IL_HAVE_INTERLOCKED_DECREMENT_RELEASE) */
+#if !defined(IL_HAVE_INTERLOCKED_DECREMENT_FULL)
+#define ILInterlockedDecrement_Full(dest)      _ILInterlockedDecrement((dest))
+#endif /* !defined(IL_HAVE_INTERLOCKED_DECREMENT_FULL) */
 
 /*
  * Atomic bitwise AND of unsigned 32 bit values
@@ -201,9 +701,109 @@ static IL_INLINE void _ILInterlockedAnd(volatile ILUInt32 
*dest,
 
        ILThreadAtomicEnd();
 }
+#if defined(IL_HAVE_INTERLOCKED_AND_FULL)
+#if !defined(IL_HAVE_INTERLOCKED_AND_ACQUIRE)
+#define ILInterlockedAnd_Acquire(dest, value) \
+               ILInterlockedAnd_Full((dest), (value))
+#define IL_HAVE_INTERLOCKED_AND_ACQUIRE 1
+#endif /* !defined(IL_HAVE_INTERLOCKED_AND_ACQUIRE) */
+#if !defined(IL_HAVE_INTERLOCKED_AND_RELEASE)
+#define ILInterlockedAnd_Release(dest, value) \
+               ILInterlockedAnd_Full((dest), (value))
+#define IL_HAVE_INTERLOCKED_AND_RELEASE 1
+#endif /* !defined(IL_HAVE_INTERLOCKED_AND_RELEASE) */
+#endif /* defined(IL_HAVE_INTERLOCKED_AND_FULL) */
+#if !defined(IL_HAVE_INTERLOCKED_AND)
+#if defined(IL_HAVE_INTERLOCKED_AND_ACQUIRE)
+#define ILInterlockedAnd(dest, value) \
+               ILInterlockedAnd_Acquire((dest), (value))
+#define IL_HAVE_INTERLOCKED_AND 1
+#elif defined(IL_HAVE_INTERLOCKED_AND_RELEASE)
+#define ILInterlockedAnd(dest, value) \
+               ILInterlockedAnd_Release((dest), (value))
+#define IL_HAVE_INTERLOCKED_AND 1
+#elif defined(IL_HAVE_INTERLOCKED_AND_FULL)
+#define ILInterlockedAnd(dest, value) \
+               ILInterlockedAnd_Full((dest), (value))
+#define IL_HAVE_INTERLOCKED_AND 1
+#endif /* defined(IL_HAVE_INTERLOCKED_AND_FULL) */
+#endif /* !defined(IL_HAVE_INTERLOCKED_AND) */
+#if !defined(IL_HAVE_INTERLOCKED_AND) && \
+       defined(IL_HAVE_INTERLOCKED_COMPAREANDEXCHANGE)
+static IL_INLINE void ILInterlockedAnd(volatile ILInt32 *dest,
+                                                                          
ILInt32 value)
+{
+       ILInt32 oldval;
+       ILInt32 retval;
+
+       do
+       {
+               oldval = ILInterlockedLoad(dest);
+               retval = oldval & value;
+       } while(ILInterlockedCompareAndExchange(dest, retval, oldval) != 
oldVal);
+}
+#define IL_HAVE_INTERLOCKED_AND 1
+#endif /* !defined(IL_HAVE_INTERLOCKED_AND) */
+#if !defined(IL_HAVE_INTERLOCKED_AND_ACQUIRE) && \
+       defined(IL_HAVE_INTERLOCKED_COMPAREANDEXCHANGE_ACQUIRE)
+static IL_INLINE void ILInterlockedAnd_Acquire(volatile ILInt32 *dest,
+                                                                               
           ILInt32 value)
+{
+       ILInt32 oldval;
+       ILInt32 retval;
+
+       do
+       {
+               oldval = ILInterlockedLoad(dest);
+               retval = oldval & value;
+       } while(ILInterlockedCompareAndExchange_Acquire(dest, retval, oldval) 
!= oldval);
+}
+#define IL_HAVE_INTERLOCKED_AND_ACQUIRE 1
+#endif /* !defined(IL_HAVE_INTERLOCKED_AND_ACQUIRE) */
+#if !defined(IL_HAVE_INTERLOCKED_AND_RELEASE) && \
+       defined(IL_HAVE_INTERLOCKED_COMPAREANDEXCHANGE_RELEASE)
+static IL_INLINE void ILInterlockedAnd_Release(volatile ILInt32 *dest,
+                                                                               
           ILInt32 value)
+{
+       ILInt32 oldval;
+       ILInt32 retval;
+
+       do
+       {
+               oldval = ILInterlockedLoad(dest);
+               retval = oldval & value;
+       } while(ILInterlockedCompareAndExchange_Release(dest, retval, oldval) 
!= oldval);
+}
+#define IL_HAVE_INTERLOCKED_AND_RELEASE 1
+#endif /* !defined(IL_HAVE_INTERLOCKED_AND_RELEASE) */
+#if !defined(IL_HAVE_INTERLOCKED_AND_FULL) && \
+       defined(IL_HAVE_INTERLOCKED_COMPAREANDEXCHANGE_FULL)
+static IL_INLINE void ILInterlockedAnd_Full(volatile ILInt32 *dest,
+                                                                               
        ILInt32 value)
+{
+       ILInt32 oldval;
+       ILInt32 retval;
+
+       do
+       {
+               oldval = ILInterlockedLoad(dest);
+               retval = oldval & value;
+       } while(ILInterlockedCompareAndExchange_Full(dest, retval, oldval) != 
oldval);
+}
+#define IL_HAVE_INTERLOCKED_AND_RELEASE 1
+#endif /* !defined(IL_HAVE_INTERLOCKED_AND_RELEASE) */
 #if !defined(IL_HAVE_INTERLOCKED_AND)
 #define ILInterlockedAnd(dest, value)  _ILInterlockedAnd((dest), (value))
 #endif /* !defined(IL_HAVE_INTERLOCKED_AND) */
+#if !defined(IL_HAVE_INTERLOCKED_AND_ACQUIRE)
+#define ILInterlockedAnd_Acquire(dest, value)  _ILInterlockedAnd((dest), 
(value))
+#endif /* !defined(IL_HAVE_INTERLOCKED_AND_ACQUIRE) */
+#if !defined(IL_HAVE_INTERLOCKED_AND_RELEASE)
+#define ILInterlockedAnd_Release(dest, value)  _ILInterlockedAnd((dest), 
(value))
+#endif /* !defined(IL_HAVE_INTERLOCKED_AND_RELEASE) */
+#if !defined(IL_HAVE_INTERLOCKED_AND_FULL)
+#define ILInterlockedAnd_Full(dest, value)     _ILInterlockedAnd((dest), 
(value))
+#endif /* !defined(IL_HAVE_INTERLOCKED_AND_FULL) */
 
 /*
  * Atomic bitwise OR of unsigned 32 bit values
@@ -217,6 +817,106 @@ static IL_INLINE void _ILInterlockedOr(volatile ILUInt32 
*dest,
 
        ILThreadAtomicEnd();
 }
+#if defined(IL_HAVE_INTERLOCKED_OR_FULL)
+#if !defined(IL_HAVE_INTERLOCKED_OR_ACQUIRE)
+#define ILInterlockedOr_Acquire(dest, value) \
+               ILInterlockedOr_Full((dest), (value))
+#define IL_HAVE_INTERLOCKED_OR_ACQUIRE 1
+#endif /* !defined(IL_HAVE_INTERLOCKED_OR_ACQUIRE) */
+#if !defined(IL_HAVE_INTERLOCKED_OR_RELEASE)
+#define ILInterlockedOr_Release(dest, value) \
+               ILInterlockedOr_Full((dest), (value))
+#define IL_HAVE_INTERLOCKED_OR_RELEASE 1
+#endif /* !defined(IL_HAVE_INTERLOCKED_OR_RELEASE) */
+#endif /* defined(IL_HAVE_INTERLOCKED_OR_FULL) */
+#if !defined(IL_HAVE_INTERLOCKED_OR)
+#if defined(IL_HAVE_INTERLOCKED_OR_ACQUIRE)
+#define ILInterlockedOr(dest, value) \
+               ILInterlockedOr_Acquire((dest), (value))
+#define IL_HAVE_INTERLOCKED_OR 1
+#elif defined(IL_HAVE_INTERLOCKED_OR_RELEASE)
+#define ILInterlockedOr(dest, value) \
+               ILInterlockedOr_Release((dest), (value))
+#define IL_HAVE_INTERLOCKED_OR 1
+#elif defined(IL_HAVE_INTERLOCKED_OR_FULL)
+#define ILInterlockedOr(dest, value) \
+               ILInterlockedOr_Full((dest), (value))
+#define IL_HAVE_INTERLOCKED_OR 1
+#endif /* defined(IL_HAVE_INTERLOCKED_OR_FULL) */
+#endif /* !defined(IL_HAVE_INTERLOCKED_OR) */
+#if !defined(IL_HAVE_INTERLOCKED_OR) && \
+       defined(IL_HAVE_INTERLOCKED_COMPAREANDEXCHANGE)
+static IL_INLINE void ILInterlockedOr(volatile ILInt32 *dest,
+                                                                         
ILInt32 value)
+{
+       ILInt32 oldval;
+       ILInt32 retval;
+
+       do
+       {
+               oldval = ILInterlockedLoad(dest);
+               retval = oldval | value;
+       } while(ILInterlockedCompareAndExchange(dest, retval, oldval) != 
oldVal);
+}
+#define IL_HAVE_INTERLOCKED_OR 1
+#endif /* !defined(IL_HAVE_INTERLOCKED_OR) */
+#if !defined(IL_HAVE_INTERLOCKED_OR_ACQUIRE) && \
+       defined(IL_HAVE_INTERLOCKED_COMPAREANDEXCHANGE_ACQUIRE)
+static IL_INLINE void ILInterlockedOr_Acquire(volatile ILInt32 *dest,
+                                                                               
          ILInt32 value)
+{
+       ILInt32 oldval;
+       ILInt32 retval;
+
+       do
+       {
+               oldval = ILInterlockedLoad(dest);
+               retval = oldval | value;
+       } while(ILInterlockedCompareAndExchange_Acquire(dest, retval, oldval) 
!= oldval);
+}
+#define IL_HAVE_INTERLOCKED_OR_ACQUIRE 1
+#endif /* !defined(IL_HAVE_INTERLOCKED_OR_ACQUIRE) */
+#if !defined(IL_HAVE_INTERLOCKED_OR_RELEASE) && \
+       defined(IL_HAVE_INTERLOCKED_COMPAREANDEXCHANGE_RELEASE)
+static IL_INLINE void ILInterlockedOr_Release(volatile ILInt32 *dest,
+                                                                               
          ILInt32 value)
+{
+       ILInt32 oldval;
+       ILInt32 retval;
+
+       do
+       {
+               oldval = ILInterlockedLoad(dest);
+               retval = oldval | value;
+       } while(ILInterlockedCompareAndExchange_Release(dest, retval, oldval) 
!= oldval);
+}
+#define IL_HAVE_INTERLOCKED_OR_RELEASE 1
+#endif /* !defined(IL_HAVE_INTERLOCKED_OR_RELEASE) */
+#if !defined(IL_HAVE_INTERLOCKED_OR_FULL) && \
+       defined(IL_HAVE_INTERLOCKED_COMPAREANDEXCHANGE_FULL)
+static IL_INLINE void ILInterlockedOr_Full(volatile ILInt32 *dest,
+                                                                               
   ILInt32 value)
+{
+       ILInt32 oldval;
+       ILInt32 retval;
+
+       do
+       {
+               oldval = ILInterlockedLoad(dest);
+               retval = oldval | value;
+       } while(ILInterlockedCompareAndExchange_Full(dest, retval, oldval) != 
oldval);
+}
+#define IL_HAVE_INTERLOCKED_OR_RELEASE 1
+#endif /* !defined(IL_HAVE_INTERLOCKED_OR_RELEASE) */
 #if !defined(IL_HAVE_INTERLOCKED_OR)
 #define ILInterlockedOr(dest, value)   _ILInterlockedOr((dest), (value))
 #endif /* !defined(IL_HAVE_INTERLOCKED_OR) */
+#if !defined(IL_HAVE_INTERLOCKED_OR_ACQUIRE)
+#define ILInterlockedOr_Acquire(dest, value)   _ILInterlockedOr((dest), 
(value))
+#endif /* !defined(IL_HAVE_INTERLOCKED_OR_ACQUIRE) */
+#if !defined(IL_HAVE_INTERLOCKED_OR_RELEASE)
+#define ILInterlockedOr_Release(dest, value)   _ILInterlockedOr((dest), 
(value))
+#endif /* !defined(IL_HAVE_INTERLOCKED_OR_RELEASE) */
+#if !defined(IL_HAVE_INTERLOCKED_OR_FULL)
+#define ILInterlockedOr_Full(dest, value)      _ILInterlockedOr((dest), 
(value))
+#endif /* !defined(IL_HAVE_INTERLOCKED_OR_FULL) */
diff --git a/support/interlocked_arm.h b/support/interlocked_arm.h
index c669c85..7a7f0b6 100644
--- a/support/interlocked_arm.h
+++ b/support/interlocked_arm.h
@@ -23,6 +23,160 @@
 
 #if defined(__GNUC__)
 
+/*
+ * Define _IL_INTERLOCKED_ARM_MP to enable multiprocessor by default
+ */
+#define _IL_INTERLOCKED_ARM_MP 1
+
+#if defined(__ARM_ARCH_6M__) || defined(__ARM_ARCH_7M__) || \
+       defined(_IL_INTERLOCKED_ARM_MP)
+/*
+ * These are the multi core variants which will need an explicit memory barrier
+ */
+#define _IL_INTERLOCKED_ARM_MEMORYBARRIER      "\tmcr p15, 0, r0, c7, c10, 5\n"
+#else /* !defined(__ARM_ARCH_6M__) && !defined(__ARM_ARCH_7M__) */
+#define _IL_INTERLOCKED_ARM_MEMORYBARRIER      ""
+#endif /* !defined(__ARM_ARCH_6M__) && !defined(__ARM_ARCH_7M__) */
+
+/*
+ * Flush cache and set a memory barrier.
+ */
+static IL_INLINE void ILInterlockedMemoryBarrier()
+{
+       __asm__ __volatile__
+       (
+               _IL_INTERLOCKED_ARM_MEMORYBARRIER
+               :
+               :
+               : "memory"
+       );
+}
+#define IL_HAVE_INTERLOCKED_MEMORYBARRIER 1
+
+/*
+ * Load a 32 bit value from a location.
+ */
+static IL_INLINE ILInt32 ILInterlockedLoad(const volatile ILInt32 *dest)
+{
+       ILInt32 retval;
+
+       __asm__ __volatile__
+       (
+               "\tldr  %0, %1\n"
+               : "=r" (retval)
+               : "m" (*dest)
+       );
+       return retval;
+}
+#define IL_HAVE_INTERLOCKED_LOAD 1
+
+static IL_INLINE ILInt32 ILInterlockedLoad_Acquire(const volatile ILInt32 
*dest)
+{
+       ILInt32 retval;
+
+       __asm__ __volatile__
+       (
+               "\tldr  %0, %1\n"
+               _IL_INTERLOCKED_ARM_MEMORYBARRIER
+               : "=r" (retval)
+               : "m" (*dest)
+               : "memory"
+       );
+       return retval;
+}
+#define IL_HAVE_INTERLOCKED_LOAD_ACQUIRE 1
+
+/*
+ * Load a pointer value from a location.
+ */
+static IL_INLINE void *ILInterlockedLoadPointer(void * const volatile *dest)
+{
+       void *retval;
+
+       __asm__ __volatile__
+       (
+               "\tldr  %0, %1\n"
+               : "=r" (retval)
+               : "m" (*dest)
+       );
+       return retval;
+}
+#define IL_HAVE_INTERLOCKED_LOADPOINTER 1
+
+static IL_INLINE void *ILInterlockedLoadPointer_Acquire(void * const volatile 
*dest)
+{
+       void *retval;
+
+       __asm__ __volatile__
+       (
+               "\tldr  %0, %1\n"
+               _IL_INTERLOCKED_ARM_MEMORYBARRIER
+               : "=r" (retval)
+               : "m" (*dest)
+               : "memory"
+       );
+       return retval;
+}
+#define IL_HAVE_INTERLOCKED_LOADPOINTER_ACQUIRE 1
+
+/*
+ * Store a 32 bit value to a location.
+ */
+static IL_INLINE void ILInterlockedStore(volatile ILInt32 *dest,
+                                                                               
 ILInt32 value)
+{
+       __asm__ __volatile__
+       (
+               "\tstr  %1, %0\n"
+               : "=m" (*dest)
+               : "r" (value)
+       );
+}
+#define IL_HAVE_INTERLOCKED_STORE 1
+
+static IL_INLINE void ILInterlockedStore_Release(volatile ILInt32 *dest,
+                                                                               
                 ILInt32 value)
+{
+       __asm__ __volatile__
+       (
+               _IL_INTERLOCKED_ARM_MEMORYBARRIER
+               "\tstr  %1, %0\n"
+               : "=m" (*dest)
+               : "r" (value)
+               : "memory"
+       );
+}
+#define IL_HAVE_INTERLOCKED_STORE_RELEASE 1
+
+/*
+ * Store a pointer value to a location.
+ */
+static IL_INLINE void ILInterlockedStorePointer(void * volatile *dest,
+                                                                               
                void *value)
+{
+       __asm__ __volatile__
+       (
+               "\tstr  %1, %0\n"
+               : "=m" (*dest)
+               : "r" (value)
+       );
+}
+#define IL_HAVE_INTERLOCKED_STOREPOINTER 1
+
+static IL_INLINE void ILInterlockedStorePointer_Release(void * volatile *dest,
+                                                                               
                                void *value)
+{
+       __asm__ __volatile__
+       (
+               _IL_INTERLOCKED_ARM_MEMORYBARRIER
+               "\tstr  %1, %0\n"
+               : "=m" (*dest)
+               : "r" (value)
+               : "memory"
+       );
+}
+#define IL_HAVE_INTERLOCKED_STOREPOINTER_RELEASE 1
+
 #if defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || \
        defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6ZK__) || \
        defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || \
@@ -30,7 +184,7 @@
 
 /*
  * The versions for the interlocked operations available for all arm cores
- * version 6 and later.
+ * version 6 and later (except Armv6_M).
  */
 
 /*
@@ -57,6 +211,73 @@ static IL_INLINE ILInt32 ILInterlockedExchange(volatile 
ILInt32 *dest,
 }
 #define IL_HAVE_INTERLOCKED_EXCHANGE 1
 
+static IL_INLINE ILInt32 ILInterlockedExchange_Acquire(volatile ILInt32 *dest,
+                                                                               
                           ILInt32 value)
+{
+       ILInt32 retval;
+       ILInt32 state;
+
+       __asm__ __volatile__
+       (
+               "1:"
+               "ldrex  %0, [%3];"
+               "strex  %1, %4, [%3];"
+               "teq            %1, #0;"
+               "bne            1b;"
+               _IL_INTERLOCKED_ARM_MEMORYBARRIER
+               : "=&r" (retval), "=&r" (state), "+m" (*dest)
+               : "r" (dest), "r" (value)
+               : "memory", "cc"
+       );
+       return retval;
+}
+#define IL_HAVE_INTERLOCKED_EXCHANGE_ACQUIRE 1
+
+static IL_INLINE ILInt32 ILInterlockedExchange_Release(volatile ILInt32 *dest,
+                                                                               
                           ILInt32 value)
+{
+       ILInt32 retval;
+       ILInt32 state;
+
+       __asm__ __volatile__
+       (
+               _IL_INTERLOCKED_ARM_MEMORYBARRIER
+               "1:"
+               "ldrex  %0, [%3];"
+               "strex  %1, %4, [%3];"
+               "teq            %1, #0;"
+               "bne            1b;"
+               : "=&r" (retval), "=&r" (state), "+m" (*dest)
+               : "r" (dest), "r" (value)
+               : "memory", "cc"
+       );
+       return retval;
+}
+#define IL_HAVE_INTERLOCKED_EXCHANGE_RELEASE 1
+
+static IL_INLINE ILInt32 ILInterlockedExchange_Full(volatile ILInt32 *dest,
+                                                                               
                        ILInt32 value)
+{
+       ILInt32 retval;
+       ILInt32 state;
+
+       __asm__ __volatile__
+       (
+               _IL_INTERLOCKED_ARM_MEMORYBARRIER
+               "1:"
+               "ldrex  %0, [%3];"
+               "strex  %1, %4, [%3];"
+               "teq            %1, #0;"
+               "bne            1b;"
+               _IL_INTERLOCKED_ARM_MEMORYBARRIER
+               : "=&r" (retval), "=&r" (state), "+m" (*dest)
+               : "r" (dest), "r" (value)
+               : "memory", "cc"
+       );
+       return retval;
+}
+#define IL_HAVE_INTERLOCKED_EXCHANGE_FULL 1
+
 /*
  * Exchange pointers.
  */
@@ -82,6 +303,76 @@ static IL_INLINE void *ILInterlockedExchangePointers(void * 
volatile *dest,
 }
 #define IL_HAVE_INTERLOCKED_EXCHANGEPOINTERS 1
 
+static IL_INLINE void *ILInterlockedExchangePointers_Acquire(void * volatile 
*dest,
+                                                                               
                                         void *value)
+{
+       void *retval;
+       ILInt32 state;
+
+       __asm__ __volatile__
+       (
+               "1:"
+               "ldrex  %0, [%3];"
+               "strex  %1, %4, [%3];"
+               "teq        %1, #0;"
+               "bne        1b;"
+               _IL_INTERLOCKED_ARM_MEMORYBARRIER
+               : "=&r" (retval), "=&r" (state), "+m" (*dest)
+               : "r" (dest), "r" (value)
+               : "memory", "cc"
+       );
+
+       return retval;
+}
+#define IL_HAVE_INTERLOCKED_EXCHANGEPOINTERS_ACQUIRE 1
+
+static IL_INLINE void *ILInterlockedExchangePointers_Release(void * volatile 
*dest,
+                                                                               
                                         void *value)
+{
+       void *retval;
+       ILInt32 state;
+
+       __asm__ __volatile__
+       (
+               _IL_INTERLOCKED_ARM_MEMORYBARRIER
+               "1:"
+               "ldrex  %0, [%3];"
+               "strex  %1, %4, [%3];"
+               "teq        %1, #0;"
+               "bne        1b;"
+               : "=&r" (retval), "=&r" (state), "+m" (*dest)
+               : "r" (dest), "r" (value)
+               : "memory", "cc"
+       );
+
+       return retval;
+}
+#define IL_HAVE_INTERLOCKED_EXCHANGEPOINTERS_RELEASE 1
+
+static IL_INLINE void *ILInterlockedExchangePointers_Full(void * volatile 
*dest,
+                                                                               
                                  void *value)
+{
+       void *retval;
+       ILInt32 state;
+
+       __asm__ __volatile__
+       (
+               _IL_INTERLOCKED_ARM_MEMORYBARRIER
+               "1:"
+               "ldrex  %0, [%3];"
+               "strex  %1, %4, [%3];"
+               "teq        %1, #0;"
+               "bne        1b;"
+               _IL_INTERLOCKED_ARM_MEMORYBARRIER
+               : "=&r" (retval), "=&r" (state), "+m" (*dest)
+               : "r" (dest), "r" (value)
+               : "memory", "cc"
+       );
+
+       return retval;
+}
+#define IL_HAVE_INTERLOCKED_EXCHANGEPOINTERS_FULL 1
+
 /*
  * Compare and exchange two 32bit integers.
  */
@@ -109,6 +400,82 @@ static IL_INLINE ILInt32 
ILInterlockedCompareAndExchange(volatile ILInt32 *dest,
 }
 #define IL_HAVE_INTERLOCKED_COMPAREANDEXCHANGE 1
 
+static IL_INLINE ILInt32 ILInterlockedCompareAndExchange_Acquire(volatile 
ILInt32 *dest,
+                                                                               
                                                 ILInt32 value,
+                                                                               
                                                 ILInt32 comparand)
+{
+       ILInt32 retval;
+       ILInt32 state;
+
+       __asm__ __volatile__
+       (
+               "1:"
+               "ldrex                  %0, [%3];"
+               "teq                    %0, %5;"
+               "strexeq        %1, %4, [%3];"
+               "teq                    %1, #0;"
+               "bne                    1b;"
+               _IL_INTERLOCKED_ARM_MEMORYBARRIER
+               : "=&r" (retval), "=&r" (state), "+m" (*dest)
+               : "r" (dest), "r" (value), "Jr" (comparand)
+               : "memory", "cc"
+       );
+
+       return retval;
+}
+#define IL_HAVE_INTERLOCKED_COMPAREANDEXCHANGE_ACQUIRE 1
+
+static IL_INLINE ILInt32 ILInterlockedCompareAndExchange_Release(volatile 
ILInt32 *dest,
+                                                                               
                                                 ILInt32 value,
+                                                                               
                                                 ILInt32 comparand)
+{
+       ILInt32 retval;
+       ILInt32 state;
+
+       __asm__ __volatile__
+       (
+               _IL_INTERLOCKED_ARM_MEMORYBARRIER
+               "1:"
+               "ldrex                  %0, [%3];"
+               "teq                    %0, %5;"
+               "strexeq        %1, %4, [%3];"
+               "teq                    %1, #0;"
+               "bne                    1b;"
+               : "=&r" (retval), "=&r" (state), "+m" (*dest)
+               : "r" (dest), "r" (value), "Jr" (comparand)
+               : "memory", "cc"
+       );
+
+       return retval;
+}
+#define IL_HAVE_INTERLOCKED_COMPAREANDEXCHANGE_RELEASE 1
+
+static IL_INLINE ILInt32 ILInterlockedCompareAndExchange_Full(volatile ILInt32 
*dest,
+                                                                               
                                          ILInt32 value,
+                                                                               
                                          ILInt32 comparand)
+{
+       ILInt32 retval;
+       ILInt32 state;
+
+       __asm__ __volatile__
+       (
+               _IL_INTERLOCKED_ARM_MEMORYBARRIER
+               "1:"
+               "ldrex                  %0, [%3];"
+               "teq                    %0, %5;"
+               "strexeq        %1, %4, [%3];"
+               "teq                    %1, #0;"
+               "bne                    1b;"
+               _IL_INTERLOCKED_ARM_MEMORYBARRIER
+               : "=&r" (retval), "=&r" (state), "+m" (*dest)
+               : "r" (dest), "r" (value), "Jr" (comparand)
+               : "memory", "cc"
+       );
+
+       return retval;
+}
+#define IL_HAVE_INTERLOCKED_COMPAREANDEXCHANGE_FULL 1
+
 /*
  * Compare and exchange two pointers.
  */
@@ -136,11 +503,87 @@ static IL_INLINE void 
*ILInterlockedCompareAndExchangePointers(void * volatile *
 }
 #define IL_HAVE_INTERLOCKED_COMPAREANDEXCHANGEPOINTERS 1
 
+static IL_INLINE void *ILInterlockedCompareAndExchangePointers_Acquire(void * 
volatile *dest,
+                                                                               
                                                           void *value,
+                                                                               
                                                           void *comparand)
+{
+       void *retval;
+       ILInt32 state;
+
+       __asm__ __volatile__
+       (
+               "1:"
+               "ldrex                  %0, [%3];"
+               "teq                    %0, %5;"
+               "strexeq        %1, %4, [%3];"
+               "teq                    %1, #0;"
+               "bne                    1b;"
+               _IL_INTERLOCKED_ARM_MEMORYBARRIER
+               : "=&r" (retval), "=&r" (state), "+m" (*dest)
+               : "r" (dest), "r" (value), "Jr" (comparand)
+               : "memory", "cc"
+       );
+
+       return retval;
+}
+#define IL_HAVE_INTERLOCKED_COMPAREANDEXCHANGEPOINTERS_ACQUIRE 1
+
+static IL_INLINE void *ILInterlockedCompareAndExchangePointers_Release(void * 
volatile *dest,
+                                                                               
                                                           void *value,
+                                                                               
                                                           void *comparand)
+{
+       void *retval;
+       ILInt32 state;
+
+       __asm__ __volatile__
+       (
+               _IL_INTERLOCKED_ARM_MEMORYBARRIER
+               "1:"
+               "ldrex                  %0, [%3];"
+               "teq                    %0, %5;"
+               "strexeq        %1, %4, [%3];"
+               "teq                    %1, #0;"
+               "bne                    1b;"
+               : "=&r" (retval), "=&r" (state), "+m" (*dest)
+               : "r" (dest), "r" (value), "Jr" (comparand)
+               : "memory", "cc"
+       );
+
+       return retval;
+}
+#define IL_HAVE_INTERLOCKED_COMPAREANDEXCHANGEPOINTERS_RELEASE 1
+
+static IL_INLINE void *ILInterlockedCompareAndExchangePointers_Full(void * 
volatile *dest,
+                                                                               
                                                        void *value,
+                                                                               
                                                        void *comparand)
+{
+       void *retval;
+       ILInt32 state;
+
+       __asm__ __volatile__
+       (
+               _IL_INTERLOCKED_ARM_MEMORYBARRIER
+               "1:"
+               "ldrex                  %0, [%3];"
+               "teq                    %0, %5;"
+               "strexeq        %1, %4, [%3];"
+               "teq                    %1, #0;"
+               "bne                    1b;"
+               _IL_INTERLOCKED_ARM_MEMORYBARRIER
+               : "=&r" (retval), "=&r" (state), "+m" (*dest)
+               : "r" (dest), "r" (value), "Jr" (comparand)
+               : "memory", "cc"
+       );
+
+       return retval;
+}
+#define IL_HAVE_INTERLOCKED_COMPAREANDEXCHANGEPOINTERS_FULL 1
+
 /*
  * Add two 32 bit integer values.
  */
 static IL_INLINE ILInt32 ILInterlockedAdd(volatile ILInt32 *dest,
-                                                                               
 ILInt32 value)
+                                                                               
  ILInt32 value)
 {
        ILInt32 retval;
        ILInt32 state;
@@ -162,11 +605,84 @@ static IL_INLINE ILInt32 ILInterlockedAdd(volatile 
ILInt32 *dest,
 }
 #define IL_HAVE_INTERLOCKED_ADD 1
 
+static IL_INLINE ILInt32 ILInterlockedAdd_Acquire(volatile ILInt32 *dest,
+                                                                               
                  ILInt32 value)
+{
+       ILInt32 retval;
+       ILInt32 state;
+
+       __asm__ __volatile__
+       (
+               "1:"
+               "ldrex          %0, [%3];"
+               "add            %0,     %0, %4;"
+               "strex  %1, %0, [%3];"
+               "teq            %1, #0;"
+               "bne            1b;"
+               _IL_INTERLOCKED_ARM_MEMORYBARRIER
+               : "=&r" (retval), "=&r" (state), "+m" (*dest)
+               : "r" (dest), "Jr" (value)
+               : "memory", "cc"
+       );
+
+       return retval;
+}
+#define IL_HAVE_INTERLOCKED_ADD_ACQUIRE 1
+
+static IL_INLINE ILInt32 ILInterlockedAdd_Release(volatile ILInt32 *dest,
+                                                                               
                  ILInt32 value)
+{
+       ILInt32 retval;
+       ILInt32 state;
+
+       __asm__ __volatile__
+       (
+               _IL_INTERLOCKED_ARM_MEMORYBARRIER
+               "1:"
+               "ldrex          %0, [%3];"
+               "add            %0,     %0, %4;"
+               "strex  %1, %0, [%3];"
+               "teq            %1, #0;"
+               "bne            1b;"
+               : "=&r" (retval), "=&r" (state), "+m" (*dest)
+               : "r" (dest), "Jr" (value)
+               : "memory", "cc"
+       );
+
+       return retval;
+}
+#define IL_HAVE_INTERLOCKED_ADD_RELEASE 1
+
+static IL_INLINE ILInt32 ILInterlockedAdd_Full(volatile ILInt32 *dest,
+                                                                               
           ILInt32 value)
+{
+       ILInt32 retval;
+       ILInt32 state;
+
+       __asm__ __volatile__
+       (
+               _IL_INTERLOCKED_ARM_MEMORYBARRIER
+               "1:"
+               "ldrex          %0, [%3];"
+               "add            %0,     %0, %4;"
+               "strex  %1, %0, [%3];"
+               "teq            %1, #0;"
+               "bne            1b;"
+               _IL_INTERLOCKED_ARM_MEMORYBARRIER
+               : "=&r" (retval), "=&r" (state), "+m" (*dest)
+               : "r" (dest), "Jr" (value)
+               : "memory", "cc"
+       );
+
+       return retval;
+}
+#define IL_HAVE_INTERLOCKED_ADD_FULL 1
+
 /*
  * Subtract two 32 bit integer values.
  */
 static IL_INLINE ILInt32 ILInterlockedSub(volatile ILInt32 *dest,
-                                                                               
 ILInt32 value)
+                                                                               
  ILInt32 value)
 {
        ILInt32 retval;
        ILInt32 state;
@@ -188,6 +704,79 @@ static IL_INLINE ILInt32 ILInterlockedSub(volatile ILInt32 
*dest,
 }
 #define IL_HAVE_INTERLOCKED_SUB 1
 
+static IL_INLINE ILInt32 ILInterlockedSub_Acquire(volatile ILInt32 *dest,
+                                                                               
                  ILInt32 value)
+{
+       ILInt32 retval;
+       ILInt32 state;
+
+       __asm__ __volatile__
+       (
+               "1:"
+               "ldrex          %0, [%3];"
+               "sub            %0,     %0, %4;"
+               "strex  %1, %0, [%3];"
+               "teq            %1, #0;"
+               "bne            1b;"
+               _IL_INTERLOCKED_ARM_MEMORYBARRIER
+               : "=&r" (retval), "=&r" (state), "+m" (*dest)
+               : "r" (dest), "Jr" (value)
+               : "memory", "cc"
+       );
+
+       return retval;
+}
+#define IL_HAVE_INTERLOCKED_SUB_ACQUIRE 1
+
+static IL_INLINE ILInt32 ILInterlockedSub_Release(volatile ILInt32 *dest,
+                                                                               
                  ILInt32 value)
+{
+       ILInt32 retval;
+       ILInt32 state;
+
+       __asm__ __volatile__
+       (
+               _IL_INTERLOCKED_ARM_MEMORYBARRIER
+               "1:"
+               "ldrex          %0, [%3];"
+               "sub            %0,     %0, %4;"
+               "strex  %1, %0, [%3];"
+               "teq            %1, #0;"
+               "bne            1b;"
+               : "=&r" (retval), "=&r" (state), "+m" (*dest)
+               : "r" (dest), "Jr" (value)
+               : "memory", "cc"
+       );
+
+       return retval;
+}
+#define IL_HAVE_INTERLOCKED_SUB_RELEASE 1
+
+static IL_INLINE ILInt32 ILInterlockedSub_Full(volatile ILInt32 *dest,
+                                                                               
           ILInt32 value)
+{
+       ILInt32 retval;
+       ILInt32 state;
+
+       __asm__ __volatile__
+       (
+               _IL_INTERLOCKED_ARM_MEMORYBARRIER
+               "1:"
+               "ldrex          %0, [%3];"
+               "sub            %0,     %0, %4;"
+               "strex  %1, %0, [%3];"
+               "teq            %1, #0;"
+               "bne            1b;"
+               _IL_INTERLOCKED_ARM_MEMORYBARRIER
+               : "=&r" (retval), "=&r" (state), "+m" (*dest)
+               : "r" (dest), "Jr" (value)
+               : "memory", "cc"
+       );
+
+       return retval;
+}
+#define IL_HAVE_INTERLOCKED_SUB_FULL 1
+
 /*
  * 32bit bitwise AND
  */
@@ -211,6 +800,73 @@ static IL_INLINE void ILInterlockedAnd(volatile ILUInt32 
*dest, ILUInt32 value)
 }
 #define IL_HAVE_INTERLOCKED_AND 1
 
+static IL_INLINE void ILInterlockedAnd_Acquire(volatile ILUInt32 *dest,
+                                                                               
           ILUInt32 value)
+{
+       ILInt32 retval;
+       ILInt32 state;
+
+       __asm__ __volatile__ 
+       (
+               "1:"
+               "ldrex          %0, [%3];"
+               "and            %0,     %0, %4;"
+               "strex  %1, %0, [%3];"
+               "teq            %1, #0;"
+               "bne            1b;"
+               _IL_INTERLOCKED_ARM_MEMORYBARRIER
+               : "=&r" (retval), "=&r" (state), "+m" (*dest)
+               : "r" (dest), "Jr" (value)
+               : "memory", "cc"
+       );
+}
+#define IL_HAVE_INTERLOCKED_AND_ACQUIRE 1
+
+static IL_INLINE void ILInterlockedAnd_Release(volatile ILUInt32 *dest,
+                                                                               
           ILUInt32 value)
+{
+       ILInt32 retval;
+       ILInt32 state;
+
+       __asm__ __volatile__ 
+       (
+               _IL_INTERLOCKED_ARM_MEMORYBARRIER
+               "1:"
+               "ldrex          %0, [%3];"
+               "and            %0,     %0, %4;"
+               "strex  %1, %0, [%3];"
+               "teq            %1, #0;"
+               "bne            1b;"
+               : "=&r" (retval), "=&r" (state), "+m" (*dest)
+               : "r" (dest), "Jr" (value)
+               : "memory", "cc"
+       );
+}
+#define IL_HAVE_INTERLOCKED_AND_RELEASE 1
+
+static IL_INLINE void ILInterlockedAnd_Full(volatile ILUInt32 *dest,
+                                                                               
        ILUInt32 value)
+{
+       ILInt32 retval;
+       ILInt32 state;
+
+       __asm__ __volatile__ 
+       (
+               _IL_INTERLOCKED_ARM_MEMORYBARRIER
+               "1:"
+               "ldrex          %0, [%3];"
+               "and            %0,     %0, %4;"
+               "strex  %1, %0, [%3];"
+               "teq            %1, #0;"
+               "bne            1b;"
+               _IL_INTERLOCKED_ARM_MEMORYBARRIER
+               : "=&r" (retval), "=&r" (state), "+m" (*dest)
+               : "r" (dest), "Jr" (value)
+               : "memory", "cc"
+       );
+}
+#define IL_HAVE_INTERLOCKED_AND_FULL 1
+
 /*
  * 32bit bitwise OR
  */
@@ -234,13 +890,77 @@ static IL_INLINE void ILInterlockedOr(volatile ILUInt32 
*dest, ILUInt32 value)
 }
 #define IL_HAVE_INTERLOCKED_OR 1
 
-#else /* __ARM_ARCH__ <= 5 */
+static IL_INLINE void ILInterlockedOr_Acquire(volatile ILUInt32 *dest, 
ILUInt32 value)
+{
+       ILInt32 retval;
+       ILInt32 state;
+
+       __asm__ __volatile__ 
+       (
+               "1:"
+               "ldrex          %0, [%3];"
+               "orr            %0,     %0, %4;"
+               "strex  %1, %0, [%3];"
+               "teq            %1, #0;"
+               "bne            1b;"
+               _IL_INTERLOCKED_ARM_MEMORYBARRIER
+               : "=&r" (retval), "=&r" (state), "+m" (*dest)
+               : "r" (dest), "Jr" (value)
+               : "memory", "cc"
+       );
+}
+#define IL_HAVE_INTERLOCKED_OR_ACQUIRE 1
+
+static IL_INLINE void ILInterlockedOr_Release(volatile ILUInt32 *dest, 
ILUInt32 value)
+{
+       ILInt32 retval;
+       ILInt32 state;
+
+       __asm__ __volatile__ 
+       (
+               _IL_INTERLOCKED_ARM_MEMORYBARRIER
+               "1:"
+               "ldrex          %0, [%3];"
+               "orr            %0,     %0, %4;"
+               "strex  %1, %0, [%3];"
+               "teq            %1, #0;"
+               "bne            1b;"
+               : "=&r" (retval), "=&r" (state), "+m" (*dest)
+               : "r" (dest), "Jr" (value)
+               : "memory", "cc"
+       );
+}
+#define IL_HAVE_INTERLOCKED_OR_RELEASE 1
+
+static IL_INLINE void ILInterlockedOr_Full(volatile ILUInt32 *dest, ILUInt32 
value)
+{
+       ILInt32 retval;
+       ILInt32 state;
+
+       __asm__ __volatile__ 
+       (
+               _IL_INTERLOCKED_ARM_MEMORYBARRIER
+               "1:"
+               "ldrex          %0, [%3];"
+               "orr            %0,     %0, %4;"
+               "strex  %1, %0, [%3];"
+               "teq            %1, #0;"
+               "bne            1b;"
+               _IL_INTERLOCKED_ARM_MEMORYBARRIER
+               : "=&r" (retval), "=&r" (state), "+m" (*dest)
+               : "r" (dest), "Jr" (value)
+               : "memory", "cc"
+       );
+}
+#define IL_HAVE_INTERLOCKED_OR_FULL 1
+
+#else /* __ARM_ARCH__ <= 5 || __ARM_ARCH_6M__ */
 
 /*
  * Exchange two 32 bit integers.
  */
-static IL_INLINE ILInt32 ILInterlockedExchange(volatile ILInt32 *dest,
-                                                                               
           ILInt32 value)
+static IL_INLINE ILInt32 ILInterlockedExchange_Full(volatile ILInt32 *dest,
+                                                                               
                        ILInt32 value)
 {
        ILInt32 retval;
 
@@ -254,13 +974,13 @@ static IL_INLINE ILInt32 ILInterlockedExchange(volatile 
ILInt32 *dest,
 
        return retval;
 }
-#define IL_HAVE_INTERLOCKED_EXCHANGE 1
+#define IL_HAVE_INTERLOCKED_EXCHANGE_FULL 1
 
 /*
  * Exchange pointers.
  */
-static IL_INLINE void *ILInterlockedExchangePointers(void * volatile *dest,
-                                                                               
                         void *value)
+static IL_INLINE void *ILInterlockedExchangePointers_Full(void * volatile 
*dest,
+                                                                               
                                  void *value)
 {
        void *retval;
 
@@ -274,9 +994,9 @@ static IL_INLINE void *ILInterlockedExchangePointers(void * 
volatile *dest,
 
        return retval;
 }
-#define IL_HAVE_INTERLOCKED_EXCHANGEPOINTERS 1
+#define IL_HAVE_INTERLOCKED_EXCHANGEPOINTERS_FULL 1
 
-#endif /* __ARM_ARCH__ <= 5 */
+#endif /* __ARM_ARCH__ <= 5  || __ARM_ARCH_6M__ */
 
 #endif /* defined(__GNUC__) */
 
diff --git a/support/interlocked_ppc.h b/support/interlocked_ppc.h
new file mode 100644
index 0000000..72d3a7d
--- /dev/null
+++ b/support/interlocked_ppc.h
@@ -0,0 +1,786 @@
+/*
+ * interlocked_ppc.h - Implementation of interlocked functions for
+ * powerpc processors.
+ *
+ * Copyright (C) 2009  Southern Storm Software, Pty Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#if defined(__powerpc__) || defined(powerpc) || \
+       defined(__powerpc) || defined(PPC) || defined(__ppc__)
+
+#if defined(__GNUC__)
+
+/*
+ * References:
+ * http://www.rdrop.com/users/paulmck/scalability/paper/N2745r.2009.02.22a.html
+ */
+
+/*
+ * Use the leight weight sync for release semantics if available.
+ */
+#ifdef __NO_LWSYNC__
+#define _IL_INTERLOCKED_PPC_LWSYNC     "\tsync\n"
+#else
+#define _IL_INTERLOCKED_PPC_LWSYNC     "\tlwsync\n"
+#endif
+
+/*
+ * Flush cache and set a memory barrier.
+ */
+static IL_INLINE void ILInterlockedMemoryBarrier()
+{
+       __asm__ __volatile__
+       (
+               "sync"
+               :
+               :
+               : "memory"
+       );
+}
+#define IL_HAVE_INTERLOCKED_MEMORYBARRIER 1
+
+/*
+ * Load a 32 bit value from a location with acquire semantics.
+ */
+static IL_INLINE ILInt32 ILInterlockedLoad_Acquire(const volatile ILInt32 
*dest)
+{
+       ILInt32 retval;
+
+       __asm__ __volatile__ 
+       (
+           "\tlwz%U1%X1 %0, %1\n"
+           "\tcmpw             %0, %0\n"
+           "\tbne-             1f\n"
+       "1:"
+               "\tisync\n"
+           : "=r" (retval)
+           : "m" (*dest)
+               : "memory", "cc"
+       );
+
+       return retval;
+}
+#define IL_HAVE_INTERLOCKED_LOAD_ACQUIRE
+
+/*
+ * Load a pointer value from a location with acquire semantics.
+ */
+static IL_INLINE void *ILInterlockedLoadPointer_Acquire(void * const volatile 
*dest)
+{
+       void *retval;
+
+       __asm__ __volatile__ 
+       (
+           "\tlwz%U1%X1 %0, %1\n"
+           "\tcmpw             %0, %0\n"
+           "\tbne-             1f\n"
+       "1:"
+               "\tisync\n"
+           : "=r" (retval)
+           : "m" (*dest)
+               : "memory", "cc"
+       );
+
+       return retval;
+}
+#define IL_HAVE_INTERLOCKED_LOADPOINTER_ACQUIRE
+
+/*
+ * Store a 32 bit value to a location with release semantics.
+ */
+static IL_INLINE void ILInterlockedStore_Release(volatile ILInt32 *dest,
+                                                                               
                 ILInt32 value)
+{
+       __asm__ __volatile__ 
+       (
+               _IL_INTERLOCKED_PPC_LWSYNC
+               "\tstw  %1, %0\n"
+               : "=m" (*dest)
+               : "r" (value)
+               : "memory"
+       );
+}
+#define IL_HAVE_INTERLOCKED_STORE_RELEASE 1
+
+/*
+ * Store a pointer value to a location with release semantics.
+ * TODO: Add support for ppc64
+ */
+static IL_INLINE void ILInterlockedStorePointer_Release(void * volatile *dest,
+                                                                               
                                void *value)
+{
+       __asm__ __volatile__ 
+       (
+               _IL_INTERLOCKED_PPC_LWSYNC
+               "\tstw  %1, %0\n"
+               : "=m" (*dest)
+               : "r" (value)
+               : "memory"
+       );
+}
+#define IL_HAVE_INTERLOCKED_STOREPOINTER_RELEASE 1
+
+/*
+ * Exchange two 32 bit integers.
+ */
+static IL_INLINE ILInt32 ILInterlockedExchange(volatile ILInt32 *dest,
+                                                                               
           ILInt32 value)
+{
+       ILInt32 retval;
+
+       __asm__ __volatile__ 
+       (
+               "1:"
+               "\tlwarx        %0, 0, %2\n"
+               "\tstwcx.       %3, 0, %2\n"
+               "\tbne-         1b\n"
+               : "=&r" (retval), "=m" (*dest)
+               : "r" (dest), "r" (value)
+               : "cc"
+       );
+
+       return retval;
+}
+#define IL_HAVE_INTERLOCKED_EXCHANGE 1
+
+static IL_INLINE ILInt32 ILInterlockedExchange_Acquire(volatile ILInt32 *dest,
+                                                                               
                           ILInt32 value)
+{
+       ILInt32 retval;
+
+       __asm__ __volatile__ 
+       (
+               "1:"
+               "\tlwarx        %0, 0, %2\n"
+               "\tstwcx.       %3, 0, %2\n"
+               "\tbne-         1b\n"
+               _IL_INTERLOCKED_PPC_LWSYNC
+               : "=&r" (retval), "=m" (*dest)
+               : "r" (dest), "r" (value)
+               : "memory", "cc"
+       );
+
+       return retval;
+}
+#define IL_HAVE_INTERLOCKED_EXCHANGE_ACQUIRE 1
+
+static IL_INLINE ILInt32 ILInterlockedExchange_Release(volatile ILInt32 *dest,
+                                                                               
                           ILInt32 value)
+{
+       ILInt32 retval;
+
+       __asm__ __volatile__ 
+       (
+               _IL_INTERLOCKED_PPC_LWSYNC
+               "1:"
+               "\tlwarx        %0, 0, %2\n"
+               "\tstwcx.       %3, 0, %2\n"
+               "\tbne-         1b\n"
+               : "=&r" (retval), "=m" (*dest)
+               : "r" (dest), "r" (value)
+               : "memory", "cc"
+       );
+
+       return retval;
+}
+#define IL_HAVE_INTERLOCKED_EXCHANGE_RELEASE 1
+
+static IL_INLINE ILInt32 ILInterlockedExchange_Full(volatile ILInt32 *dest,
+                                                                               
                        ILInt32 value)
+{
+       ILInt32 retval;
+
+       __asm__ __volatile__ 
+       (
+               _IL_INTERLOCKED_PPC_LWSYNC
+               "1:"
+               "\tlwarx        %0, 0, %2\n"
+               "\tstwcx.       %3, 0, %2\n"
+               "\tbne-         1b\n"
+               _IL_INTERLOCKED_PPC_LWSYNC
+               : "=&r" (retval), "=m" (*dest)
+               : "r" (dest), "r" (value)
+               : "memory", "cc"
+       );
+
+       return retval;
+}
+#define IL_HAVE_INTERLOCKED_EXCHANGE_FULL 1
+
+/*
+ * Exchange pointers.
+ *
+ * FIXME: Add support for the 64bit powerpc
+ */
+static IL_INLINE void *ILInterlockedExchangePointers(void * volatile *dest,
+                                                                               
                         void *value)
+{
+       void *retval;
+
+       __asm__ __volatile__ 
+       (
+               "1:"
+               "\tlwarx        %0, 0, %2\n"
+               "\tstwcx.       %3, 0, %2\n"
+               "\tbne-         1b\n"
+               : "=&r" (retval), "=m" (*dest)
+               : "r" (dest), "r" (value)
+               : "cc"
+       );
+
+       return retval;
+}
+#define IL_HAVE_INTERLOCKED_EXCHANGEPOINTERS 1
+
+static IL_INLINE void *ILInterlockedExchangePointers_Acquire(void * volatile 
*dest,
+                                                                               
                                         void *value)
+{
+       void *retval;
+
+       __asm__ __volatile__ 
+       (
+               "1:"
+               "\tlwarx        %0, 0, %2\n"
+               "\tstwcx.       %3, 0, %2\n"
+               "\tbne-         1b\n"
+               _IL_INTERLOCKED_PPC_LWSYNC
+               : "=&r" (retval), "=m" (*dest)
+               : "r" (dest), "r" (value)
+               : "memory", "cc"
+       );
+
+       return retval;
+}
+#define IL_HAVE_INTERLOCKED_EXCHANGEPOINTERS_ACQUIRE 1
+
+static IL_INLINE void *ILInterlockedExchangePointers_Release(void * volatile 
*dest,
+                                                                               
                                         void *value)
+{
+       void *retval;
+
+       __asm__ __volatile__ 
+       (
+               _IL_INTERLOCKED_PPC_LWSYNC
+               "1:"
+               "\tlwarx        %0, 0, %2\n"
+               "\tstwcx.       %3, 0, %2\n"
+               "\tbne-         1b\n"
+               : "=&r" (retval), "=m" (*dest)
+               : "r" (dest), "r" (value)
+               : "memory", "cc"
+       );
+
+       return retval;
+}
+#define IL_HAVE_INTERLOCKED_EXCHANGEPOINTERS_RELEASE 1
+
+static IL_INLINE void *ILInterlockedExchangePointers_Full(void * volatile 
*dest,
+                                                                               
                                  void *value)
+{
+       void *retval;
+
+       __asm__ __volatile__ 
+       (
+               _IL_INTERLOCKED_PPC_LWSYNC
+               "1:"
+               "\tlwarx        %0, 0, %2\n"
+               "\tstwcx.       %3, 0, %2\n"
+               "\tbne-         1b\n"
+               _IL_INTERLOCKED_PPC_LWSYNC
+               : "=&r" (retval), "=m" (*dest)
+               : "r" (dest), "r" (value)
+               : "memory", "cc"
+       );
+
+       return retval;
+}
+#define IL_HAVE_INTERLOCKED_EXCHANGEPOINTERS_FULL 1
+
+/*
+ * Compare and exchange two 32bit integers.
+ */
+static IL_INLINE ILInt32 ILInterlockedCompareAndExchange(volatile ILInt32 
*dest,
+                                                                               
                                 ILInt32 value,
+                                                                               
                                 ILInt32 comparand)
+{
+       ILInt32 retval;
+
+       __asm__ __volatile__
+       (
+               "1:"
+               "\tlwarx        %0, 0, %2\n"
+               "\tcmpw         %0, %4\n"
+               "\tbne          2f\n"
+               "\tstwcx.       %3, 0, %2\n"
+               "\tbne-         1b\n"
+               "2:"
+               : "=&r" (retval), "=m" (*dest)
+               : "r" (dest), "r" (value), "r" (comparand)
+               : "cc"
+       );
+
+       return retval;
+}
+#define IL_HAVE_INTERLOCKED_COMPAREANDEXCHANGE 1
+
+static IL_INLINE ILInt32 ILInterlockedCompareAndExchange_Acquire(volatile 
ILInt32 *dest,
+                                                                               
                                                 ILInt32 value,
+                                                                               
                                                 ILInt32 comparand)
+{
+       ILInt32 retval;
+
+       __asm__ __volatile__
+       (
+               "1:"
+               "\tlwarx        %0, 0, %2\n"
+               "\tcmpw         %0, %4\n"
+               "\tbne          2f\n"
+               "\tstwcx.       %3, 0, %2\n"
+               "\tbne-         1b\n"
+               "2:"
+               _IL_INTERLOCKED_PPC_LWSYNC
+               : "=&r" (retval), "=m" (*dest)
+               : "r" (dest), "r" (value), "r" (comparand)
+               : "memory", "cc"
+       );
+
+       return retval;
+}
+#define IL_HAVE_INTERLOCKED_COMPAREANDEXCHANGE_ACQUIRE 1
+
+static IL_INLINE ILInt32 ILInterlockedCompareAndExchange_Release(volatile 
ILInt32 *dest,
+                                                                               
                                                 ILInt32 value,
+                                                                               
                                                 ILInt32 comparand)
+{
+       ILInt32 retval;
+
+       __asm__ __volatile__
+       (
+               _IL_INTERLOCKED_PPC_LWSYNC
+               "1:"
+               "\tlwarx        %0, 0, %2\n"
+               "\tcmpw         %0, %4\n"
+               "\tbne          2f\n"
+               "\tstwcx.       %3, 0, %2\n"
+               "\tbne-         1b\n"
+               "2:"
+               : "=&r" (retval), "=m" (*dest)
+               : "r" (dest), "r" (value), "r" (comparand)
+               : "memory", "cc"
+       );
+
+       return retval;
+}
+#define IL_HAVE_INTERLOCKED_COMPAREANDEXCHANGE_RELEASE 1
+
+static IL_INLINE ILInt32 ILInterlockedCompareAndExchange_Full(volatile ILInt32 
*dest,
+                                                                               
                                          ILInt32 value,
+                                                                               
                                          ILInt32 comparand)
+{
+       ILInt32 retval;
+
+       __asm__ __volatile__
+       (
+               _IL_INTERLOCKED_PPC_LWSYNC
+               "1:"
+               "\tlwarx        %0, 0, %2\n"
+               "\tcmpw         %0, %4\n"
+               "\tbne          2f\n"
+               "\tstwcx.       %3, 0, %2\n"
+               "\tbne-         1b\n"
+               "2:"
+               _IL_INTERLOCKED_PPC_LWSYNC
+               : "=&r" (retval), "=m" (*dest)
+               : "r" (dest), "r" (value), "r" (comparand)
+               : "memory", "cc"
+       );
+
+       return retval;
+}
+#define IL_HAVE_INTERLOCKED_COMPAREANDEXCHANGE_FULL 1
+
+/*
+ * Compare and exchange two pointers.
+ * TODO: Add ppc64 support
+ */
+static IL_INLINE void *ILInterlockedCompareAndExchangePointers(void * volatile 
*dest,
+                                                                               
                                           void *value,
+                                                                               
                                           void *comparand)
+{
+       void *retval;
+
+       __asm__ __volatile__
+       (
+               "1:"
+               "\tlwarx        %0, 0, %2\n"
+               "\tcmpw         %0, %4\n"
+               "\tbne          2f\n"
+               "\tstwcx.       %3, 0, %2\n"
+               "\tbne-         1b\n"
+               "2:"
+               : "=&r" (retval), "=m" (*dest)
+               : "r" (dest), "r" (value), "r" (comparand)
+               : "cc"
+       );
+
+       return retval;
+}
+#define IL_HAVE_INTERLOCKED_COMPAREANDEXCHANGEPOINTERS 1
+
+static IL_INLINE void *ILInterlockedCompareAndExchangePointers_Acquire(void * 
volatile *dest,
+                                                                               
                                                           void *value,
+                                                                               
                                                           void *comparand)
+{
+       void *retval;
+
+       __asm__ __volatile__
+       (
+               "1:"
+               "\tlwarx        %0, 0, %2\n"
+               "\tcmpw         %0, %4\n"
+               "\tbne          2f\n"
+               "\tstwcx.       %3, 0, %2\n"
+               "\tbne-         1b\n"
+               "2:"
+               _IL_INTERLOCKED_PPC_LWSYNC
+               : "=&r" (retval), "=m" (*dest)
+               : "r" (dest), "r" (value), "r" (comparand)
+               : "memory", "cc"
+       );
+
+       return retval;
+}
+#define IL_HAVE_INTERLOCKED_COMPAREANDEXCHANGEPOINTERS_ACQUIRE 1
+
+static IL_INLINE void *ILInterlockedCompareAndExchangePointers_Release(void * 
volatile *dest,
+                                                                               
                                                           void *value,
+                                                                               
                                                           void *comparand)
+{
+       void *retval;
+
+       __asm__ __volatile__
+       (
+               _IL_INTERLOCKED_PPC_LWSYNC
+               "1:"
+               "\tlwarx        %0, 0, %2\n"
+               "\tcmpw         %0, %4\n"
+               "\tbne          2f\n"
+               "\tstwcx.       %3, 0, %2\n"
+               "\tbne-         1b\n"
+               "2:"
+               : "=&r" (retval), "=m" (*dest)
+               : "r" (dest), "r" (value), "r" (comparand)
+               : "memory", "cc"
+       );
+
+       return retval;
+}
+#define IL_HAVE_INTERLOCKED_COMPAREANDEXCHANGEPOINTERS_RELEASE 1
+
+static IL_INLINE void *ILInterlockedCompareAndExchangePointers_Full(void * 
volatile *dest,
+                                                                               
                                                        void *value,
+                                                                               
                                                        void *comparand)
+{
+       void *retval;
+
+       __asm__ __volatile__
+       (
+               _IL_INTERLOCKED_PPC_LWSYNC
+               "1:"
+               "\tlwarx        %0, 0, %2\n"
+               "\tcmpw         %0, %4\n"
+               "\tbne          2f\n"
+               "\tstwcx.       %3, 0, %2\n"
+               "\tbne-         1b\n"
+               "2:"
+               _IL_INTERLOCKED_PPC_LWSYNC
+               : "=&r" (retval), "=m" (*dest)
+               : "r" (dest), "r" (value), "r" (comparand)
+               : "memory", "cc"
+       );
+
+       return retval;
+}
+#define IL_HAVE_INTERLOCKED_COMPAREANDEXCHANGEPOINTERS_FULL 1
+
+/*
+ * Add two 32 bit integer values.
+ */
+static IL_INLINE ILInt32 ILInterlockedAdd(volatile ILInt32 *dest,
+                                                                               
  ILInt32 value)
+{
+       ILInt32 retval;
+
+       __asm__ __volatile__ 
+       (
+               "1:"
+               "\tlwarx        %0, 0, %2\n"
+               "\tadd          %0, %0, %3\n"
+               "\tstwcx.       %0, 0, %2\n"
+               "\tbne-         1b\n"
+               : "=r" (retval), "=m" (*dest)
+               : "r" (dest), "r" (value)
+               : "cc"
+       );
+
+       return retval;
+}
+#define IL_HAVE_INTERLOCKED_ADD 1
+
+static IL_INLINE ILInt32 ILInterlockedAdd_Acquire(volatile ILInt32 *dest,
+                                                                               
                  ILInt32 value)
+{
+       ILInt32 retval;
+
+       __asm__ __volatile__ 
+       (
+               "1:"
+               "\tlwarx        %0, 0, %2\n"
+               "\tadd          %0, %0, %3\n"
+               "\tstwcx.       %0, 0, %2\n"
+               "\tbne-         1b\n"
+               _IL_INTERLOCKED_PPC_LWSYNC
+               : "=r" (retval), "=m" (*dest)
+               : "r" (dest), "r" (value)
+               : "memory", "cc"
+       );
+
+       return retval;
+}
+#define IL_HAVE_INTERLOCKED_ADD_ACQUIRE 1
+
+static IL_INLINE ILInt32 ILInterlockedAdd_Release(volatile ILInt32 *dest,
+                                                                               
                  ILInt32 value)
+{
+       ILInt32 retval;
+
+       __asm__ __volatile__ 
+       (
+               _IL_INTERLOCKED_PPC_LWSYNC
+               "1:"
+               "\tlwarx        %0, 0, %2\n"
+               "\tadd          %0, %0, %3\n"
+               "\tstwcx.       %0, 0, %2\n"
+               "\tbne-         1b\n"
+               : "=r" (retval), "=m" (*dest)
+               : "r" (dest), "r" (value)
+               : "memory", "cc"
+       );
+
+       return retval;
+}
+#define IL_HAVE_INTERLOCKED_ADD_RELEASE 1
+
+static IL_INLINE ILInt32 ILInterlockedAdd_Full(volatile ILInt32 *dest,
+                                                                               
           ILInt32 value)
+{
+       ILInt32 retval;
+
+       __asm__ __volatile__ 
+       (
+               _IL_INTERLOCKED_PPC_LWSYNC
+               "1:"
+               "\tlwarx        %0, 0, %2\n"
+               "\tadd          %0, %0, %3\n"
+               "\tstwcx.       %0, 0, %2\n"
+               "\tbne-         1b\n"
+               _IL_INTERLOCKED_PPC_LWSYNC
+               : "=r" (retval), "=m" (*dest)
+               : "r" (dest), "r" (value)
+               : "memory", "cc"
+       );
+
+       return retval;
+}
+#define IL_HAVE_INTERLOCKED_ADD_FULL 1
+
+/*
+ * Subtract two 32 bit integer values.
+ */
+static IL_INLINE ILInt32 ILInterlockedSub(volatile ILInt32 *dest,
+                                                                               
  ILInt32 value)
+{
+       ILInt32 retval;
+
+       __asm__ __volatile__ 
+       (
+               "1:"
+               "\tlwarx        %0, 0, %2\n"
+               "\tsubf         %0, %3, %0\n"
+               "\tstwcx.       %0, 0, %2\n"
+               "\tbne-         1b\n"
+               : "=r" (retval), "=m" (*dest)
+               : "r" (dest), "r" (value)
+               : "cc"
+       );
+
+       return retval;
+}
+#define IL_HAVE_INTERLOCKED_SUB 1
+
+static IL_INLINE ILInt32 ILInterlockedSub_Acquire(volatile ILInt32 *dest,
+                                                                               
                  ILInt32 value)
+{
+       ILInt32 retval;
+
+       __asm__ __volatile__ 
+       (
+               "1:"
+               "\tlwarx        %0, 0, %2\n"
+               "\tsubf         %0, %3, %0\n"
+               "\tstwcx.       %0, 0, %2\n"
+               "\tbne-         1b\n"
+               _IL_INTERLOCKED_PPC_LWSYNC
+               : "=r" (retval), "=m" (*dest)
+               : "r" (dest), "r" (value)
+               : "memory", "cc"
+       );
+
+       return retval;
+}
+#define IL_HAVE_INTERLOCKED_SUB_ACQUIRE 1
+
+static IL_INLINE ILInt32 ILInterlockedSub_Release(volatile ILInt32 *dest,
+                                                                               
                  ILInt32 value)
+{
+       ILInt32 retval;
+
+       __asm__ __volatile__ 
+       (
+               _IL_INTERLOCKED_PPC_LWSYNC
+               "1:"
+               "\tlwarx        %0, 0, %2\n"
+               "\tsubf         %0, %3, %0\n"
+               "\tstwcx.       %0, 0, %2\n"
+               "\tbne-         1b\n"
+               : "=r" (retval), "=m" (*dest)
+               : "r" (dest), "r" (value)
+               : "memory", "cc"
+       );
+
+       return retval;
+}
+#define IL_HAVE_INTERLOCKED_SUB_RELEASE 1
+
+static IL_INLINE ILInt32 ILInterlockedSub_Full(volatile ILInt32 *dest,
+                                                                               
           ILInt32 value)
+{
+       ILInt32 retval;
+
+       __asm__ __volatile__ 
+       (
+               _IL_INTERLOCKED_PPC_LWSYNC
+               "1:"
+               "\tlwarx        %0, 0, %2\n"
+               "\tsubf         %0, %3, %0\n"
+               "\tstwcx.       %0, 0, %2\n"
+               "\tbne-         1b\n"
+               _IL_INTERLOCKED_PPC_LWSYNC
+               : "=r" (retval), "=m" (*dest)
+               : "r" (dest), "r" (value)
+               : "memory", "cc"
+       );
+
+       return retval;
+}
+#define IL_HAVE_INTERLOCKED_SUB_FULL 1
+
+/*
+ * 32bit bitwise AND
+ */
+static IL_INLINE void ILInterlockedAnd(volatile ILUInt32 *dest, ILUInt32 value)
+{
+       ILInt32 retval;
+
+       __asm__ __volatile__ 
+       (
+               "1:"
+               "\tlwarx        %0, 0, %2\n"
+               "\tand          %0, %0, %3\n"
+               "\tstwcx.       %0, 0, %2\n"
+               "\tbne-         1b\n"
+               : "=r" (retval), "=m" (*dest)
+               : "r" (dest), "r" (value)
+               : "cc"
+       );
+}
+#define IL_HAVE_INTERLOCKED_AND 1
+
+static IL_INLINE void ILInterlockedAnd_Full(volatile ILUInt32 *dest, ILUInt32 
value)
+{
+       ILInt32 retval;
+
+       __asm__ __volatile__ 
+       (
+               _IL_INTERLOCKED_PPC_LWSYNC
+               "1:"
+               "\tlwarx        %0, 0, %2\n"
+               "\tand          %0, %0, %3\n"
+               "\tstwcx.       %0, 0, %2\n"
+               "\tbne-         1b\n"
+               _IL_INTERLOCKED_PPC_LWSYNC
+               : "=r" (retval), "=m" (*dest)
+               : "r" (dest), "r" (value)
+               : "memory", "cc"
+       );
+}
+#define IL_HAVE_INTERLOCKED_AND_FULL 1
+
+/*
+ * 32bit bitwise OR
+ */
+static IL_INLINE void ILInterlockedOr(volatile ILUInt32 *dest, ILUInt32 value)
+{
+       ILInt32 retval;
+
+       __asm__ __volatile__ 
+       (
+               "1:"
+               "\tlwarx        %0, 0, %2\n"
+               "\tor           %0, %0, %3\n"
+               "\tstwcx.       %0, 0, %2\n"
+               "\tbne-         1b\n"
+               : "=r" (retval), "=m" (*dest)
+               : "r" (dest), "r" (value)
+               : "cc"
+       );
+}
+#define IL_HAVE_INTERLOCKED_OR 1
+
+static IL_INLINE void ILInterlockedOr_Full(volatile ILUInt32 *dest, ILUInt32 
value)
+{
+       ILInt32 retval;
+
+       __asm__ __volatile__ 
+       (
+               _IL_INTERLOCKED_PPC_LWSYNC
+               "1:"
+               "\tlwarx        %0, 0, %2\n"
+               "\tor           %0, %0, %3\n"
+               "\tstwcx.       %0, 0, %2\n"
+               "\tbne-         1b\n"
+               _IL_INTERLOCKED_PPC_LWSYNC
+               : "=r" (retval), "=m" (*dest)
+               : "r" (dest), "r" (value)
+               : "memory", "cc"
+       );
+}
+#define IL_HAVE_INTERLOCKED_OR_FULL 1
+
+#endif /* defined(__GNUC__) */
+
+#endif /* defined(__powerpc__) || defined(powerpc) || defined(__powerpc) || 
defined(PPC) || defined(__ppc__) */
diff --git a/support/interlocked_x86.h b/support/interlocked_x86.h
index b723919..d9847a0 100644
--- a/support/interlocked_x86.h
+++ b/support/interlocked_x86.h
@@ -25,37 +25,124 @@
 
 #if defined(__GNUC__)
 
+#if defined(__SSE2__) || defined(__sse2__)
+#define _IL_INTERLOCKED_X86_MFENCE     "mfence;"
+#else
+#define _IL_INTERLOCKED_X86_MFENCE     "lock; addl $0,0(%%esp);"
+#endif
+
 /*
  * Flush cache and set a memory barrier.
  */
 static IL_INLINE void ILInterlockedMemoryBarrier()
 {
-#if defined(__SSE2__) || defined(__sse2__)
        __asm__ __volatile__
        (
-               "mfence"
+               _IL_INTERLOCKED_X86_MFENCE
                :::
                "memory"
        );
+}
+#define IL_HAVE_INTERLOCKED_MEMORYBARRIER 1
+
+/*
+ * NOTE: All operations on x86 using the lock prefix have full barrier
+ * semantics.
+ */
+
+/*
+ * Load a 32 bit value from a location with acquire semantics.
+ */
+static IL_INLINE ILInt32 ILInterlockedLoad_Acquire(const volatile ILInt32 
*dest)
+{
+       ILInt32 retval;
+
+       __asm__ __volatile__ 
+       (
+           "movl       %1, %0;"
+               _IL_INTERLOCKED_X86_MFENCE
+           : "=r" (retval)
+           : "m" (*dest)
+               : "memory"
+       );
+
+       return retval;
+}
+#define IL_HAVE_INTERLOCKED_LOAD_ACQUIRE
+
+/*
+ * Load a pointer value from a location with acquire semantics.
+ */
+static IL_INLINE void * ILInterlockedLoadPointer_Acquire(void * const volatile 
*dest)
+{
+       void *retval;
+
+       __asm__ __volatile__ 
+       (
+#if defined(__x86_64__)
+           "movq       %1, %0;"
 #else
-       __asm__ __volatile__
+           "movl       %1, %0;"
+#endif
+               _IL_INTERLOCKED_X86_MFENCE
+           : "=r" (retval)
+           : "m" (*dest)
+               : "memory"
+       );
+
+       return retval;
+}
+#define IL_HAVE_INTERLOCKED_LOADPOINTER_ACQUIRE
+
+/*
+ * Store a 32 bit value to a location with release semantics.
+ */
+static IL_INLINE void ILInterlockedStore_Release(volatile ILInt32 *dest,
+                                                                               
                 ILInt32 value)
+{
+       __asm__ __volatile__ 
        (
-               "lock; addl $0,0(%%esp)"
-               :::
-               "memory"
+               _IL_INTERLOCKED_X86_MFENCE
+               "movl   %1, %0;"
+               : "=m" (*dest)
+               : "er" (value)
+               : "memory"
        );
+}
+#define IL_HAVE_INTERLOCKED_STORE_RELEASE 1
+
+/*
+ * Store a pointer value to a location with release semantics.
+ */
+static IL_INLINE void ILInterlockedStorePointer_Release(void * volatile *dest,
+                                                                               
                                void *value)
+{
+       __asm__ __volatile__ 
+       (
+               _IL_INTERLOCKED_X86_MFENCE
+#if defined(__x86_64__)
+               "movq   %1, %0;"
+#else
+               "movl   %1, %0;"
 #endif
+               : "=m" (*dest)
+               : "er" (value)
+               : "memory"
+       );
 }
-#define IL_HAVE_INTERLOCKED_MEMORYBARRIER 1
+#define IL_HAVE_INTERLOCKED_STOREPOINTER_RELEASE 1
 
 /*
  * Exchange two 32 bit integers.
  */
-static IL_INLINE ILInt32 ILInterlockedExchange(volatile ILInt32 *dest,
-                                                                               
           ILInt32 value)
+static IL_INLINE ILInt32 ILInterlockedExchange_Full(volatile ILInt32 *dest,
+                                                                               
                        ILInt32 value)
 {
        ILInt32 retval;
 
+       /*
+        * NOTE: xchg has an implicit lock if a memory operand is involved.
+        */
        __asm__ __volatile__ 
        (
                "xchgl %2, %0;"
@@ -66,16 +153,19 @@ static IL_INLINE ILInt32 ILInterlockedExchange(volatile 
ILInt32 *dest,
 
        return retval;
 }
-#define IL_HAVE_INTERLOCKED_EXCHANGE 1
+#define IL_HAVE_INTERLOCKED_EXCHANGE_FULL 1
 
 /*
  * Exchange pointers.
  */
-static IL_INLINE void *ILInterlockedExchangePointers(void * volatile *dest,
-                                                                               
                         void *value)
+static IL_INLINE void *ILInterlockedExchangePointers_Full(void * volatile 
*dest,
+                                                                               
                                  void *value)
 {
        void *retval;
 
+       /*
+        * NOTE: xchg has an implicit lock if a memory operand is involved.
+        */
        __asm__ __volatile__ 
        (
 #if defined(__x86_64__)
@@ -90,7 +180,7 @@ static IL_INLINE void *ILInterlockedExchangePointers(void * 
volatile *dest,
 
        return retval;
 }
-#define IL_HAVE_INTERLOCKED_EXCHANGEPOINTERS 1
+#define IL_HAVE_INTERLOCKED_EXCHANGEPOINTERS_FULL 1
 
 /*
  * Compare and exchange two 32bit integers.
@@ -114,6 +204,30 @@ static IL_INLINE ILInt32 
ILInterlockedCompareAndExchange(volatile ILInt32 *dest,
 #define IL_HAVE_INTERLOCKED_COMPAREANDEXCHANGE 1
 
 /*
+ * Compare and exchange two 32bit integers with full semantics.
+ * x86 has full semantics with the lock prefix but gcc might move memory
+ * loads before this statement so we have to add the "memory" clobber here.
+ */
+static IL_INLINE ILInt32 ILInterlockedCompareAndExchange_Full(volatile ILInt32 
*dest,
+                                                                               
                                          ILInt32 value,
+                                                                               
                                          ILInt32 comparand)
+{
+       ILInt32 retval;
+
+       __asm__ __volatile__
+       (
+               "lock;"
+               "cmpxchgl %2, %0"
+               : "=m" (*dest), "=a" (retval)
+               : "r" (value), "m" (*dest), "a" (comparand)
+               : "memory"
+       );
+
+       return retval;
+}
+#define IL_HAVE_INTERLOCKED_COMPAREANDEXCHANGE_FULL 1
+
+/*
  * Compare and exchange two pointers.
  */
 static IL_INLINE void *ILInterlockedCompareAndExchangePointers(void * volatile 
*dest,
@@ -139,10 +253,36 @@ static IL_INLINE void 
*ILInterlockedCompareAndExchangePointers(void * volatile *
 #define IL_HAVE_INTERLOCKED_COMPAREANDEXCHANGEPOINTERS 1
 
 /*
+ * Compare and exchange two pointers.
+ */
+static IL_INLINE void *ILInterlockedCompareAndExchangePointers_Full(void * 
volatile *dest,
+                                                                               
                                                        void *value,
+                                                                               
                                                        void *comparand)
+{
+       void *retval;
+
+       __asm__ __volatile__
+       (
+               "lock;"
+#if defined(__x86_64__)
+               "cmpxchgq %2, %0;"
+#else
+               "cmpxchgl %2, %0;"
+#endif
+               : "=m" (*dest), "=a" (retval)
+               : "r" (value), "m" (*dest), "a" (comparand)
+               : "memory"
+       );
+
+       return retval;
+}
+#define IL_HAVE_INTERLOCKED_COMPAREANDEXCHANGEPOINTERS_FULL 1
+
+/*
  * Add two 32 bit integer values.
  */
-static IL_INLINE ILInt32 ILInterlockedAdd(volatile ILInt32 *dest,
-                                                                               
 ILInt32 value)
+static IL_INLINE ILInt32 ILInterlockedAdd_Full(volatile ILInt32 *dest,
+                                                                               
           ILInt32 value)
 {
        ILInt32 retval;
 
@@ -151,17 +291,19 @@ static IL_INLINE ILInt32 ILInterlockedAdd(volatile 
ILInt32 *dest,
                "lock;"
                "xaddl %0, %1"
                : "=r" (retval), "=m" (*dest)
-               : "0" (value), "m" (*dest) : "memory"
+               : "0" (value), "m" (*dest)
+               : "memory"
        );
 
        return retval + value;
 }
-#define IL_HAVE_INTERLOCKED_ADD 1
+#define IL_HAVE_INTERLOCKED_ADD_FULL 1
 
 /*
  * 32bit bitwise AND
  */
-static IL_INLINE void ILInterlockedAnd(volatile ILUInt32 *dest, ILUInt32 value)
+static IL_INLINE void ILInterlockedAnd_Full(volatile ILUInt32 *dest,
+                                                                               
        ILUInt32 value)
 {
        __asm__ __volatile__ 
        (
@@ -171,12 +313,13 @@ static IL_INLINE void ILInterlockedAnd(volatile ILUInt32 
*dest, ILUInt32 value)
                : "er" (value), "m" (*dest)
                : "memory");
 }
-#define IL_HAVE_INTERLOCKED_AND 1
+#define IL_HAVE_INTERLOCKED_AND_FULL 1
 
 /*
  * 32bit bitwise OR
  */
-static IL_INLINE void ILInterlockedOr(volatile ILUInt32 *dest, ILUInt32 value)
+static IL_INLINE void ILInterlockedOr_Full(volatile ILUInt32 *dest,
+                                                                               
   ILUInt32 value)
 {
        __asm__ __volatile__ 
        (
@@ -186,7 +329,7 @@ static IL_INLINE void ILInterlockedOr(volatile ILUInt32 
*dest, ILUInt32 value)
                : "er" (value), "m" (*dest)
                : "memory");
 }
-#define IL_HAVE_INTERLOCKED_OR 1
+#define IL_HAVE_INTERLOCKED_OR_FULL 1
 
 #endif /* defined(__GNUC__) */
 
diff --git a/tests/test_thread.c b/tests/test_thread.c
index 0ab4fbe..52e765b 100755
--- a/tests/test_thread.c
+++ b/tests/test_thread.c
@@ -1100,6 +1100,80 @@ static void thread_counts(void *arg)
        }
 }
 
+static void interlocked_load(void *arg)
+{
+       volatile ILInt32 value;
+       void * volatile ptrValue;
+       int haveError;
+
+       haveError = 0;
+       value = 1;
+       if(ILInterlockedLoad(&value) != 1)
+       {
+               haveError = 1;
+               ILUnitFailMessage("Incorrect return value of 
ILInterlockedLoad");
+       }
+       if(ILInterlockedLoad_Acquire(&value) != 1)
+       {
+               haveError = 1;
+               ILUnitFailMessage("Incorrect return value of 
ILInterlockedLoad_Acquire");
+       }
+       ptrValue = (void *)1;
+       if(ILInterlockedLoadPointer(&ptrValue) != (void *)1)
+       {
+               haveError = 1;
+               ILUnitFailMessage("Incorrect return value of 
ILInterlockedLoadPointer");
+       }
+       if(ILInterlockedLoadPointer_Acquire(&ptrValue) != (void *)1)
+       {
+               haveError = 1;
+               ILUnitFailMessage("Incorrect return value of 
ILInterlockedLoadPointer_Acquire");
+       }
+       if(haveError)
+       {
+               ILUnitFailEndMessages();
+       }
+}
+
+static void interlocked_store(void *arg)
+{
+       volatile ILInt32 value;
+       void * volatile ptrValue;
+       int haveError;
+
+       haveError = 0;
+       value = 1;
+       ILInterlockedStore(&value, 2);
+       if(value != 2)
+       {
+               haveError = 1;
+               ILUnitFailMessage("ILInterlockedStore doesn't store the correct 
value");
+       }
+       ILInterlockedStore_Release(&value, 3);
+       if(value != 3)
+       {
+               haveError = 1;
+               ILUnitFailMessage("ILInterlockedStore_Release doesn't store the 
correct value");
+       }
+       ptrValue = (void *)1;
+       ILInterlockedStorePointer(&ptrValue, (void *)2);
+       if(ptrValue != (void *)2)
+       {
+               haveError = 1;
+               ILUnitFailMessage("ILInterlockedStorePointer doesn't store the 
correct value");
+       }
+       ILInterlockedStorePointer_Release(&ptrValue, (void *)3);
+       if(ptrValue != (void *)3)
+       {
+               haveError = 1;
+               ILUnitFailMessage("ILInterlockedStorePointer_Release doesn't 
store the correct value");
+       }
+       if(haveError)
+       {
+               ILUnitFailEndMessages();
+       }
+}
+
 static void interlocked_exchange(void *arg)
 {
        volatile ILInt32 value;
@@ -1354,8 +1428,8 @@ static void _interlocked_thrash_incdec(void *arg)
        ref = (ILInt32 *)arg;
        for(counter = 0; counter < 1000000; ++counter)
        {
-               ILInterlockedIncrement(ref);
-               ILInterlockedDecrement(ref);
+               ILInterlockedIncrement_Acquire(ref);
+               ILInterlockedDecrement_Release(ref);
        }
 }
 
@@ -1367,8 +1441,8 @@ static void _interlocked_thrash_addsub(void *arg)
        ref = (ILInt32 *)arg;
        for(counter = 0; counter < 1000000; ++counter)
        {
-               ILInterlockedAdd(ref, 10);
-               ILInterlockedSub(ref, 10);
+               ILInterlockedAdd_Acquire(ref, 10);
+               ILInterlockedSub_Release(ref, 10);
        }
 }
 
@@ -3201,6 +3275,8 @@ void ILUnitRegisterTests(void)
         * Test the interlocked operations.
         */
        ILUnitRegisterSuite("Interlocked operations");
+       RegisterSimple(interlocked_load);
+       RegisterSimple(interlocked_store);
        RegisterSimple(interlocked_exchange);
        RegisterSimple(interlocked_exchange_pointers);
        RegisterSimple(interlocked_compare_and_exchange);

-----------------------------------------------------------------------

Summary of changes:
 ChangeLog                 |   26 ++
 support/Makefile.am       |    2 +
 support/interlocked.h     |  108 ++++++-
 support/interlocked_any.h |  724 ++++++++++++++++++++++++++++++++++++++++-
 support/interlocked_arm.h |  742 +++++++++++++++++++++++++++++++++++++++++-
 support/interlocked_ppc.h |  786 +++++++++++++++++++++++++++++++++++++++++++++
 support/interlocked_x86.h |  185 ++++++++++--
 tests/test_thread.c       |   84 +++++-
 8 files changed, 2599 insertions(+), 58 deletions(-)
 create mode 100644 support/interlocked_ppc.h


hooks/post-receive
-- 
DotGNU Portable.NET engine, compilers and tools (pnet)




reply via email to

[Prev in Thread] Current Thread [Next in Thread]