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 830: 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 */ 1041: 105 pop %esi 106 add (%esi, %ecx, 4), %esi 107 jmp *%esi 108 109 /* Sign/zero extend as appropriate. */ 110retsint8: 111 movsbl %al, %eax 112 jmp retint 113 114retsint16: 115 movswl %ax, %eax 116 jmp retint 117 118retuint8: 119 movzbl %al, %eax 120 jmp retint 121 122retuint16: 123 movzwl %ax, %eax 124 jmp retint 125 126retfloat: 127 /* Load %ecx with the pointer to storage for the return value */ 128 movl 24(%ebp),%ecx 129 fstps (%ecx) 130 jmp epilogue 131 132retdouble: 133 /* Load %ecx with the pointer to storage for the return value */ 134 movl 24(%ebp),%ecx 135 fstpl (%ecx) 136 jmp epilogue 137 138retlongdouble: 139 /* Load %ecx with the pointer to storage for the return value */ 140 movl 24(%ebp),%ecx 141 fstpt (%ecx) 142 jmp epilogue 143 144retint64: 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 151retstruct1b: 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 157retstruct2b: 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 163retint: 164 /* Load %ecx with the pointer to storage for the return value */ 165 movl 24(%ebp),%ecx 166 movl %eax,0(%ecx) 167 168retstruct: 169 /* Nothing to do! */ 170 171noretval: 172epilogue: 173 popl %esi 174 movl %ebp,%esp 175 popl %ebp 176 ret 177 178.LFE1: 179.ffi_call_SYSV_end: 180 181 .align 4 182FFI_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 2130: 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 268FFI_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 2990: 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 333L_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 339EH_frame1: 340 .set L$set$0,LECIE1-LSCIE1 341 .long L$set$0 342LSCIE1: 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 357LECIE1: 358.globl _ffi_call_SYSV.eh 359_ffi_call_SYSV.eh: 360LSFDE1: 361 .set L$set$1,LEFDE1-LASFDE1 362 .long L$set$1 363LASFDE1: 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 382LEFDE1: 383.globl _ffi_closure_SYSV.eh 384_ffi_closure_SYSV.eh: 385LSFDE2: 386 .set L$set$5,LEFDE2-LASFDE2 387 .long L$set$5 388LASFDE2: 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 407LEFDE2: 408 409#if !FFI_NO_RAW_API 410 411.globl _ffi_closure_raw_SYSV.eh 412_ffi_closure_raw_SYSV.eh: 413LSFDE3: 414 .set L$set$10,LEFDE3-LASFDE3 415 .long L$set$10 416LASFDE3: 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 440LEFDE3: 441 442#endif 443 444#endif /* ifndef __x86_64__ */ 445