Module: wine Branch: master Commit: 894dbe835336c45a48b2e3468a478c62899d1fd8 URL: https://source.winehq.org/git/wine.git/?a=commit;h=894dbe835336c45a48b2e3468...
Author: Jacek Caban jacek@codeweavers.com Date: Fri Feb 26 15:56:13 2021 +0100
include: Use GCC-style InterlockedCompareExchange128 implementation on clang in MSVC mode.
It's not yet supported on aarch64.
Signed-off-by: Jacek Caban jacek@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
include/winnt.h | 60 ++++++++++++++++++++++++++++----------------------------- 1 file changed, 30 insertions(+), 30 deletions(-)
diff --git a/include/winnt.h b/include/winnt.h index e19f515eddb..7973960bf21 100644 --- a/include/winnt.h +++ b/include/winnt.h @@ -6918,9 +6918,6 @@ static inline BOOLEAN BitScanReverse(DWORD *index, DWORD mask) #pragma intrinsic(_InterlockedAnd) #pragma intrinsic(_InterlockedCompareExchange) #pragma intrinsic(_InterlockedCompareExchange64) -#ifdef _WIN64 -#pragma intrinsic(_InterlockedCompareExchange128) -#endif #pragma intrinsic(_InterlockedExchange) #pragma intrinsic(_InterlockedExchangeAdd) #pragma intrinsic(_InterlockedIncrement) @@ -6932,9 +6929,6 @@ static inline BOOLEAN BitScanReverse(DWORD *index, DWORD mask) long _InterlockedAnd(long volatile *,long); long _InterlockedCompareExchange(long volatile*,long,long); long long _InterlockedCompareExchange64(long long volatile*,long long,long long); -#ifdef _WIN64 -unsigned char _InterlockedCompareExchange128(volatile __int64 *, __int64, __int64, __int64 *); -#endif long _InterlockedDecrement(long volatile*); short _InterlockedDecrement16(short volatile*); long _InterlockedExchange(long volatile*,long); @@ -6958,13 +6952,6 @@ static FORCEINLINE LONGLONG WINAPI InterlockedCompareExchange64( LONGLONG volati return _InterlockedCompareExchange64( (long long volatile *)dest, xchg, compare ); }
-#ifdef _WIN64 -static FORCEINLINE unsigned char WINAPI InterlockedCompareExchange128( volatile __int64 *dest, __int64 xchg_high, __int64 xchg_low, __int64 *compare ) -{ - return _InterlockedCompareExchange128( dest, xchg_high, xchg_low, compare ); -} -#endif - static FORCEINLINE LONG WINAPI InterlockedExchange( LONG volatile *dest, LONG val ) { return _InterlockedExchange( (long volatile *)dest, val ); @@ -7082,23 +7069,6 @@ static FORCEINLINE LONGLONG WINAPI InterlockedCompareExchange64( LONGLONG volati return __sync_val_compare_and_swap( dest, compare, xchg ); }
-#ifdef _WIN64 -static FORCEINLINE unsigned char InterlockedCompareExchange128( volatile __int64 *dest, __int64 xchg_high, __int64 xchg_low, __int64 *compare ) -{ -#ifdef __x86_64__ - unsigned char ret; - __asm__ __volatile__( "lock cmpxchg16b %0; setz %b2" - : "=m" (dest[0]), "=m" (dest[1]), "=r" (ret), - "=a" (compare[0]), "=d" (compare[1]) - : "m" (dest[0]), "m" (dest[1]), "3" (compare[0]), "4" (compare[1]), - "c" (xchg_high), "b" (xchg_low) ); - return ret; -#else - return __sync_bool_compare_and_swap( (__int128 *)dest, *(__int128 *)compare, ((__int128)xchg_high << 64) | xchg_low ); -#endif -} -#endif - static FORCEINLINE LONG WINAPI InterlockedExchange( LONG volatile *dest, LONG val ) { LONG ret; @@ -7165,6 +7135,36 @@ static FORCEINLINE void MemoryBarrier(void)
#endif /* __GNUC__ */
+#ifdef _WIN64 +#if defined(_MSC_VER) && !defined(__clang__) + +#pragma intrinsic(_InterlockedCompareExchange128) +unsigned char _InterlockedCompareExchange128(volatile __int64 *, __int64, __int64, __int64 *); +static FORCEINLINE unsigned char WINAPI InterlockedCompareExchange128( volatile __int64 *dest, __int64 xchg_high, __int64 xchg_low, __int64 *compare ) +{ + return _InterlockedCompareExchange128( dest, xchg_high, xchg_low, compare ); +} + +#else + +static FORCEINLINE unsigned char InterlockedCompareExchange128( volatile __int64 *dest, __int64 xchg_high, __int64 xchg_low, __int64 *compare ) +{ +#ifdef __x86_64__ + unsigned char ret; + __asm__ __volatile__( "lock cmpxchg16b %0; setz %b2" + : "=m" (dest[0]), "=m" (dest[1]), "=r" (ret), + "=a" (compare[0]), "=d" (compare[1]) + : "m" (dest[0]), "m" (dest[1]), "3" (compare[0]), "4" (compare[1]), + "c" (xchg_high), "b" (xchg_low) ); + return ret; +#else + return __sync_bool_compare_and_swap( (__int128 *)dest, *(__int128 *)compare, ((__int128)xchg_high << 64) | xchg_low ); +#endif +} + +#endif +#endif + static FORCEINLINE void YieldProcessor(void) { #ifdef __GNUC__