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 	/* Align the stack pointer to 16-bytes */
     53 	andl  $0xfffffff0, %esp
     54 
     55 	movl  %esp,%eax
     56 
     57 	/* Place all of the ffi_prep_args in position  */
     58 	pushl 12(%ebp)
     59 	pushl %eax
     60 	call  *8(%ebp)
     61 
     62 	/* Return stack to previous state and call the function  */
     63 	addl  $8,%esp
     64 
     65 	call  *28(%ebp)
     66 
     67 	/* Load %ecx with the return type code  */
     68 	movl  20(%ebp),%ecx
     69 
     70 	/* Protect %esi.  We're going to pop it in the epilogue.  */
     71 	pushl %esi
     72 
     73 	/* If the return value pointer is NULL, assume no return value.  */
     74 	cmpl  $0,24(%ebp)
     75 	jne  0f
     76 
     77 	/* Even if there is no space for the return value, we are
     78 	   obliged to handle floating-point values.  */
     79 	cmpl  $FFI_TYPE_FLOAT,%ecx
     80 	jne   noretval
     81 	fstp  %st(0)
     82 
     83         jmp   epilogue
     84 
     85 0:
     86 	call  1f
     87 
     88 .Lstore_table:
     89 	.long	noretval-.Lstore_table	/* FFI_TYPE_VOID */
     90 	.long	retint-.Lstore_table	/* FFI_TYPE_INT */
     91 	.long	retfloat-.Lstore_table	/* FFI_TYPE_FLOAT */
     92 	.long	retdouble-.Lstore_table	/* FFI_TYPE_DOUBLE */
     93 	.long	retlongdouble-.Lstore_table	/* FFI_TYPE_LONGDOUBLE */
     94 	.long	retuint8-.Lstore_table	/* FFI_TYPE_UINT8 */
     95 	.long	retsint8-.Lstore_table	/* FFI_TYPE_SINT8 */
     96 	.long	retuint16-.Lstore_table	/* FFI_TYPE_UINT16 */
     97 	.long	retsint16-.Lstore_table	/* FFI_TYPE_SINT16 */
     98 	.long	retint-.Lstore_table	/* FFI_TYPE_UINT32 */
     99 	.long	retint-.Lstore_table	/* FFI_TYPE_SINT32 */
    100 	.long	retint64-.Lstore_table	/* FFI_TYPE_UINT64 */
    101 	.long	retint64-.Lstore_table	/* FFI_TYPE_SINT64 */
    102 	.long	retstruct-.Lstore_table	/* FFI_TYPE_STRUCT */
    103 	.long	retint-.Lstore_table	/* FFI_TYPE_POINTER */
    104 	.long   retstruct1b-.Lstore_table	/* FFI_TYPE_SMALL_STRUCT_1B */
    105 	.long   retstruct2b-.Lstore_table	/* FFI_TYPE_SMALL_STRUCT_2B */
    106 
    107 1:
    108 	pop  %esi
    109 	add  (%esi, %ecx, 4), %esi
    110 	jmp  *%esi
    111 
    112 	/* Sign/zero extend as appropriate.  */
    113 retsint8:
    114 	movsbl  %al, %eax
    115 	jmp  retint
    116 
    117 retsint16:
    118 	movswl  %ax, %eax
    119 	jmp  retint
    120 
    121 retuint8:
    122 	movzbl  %al, %eax
    123 	jmp  retint
    124 
    125 retuint16:
    126 	movzwl  %ax, %eax
    127 	jmp  retint
    128 
    129 retfloat:
    130 	/* Load %ecx with the pointer to storage for the return value  */
    131 	movl  24(%ebp),%ecx
    132 	fstps (%ecx)
    133 	jmp   epilogue
    134 
    135 retdouble:
    136 	/* Load %ecx with the pointer to storage for the return value  */
    137 	movl  24(%ebp),%ecx
    138 	fstpl (%ecx)
    139 	jmp   epilogue
    140 
    141 retlongdouble:
    142 	/* Load %ecx with the pointer to storage for the return value  */
    143 	movl  24(%ebp),%ecx
    144 	fstpt (%ecx)
    145 	jmp   epilogue
    146 
    147 retint64:
    148 	/* Load %ecx with the pointer to storage for the return value  */
    149 	movl  24(%ebp),%ecx
    150 	movl  %eax,0(%ecx)
    151 	movl  %edx,4(%ecx)
    152 	jmp   epilogue
    153 
    154 retstruct1b:
    155 	/* Load %ecx with the pointer to storage for the return value  */
    156 	movl  24(%ebp),%ecx
    157 	movb  %al,0(%ecx)
    158 	jmp   epilogue
    159 
    160 retstruct2b:
    161 	/* Load %ecx with the pointer to storage for the return value  */
    162 	movl  24(%ebp),%ecx
    163 	movw  %ax,0(%ecx)
    164 	jmp   epilogue
    165 
    166 retint:
    167 	/* Load %ecx with the pointer to storage for the return value  */
    168 	movl  24(%ebp),%ecx
    169 	movl  %eax,0(%ecx)
    170 
    171 retstruct:
    172 	/* Nothing to do!  */
    173 
    174 noretval:
    175 epilogue:
    176         popl %esi
    177         movl %ebp,%esp
    178         popl %ebp
    179         ret
    180 .LFE1:
    181 .ffi_call_SYSV_end:
    182         .size    ffi_call_SYSV,.ffi_call_SYSV_end-ffi_call_SYSV
    183 
    184 	.align	4
    185 FFI_HIDDEN (ffi_closure_SYSV)
    186 .globl ffi_closure_SYSV
    187 	.type	ffi_closure_SYSV, @function
    188 
    189 ffi_closure_SYSV:
    190 .LFB2:
    191 	pushl	%ebp
    192 .LCFI2:
    193 	movl	%esp, %ebp
    194 .LCFI3:
    195 	subl	$40, %esp
    196 	leal	-24(%ebp), %edx
    197 	movl	%edx, -12(%ebp)	/* resp */
    198 	leal	8(%ebp), %edx
    199 	movl	%edx, 4(%esp)	/* args = __builtin_dwarf_cfa () */
    200 	leal	-12(%ebp), %edx
    201 	movl	%edx, (%esp)	/* &resp */
    202 #if defined HAVE_HIDDEN_VISIBILITY_ATTRIBUTE || !defined __PIC__
    203 	call	ffi_closure_SYSV_inner
    204 #else
    205 	movl	%ebx, 8(%esp)
    206 .LCFI7:
    207 	call	1f
    208 1:	popl	%ebx
    209 	addl	$_GLOBAL_OFFSET_TABLE_+[.-1b], %ebx
    210 	call	ffi_closure_SYSV_inner@PLT
    211 	movl	8(%esp), %ebx
    212 #endif
    213 	movl	-12(%ebp), %ecx
    214 	cmpl	$FFI_TYPE_INT, %eax
    215 	je	.Lcls_retint
    216 
    217 	/* Handle FFI_TYPE_UINT8, FFI_TYPE_SINT8, FFI_TYPE_UINT16,
    218 	   FFI_TYPE_SINT16, FFI_TYPE_UINT32, FFI_TYPE_SINT32.  */
    219 	cmpl	$FFI_TYPE_UINT64, %eax
    220 	jge	0f
    221 	cmpl	$FFI_TYPE_UINT8, %eax
    222 	jge	.Lcls_retint
    223 
    224 0:	cmpl	$FFI_TYPE_FLOAT, %eax
    225 	je	.Lcls_retfloat
    226 	cmpl	$FFI_TYPE_DOUBLE, %eax
    227 	je	.Lcls_retdouble
    228 	cmpl	$FFI_TYPE_LONGDOUBLE, %eax
    229 	je	.Lcls_retldouble
    230 	cmpl	$FFI_TYPE_SINT64, %eax
    231 	je	.Lcls_retllong
    232 	cmpl	$FFI_TYPE_SMALL_STRUCT_1B, %eax
    233 	je	.Lcls_retstruct1b
    234 	cmpl	$FFI_TYPE_SMALL_STRUCT_2B, %eax
    235 	je	.Lcls_retstruct2b
    236 	cmpl	$FFI_TYPE_STRUCT, %eax
    237 	je	.Lcls_retstruct
    238 .Lcls_epilogue:
    239 	movl	%ebp, %esp
    240 	popl	%ebp
    241 	ret
    242 .Lcls_retint:
    243 	movl	(%ecx), %eax
    244 	jmp	.Lcls_epilogue
    245 .Lcls_retfloat:
    246 	flds	(%ecx)
    247 	jmp	.Lcls_epilogue
    248 .Lcls_retdouble:
    249 	fldl	(%ecx)
    250 	jmp	.Lcls_epilogue
    251 .Lcls_retldouble:
    252 	fldt	(%ecx)
    253 	jmp	.Lcls_epilogue
    254 .Lcls_retllong:
    255 	movl	(%ecx), %eax
    256 	movl	4(%ecx), %edx
    257 	jmp	.Lcls_epilogue
    258 .Lcls_retstruct1b:
    259 	movsbl	(%ecx), %eax
    260 	jmp	.Lcls_epilogue
    261 .Lcls_retstruct2b:
    262 	movswl	(%ecx), %eax
    263 	jmp	.Lcls_epilogue
    264 .Lcls_retstruct:
    265 	movl	%ebp, %esp
    266 	popl	%ebp
    267 	ret	$4
    268 .LFE2:
    269 	.size	ffi_closure_SYSV, .-ffi_closure_SYSV
    270 
    271 #if !FFI_NO_RAW_API
    272 
    273 #define RAW_CLOSURE_CIF_OFFSET ((FFI_TRAMPOLINE_SIZE + 3) & ~3)
    274 #define RAW_CLOSURE_FUN_OFFSET (RAW_CLOSURE_CIF_OFFSET + 4)
    275 #define RAW_CLOSURE_USER_DATA_OFFSET (RAW_CLOSURE_FUN_OFFSET + 4)
    276 #define CIF_FLAGS_OFFSET 20
    277 
    278 	.align	4
    279 FFI_HIDDEN (ffi_closure_raw_SYSV)
    280 .globl ffi_closure_raw_SYSV
    281 	.type	ffi_closure_raw_SYSV, @function
    282 
    283 ffi_closure_raw_SYSV:
    284 .LFB3:
    285 	pushl	%ebp
    286 .LCFI4:
    287 	movl	%esp, %ebp
    288 .LCFI5:
    289 	pushl	%esi
    290 .LCFI6:
    291 	subl	$36, %esp
    292 	movl	RAW_CLOSURE_CIF_OFFSET(%eax), %esi	 /* closure->cif */
    293 	movl	RAW_CLOSURE_USER_DATA_OFFSET(%eax), %edx /* closure->user_data */
    294 	movl	%edx, 12(%esp)	/* user_data */
    295 	leal	8(%ebp), %edx	/* __builtin_dwarf_cfa () */
    296 	movl	%edx, 8(%esp)	/* raw_args */
    297 	leal	-24(%ebp), %edx
    298 	movl	%edx, 4(%esp)	/* &res */
    299 	movl	%esi, (%esp)	/* cif */
    300 	call	*RAW_CLOSURE_FUN_OFFSET(%eax)		 /* closure->fun */
    301 	movl	CIF_FLAGS_OFFSET(%esi), %eax		 /* rtype */
    302 	cmpl	$FFI_TYPE_INT, %eax
    303 	je	.Lrcls_retint
    304 
    305 	/* Handle FFI_TYPE_UINT8, FFI_TYPE_SINT8, FFI_TYPE_UINT16,
    306 	   FFI_TYPE_SINT16, FFI_TYPE_UINT32, FFI_TYPE_SINT32.  */
    307 	cmpl	$FFI_TYPE_UINT64, %eax
    308 	jge	0f
    309 	cmpl	$FFI_TYPE_UINT8, %eax
    310 	jge	.Lrcls_retint
    311 0:
    312 	cmpl	$FFI_TYPE_FLOAT, %eax
    313 	je	.Lrcls_retfloat
    314 	cmpl	$FFI_TYPE_DOUBLE, %eax
    315 	je	.Lrcls_retdouble
    316 	cmpl	$FFI_TYPE_LONGDOUBLE, %eax
    317 	je	.Lrcls_retldouble
    318 	cmpl	$FFI_TYPE_SINT64, %eax
    319 	je	.Lrcls_retllong
    320 .Lrcls_epilogue:
    321 	addl	$36, %esp
    322 	popl	%esi
    323 	popl	%ebp
    324 	ret
    325 .Lrcls_retint:
    326 	movl	-24(%ebp), %eax
    327 	jmp	.Lrcls_epilogue
    328 .Lrcls_retfloat:
    329 	flds	-24(%ebp)
    330 	jmp	.Lrcls_epilogue
    331 .Lrcls_retdouble:
    332 	fldl	-24(%ebp)
    333 	jmp	.Lrcls_epilogue
    334 .Lrcls_retldouble:
    335 	fldt	-24(%ebp)
    336 	jmp	.Lrcls_epilogue
    337 .Lrcls_retllong:
    338 	movl	-24(%ebp), %eax
    339 	movl	-20(%ebp), %edx
    340 	jmp	.Lrcls_epilogue
    341 .LFE3:
    342 	.size	ffi_closure_raw_SYSV, .-ffi_closure_raw_SYSV
    343 #endif
    344 
    345 	.section	.eh_frame,EH_FRAME_FLAGS,@progbits
    346 .Lframe1:
    347 	.long	.LECIE1-.LSCIE1	/* Length of Common Information Entry */
    348 .LSCIE1:
    349 	.long	0x0	/* CIE Identifier Tag */
    350 	.byte	0x1	/* CIE Version */
    351 #ifdef __PIC__
    352 	.ascii "zR\0"	/* CIE Augmentation */
    353 #else
    354 	.ascii "\0"	/* CIE Augmentation */
    355 #endif
    356 	.byte	0x1	/* .uleb128 0x1; CIE Code Alignment Factor */
    357 	.byte	0x7c	/* .sleb128 -4; CIE Data Alignment Factor */
    358 	.byte	0x8	/* CIE RA Column */
    359 #ifdef __PIC__
    360 	.byte	0x1	/* .uleb128 0x1; Augmentation size */
    361 	.byte	0x1b	/* FDE Encoding (pcrel sdata4) */
    362 #endif
    363 	.byte	0xc	/* DW_CFA_def_cfa */
    364 	.byte	0x4	/* .uleb128 0x4 */
    365 	.byte	0x4	/* .uleb128 0x4 */
    366 	.byte	0x88	/* DW_CFA_offset, column 0x8 */
    367 	.byte	0x1	/* .uleb128 0x1 */
    368 	.align 4
    369 .LECIE1:
    370 .LSFDE1:
    371 	.long	.LEFDE1-.LASFDE1	/* FDE Length */
    372 .LASFDE1:
    373 	.long	.LASFDE1-.Lframe1	/* FDE CIE offset */
    374 #ifdef __PIC__
    375 	.long	.LFB1-.	/* FDE initial location */
    376 #else
    377 	.long	.LFB1	/* FDE initial location */
    378 #endif
    379 	.long	.LFE1-.LFB1	/* FDE address range */
    380 #ifdef __PIC__
    381 	.byte	0x0	/* .uleb128 0x0; Augmentation size */
    382 #endif
    383 	.byte	0x4	/* DW_CFA_advance_loc4 */
    384 	.long	.LCFI0-.LFB1
    385 	.byte	0xe	/* DW_CFA_def_cfa_offset */
    386 	.byte	0x8	/* .uleb128 0x8 */
    387 	.byte	0x85	/* DW_CFA_offset, column 0x5 */
    388 	.byte	0x2	/* .uleb128 0x2 */
    389 	.byte	0x4	/* DW_CFA_advance_loc4 */
    390 	.long	.LCFI1-.LCFI0
    391 	.byte	0xd	/* DW_CFA_def_cfa_register */
    392 	.byte	0x5	/* .uleb128 0x5 */
    393 	.align 4
    394 .LEFDE1:
    395 .LSFDE2:
    396 	.long	.LEFDE2-.LASFDE2	/* FDE Length */
    397 .LASFDE2:
    398 	.long	.LASFDE2-.Lframe1	/* FDE CIE offset */
    399 #ifdef __PIC__
    400 	.long	.LFB2-.	/* FDE initial location */
    401 #else
    402 	.long	.LFB2
    403 #endif
    404 	.long	.LFE2-.LFB2	/* FDE address range */
    405 #ifdef __PIC__
    406 	.byte	0x0	/* .uleb128 0x0; Augmentation size */
    407 #endif
    408 	.byte	0x4	/* DW_CFA_advance_loc4 */
    409 	.long	.LCFI2-.LFB2
    410 	.byte	0xe	/* DW_CFA_def_cfa_offset */
    411 	.byte	0x8	/* .uleb128 0x8 */
    412 	.byte	0x85	/* DW_CFA_offset, column 0x5 */
    413 	.byte	0x2	/* .uleb128 0x2 */
    414 	.byte	0x4	/* DW_CFA_advance_loc4 */
    415 	.long	.LCFI3-.LCFI2
    416 	.byte	0xd	/* DW_CFA_def_cfa_register */
    417 	.byte	0x5	/* .uleb128 0x5 */
    418 #if !defined HAVE_HIDDEN_VISIBILITY_ATTRIBUTE && defined __PIC__
    419 	.byte	0x4	/* DW_CFA_advance_loc4 */
    420 	.long	.LCFI7-.LCFI3
    421 	.byte	0x83	/* DW_CFA_offset, column 0x3 */
    422 	.byte	0xa	/* .uleb128 0xa */
    423 #endif
    424 	.align 4
    425 .LEFDE2:
    426 
    427 #if !FFI_NO_RAW_API
    428 
    429 .LSFDE3:
    430 	.long	.LEFDE3-.LASFDE3	/* FDE Length */
    431 .LASFDE3:
    432 	.long	.LASFDE3-.Lframe1	/* FDE CIE offset */
    433 #ifdef __PIC__
    434 	.long	.LFB3-.	/* FDE initial location */
    435 #else
    436 	.long	.LFB3
    437 #endif
    438 	.long	.LFE3-.LFB3	/* FDE address range */
    439 #ifdef __PIC__
    440 	.byte	0x0	/* .uleb128 0x0; Augmentation size */
    441 #endif
    442 	.byte	0x4	/* DW_CFA_advance_loc4 */
    443 	.long	.LCFI4-.LFB3
    444 	.byte	0xe	/* DW_CFA_def_cfa_offset */
    445 	.byte	0x8	/* .uleb128 0x8 */
    446 	.byte	0x85	/* DW_CFA_offset, column 0x5 */
    447 	.byte	0x2	/* .uleb128 0x2 */
    448 	.byte	0x4	/* DW_CFA_advance_loc4 */
    449 	.long	.LCFI5-.LCFI4
    450 	.byte	0xd	/* DW_CFA_def_cfa_register */
    451 	.byte	0x5	/* .uleb128 0x5 */
    452 	.byte	0x4	/* DW_CFA_advance_loc4 */
    453 	.long	.LCFI6-.LCFI5
    454 	.byte	0x86	/* DW_CFA_offset, column 0x6 */
    455 	.byte	0x3	/* .uleb128 0x3 */
    456 	.align 4
    457 .LEFDE3:
    458 
    459 #endif
    460 
    461 #endif /* ifndef __x86_64__ */
    462 
    463 	.section .note.GNU-stack,"",%progbits
    464