Fix typo.
[official-gcc.git] / libffi / src / x86 / darwin.S
blob8f0f0707aaf040bda76d1172c1bd7d398421fc70
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,
19    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21    NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
22    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25    DEALINGS IN THE SOFTWARE.
26    -----------------------------------------------------------------------
27    */
29 #ifndef __x86_64__
31 #define LIBFFI_ASM      
32 #include <fficonfig.h>
33 #include <ffi.h>
35 .text
37 .globl _ffi_prep_args
39         .align 4
40 .globl _ffi_call_SYSV
42 _ffi_call_SYSV:
43 .LFB1:
44         pushl %ebp
45 .LCFI0:
46         movl  %esp,%ebp
47 .LCFI1:
48         subl $8,%esp
49         /* Make room for all of the new args.  */
50         movl  16(%ebp),%ecx
51         subl  %ecx,%esp
53         movl  %esp,%eax
55         /* Place all of the ffi_prep_args in position  */
56         subl  $8,%esp
57         pushl 12(%ebp)
58         pushl %eax
59         call  *8(%ebp)
61         /* Return stack to previous state and call the function  */
62         addl  $16,%esp  
64         call  *28(%ebp)
66         /* Load %ecx with the return type code  */
67         movl  20(%ebp),%ecx     
69         /* Protect %esi.  We're going to pop it in the epilogue.  */
70         pushl %esi
72         /* If the return value pointer is NULL, assume no return value.  */
73         cmpl  $0,24(%ebp)
74         jne  0f
76         /* Even if there is no space for the return value, we are 
77            obliged to handle floating-point values.  */
78         cmpl  $FFI_TYPE_FLOAT,%ecx
79         jne   noretval
80         fstp  %st(0)
82         jmp   epilogue
84         .align 4
85         call 1f
86 .Lstore_table:
87         .long   noretval-.Lstore_table          /* FFI_TYPE_VOID */
88         .long   retint-.Lstore_table            /* FFI_TYPE_INT */
89         .long   retfloat-.Lstore_table          /* FFI_TYPE_FLOAT */
90         .long   retdouble-.Lstore_table         /* FFI_TYPE_DOUBLE */
91         .long   retlongdouble-.Lstore_table     /* FFI_TYPE_LONGDOUBLE */
92         .long   retuint8-.Lstore_table          /* FFI_TYPE_UINT8 */
93         .long   retsint8-.Lstore_table          /* FFI_TYPE_SINT8 */
94         .long   retuint16-.Lstore_table         /* FFI_TYPE_UINT16 */
95         .long   retsint16-.Lstore_table         /* FFI_TYPE_SINT16 */
96         .long   retint-.Lstore_table            /* FFI_TYPE_UINT32 */
97         .long   retint-.Lstore_table            /* FFI_TYPE_SINT32 */
98         .long   retint64-.Lstore_table          /* FFI_TYPE_UINT64 */
99         .long   retint64-.Lstore_table          /* FFI_TYPE_SINT64 */
100         .long   retstruct-.Lstore_table         /* FFI_TYPE_STRUCT */
101         .long   retint-.Lstore_table            /* FFI_TYPE_POINTER */
102         .long   retstruct1b-.Lstore_table       /* FFI_TYPE_SMALL_STRUCT_1B */
103         .long   retstruct2b-.Lstore_table       /* FFI_TYPE_SMALL_STRUCT_2B */
105         pop  %esi
106         add  (%esi, %ecx, 4), %esi
107         jmp  *%esi
109         /* Sign/zero extend as appropriate.  */
110 retsint8:
111         movsbl  %al, %eax
112         jmp  retint
114 retsint16:
115         movswl  %ax, %eax
116         jmp  retint
118 retuint8:
119         movzbl  %al, %eax
120         jmp  retint
122 retuint16:
123         movzwl  %ax, %eax
124         jmp  retint
126 retfloat:
127         /* Load %ecx with the pointer to storage for the return value  */
128         movl  24(%ebp),%ecx
129         fstps (%ecx)
130         jmp   epilogue
132 retdouble:
133         /* Load %ecx with the pointer to storage for the return value  */
134         movl  24(%ebp),%ecx
135         fstpl (%ecx)
136         jmp   epilogue
138 retlongdouble:
139         /* Load %ecx with the pointer to storage for the return value  */
140         movl  24(%ebp),%ecx
141         fstpt (%ecx)
142         jmp   epilogue
144 retint64:
145         /* Load %ecx with the pointer to storage for the return value  */
146         movl  24(%ebp),%ecx
147         movl  %eax,0(%ecx)
148         movl  %edx,4(%ecx)
149         jmp   epilogue
151 retstruct1b:
152         /* Load %ecx with the pointer to storage for the return value  */
153         movl  24(%ebp),%ecx
154         movb  %al,0(%ecx)
155         jmp   epilogue
157 retstruct2b:
158         /* Load %ecx with the pointer to storage for the return value  */
159         movl  24(%ebp),%ecx
160         movw  %ax,0(%ecx)
161         jmp   epilogue
163 retint:
164         /* Load %ecx with the pointer to storage for the return value  */
165         movl  24(%ebp),%ecx
166         movl  %eax,0(%ecx)
168 retstruct:
169         /* Nothing to do!  */
171 noretval:
172 epilogue:
173         popl %esi
174         movl %ebp,%esp
175         popl %ebp
176         ret
178 .LFE1:
179 .ffi_call_SYSV_end:
181         .align  4
182 FFI_HIDDEN (ffi_closure_SYSV)
183 .globl _ffi_closure_SYSV
185 _ffi_closure_SYSV:
186 .LFB2:
187         pushl   %ebp
188 .LCFI2:
189         movl    %esp, %ebp
190 .LCFI3:
191         subl    $40, %esp
192         leal    -24(%ebp), %edx
193         movl    %edx, -12(%ebp) /* resp */
194         leal    8(%ebp), %edx
195         movl    %edx, 4(%esp)   /* args = __builtin_dwarf_cfa () */
196         leal    -12(%ebp), %edx
197         movl    %edx, (%esp)    /* &resp */
198         movl    %ebx, 8(%esp)
199 .LCFI7:
200         call    L_ffi_closure_SYSV_inner$stub
201         movl    8(%esp), %ebx
202         movl    -12(%ebp), %ecx
203         cmpl    $FFI_TYPE_INT, %eax
204         je      .Lcls_retint
206         /* Handle FFI_TYPE_UINT8, FFI_TYPE_SINT8, FFI_TYPE_UINT16,
207            FFI_TYPE_SINT16, FFI_TYPE_UINT32, FFI_TYPE_SINT32.  */
208         cmpl    $FFI_TYPE_UINT64, %eax
209         jge     0f
210         cmpl    $FFI_TYPE_UINT8, %eax
211         jge     .Lcls_retint
213 0:      cmpl    $FFI_TYPE_FLOAT, %eax
214         je      .Lcls_retfloat
215         cmpl    $FFI_TYPE_DOUBLE, %eax
216         je      .Lcls_retdouble
217         cmpl    $FFI_TYPE_LONGDOUBLE, %eax
218         je      .Lcls_retldouble
219         cmpl    $FFI_TYPE_SINT64, %eax
220         je      .Lcls_retllong
221         cmpl    $FFI_TYPE_SMALL_STRUCT_1B, %eax
222         je      .Lcls_retstruct1b
223         cmpl    $FFI_TYPE_SMALL_STRUCT_2B, %eax
224         je      .Lcls_retstruct2b
225         cmpl    $FFI_TYPE_STRUCT, %eax
226         je      .Lcls_retstruct
227 .Lcls_epilogue:
228         movl    %ebp, %esp
229         popl    %ebp
230         ret
231 .Lcls_retint:
232         movl    (%ecx), %eax
233         jmp     .Lcls_epilogue
234 .Lcls_retfloat:
235         flds    (%ecx)
236         jmp     .Lcls_epilogue
237 .Lcls_retdouble:
238         fldl    (%ecx)
239         jmp     .Lcls_epilogue
240 .Lcls_retldouble:
241         fldt    (%ecx)
242         jmp     .Lcls_epilogue
243 .Lcls_retllong:
244         movl    (%ecx), %eax
245         movl    4(%ecx), %edx
246         jmp     .Lcls_epilogue
247 .Lcls_retstruct1b:
248         movsbl  (%ecx), %eax
249         jmp     .Lcls_epilogue
250 .Lcls_retstruct2b:
251         movswl  (%ecx), %eax
252         jmp     .Lcls_epilogue
253 .Lcls_retstruct:
254         lea -8(%ebp),%esp
255         movl    %ebp, %esp
256         popl    %ebp
257         ret $4
258 .LFE2:
260 #if !FFI_NO_RAW_API
262 #define RAW_CLOSURE_CIF_OFFSET ((FFI_TRAMPOLINE_SIZE + 3) & ~3)
263 #define RAW_CLOSURE_FUN_OFFSET (RAW_CLOSURE_CIF_OFFSET + 4)
264 #define RAW_CLOSURE_USER_DATA_OFFSET (RAW_CLOSURE_FUN_OFFSET + 4)
265 #define CIF_FLAGS_OFFSET 20
267         .align  4
268 FFI_HIDDEN (ffi_closure_raw_SYSV)
269 .globl _ffi_closure_raw_SYSV
271 _ffi_closure_raw_SYSV:
272 .LFB3:
273         pushl   %ebp
274 .LCFI4:
275         movl    %esp, %ebp
276 .LCFI5:
277         pushl   %esi
278 .LCFI6:
279         subl    $36, %esp
280         movl    RAW_CLOSURE_CIF_OFFSET(%eax), %esi       /* closure->cif */
281         movl    RAW_CLOSURE_USER_DATA_OFFSET(%eax), %edx /* closure->user_data */
282         movl    %edx, 12(%esp)  /* user_data */
283         leal    8(%ebp), %edx   /* __builtin_dwarf_cfa () */
284         movl    %edx, 8(%esp)   /* raw_args */
285         leal    -24(%ebp), %edx
286         movl    %edx, 4(%esp)   /* &res */
287         movl    %esi, (%esp)    /* cif */
288         call    *RAW_CLOSURE_FUN_OFFSET(%eax)            /* closure->fun */
289         movl    CIF_FLAGS_OFFSET(%esi), %eax             /* rtype */
290         cmpl    $FFI_TYPE_INT, %eax
291         je      .Lrcls_retint
293         /* Handle FFI_TYPE_UINT8, FFI_TYPE_SINT8, FFI_TYPE_UINT16,
294            FFI_TYPE_SINT16, FFI_TYPE_UINT32, FFI_TYPE_SINT32.  */
295         cmpl    $FFI_TYPE_UINT64, %eax
296         jge     0f
297         cmpl    $FFI_TYPE_UINT8, %eax
298         jge     .Lrcls_retint
300         cmpl    $FFI_TYPE_FLOAT, %eax
301         je      .Lrcls_retfloat
302         cmpl    $FFI_TYPE_DOUBLE, %eax
303         je      .Lrcls_retdouble
304         cmpl    $FFI_TYPE_LONGDOUBLE, %eax
305         je      .Lrcls_retldouble
306         cmpl    $FFI_TYPE_SINT64, %eax
307         je      .Lrcls_retllong
308 .Lrcls_epilogue:
309         addl    $36, %esp
310         popl    %esi
311         popl    %ebp
312         ret
313 .Lrcls_retint:
314         movl    -24(%ebp), %eax
315         jmp     .Lrcls_epilogue
316 .Lrcls_retfloat:
317         flds    -24(%ebp)
318         jmp     .Lrcls_epilogue
319 .Lrcls_retdouble:
320         fldl    -24(%ebp)
321         jmp     .Lrcls_epilogue
322 .Lrcls_retldouble:
323         fldt    -24(%ebp)
324         jmp     .Lrcls_epilogue
325 .Lrcls_retllong:
326         movl    -24(%ebp), %eax
327         movl    -20(%ebp), %edx
328         jmp     .Lrcls_epilogue
329 .LFE3:
330 #endif
332 .section __IMPORT,__jump_table,symbol_stubs,self_modifying_code+pure_instructions,5
333 L_ffi_closure_SYSV_inner$stub:
334         .indirect_symbol _ffi_closure_SYSV_inner
335         hlt ; hlt ; hlt ; hlt ; hlt
338 .section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support
339 EH_frame1:
340         .set    L$set$0,LECIE1-LSCIE1
341         .long   L$set$0
342 LSCIE1:
343         .long   0x0
344         .byte   0x1
345         .ascii "zR\0"
346         .byte   0x1
347         .byte   0x7c
348         .byte   0x8
349         .byte   0x1
350         .byte   0x10
351         .byte   0xc
352         .byte   0x5
353         .byte   0x4
354         .byte   0x88
355         .byte   0x1
356         .align 2
357 LECIE1:
358 .globl _ffi_call_SYSV.eh
359 _ffi_call_SYSV.eh:
360 LSFDE1:
361         .set    L$set$1,LEFDE1-LASFDE1
362         .long   L$set$1
363 LASFDE1:
364         .long   LASFDE1-EH_frame1
365         .long   .LFB1-.
366         .set L$set$2,.LFE1-.LFB1
367         .long L$set$2
368         .byte   0x0
369         .byte   0x4
370         .set L$set$3,.LCFI0-.LFB1
371         .long L$set$3
372         .byte   0xe
373         .byte   0x8
374         .byte   0x84
375         .byte   0x2
376         .byte   0x4
377         .set L$set$4,.LCFI1-.LCFI0
378         .long L$set$4
379         .byte   0xd
380         .byte   0x4
381         .align 2
382 LEFDE1:
383 .globl _ffi_closure_SYSV.eh
384 _ffi_closure_SYSV.eh:
385 LSFDE2:
386         .set    L$set$5,LEFDE2-LASFDE2
387         .long   L$set$5
388 LASFDE2:
389         .long   LASFDE2-EH_frame1
390         .long   .LFB2-.
391         .set L$set$6,.LFE2-.LFB2
392         .long L$set$6
393         .byte   0x0
394         .byte   0x4
395         .set L$set$7,.LCFI2-.LFB2
396         .long L$set$7
397         .byte   0xe
398         .byte   0x8
399         .byte   0x84
400         .byte   0x2
401         .byte   0x4
402         .set L$set$8,.LCFI3-.LCFI2
403         .long L$set$8
404         .byte   0xd
405         .byte   0x4
406         .align 2
407 LEFDE2:
409 #if !FFI_NO_RAW_API
411 .globl _ffi_closure_raw_SYSV.eh
412 _ffi_closure_raw_SYSV.eh:
413 LSFDE3:
414         .set    L$set$10,LEFDE3-LASFDE3
415         .long   L$set$10
416 LASFDE3:
417         .long   LASFDE3-EH_frame1
418         .long   .LFB3-.
419         .set L$set$11,.LFE3-.LFB3
420         .long L$set$11
421         .byte   0x0
422         .byte   0x4
423         .set L$set$12,.LCFI4-.LFB3
424         .long L$set$12
425         .byte   0xe
426         .byte   0x8
427         .byte   0x84
428         .byte   0x2
429         .byte   0x4
430         .set L$set$13,.LCFI5-.LCFI4
431         .long L$set$13
432         .byte   0xd
433         .byte   0x4
434         .byte   0x4
435         .set L$set$14,.LCFI6-.LCFI5
436         .long L$set$14
437         .byte   0x85
438         .byte   0x3
439         .align 2
440 LEFDE3:
442 #endif
444 #endif /* ifndef __x86_64__ */