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>
This commit is contained in:
Jacek Caban 2020-07-31 15:37:39 +02:00 committed by Alexandre Julliard
parent a6ae2b5c11
commit b59bf31f61
2 changed files with 36 additions and 22 deletions

View file

@ -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;

View file

@ -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