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