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