From: Jacek Caban jacek@codeweavers.com
Based on patch by Rémi Bernon. --- include/msvcrt/intrin.h | 4 ++++ include/winnt.h | 21 +++++++++++++++++++++ 2 files changed, 25 insertions(+)
diff --git a/include/msvcrt/intrin.h b/include/msvcrt/intrin.h index 178c85ff59e..35762483313 100644 --- a/include/msvcrt/intrin.h +++ b/include/msvcrt/intrin.h @@ -98,6 +98,10 @@ unsigned char _BitScanForward(unsigned long*,unsigned long); unsigned char _BitScanForward64(unsigned long*,unsigned __int64); #endif
+#if defined(_MSC_VER) && defined(__x86_64__) +unsigned __int64 _umul128(unsigned __int64, unsigned __int64, unsigned __int64*); +#endif + #ifdef __cplusplus } #endif diff --git a/include/winnt.h b/include/winnt.h index 31ee273d11d..223db81576f 100644 --- a/include/winnt.h +++ b/include/winnt.h @@ -7436,6 +7436,27 @@ static FORCEINLINE void YieldProcessor(void) #endif }
+#if defined(__x86_64__) +# if defined(__arm64ec__) +# define _umul128 UnsignedMultiply128 +# else +# define UnsignedMultiply128 _umul128 +# if defined(_MSC_VER) +DWORD64 _umul128(DWORD64,DWORD64,DWORD64*); +# pragma intrinsic(_umul128) +# endif +# endif +#endif + +#if (defined(__x86_64__) && !defined(_MSC_VER)) || defined(__aarch64__) || defined(__arm64ec__) +static FORCEINLINE DWORD64 UnsignedMultiply128( DWORD64 a, DWORD64 b, DWORD64 *hi ) +{ + unsigned __int128 v = (unsigned __int128)a * b; + *hi = v >> 64; + return (DWORD64)v; +} +#endif + #ifdef __cplusplus } #endif