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, 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 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR 22 ANY CLAIM, DAMAGES OR 23 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 24 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 25 OTHER 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 41_ffi_call_SYSV: 42.LFB1: 43 pushl %ebp 44.LCFI0: 45 movl %esp,%ebp 46.LCFI1: 47 subl $8,%esp 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 subl $8,%esp 56 pushl 12(%ebp) 57 pushl %eax 58 call *8(%ebp) 59 60 /* Return stack to previous state and call the function */ 61 addl $16,%esp 62 63 call *28(%ebp) 64 65 /* Load %ecx with the return type code */ 66 movl 20(%ebp),%ecx 67 68 /* Protect %esi. We're going to pop it in the epilogue. */ 69 pushl %esi 70 71 /* If the return value pointer is NULL, assume no return value. */ 72 cmpl $0,24(%ebp) 73 jne 0f 74 75 /* Even if there is no space for the return value, we are 76 obliged to handle floating-point values. */ 77 cmpl $FFI_TYPE_FLOAT,%ecx 78 jne noretval 79 fstp %st(0) 80 81 jmp epilogue 820: 83 .align 4 84 call 1f 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 */ 1031: 104 pop %esi 105 add (%esi, %ecx, 4), %esi 106 jmp *%esi 107 108 /* Sign/zero extend as appropriate. */ 109retsint8: 110 movsbl %al, %eax 111 jmp retint 112 113retsint16: 114 movswl %ax, %eax 115 jmp retint 116 117retuint8: 118 movzbl %al, %eax 119 jmp retint 120 121retuint16: 122 movzwl %ax, %eax 123 jmp retint 124 125retfloat: 126 /* Load %ecx with the pointer to storage for the return value */ 127 movl 24(%ebp),%ecx 128 fstps (%ecx) 129 jmp epilogue 130 131retdouble: 132 /* Load %ecx with the pointer to storage for the return value */ 133 movl 24(%ebp),%ecx 134 fstpl (%ecx) 135 jmp epilogue 136 137retlongdouble: 138 /* Load %ecx with the pointer to storage for the return value */ 139 movl 24(%ebp),%ecx 140 fstpt (%ecx) 141 jmp epilogue 142 143retint64: 144 /* Load %ecx with the pointer to storage for the return value */ 145 movl 24(%ebp),%ecx 146 movl %eax,0(%ecx) 147 movl %edx,4(%ecx) 148 jmp epilogue 149 150retstruct1b: 151 /* Load %ecx with the pointer to storage for the return value */ 152 movl 24(%ebp),%ecx 153 movb %al,0(%ecx) 154 jmp epilogue 155 156retstruct2b: 157 /* Load %ecx with the pointer to storage for the return value */ 158 movl 24(%ebp),%ecx 159 movw %ax,0(%ecx) 160 jmp epilogue 161 162retint: 163 /* Load %ecx with the pointer to storage for the return value */ 164 movl 24(%ebp),%ecx 165 movl %eax,0(%ecx) 166 167retstruct: 168 /* Nothing to do! */ 169 170noretval: 171epilogue: 172 popl %esi 173 movl %ebp,%esp 174 popl %ebp 175 ret 176 177.LFE1: 178.ffi_call_SYSV_end: 179 180 .align 4 181FFI_HIDDEN (ffi_closure_SYSV) 182.globl _ffi_closure_SYSV 183 184_ffi_closure_SYSV: 185.LFB2: 186 pushl %ebp 187.LCFI2: 188 movl %esp, %ebp 189.LCFI3: 190 subl $40, %esp 191 leal -24(%ebp), %edx 192 movl %edx, -12(%ebp) /* resp */ 193 leal 8(%ebp), %edx 194 movl %edx, 4(%esp) /* args = __builtin_dwarf_cfa () */ 195 leal -12(%ebp), %edx 196 movl %edx, (%esp) /* &resp */ 197 movl %ebx, 8(%esp) 198.LCFI7: 199 call L_ffi_closure_SYSV_inner$stub 200 movl 8(%esp), %ebx 201 movl -12(%ebp), %ecx 202 cmpl $FFI_TYPE_INT, %eax 203 je .Lcls_retint 204 205 /* Handle FFI_TYPE_UINT8, FFI_TYPE_SINT8, FFI_TYPE_UINT16, 206 FFI_TYPE_SINT16, FFI_TYPE_UINT32, FFI_TYPE_SINT32. */ 207 cmpl $FFI_TYPE_UINT64, %eax 208 jge 0f 209 cmpl $FFI_TYPE_UINT8, %eax 210 jge .Lcls_retint 211 2120: cmpl $FFI_TYPE_FLOAT, %eax 213 je .Lcls_retfloat 214 cmpl $FFI_TYPE_DOUBLE, %eax 215 je .Lcls_retdouble 216 cmpl $FFI_TYPE_LONGDOUBLE, %eax 217 je .Lcls_retldouble 218 cmpl $FFI_TYPE_SINT64, %eax 219 je .Lcls_retllong 220 cmpl $FFI_TYPE_SMALL_STRUCT_1B, %eax 221 je .Lcls_retstruct1b 222 cmpl $FFI_TYPE_SMALL_STRUCT_2B, %eax 223 je .Lcls_retstruct2b 224 cmpl $FFI_TYPE_STRUCT, %eax 225 je .Lcls_retstruct 226.Lcls_epilogue: 227 movl %ebp, %esp 228 popl %ebp 229 ret 230.Lcls_retint: 231 movl (%ecx), %eax 232 jmp .Lcls_epilogue 233.Lcls_retfloat: 234 flds (%ecx) 235 jmp .Lcls_epilogue 236.Lcls_retdouble: 237 fldl (%ecx) 238 jmp .Lcls_epilogue 239.Lcls_retldouble: 240 fldt (%ecx) 241 jmp .Lcls_epilogue 242.Lcls_retllong: 243 movl (%ecx), %eax 244 movl 4(%ecx), %edx 245 jmp .Lcls_epilogue 246.Lcls_retstruct1b: 247 movsbl (%ecx), %eax 248 jmp .Lcls_epilogue 249.Lcls_retstruct2b: 250 movswl (%ecx), %eax 251 jmp .Lcls_epilogue 252.Lcls_retstruct: 253 lea -8(%ebp),%esp 254 movl %ebp, %esp 255 popl %ebp 256 ret $4 257.LFE2: 258 259#if !FFI_NO_RAW_API 260 261#define RAW_CLOSURE_CIF_OFFSET ((FFI_TRAMPOLINE_SIZE + 3) & ~3) 262#define RAW_CLOSURE_FUN_OFFSET (RAW_CLOSURE_CIF_OFFSET + 4) 263#define RAW_CLOSURE_USER_DATA_OFFSET (RAW_CLOSURE_FUN_OFFSET + 4) 264#define CIF_FLAGS_OFFSET 20 265 266 .align 4 267FFI_HIDDEN (ffi_closure_raw_SYSV) 268.globl _ffi_closure_raw_SYSV 269 270_ffi_closure_raw_SYSV: 271.LFB3: 272 pushl %ebp 273.LCFI4: 274 movl %esp, %ebp 275.LCFI5: 276 pushl %esi 277.LCFI6: 278 subl $36, %esp 279 movl RAW_CLOSURE_CIF_OFFSET(%eax), %esi /* closure->cif */ 280 movl RAW_CLOSURE_USER_DATA_OFFSET(%eax), %edx /* closure->user_data */ 281 movl %edx, 12(%esp) /* user_data */ 282 leal 8(%ebp), %edx /* __builtin_dwarf_cfa () */ 283 movl %edx, 8(%esp) /* raw_args */ 284 leal -24(%ebp), %edx 285 movl %edx, 4(%esp) /* &res */ 286 movl %esi, (%esp) /* cif */ 287 call *RAW_CLOSURE_FUN_OFFSET(%eax) /* closure->fun */ 288 movl CIF_FLAGS_OFFSET(%esi), %eax /* rtype */ 289 cmpl $FFI_TYPE_INT, %eax 290 je .Lrcls_retint 291 292 /* Handle FFI_TYPE_UINT8, FFI_TYPE_SINT8, FFI_TYPE_UINT16, 293 FFI_TYPE_SINT16, FFI_TYPE_UINT32, FFI_TYPE_SINT32. */ 294 cmpl $FFI_TYPE_UINT64, %eax 295 jge 0f 296 cmpl $FFI_TYPE_UINT8, %eax 297 jge .Lrcls_retint 2980: 299 cmpl $FFI_TYPE_FLOAT, %eax 300 je .Lrcls_retfloat 301 cmpl $FFI_TYPE_DOUBLE, %eax 302 je .Lrcls_retdouble 303 cmpl $FFI_TYPE_LONGDOUBLE, %eax 304 je .Lrcls_retldouble 305 cmpl $FFI_TYPE_SINT64, %eax 306 je .Lrcls_retllong 307.Lrcls_epilogue: 308 addl $36, %esp 309 popl %esi 310 popl %ebp 311 ret 312.Lrcls_retint: 313 movl -24(%ebp), %eax 314 jmp .Lrcls_epilogue 315.Lrcls_retfloat: 316 flds -24(%ebp) 317 jmp .Lrcls_epilogue 318.Lrcls_retdouble: 319 fldl -24(%ebp) 320 jmp .Lrcls_epilogue 321.Lrcls_retldouble: 322 fldt -24(%ebp) 323 jmp .Lrcls_epilogue 324.Lrcls_retllong: 325 movl -24(%ebp), %eax 326 movl -20(%ebp), %edx 327 jmp .Lrcls_epilogue 328.LFE3: 329#endif 330 331.section __IMPORT,__jump_table,symbol_stubs,self_modifying_code+pure_instructions,5 332L_ffi_closure_SYSV_inner$stub: 333 .indirect_symbol _ffi_closure_SYSV_inner 334 hlt ; hlt ; hlt ; hlt ; hlt 335 336 337.section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support 338EH_frame1: 339 .set L$set$0,LECIE1-LSCIE1 340 .long L$set$0 341LSCIE1: 342 .long 0x0 343 .byte 0x1 344 .ascii "zR\0" 345 .byte 0x1 346 .byte 0x7c 347 .byte 0x8 348 .byte 0x1 349 .byte 0x10 350 .byte 0xc 351 .byte 0x5 352 .byte 0x4 353 .byte 0x88 354 .byte 0x1 355 .align 2 356LECIE1: 357.globl _ffi_call_SYSV.eh 358_ffi_call_SYSV.eh: 359LSFDE1: 360 .set L$set$1,LEFDE1-LASFDE1 361 .long L$set$1 362LASFDE1: 363 .long LASFDE1-EH_frame1 364 .long .LFB1-. 365 .set L$set$2,.LFE1-.LFB1 366 .long L$set$2 367 .byte 0x0 368 .byte 0x4 369 .set L$set$3,.LCFI0-.LFB1 370 .long L$set$3 371 .byte 0xe 372 .byte 0x8 373 .byte 0x84 374 .byte 0x2 375 .byte 0x4 376 .set L$set$4,.LCFI1-.LCFI0 377 .long L$set$4 378 .byte 0xd 379 .byte 0x4 380 .align 2 381LEFDE1: 382.globl _ffi_closure_SYSV.eh 383_ffi_closure_SYSV.eh: 384LSFDE2: 385 .set L$set$5,LEFDE2-LASFDE2 386 .long L$set$5 387LASFDE2: 388 .long LASFDE2-EH_frame1 389 .long .LFB2-. 390 .set L$set$6,.LFE2-.LFB2 391 .long L$set$6 392 .byte 0x0 393 .byte 0x4 394 .set L$set$7,.LCFI2-.LFB2 395 .long L$set$7 396 .byte 0xe 397 .byte 0x8 398 .byte 0x84 399 .byte 0x2 400 .byte 0x4 401 .set L$set$8,.LCFI3-.LCFI2 402 .long L$set$8 403 .byte 0xd 404 .byte 0x4 405 .align 2 406LEFDE2: 407 408#if !FFI_NO_RAW_API 409 410.globl _ffi_closure_raw_SYSV.eh 411_ffi_closure_raw_SYSV.eh: 412LSFDE3: 413 .set L$set$10,LEFDE3-LASFDE3 414 .long L$set$10 415LASFDE3: 416 .long LASFDE3-EH_frame1 417 .long .LFB3-. 418 .set L$set$11,.LFE3-.LFB3 419 .long L$set$11 420 .byte 0x0 421 .byte 0x4 422 .set L$set$12,.LCFI4-.LFB3 423 .long L$set$12 424 .byte 0xe 425 .byte 0x8 426 .byte 0x84 427 .byte 0x2 428 .byte 0x4 429 .set L$set$13,.LCFI5-.LCFI4 430 .long L$set$13 431 .byte 0xd 432 .byte 0x4 433 .byte 0x4 434 .set L$set$14,.LCFI6-.LCFI5 435 .long L$set$14 436 .byte 0x85 437 .byte 0x3 438 .align 2 439LEFDE3: 440 441#endif 442 443#endif /* ifndef __x86_64__ */ 444