[CRT] Implement _InterlockedCompareExchange128 intrinsic for GCC
authorTimo Kreuzer <timo.kreuzer@reactos.org>
Wed, 31 Aug 2022 18:52:09 +0000 (20:52 +0200)
committerTimo Kreuzer <timo.kreuzer@reactos.org>
Thu, 24 Nov 2022 19:17:58 +0000 (21:17 +0200)
sdk/cmake/gcc.cmake
sdk/cmake/msvc.cmake
sdk/include/crt/mingw32/intrin_x86.h

index 5a37db3..bc72c97 100644 (file)
@@ -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)
index ede1597..e19e8e8 100644 (file)
@@ -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()
 
index 1bfae86..fa6a74f 100644 (file)
@@ -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)
 {