Merge -r 127928:132243 from trunk
[official-gcc.git] / libffi / src / x86 / darwin.S
blobeeee8020383b1e7e0f1afae6143f0fd19f258dda
1 /* -----------------------------------------------------------------------
2    darwin.S - Copyright (c) 1996, 1998, 2001, 2002, 2003, 2005  Red Hat, Inc.
3         Copyright (C) 2008  Free Software Foundation, Inc.
5    X86 Foreign Function Interface
7    Permission is hereby granted, free of charge, to any person obtaining
8    a copy of this software and associated documentation files (the
9    ``Software''), to deal in the Software without restriction, including
10    without limitation the rights to use, copy, modify, merge, publish,
11    distribute, sublicense, and/or sell copies of the Software, and to
12    permit persons to whom the Software is furnished to do so, subject to
13    the following conditions:
15    The above copyright notice and this permission notice shall be included
16    in all copies or substantial portions of the Software.
18    THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
19    OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21    IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
22    OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
23    ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24    OTHER DEALINGS IN THE SOFTWARE.
25    ----------------------------------------------------------------------- */
27 #ifndef __x86_64__
29 #define LIBFFI_ASM      
30 #include <fficonfig.h>
31 #include <ffi.h>
33 .text
35 .globl _ffi_prep_args
37         .align 4
38 .globl _ffi_call_SYSV
40 _ffi_call_SYSV:
41 .LFB1:
42         pushl %ebp
43 .LCFI0:
44         movl  %esp,%ebp
45 .LCFI1:
46         subl $8,%esp
47         /* Make room for all of the new args.  */
48         movl  16(%ebp),%ecx
49         subl  %ecx,%esp
51         movl  %esp,%eax
53         /* Place all of the ffi_prep_args in position  */
54         subl  $8,%esp
55         pushl 12(%ebp)
56         pushl %eax
57         call  *8(%ebp)
59         /* Return stack to previous state and call the function  */
60         addl  $16,%esp  
62         call  *28(%ebp)
64         /* Load %ecx with the return type code  */
65         movl  20(%ebp),%ecx     
67         /* Protect %esi.  We're going to pop it in the epilogue.  */
68         pushl %esi
70         /* If the return value pointer is NULL, assume no return value.  */
71         cmpl  $0,24(%ebp)
72         jne  0f
74         /* Even if there is no space for the return value, we are 
75            obliged to handle floating-point values.  */
76         cmpl  $FFI_TYPE_FLOAT,%ecx
77         jne   noretval
78         fstp  %st(0)
80         jmp   epilogue
82         .align 4
83         call 1f
84 .Lstore_table:
85         .long   noretval-.Lstore_table          /* FFI_TYPE_VOID */
86         .long   retint-.Lstore_table            /* FFI_TYPE_INT */
87         .long   retfloat-.Lstore_table          /* FFI_TYPE_FLOAT */
88         .long   retdouble-.Lstore_table         /* FFI_TYPE_DOUBLE */
89         .long   retlongdouble-.Lstore_table     /* FFI_TYPE_LONGDOUBLE */
90         .long   retuint8-.Lstore_table          /* FFI_TYPE_UINT8 */
91         .long   retsint8-.Lstore_table          /* FFI_TYPE_SINT8 */
92         .long   retuint16-.Lstore_table         /* FFI_TYPE_UINT16 */
93         .long   retsint16-.Lstore_table         /* FFI_TYPE_SINT16 */
94         .long   retint-.Lstore_table            /* FFI_TYPE_UINT32 */
95         .long   retint-.Lstore_table            /* FFI_TYPE_SINT32 */
96         .long   retint64-.Lstore_table          /* FFI_TYPE_UINT64 */
97         .long   retint64-.Lstore_table          /* FFI_TYPE_SINT64 */
98         .long   retstruct-.Lstore_table         /* FFI_TYPE_STRUCT */
99         .long   retint-.Lstore_table            /* FFI_TYPE_POINTER */
100         .long   retstruct1b-.Lstore_table       /* FFI_TYPE_SMALL_STRUCT_1B */
101         .long   retstruct2b-.Lstore_table       /* FFI_TYPE_SMALL_STRUCT_2B */
103         pop  %esi
104         add  (%esi, %ecx, 4), %esi
105         jmp  *%esi
107         /* Sign/zero extend as appropriate.  */
108 retsint8:
109         movsbl  %al, %eax
110         jmp  retint
112 retsint16:
113         movswl  %ax, %eax
114         jmp  retint
116 retuint8:
117         movzbl  %al, %eax
118         jmp  retint
120 retuint16:
121         movzwl  %ax, %eax
122         jmp  retint
124 retfloat:
125         /* Load %ecx with the pointer to storage for the return value  */
126         movl  24(%ebp),%ecx
127         fstps (%ecx)
128         jmp   epilogue
130 retdouble:
131         /* Load %ecx with the pointer to storage for the return value  */
132         movl  24(%ebp),%ecx
133         fstpl (%ecx)
134         jmp   epilogue
136 retlongdouble:
137         /* Load %ecx with the pointer to storage for the return value  */
138         movl  24(%ebp),%ecx
139         fstpt (%ecx)
140         jmp   epilogue
142 retint64:
143         /* Load %ecx with the pointer to storage for the return value  */
144         movl  24(%ebp),%ecx
145         movl  %eax,0(%ecx)
146         movl  %edx,4(%ecx)
147         jmp   epilogue
149 retstruct1b:
150         /* Load %ecx with the pointer to storage for the return value  */
151         movl  24(%ebp),%ecx
152         movb  %al,0(%ecx)
153         jmp   epilogue
155 retstruct2b:
156         /* Load %ecx with the pointer to storage for the return value  */
157         movl  24(%ebp),%ecx
158         movw  %ax,0(%ecx)
159         jmp   epilogue
161 retint:
162         /* Load %ecx with the pointer to storage for the return value  */
163         movl  24(%ebp),%ecx
164         movl  %eax,0(%ecx)
166 retstruct:
167         /* Nothing to do!  */
169 noretval:
170 epilogue:
171         popl %esi
172         movl %ebp,%esp
173         popl %ebp
174         ret
176 .LFE1:
177 .ffi_call_SYSV_end:
179         .align  4
180 FFI_HIDDEN (ffi_closure_SYSV)
181 .globl _ffi_closure_SYSV
183 _ffi_closure_SYSV:
184 .LFB2:
185         pushl   %ebp
186 .LCFI2:
187         movl    %esp, %ebp
188 .LCFI3:
189         subl    $40, %esp
190         leal    -24(%ebp), %edx
191         movl    %edx, -12(%ebp) /* resp */
192         leal    8(%ebp), %edx
193         movl    %edx, 4(%esp)   /* args = __builtin_dwarf_cfa () */
194         leal    -12(%ebp), %edx
195         movl    %edx, (%esp)    /* &resp */
196         movl    %ebx, 8(%esp)
197 .LCFI7:
198         call    L_ffi_closure_SYSV_inner$stub
199         movl    8(%esp), %ebx
200         movl    -12(%ebp), %ecx
201         cmpl    $FFI_TYPE_INT, %eax
202         je      .Lcls_retint
204         /* Handle FFI_TYPE_UINT8, FFI_TYPE_SINT8, FFI_TYPE_UINT16,
205            FFI_TYPE_SINT16, FFI_TYPE_UINT32, FFI_TYPE_SINT32.  */
206         cmpl    $FFI_TYPE_UINT64, %eax
207         jge     0f
208         cmpl    $FFI_TYPE_UINT8, %eax
209         jge     .Lcls_retint
211 0:      cmpl    $FFI_TYPE_FLOAT, %eax
212         je      .Lcls_retfloat
213         cmpl    $FFI_TYPE_DOUBLE, %eax
214         je      .Lcls_retdouble
215         cmpl    $FFI_TYPE_LONGDOUBLE, %eax
216         je      .Lcls_retldouble
217         cmpl    $FFI_TYPE_SINT64, %eax
218         je      .Lcls_retllong
219         cmpl    $FFI_TYPE_SMALL_STRUCT_1B, %eax
220         je      .Lcls_retstruct1b
221         cmpl    $FFI_TYPE_SMALL_STRUCT_2B, %eax
222         je      .Lcls_retstruct2b
223         cmpl    $FFI_TYPE_STRUCT, %eax
224         je      .Lcls_retstruct
225 .Lcls_epilogue:
226         movl    %ebp, %esp
227         popl    %ebp
228         ret
229 .Lcls_retint:
230         movl    (%ecx), %eax
231         jmp     .Lcls_epilogue
232 .Lcls_retfloat:
233         flds    (%ecx)
234         jmp     .Lcls_epilogue
235 .Lcls_retdouble:
236         fldl    (%ecx)
237         jmp     .Lcls_epilogue
238 .Lcls_retldouble:
239         fldt    (%ecx)
240         jmp     .Lcls_epilogue
241 .Lcls_retllong:
242         movl    (%ecx), %eax
243         movl    4(%ecx), %edx
244         jmp     .Lcls_epilogue
245 .Lcls_retstruct1b:
246         movsbl  (%ecx), %eax
247         jmp     .Lcls_epilogue
248 .Lcls_retstruct2b:
249         movswl  (%ecx), %eax
250         jmp     .Lcls_epilogue
251 .Lcls_retstruct:
252         lea -8(%ebp),%esp
253         movl    %ebp, %esp
254         popl    %ebp
255         ret $4
256 .LFE2:
258 #if !FFI_NO_RAW_API
260 #define RAW_CLOSURE_CIF_OFFSET ((FFI_TRAMPOLINE_SIZE + 3) & ~3)
261 #define RAW_CLOSURE_FUN_OFFSET (RAW_CLOSURE_CIF_OFFSET + 4)
262 #define RAW_CLOSURE_USER_DATA_OFFSET (RAW_CLOSURE_FUN_OFFSET + 4)
263 #define CIF_FLAGS_OFFSET 20
265         .align  4
266 FFI_HIDDEN (ffi_closure_raw_SYSV)
267 .globl _ffi_closure_raw_SYSV
269 _ffi_closure_raw_SYSV:
270 .LFB3:
271         pushl   %ebp
272 .LCFI4:
273         movl    %esp, %ebp
274 .LCFI5:
275         pushl   %esi
276 .LCFI6:
277         subl    $36, %esp
278         movl    RAW_CLOSURE_CIF_OFFSET(%eax), %esi       /* closure->cif */
279         movl    RAW_CLOSURE_USER_DATA_OFFSET(%eax), %edx /* closure->user_data */
280         movl    %edx, 12(%esp)  /* user_data */
281         leal    8(%ebp), %edx   /* __builtin_dwarf_cfa () */
282         movl    %edx, 8(%esp)   /* raw_args */
283         leal    -24(%ebp), %edx
284         movl    %edx, 4(%esp)   /* &res */
285         movl    %esi, (%esp)    /* cif */
286         call    *RAW_CLOSURE_FUN_OFFSET(%eax)            /* closure->fun */
287         movl    CIF_FLAGS_OFFSET(%esi), %eax             /* rtype */
288         cmpl    $FFI_TYPE_INT, %eax
289         je      .Lrcls_retint
291         /* Handle FFI_TYPE_UINT8, FFI_TYPE_SINT8, FFI_TYPE_UINT16,
292            FFI_TYPE_SINT16, FFI_TYPE_UINT32, FFI_TYPE_SINT32.  */
293         cmpl    $FFI_TYPE_UINT64, %eax
294         jge     0f
295         cmpl    $FFI_TYPE_UINT8, %eax
296         jge     .Lrcls_retint
298         cmpl    $FFI_TYPE_FLOAT, %eax
299         je      .Lrcls_retfloat
300         cmpl    $FFI_TYPE_DOUBLE, %eax
301         je      .Lrcls_retdouble
302         cmpl    $FFI_TYPE_LONGDOUBLE, %eax
303         je      .Lrcls_retldouble
304         cmpl    $FFI_TYPE_SINT64, %eax
305         je      .Lrcls_retllong
306 .Lrcls_epilogue:
307         addl    $36, %esp
308         popl    %esi
309         popl    %ebp
310         ret
311 .Lrcls_retint:
312         movl    -24(%ebp), %eax
313         jmp     .Lrcls_epilogue
314 .Lrcls_retfloat:
315         flds    -24(%ebp)
316         jmp     .Lrcls_epilogue
317 .Lrcls_retdouble:
318         fldl    -24(%ebp)
319         jmp     .Lrcls_epilogue
320 .Lrcls_retldouble:
321         fldt    -24(%ebp)
322         jmp     .Lrcls_epilogue
323 .Lrcls_retllong:
324         movl    -24(%ebp), %eax
325         movl    -20(%ebp), %edx
326         jmp     .Lrcls_epilogue
327 .LFE3:
328 #endif
330 .section __IMPORT,__jump_table,symbol_stubs,self_modifying_code+pure_instructions,5
331 L_ffi_closure_SYSV_inner$stub:
332         .indirect_symbol _ffi_closure_SYSV_inner
333         hlt ; hlt ; hlt ; hlt ; hlt
336 .section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support
337 EH_frame1:
338         .set    L$set$0,LECIE1-LSCIE1
339         .long   L$set$0
340 LSCIE1:
341         .long   0x0
342         .byte   0x1
343         .ascii "zR\0"
344         .byte   0x1
345         .byte   0x7c
346         .byte   0x8
347         .byte   0x1
348         .byte   0x10
349         .byte   0xc
350         .byte   0x5
351         .byte   0x4
352         .byte   0x88
353         .byte   0x1
354         .align 2
355 LECIE1:
356 .globl _ffi_call_SYSV.eh
357 _ffi_call_SYSV.eh:
358 LSFDE1:
359         .set    L$set$1,LEFDE1-LASFDE1
360         .long   L$set$1
361 LASFDE1:
362         .long   LASFDE1-EH_frame1
363         .long   .LFB1-.
364         .set L$set$2,.LFE1-.LFB1
365         .long L$set$2
366         .byte   0x0
367         .byte   0x4
368         .set L$set$3,.LCFI0-.LFB1
369         .long L$set$3
370         .byte   0xe
371         .byte   0x8
372         .byte   0x84
373         .byte   0x2
374         .byte   0x4
375         .set L$set$4,.LCFI1-.LCFI0
376         .long L$set$4
377         .byte   0xd
378         .byte   0x4
379         .align 2
380 LEFDE1:
381 .globl _ffi_closure_SYSV.eh
382 _ffi_closure_SYSV.eh:
383 LSFDE2:
384         .set    L$set$5,LEFDE2-LASFDE2
385         .long   L$set$5
386 LASFDE2:
387         .long   LASFDE2-EH_frame1
388         .long   .LFB2-.
389         .set L$set$6,.LFE2-.LFB2
390         .long L$set$6
391         .byte   0x0
392         .byte   0x4
393         .set L$set$7,.LCFI2-.LFB2
394         .long L$set$7
395         .byte   0xe
396         .byte   0x8
397         .byte   0x84
398         .byte   0x2
399         .byte   0x4
400         .set L$set$8,.LCFI3-.LCFI2
401         .long L$set$8
402         .byte   0xd
403         .byte   0x4
404         .align 2
405 LEFDE2:
407 #if !FFI_NO_RAW_API
409 .globl _ffi_closure_raw_SYSV.eh
410 _ffi_closure_raw_SYSV.eh:
411 LSFDE3:
412         .set    L$set$10,LEFDE3-LASFDE3
413         .long   L$set$10
414 LASFDE3:
415         .long   LASFDE3-EH_frame1
416         .long   .LFB3-.
417         .set L$set$11,.LFE3-.LFB3
418         .long L$set$11
419         .byte   0x0
420         .byte   0x4
421         .set L$set$12,.LCFI4-.LFB3
422         .long L$set$12
423         .byte   0xe
424         .byte   0x8
425         .byte   0x84
426         .byte   0x2
427         .byte   0x4
428         .set L$set$13,.LCFI5-.LCFI4
429         .long L$set$13
430         .byte   0xd
431         .byte   0x4
432         .byte   0x4
433         .set L$set$14,.LCFI6-.LCFI5
434         .long L$set$14
435         .byte   0x85
436         .byte   0x3
437         .align 2
438 LEFDE3:
440 #endif
442 #endif /* ifndef __x86_64__ */