From 9e6221529b168114c87caead6d6b4ea1bdee07b8 Mon Sep 17 00:00:00 2001 From: Richard Lau Date: Wed, 8 Feb 2023 14:13:24 +0100 Subject: [PATCH] deps: cherry-pick Windows ARM64 fix for openssl Original commit message: rsa: add msvc intrinsic for non x64 platforms _umul128() is x86_64 (x64) only, while __umulh() works everywhere, but doesn't generate optimal code on x64 PR-URL: https://github.com/nodejs/node/pull/46566 Refs: https://github.com/openssl/openssl/pull/20244 Refs: https://mta.openssl.org/pipermail/openssl-announce/2023-February/000251.html Reviewed-By: Richard Lau Reviewed-By: Beth Griggs --- deps/openssl/openssl/crypto/bn/rsa_sup_mul.c | 24 +++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/deps/openssl/openssl/crypto/bn/rsa_sup_mul.c b/deps/openssl/openssl/crypto/bn/rsa_sup_mul.c index acafefd5febf70..c027ba411e2808 100644 --- a/deps/openssl/openssl/crypto/bn/rsa_sup_mul.c +++ b/deps/openssl/openssl/crypto/bn/rsa_sup_mul.c @@ -110,12 +110,34 @@ static ossl_inline void _mul_limb(limb_t *hi, limb_t *lo, limb_t a, limb_t b) *lo = (limb_t)t; } #elif (BN_BYTES == 8) && (defined _MSC_VER) -/* https://learn.microsoft.com/en-us/cpp/intrinsics/umul128?view=msvc-170 */ +# if defined(_M_X64) +/* + * on x86_64 (x64) we can use the _umul128 intrinsic to get one `mul` + * instruction to get both high and low 64 bits of the multiplication. + * https://learn.microsoft.com/en-us/cpp/intrinsics/umul128?view=msvc-140 + */ +#include #pragma intrinsic(_umul128) static ossl_inline void _mul_limb(limb_t *hi, limb_t *lo, limb_t a, limb_t b) { *lo = _umul128(a, b, hi); } +# elif defined(_M_ARM64) || defined (_M_IA64) +/* + * We can't use the __umulh() on x86_64 as then msvc generates two `mul` + * instructions; so use this more portable intrinsic on platforms that + * don't support _umul128 (like aarch64 (ARM64) or ia64) + * https://learn.microsoft.com/en-us/cpp/intrinsics/umulh?view=msvc-140 + */ +#include +static ossl_inline void _mul_limb(limb_t *hi, limb_t *lo, limb_t a, limb_t b) +{ + *lo = a * b; + *hi = __umulh(a, b); +} +# else +# error Only x64, ARM64 and IA64 supported. +# endif /* defined(_M_X64) */ #else /* * if the compiler doesn't have either a 128bit data type nor a "return