src/x86/win64.S: Support compiling on non-WIN64 platforms
authorJosh Triplett <josh@joshtriplett.org>
Sun, 26 Jul 2015 23:18:57 +0000 (16:18 -0700)
committerJosh Triplett <josh@joshtriplett.org>
Sun, 26 Jul 2015 23:18:57 +0000 (16:18 -0700)
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.

src/x86/win64.S

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