Selaa lähdekoodia

Implement invokeNative asm code for armasm64 assembler on ARM64 Windows (#4636)

* Implement invokeNative asm code for armasm64 assembler on ARM64 Windows
* Use more solid wrapper for armasm64 executable

Signed-off-by: Hiroshi Hatake <cosmo0920.oucc@gmail.com>
Hiroshi Hatake 3 kuukautta sitten
vanhempi
sitoutus
1b9542830e

+ 73 - 0
core/iwasm/common/arch/invokeNative_armasm64.asm

@@ -0,0 +1,73 @@
+        ; Copyright (C) 2019 Intel Corporation.  All rights reserved.
+        ; SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+
+        AREA    |.text|, CODE, READONLY, ALIGN=2
+
+        EXPORT  invokeNative
+
+; ------------------------ direct call path ------------------------
+
+call_func
+        mov     x20, x30                 ; save x30(lr)
+        blr     x19
+        mov     sp, x22                  ; restore sp saved before function call
+
+return_label
+        mov     x30,  x20                ; restore x30(lr)
+        ldp     x19, x20, [sp, #0x20]
+        ldp     x21, x22, [sp, #0x10]
+        ldp     x23, x24, [sp, #0x0]
+        add     sp, sp, #0x30
+        ret
+
+; ------------------------ stack-args path ------------------------
+
+handle_stack
+        ; Reserve aligned stack space for stack arguments and copy them
+        mov     x23, sp
+        bic     sp,  x23, #15            ; Ensure 16-byte alignment
+        lsl     x23, x21, #3             ; x23 = nstacks * 8
+        add     x23, x23, #15
+        bic     x23, x23, #15
+        sub     sp, sp, x23
+        mov     x23, sp
+
+copy_loop
+        cmp     x21, #0
+        b.eq    call_func                ; when done, branch back to call path
+        ldr     x24, [x20], #8
+        str     x24, [x23], #8
+        sub     x21, x21, #1
+        b       copy_loop
+
+; ------------------------ function entry ------------------------
+
+invokeNative
+        sub     sp, sp, #0x30
+        stp     x19, x20, [sp, #0x20]    ; save the registers
+        stp     x21, x22, [sp, #0x10]
+        stp     x23, x24, [sp, #0x0]
+
+        mov     x19, x0                  ; x19 = function ptr
+        mov     x20, x1                  ; x20 = argv
+        mov     x21, x2                  ; x21 = nstacks
+        mov     x22, sp                  ; save the sp before call function
+
+        ; Fill in floating-point registers
+        ldp     d0, d1, [x20], #16
+        ldp     d2, d3, [x20], #16
+        ldp     d4, d5, [x20], #16
+        ldp     d6, d7, [x20], #16
+
+        ; Fill integer registers
+        ldp     x0, x1, [x20], #16       ; x0 = argv[8] = exec_env, x1 = argv[9]
+        ldp     x2, x3, [x20], #16
+        ldp     x4, x5, [x20], #16
+        ldp     x6, x7, [x20], #16
+
+        ; Now x20 points to stack args
+        cmp     x21, #0
+        b.ne    handle_stack             ; backward: there are stack args
+        b       call_func                ; backward: no stack args
+
+        END

+ 73 - 0
core/iwasm/common/arch/invokeNative_armasm64_simd.asm

@@ -0,0 +1,73 @@
+        ; Copyright (C) 2019 Intel Corporation.  All rights reserved.
+        ; SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+
+        AREA    |.text|, CODE, READONLY, ALIGN=2
+
+        EXPORT  invokeNative
+
+; ------------------------ direct call path ------------------------
+
+call_func
+        mov     x20, x30                 ; save x30(lr)
+        blr     x19
+        mov     sp, x22                  ; restore sp saved before function call
+
+return_label
+        mov     x30,  x20                ; restore x30(lr)
+        ldp     x19, x20, [sp, #0x20]
+        ldp     x21, x22, [sp, #0x10]
+        ldp     x23, x24, [sp, #0x0]
+        add     sp, sp, #0x30
+        ret
+
+; ------------------------ stack-args path ------------------------
+
+handle_stack
+        ; Reserve aligned stack space for stack arguments and copy them
+        mov     x23, sp
+        bic     sp,  x23, #15            ; Ensure 16-byte alignment
+        lsl     x23, x21, #3             ; x23 = nstacks * 8
+        add     x23, x23, #15
+        bic     x23, x23, #15
+        sub     sp, sp, x23
+        mov     x23, sp
+
+copy_loop
+        cmp     x21, #0
+        b.eq    call_func                ; when done, branch back to call path
+        ldr     x24, [x20], #8
+        str     x24, [x23], #8
+        sub     x21, x21, #1
+        b       copy_loop
+
+; ------------------------ function entry ------------------------
+
+invokeNative
+        sub     sp, sp, #0x30
+        stp     x19, x20, [sp, #0x20]    ; save the registers
+        stp     x21, x22, [sp, #0x10]
+        stp     x23, x24, [sp, #0x0]
+
+        mov     x19, x0                  ; x19 = function ptr
+        mov     x20, x1                  ; x20 = argv
+        mov     x21, x2                  ; x21 = nstacks
+        mov     x22, sp                  ; save the sp before call function
+
+        ; Fill in floating-point registers
+        ; v0 = argv[0], v1 = argv[1], v2 = argv[2], v3 = argv[3]
+        ld1     {v0.2D, v1.2D, v2.2D, v3.2D}, [x20], #64
+        ; v4 = argv[4], v5 = argv[5], v6 = argv[6], v7 = argv[7]
+        ld1     {v4.2D, v5.2D, v6.2D, v7.2D}, [x20], #64
+
+        ; Fill integer registers
+        ldp     x0, x1, [x20], #16       ; x0 = argv[8] = exec_env, x1 = argv[9]
+        ldp     x2, x3, [x20], #16
+        ldp     x4, x5, [x20], #16
+        ldp     x6, x7, [x20], #16
+
+        ; Now x20 points to stack args
+        cmp     x21, #0
+        b.ne    handle_stack             ; (backward) there are stack args
+        b       call_func                ; (backward) no stack args
+
+        END

+ 66 - 2
core/iwasm/common/iwasm_common.cmake

@@ -4,6 +4,42 @@
 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})
+    # Detect host tool dir
+    set(_ARMASM64_CANDIDATES
+        "$ENV{VCToolsInstallDir}/bin/HostX64/ARM64/armasm64.exe"
+        "$ENV{VCToolsInstallDir}/bin/HostARM64/arm64/armasm64.exe")
+    set(_ARMASM64_EXE "")
+    foreach(_p IN LISTS _ARMASM64_CANDIDATES)
+      if (EXISTS "${_p}")
+        set(_ARMASM64_EXE "${_p}")
+        break()
+      endif()
+    endforeach()
+    if (_ARMASM64_EXE STREQUAL "")
+      message(FATAL_ERROR "armasm64.exe not found under VCToolsInstallDir")
+    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")
+
+    # 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
+        "<CMAKE_ASM_MASM_COMPILER> /nologo -o \"<OBJECT>\" \"<SOURCE>\""
+        CACHE STRING "" FORCE)
+
+  else()
+    message(FATAL_ERROR "VCToolsInstallDir is not defined. Please run from a Developer Command Prompt or specify armasm64.exe manually.")
+  endif()
+endif()
 
 add_definitions(-DBH_MALLOC=wasm_runtime_malloc)
 add_definitions(-DBH_FREE=wasm_runtime_free)
@@ -79,9 +115,37 @@ elseif (WAMR_BUILD_TARGET MATCHES "THUMB.*")
   endif ()
 elseif (WAMR_BUILD_TARGET MATCHES "AARCH64.*")
   if (NOT WAMR_BUILD_SIMD EQUAL 1)
-    set (source_all ${c_source_all} ${IWASM_COMMON_DIR}/arch/invokeNative_aarch64.s)
+    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"
+        )
+      endif ()
+    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_simd.s)
+    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"
+        )
+      endif ()
+    else ()
+      set (source_all ${c_source_all} ${IWASM_COMMON_DIR}/arch/invokeNative_aarch64_simd.s)
+    endif ()
   endif()
 elseif (WAMR_BUILD_TARGET STREQUAL "MIPS")
   set (source_all ${c_source_all} ${IWASM_COMMON_DIR}/arch/invokeNative_mips.s)