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 ----------------------------------------------------------------------- */
30 #include <fficonfig.h>
47 /* Make room for all of the new args. */
53 /* Place all of the ffi_prep_args in position */
59 /* Return stack to previous state and call the function */
64 /* Load %ecx with the return type code */
67 /* Protect %esi. We're going to pop it in the epilogue. */
70 /* If the return value pointer is NULL, assume no return value. */
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
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 */
104 add (%esi, %ecx, 4), %esi
107 /* Sign/zero extend as appropriate. */
125 /* Load %ecx with the pointer to storage for the return value */
131 /* Load %ecx with the pointer to storage for the return value */
137 /* Load %ecx with the pointer to storage for the return value */
143 /* Load %ecx with the pointer to storage for the return value */
150 /* Load %ecx with the pointer to storage for the return value */
156 /* Load %ecx with the pointer to storage for the return value */
162 /* Load %ecx with the pointer to storage for the return value */
180 FFI_HIDDEN (ffi_closure_SYSV)
181 .globl _ffi_closure_SYSV
191 movl %edx, -12(%ebp) /* resp */
193 movl %edx, 4(%esp) /* args = __builtin_dwarf_cfa () */
195 movl %edx, (%esp) /* &resp */
198 call L_ffi_closure_SYSV_inner$stub
201 cmpl $FFI_TYPE_INT, %eax
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
208 cmpl $FFI_TYPE_UINT8, %eax
211 0: cmpl $FFI_TYPE_FLOAT, %eax
213 cmpl $FFI_TYPE_DOUBLE, %eax
215 cmpl $FFI_TYPE_LONGDOUBLE, %eax
217 cmpl $FFI_TYPE_SINT64, %eax
219 cmpl $FFI_TYPE_SMALL_STRUCT_1B, %eax
221 cmpl $FFI_TYPE_SMALL_STRUCT_2B, %eax
223 cmpl $FFI_TYPE_STRUCT, %eax
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
266 FFI_HIDDEN (ffi_closure_raw_SYSV)
267 .globl _ffi_closure_raw_SYSV
269 _ffi_closure_raw_SYSV:
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 */
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
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
295 cmpl $FFI_TYPE_UINT8, %eax
298 cmpl $FFI_TYPE_FLOAT, %eax
300 cmpl $FFI_TYPE_DOUBLE, %eax
302 cmpl $FFI_TYPE_LONGDOUBLE, %eax
304 cmpl $FFI_TYPE_SINT64, %eax
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
338 .set L$set$0,LECIE1-LSCIE1
356 .globl _ffi_call_SYSV.eh
359 .set L$set$1,LEFDE1-LASFDE1
362 .long LASFDE1-EH_frame1
364 .set L$set$2,.LFE1-.LFB1
368 .set L$set$3,.LCFI0-.LFB1
375 .set L$set$4,.LCFI1-.LCFI0
381 .globl _ffi_closure_SYSV.eh
382 _ffi_closure_SYSV.eh:
384 .set L$set$5,LEFDE2-LASFDE2
387 .long LASFDE2-EH_frame1
389 .set L$set$6,.LFE2-.LFB2
393 .set L$set$7,.LCFI2-.LFB2
400 .set L$set$8,.LCFI3-.LCFI2
409 .globl _ffi_closure_raw_SYSV.eh
410 _ffi_closure_raw_SYSV.eh:
412 .set L$set$10,LEFDE3-LASFDE3
415 .long LASFDE3-EH_frame1
417 .set L$set$11,.LFE3-.LFB3
421 .set L$set$12,.LCFI4-.LFB3
428 .set L$set$13,.LCFI5-.LCFI4
433 .set L$set$14,.LCFI6-.LCFI5
442 #endif /* ifndef __x86_64__ */