Update LOCAL_PATCHES after libsanitizer merge.
[official-gcc.git] / libffi / src / x86 / win64.S
bloba5a20b6437c1cb260ba8394f323f54e5121e863c
1 #define LIBFFI_ASM
2 #include <fficonfig.h>
3 #include <ffi.h>
4 #include <ffi_cfi.h>
6 #if defined(HAVE_AS_CFI_PSEUDO_OP)
7         .cfi_sections   .debug_frame
8 #endif
10 #define arg0    %rcx
11 #define arg1    %rdx
12 #define arg2    %r8
13 #define arg3    %r9
15 #ifdef SYMBOL_UNDERSCORE
16 #define SYMBOL_NAME(name) _##name
17 #else
18 #define SYMBOL_NAME(name) name
19 #endif
21 .macro E which
22         .align  8
23         .org    0b + \which * 8
24 .endm
26         .text
28 /* ffi_call_win64 (void *stack, struct win64_call_frame *frame, void *r10)
30    Bit o trickiness here -- FRAME is the base of the stack frame
31    for this function.  This has been allocated by ffi_call.  We also
32    deallocate some of the stack that has been alloca'd.  */
34         .align  8
35         .globl  ffi_call_win64
37         .seh_proc ffi_call_win64
38 ffi_call_win64:
39         cfi_startproc
40         /* Set up the local stack frame and install it in rbp/rsp.  */
41         movq    (%rsp), %rax
42         movq    %rbp, (arg1)
43         movq    %rax, 8(arg1)
44         movq    arg1, %rbp
45         cfi_def_cfa(%rbp, 16)
46         cfi_rel_offset(%rbp, 0)
47         .seh_pushreg %rbp
48         .seh_setframe %rbp, 0
49         .seh_endprologue
50         movq    arg0, %rsp
52         movq    arg2, %r10
54         /* Load all slots into both general and xmm registers.  */
55         movq    (%rsp), %rcx
56         movsd   (%rsp), %xmm0
57         movq    8(%rsp), %rdx
58         movsd   8(%rsp), %xmm1
59         movq    16(%rsp), %r8
60         movsd   16(%rsp), %xmm2
61         movq    24(%rsp), %r9
62         movsd   24(%rsp), %xmm3
64         call    *16(%rbp)
66         movl    24(%rbp), %ecx
67         movq    32(%rbp), %r8
68         leaq    0f(%rip), %r10
69         cmpl    $FFI_TYPE_SMALL_STRUCT_4B, %ecx
70         leaq    (%r10, %rcx, 8), %r10
71         ja      99f
72         jmp     *%r10
74 /* Below, we're space constrained most of the time.  Thus we eschew the
75    modern "mov, pop, ret" sequence (5 bytes) for "leave, ret" (2 bytes).  */
76 .macro epilogue
77         leaveq
78         cfi_remember_state
79         cfi_def_cfa(%rsp, 8)
80         cfi_restore(%rbp)
81         ret
82         cfi_restore_state
83 .endm
85         .align  8
87 E FFI_TYPE_VOID
88         epilogue
89 E FFI_TYPE_INT
90         movslq  %eax, %rax
91         movq    %rax, (%r8)
92         epilogue
93 E FFI_TYPE_FLOAT
94         movss   %xmm0, (%r8)
95         epilogue
96 E FFI_TYPE_DOUBLE
97         movsd   %xmm0, (%r8)
98         epilogue
99 E FFI_TYPE_LONGDOUBLE
100         call    abort
101 E FFI_TYPE_UINT8
102         movzbl  %al, %eax
103         movq    %rax, (%r8)
104         epilogue
105 E FFI_TYPE_SINT8
106         movsbq  %al, %rax
107         jmp     98f
108 E FFI_TYPE_UINT16
109         movzwl  %ax, %eax
110         movq    %rax, (%r8)
111         epilogue
112 E FFI_TYPE_SINT16
113         movswq  %ax, %rax
114         jmp     98f
115 E FFI_TYPE_UINT32
116         movl    %eax, %eax
117         movq    %rax, (%r8)
118         epilogue
119 E FFI_TYPE_SINT32
120         movslq  %eax, %rax
121         movq    %rax, (%r8)
122         epilogue
123 E FFI_TYPE_UINT64
124 98:     movq    %rax, (%r8)
125         epilogue
126 E FFI_TYPE_SINT64
127         movq    %rax, (%r8)
128         epilogue
129 E FFI_TYPE_STRUCT
130         epilogue
131 E FFI_TYPE_POINTER
132         movq    %rax, (%r8)
133         epilogue
134 E FFI_TYPE_COMPLEX
135         call    abort
136 E FFI_TYPE_SMALL_STRUCT_1B
137         movb    %al, (%r8)
138         epilogue
139 E FFI_TYPE_SMALL_STRUCT_2B
140         movw    %ax, (%r8)
141         epilogue
142 E FFI_TYPE_SMALL_STRUCT_4B
143         movl    %eax, (%r8)
144         epilogue
146         .align  8
147 99:     call    abort
149 .purgem epilogue
151         cfi_endproc
152         .seh_endproc
155 /* 32 bytes of outgoing register stack space, 8 bytes of alignment,
156    16 bytes of result, 32 bytes of xmm registers.  */
157 #define ffi_clo_FS      (32+8+16+32)
158 #define ffi_clo_OFF_R   (32+8)
159 #define ffi_clo_OFF_X   (32+8+16)
161         .align  8
162         .globl  ffi_go_closure_win64
164         .seh_proc ffi_go_closure_win64
165 ffi_go_closure_win64:
166         cfi_startproc
167         /* Save all integer arguments into the incoming reg stack space.  */
168         movq    arg0, 8(%rsp)
169         movq    arg1, 16(%rsp)
170         movq    arg2, 24(%rsp)
171         movq    arg3, 32(%rsp)
173         movq    8(%r10), arg0                   /* load cif */
174         movq    16(%r10), arg1                  /* load fun */
175         movq    %r10, arg2                      /* closure is user_data */
176         jmp     0f
177         cfi_endproc
178         .seh_endproc
180         .align  8
181         .globl  ffi_closure_win64
183         .seh_proc ffi_closure_win64
184 ffi_closure_win64:
185         cfi_startproc
186         /* Save all integer arguments into the incoming reg stack space.  */
187         movq    arg0, 8(%rsp)
188         movq    arg1, 16(%rsp)
189         movq    arg2, 24(%rsp)
190         movq    arg3, 32(%rsp)
192         movq    FFI_TRAMPOLINE_SIZE(%r10), arg0         /* load cif */
193         movq    FFI_TRAMPOLINE_SIZE+8(%r10), arg1       /* load fun */
194         movq    FFI_TRAMPOLINE_SIZE+16(%r10), arg2      /* load user_data */
196         subq    $ffi_clo_FS, %rsp
197         cfi_adjust_cfa_offset(ffi_clo_FS)
198         .seh_stackalloc ffi_clo_FS
199         .seh_endprologue
201         /* Save all sse arguments into the stack frame.  */
202         movsd   %xmm0, ffi_clo_OFF_X(%rsp)
203         movsd   %xmm1, ffi_clo_OFF_X+8(%rsp)
204         movsd   %xmm2, ffi_clo_OFF_X+16(%rsp)
205         movsd   %xmm3, ffi_clo_OFF_X+24(%rsp)
207         leaq    ffi_clo_OFF_R(%rsp), arg3
208         call    ffi_closure_win64_inner
210         /* Load the result into both possible result registers.  */
211         movq    ffi_clo_OFF_R(%rsp), %rax
212         movsd   ffi_clo_OFF_R(%rsp), %xmm0
214         addq    $ffi_clo_FS, %rsp
215         cfi_adjust_cfa_offset(-ffi_clo_FS)
216         ret
218         cfi_endproc
219         .seh_endproc