8 #if defined(HAVE_AS_CFI_PSEUDO_OP)
9 .cfi_sections .debug_frame
13 #define SEH(...) __VA_ARGS__
26 /* This macro allows the safe creation of jump tables without an
27 actual table. The entry points into the table are all 8 bytes.
28 The use of ORG asserts that we're at the correct location. */
29 /* ??? The clang assembler doesn't handle .org with symbolic expressions. */
30 #if defined(__clang__) || defined(__APPLE__) || (defined (__sun__) && defined(__svr4__))
31 # define E(BASE, X) .balign 8
33 # define E(BASE, X) .balign 8; .org BASE + (X) * 8
38 /* ffi_call_win64 (void *stack, struct win64_call_frame *frame, void *r10)
40 Bit o trickiness here -- FRAME is the base of the stack frame
41 for this function. This has been allocated by ffi_call. We also
42 deallocate some of the stack that has been alloca'd. */
45 .globl C(ffi_call_win64)
46 FFI_HIDDEN(C(ffi_call_win64))
48 SEH(.seh_proc ffi_call_win64)
52 /* Set up the local stack frame and install it in rbp/rsp. */
58 cfi_rel_offset(%rbp, 0)
59 SEH(.seh_pushreg %rbp)
60 SEH(.seh_setframe %rbp, 0)
66 /* Load all slots into both general and xmm registers. */
81 cmpl $FFI_TYPE_SMALL_STRUCT_4B, %ecx
82 leaq (%r10, %rcx, 8), %r10
84 _CET_NOTRACK jmp *%r10
86 /* Below, we're space constrained most of the time. Thus we eschew the
87 modern "mov, pop, ret" sequence (5 bytes) for "leave, ret" (2 bytes). */
105 E(0b, FFI_TYPE_FLOAT)
108 E(0b, FFI_TYPE_DOUBLE)
111 // FFI_TYPE_LONGDOUBLE may be FFI_TYPE_DOUBLE but we need a different value here.
112 E(0b, FFI_TYPE_DOUBLE + 1)
114 E(0b, FFI_TYPE_UINT8)
118 E(0b, FFI_TYPE_SINT8)
121 E(0b, FFI_TYPE_UINT16)
125 E(0b, FFI_TYPE_SINT16)
128 E(0b, FFI_TYPE_UINT32)
132 E(0b, FFI_TYPE_SINT32)
136 E(0b, FFI_TYPE_UINT64)
139 E(0b, FFI_TYPE_SINT64)
142 E(0b, FFI_TYPE_STRUCT)
144 E(0b, FFI_TYPE_POINTER)
147 E(0b, FFI_TYPE_COMPLEX)
149 E(0b, FFI_TYPE_SMALL_STRUCT_1B)
152 E(0b, FFI_TYPE_SMALL_STRUCT_2B)
155 E(0b, FFI_TYPE_SMALL_STRUCT_4B)
160 99: call PLT(C(abort))
168 /* 32 bytes of outgoing register stack space, 8 bytes of alignment,
169 16 bytes of result, 32 bytes of xmm registers. */
170 #define ffi_clo_FS (32+8+16+32)
171 #define ffi_clo_OFF_R (32+8)
172 #define ffi_clo_OFF_X (32+8+16)
175 .globl C(ffi_go_closure_win64)
176 FFI_HIDDEN(C(ffi_go_closure_win64))
178 SEH(.seh_proc ffi_go_closure_win64)
179 C(ffi_go_closure_win64):
182 /* Save all integer arguments into the incoming reg stack space. */
188 movq 8(%r10), %rcx /* load cif */
189 movq 16(%r10), %rdx /* load fun */
190 movq %r10, %r8 /* closure is user_data */
196 .globl C(ffi_closure_win64)
197 FFI_HIDDEN(C(ffi_closure_win64))
199 SEH(.seh_proc ffi_closure_win64)
200 C(ffi_closure_win64):
203 /* Save all integer arguments into the incoming reg stack space. */
209 movq FFI_TRAMPOLINE_SIZE(%r10), %rcx /* load cif */
210 movq FFI_TRAMPOLINE_SIZE+8(%r10), %rdx /* load fun */
211 movq FFI_TRAMPOLINE_SIZE+16(%r10), %r8 /* load user_data */
213 subq $ffi_clo_FS, %rsp
214 cfi_adjust_cfa_offset(ffi_clo_FS)
215 SEH(.seh_stackalloc ffi_clo_FS)
216 SEH(.seh_endprologue)
218 /* Save all sse arguments into the stack frame. */
219 movsd %xmm0, ffi_clo_OFF_X(%rsp)
220 movsd %xmm1, ffi_clo_OFF_X+8(%rsp)
221 movsd %xmm2, ffi_clo_OFF_X+16(%rsp)
222 movsd %xmm3, ffi_clo_OFF_X+24(%rsp)
224 leaq ffi_clo_OFF_R(%rsp), %r9
225 call PLT(C(ffi_closure_win64_inner))
227 /* Load the result into both possible result registers. */
228 movq ffi_clo_OFF_R(%rsp), %rax
229 movsd ffi_clo_OFF_R(%rsp), %xmm0
231 addq $ffi_clo_FS, %rsp
232 cfi_adjust_cfa_offset(-ffi_clo_FS)
238 #if defined(FFI_EXEC_STATIC_TRAMP)
240 .globl C(ffi_closure_win64_alt)
241 FFI_HIDDEN(C(ffi_closure_win64_alt))
243 SEH(.seh_proc ffi_closure_win64_alt)
244 C(ffi_closure_win64_alt):
248 jmp C(ffi_closure_win64)
251 #endif /* __x86_64__ */
253 #if defined __ELF__ && defined __linux__
254 .section .note.GNU-stack,"",@progbits