# HG changeset patch # User Tassilo Philipp # Date 1608916059 -3600 # Node ID 451299d50c1a72b4c98af9c86d5c1ce30848f705 # Parent fa78490381f3dc35f4f114bdacdc6a66f77f4697 - windows arm64 support (dyncall, dyncallback, cmake support for armasm64), thanks Bernhard Urban-Forster! - minor cleanups diff -r fa78490381f3 -r 451299d50c1a AUTHORS --- a/AUTHORS Sat Dec 19 20:02:08 2020 +0100 +++ b/AUTHORS Fri Dec 25 18:07:39 2020 +0100 @@ -3,4 +3,5 @@ Olivier Chafik Erik Mackdanz Masanori Mitsugi +Bernhard Urban-Forster diff -r fa78490381f3 -r 451299d50c1a CMakeLists.txt --- a/CMakeLists.txt Sat Dec 19 20:02:08 2020 +0100 +++ b/CMakeLists.txt Fri Dec 25 18:07:39 2020 +0100 @@ -3,7 +3,8 @@ # Description: DynCall Project cmake files # License: # -# Copyright (c) 2010 Daniel Adler +# Copyright (c) 2010-2020 Daniel Adler +# 2020 armasm64 support: Bernhard Urban-Forster # # Permission to use, copy, modify, and distribute this software for any # purpose with or without fee is hereby granted, provided that the above @@ -44,16 +45,71 @@ include(CheckCCompilerFlag) check_c_compiler_flag("-fPIC -Werror" COMPILER_HAS_FPIC) + +# compile_asm(TARGET target ASM_FILES file1 [file2 ...] OUTPUT_OBJECTS [variableName]) +# CMake does not support the ARM or ARM64 assemblers on Windows when using the +# MSBuild generator. +# credit to dotnet/runtime: +# https://github.com/dotnet/runtime/blob/e98fb61d8b4bb6687ccddead861d8b140751647b/eng/native/functions.cmake#L173-L207 +function(compile_asm) + set(options "") + set(oneValueArgs TARGET OUTPUT_OBJECTS) + set(multiValueArgs ASM_FILES) + cmake_parse_arguments(COMPILE_ASM "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGV}) + + set (ASSEMBLED_OBJECTS "") + + foreach(ASM_FILE ${COMPILE_ASM_ASM_FILES}) + get_filename_component(name ${ASM_FILE} NAME_WE) + # Produce object file where CMake would store .obj files for an OBJECT library. + # ex: artifacts\obj\coreclr\windows.arm64.Debug\src\vm\wks\cee_wks.dir\Debug\AsmHelpers.obj + set (OBJ_FILE "${CMAKE_CURRENT_BINARY_DIR}/${COMPILE_ASM_TARGET}.dir/${CMAKE_CFG_INTDIR}/${name}.obj") + + # Need to compile asm file using custom command as include directories are not provided to asm compiler + add_custom_command(OUTPUT ${OBJ_FILE} + COMMAND "${CMAKE_ASM_COMPILER}" ${ASM_INCLUDE_DIRECTORIES} -o ${OBJ_FILE} ${ASM_FILE} + DEPENDS ${ASM_FILE} + COMMENT "Assembling ${ASM_FILE} ---> \"${CMAKE_ASM_COMPILER}\" ${ASM_INCLUDE_DIRECTORIES} -o ${OBJ_FILE} ${ASM_FILE}"+ COMMENT "Assembling ${ASM_FILE} ---> \"${CMAKE_ASM_COMPILER}\" ${ASM_INCLUDE_DIRECTORIES} -o ${OBJ_FILE} ${ASM_FILE}") + + # mark obj as source that does not require compile + set_source_files_properties(${OBJ_FILE} PROPERTIES EXTERNAL_OBJECT TRUE) + + # Add the generated OBJ in the dependency list so that it gets consumed during linkage + list(APPEND ASSEMBLED_OBJECTS ${OBJ_FILE}) + endforeach() + + set(${COMPILE_ASM_OUTPUT_OBJECTS} ${ASSEMBLED_OBJECTS} PARENT_SCOPE) +endfunction() + + if(MSVC) - enable_language(ASM_MASM) - #if(CMAKE_SIZEOF_VOID_P MATCHES 8) - # set(CMAKE_ASM_COMPILER "ml64") - #else() - # set(CMAKE_ASM_COMPILER "ml") - #endif() - #set(CMAKE_ASM_COMPILER_ARG1 "/c") - #set(CMAKE_ASM_MASM_SOURCE_FILE_EXTENSIONS asm) - #set(CMAKE_ASM_MASM_COMPILE_OBJECT " /c /Fo ") + if("${CMAKE_GENERATOR_PLATFORM}" MATCHES "ARM64") + # Explicitly specify the assembler to be used for Arm64 compile + file(TO_CMAKE_PATH "$ENV{VCToolsInstallDir}\\bin\\HostX64\\arm64\\armasm64.exe" CMAKE_ASM_COMPILER) + # file(TO_CMAKE_PATH "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Enterprise\\VC\\Tools\\MSVC\\14.28.29333\\bin\\HostX64\\arm64\\armasm64.exe" CMAKE_ASM_COMPILER) + + set(CMAKE_ASM_MASM_COMPILER ${CMAKE_ASM_COMPILER}) + message("CMAKE_ASM_MASM_COMPILER explicitly set to: ${CMAKE_ASM_MASM_COMPILER}") + # Enable generic assembly compilation to avoid CMake generate VS proj files that explicitly + # use ml[64].exe as the assembler. + enable_language(ASM) + set(CMAKE_ASM_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreaded "") + set(CMAKE_ASM_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDLL "") + set(CMAKE_ASM_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDebug "") + set(CMAKE_ASM_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDebugDLL "") + set(CMAKE_ASM_COMPILE_OBJECT " -o ") + else() + enable_language(ASM_MASM) + + #if(CMAKE_SIZEOF_VOID_P MATCHES 8) + # set(CMAKE_ASM_COMPILER "ml64") + #else() + # set(CMAKE_ASM_COMPILER "ml") + #endif() + #set(CMAKE_ASM_COMPILER_ARG1 "/c") + #set(CMAKE_ASM_MASM_SOURCE_FILE_EXTENSIONS asm) + #set(CMAKE_ASM_MASM_COMPILE_OBJECT " /c /Fo ") + endif() elseif(CMAKE_COMPILER_IS_GNUCC OR "${CMAKE_C_COMPILER_ID}" STREQUAL "Intel") if(COMPILER_HAS_FPIC) # when used in shared libraries, -fPIC is required by several architectures diff -r fa78490381f3 -r 451299d50c1a ChangeLog --- a/ChangeLog Sat Dec 19 20:02:08 2020 +0100 +++ b/ChangeLog Fri Dec 25 18:07:39 2020 +0100 @@ -1,7 +1,10 @@ This file lists bigger/noteworthy changes, only... + Version 1.2 (upcoming) + dyncall: + o windows arm64 support (thanks Bernhard!) o extended signature with more chars for calling convention switching (only for modes that coexist on a platform with other conventions) o made "formatted" call interface use calling convention signature chars @@ -9,6 +12,7 @@ o removed some unnecessary headers (only contained internal used forward declarations) o support clang's integrated as (didn't build on non-Darwin PPC32 platforms) dyncallback: + o windows arm64 support (thanks Bernhard!) o support clang's integrated as (didn't build on non-Darwin PPC32 platforms) dynload: o fix to build with musl libc @@ -16,14 +20,19 @@ o manual now specifying calling convention signature chars bindings: o python: Python 3 support, Python 2 unicode support, added get_path function, changing - 'Z' conversions to only immutable types and 'p' to mutable types (and handles), bytearray - support, support to specify calling convention + 'Z' conversions to only immutable types and 'p' to mutable types (and handles), support + passing None for 'Z' and 'p', bytearray support, support to specify calling convention o shell: can reference own executable now and support for more calling conventions o shell: syscall support tests: o extended callf testcode to test callconv mode switch signature chars (including syscalls) + o robustness fixes (thanks Bernhard!) +buildsys: + o cmake support of armasm64 on windows (thanks Bernhard!) + Version 1.1 (2020/01/11) + dyncall: o support for soft-float MIPS o32 & n64 (big- and little-endian, each) o x64 System V syscall support @@ -53,7 +62,9 @@ o default ./configure: FreeBSD/mips*hf needed -mhard-float compiler flag set explicitly o better MacOS Mojave support in ./configure (Mojave dropped i386 builds) + Version 1.0 (2018/04/23) + dyncall: o PPC64 single-precision float fixes for more than 13 float args (thanks Masanori Mitsugi!) o fixed potential buffer overrun on ARM64 @@ -97,12 +108,15 @@ buildsys: o cmake: made to work on systems without C++ compiler (thanks Franklin Mathieu) + Version 0.9 (2015/12/31) + dyncall: o ARM64 support (AAPCS64 on Linux & Apple's derived version on iOS) o armhf calling convention support for ARM32 o PPC64 support, including syscalls (thanks Masanori Mitsugi!) - o introduced dcArgF and dcVArgF for flexible/convenient argument binding (works like dcCallF/dcVCallF but without the function call) + o introduced dcArgF and dcVArgF for flexible/convenient argument binding (works like + dcCallF/dcVCallF but without the function call) o using -fPIC by default for FreeBSD o PPC32 linux syscall support o fixed return value errors for ARM32 on some platforms (e.g. freebsd/arm32, nintendo ds); arm & thumb mode @@ -133,7 +147,9 @@ o moved to hg o moved bindings to own repository + Version 0.8 (2014/03/24) + buildsys: o big simplification make-based build system, no more distinct GNU and BSD makefiles anymore o new, much simpler ./configure for new make-based build-system @@ -163,7 +179,9 @@ o rbdc: fixed and extended ruby bindings o shdc: renamed shell binding to shdc and added feature to list shared-objects' symbols + Version 0.7 (2012/01/02) + architecture: o added subproject: portasm - portable (GNU AS,+Apple and MASM) assembly framework o added subproject: autovar - predefined macro framework (was dyncall_macros.h) @@ -231,7 +249,9 @@ o improved dir name portability (renamed plain_c++ -> plain_cxx) o renamed *.cpp -> *.cc files (OpenBSD/Sun make has no implicit rules for cpp) + Version 0.6 (2010/09/25) + building: o new build systems: CMake and Plan9's mk o buildsys/gmake tool chain update: pcc and iphone sdk @@ -253,7 +273,9 @@ o plain: split "plain" test up in C and C++ part o callbacksuite: added multiple configuration support for callback_suite + Version 0.5 (2010/02/01) + o renamed arm9 stuff to arm32 o added non-EABI ABI for arm32 (before, EABI was the default implementation) o added dyncallback support for x64/windows (thanks Olivier), x64/darwin, arm32/arm, arm32/thumb @@ -264,7 +286,9 @@ o added new tests callback_plain and calback_suite o added Haiku/BeOS support + Version 0.4 (2009/07/06) + o added 'doc' makefile target for coherency and ease of use o fixed nmake buildfiles and configure.bat (were out of date and wrong) o test suite clean up (GNUmake, BSDmake): @@ -280,19 +304,25 @@ o added: test cases for alloc_wx, thunk o updated Documentation + Version 0.3 (2009/01/17) + o added Linux PPC32 support o added ARM THUMB mode support o cosmetic changes, documentation updated o bugfix: on cygwin exported C symbols in GNU as are prefixed with '_' now. o removed scons build support + Version 0.2 (2008/05/18) + o added scons build support o configure variables all prefix CONFIG_* now o configure variable INSTALL_DIR changed to INSTALL_PREFIX o configure (shell version) option "--prefix" changed to "--prefix=" + Version 0.1 (2008/01/23) + o initial release diff -r fa78490381f3 -r 451299d50c1a autovar/autovar_ARCH.h --- a/autovar/autovar_ARCH.h Sat Dec 19 20:02:08 2020 +0100 +++ b/autovar/autovar_ARCH.h Fri Dec 25 18:07:39 2020 +0100 @@ -48,7 +48,7 @@ # if defined(__thumb__) # define ARCH_THUMB # endif -#elif defined(__aarch64__) || defined(__arm64) || defined(__arm64__) +#elif defined(_M_ARM64) || defined(__aarch64__) || defined(__arm64) || defined(__arm64__) # define ARCH_ARM64 #elif defined(__sh__) # define ARCH_SH diff -r fa78490381f3 -r 451299d50c1a doc/README.Windows --- a/doc/README.Windows Sat Dec 19 20:02:08 2020 +0100 +++ b/doc/README.Windows Fri Dec 25 18:07:39 2020 +0100 @@ -23,6 +23,7 @@ executed mistakenly for re-generation of test C code) timestamps are wrong; workaround: run "svn revert -R ." several times. + Build using buildsys/gmake and MinGW or Cygwin: ----------------------------------------------- @@ -62,3 +63,12 @@ BROKEN: Rules to assemble MASM files are still missing. + +Build ARM64 using CMake and Visual Studio 2019: +----------------------------------------------- + + vcvarsall.bat amd64_arm64 + mkdir build && cd build + cmake -G "Visual Studio 16 2019" -A ARM64 .. + cmake --build . --config Release + diff -r fa78490381f3 -r 451299d50c1a dyncall/CMakeLists.txt --- a/dyncall/CMakeLists.txt Sat Dec 19 20:02:08 2020 +0100 +++ b/dyncall/CMakeLists.txt Fri Dec 25 18:07:39 2020 +0100 @@ -20,7 +20,10 @@ if(MSVC) if(CMAKE_SIZEOF_VOID_P MATCHES 4) - set(ASM_SRC dyncall_call_x86_generic_masm.asm) + set(ASM_SRC dyncall_call_x86_generic_masm.asm) + elseif("${CMAKE_GENERATOR_PLATFORM}" MATCHES "ARM64") + set(ASM_SRC ${CMAKE_SOURCE_DIR}/dyncall/dyncall_call_arm64_masm.asm) + compile_asm(TARGET dyncall_s ASM_FILES ${ASM_SRC} OUTPUT_OBJECTS ASM_SRC) else() set(ASM_SRC dyncall_call_x64_generic_masm.asm) endif() diff -r fa78490381f3 -r 451299d50c1a dyncall/dyncall_call_arm64.S --- a/dyncall/dyncall_call_arm64.S Sat Dec 19 20:02:08 2020 +0100 +++ b/dyncall/dyncall_call_arm64.S Fri Dec 25 18:07:39 2020 +0100 @@ -6,7 +6,7 @@ Description: Call Kernel for ARM 64-bit Architecture (aka ARM64, AArch64) License: - Copyright (c) 2015-2018 Daniel Adler , + Copyright (c) 2015-2020 Daniel Adler , Tassilo Philipp Permission to use, copy, modify, and distribute this software for any @@ -25,7 +25,8 @@ -#include "../portasm/portasm-arm.S" +#include "../portasm/portasm-arm64.S" +BEGIN_ASM /* ============================================================================ DynCall Call Kernel for ARM 64-bit ARM Architecture @@ -33,10 +34,10 @@ C Interface: dcCall_arm64 (DCpointer target, DCpointer data, DCsize size, DCfloat* regdata); - This Call Kernel was tested on Debian/qemu-debootstrap arm64 jessie. + This Call Kernel was tested on Debian/qemu-debootstrap arm64 jessie and on win64. */ -.text +TEXTAREA // // DynCall Back-End arm64 // @@ -48,7 +49,7 @@ GLOBAL_C(dcCall_arm64) ENTRY_C(dcCall_arm64) -.align 2 +ALIGN(2) // input: // x0: target (address of target) @@ -81,17 +82,17 @@ mov x5, x1 // x5: read pointer = data mov x6, sp // x6: write pointer = sp -.next: +LABELDEF(next) cmp x4, x2 - b.ge .done + b.ge LABELUSE(done) ldp x7, x9, [x5], #16 // get pair from data stp x7, x9, [x6], #16 // put to stack add x4, x4, 16 // advance 16 bytes - b .next + b LABELUSE(next) -.done: +LABELDEF(done) // rescue temp int registers @@ -122,105 +123,7 @@ ret -#if 0 - - - -// epilog: - - add sp, x28, 0 // remove call record - - ret - - // -- OLD: - - str x27, [sp, 16] // use 1 local var (size) - - - ldr q0, [x3,#0 ] - ldr q1, [x3,#8 ] - ldr q2, [x3,#16] - ldr q3, [x3,#24] - ldr q4, [x3,#32] - ldr q5, [x3,#40] - ldr q6, [x3,#48] - ldr q7, [x3,#56] - - ldr d8, [x3,#32] - ldr d9, [x3,#36] - ldr d10, [x3,#40] - ldr d11, [x3,#44] - ldr d12, [x3,#48] - ldr d13, [x3,#52] - ldr d14, [x3,#56] - ldr d15, [x3,#60] - - - // load float ( 16 x 32-bit ) - ldr s0, [x3,#0 ] - ldr s1, [x3,#4 ] - ldr s2, [x3,#8 ] - ldr s3, [x3,#12] - ldr s4, [x3,#16] - ldr s5, [x3,#20] - ldr s6, [x3,#24] - ldr s7, [x3,#28] - ldr s8, [x3,#32] - ldr s9, [x3,#36] - ldr s10, [x3,#40] - ldr s11, [x3,#44] - ldr s12, [x3,#48] - ldr s13, [x3,#52] - ldr s14, [x3,#56] - ldr s15, [x3,#60] - - // call - - blr x0 - - // epilog - - ldp x29, x30, [sp], 32 - ret - - // stack copy - - sub sp, sp, x2 // decrement stack by size (x2) - eor x3, x3, x3 // x3 = counter, set to zero +END_PROC +END_ASM -// .next: - ldr x4, [x1, x3] // x4 = 64-bit stack data - str x4, [sp, x3] // store to stack - add x3, x3, #8 - cmp x3, x2 - blt .next - - - // rescue int registers - - mov x9 , x0 // x9 = code ptr - mov x10, x2 - - // load int ( 8 x 64-bit ) - - ldr x0, [sp, #0] - ldr x1, [sp, #8] - ldr x2, [sp, #16] - ldr x3, [sp, #24] - ldr x4, [sp, #32] - ldr x5, [sp, #40] - ldr x6, [sp, #48] - ldr x7, [sp, #56] - - // call - - blr x9 - - // epilog - - ldp x29, x30, [sp], 32 - ret -#endif - - diff -r fa78490381f3 -r 451299d50c1a dyncall/dyncall_call_arm64_masm.asm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dyncall/dyncall_call_arm64_masm.asm Fri Dec 25 18:07:39 2020 +0100 @@ -0,0 +1,42 @@ +; auto-generated by gen-masm.sh + AREA .text, CODE, ARM64 + EXPORT dcCall_arm64 +dcCall_arm64 PROC + stp x29, x30, [sp, #-16]! + mov x29, sp + ldr d0, [x3,#0 ] + ldr d1, [x3,#8 ] + ldr d2, [x3,#16] + ldr d3, [x3,#24] + ldr d4, [x3,#32] + ldr d5, [x3,#40] + ldr d6, [x3,#48] + ldr d7, [x3,#56] + sub sp, sp, x2 + eor x4, x4, x4 + mov x5, x1 + mov x6, sp +dcCall_arm64_next + cmp x4, x2 + b.ge dcCall_arm64_done + ldp x7, x9, [x5], #16 + stp x7, x9, [x6], #16 + add x4, x4, 16 + b dcCall_arm64_next +dcCall_arm64_done + mov x9 , x0 + add x10, x3, 64 + ldr x0, [x10, #0] + ldr x1, [x10, #8] + ldr x2, [x10, #16] + ldr x3, [x10, #24] + ldr x4, [x10, #32] + ldr x5, [x10, #40] + ldr x6, [x10, #48] + ldr x7, [x10, #56] + blr x9 + mov sp, x29 + ldp x29, x30, [sp], 16 + ret + ENDP + END diff -r fa78490381f3 -r 451299d50c1a dyncall/dyncall_callvm_arm64.c --- a/dyncall/dyncall_callvm_arm64.c Sat Dec 19 20:02:08 2020 +0100 +++ b/dyncall/dyncall_callvm_arm64.c Fri Dec 25 18:07:39 2020 +0100 @@ -26,6 +26,7 @@ #include "dyncall_callvm_arm64.h" #include "dyncall_alloc.h" +#include "dyncall_macros.h" void dcCall_arm64(DCpointer target, DCpointer data, DCsize size, DCpointer regdata); @@ -74,7 +75,7 @@ p->f++; } else { dcVecAppend(&p->mVecHead, &x, sizeof(DCfloat)); - dcVecSkip(&p->mVecHead, 4); /* align to 8-bytes */ + dcVecSkip(&p->mVecHead, 4); /* align to 8-bytes */ } } @@ -130,16 +131,69 @@ , NULL /* callStruct */ }; +#ifdef DC__OS_Win64 +/* for variadic, allocate arguments to an imaginary stack, where the first 64 bytes of + the stack are loaded into x0-x7, and any remaining arguments on the stack */ + +static void var_bool (DCCallVM* in_p, DCbool x) { a_i64( in_p, ((DClonglong) x) ); } +static void var_char (DCCallVM* in_p, DCchar x) { a_i64( in_p, ((DClonglong) x) ); } +static void var_short (DCCallVM* in_p, DCshort x) { a_i64( in_p, ((DClonglong) x) ); } +static void var_int (DCCallVM* in_p, DCint x) { a_i64( in_p, ((DClonglong) x) ); } +static void var_long (DCCallVM* in_p, DClong x) { a_i64( in_p, ((DClonglong) x) ); } +static void var_pointer (DCCallVM* in_p, DCpointer x) { a_i64( in_p, ((DClonglong) x) ); } +static void var_float (DCCallVM* in_p, DCfloat x) { + DClonglong tmp = 0; + memcpy(&tmp, &x, sizeof(DCfloat)); + a_i64(in_p, tmp); +} +static void var_double (DCCallVM* in_p, DCdouble x) { + a_i64(in_p, *(DClonglong *)&x); +} + +DCCallVM_vt vt_arm64_win_varargs = +{ + &deinit +, &reset +, &mode +, &var_bool +, &var_char +, &var_short +, &var_int +, &var_long +, &a_i64 +, &var_float +, &var_double +, &var_pointer +, NULL /* argStruct */ +, (DCvoidvmfunc*) &call +, (DCboolvmfunc*) &call +, (DCcharvmfunc*) &call +, (DCshortvmfunc*) &call +, (DCintvmfunc*) &call +, (DClongvmfunc*) &call +, (DClonglongvmfunc*) &call +, (DCfloatvmfunc*) &call +, (DCdoublevmfunc*) &call +, (DCpointervmfunc*) &call +, NULL /* callStruct */ +}; +#endif + static void mode(DCCallVM* in_self, DCint mode) { DCCallVM_arm64* self = (DCCallVM_arm64*)in_self; DCCallVM_vt* vt; switch(mode) { + case DC_CALL_C_ELLIPSIS: + case DC_CALL_C_ELLIPSIS_VARARGS: +#ifdef DC__OS_Win64 + vt = &vt_arm64_win_varargs; + break; +#endif /* if not win64, use below */ + case DC_CALL_SYS_DEFAULT: case DC_CALL_C_DEFAULT: case DC_CALL_C_ARM64: - case DC_CALL_C_ELLIPSIS: - case DC_CALL_C_ELLIPSIS_VARARGS: vt = &vt_arm64; break; default: diff -r fa78490381f3 -r 451299d50c1a dyncall/dyncall_callvm_arm64_apple.c --- a/dyncall/dyncall_callvm_arm64_apple.c Sat Dec 19 20:02:08 2020 +0100 +++ b/dyncall/dyncall_callvm_arm64_apple.c Fri Dec 25 18:07:39 2020 +0100 @@ -238,6 +238,7 @@ DCCallVM_vt* vt; switch(mode) { + case DC_CALL_SYS_DEFAULT: case DC_CALL_C_DEFAULT: case DC_CALL_C_ARM64: case DC_CALL_C_ELLIPSIS: diff -r fa78490381f3 -r 451299d50c1a dyncall/dyncall_macros.h --- a/dyncall/dyncall_macros.h Sat Dec 19 20:02:08 2020 +0100 +++ b/dyncall/dyncall_macros.h Fri Dec 25 18:07:39 2020 +0100 @@ -189,7 +189,7 @@ # define DC__Arch_MIPS #elif defined(__arm__) # define DC__Arch_ARM -#elif defined(__aarch64__) || defined(__arm64) || defined(__arm64__) +#elif defined(_M_ARM64) || defined(__aarch64__) || defined(__arm64) || defined(__arm64__) # define DC__Arch_ARM64 #elif defined(__sh__) # define DC__Arch_SuperH diff -r fa78490381f3 -r 451299d50c1a dyncallback/CMakeLists.txt --- a/dyncallback/CMakeLists.txt Sat Dec 19 20:02:08 2020 +0100 +++ b/dyncallback/CMakeLists.txt Fri Dec 25 18:07:39 2020 +0100 @@ -23,6 +23,9 @@ if(MSVC) if(CMAKE_SIZEOF_VOID_P MATCHES 4) set(ASM_SRC dyncall_callback_x86_masm.asm) + elseif("${CMAKE_GENERATOR_PLATFORM}" MATCHES "ARM64") + set(ASM_SRC ${CMAKE_SOURCE_DIR}/dyncallback/dyncall_callback_arm64_masm.asm) + compile_asm(TARGET dyncallback_s ASM_FILES ${ASM_SRC} OUTPUT_OBJECTS ASM_SRC) else() set(ASM_SRC dyncall_callback_x64_masm.asm) endif() diff -r fa78490381f3 -r 451299d50c1a dyncallback/dyncall_callback_arm64.S --- a/dyncallback/dyncall_callback_arm64.S Sat Dec 19 20:02:08 2020 +0100 +++ b/dyncallback/dyncall_callback_arm64.S Fri Dec 25 18:07:39 2020 +0100 @@ -6,7 +6,7 @@ Description: Callback Thunk - Implementation for ARM64 / ARMv8 / AAPCS64 License: - Copyright (c) 2015-2018 Daniel Adler , + Copyright (c) 2015-2020 Daniel Adler , Tassilo Philipp Permission to use, copy, modify, and distribute this software for any @@ -22,6 +22,10 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include "../portasm/portasm-arm64.S" +BEGIN_ASM + // struct DCCallback // type off size // ---------|------|------ @@ -29,11 +33,11 @@ // handler | 32 | 8 // userdata | 40 | 8 -#include "../portasm/portasm-arm.S" +TEXTAREA -.align 4 GLOBAL_C(dcCallbackThunkEntry) ENTRY_C(dcCallbackThunkEntry) +ALIGN(4) // input: // x9: DCCallback* pcb @@ -71,8 +75,8 @@ stp d0, d1, [x11, #64] stp d2, d3, [x11, #80] - stp d4, d5, [x11, #96] - stp d6, d7, [x11, #112] + stp d4, d5, [x11, #96] + stp d6, d7, [x11, #112] eor x12, x12, x12 stp x10,x12,[x11, #128] // sp=sp, i=0, f=0 @@ -97,15 +101,20 @@ and w0, w0, #255 cmp w0, 'f' - b.eq .retf + b.eq LABELUSE(retf) cmp w0, 'd' - b.eq .retf + b.eq LABELUSE(retf) -.reti: +LABELDEF(reti) ldr x0, [x29, #184] - b .ret -.retf: + b LABELUSE(ret) +LABELDEF(retf) ldr d0, [x29, #184] -.ret: +LABELDEF(ret) ldp x29, x30, [sp], #208 ret + + +END_PROC +END_ASM + diff -r fa78490381f3 -r 451299d50c1a dyncallback/dyncall_callback_arm64_masm.asm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dyncallback/dyncall_callback_arm64_masm.asm Fri Dec 25 18:07:39 2020 +0100 @@ -0,0 +1,39 @@ + AREA .text, CODE, ARM64 + EXPORT dcCallbackThunkEntry +dcCallbackThunkEntry PROC + mov x10, sp + stp x29, x30, [sp, #-208 ]! + mov x29, sp + add x11, x29 , #16 + stp x0, x1, [x11, #0 ] + stp x2, x3, [x11, #16] + stp x4, x5, [x11, #32] + stp x6, x7, [x11, #48] + stp d0, d1, [x11, #64] + stp d2, d3, [x11, #80] + stp d4, d5, [x11, #96] + stp d6, d7, [x11, #112] + eor x12, x12, x12 + stp x10,x12,[x11, #128] + str x12, [x11, #144] + mov x0 , x9 + add x1 , x29 , #16 + add x2 , x29 , #184 + ldr x3 , [x9 , #40] + ldr x11, [x9 , #32] + blr x11 + and w0, w0, #255 + cmp w0, 'f' + b.eq dcCall_arm64_retf + cmp w0, 'd' + b.eq dcCall_arm64_retf +dcCall_arm64_reti + ldr x0, [x29, #184] + b dcCall_arm64_ret +dcCall_arm64_retf + ldr d0, [x29, #184] +dcCall_arm64_ret + ldp x29, x30, [sp], #208 + ret + ENDP + END diff -r fa78490381f3 -r 451299d50c1a portasm/portasm-arm64.S --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/portasm/portasm-arm64.S Fri Dec 25 18:07:39 2020 +0100 @@ -0,0 +1,58 @@ +/* + + Package: dyncall + Library: portasm + File: portasm/portasm-arm.S + Description: + License: + + Copyright (c) 2020 Bernhard Urban-Forster + + Permission to use, copy, modify, and distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +*/ + + + +#define BEGIN_ASM +#include "../autovar/autovar_OS.h" + +#if defined(GEN_MASM) +#define TEXTAREA AREA .text, CODE, ARM64 +#define ALIGN(X) +#define LABELDEF(X) dcCall_arm64_##X +#define LABELUSE(X) dcCall_arm64_##X +#define END_PROC ENDP +#define END_ASM END +#define GLOBAL_C(X) EXPORT X +#define ENTRY_C(X) X PROC + +#else + +#define TEXTAREA .text +#define ALIGN(X) .align 2 +#define LABELDEF(X) .##X##: +#define LABELUSE(X) .##X +#define END_PROC +#define END_ASM + +#if defined(OS_Darwin) +#define GLOBAL_C(X) .globl _##X +#define ENTRY_C(X) _##X: +#else +#define GLOBAL_C(X) .globl X +#define ENTRY_C(X) X: +#endif + +#endif + diff -r fa78490381f3 -r 451299d50c1a test/callf/main.c --- a/test/callf/main.c Sat Dec 19 20:02:08 2020 +0100 +++ b/test/callf/main.c Fri Dec 25 18:07:39 2020 +0100 @@ -6,7 +6,7 @@ Description: License: - Copyright (c) 2007-2018 Daniel Adler , + Copyright (c) 2007-2020 Daniel Adler , Tassilo Philipp Permission to use, copy, modify, and distribute this software for any @@ -113,6 +113,8 @@ /* arg binding then call using 'formatted' API */ dcReset(vm); + /* reset calling convention too */ + dcMode(vm, DC_CALL_C_DEFAULT); printf("\nargf iii)i then call: "); dcArgF(vm, "iii)i", 1, 2, 3); r = r && dcCallInt(vm, (void*)&vf_iii); @@ -132,7 +134,7 @@ dcArgF(vm, "ffiffiffi", 1.f, 2.f, 3, 4.f, 5.f, 6, 7.f, 8.f, 9); r = r && dcCallInt(vm, (void*)&vf_ffiffiffi); -#if defined(DC_UNIX) +#if defined(DC_UNIX) && !defined(DC__OS_MacOSX) && !defined(DC__OS_SunOS) /* testing syscall using calling convention prefix - not available on all platforms */ dcReset(vm); printf("\ncallf _$iZi)i"); diff -r fa78490381f3 -r 451299d50c1a test/thunk/test_thunk.c --- a/test/thunk/test_thunk.c Sat Dec 19 20:02:08 2020 +0100 +++ b/test/thunk/test_thunk.c Fri Dec 25 18:07:39 2020 +0100 @@ -6,7 +6,7 @@ Description: License: - Copyright (c) 2011-2018 Daniel Adler , + Copyright (c) 2011-2020 Daniel Adler , Tassilo Philipp Permission to use, copy, modify, and distribute this software for any @@ -116,7 +116,19 @@ { dcTest_initPlatform(); +#if defined(DC__OS_MacOSX) + /* Memory access errors can result into SIGBUS */ + signal(SIGBUS, segv_handler); + + struct sigaction sigAct; + sigfillset(&(sigAct.sa_mask)); + sigAct.sa_sigaction = segv_handler; + /* we need to enable SA_ONSTACK which allows faulting on the stack */ + sigAct.sa_flags = SA_SIGINFO|SA_RESTART|SA_ONSTACK; + sigaction(SIGSEGV, &sigAct, NULL); +#else signal(SIGSEGV, segv_handler); +#endif printf("Allocating ...\n"); printf("... W^X memory: ");