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
----------------------------------------------------------------------- */
29
/* theller: almost verbatim translation from gas syntax to MSVC inline
32
/* theller: ffi_call_x86 now returns an integer - the difference of the stack
33
pointer before and after the function call. If everything is ok, zero is
34
returned. If stdcall functions are passed the wrong number of arguments,
35
the difference will be nonzero. */
38
#include <ffi_common.h>
41
ffi_call_x86(void (* prepfunc)(char *, extended_cif *), /* 8 */
42
extended_cif *ecif, /* 12 */
43
unsigned bytes, /* 16 */
44
unsigned flags, /* 20 */
45
unsigned *rvalue, /* 24 */
46
void (*fn)()) /* 28 */
52
push esi // NEW: this register must be preserved across function calls
54
mov esi, esp // save stack pointer before the call
56
// Make room for all of the new args.
58
sub esp, ecx // sub esp, bytes
62
// Place all of the ffi_prep_args in position
63
push [ebp + 12] // ecif
65
call [ebp + 8] // prepfunc
67
// Return stack to previous state and call the function
69
// FIXME: Align the stack to a 128-bit boundary to avoid
70
// potential performance hits.
73
// Load ecif->cif->abi
75
mov ecx, [ecx]ecif.cif
76
mov ecx, [ecx]ecif.cif.abi
80
// STDCALL: Remove the space we pushed for the args
83
// CDECL: Caller has already cleaned the stack
85
// Check that esp has the same value as before!
88
// Load %ecx with the return type code
91
// If the return value pointer is NULL, assume no return value.
93
Intel asm is weird. We have to explicitely specify 'DWORD PTR' in the nexr instruction,
94
otherwise only one BYTE will be compared (instead of a DWORD)!
96
cmp DWORD PTR [ebp + 24], 0
99
// Even if there is no space for the return value, we are
100
// obliged to handle floating-point values.
101
cmp ecx, FFI_TYPE_FLOAT
109
cmp ecx, FFI_TYPE_INT
111
// # Load %ecx with the pointer to storage for the return value
117
cmp ecx, FFI_TYPE_FLOAT
119
// Load %ecx with the pointer to storage for the return value
126
cmp ecx, FFI_TYPE_DOUBLE
128
// movl 24(%ebp),%ecx
133
jmp sc_retlongdouble // avoid warning about unused label
135
cmp ecx, FFI_TYPE_LONGDOUBLE
137
// Load %ecx with the pointer to storage for the return value
140
fstp QWORD PTR [ecx] /* XXX ??? */
144
cmp ecx, FFI_TYPE_SINT64
146
// Load %ecx with the pointer to storage for the return value
157
pop esi // NEW restore: must be preserved across function calls