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
7
X86 Foreign Function Interface
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:
17
The above copyright notice and this permission notice shall be included
18
in all copies or substantial portions of the Software.
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
----------------------------------------------------------------------- */
30
#include <fficonfig.h>
37
# This assumes we are using gas.
45
# Make room for all of the new args.
51
# Place all of the ffi_prep_args in position
56
# Return stack to previous state and call the function
59
# FIXME: Align the stack to a 128-bit boundary to avoid
60
# potential performance hits.
64
# Remove the space we pushed for the args
68
# Load %ecx with the return type code
71
# If the return value pointer is NULL, assume no return value.
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
84
cmpl $FFI_TYPE_INT,%ecx
86
# Load %ecx with the pointer to storage for the return value
92
cmpl $FFI_TYPE_FLOAT,%ecx
94
# Load %ecx with the pointer to storage for the return value
100
cmpl $FFI_TYPE_DOUBLE,%ecx
102
# Load %ecx with the pointer to storage for the return value
108
cmpl $FFI_TYPE_LONGDOUBLE,%ecx
110
# Load %ecx with the pointer to storage for the return value
116
cmpl $FFI_TYPE_SINT64,%ecx
118
# Load %ecx with the pointer to storage for the return value
124
cmpl $FFI_TYPE_SINT8,%ecx
126
# Load %ecx with the pointer to storage for the return value
132
cmpl $FFI_TYPE_SINT16,%ecx
134
# Load %ecx with the pointer to storage for the return value
150
# This assumes we are using gas.
152
.globl _ffi_call_STDCALL
158
# Make room for all of the new args.
164
# Place all of the ffi_prep_args in position
169
# Return stack to previous state and call the function
172
# FIXME: Align the stack to a 128-bit boundary to avoid
173
# potential performance hits.
177
# stdcall functions pop arguments off the stack themselves
179
# Load %ecx with the return type code
182
# If the return value pointer is NULL, assume no return value.
186
# Even if there is no space for the return value, we are
187
# obliged to handle floating-point values.
188
cmpl $FFI_TYPE_FLOAT,%ecx
195
cmpl $FFI_TYPE_INT,%ecx
197
# Load %ecx with the pointer to storage for the return value
203
cmpl $FFI_TYPE_FLOAT,%ecx
205
# Load %ecx with the pointer to storage for the return value
211
cmpl $FFI_TYPE_DOUBLE,%ecx
213
# Load %ecx with the pointer to storage for the return value
219
cmpl $FFI_TYPE_LONGDOUBLE,%ecx
221
# Load %ecx with the pointer to storage for the return value
227
cmpl $FFI_TYPE_SINT64,%ecx
229
# Load %ecx with the pointer to storage for the return value
235
cmpl $FFI_TYPE_SINT8,%ecx
237
# Load %ecx with the pointer to storage for the return value
243
cmpl $FFI_TYPE_SINT16,%ecx
245
# Load %ecx with the pointer to storage for the return value
259
.ffi_call_STDCALL_end:
261
.globl _ffi_closure_SYSV
267
movl %edx, -12(%ebp) /* resp */
269
movl %edx, 4(%esp) /* args = __builtin_dwarf_cfa () */
271
movl %edx, (%esp) /* &resp */
272
call _ffi_closure_SYSV_inner
274
cmpl $FFI_TYPE_INT, %eax
276
cmpl $FFI_TYPE_FLOAT, %eax
278
cmpl $FFI_TYPE_DOUBLE, %eax
280
cmpl $FFI_TYPE_LONGDOUBLE, %eax
282
cmpl $FFI_TYPE_SINT64, %eax
284
cmpl $FFI_TYPE_SINT8, %eax /* 1-byte struct */
286
cmpl $FFI_TYPE_SINT16, %eax /* 2-bytes struct */
314
.ffi_closure_SYSV_end:
318
#define RAW_CLOSURE_CIF_OFFSET ((FFI_TRAMPOLINE_SIZE + 3) & ~3)
319
#define RAW_CLOSURE_FUN_OFFSET (RAW_CLOSURE_CIF_OFFSET + 4)
320
#define RAW_CLOSURE_USER_DATA_OFFSET (RAW_CLOSURE_FUN_OFFSET + 4)
321
#define CIF_FLAGS_OFFSET 20
324
.globl _ffi_closure_raw_SYSV
325
_ffi_closure_raw_SYSV:
330
movl RAW_CLOSURE_CIF_OFFSET(%eax), %esi /* closure->cif */
331
movl RAW_CLOSURE_USER_DATA_OFFSET(%eax), %edx /* closure->user_data */
332
movl %edx, 12(%esp) /* user_data */
333
leal 8(%ebp), %edx /* __builtin_dwarf_cfa () */
334
movl %edx, 8(%esp) /* raw_args */
336
movl %edx, 4(%esp) /* &res */
337
movl %esi, (%esp) /* cif */
338
call *RAW_CLOSURE_FUN_OFFSET(%eax) /* closure->fun */
339
movl CIF_FLAGS_OFFSET(%esi), %eax /* rtype */
340
cmpl $FFI_TYPE_INT, %eax
342
cmpl $FFI_TYPE_FLOAT, %eax
344
cmpl $FFI_TYPE_DOUBLE, %eax
346
cmpl $FFI_TYPE_LONGDOUBLE, %eax
348
cmpl $FFI_TYPE_SINT64, %eax
371
.ffi_closure_raw_SYSV_end: