changeset 371:451299d50c1a

- windows arm64 support (dyncall, dyncallback, cmake support for armasm64), thanks Bernhard Urban-Forster! - minor cleanups
author Tassilo Philipp
date Fri, 25 Dec 2020 18:07:39 +0100
parents fa78490381f3
children bac52ab8869f
files AUTHORS CMakeLists.txt ChangeLog autovar/autovar_ARCH.h doc/README.Windows dyncall/CMakeLists.txt dyncall/dyncall_call_arm64.S dyncall/dyncall_call_arm64_masm.asm dyncall/dyncall_callvm_arm64.c dyncall/dyncall_callvm_arm64_apple.c dyncall/dyncall_macros.h dyncallback/CMakeLists.txt dyncallback/dyncall_callback_arm64.S dyncallback/dyncall_callback_arm64_masm.asm portasm/portasm-arm64.S test/callf/main.c test/thunk/test_thunk.c
diffstat 17 files changed, 365 insertions(+), 142 deletions(-) [+]
line wrap: on
line diff
--- 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 <olivier.chafik@gmail.com>
 Erik Mackdanz <erikmack@gmail.com>
 Masanori Mitsugi <mitsugi@linux.vnet.ibm.com>
+Bernhard Urban-Forster <beurba@microsoft.com>
 
--- 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 <dadler@uni-goettingen.de>
+# Copyright (c) 2010-2020 Daniel Adler <dadler@uni-goettingen.de>
+#                    2020 armasm64 support: Bernhard Urban-Forster <beurba@microsoft.com>
 # 
 # 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 "<CMAKE_ASM_MASM_COMPILER> <FLAGS> /c /Fo <OBJECT> <SOURCE>")
+  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 "<CMAKE_ASM_COMPILER> <INCLUDES> <FLAGS> -o <OBJECT> <SOURCE>")
+  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 "<CMAKE_ASM_MASM_COMPILER> <FLAGS> /c /Fo <OBJECT> <SOURCE>")
+  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
--- 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=<path>"
 
+
 Version 0.1 (2008/01/23)
+
   o initial release
 
--- 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
--- 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
+
--- 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()
--- 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 <dadler@uni-goettingen.de>, 
+   Copyright (c) 2015-2020 Daniel Adler <dadler@uni-goettingen.de>, 
                            Tassilo Philipp <tphilipp@potion-studios.com>
 
    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
- 
-
--- /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
--- 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: 
--- 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:
--- 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
--- 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()
--- 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 <dadler@uni-goettingen.de>,
+   Copyright (c) 2015-2020 Daniel Adler <dadler@uni-goettingen.de>,
                            Tassilo Philipp <tphilipp@potion-studios.com>
 
    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
+
--- /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
--- /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 <beurba@microsoft.com>
+
+   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
+
--- 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 <dadler@uni-goettingen.de>, 
+   Copyright (c) 2007-2020 Daniel Adler <dadler@uni-goettingen.de>, 
                            Tassilo Philipp <tphilipp@potion-studios.com>
 
    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");
--- 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 <dadler@uni-goettingen.de>,
+   Copyright (c) 2011-2020 Daniel Adler <dadler@uni-goettingen.de>,
                            Tassilo Philipp <tphilipp@potion-studios.com>
 
    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: ");