summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Henderson <rth@twiddle.net>2016-04-15 16:10:08 -0700
committerRichard Henderson <rth@twiddle.net>2016-04-29 14:17:36 -0700
commite5843a3a09976f9d8fa77671e9d6c188c890199d (patch)
tree47377856498e632029fe741bdd4970454b3d3f02
parentd06751979bf0e4c9caabf0bca531d74de8cb9152 (diff)
downloadlibffi-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.c6
-rw-r--r--src/x86/win64.S14
-rw-r--r--testsuite/lib/libffi.exp5
-rw-r--r--testsuite/libffi.call/ffitest.h1
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