Home | History | Annotate | Download | only in x86
      1 /* -----------------------------------------------------------------------
      2    freebsd.S - Copyright (c) 1996, 1998, 2001, 2002, 2003, 2005  Red Hat, Inc.
      3 	       Copyright (c) 2008  Bjrn Knig
      4 
      5    X86 Foreign Function Interface for FreeBSD
      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 #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         .type    ffi_call_SYSV,@function
     41 
     42 ffi_call_SYSV:
     43 .LFB1:
     44         pushl %ebp
     45 .LCFI0:
     46         movl  %esp,%ebp
     47 .LCFI1:
     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 	pushl 12(%ebp)
     56 	pushl %eax
     57 	call  *8(%ebp)
     58 
     59 	/* Return stack to previous state and call the function  */
     60 	addl  $8,%esp
     61 
     62 	call  *28(%ebp)
     63 
     64 	/* Load %ecx with the return type code  */
     65 	movl  20(%ebp),%ecx
     66 
     67 	/* Protect %esi.  We're going to pop it in the epilogue.  */
     68 	pushl %esi
     69 
     70 	/* If the return value pointer is NULL, assume no return value.  */
     71 	cmpl  $0,24(%ebp)
     72 	jne  0f
     73 
     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
     77 	jne   noretval
     78 	fstp  %st(0)
     79 
     80         jmp   epilogue
     81 
     82 0:
     83 	call  1f
     84 
     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 
    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 .LFE1:
    178 .ffi_call_SYSV_end:
    179         .size    ffi_call_SYSV,.ffi_call_SYSV_end-ffi_call_SYSV
    180 
    181 	.align	4
    182 FFI_HIDDEN (ffi_closure_SYSV)
    183 .globl ffi_closure_SYSV
    184 	.type	ffi_closure_SYSV, @function
    185 
    186 ffi_closure_SYSV:
    187 .LFB2:
    188 	pushl	%ebp
    189 .LCFI2:
    190 	movl	%esp, %ebp
    191 .LCFI3:
    192 	subl	$40, %esp
    193 	leal	-24(%ebp), %edx
    194 	movl	%edx, -12(%ebp)	/* resp */
    195 	leal	8(%ebp), %edx
    196 	movl	%edx, 4(%esp)	/* args = __builtin_dwarf_cfa () */
    197 	leal	-12(%ebp), %edx
    198 	movl	%edx, (%esp)	/* &resp */
    199 #if defined HAVE_HIDDEN_VISIBILITY_ATTRIBUTE || !defined __PIC__
    200 	call	ffi_closure_SYSV_inner
    201 #else
    202 	movl	%ebx, 8(%esp)
    203 .LCFI7:
    204 	call	1f
    205 1:	popl	%ebx
    206 	addl	$_GLOBAL_OFFSET_TABLE_+[.-1b], %ebx
    207 	call	ffi_closure_SYSV_inner@PLT
    208 	movl	8(%esp), %ebx
    209 #endif
    210 	movl	-12(%ebp), %ecx
    211 	cmpl	$FFI_TYPE_INT, %eax
    212 	je	.Lcls_retint
    213 
    214 	/* Handle FFI_TYPE_UINT8, FFI_TYPE_SINT8, FFI_TYPE_UINT16,
    215 	   FFI_TYPE_SINT16, FFI_TYPE_UINT32, FFI_TYPE_SINT32.  */
    216 	cmpl	$FFI_TYPE_UINT64, %eax
    217 	jge	0f
    218 	cmpl	$FFI_TYPE_UINT8, %eax
    219 	jge	.Lcls_retint
    220 
    221 0:	cmpl	$FFI_TYPE_FLOAT, %eax
    222 	je	.Lcls_retfloat
    223 	cmpl	$FFI_TYPE_DOUBLE, %eax
    224 	je	.Lcls_retdouble
    225 	cmpl	$FFI_TYPE_LONGDOUBLE, %eax
    226 	je	.Lcls_retldouble
    227 	cmpl	$FFI_TYPE_SINT64, %eax
    228 	je	.Lcls_retllong
    229 	cmpl	$FFI_TYPE_SMALL_STRUCT_1B, %eax
    230 	je	.Lcls_retstruct1b
    231 	cmpl	$FFI_TYPE_SMALL_STRUCT_2B, %eax
    232 	je	.Lcls_retstruct2b
    233 	cmpl	$FFI_TYPE_STRUCT, %eax
    234 	je	.Lcls_retstruct
    235 .Lcls_epilogue:
    236 	movl	%ebp, %esp
    237 	popl	%ebp
    238 	ret
    239 .Lcls_retint:
    240 	movl	(%ecx), %eax
    241 	jmp	.Lcls_epilogue
    242 .Lcls_retfloat:
    243 	flds	(%ecx)
    244 	jmp	.Lcls_epilogue
    245 .Lcls_retdouble:
    246 	fldl	(%ecx)
    247 	jmp	.Lcls_epilogue
    248 .Lcls_retldouble:
    249 	fldt	(%ecx)
    250 	jmp	.Lcls_epilogue
    251 .Lcls_retllong:
    252 	movl	(%ecx), %eax
    253 	movl	4(%ecx), %edx
    254 	jmp	.Lcls_epilogue
    255 .Lcls_retstruct1b:
    256 	movsbl	(%ecx), %eax
    257 	jmp	.Lcls_epilogue
    258 .Lcls_retstruct2b:
    259 	movswl	(%ecx), %eax
    260 	jmp	.Lcls_epilogue
    261 .Lcls_retstruct:
    262 	movl	%ebp, %esp
    263 	popl	%ebp
    264 	ret	$4
    265 .LFE2:
    266 	.size	ffi_closure_SYSV, .-ffi_closure_SYSV
    267 
    268 #if !FFI_NO_RAW_API
    269 
    270 #define RAW_CLOSURE_CIF_OFFSET ((FFI_TRAMPOLINE_SIZE + 3) & ~3)
    271 #define RAW_CLOSURE_FUN_OFFSET (RAW_CLOSURE_CIF_OFFSET + 4)
    272 #define RAW_CLOSURE_USER_DATA_OFFSET (RAW_CLOSURE_FUN_OFFSET + 4)
    273 #define CIF_FLAGS_OFFSET 20
    274 
    275 	.align	4
    276 FFI_HIDDEN (ffi_closure_raw_SYSV)
    277 .globl ffi_closure_raw_SYSV
    278 	.type	ffi_closure_raw_SYSV, @function
    279 
    280 ffi_closure_raw_SYSV:
    281 .LFB3:
    282 	pushl	%ebp
    283 .LCFI4:
    284 	movl	%esp, %ebp
    285 .LCFI5:
    286 	pushl	%esi
    287 .LCFI6:
    288 	subl	$36, %esp
    289 	movl	RAW_CLOSURE_CIF_OFFSET(%eax), %esi	 /* closure->cif */
    290 	movl	RAW_CLOSURE_USER_DATA_OFFSET(%eax), %edx /* closure->user_data */
    291 	movl	%edx, 12(%esp)	/* user_data */
    292 	leal	8(%ebp), %edx	/* __builtin_dwarf_cfa () */
    293 	movl	%edx, 8(%esp)	/* raw_args */
    294 	leal	-24(%ebp), %edx
    295 	movl	%edx, 4(%esp)	/* &res */
    296 	movl	%esi, (%esp)	/* cif */
    297 	call	*RAW_CLOSURE_FUN_OFFSET(%eax)		 /* closure->fun */
    298 	movl	CIF_FLAGS_OFFSET(%esi), %eax		 /* rtype */
    299 	cmpl	$FFI_TYPE_INT, %eax
    300 	je	.Lrcls_retint
    301 
    302 	/* Handle FFI_TYPE_UINT8, FFI_TYPE_SINT8, FFI_TYPE_UINT16,
    303 	   FFI_TYPE_SINT16, FFI_TYPE_UINT32, FFI_TYPE_SINT32.  */
    304 	cmpl	$FFI_TYPE_UINT64, %eax
    305 	jge	0f
    306 	cmpl	$FFI_TYPE_UINT8, %eax
    307 	jge	.Lrcls_retint
    308 0:
    309 	cmpl	$FFI_TYPE_FLOAT, %eax
    310 	je	.Lrcls_retfloat
    311 	cmpl	$FFI_TYPE_DOUBLE, %eax
    312 	je	.Lrcls_retdouble
    313 	cmpl	$FFI_TYPE_LONGDOUBLE, %eax
    314 	je	.Lrcls_retldouble
    315 	cmpl	$FFI_TYPE_SINT64, %eax
    316 	je	.Lrcls_retllong
    317 .Lrcls_epilogue:
    318 	addl	$36, %esp
    319 	popl	%esi
    320 	popl	%ebp
    321 	ret
    322 .Lrcls_retint:
    323 	movl	-24(%ebp), %eax
    324 	jmp	.Lrcls_epilogue
    325 .Lrcls_retfloat:
    326 	flds	-24(%ebp)
    327 	jmp	.Lrcls_epilogue
    328 .Lrcls_retdouble:
    329 	fldl	-24(%ebp)
    330 	jmp	.Lrcls_epilogue
    331 .Lrcls_retldouble:
    332 	fldt	-24(%ebp)
    333 	jmp	.Lrcls_epilogue
    334 .Lrcls_retllong:
    335 	movl	-24(%ebp), %eax
    336 	movl	-20(%ebp), %edx
    337 	jmp	.Lrcls_epilogue
    338 .LFE3:
    339 	.size	ffi_closure_raw_SYSV, .-ffi_closure_raw_SYSV
    340 #endif
    341 
    342 	.section	.eh_frame,EH_FRAME_FLAGS,@progbits
    343 .Lframe1:
    344 	.long	.LECIE1-.LSCIE1	/* Length of Common Information Entry */
    345 .LSCIE1:
    346 	.long	0x0	/* CIE Identifier Tag */
    347 	.byte	0x1	/* CIE Version */
    348 #ifdef __PIC__
    349 	.ascii "zR\0"	/* CIE Augmentation */
    350 #else
    351 	.ascii "\0"	/* CIE Augmentation */
    352 #endif
    353 	.byte	0x1	/* .uleb128 0x1; CIE Code Alignment Factor */
    354 	.byte	0x7c	/* .sleb128 -4; CIE Data Alignment Factor */
    355 	.byte	0x8	/* CIE RA Column */
    356 #ifdef __PIC__
    357 	.byte	0x1	/* .uleb128 0x1; Augmentation size */
    358 	.byte	0x1b	/* FDE Encoding (pcrel sdata4) */
    359 #endif
    360 	.byte	0xc	/* DW_CFA_def_cfa */
    361 	.byte	0x4	/* .uleb128 0x4 */
    362 	.byte	0x4	/* .uleb128 0x4 */
    363 	.byte	0x88	/* DW_CFA_offset, column 0x8 */
    364 	.byte	0x1	/* .uleb128 0x1 */
    365 	.align 4
    366 .LECIE1:
    367 .LSFDE1:
    368 	.long	.LEFDE1-.LASFDE1	/* FDE Length */
    369 .LASFDE1:
    370 	.long	.LASFDE1-.Lframe1	/* FDE CIE offset */
    371 #ifdef __PIC__
    372 	.long	.LFB1-.	/* FDE initial location */
    373 #else
    374 	.long	.LFB1	/* FDE initial location */
    375 #endif
    376 	.long	.LFE1-.LFB1	/* FDE address range */
    377 #ifdef __PIC__
    378 	.byte	0x0	/* .uleb128 0x0; Augmentation size */
    379 #endif
    380 	.byte	0x4	/* DW_CFA_advance_loc4 */
    381 	.long	.LCFI0-.LFB1
    382 	.byte	0xe	/* DW_CFA_def_cfa_offset */
    383 	.byte	0x8	/* .uleb128 0x8 */
    384 	.byte	0x85	/* DW_CFA_offset, column 0x5 */
    385 	.byte	0x2	/* .uleb128 0x2 */
    386 	.byte	0x4	/* DW_CFA_advance_loc4 */
    387 	.long	.LCFI1-.LCFI0
    388 	.byte	0xd	/* DW_CFA_def_cfa_register */
    389 	.byte	0x5	/* .uleb128 0x5 */
    390 	.align 4
    391 .LEFDE1:
    392 .LSFDE2:
    393 	.long	.LEFDE2-.LASFDE2	/* FDE Length */
    394 .LASFDE2:
    395 	.long	.LASFDE2-.Lframe1	/* FDE CIE offset */
    396 #ifdef __PIC__
    397 	.long	.LFB2-.	/* FDE initial location */
    398 #else
    399 	.long	.LFB2
    400 #endif
    401 	.long	.LFE2-.LFB2	/* FDE address range */
    402 #ifdef __PIC__
    403 	.byte	0x0	/* .uleb128 0x0; Augmentation size */
    404 #endif
    405 	.byte	0x4	/* DW_CFA_advance_loc4 */
    406 	.long	.LCFI2-.LFB2
    407 	.byte	0xe	/* DW_CFA_def_cfa_offset */
    408 	.byte	0x8	/* .uleb128 0x8 */
    409 	.byte	0x85	/* DW_CFA_offset, column 0x5 */
    410 	.byte	0x2	/* .uleb128 0x2 */
    411 	.byte	0x4	/* DW_CFA_advance_loc4 */
    412 	.long	.LCFI3-.LCFI2
    413 	.byte	0xd	/* DW_CFA_def_cfa_register */
    414 	.byte	0x5	/* .uleb128 0x5 */
    415 #if !defined HAVE_HIDDEN_VISIBILITY_ATTRIBUTE && defined __PIC__
    416 	.byte	0x4	/* DW_CFA_advance_loc4 */
    417 	.long	.LCFI7-.LCFI3
    418 	.byte	0x83	/* DW_CFA_offset, column 0x3 */
    419 	.byte	0xa	/* .uleb128 0xa */
    420 #endif
    421 	.align 4
    422 .LEFDE2:
    423 
    424 #if !FFI_NO_RAW_API
    425 
    426 .LSFDE3:
    427 	.long	.LEFDE3-.LASFDE3	/* FDE Length */
    428 .LASFDE3:
    429 	.long	.LASFDE3-.Lframe1	/* FDE CIE offset */
    430 #ifdef __PIC__
    431 	.long	.LFB3-.	/* FDE initial location */
    432 #else
    433 	.long	.LFB3
    434 #endif
    435 	.long	.LFE3-.LFB3	/* FDE address range */
    436 #ifdef __PIC__
    437 	.byte	0x0	/* .uleb128 0x0; Augmentation size */
    438 #endif
    439 	.byte	0x4	/* DW_CFA_advance_loc4 */
    440 	.long	.LCFI4-.LFB3
    441 	.byte	0xe	/* DW_CFA_def_cfa_offset */
    442 	.byte	0x8	/* .uleb128 0x8 */
    443 	.byte	0x85	/* DW_CFA_offset, column 0x5 */
    444 	.byte	0x2	/* .uleb128 0x2 */
    445 	.byte	0x4	/* DW_CFA_advance_loc4 */
    446 	.long	.LCFI5-.LCFI4
    447 	.byte	0xd	/* DW_CFA_def_cfa_register */
    448 	.byte	0x5	/* .uleb128 0x5 */
    449 	.byte	0x4	/* DW_CFA_advance_loc4 */
    450 	.long	.LCFI6-.LCFI5
    451 	.byte	0x86	/* DW_CFA_offset, column 0x6 */
    452 	.byte	0x3	/* .uleb128 0x3 */
    453 	.align 4
    454 .LEFDE3:
    455 
    456 #endif
    457 
    458 #endif /* ifndef __x86_64__ */
    459