1/* ----------------------------------------------------------------------- 2 win32.S - Copyright (c) 1996, 1998, 2001, 2002 Red Hat, Inc. 3 Copyright (c) 2001 John Beniton 4 Copyright (c) 2002 Ranjit Mathew 5 6 7 X86 Foreign Function Interface 8 9 Permission is hereby granted, free of charge, to any person obtaining 10 a copy of this software and associated documentation files (the 11 ``Software''), to deal in the Software without restriction, including 12 without limitation the rights to use, copy, modify, merge, publish, 13 distribute, sublicense, and/or sell copies of the Software, and to 14 permit persons to whom the Software is furnished to do so, subject to 15 the following conditions: 16 17 The above copyright notice and this permission notice shall be included 18 in all copies or substantial portions of the Software. 19 20 THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS 21 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 22 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 23 IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR 24 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 25 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 26 OTHER DEALINGS IN THE SOFTWARE. 27 ----------------------------------------------------------------------- */ 28 29#define LIBFFI_ASM 30#include <fficonfig.h> 31#include <ffi.h> 32 33.text 34 35.globl ffi_prep_args 36 37 # This assumes we are using gas. 38 .balign 16 39.globl _ffi_call_SYSV 40 41_ffi_call_SYSV: 42 pushl %ebp 43 movl %esp,%ebp 44 45 # Make room for all of the new args. 46 movl 16(%ebp),%ecx 47 subl %ecx,%esp 48 49 movl %esp,%eax 50 51 # Place all of the ffi_prep_args in position 52 pushl 12(%ebp) 53 pushl %eax 54 call *8(%ebp) 55 56 # Return stack to previous state and call the function 57 addl $8,%esp 58 59 # FIXME: Align the stack to a 128-bit boundary to avoid 60 # potential performance hits. 61 62 call *28(%ebp) 63 64 # Remove the space we pushed for the args 65 movl 16(%ebp),%ecx 66 addl %ecx,%esp 67 68 # Load %ecx with the return type code 69 movl 20(%ebp),%ecx 70 71 # If the return value pointer is NULL, assume no return value. 72 cmpl $0,24(%ebp) 73 jne retint 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 82 83retint: 84 cmpl $FFI_TYPE_INT,%ecx 85 jne retfloat 86 # Load %ecx with the pointer to storage for the return value 87 movl 24(%ebp),%ecx 88 movl %eax,0(%ecx) 89 jmp epilogue 90 91retfloat: 92 cmpl $FFI_TYPE_FLOAT,%ecx 93 jne retdouble 94 # Load %ecx with the pointer to storage for the return value 95 movl 24(%ebp),%ecx 96 fstps (%ecx) 97 jmp epilogue 98 99retdouble: 100 cmpl $FFI_TYPE_DOUBLE,%ecx 101 jne retlongdouble 102 # Load %ecx with the pointer to storage for the return value 103 movl 24(%ebp),%ecx 104 fstpl (%ecx) 105 jmp epilogue 106 107retlongdouble: 108 cmpl $FFI_TYPE_LONGDOUBLE,%ecx 109 jne retint64 110 # Load %ecx with the pointer to storage for the return value 111 movl 24(%ebp),%ecx 112 fstpt (%ecx) 113 jmp epilogue 114 115retint64: 116 cmpl $FFI_TYPE_SINT64,%ecx 117 jne retstruct 118 # Load %ecx with the pointer to storage for the return value 119 movl 24(%ebp),%ecx 120 movl %eax,0(%ecx) 121 movl %edx,4(%ecx) 122 123retstruct: 124 # Nothing to do! 125 126noretval: 127epilogue: 128 movl %ebp,%esp 129 popl %ebp 130 ret 131 132.ffi_call_SYSV_end: 133 134 # This assumes we are using gas. 135 .balign 16 136.globl _ffi_call_STDCALL 137 138_ffi_call_STDCALL: 139 pushl %ebp 140 movl %esp,%ebp 141 142 # Make room for all of the new args. 143 movl 16(%ebp),%ecx 144 subl %ecx,%esp 145 146 movl %esp,%eax 147 148 # Place all of the ffi_prep_args in position 149 pushl 12(%ebp) 150 pushl %eax 151 call *8(%ebp) 152 153 # Return stack to previous state and call the function 154 addl $8,%esp 155 156 # FIXME: Align the stack to a 128-bit boundary to avoid 157 # potential performance hits. 158 159 call *28(%ebp) 160 161 # stdcall functions pop arguments off the stack themselves 162 163 # Load %ecx with the return type code 164 movl 20(%ebp),%ecx 165 166 # If the return value pointer is NULL, assume no return value. 167 cmpl $0,24(%ebp) 168 jne sc_retint 169 170 # Even if there is no space for the return value, we are 171 # obliged to handle floating-point values. 172 cmpl $FFI_TYPE_FLOAT,%ecx 173 jne sc_noretval 174 fstp %st(0) 175 176 jmp sc_epilogue 177 178sc_retint: 179 cmpl $FFI_TYPE_INT,%ecx 180 jne sc_retfloat 181 # Load %ecx with the pointer to storage for the return value 182 movl 24(%ebp),%ecx 183 movl %eax,0(%ecx) 184 jmp sc_epilogue 185 186sc_retfloat: 187 cmpl $FFI_TYPE_FLOAT,%ecx 188 jne sc_retdouble 189 # Load %ecx with the pointer to storage for the return value 190 movl 24(%ebp),%ecx 191 fstps (%ecx) 192 jmp sc_epilogue 193 194sc_retdouble: 195 cmpl $FFI_TYPE_DOUBLE,%ecx 196 jne sc_retlongdouble 197 # Load %ecx with the pointer to storage for the return value 198 movl 24(%ebp),%ecx 199 fstpl (%ecx) 200 jmp sc_epilogue 201 202sc_retlongdouble: 203 cmpl $FFI_TYPE_LONGDOUBLE,%ecx 204 jne sc_retint64 205 # Load %ecx with the pointer to storage for the return value 206 movl 24(%ebp),%ecx 207 fstpt (%ecx) 208 jmp sc_epilogue 209 210sc_retint64: 211 cmpl $FFI_TYPE_SINT64,%ecx 212 jne sc_retstruct 213 # Load %ecx with the pointer to storage for the return value 214 movl 24(%ebp),%ecx 215 movl %eax,0(%ecx) 216 movl %edx,4(%ecx) 217 218sc_retstruct: 219 # Nothing to do! 220 221sc_noretval: 222sc_epilogue: 223 movl %ebp,%esp 224 popl %ebp 225 ret 226 227.ffi_call_STDCALL_end: 228