OSDN Git Service

40743af5893f878501f8174dc1e907b2dad7da86
[pf3gnuchains/gcc-fork.git] / libffi / src / x86 / win32.S
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  
83 retint:
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  
91 retfloat:
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  
99 retdouble:
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  
107 retlongdouble:
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  
115 retint64:
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  
123 retstruct:
124         # Nothing to do!
125  
126 noretval:
127 epilogue:
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
178 sc_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
186 sc_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
194 sc_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
202 sc_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
210 sc_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
218 sc_retstruct:
219         # Nothing to do!
220
221 sc_noretval:
222 sc_epilogue:
223         movl %ebp,%esp
224         popl %ebp
225         ret
226
227 .ffi_call_STDCALL_end: