From 516197596087f7e94123bb4d84810fac1b052a3e Mon Sep 17 00:00:00 2001 From: Joe van den Heuvel Date: Mon, 2 Mar 2026 08:47:21 -0800 Subject: [PATCH] Fixed build configs and invoke for windows arm64 --- CMakeLists.txt | 2 +- build-scripts/runtime_lib.cmake | 6 +- build-scripts/warnings.cmake | 2 +- core/iwasm/common/iwasm_common.cmake | 107 ++++++++++++------ core/iwasm/common/wasm_runtime_common.c | 15 ++- product-mini/platforms/windows/CMakeLists.txt | 4 +- wamr-compiler/CMakeLists.txt | 6 +- 7 files changed, 98 insertions(+), 44 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3872b2c9c7..2826c28249 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -30,7 +30,7 @@ set (CMAKE_C_STANDARD 99) # "X86_64", "AMD_64", "X86_32", "AARCH64[sub]", "ARM[sub]", "THUMB[sub]", # "MIPS", "XTENSA", "RISCV64[sub]", "RISCV32[sub]" if (NOT DEFINED WAMR_BUILD_TARGET) - if (CMAKE_SYSTEM_PROCESSOR MATCHES "^(arm64|aarch64)") + if (CMAKE_SYSTEM_PROCESSOR MATCHES "^(arm64|aarch64|ARM64|AARCH64)") set (WAMR_BUILD_TARGET "AARCH64") elseif (CMAKE_SYSTEM_PROCESSOR STREQUAL "riscv64") set (WAMR_BUILD_TARGET "RISCV64") diff --git a/build-scripts/runtime_lib.cmake b/build-scripts/runtime_lib.cmake index bac81c4f2d..2a73bc6f17 100644 --- a/build-scripts/runtime_lib.cmake +++ b/build-scripts/runtime_lib.cmake @@ -188,7 +188,11 @@ file (GLOB header LIST (APPEND RUNTIME_LIB_HEADER_LIST ${header}) if (WAMR_BUILD_PLATFORM STREQUAL "windows") - enable_language (ASM_MASM) + if(WAMR_BUILD_TARGET STREQUAL "AARCH64") + enable_language (ASM_MARMASM) + else() + enable_language (ASM_MASM) + endif() else() enable_language (ASM) endif() diff --git a/build-scripts/warnings.cmake b/build-scripts/warnings.cmake index fbe6966ccc..77813b963d 100644 --- a/build-scripts/warnings.cmake +++ b/build-scripts/warnings.cmake @@ -4,7 +4,7 @@ # global additional warnings. if (MSVC) # warning level 4 - add_compile_options(/W4) + add_compile_options($<$:/W4>) else () # refer to https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html add_compile_options( diff --git a/core/iwasm/common/iwasm_common.cmake b/core/iwasm/common/iwasm_common.cmake index c3653f156c..fe030e37d0 100644 --- a/core/iwasm/common/iwasm_common.cmake +++ b/core/iwasm/common/iwasm_common.cmake @@ -4,12 +4,18 @@ set (IWASM_COMMON_DIR ${CMAKE_CURRENT_LIST_DIR}) include_directories (${IWASM_COMMON_DIR}) -if (MSVC AND WAMR_BUILD_PLATFORM STREQUAL "windows" AND WAMR_BUILD_TARGET MATCHES "AARCH64.*") - if (DEFINED ENV{VCToolsInstallDir}) +if (MSVC AND WAMR_BUILD_PLATFORM STREQUAL "windows" AND WAMR_BUILD_TARGET MATCHES "AARCH64.*" AND NOT WAMR_BUILD_WAMR_COMPILER) + if (CMAKE_ASM_MARMASM_COMPILER) + # Use the already detected assembler + set(_ARMASM64_EXE "${CMAKE_ASM_MARMASM_COMPILER}") + elseif (DEFINED ENV{VCToolsInstallDir} OR VCToolsInstallDir) + if (NOT VCToolsInstallDir) + set(VCToolsInstallDir "$ENV{VCToolsInstallDir}") + endif() # Detect host tool dir set(_ARMASM64_CANDIDATES - "$ENV{VCToolsInstallDir}/bin/HostX64/ARM64/armasm64.exe" - "$ENV{VCToolsInstallDir}/bin/HostARM64/arm64/armasm64.exe") + "${VCToolsInstallDir}bin/Hostx64/arm64/armasm64.exe" + "${VCToolsInstallDir}bin/Hostarm64/arm64/armasm64.exe") set(_ARMASM64_EXE "") foreach(_p IN LISTS _ARMASM64_CANDIDATES) if (EXISTS "${_p}") @@ -18,27 +24,42 @@ if (MSVC AND WAMR_BUILD_PLATFORM STREQUAL "windows" AND WAMR_BUILD_TARGET MATCHE endif() endforeach() if (_ARMASM64_EXE STREQUAL "") - message(FATAL_ERROR "armasm64.exe not found under VCToolsInstallDir") + message(FATAL_ERROR "armasm64.exe not found under VCToolsInstallDir: ${VCToolsInstallDir}") endif() + else() + message(FATAL_ERROR "VCToolsInstallDir is not defined. Please run from a Developer Command Prompt or specify armasm64.exe manually.") + endif() - # Wrapper without spaces to avoid quoting hell on NMake/cmd.exe - set(_WRAP "${CMAKE_BINARY_DIR}/armasm64_wrapper.bat") - file(WRITE "${_WRAP}" -"@echo off\r\n\"${_ARMASM64_EXE}\" %*\r\n") + # Wrapper without spaces to avoid quoting hell on NMake/cmd.exe + set(_WRAP "${CMAKE_BINARY_DIR}/armasm64_wrapper.bat") + file(WRITE "${_WRAP}" +"@echo off\r\n" +"setlocal enabledelayedexpansion\r\n" +"set ARGS=\r\n" +"for %%A in (%*) do (\r\n" +" if /I not \"%%~A\"==\"/experimental:c11atomics\" (\r\n" +" set ARGS=!ARGS! %%A\r\n" +" )\r\n" +")\r\n" +"\"${_ARMASM64_EXE}\" !ARGS!\r\n") - # Use wrapper as compiler (no spaces in path) - set(CMAKE_ASM_MASM_COMPILER - "${_WRAP}" - CACHE FILEPATH "" FORCE) + # Use wrapper as compiler (no spaces in path) + set(CMAKE_ASM_MASM_COMPILER + "${_WRAP}" + CACHE FILEPATH "" FORCE) - # Quote ONLY object and source (compiler path has no spaces now) - set(CMAKE_ASM_MASM_COMPILE_OBJECT - " /nologo -o \"\" \"\"" - CACHE STRING "" FORCE) + set(CMAKE_ASM_MARMASM_COMPILER + "${_WRAP}" + CACHE FILEPATH "" FORCE) - else() - message(FATAL_ERROR "VCToolsInstallDir is not defined. Please run from a Developer Command Prompt or specify armasm64.exe manually.") - endif() + # Quote ONLY object and source (compiler path has no spaces now) + set(CMAKE_ASM_MASM_COMPILE_OBJECT + " /nologo -o \"\" \"\"" + CACHE STRING "" FORCE) + + set(CMAKE_ASM_MARMASM_COMPILE_OBJECT + " /nologo -o \"\" \"\"" + CACHE STRING "" FORCE) endif() add_definitions(-DBH_MALLOC=wasm_runtime_malloc) @@ -61,7 +82,7 @@ if (CMAKE_OSX_ARCHITECTURES) endif() endif() -if (WAMR_BUILD_INVOKE_NATIVE_GENERAL EQUAL 1) +if (WAMR_BUILD_INVOKE_NATIVE_GENERAL EQUAL 1 AND NOT (MSVC AND WAMR_BUILD_PLATFORM STREQUAL "windows" AND WAMR_BUILD_TARGET MATCHES "AARCH64.*")) # Use invokeNative C version instead of asm code version # if WAMR_BUILD_INVOKE_NATIVE_GENERAL is explicitly set. # Note: @@ -117,15 +138,21 @@ elseif (WAMR_BUILD_TARGET MATCHES "AARCH64.*") if (NOT WAMR_BUILD_SIMD EQUAL 1) if (WAMR_BUILD_PLATFORM STREQUAL "windows") if (MSVC) - set (source_all ${c_source_all} ${IWASM_COMMON_DIR}/arch/invokeNative_armasm64.asm) - set(_WAMR_ARM64_MASM_SOURCES ${IWASM_COMMON_DIR}/arch/invokeNative_armasm64.asm) - set_source_files_properties(${_WAMR_ARM64_MASM_SOURCES} - PROPERTIES - LANGUAGE ASM_MASM - COMPILE_DEFINITIONS "" - INCLUDE_DIRECTORIES "" - COMPILE_OPTIONS "/nologo" + set(_WAMR_ARM64_MASM_SOURCE ${IWASM_COMMON_DIR}/arch/invokeNative_armasm64.asm) + set(_WAMR_ARM64_MASM_OBJ ${CMAKE_CURRENT_BINARY_DIR}/invokeNative_armasm64.obj) + add_custom_command( + OUTPUT ${_WAMR_ARM64_MASM_OBJ} + COMMAND ${CMAKE_ASM_MASM_COMPILER} /nologo -o "${_WAMR_ARM64_MASM_OBJ}" "${_WAMR_ARM64_MASM_SOURCE}" + DEPENDS ${_WAMR_ARM64_MASM_SOURCE} + COMMENT "Assembling invokeNative_armasm64.asm" + VERBATIM + ) + set_source_files_properties(${_WAMR_ARM64_MASM_OBJ} + PROPERTIES GENERATED TRUE EXTERNAL_OBJECT TRUE ) + set (source_all ${c_source_all} ${_WAMR_ARM64_MASM_OBJ}) + else () + set (source_all ${c_source_all} ${IWASM_COMMON_DIR}/arch/invokeNative_aarch64.s) endif () else () set (source_all ${c_source_all} ${IWASM_COMMON_DIR}/arch/invokeNative_aarch64.s) @@ -133,15 +160,21 @@ elseif (WAMR_BUILD_TARGET MATCHES "AARCH64.*") else() if (WAMR_BUILD_PLATFORM STREQUAL "windows") if (MSVC) - set (source_all ${c_source_all} ${IWASM_COMMON_DIR}/arch/invokeNative_armasm64_simd.asm) - set(_WAMR_ARM64_MASM_SOURCES_SIMD ${IWASM_COMMON_DIR}/arch/invokeNative_armasm64_simd.asm) - set_source_files_properties(${_WAMR_ARM64_MASM_SOURCES_SIMD} - PROPERTIES - LANGUAGE ASM_MASM - COMPILE_DEFINITIONS "" - INCLUDE_DIRECTORIES "" - COMPILE_OPTIONS "/nologo" + set(_WAMR_ARM64_MASM_SIMD_SOURCE ${IWASM_COMMON_DIR}/arch/invokeNative_armasm64_simd.asm) + set(_WAMR_ARM64_MASM_SIMD_OBJ ${CMAKE_CURRENT_BINARY_DIR}/invokeNative_armasm64_simd.obj) + add_custom_command( + OUTPUT ${_WAMR_ARM64_MASM_SIMD_OBJ} + COMMAND ${CMAKE_ASM_MASM_COMPILER} /nologo -o "${_WAMR_ARM64_MASM_SIMD_OBJ}" "${_WAMR_ARM64_MASM_SIMD_SOURCE}" + DEPENDS ${_WAMR_ARM64_MASM_SIMD_SOURCE} + COMMENT "Assembling invokeNative_armasm64_simd.asm" + VERBATIM + ) + set_source_files_properties(${_WAMR_ARM64_MASM_SIMD_OBJ} + PROPERTIES GENERATED TRUE EXTERNAL_OBJECT TRUE ) + set (source_all ${c_source_all} ${_WAMR_ARM64_MASM_SIMD_OBJ}) + else () + set (source_all ${c_source_all} ${IWASM_COMMON_DIR}/arch/invokeNative_aarch64_simd.s) endif () else () set (source_all ${c_source_all} ${IWASM_COMMON_DIR}/arch/invokeNative_aarch64_simd.s) diff --git a/core/iwasm/common/wasm_runtime_common.c b/core/iwasm/common/wasm_runtime_common.c index d0bd0b35ad..407dfe76f0 100644 --- a/core/iwasm/common/wasm_runtime_common.c +++ b/core/iwasm/common/wasm_runtime_common.c @@ -6026,8 +6026,15 @@ static V128FuncPtr invokeNative_V128 = (V128FuncPtr)(uintptr_t)invokeNative; /* NOLINTEND */ #if defined(_WIN32) || defined(_WIN32_) +#if defined(BUILD_TARGET_AARCH64) +/* Windows on ARM uses AAPCS64: 8 integer and 8 floating-point arg registers */ +#define MAX_REG_FLOATS 8 +#define MAX_REG_INTS 8 +#else /* else of defined(BUILD_TARGET_AARCH64) */ +/* Windows x64 calling convention: 4 integer and 4 floating-point arg registers */ #define MAX_REG_FLOATS 4 #define MAX_REG_INTS 4 +#endif /* end of defined(BUILD_TARGET_AARCH64) */ #else /* else of defined(_WIN32) || defined(_WIN32_) */ #define MAX_REG_FLOATS 8 #if defined(BUILD_TARGET_AARCH64) || defined(BUILD_TARGET_RISCV64_LP64D) \ @@ -6080,8 +6087,12 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr, #define fps ints #endif /* end of BUILD_TARGET_RISCV64_LP64 */ -#if defined(_WIN32) || defined(_WIN32_) || defined(BUILD_TARGET_RISCV64_LP64) - /* important difference in calling conventions */ +#if (defined(_WIN32) || defined(_WIN32_) || defined(BUILD_TARGET_RISCV64_LP64)) \ + && !defined(BUILD_TARGET_AARCH64) + /* important difference in calling conventions: on the Microsoft x64 ABI and + RISCV64_LP64 the float args share a register-slot counter with the int + args. Windows on ARM uses AAPCS64, which allocates integer and FP + registers from independent counters, so it needs its own n_fps. */ #define n_fps n_ints #else int n_fps = 0; diff --git a/product-mini/platforms/windows/CMakeLists.txt b/product-mini/platforms/windows/CMakeLists.txt index 326c2cf6cf..034149c7af 100644 --- a/product-mini/platforms/windows/CMakeLists.txt +++ b/product-mini/platforms/windows/CMakeLists.txt @@ -19,7 +19,9 @@ set(CMAKE_CXX_STANDARD 17) # Set WAMR_BUILD_TARGET, currently values supported: # "X86_64", "AMD_64", "X86_32", "AARCH64[sub]", "ARM[sub]", "THUMB[sub]", "MIPS", "XTENSA" if (NOT DEFINED WAMR_BUILD_TARGET) - if (CMAKE_SIZEOF_VOID_P EQUAL 8) + if (CMAKE_SYSTEM_PROCESSOR MATCHES "^(arm64|aarch64|ARM64|AARCH64)") + set (WAMR_BUILD_TARGET "AARCH64") + elseif (CMAKE_SIZEOF_VOID_P EQUAL 8) # Build as X86_64 by default in 64-bit platform set (WAMR_BUILD_TARGET "X86_64") elseif (CMAKE_SIZEOF_VOID_P EQUAL 4) diff --git a/wamr-compiler/CMakeLists.txt b/wamr-compiler/CMakeLists.txt index 7690417356..def98aad4c 100644 --- a/wamr-compiler/CMakeLists.txt +++ b/wamr-compiler/CMakeLists.txt @@ -17,7 +17,11 @@ if (NOT WAMR_BUILD_PLATFORM STREQUAL "windows") project (aot-compiler) else() project (aot-compiler C ASM CXX) - enable_language (ASM_MASM) + if (WAMR_BUILD_TARGET STREQUAL "AARCH64") + enable_language (ASM_MARMASM) + else() + enable_language (ASM_MASM) + endif() add_definitions(-DCOMPILING_WASM_RUNTIME_API=1) endif()