Merge pull request #241 from rth7680/fix-win64

Fix win64 abi calling from unix64
This commit is contained in:
Richard Henderson
2016-05-01 11:02:40 -10:00
4 changed files with 46 additions and 31 deletions

View File

@@ -231,7 +231,11 @@ struct win64_closure_frame
UINT64 args[]; 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, ffi_closure_win64_inner(ffi_cif *cif,
void (*fun)(ffi_cif*, void*, void**, void*), void (*fun)(ffi_cif*, void*, void**, void*),
void *user_data, void *user_data,

View File

@@ -22,10 +22,15 @@
#define arg3 %rcx #define arg3 %rcx
#endif #endif
.macro E which /* This macro allows the safe creation of jump tables without an
.align 8 actual table. The entry points into the table are all 8 bytes.
.org 0b + \which * 8 The use of ORG asserts that we're at the correct location. */
.endm /* ??? The clang assembler doesn't handle .org with symbolic expressions. */
#if defined(__clang__) || defined(__APPLE__) || (defined (__sun__) && defined(__svr4__))
# define E(BASE, X) .balign 8
#else
# define E(BASE, X) .balign 8; .org BASE + X * 8
#endif
.text .text
@@ -88,62 +93,62 @@ ffi_call_win64:
.align 8 .align 8
0: 0:
E FFI_TYPE_VOID E(0b, FFI_TYPE_VOID)
epilogue epilogue
E FFI_TYPE_INT E(0b, FFI_TYPE_INT)
movslq %eax, %rax movslq %eax, %rax
movq %rax, (%r8) movq %rax, (%r8)
epilogue epilogue
E FFI_TYPE_FLOAT E(0b, FFI_TYPE_FLOAT)
movss %xmm0, (%r8) movss %xmm0, (%r8)
epilogue epilogue
E FFI_TYPE_DOUBLE E(0b, FFI_TYPE_DOUBLE)
movsd %xmm0, (%r8) movsd %xmm0, (%r8)
epilogue epilogue
E FFI_TYPE_LONGDOUBLE E(0b, FFI_TYPE_LONGDOUBLE)
call PLT(C(abort)) call PLT(C(abort))
E FFI_TYPE_UINT8 E(0b, FFI_TYPE_UINT8)
movzbl %al, %eax movzbl %al, %eax
movq %rax, (%r8) movq %rax, (%r8)
epilogue epilogue
E FFI_TYPE_SINT8 E(0b, FFI_TYPE_SINT8)
movsbq %al, %rax movsbq %al, %rax
jmp 98f jmp 98f
E FFI_TYPE_UINT16 E(0b, FFI_TYPE_UINT16)
movzwl %ax, %eax movzwl %ax, %eax
movq %rax, (%r8) movq %rax, (%r8)
epilogue epilogue
E FFI_TYPE_SINT16 E(0b, FFI_TYPE_SINT16)
movswq %ax, %rax movswq %ax, %rax
jmp 98f jmp 98f
E FFI_TYPE_UINT32 E(0b, FFI_TYPE_UINT32)
movl %eax, %eax movl %eax, %eax
movq %rax, (%r8) movq %rax, (%r8)
epilogue epilogue
E FFI_TYPE_SINT32 E(0b, FFI_TYPE_SINT32)
movslq %eax, %rax movslq %eax, %rax
movq %rax, (%r8) movq %rax, (%r8)
epilogue epilogue
E FFI_TYPE_UINT64 E(0b, FFI_TYPE_UINT64)
98: movq %rax, (%r8) 98: movq %rax, (%r8)
epilogue epilogue
E FFI_TYPE_SINT64 E(0b, FFI_TYPE_SINT64)
movq %rax, (%r8) movq %rax, (%r8)
epilogue epilogue
E FFI_TYPE_STRUCT E(0b, FFI_TYPE_STRUCT)
epilogue epilogue
E FFI_TYPE_POINTER E(0b, FFI_TYPE_POINTER)
movq %rax, (%r8) movq %rax, (%r8)
epilogue epilogue
E FFI_TYPE_COMPLEX E(0b, FFI_TYPE_COMPLEX)
call PLT(C(abort)) call PLT(C(abort))
E FFI_TYPE_SMALL_STRUCT_1B E(0b, FFI_TYPE_SMALL_STRUCT_1B)
movb %al, (%r8) movb %al, (%r8)
epilogue epilogue
E FFI_TYPE_SMALL_STRUCT_2B E(0b, FFI_TYPE_SMALL_STRUCT_2B)
movw %ax, (%r8) movw %ax, (%r8)
epilogue epilogue
E FFI_TYPE_SMALL_STRUCT_4B E(0b, FFI_TYPE_SMALL_STRUCT_4B)
movl %eax, (%r8) movl %eax, (%r8)
epilogue epilogue
@@ -174,9 +179,9 @@ ffi_go_closure_win64:
movq %r8, 24(%rsp) movq %r8, 24(%rsp)
movq %r9, 32(%rsp) movq %r9, 32(%rsp)
movq 8(%r10), arg0 /* load cif */ movq 8(%r10), %rcx /* load cif */
movq 16(%r10), arg1 /* load fun */ movq 16(%r10), %rdx /* load fun */
movq %r10, arg2 /* closure is user_data */ movq %r10, %r8 /* closure is user_data */
jmp 0f jmp 0f
cfi_endproc cfi_endproc
SEH(.seh_endproc) SEH(.seh_endproc)
@@ -193,9 +198,9 @@ ffi_closure_win64:
movq %r8, 24(%rsp) movq %r8, 24(%rsp)
movq %r9, 32(%rsp) movq %r9, 32(%rsp)
movq FFI_TRAMPOLINE_SIZE(%r10), arg0 /* load cif */ movq FFI_TRAMPOLINE_SIZE(%r10), %rcx /* load cif */
movq FFI_TRAMPOLINE_SIZE+8(%r10), arg1 /* load fun */ movq FFI_TRAMPOLINE_SIZE+8(%r10), %rdx /* load fun */
movq FFI_TRAMPOLINE_SIZE+16(%r10), arg2 /* load user_data */ movq FFI_TRAMPOLINE_SIZE+16(%r10), %r8 /* load user_data */
0: 0:
subq $ffi_clo_FS, %rsp subq $ffi_clo_FS, %rsp
cfi_adjust_cfa_offset(ffi_clo_FS) cfi_adjust_cfa_offset(ffi_clo_FS)
@@ -208,7 +213,7 @@ ffi_closure_win64:
movsd %xmm2, ffi_clo_OFF_X+16(%rsp) movsd %xmm2, ffi_clo_OFF_X+16(%rsp)
movsd %xmm3, ffi_clo_OFF_X+24(%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 call ffi_closure_win64_inner
/* Load the result into both possible result registers. */ /* Load the result into both possible result registers. */

View File

@@ -315,6 +315,11 @@ proc run-many-tests { testcases extra_flags } {
"-DABI_NUM=FFI_THISCALL -DABI_ATTR=__THISCALL__" "-DABI_NUM=FFI_THISCALL -DABI_ATTR=__THISCALL__"
"-DABI_NUM=FFI_FASTCALL -DABI_ATTR=__FASTCALL__" "-DABI_NUM=FFI_FASTCALL -DABI_ATTR=__FASTCALL__"
} }
} elseif [istarget "x86_64-*-*"] {
set targetabis {
""
"-DABI_NUM=FFI_WIN64 -DABI_ATTR=__MSABI__"
}
} }
} }

View File

@@ -24,6 +24,7 @@
#define __STDCALL__ __attribute__((stdcall)) #define __STDCALL__ __attribute__((stdcall))
#define __THISCALL__ __attribute__((thiscall)) #define __THISCALL__ __attribute__((thiscall))
#define __FASTCALL__ __attribute__((fastcall)) #define __FASTCALL__ __attribute__((fastcall))
#define __MSABI__ __attribute__((ms_abi))
#else #else
#define __UNUSED__ #define __UNUSED__
#define __STDCALL__ __stdcall #define __STDCALL__ __stdcall