Module: wine Branch: master Commit: b59bf31f61ed93a0c2f166af0af0c0d557d7466b URL: https://source.winehq.org/git/wine.git/?a=commit;h=b59bf31f61ed93a0c2f166af0...
Author: Jacek Caban jacek@codeweavers.com Date: Fri Jul 31 15:37:39 2020 +0200
ntdll: Move InterlockedCompareExchange128 support to winnt.h.
Also properly declare intrinsic on msvc.
Signed-off-by: Jacek Caban jacek@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/ntdll/rtl.c | 26 ++++---------------------- include/winnt.h | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 22 deletions(-)
diff --git a/dlls/ntdll/rtl.c b/dlls/ntdll/rtl.c index c32c63a880..ca4fea8420 100644 --- a/dlls/ntdll/rtl.c +++ b/dlls/ntdll/rtl.c @@ -98,24 +98,6 @@ static const int hex_table[] = { -1, 10, 11, 12, 13, 14, 15 /* 0x60-0x66 */ };
-#if defined(_WIN64) && !defined(_MSC_VER) -static inline unsigned char _InterlockedCompareExchange128(__int64 *dest, __int64 xchg_high, __int64 xchg_low, __int64 *compare) -{ - unsigned char ret; -#ifdef __x86_64__ - __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) ); -#else - ret = __sync_bool_compare_and_swap( (__int128 *)dest, *(__int128 *)compare, - ((__int128)xchg_high << 64) | xchg_low ); -#endif - return ret; -} -#endif - /* * resource functions */ @@ -1627,7 +1609,7 @@ PSLIST_ENTRY WINAPI RtlInterlockedFlushSList(PSLIST_HEADER list) { old = *list; new.Header16.Sequence = old.Header16.Sequence + 1; - } while (!_InterlockedCompareExchange128((__int64 *)list, new.s.Region, new.s.Alignment, (__int64 *)&old)); + } while (!InterlockedCompareExchange128((__int64 *)list, new.s.Region, new.s.Alignment, (__int64 *)&old)); return (SLIST_ENTRY *)((ULONG_PTR)old.Header16.NextEntry << 4); #else if (!list->s.Next.Next) return NULL; @@ -1657,7 +1639,7 @@ PSLIST_ENTRY WINAPI RtlInterlockedPushEntrySList(PSLIST_HEADER list, PSLIST_ENTR entry->Next = (SLIST_ENTRY *)((ULONG_PTR)old.Header16.NextEntry << 4); new.Header16.Depth = old.Header16.Depth + 1; new.Header16.Sequence = old.Header16.Sequence + 1; - } while (!_InterlockedCompareExchange128((__int64 *)list, new.s.Region, new.s.Alignment, (__int64 *)&old)); + } while (!InterlockedCompareExchange128((__int64 *)list, new.s.Region, new.s.Alignment, (__int64 *)&old)); return (SLIST_ENTRY *)((ULONG_PTR)old.Header16.NextEntry << 4); #else new.s.Next.Next = entry; @@ -1697,7 +1679,7 @@ PSLIST_ENTRY WINAPI RtlInterlockedPopEntrySList(PSLIST_HEADER list) { } __ENDTRY - } while (!_InterlockedCompareExchange128((__int64 *)list, new.s.Region, new.s.Alignment, (__int64 *)&old)); + } while (!InterlockedCompareExchange128((__int64 *)list, new.s.Region, new.s.Alignment, (__int64 *)&old)); #else do { @@ -1736,7 +1718,7 @@ PSLIST_ENTRY WINAPI RtlInterlockedPushListSListEx(PSLIST_HEADER list, PSLIST_ENT new.Header16.Depth = old.Header16.Depth + count; new.Header16.Sequence = old.Header16.Sequence + 1; last->Next = (SLIST_ENTRY *)((ULONG_PTR)old.Header16.NextEntry << 4); - } while (!_InterlockedCompareExchange128((__int64 *)list, new.s.Region, new.s.Alignment, (__int64 *)&old)); + } while (!InterlockedCompareExchange128((__int64 *)list, new.s.Region, new.s.Alignment, (__int64 *)&old)); return (SLIST_ENTRY *)((ULONG_PTR)old.Header16.NextEntry << 4); #else new.s.Next.Next = first; diff --git a/include/winnt.h b/include/winnt.h index e1cf78420a..6aef97595d 100644 --- a/include/winnt.h +++ b/include/winnt.h @@ -6769,6 +6769,38 @@ static inline BOOLEAN BitScanReverse(DWORD *index, DWORD mask)
#endif
+#ifdef _WIN64 + +#if defined(_MSC_VER) + +#define InterlockedCompareExchange128 _InterlockedCompareExchange128 +static inline unsigned char _InterlockedCompareExchange128(__int64 *dest, __int64 xchg_high, __int64 xchg_low, __int64 *compare); +#pragma intrinsic(_InterlockedCompareExchange128) + +#elif defined(__x86_64__) + +static inline unsigned char InterlockedCompareExchange128(__int64 *dest, __int64 xchg_high, __int64 xchg_low, __int64 *compare) +{ + 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; +} + +#elif defined(__GNUC__) + +static inline unsigned char InterlockedCompareExchange128(__int64 *dest, __int64 xchg_high, __int64 xchg_low, __int64 *compare) +{ + return __sync_bool_compare_and_swap( (__int128 *)dest, *(__int128 *)compare, ((__int128)xchg_high << 64) | xchg_low ); +} + +#endif + +#endif /* _WIN64 */ + #ifdef __cplusplus } #endif