[CRT/INTRIN_X86]
[reactos.git] / reactos / include / crt / mingw32 / intrin_x86.h
index 00ef94d..d9dcced 100644 (file)
@@ -70,6 +70,7 @@ extern "C" {
 #endif
 
 /*** memcopy must be memmove ***/
+void* memmove(void*, const void*, size_t);
 __INTRIN_INLINE void* memcpy(void* dest, const void* source, size_t num)
 {
     return memmove(dest, source, num);
@@ -149,6 +150,8 @@ __INTRIN_INLINE char _InterlockedCompareExchange8(volatile char * const Destinat
 __INTRIN_INLINE short _InterlockedCompareExchange16(volatile short * const Destination, const short Exchange, const short Comperand);
 __INTRIN_INLINE long _InterlockedCompareExchange(volatile long * const Destination, const long Exchange, const long Comperand);
 __INTRIN_INLINE void * _InterlockedCompareExchangePointer(void * volatile * const Destination, void * const Exchange, void * const Comperand);
+__INTRIN_INLINE char _InterlockedExchange8(volatile char * const Target, const char Value);
+__INTRIN_INLINE short _InterlockedExchange16(volatile short * const Target, const short Value);
 __INTRIN_INLINE long _InterlockedExchange(volatile long * const Target, const long Value);
 __INTRIN_INLINE void * _InterlockedExchangePointer(void * volatile * const Target, void * const Value);
 __INTRIN_INLINE long _InterlockedExchangeAdd16(volatile short * const Addend, const short Value);
@@ -186,16 +189,32 @@ __INTRIN_INLINE short _InterlockedCompareExchange16(volatile short * const Desti
        return __sync_val_compare_and_swap(Destination, Comperand, Exchange);
 }
 
+#ifndef __clang__
 __INTRIN_INLINE long _InterlockedCompareExchange(volatile long * const Destination, const long Exchange, const long Comperand)
 {
        return __sync_val_compare_and_swap(Destination, Comperand, Exchange);
 }
+#endif
 
 __INTRIN_INLINE void * _InterlockedCompareExchangePointer(void * volatile * const Destination, void * const Exchange, void * const Comperand)
 {
        return (void *)__sync_val_compare_and_swap(Destination, Comperand, Exchange);
 }
 
+__INTRIN_INLINE char _InterlockedExchange8(volatile char * const Target, const char Value)
+{
+       /* NOTE: __sync_lock_test_and_set would be an acquire barrier, so we force a full barrier */
+       __sync_synchronize();
+       return __sync_lock_test_and_set(Target, Value);
+}
+
+__INTRIN_INLINE short _InterlockedExchange16(volatile short * const Target, const short Value)
+{
+       /* NOTE: __sync_lock_test_and_set would be an acquire barrier, so we force a full barrier */
+       __sync_synchronize();
+       return __sync_lock_test_and_set(Target, Value);
+}
+
 __INTRIN_INLINE long _InterlockedExchange(volatile long * const Target, const long Value)
 {
        /* NOTE: __sync_lock_test_and_set would be an acquire barrier, so we force a full barrier */
@@ -214,7 +233,7 @@ __INTRIN_INLINE long long _InterlockedExchange64(volatile long long * const Targ
 
 __INTRIN_INLINE void * _InterlockedExchangePointer(void * volatile * const Target, void * const Value)
 {
-       /* NOTE: ditto */
+       /* NOTE: __sync_lock_test_and_set would be an acquire barrier, so we force a full barrier */
        __sync_synchronize();
        return (void *)__sync_lock_test_and_set(Target, Value);
 }
@@ -224,10 +243,12 @@ __INTRIN_INLINE long _InterlockedExchangeAdd16(volatile short * const Addend, co
        return __sync_fetch_and_add(Addend, Value);
 }
 
+#ifndef __clang__
 __INTRIN_INLINE long _InterlockedExchangeAdd(volatile long * const Addend, const long Value)
 {
        return __sync_fetch_and_add(Addend, Value);
 }
+#endif
 
 #if defined(_M_AMD64)
 __INTRIN_INLINE long long _InterlockedExchangeAdd64(volatile long long * const Addend, const long long Value)
@@ -302,6 +323,7 @@ __INTRIN_INLINE long long _InterlockedXor64(volatile long long * const value, co
 }
 #endif
 
+#ifndef __clang__
 __INTRIN_INLINE long _InterlockedDecrement(volatile long * const lpAddend)
 {
        return __sync_sub_and_fetch(lpAddend, 1);
@@ -311,6 +333,7 @@ __INTRIN_INLINE long _InterlockedIncrement(volatile long * const lpAddend)
 {
        return __sync_add_and_fetch(lpAddend, 1);
 }
+#endif
 
 __INTRIN_INLINE short _InterlockedDecrement16(volatile short * const lpAddend)
 {
@@ -340,6 +363,8 @@ __INTRIN_INLINE char _InterlockedCompareExchange8(volatile char * const Destinat
 __INTRIN_INLINE short _InterlockedCompareExchange16(volatile short * const Destination, const short Exchange, const short Comperand);
 __INTRIN_INLINE long _InterlockedCompareExchange(volatile long * const Destination, const long Exchange, const long Comperand);
 __INTRIN_INLINE void * _InterlockedCompareExchangePointer(void * volatile * const Destination, void * const Exchange, void * const Comperand);
+__INTRIN_INLINE char _InterlockedExchange8(volatile char * const Target, const char Value);
+__INTRIN_INLINE short _InterlockedExchange16(volatile short * const Target, const short Value);
 __INTRIN_INLINE long _InterlockedExchange(volatile long * const Target, const long Value);
 __INTRIN_INLINE void * _InterlockedExchangePointer(void * volatile * const Target, void * const Value);
 __INTRIN_INLINE long _InterlockedExchangeAdd16(volatile short * const Addend, const short Value);
@@ -390,6 +415,20 @@ __INTRIN_INLINE void * _InterlockedCompareExchangePointer(void * volatile * cons
        return retval;
 }
 
+__INTRIN_INLINE char _InterlockedExchange8(volatile char * const Target, const char Value)
+{
+       char retval = Value;
+       __asm__("xchgb %[retval], %[Target]" : [retval] "+r" (retval) : [Target] "m" (*Target) : "memory");
+       return retval;
+}
+
+__INTRIN_INLINE short _InterlockedExchange16(volatile short * const Target, const short Value)
+{
+       short retval = Value;
+       __asm__("xchgw %[retval], %[Target]" : [retval] "+r" (retval) : [Target] "m" (*Target) : "memory");
+       return retval;
+}
+
 __INTRIN_INLINE long _InterlockedExchange(volatile long * const Target, const long Value)
 {
        long retval = Value;
@@ -997,6 +1036,7 @@ __INTRIN_INLINE unsigned char _bittestandset(long * const a, const long b);
 __INTRIN_INLINE unsigned char _rotl8(unsigned char value, unsigned char shift);
 __INTRIN_INLINE unsigned short _rotl16(unsigned short value, unsigned char shift);
 __INTRIN_INLINE unsigned int _rotl(unsigned int value, int shift);
+__INTRIN_INLINE unsigned __int64 _rotl64(unsigned __int64 value, int shift);
 __INTRIN_INLINE unsigned int _rotr(unsigned int value, int shift);
 __INTRIN_INLINE unsigned char _rotr8(unsigned char value, unsigned char shift);
 __INTRIN_INLINE unsigned short _rotr16(unsigned short value, unsigned char shift);
@@ -1032,7 +1072,7 @@ __INTRIN_INLINE unsigned char _bittest(const long * const a, const long b)
        if(__builtin_constant_p(b))
                __asm__("bt %[b], %[a]; setb %b[retval]" : [retval] "=q" (retval) : [a] "mr" (*(a + (b / 32))), [b] "Ir" (b % 32));
        else
-               __asm__("bt %[b], %[a]; setb %b[retval]" : [retval] "=q" (retval) : [a] "mr" (*a), [b] "r" (b));
+               __asm__("bt %[b], %[a]; setb %b[retval]" : [retval] "=q" (retval) : [a] "m" (*a), [b] "r" (b));
 
        return retval;
 }
@@ -1045,7 +1085,7 @@ __INTRIN_INLINE unsigned char _bittest64(const __int64 * const a, const __int64
        if(__builtin_constant_p(b))
                __asm__("bt %[b], %[a]; setb %b[retval]" : [retval] "=q" (retval) : [a] "mr" (*(a + (b / 64))), [b] "Ir" (b % 64));
        else
-               __asm__("bt %[b], %[a]; setb %b[retval]" : [retval] "=q" (retval) : [a] "mr" (*a), [b] "r" (b));
+               __asm__("bt %[b], %[a]; setb %b[retval]" : [retval] "=q" (retval) : [a] "m" (*a), [b] "r" (b));
 
        return retval;
 }
@@ -1058,7 +1098,7 @@ __INTRIN_INLINE unsigned char _bittestandcomplement(long * const a, const long b
        if(__builtin_constant_p(b))
                __asm__("btc %[b], %[a]; setb %b[retval]" : [a] "+mr" (*(a + (b / 32))), [retval] "=q" (retval) : [b] "Ir" (b % 32));
        else
-               __asm__("btc %[b], %[a]; setb %b[retval]" : [a] "+mr" (*a), [retval] "=q" (retval) : [b] "r" (b));
+               __asm__("btc %[b], %[a]; setb %b[retval]" : [a] "+m" (*a), [retval] "=q" (retval) : [b] "r" (b));
 
        return retval;
 }
@@ -1070,7 +1110,7 @@ __INTRIN_INLINE unsigned char _bittestandreset(long * const a, const long b)
        if(__builtin_constant_p(b))
                __asm__("btr %[b], %[a]; setb %b[retval]" : [a] "+mr" (*(a + (b / 32))), [retval] "=q" (retval) : [b] "Ir" (b % 32));
        else
-               __asm__("btr %[b], %[a]; setb %b[retval]" : [a] "+mr" (*a), [retval] "=q" (retval) : [b] "r" (b));
+               __asm__("btr %[b], %[a]; setb %b[retval]" : [a] "+m" (*a), [retval] "=q" (retval) : [b] "r" (b));
 
        return retval;
 }
@@ -1082,7 +1122,7 @@ __INTRIN_INLINE unsigned char _bittestandset(long * const a, const long b)
        if(__builtin_constant_p(b))
                __asm__("bts %[b], %[a]; setb %b[retval]" : [a] "+mr" (*(a + (b / 32))), [retval] "=q" (retval) : [b] "Ir" (b % 32));
        else
-               __asm__("bts %[b], %[a]; setb %b[retval]" : [a] "+mr" (*a), [retval] "=q" (retval) : [b] "r" (b));
+               __asm__("bts %[b], %[a]; setb %b[retval]" : [a] "+m" (*a), [retval] "=q" (retval) : [b] "r" (b));
 
        return retval;
 }
@@ -1108,6 +1148,21 @@ __INTRIN_INLINE unsigned int _rotl(unsigned int value, int shift)
        return retval;
 }
 
+#ifdef _M_AMD64
+__INTRIN_INLINE unsigned __int64 _rotl64(unsigned __int64 value, int shift)
+{
+       unsigned __int64 retval;
+       __asm__("rolq %b[shift], %k[retval]" : [retval] "=rm" (retval) : "[retval]" (value), [shift] "Nc" (shift));
+       return retval;
+}
+#else
+__INTRIN_INLINE unsigned __int64 _rotl64(unsigned __int64 value, int shift)
+{
+    /* FIXME: this is probably not optimal */
+    return (value << shift) | (value >> (64 - shift));
+}
+#endif
+
 __INTRIN_INLINE unsigned int _rotr(unsigned int value, int shift)
 {
        unsigned long retval;