Porting from x86/x86_64 to ARM64EC or Pure Native ARM64#

This chapter describes the changes required to build existing x86 or x86_64 source code as ARM64EC, followed by the additional considerations that apply when targeting pure native ARM64.

Porting to ARM64EC#

The following sections describe header file usage, ARM64EC ABI requirements, minimum tooling requirements, predefined compilation variables, and the intrinsics support available for ARM64EC builds.

Header File Usage#

Avoid including x86/x86_64-specific headers such as xmmintrin.h. Instead, use the generic umbrella header intrin.h, which is automatically included when you use windows.h.

ARM64EC ABI Requirements#

The ARM64EC ABI mandates that all function addresses be 4-byte aligned. Existing unported assembly code may need align 4 directives to meet this requirement.

Minimum Tooling Requirements#

At a minimum, use Windows SDK 26100 and Visual Studio 2022 version 17.14. These versions include recent fixes for ARM64EC and native ARM64 support. Microsoft’s documented Arm64EC floor is Visual Studio 2022 17.3 or later and a Windows 11 SDK; 17.14 is the recommended bar here for recent compiler fixes. For the best code generation and performance results, use the latest supported Visual Studio toolset, Windows SDK, and build tools. Updates can include architecture-specific compiler optimizations and fixes.

Predefined Compilation Variables#

When compiling as ARM64EC, the compiler predefines _M_AMD64 and _M_ARM64EC. It does not define _M_ARM64, even though the target is ARM-based.

Intrinsics Support#

The soft intrinsics library in the Windows SDK supports SSE intrinsics. By default, AVX intrinsics and 256-bit types such as __m256 do not compile.

Enhanced Intrinsics Library#

A more complete soft intrinsics library is available at softintrin-avx2. It adds support for AVX and AVX2 intrinsics, provides faster implementations of SSE intrinsics, and adds missing type support for 256-bit operations.

Porting to Pure Native ARM64#

This process builds on the same rules used for ARM64EC porting, with a few additional considerations:

Compiler Settings#

Use the compiler switch /volatile:ms to enforce x86-style behavior for volatile variables. Without this switch, race conditions may occur because of relaxed memory ordering in native ARM64. ARM64EC already defaults to MS volatile semantics.

Intrinsics Support#

Soft intrinsics support is not enabled by default for native ARM64 builds. To enable AVX and AVX2 intrinsics and improve SSE performance, use the enhanced soft intrinsics library.

Performance Impact of Store-Only Atomics#

Certain store-only atomic instructions such as STADD may execute as far atomics, leading to significant performance penalties. This behavior differs from previous Windows on ARM CPUs, where such penalties were not observed. A recommended alternative is to use the load versions of these atomics; for example, replace STADD with LDADD to avoid far atomic execution and improve performance.