diff --git a/sdk/cmake/gcc.cmake b/sdk/cmake/gcc.cmake index 5a37db32dea..bc72c977773 100644 --- a/sdk/cmake/gcc.cmake +++ b/sdk/cmake/gcc.cmake @@ -160,6 +160,7 @@ endif() # Other if(ARCH STREQUAL "amd64") + add_compile_options(-mcx16) # Generate CMPXCHG16 add_definitions(-U_X86_ -UWIN32) elseif(ARCH STREQUAL "arm") add_definitions(-U_UNICODE -UUNICODE) diff --git a/sdk/cmake/msvc.cmake b/sdk/cmake/msvc.cmake index ede1597a454..e19e8e8b6ff 100644 --- a/sdk/cmake/msvc.cmake +++ b/sdk/cmake/msvc.cmake @@ -41,6 +41,9 @@ endif() add_compile_options(/GS-) if(CMAKE_C_COMPILER_ID STREQUAL "Clang") + if(ARCH STREQUAL "amd64") + add_compile_options(-mcx16) # Generate CMPXCHG16B + endif() set(CMAKE_CL_SHOWINCLUDES_PREFIX "Note: including file: ") endif() diff --git a/sdk/include/crt/mingw32/intrin_x86.h b/sdk/include/crt/mingw32/intrin_x86.h index 1bfae865d77..fa6a74f6407 100644 --- a/sdk/include/crt/mingw32/intrin_x86.h +++ b/sdk/include/crt/mingw32/intrin_x86.h @@ -699,6 +699,14 @@ __INTRIN_INLINE long long _InterlockedCompareExchange64(volatile long long * Des #endif /* (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) > 40100 && defined(__x86_64__) */ #endif /* !HAS_BUILTIN(_InterlockedCompareExchange64) */ +#if defined(__x86_64__) && !HAS_BUILTIN(_InterlockedCompareExchange128) +__INTRIN_INLINE unsigned char _InterlockedCompareExchange128(_Interlocked_operand_ __int64 volatile* Destination, __int64 ExchangeHigh, __int64 ExchangeLow, __int64* ComparandResult) +{ + __int64 xchg[2] = { ExchangeLow, ExchangeHigh }; + return __sync_bool_compare_and_swap((__uint128_t*)Destination, *((__uint128_t*)ComparandResult), *((__uint128_t*)xchg)); +} +#endif + #ifdef __i386__ __INTRIN_INLINE long _InterlockedAddLargeStatistic(volatile long long * Addend, long Value) {