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