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: 53LFB1: 54 pushl %ebp 55LCFI0: 56 movl %esp,%ebp 57LCFI1: 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 95Lretint: 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 103Lretfloat: 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 111Lretdouble: 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 119Lretlongdouble: 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 127Lretint64: 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 136Lretstruct1b: 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 144Lretstruct2b: 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 152Lretstruct: 153 cmpl $FFI_TYPE_STRUCT,%ecx 154 jne Lnoretval 155 /* Nothing to do! */ 156 addl $4,%esp 157 popl %ebp 158 ret 159 160Lnoretval: 161Lepilogue: 162 addl $8,%esp 163 movl %ebp,%esp 164 popl %ebp 165 ret 166LFE1: 167.ffi_call_SYSV_end: 168 169 .align 4 170FFI_HIDDEN (ffi_closure_SYSV) 171.globl _ffi_closure_SYSV 172 173_ffi_closure_SYSV: 174LFB2: 175 pushl %ebp 176LCFI2: 177 movl %esp, %ebp 178LCFI3: 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) 187LCFI7: 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 211Lcls_epilogue: 212 movl %ebp, %esp 213 popl %ebp 214 ret 215Lcls_retint: 216 movl (%ecx), %eax 217 jmp Lcls_epilogue 218Lcls_retfloat: 219 flds (%ecx) 220 jmp Lcls_epilogue 221Lcls_retdouble: 222 fldl (%ecx) 223 jmp Lcls_epilogue 224Lcls_retldouble: 225 fldt (%ecx) 226 jmp Lcls_epilogue 227Lcls_retllong: 228 movl (%ecx), %eax 229 movl 4(%ecx), %edx 230 jmp Lcls_epilogue 231Lcls_retstruct1: 232 movsbl (%ecx), %eax 233 jmp Lcls_epilogue 234Lcls_retstruct2: 235 movswl (%ecx), %eax 236 jmp Lcls_epilogue 237Lcls_retstruct: 238 lea -8(%ebp),%esp 239 movl %ebp, %esp 240 popl %ebp 241 ret $4 242LFE2: 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 252FFI_HIDDEN (ffi_closure_raw_SYSV) 253.globl _ffi_closure_raw_SYSV 254 255_ffi_closure_raw_SYSV: 256LFB3: 257 pushl %ebp 258LCFI4: 259 movl %esp, %ebp 260LCFI5: 261 pushl %esi 262LCFI6: 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 284Lrcls_epilogue: 285 addl $36, %esp 286 popl %esi 287 popl %ebp 288 ret 289Lrcls_retint: 290 movl -24(%ebp), %eax 291 jmp Lrcls_epilogue 292Lrcls_retfloat: 293 flds -24(%ebp) 294 jmp Lrcls_epilogue 295Lrcls_retdouble: 296 fldl -24(%ebp) 297 jmp Lrcls_epilogue 298Lrcls_retldouble: 299 fldt -24(%ebp) 300 jmp Lrcls_epilogue 301Lrcls_retllong: 302 movl -24(%ebp), %eax 303 movl -20(%ebp), %edx 304 jmp Lrcls_epilogue 305LFE3: 306#endif 307 308.section __IMPORT,__jump_table,symbol_stubs,self_modifying_code+pure_instructions,5 309L_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 315EH_frame1: 316 .set L$set$0,LECIE1-LSCIE1 317 .long L$set$0 318LSCIE1: 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 333LECIE1: 334.globl _ffi_call_SYSV.eh 335_ffi_call_SYSV.eh: 336LSFDE1: 337 .set L$set$1,LEFDE1-LASFDE1 338 .long L$set$1 339LASFDE1: 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 358LEFDE1: 359.globl _ffi_closure_SYSV.eh 360_ffi_closure_SYSV.eh: 361LSFDE2: 362 .set L$set$5,LEFDE2-LASFDE2 363 .long L$set$5 364LASFDE2: 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 383LEFDE2: 384 385#if !FFI_NO_RAW_API 386 387.globl _ffi_closure_raw_SYSV.eh 388_ffi_closure_raw_SYSV.eh: 389LSFDE3: 390 .set L$set$10,LEFDE3-LASFDE3 391 .long L$set$10 392LASFDE3: 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 416LEFDE3: 417 418#endif 419 420#endif /* ifndef __x86_64__ */ 421 422#endif /* defined __i386__ */ 423