x86: Fix calling convention for ffi_closure_win64_inner
authorRichard Henderson <rth@twiddle.net>
Fri, 15 Apr 2016 23:10:08 +0000 (16:10 -0700)
committerRichard Henderson <rth@twiddle.net>
Fri, 29 Apr 2016 21:17:36 +0000 (14:17 -0700)
Also enable testing for the cross-abi calls.

src/x86/ffiw64.c
src/x86/win64.S
testsuite/lib/libffi.exp
testsuite/libffi.call/ffitest.h

index 0029be0..fd47c58 100644 (file)
@@ -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,
index 09b9854..1f82a3e 100644 (file)
@@ -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.  */
index 0d74627..6d19393 100644 (file)
@@ -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__"
+            }
         }
     }
 
index 15d5e44..5e19451 100644 (file)
@@ -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