summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Ben Niu <niuben003@gmail.com>2022-03-18 13:10:10 -0700
committerGravatar GitHub <noreply@github.com>2022-03-18 16:10:10 -0400
commit4c015dbb49fcfac25899f3ba7da4be665b5f9aab (patch)
tree3c914a0c7e696557705fdab1b79f5f441d82d27d
parentc33f21f86a14216336b87d48e9b552a13985b2bc (diff)
Exclude unsupported x64 intrinsics from ARM64EC (#1135)
ARM64EC is a Microsoft-designed ARM64 ABI compatible with AMD64 applications on ARM64 Windows 11. The ARM64EC does not support _umul128 and __rdtsc as x64 intrinsics, though it provides inline function implementations for them, by emulation. Since the code already has portable code paths without using the intrinsics, instead of using the emulated intrinsic implementations, we use the said portable code paths for ARM64EC.
-rw-r--r--absl/base/internal/unscaledcycleclock.h2
-rw-r--r--absl/numeric/int128.h4
2 files changed, 3 insertions, 3 deletions
diff --git a/absl/base/internal/unscaledcycleclock.h b/absl/base/internal/unscaledcycleclock.h
index 07f867a6..a4351406 100644
--- a/absl/base/internal/unscaledcycleclock.h
+++ b/absl/base/internal/unscaledcycleclock.h
@@ -47,7 +47,7 @@
// The following platforms have an implementation of a hardware counter.
#if defined(__i386__) || defined(__x86_64__) || defined(__aarch64__) || \
defined(__powerpc__) || defined(__ppc__) || defined(__riscv) || \
- defined(_M_IX86) || defined(_M_X64)
+ defined(_M_IX86) || (defined(_M_X64) && !defined(_M_ARM64EC))
#define ABSL_HAVE_UNSCALED_CYCLECLOCK_IMPLEMENTATION 1
#else
#define ABSL_HAVE_UNSCALED_CYCLECLOCK_IMPLEMENTATION 0
diff --git a/absl/numeric/int128.h b/absl/numeric/int128.h
index c7ad96be..7a899eec 100644
--- a/absl/numeric/int128.h
+++ b/absl/numeric/int128.h
@@ -44,7 +44,7 @@
// builtin type. We need to make sure not to define operator wchar_t()
// alongside operator unsigned short() in these instances.
#define ABSL_INTERNAL_WCHAR_T __wchar_t
-#if defined(_M_X64)
+#if defined(_M_X64) && !defined(_M_ARM64EC)
#include <intrin.h>
#pragma intrinsic(_umul128)
#endif // defined(_M_X64)
@@ -980,7 +980,7 @@ inline uint128 operator*(uint128 lhs, uint128 rhs) {
// can be used for uint128 storage.
return static_cast<unsigned __int128>(lhs) *
static_cast<unsigned __int128>(rhs);
-#elif defined(_MSC_VER) && defined(_M_X64)
+#elif defined(_MSC_VER) && defined(_M_X64) && !defined(_M_ARM64EC)
uint64_t carry;
uint64_t low = _umul128(Uint128Low64(lhs), Uint128Low64(rhs), &carry);
return MakeUint128(Uint128Low64(lhs) * Uint128High64(rhs) +