diff options
author | Richard Henderson <rth@twiddle.net> | 2016-04-15 16:10:08 -0700 |
---|---|---|
committer | Richard Henderson <rth@twiddle.net> | 2016-04-29 14:17:36 -0700 |
commit | e5843a3a09976f9d8fa77671e9d6c188c890199d (patch) | |
tree | 47377856498e632029fe741bdd4970454b3d3f02 | |
parent | d06751979bf0e4c9caabf0bca531d74de8cb9152 (diff) | |
download | libffi-e5843a3a09976f9d8fa77671e9d6c188c890199d.tar.gz |
x86: Fix calling convention for ffi_closure_win64_inner
Also enable testing for the cross-abi calls.
-rw-r--r-- | src/x86/ffiw64.c | 6 | ||||
-rw-r--r-- | src/x86/win64.S | 14 | ||||
-rw-r--r-- | testsuite/lib/libffi.exp | 5 | ||||
-rw-r--r-- | testsuite/libffi.call/ffitest.h | 1 |
4 files changed, 18 insertions, 8 deletions
diff --git a/src/x86/ffiw64.c b/src/x86/ffiw64.c index 0029be0..fd47c58 100644 --- a/src/x86/ffiw64.c +++ b/src/x86/ffiw64.c @@ -231,7 +231,11 @@ struct win64_closure_frame UINT64 args[]; }; -int FFI_HIDDEN +/* Force the inner function to use the MS ABI. When compiling on win64 + this is a nop. When compiling on unix, this simplifies the assembly, + and places the burden of saving the extra call-saved registers on + the compiler. */ +int FFI_HIDDEN __attribute__((ms_abi)) ffi_closure_win64_inner(ffi_cif *cif, void (*fun)(ffi_cif*, void*, void**, void*), void *user_data, diff --git a/src/x86/win64.S b/src/x86/win64.S index 09b9854..1f82a3e 100644 --- a/src/x86/win64.S +++ b/src/x86/win64.S @@ -179,9 +179,9 @@ ffi_go_closure_win64: movq %r8, 24(%rsp) movq %r9, 32(%rsp) - movq 8(%r10), arg0 /* load cif */ - movq 16(%r10), arg1 /* load fun */ - movq %r10, arg2 /* closure is user_data */ + movq 8(%r10), %rcx /* load cif */ + movq 16(%r10), %rdx /* load fun */ + movq %r10, %r8 /* closure is user_data */ jmp 0f cfi_endproc SEH(.seh_endproc) @@ -198,9 +198,9 @@ ffi_closure_win64: movq %r8, 24(%rsp) movq %r9, 32(%rsp) - movq FFI_TRAMPOLINE_SIZE(%r10), arg0 /* load cif */ - movq FFI_TRAMPOLINE_SIZE+8(%r10), arg1 /* load fun */ - movq FFI_TRAMPOLINE_SIZE+16(%r10), arg2 /* load user_data */ + movq FFI_TRAMPOLINE_SIZE(%r10), %rcx /* load cif */ + movq FFI_TRAMPOLINE_SIZE+8(%r10), %rdx /* load fun */ + movq FFI_TRAMPOLINE_SIZE+16(%r10), %r8 /* load user_data */ 0: subq $ffi_clo_FS, %rsp cfi_adjust_cfa_offset(ffi_clo_FS) @@ -213,7 +213,7 @@ ffi_closure_win64: movsd %xmm2, ffi_clo_OFF_X+16(%rsp) movsd %xmm3, ffi_clo_OFF_X+24(%rsp) - leaq ffi_clo_OFF_R(%rsp), arg3 + leaq ffi_clo_OFF_R(%rsp), %r9 call ffi_closure_win64_inner /* Load the result into both possible result registers. */ diff --git a/testsuite/lib/libffi.exp b/testsuite/lib/libffi.exp index 0d74627..6d19393 100644 --- a/testsuite/lib/libffi.exp +++ b/testsuite/lib/libffi.exp @@ -315,6 +315,11 @@ proc run-many-tests { testcases extra_flags } { "-DABI_NUM=FFI_THISCALL -DABI_ATTR=__THISCALL__" "-DABI_NUM=FFI_FASTCALL -DABI_ATTR=__FASTCALL__" } + } elseif [istarget "x86_64-*-*"] { + set targetabis { + "" + "-DABI_NUM=FFI_WIN64 -DABI_ATTR=__MSABI__" + } } } diff --git a/testsuite/libffi.call/ffitest.h b/testsuite/libffi.call/ffitest.h index 15d5e44..5e19451 100644 --- a/testsuite/libffi.call/ffitest.h +++ b/testsuite/libffi.call/ffitest.h @@ -24,6 +24,7 @@ #define __STDCALL__ __attribute__((stdcall)) #define __THISCALL__ __attribute__((thiscall)) #define __FASTCALL__ __attribute__((fastcall)) +#define __MSABI__ __attribute__((ms_abi)) #else #define __UNUSED__ #define __STDCALL__ __stdcall |