1 /* -----------------------------------------------------------------------
2 unix64.S - Copyright (c) 2002 Bo Thorsen <bo@suse.de>
4 x86-64 Foreign Function Interface
6 Permission is hereby granted, free of charge, to any person obtaining
7 a copy of this software and associated documentation files (the
8 ``Software''), to deal in the Software without restriction, including
9 without limitation the rights to use, copy, modify, merge, publish,
10 distribute, sublicense, and/or sell copies of the Software, and to
11 permit persons to whom the Software is furnished to do so, subject to
12 the following conditions:
14 The above copyright notice and this permission notice shall be included
15 in all copies or substantial portions of the Software.
17 THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20 IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
21 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23 OTHER DEALINGS IN THE SOFTWARE.
24 ----------------------------------------------------------------------- */
28 #include <fficonfig.h>
33 .string "asm in progress %lld\n"
35 .string "asm in progress\n"
38 .globl ffi_call_UNIX64
39 .type ffi_call_UNIX64,@function
47 /* Save all arguments */
50 movq %rdi, -8(%rbp) /* ffi_prep_args */
51 movq %rsi, -16(%rbp) /* ffi_fill_return_value */
52 movq %rdx, -24(%rbp) /* ecif */
53 movq %rcx, -32(%rbp) /* cif->bytes */
54 movq %r8, -40(%rbp) /* ecif.rvalue */
55 movq %r9, -48(%rbp) /* fn */
57 /* Make room for all of the new args and the register args */
62 /* Setup the call to ffi_prep_args. */
63 movq %rdi, %rax /* &ffi_prep_args */
64 movq %rsp, %rdi /* stackLayout */
65 movq %rdx, %rsi /* ecif */
66 call *%rax /* ffi_prep_args(stackLayout, ecif);*/
68 /* ffi_prep_args have put all the register contents into the */
69 /* stackLayout struct. Now put the register values in place. */
76 movaps 48(%rsp), %xmm0
77 movaps 64(%rsp), %xmm1
78 movaps 80(%rsp), %xmm2
79 movaps 96(%rsp), %xmm3
80 movaps 112(%rsp), %xmm4
81 movaps 128(%rsp), %xmm5
82 movaps 144(%rsp), %xmm6
83 movaps 160(%rsp), %xmm7
85 /* Remove space for stackLayout so stack arguments are placed
86 correctly for the call. */
90 /* Call the user function. */
93 /* Make stack space for the return_value struct. */
96 /* Fill in all potential return values to this struct. */
99 movaps %xmm0, 16(%rsp)
100 movaps %xmm1, 32(%rsp)
103 /* Now call ffi_fill_return_value. */
104 movq %rsp, %rdi /* struct return_value */
105 movq -24(%rbp), %rsi /* ecif */
106 movq -16(%rbp), %rax /* &ffi_fill_return_value */
107 call *%rax /* call it */
109 /* And the work is done. */
113 .ffi_call_UNIX64_end:
114 .size ffi_call_UNIX64,.ffi_call_UNIX64_end-ffi_call_UNIX64
119 .type float2sse,@function
121 /* Save the contents of this sse-float in a pointer. */
126 .globl floatfloat2sse
127 .type floatfloat2sse,@function
129 /* Save the contents of these two sse-floats in a pointer. */
136 .type double2sse,@function
138 /* Save the contents of this sse-double in a pointer. */
144 .type sse2float,@function
146 /* Save the contents of this sse-float in a pointer. */
152 .type sse2double,@function
154 /* Save the contents of this pointer in a sse-double. */
159 .globl sse2floatfloat
160 .type sse2floatfloat,@function
162 /* Save the contents of this pointer in two sse-floats. */
168 .globl ffi_closure_UNIX64
169 .type ffi_closure_UNIX64,@function
179 movq %rdi, -176(%rbp)
180 movq %rsi, -168(%rbp)
181 movq %rdx, -160(%rbp)
182 movq %rcx, -152(%rbp)
185 /* FIXME: We can avoid all this stashing of XMM registers by
186 (in ffi_prep_closure) computing the number of
187 floating-point args and moving it into %rax before calling
188 this function. Once this is done, uncomment the next few
189 lines and only the essential XMM registers will be written
190 to memory. This is a significant saving. */
191 /* movzbl %al, %eax */
192 /* movq %rax, %rdx */
193 /* leaq 0(,%rdx,4), %rax */
194 /* leaq 2f(%rip), %rdx */
195 /* subq %rax, %rdx */
198 movaps %xmm7, -15(%rax)
199 movaps %xmm6, -31(%rax)
200 movaps %xmm5, -47(%rax)
201 movaps %xmm4, -63(%rax)
202 movaps %xmm3, -79(%rax)
203 movaps %xmm2, -95(%rax)
204 movaps %xmm1, -111(%rax)
205 movaps %xmm0, -127(%rax)
207 movl %edi, -180(%rbp)
211 movq %rax, -216(%rbp)
212 leaq -176(%rbp), %rdx
213 movq %rdx, -208(%rbp)
214 leaq -224(%rbp), %rsi
217 call ffi_closure_UNIX64_inner@PLT
219 cmpl $FFI_TYPE_FLOAT, %eax
221 cmpl $FFI_TYPE_DOUBLE, %eax
223 cmpl $FFI_TYPE_LONGDOUBLE, %eax
225 cmpl $FFI_TYPE_STRUCT, %eax
233 movaps -240(%rbp), %xmm0
241 .section .eh_frame,EH_FRAME_FLAGS,@progbits
243 .long .LECIE1-.LSCIE1
261 .long .LEFDE1-.LASFDE1
263 .long .LASFDE1-.Lframe0
268 .byte 0x4 # DW_CFA_advance_loc4
270 .byte 0xe # DW_CFA_def_cfa_offset
272 .byte 0x86 # DW_CFA_offset: r6 at cfa-16
274 .byte 0x4 # DW_CFA_advance_loc4
276 .byte 0x86 # DW_CFA_offset: r6 at cfa-16
278 .byte 0xd # DW_CFA_def_cfa_reg: r6
283 .long .LEFDE3-.LASFDE3 # FDE Length
285 .long .LASFDE3-.Lframe0 # FDE CIE offset
287 .long .LFB2-. # FDE initial location
288 .long .LFE2-.LFB2 # FDE address range
289 .uleb128 0x0 # Augmentation size
290 .byte 0x4 # DW_CFA_advance_loc4
292 .byte 0xe # DW_CFA_def_cfa_offset
294 .byte 0x86 # DW_CFA_offset, column 0x6
296 .byte 0x4 # DW_CFA_advance_loc4
297 .long .LCFI11-.LCFI10
298 .byte 0xd # DW_CFA_def_cfa_register
303 #endif /* __x86_64__ */