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 subl $8,%esp 58 ASSERT_STACK_ALIGNED 59.LCFI1: 60 /* Make room for all of the new args. */ 61 movl 16(%ebp),%ecx 62 subl %ecx,%esp 63 64 ASSERT_STACK_ALIGNED 65 66 movl %esp,%eax 67 68 /* Place all of the ffi_prep_args in position */ 69 subl $8,%esp 70 pushl 12(%ebp) 71 pushl %eax 72 call *8(%ebp) 73 74 ASSERT_STACK_ALIGNED 75 76 /* Return stack to previous state and call the function */ 77 addl $16,%esp 78 79 ASSERT_STACK_ALIGNED 80 81 call *28(%ebp) 82 83 /* XXX: return returns return with 'ret $4', that upsets the stack! */ 84 movl 16(%ebp),%ecx 85 addl %ecx,%esp 86 87 88 /* Load %ecx with the return type code */ 89 movl 20(%ebp),%ecx 90 91 92 /* If the return value pointer is NULL, assume no return value. */ 93 cmpl $0,24(%ebp) 94 jne retint 95 96 /* Even if there is no space for the return value, we are 97 obliged to handle floating-point values. */ 98 cmpl $FFI_TYPE_FLOAT,%ecx 99 jne noretval 100 fstp %st(0) 101 102 jmp epilogue 103 104retint: 105 cmpl $FFI_TYPE_INT,%ecx 106 jne retfloat 107 /* Load %ecx with the pointer to storage for the return value */ 108 movl 24(%ebp),%ecx 109 movl %eax,0(%ecx) 110 jmp epilogue 111 112retfloat: 113 cmpl $FFI_TYPE_FLOAT,%ecx 114 jne retdouble 115 /* Load %ecx with the pointer to storage for the return value */ 116 movl 24(%ebp),%ecx 117 fstps (%ecx) 118 jmp epilogue 119 120retdouble: 121 cmpl $FFI_TYPE_DOUBLE,%ecx 122 jne retlongdouble 123 /* Load %ecx with the pointer to storage for the return value */ 124 movl 24(%ebp),%ecx 125 fstpl (%ecx) 126 jmp epilogue 127 128retlongdouble: 129 cmpl $FFI_TYPE_LONGDOUBLE,%ecx 130 jne retint64 131 /* Load %ecx with the pointer to storage for the return value */ 132 movl 24(%ebp),%ecx 133 fstpt (%ecx) 134 jmp epilogue 135 136retint64: 137 cmpl $FFI_TYPE_SINT64,%ecx 138 jne retstruct1b 139 /* Load %ecx with the pointer to storage for the return value */ 140 movl 24(%ebp),%ecx 141 movl %eax,0(%ecx) 142 movl %edx,4(%ecx) 143 jmp epilogue 144 145retstruct1b: 146 cmpl $FFI_TYPE_SINT8,%ecx 147 jne retstruct2b 148 movl 24(%ebp),%ecx 149 movb %al,0(%ecx) 150 jmp epilogue 151 152retstruct2b: 153 cmpl $FFI_TYPE_SINT16,%ecx 154 jne retstruct 155 movl 24(%ebp),%ecx 156 movw %ax,0(%ecx) 157 jmp epilogue 158 159retstruct: 160 cmpl $FFI_TYPE_STRUCT,%ecx 161 jne noretval 162 /* Nothing to do! */ 163 164 subl $4,%esp 165 166 ASSERT_STACK_ALIGNED 167 168 addl $8,%esp 169 movl %ebp, %esp 170 popl %ebp 171 ret 172 173noretval: 174epilogue: 175 ASSERT_STACK_ALIGNED 176 addl $8, %esp 177 178 179 movl %ebp,%esp 180 popl %ebp 181 ret 182.LFE1: 183.ffi_call_SYSV_end: 184#if 0 185 .size ffi_call_SYSV,.ffi_call_SYSV_end-ffi_call_SYSV 186#endif 187 188#if 0 189 .section .eh_frame,EH_FRAME_FLAGS,@progbits 190.Lframe1: 191 .long .LECIE1-.LSCIE1 /* Length of Common Information Entry */ 192.LSCIE1: 193 .long 0x0 /* CIE Identifier Tag */ 194 .byte 0x1 /* CIE Version */ 195#ifdef __PIC__ 196 .ascii "zR\0" /* CIE Augmentation */ 197#else 198 .ascii "\0" /* CIE Augmentation */ 199#endif 200 .byte 0x1 /* .uleb128 0x1; CIE Code Alignment Factor */ 201 .byte 0x7c /* .sleb128 -4; CIE Data Alignment Factor */ 202 .byte 0x8 /* CIE RA Column */ 203#ifdef __PIC__ 204 .byte 0x1 /* .uleb128 0x1; Augmentation size */ 205 .byte 0x1b /* FDE Encoding (pcrel sdata4) */ 206#endif 207 .byte 0xc /* DW_CFA_def_cfa */ 208 .byte 0x4 /* .uleb128 0x4 */ 209 .byte 0x4 /* .uleb128 0x4 */ 210 .byte 0x88 /* DW_CFA_offset, column 0x8 */ 211 .byte 0x1 /* .uleb128 0x1 */ 212 .align 4 213.LECIE1: 214.LSFDE1: 215 .long .LEFDE1-.LASFDE1 /* FDE Length */ 216.LASFDE1: 217 .long .LASFDE1-.Lframe1 /* FDE CIE offset */ 218#ifdef __PIC__ 219 .long .LFB1-. /* FDE initial location */ 220#else 221 .long .LFB1 /* FDE initial location */ 222#endif 223 .long .LFE1-.LFB1 /* FDE address range */ 224#ifdef __PIC__ 225 .byte 0x0 /* .uleb128 0x0; Augmentation size */ 226#endif 227 .byte 0x4 /* DW_CFA_advance_loc4 */ 228 .long .LCFI0-.LFB1 229 .byte 0xe /* DW_CFA_def_cfa_offset */ 230 .byte 0x8 /* .uleb128 0x8 */ 231 .byte 0x85 /* DW_CFA_offset, column 0x5 */ 232 .byte 0x2 /* .uleb128 0x2 */ 233 .byte 0x4 /* DW_CFA_advance_loc4 */ 234 .long .LCFI1-.LCFI0 235 .byte 0xd /* DW_CFA_def_cfa_register */ 236 .byte 0x5 /* .uleb128 0x5 */ 237 .align 4 238.LEFDE1: 239#endif 240 241#endif /* ifndef __x86_64__ */ 242 243#endif /* defined __i386__ */ 244