2003-12-26 Guilhem Lavaux <guilhem@kaffe.org>
[official-gcc.git] / libffi / src / x86 / unix64.S
blob310fed71843996a924cfd8c8d65c7298cdf4813c
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    ----------------------------------------------------------------------- */
26 #ifdef __x86_64__
27 #define LIBFFI_ASM      
28 #include <fficonfig.h>
29 #include <ffi.h>
31         .section        .rodata
32 .LC0:
33         .string "asm in progress %lld\n"
34 .LC1:
35         .string "asm in progress\n"
36 .text
37         .align  2
38 .globl ffi_call_UNIX64
39         .type   ffi_call_UNIX64,@function
41 ffi_call_UNIX64:
42 .LFB1:
43         pushq   %rbp
44 .LCFI0:
45         movq    %rsp, %rbp
46 .LCFI1:
47         /* Save all arguments */
48         subq    $48, %rsp
49 .LCFI2:
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 */
58         addl    $176, %ecx
59 .LCFI3:
60         subq    %rcx, %rsp
61 .LCFI4:
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.  */
70         movq    (%rsp), %rdi
71         movq    8(%rsp), %rsi
72         movq    16(%rsp), %rdx
73         movq    24(%rsp), %rcx
74         movq    32(%rsp), %r8
75         movq    40(%rsp), %r9
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.  */
87 .LCFI5:
88         addq    $176, %rsp
89 .LCFI6:
90         /* Call the user function.  */
91         call    *-48(%rbp)
93         /* Make stack space for the return_value struct.  */
94         subq    $64, %rsp
96         /* Fill in all potential return values to this struct.  */
97         movq    %rax, (%rsp)
98         movq    %rdx, 8(%rsp)
99         movaps  %xmm0, 16(%rsp)
100         movaps  %xmm1, 32(%rsp)
101         fstpt   48(%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.  */
110         leave
111         ret
112 .LFE1:
113 .ffi_call_UNIX64_end:
114         .size    ffi_call_UNIX64,.ffi_call_UNIX64_end-ffi_call_UNIX64
116 .text
117         .align  2
118 .globl float2sse
119         .type   float2sse,@function
120 float2sse:
121         /* Save the contents of this sse-float in a pointer.  */
122         movaps  %xmm0, (%rdi)
123         ret
125         .align  2
126 .globl floatfloat2sse
127         .type   floatfloat2sse,@function
128 floatfloat2sse:
129         /* Save the contents of these two sse-floats in a pointer.  */
130         movq    (%rdi), %xmm0
131         movaps  %xmm0, (%rsi)
132         ret
134         .align  2
135 .globl double2sse
136         .type   double2sse,@function
137 double2sse:
138         /* Save the contents of this sse-double in a pointer.  */
139         movaps  %xmm0, (%rdi)
140         ret
142         .align  2
143 .globl sse2float
144         .type   sse2float,@function
145 sse2float:
146         /* Save the contents of this sse-float in a pointer.  */
147         movaps  (%rdi), %xmm0
148         ret
150         .align  2
151 .globl sse2double
152         .type   sse2double,@function
153 sse2double:
154         /* Save the contents of this pointer in a sse-double.  */
155         movaps  (%rdi), %xmm0
156         ret
158         .align  2
159 .globl sse2floatfloat
160         .type   sse2floatfloat,@function
161 sse2floatfloat:
162         /* Save the contents of this pointer in two sse-floats.  */
163         movaps  (%rdi), %xmm0
164         movq    %xmm0, (%rsi)
165         ret
167         .align  2
168 .globl ffi_closure_UNIX64
169         .type   ffi_closure_UNIX64,@function
171 ffi_closure_UNIX64:
172 .LFB2:
173         pushq   %rbp
174 .LCFI10:
175         movq    %rsp, %rbp
176 .LCFI11:
177         subq    $240, %rsp
178 .LCFI12:
179         movq    %rdi, -176(%rbp)
180         movq    %rsi, -168(%rbp)
181         movq    %rdx, -160(%rbp)
182         movq    %rcx, -152(%rbp)
183         movq    %r8, -144(%rbp)
184         movq    %r9, -136(%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 */
196         leaq    -1(%rbp), %rax
197 /*         jmp     *%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)
208         movl    $0, -224(%rbp)
209         movl    $48, -220(%rbp)
210         leaq    16(%rbp), %rax
211         movq    %rax, -216(%rbp)
212         leaq    -176(%rbp), %rdx
213         movq    %rdx, -208(%rbp)
214         leaq    -224(%rbp), %rsi
215         movq    %r10, %rdi
216         movq    %rsp, %rdx
217         call    ffi_closure_UNIX64_inner@PLT
219         cmpl    $FFI_TYPE_FLOAT, %eax
220         je      1f
221         cmpl    $FFI_TYPE_DOUBLE, %eax
222         je      2f
223         cmpl    $FFI_TYPE_LONGDOUBLE, %eax
224         je      3f
225         cmpl    $FFI_TYPE_STRUCT, %eax
226         je      4f
227         popq    %rax
228         leave
229         ret
232 3:      
233         movaps  -240(%rbp), %xmm0
234         leave
235         ret
237         leave
238         ret
239 .LFE2:  
240                 
241         .section        .eh_frame,EH_FRAME_FLAGS,@progbits
242 .Lframe0:
243         .long   .LECIE1-.LSCIE1
244 .LSCIE1:
245         .long   0x0
246         .byte   0x1
247         .string "zR"
248         .uleb128 0x1
249         .sleb128 -8
250         .byte   0x10
251         .uleb128 0x1
252         .byte   0x1b
253         .byte   0xc
254         .uleb128 0x7
255         .uleb128 0x8
256         .byte   0x90
257         .uleb128 0x1
258         .align 8
259 .LECIE1:
260 .LSFDE1:
261         .long   .LEFDE1-.LASFDE1
262 .LASFDE1:
263         .long   .LASFDE1-.Lframe0
265         .long   .LFB1-.
266         .long   .LFE1-.LFB1
267         .uleb128 0x0
268         .byte   0x4             # DW_CFA_advance_loc4
269         .long   .LCFI0-.LFB1
270         .byte   0xe             # DW_CFA_def_cfa_offset
271         .uleb128 0x10
272         .byte   0x86            # DW_CFA_offset: r6 at cfa-16
273         .uleb128 0x2
274         .byte   0x4             # DW_CFA_advance_loc4
275         .long   .LCFI1-.LCFI0
276         .byte   0x86            # DW_CFA_offset: r6 at cfa-16
277         .uleb128 0x2
278         .byte   0xd             # DW_CFA_def_cfa_reg: r6
279         .uleb128 0x6
280         .align 8
281 .LEFDE1:
282 .LSFDE3:
283         .long   .LEFDE3-.LASFDE3        # FDE Length
284 .LASFDE3:
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
291         .long   .LCFI10-.LFB2
292         .byte   0xe     # DW_CFA_def_cfa_offset
293         .uleb128 0x10
294         .byte   0x86    # DW_CFA_offset, column 0x6
295         .uleb128 0x2
296         .byte   0x4     # DW_CFA_advance_loc4
297         .long   .LCFI11-.LCFI10
298         .byte   0xd     # DW_CFA_def_cfa_register
299         .uleb128 0x6
300         .align 8
301 .LEFDE3:
303 #endif /* __x86_64__  */