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,
     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    */
     28 
     29 #ifndef __x86_64__
     30 
     31 #define LIBFFI_ASM
     32 #include <fficonfig.h>
     33 #include <ffi.h>
     34 
     35 .text
     36 
     37 .globl _ffi_prep_args
     38 
     39 	.align 4
     40 .globl _ffi_call_SYSV
     41 
     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
     52 
     53 	movl  %esp,%eax
     54 
     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)
     60 
     61 	/* Return stack to previous state and call the function  */
     62 	addl  $16,%esp
     63 
     64 	call  *28(%ebp)
     65 
     66 	/* Load %ecx with the return type code  */
     67 	movl  20(%ebp),%ecx
     68 
     69 	/* Protect %esi.  We're going to pop it in the epilogue.  */
     70 	pushl %esi
     71 
     72 	/* If the return value pointer is NULL, assume no return value.  */
     73 	cmpl  $0,24(%ebp)
     74 	jne  0f
     75 
     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)
     81 
     82 	jmp   epilogue
     83 0:
     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 */
    104 1:
    105 	pop  %esi
    106 	add  (%esi, %ecx, 4), %esi
    107 	jmp  *%esi
    108 
    109 	/* Sign/zero extend as appropriate.  */
    110 retsint8:
    111 	movsbl  %al, %eax
    112 	jmp  retint
    113 
    114 retsint16:
    115 	movswl  %ax, %eax
    116 	jmp  retint
    117 
    118 retuint8:
    119 	movzbl  %al, %eax
    120 	jmp  retint
    121 
    122 retuint16:
    123 	movzwl  %ax, %eax
    124 	jmp  retint
    125 
    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
    131 
    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
    137 
    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
    143 
    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
    150 
    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
    156 
    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
    162 
    163 retint:
    164 	/* Load %ecx with the pointer to storage for the return value  */
    165 	movl  24(%ebp),%ecx
    166 	movl  %eax,0(%ecx)
    167 
    168 retstruct:
    169 	/* Nothing to do!  */
    170 
    171 noretval:
    172 epilogue:
    173 	popl %esi
    174 	movl %ebp,%esp
    175 	popl %ebp
    176 	ret
    177 
    178 .LFE1:
    179 .ffi_call_SYSV_end:
    180 
    181 	.align	4
    182 FFI_HIDDEN (ffi_closure_SYSV)
    183 .globl _ffi_closure_SYSV
    184 
    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
    205 
    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
    212 
    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:
    259 
    260 #if !FFI_NO_RAW_API
    261 
    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
    266 
    267 	.align	4
    268 FFI_HIDDEN (ffi_closure_raw_SYSV)
    269 .globl _ffi_closure_raw_SYSV
    270 
    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
    292 
    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
    299 0:
    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
    331 
    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
    336 
    337 
    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:
    408 
    409 #if !FFI_NO_RAW_API
    410 
    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:
    441 
    442 #endif
    443 
    444 #endif /* ifndef __x86_64__ */
    445