From 8976caa3f066458b26ddb309e201d887fea49730 Mon Sep 17 00:00:00 2001 From: David Korth Date: Sat, 15 Jul 2023 10:13:20 -0400 Subject: [PATCH] Handle ARM64EC as ARM64. ARM64EC is a new ARM64 variant introduced in Windows 11 that uses an ABI similar to AMD64, which allows for better interoperability with emulated AMD64 applications. When enabled in MSVC, it defines _M_AMD64 and _M_ARM64EC, but not _M_ARM64, so we need to check for _M_ARM64EC. --- arch/arm/arm_features.c | 4 ++-- arch/arm/chunkset_neon.c | 2 +- arch/arm/crc32_acle.c | 2 +- arch/arm/neon_intrins.h | 4 ++-- cmake/detect-arch.c | 2 +- cmake/detect-arch.cmake | 2 +- cmake/detect-intrinsics.cmake | 4 ++-- configure | 4 ++-- fallback_builtins.h | 2 +- zbuild.h | 2 +- zendian.h | 2 +- 11 files changed, 15 insertions(+), 15 deletions(-) diff --git a/arch/arm/arm_features.c b/arch/arm/arm_features.c index 7394351f..8ef82000 100644 --- a/arch/arm/arm_features.c +++ b/arch/arm/arm_features.c @@ -45,7 +45,7 @@ static int arm_has_crc32() { } /* AArch64 has neon. */ -#if !defined(__aarch64__) && !defined(_M_ARM64) +#if !defined(__aarch64__) && !defined(_M_ARM64) && !defined(_M_ARM64EC) static inline int arm_has_neon() { #if defined(__linux__) && defined(ARM_AUXV_HAS_NEON) # ifdef HWCAP_ARM_NEON @@ -73,7 +73,7 @@ static inline int arm_has_neon() { #endif void Z_INTERNAL arm_check_features(struct arm_cpu_features *features) { -#if defined(__aarch64__) || defined(_M_ARM64) +#if defined(__aarch64__) || defined(_M_ARM64) || defined(_M_ARM64EC) features->has_neon = 1; /* always available */ #else features->has_neon = arm_has_neon(); diff --git a/arch/arm/chunkset_neon.c b/arch/arm/chunkset_neon.c index 7891eabd..f9a444b0 100644 --- a/arch/arm/chunkset_neon.c +++ b/arch/arm/chunkset_neon.c @@ -72,7 +72,7 @@ static inline chunk_t GET_CHUNK_MAG(uint8_t *buf, uint32_t *chunk_rem, uint32_t __msan_unpoison(buf + dist, 16 - dist); /* This version of table is only available on aarch64 */ -#if defined(_M_ARM64) || defined(__aarch64__) +#if defined(_M_ARM64) || defined(_M_ARM64EC) || defined(__aarch64__) uint8x16_t ret_vec = vld1q_u8(buf); uint8x16_t perm_vec = vld1q_u8(permute_table + lut_rem.idx); diff --git a/arch/arm/crc32_acle.c b/arch/arm/crc32_acle.c index a4e54d71..0c9b9b65 100644 --- a/arch/arm/crc32_acle.c +++ b/arch/arm/crc32_acle.c @@ -33,7 +33,7 @@ Z_INTERNAL uint32_t crc32_acle(uint32_t crc, const uint8_t *buf, size_t len) { buf4 = (const uint32_t *) buf; } -#if defined(__aarch64__) || defined(_M_ARM64) +#if defined(__aarch64__) || defined(_M_ARM64) || defined(_M_ARM64EC) if ((len >= sizeof(uint32_t)) && ((ptrdiff_t)buf & sizeof(uint32_t))) { c = __crc32w(c, *buf4++); len -= sizeof(uint32_t); diff --git a/arch/arm/neon_intrins.h b/arch/arm/neon_intrins.h index d6b57f64..478697a6 100644 --- a/arch/arm/neon_intrins.h +++ b/arch/arm/neon_intrins.h @@ -1,13 +1,13 @@ #ifndef ARM_NEON_INTRINS_H #define ARM_NEON_INTRINS_H -#ifdef _M_ARM64 +#if defined(_M_ARM64) || defined(_M_ARM64EC) # include #else # include #endif -#if defined(ARM_NEON) && !defined(__aarch64__) && !defined(_M_ARM64) +#if defined(ARM_NEON) && !defined(__aarch64__) && !defined(_M_ARM64) && !defined(_M_ARM64EC) /* Compatibility shim for the _high family of functions */ #define vmull_high_u8(a, b) vmull_u8(vget_high_u8(a), vget_high_u8(b)) #define vmlal_high_u8(a, b, c) vmlal_u8(a, vget_high_u8(b), vget_high_u8(c)) diff --git a/cmake/detect-arch.c b/cmake/detect-arch.c index 903ae5f2..92590182 100644 --- a/cmake/detect-arch.c +++ b/cmake/detect-arch.c @@ -12,7 +12,7 @@ #error archfound i686 // ARM -#elif defined(__aarch64__) || defined(__arm64__) || defined(_M_ARM64) +#elif defined(__aarch64__) || defined(__arm64__) || defined(_M_ARM64) || defined(_M_ARM64EC) #error archfound aarch64 #elif defined(__arm__) || defined(__arm) || defined(_M_ARM) || defined(__TARGET_ARCH_ARM) #if defined(__ARM64_ARCH_8__) || defined(__ARMv8__) || defined(__ARMv8_A__) diff --git a/cmake/detect-arch.cmake b/cmake/detect-arch.cmake index 706d13f8..dfdc6013 100644 --- a/cmake/detect-arch.cmake +++ b/cmake/detect-arch.cmake @@ -13,7 +13,7 @@ elseif(MSVC) set(ARCH "x86_64") elseif("${MSVC_C_ARCHITECTURE_ID}" STREQUAL "ARM" OR "${MSVC_C_ARCHITECTURE_ID}" STREQUAL "ARMV7") set(ARCH "arm") - elseif ("${MSVC_C_ARCHITECTURE_ID}" STREQUAL "ARM64") + elseif ("${MSVC_C_ARCHITECTURE_ID}" STREQUAL "ARM64" OR "${MSVC_C_ARCHITECTURE_ID}" STREQUAL "ARM64EC") set(ARCH "aarch64") endif() elseif(EMSCRIPTEN) diff --git a/cmake/detect-intrinsics.cmake b/cmake/detect-intrinsics.cmake index 9cbc5908..b0b0516e 100644 --- a/cmake/detect-intrinsics.cmake +++ b/cmake/detect-intrinsics.cmake @@ -176,7 +176,7 @@ macro(check_neon_compiler_flag) # Check whether compiler supports NEON flag set(CMAKE_REQUIRED_FLAGS "${NEONFLAG} ${NATIVEFLAG}") check_c_source_compiles( - "#ifdef _M_ARM64 + "#if defined(_M_ARM64) || defined(_M_ARM64EC) # include #else # include @@ -199,7 +199,7 @@ macro(check_neon_ld4_intrinsics) # Check whether compiler supports loading 4 neon vecs into a register range set(CMAKE_REQUIRED_FLAGS "${NEONFLAG}") check_c_source_compiles( - "#ifdef _M_ARM64 + "#if defined(_M_ARM64) || defined(_M_ARM64EC) # include #else # include diff --git a/configure b/configure index 8714590e..29a64bad 100755 --- a/configure +++ b/configure @@ -1200,7 +1200,7 @@ EOF check_neon_compiler_flag() { # Check whether -mfpu=neon is available on ARM processors. cat > $test.c << EOF -#ifdef _M_ARM64 +#if defined(_M_ARM64) || defined(_M_ARM64EC) # include #else # include @@ -1225,7 +1225,7 @@ check_neon_ld4_intrinsics() { fi fi cat > $test.c << EOF -#ifdef _M_ARM64 +#if defined(_M_ARM64) || defined(_M_ARM64EC) # include #else # include diff --git a/fallback_builtins.h b/fallback_builtins.h index 447f9ac1..6e8ed9f4 100644 --- a/fallback_builtins.h +++ b/fallback_builtins.h @@ -2,7 +2,7 @@ #define FALLBACK_BUILTINS_H #if defined(_MSC_VER) && !defined(__clang__) -#if defined(_M_IX86) || defined(_M_AMD64) || defined(_M_IA64) || defined(_M_ARM) || defined(_M_ARM64) +#if defined(_M_IX86) || defined(_M_AMD64) || defined(_M_IA64) || defined(_M_ARM) || defined(_M_ARM64) || defined(_M_ARM64EC) #include #ifdef X86_FEATURES diff --git a/zbuild.h b/zbuild.h index d9559591..2f9dd6b1 100644 --- a/zbuild.h +++ b/zbuild.h @@ -221,7 +221,7 @@ # elif defined(__i386__) || defined(__i486__) || defined(__i586__) || \ defined(__i686__) || defined(_X86_) || defined(_M_IX86) # define UNALIGNED_OK -# elif defined(__aarch64__) || defined(_M_ARM64) +# elif defined(__aarch64__) || defined(_M_ARM64) || defined(_M_ARM64EC) # if (defined(__GNUC__) && defined(__ARM_FEATURE_UNALIGNED)) || !defined(__GNUC__) # define UNALIGNED_OK # define UNALIGNED64_OK diff --git a/zendian.h b/zendian.h index 3fdb1304..28177a60 100644 --- a/zendian.h +++ b/zendian.h @@ -27,7 +27,7 @@ #elif defined(_WIN32) # define LITTLE_ENDIAN 1234 # define BIG_ENDIAN 4321 -# if defined(_M_IX86) || defined(_M_AMD64) || defined(_M_IA64) || defined (_M_ARM) || defined (_M_ARM64) +# if defined(_M_IX86) || defined(_M_AMD64) || defined(_M_IA64) || defined (_M_ARM) || defined (_M_ARM64) || defined (_M_ARM64EC) # define BYTE_ORDER LITTLE_ENDIAN # else # error Unknown endianness!