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_SINT8, %eax 202 je Lcls_retstruct1 203 cmpl $FFI_TYPE_SINT16, %eax 204 je Lcls_retstruct2 205 cmpl $FFI_TYPE_STRUCT, %eax 206 je Lcls_retstruct 207Lcls_epilogue: 208 movl %ebp, %esp 209 popl %ebp 210 ret 211Lcls_retint: 212 movl (%ecx), %eax 213 jmp Lcls_epilogue 214Lcls_retfloat: 215 flds (%ecx) 216 jmp Lcls_epilogue 217Lcls_retdouble: 218 fldl (%ecx) 219 jmp Lcls_epilogue 220Lcls_retldouble: 221 fldt (%ecx) 222 jmp Lcls_epilogue 223Lcls_retllong: 224 movl (%ecx), %eax 225 movl 4(%ecx), %edx 226 jmp Lcls_epilogue 227Lcls_retstruct1: 228 movsbl (%ecx), %eax 229 jmp Lcls_epilogue 230Lcls_retstruct2: 231 movswl (%ecx), %eax 232 jmp Lcls_epilogue 233Lcls_retstruct: 234 lea -8(%ebp),%esp 235 movl %ebp, %esp 236 popl %ebp 237 ret $4 238LFE2: 239 240#if !FFI_NO_RAW_API 241 242#define RAW_CLOSURE_CIF_OFFSET ((FFI_TRAMPOLINE_SIZE + 3) & ~3) 243#define RAW_CLOSURE_FUN_OFFSET (RAW_CLOSURE_CIF_OFFSET + 4) 244#define RAW_CLOSURE_USER_DATA_OFFSET (RAW_CLOSURE_FUN_OFFSET + 4) 245#define CIF_FLAGS_OFFSET 20 246 247 .align 4 248FFI_HIDDEN (ffi_closure_raw_SYSV) 249.globl _ffi_closure_raw_SYSV 250 251_ffi_closure_raw_SYSV: 252LFB3: 253 pushl %ebp 254LCFI4: 255 movl %esp, %ebp 256LCFI5: 257 pushl %esi 258LCFI6: 259 subl $36, %esp 260 movl RAW_CLOSURE_CIF_OFFSET(%eax), %esi /* closure->cif */ 261 movl RAW_CLOSURE_USER_DATA_OFFSET(%eax), %edx /* closure->user_data */ 262 movl %edx, 12(%esp) /* user_data */ 263 leal 8(%ebp), %edx /* __builtin_dwarf_cfa () */ 264 movl %edx, 8(%esp) /* raw_args */ 265 leal -24(%ebp), %edx 266 movl %edx, 4(%esp) /* &res */ 267 movl %esi, (%esp) /* cif */ 268 call *RAW_CLOSURE_FUN_OFFSET(%eax) /* closure->fun */ 269 movl CIF_FLAGS_OFFSET(%esi), %eax /* rtype */ 270 cmpl $FFI_TYPE_INT, %eax 271 je Lrcls_retint 272 cmpl $FFI_TYPE_FLOAT, %eax 273 je Lrcls_retfloat 274 cmpl $FFI_TYPE_DOUBLE, %eax 275 je Lrcls_retdouble 276 cmpl $FFI_TYPE_LONGDOUBLE, %eax 277 je Lrcls_retldouble 278 cmpl $FFI_TYPE_SINT64, %eax 279 je Lrcls_retllong 280Lrcls_epilogue: 281 addl $36, %esp 282 popl %esi 283 popl %ebp 284 ret 285Lrcls_retint: 286 movl -24(%ebp), %eax 287 jmp Lrcls_epilogue 288Lrcls_retfloat: 289 flds -24(%ebp) 290 jmp Lrcls_epilogue 291Lrcls_retdouble: 292 fldl -24(%ebp) 293 jmp Lrcls_epilogue 294Lrcls_retldouble: 295 fldt -24(%ebp) 296 jmp Lrcls_epilogue 297Lrcls_retllong: 298 movl -24(%ebp), %eax 299 movl -20(%ebp), %edx 300 jmp Lrcls_epilogue 301LFE3: 302#endif 303 304.section __IMPORT,__jump_table,symbol_stubs,self_modifying_code+pure_instructions,5 305L_ffi_closure_SYSV_inner$stub: 306 .indirect_symbol _ffi_closure_SYSV_inner 307 hlt ; hlt ; hlt ; hlt ; hlt 308 309 310.section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support 311EH_frame1: 312 .set L$set$0,LECIE1-LSCIE1 313 .long L$set$0 314LSCIE1: 315 .long 0x0 316 .byte 0x1 317 .ascii "zR\0" 318 .byte 0x1 319 .byte 0x7c 320 .byte 0x8 321 .byte 0x1 322 .byte 0x10 323 .byte 0xc 324 .byte 0x5 325 .byte 0x4 326 .byte 0x88 327 .byte 0x1 328 .align 2 329LECIE1: 330.globl _ffi_call_SYSV.eh 331_ffi_call_SYSV.eh: 332LSFDE1: 333 .set L$set$1,LEFDE1-LASFDE1 334 .long L$set$1 335LASFDE1: 336 .long LASFDE1-EH_frame1 337 .long LFB1-. 338 .set L$set$2,LFE1-LFB1 339 .long L$set$2 340 .byte 0x0 341 .byte 0x4 342 .set L$set$3,LCFI0-LFB1 343 .long L$set$3 344 .byte 0xe 345 .byte 0x8 346 .byte 0x84 347 .byte 0x2 348 .byte 0x4 349 .set L$set$4,LCFI1-LCFI0 350 .long L$set$4 351 .byte 0xd 352 .byte 0x4 353 .align 2 354LEFDE1: 355.globl _ffi_closure_SYSV.eh 356_ffi_closure_SYSV.eh: 357LSFDE2: 358 .set L$set$5,LEFDE2-LASFDE2 359 .long L$set$5 360LASFDE2: 361 .long LASFDE2-EH_frame1 362 .long LFB2-. 363 .set L$set$6,LFE2-LFB2 364 .long L$set$6 365 .byte 0x0 366 .byte 0x4 367 .set L$set$7,LCFI2-LFB2 368 .long L$set$7 369 .byte 0xe 370 .byte 0x8 371 .byte 0x84 372 .byte 0x2 373 .byte 0x4 374 .set L$set$8,LCFI3-LCFI2 375 .long L$set$8 376 .byte 0xd 377 .byte 0x4 378 .align 2 379LEFDE2: 380 381#if !FFI_NO_RAW_API 382 383.globl _ffi_closure_raw_SYSV.eh 384_ffi_closure_raw_SYSV.eh: 385LSFDE3: 386 .set L$set$10,LEFDE3-LASFDE3 387 .long L$set$10 388LASFDE3: 389 .long LASFDE3-EH_frame1 390 .long LFB3-. 391 .set L$set$11,LFE3-LFB3 392 .long L$set$11 393 .byte 0x0 394 .byte 0x4 395 .set L$set$12,LCFI4-LFB3 396 .long L$set$12 397 .byte 0xe 398 .byte 0x8 399 .byte 0x84 400 .byte 0x2 401 .byte 0x4 402 .set L$set$13,LCFI5-LCFI4 403 .long L$set$13 404 .byte 0xd 405 .byte 0x4 406 .byte 0x4 407 .set L$set$14,LCFI6-LCFI5 408 .long L$set$14 409 .byte 0x85 410 .byte 0x3 411 .align 2 412LEFDE3: 413 414#endif 415 416#endif /* ifndef __x86_64__ */ 417 418#endif /* defined __i386__ */ 419