src/x86/win64.S: Support compiling on non-WIN64 platforms

Non-WIN64 versions of the GNU assembler don't support the .seh_*
directives for structured exception handling, so wrap them in a macro
that compiles to nothing.

Handle the registers used for the non-Windows x86-64 calling convention
when on a non-Windows platform.  Distinguish between cases that should
refer to the native argument registers (defined as arg0, arg1, arg2, and
arg3) and cases that should always refer to the Windows argument
registers.
This commit is contained in:
Josh Triplett
2015-07-26 16:18:57 -07:00
parent 17ffc3655a
commit c8e82d9fbf

View File

@@ -7,10 +7,19 @@
.cfi_sections .debug_frame .cfi_sections .debug_frame
#endif #endif
#ifdef X86_WIN64
#define SEH(...) __VA_ARGS__
#define arg0 %rcx #define arg0 %rcx
#define arg1 %rdx #define arg1 %rdx
#define arg2 %r8 #define arg2 %r8
#define arg3 %r9 #define arg3 %r9
#else
#define SEH(...)
#define arg0 %rdi
#define arg1 %rsi
#define arg2 %rdx
#define arg3 %rcx
#endif
#ifdef SYMBOL_UNDERSCORE #ifdef SYMBOL_UNDERSCORE
#define SYMBOL_NAME(name) _##name #define SYMBOL_NAME(name) _##name
@@ -34,7 +43,7 @@
.align 8 .align 8
.globl ffi_call_win64 .globl ffi_call_win64
.seh_proc ffi_call_win64 SEH(.seh_proc ffi_call_win64)
ffi_call_win64: ffi_call_win64:
cfi_startproc cfi_startproc
/* Set up the local stack frame and install it in rbp/rsp. */ /* Set up the local stack frame and install it in rbp/rsp. */
@@ -44,9 +53,9 @@ ffi_call_win64:
movq arg1, %rbp movq arg1, %rbp
cfi_def_cfa(%rbp, 16) cfi_def_cfa(%rbp, 16)
cfi_rel_offset(%rbp, 0) cfi_rel_offset(%rbp, 0)
.seh_pushreg %rbp SEH(.seh_pushreg %rbp)
.seh_setframe %rbp, 0 SEH(.seh_setframe %rbp, 0)
.seh_endprologue SEH(.seh_endprologue)
movq arg0, %rsp movq arg0, %rsp
movq arg2, %r10 movq arg2, %r10
@@ -149,7 +158,7 @@ E FFI_TYPE_SMALL_STRUCT_4B
.purgem epilogue .purgem epilogue
cfi_endproc cfi_endproc
.seh_endproc SEH(.seh_endproc)
/* 32 bytes of outgoing register stack space, 8 bytes of alignment, /* 32 bytes of outgoing register stack space, 8 bytes of alignment,
@@ -161,33 +170,33 @@ E FFI_TYPE_SMALL_STRUCT_4B
.align 8 .align 8
.globl ffi_go_closure_win64 .globl ffi_go_closure_win64
.seh_proc ffi_go_closure_win64 SEH(.seh_proc ffi_go_closure_win64)
ffi_go_closure_win64: ffi_go_closure_win64:
cfi_startproc cfi_startproc
/* Save all integer arguments into the incoming reg stack space. */ /* Save all integer arguments into the incoming reg stack space. */
movq arg0, 8(%rsp) movq %rcx, 8(%rsp)
movq arg1, 16(%rsp) movq %rdx, 16(%rsp)
movq arg2, 24(%rsp) movq %r8, 24(%rsp)
movq arg3, 32(%rsp) movq %r9, 32(%rsp)
movq 8(%r10), arg0 /* load cif */ movq 8(%r10), arg0 /* load cif */
movq 16(%r10), arg1 /* load fun */ movq 16(%r10), arg1 /* load fun */
movq %r10, arg2 /* closure is user_data */ movq %r10, arg2 /* closure is user_data */
jmp 0f jmp 0f
cfi_endproc cfi_endproc
.seh_endproc SEH(.seh_endproc)
.align 8 .align 8
.globl ffi_closure_win64 .globl ffi_closure_win64
.seh_proc ffi_closure_win64 SEH(.seh_proc ffi_closure_win64)
ffi_closure_win64: ffi_closure_win64:
cfi_startproc cfi_startproc
/* Save all integer arguments into the incoming reg stack space. */ /* Save all integer arguments into the incoming reg stack space. */
movq arg0, 8(%rsp) movq %rcx, 8(%rsp)
movq arg1, 16(%rsp) movq %rdx, 16(%rsp)
movq arg2, 24(%rsp) movq %r8, 24(%rsp)
movq arg3, 32(%rsp) movq %r9, 32(%rsp)
movq FFI_TRAMPOLINE_SIZE(%r10), arg0 /* load cif */ movq FFI_TRAMPOLINE_SIZE(%r10), arg0 /* load cif */
movq FFI_TRAMPOLINE_SIZE+8(%r10), arg1 /* load fun */ movq FFI_TRAMPOLINE_SIZE+8(%r10), arg1 /* load fun */
@@ -195,8 +204,8 @@ ffi_closure_win64:
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)
.seh_stackalloc ffi_clo_FS SEH(.seh_stackalloc ffi_clo_FS)
.seh_endprologue SEH(.seh_endprologue)
/* Save all sse arguments into the stack frame. */ /* Save all sse arguments into the stack frame. */
movsd %xmm0, ffi_clo_OFF_X(%rsp) movsd %xmm0, ffi_clo_OFF_X(%rsp)
@@ -216,4 +225,4 @@ ffi_closure_win64:
ret ret
cfi_endproc cfi_endproc
.seh_endproc SEH(.seh_endproc)