OSDN Git Service

* configure.ac (HAVE_HIDDEN_VISIBILITY_ATTRIBUTE): New test.
[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   retstruct1b
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 retstruct1b:
124         cmpl  $FFI_TYPE_SINT8,%ecx
125         jne   retstruct2b
126         # Load %ecx with the pointer to storage for the return value
127         movl  24(%ebp),%ecx
128         movb  %al,0(%ecx)
129         jmp   epilogue
130  
131 retstruct2b:
132         cmpl  $FFI_TYPE_SINT16,%ecx
133         jne   retstruct
134         # Load %ecx with the pointer to storage for the return value
135         movl  24(%ebp),%ecx
136         movw  %ax,0(%ecx)
137         jmp   epilogue
138  
139 retstruct:
140         # Nothing to do!
141  
142 noretval:
143 epilogue:
144         movl %ebp,%esp
145         popl %ebp
146         ret
147  
148 .ffi_call_SYSV_end:
149
150         # This assumes we are using gas.
151         .balign 16
152 .globl _ffi_call_STDCALL
153
154 _ffi_call_STDCALL:
155         pushl %ebp
156         movl  %esp,%ebp
157
158         # Make room for all of the new args.
159         movl  16(%ebp),%ecx 
160         subl  %ecx,%esp
161
162         movl  %esp,%eax
163
164         # Place all of the ffi_prep_args in position
165         pushl 12(%ebp)
166         pushl %eax
167         call  *8(%ebp)
168
169         # Return stack to previous state and call the function
170         addl  $8,%esp
171
172         # FIXME: Align the stack to a 128-bit boundary to avoid
173         # potential performance hits.
174
175         call  *28(%ebp)
176
177         # stdcall functions pop arguments off the stack themselves
178
179         # Load %ecx with the return type code
180         movl  20(%ebp),%ecx
181
182         # If the return value pointer is NULL, assume no return value.
183         cmpl  $0,24(%ebp)
184         jne   sc_retint
185
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
189         jne   sc_noretval
190         fstp  %st(0)
191
192         jmp   sc_epilogue
193
194 sc_retint:
195         cmpl  $FFI_TYPE_INT,%ecx
196         jne   sc_retfloat
197         # Load %ecx with the pointer to storage for the return value
198         movl  24(%ebp),%ecx
199         movl  %eax,0(%ecx)
200         jmp   sc_epilogue
201
202 sc_retfloat:
203         cmpl  $FFI_TYPE_FLOAT,%ecx
204         jne   sc_retdouble
205          # Load %ecx with the pointer to storage for the return value
206         movl  24(%ebp),%ecx
207         fstps (%ecx)
208         jmp   sc_epilogue
209
210 sc_retdouble:
211         cmpl  $FFI_TYPE_DOUBLE,%ecx
212         jne   sc_retlongdouble
213         # Load %ecx with the pointer to storage for the return value
214         movl  24(%ebp),%ecx
215         fstpl (%ecx)
216         jmp   sc_epilogue
217
218 sc_retlongdouble:
219         cmpl  $FFI_TYPE_LONGDOUBLE,%ecx
220         jne   sc_retint64
221         # Load %ecx with the pointer to storage for the return value
222         movl  24(%ebp),%ecx
223         fstpt (%ecx)
224         jmp   sc_epilogue
225
226 sc_retint64:
227         cmpl  $FFI_TYPE_SINT64,%ecx
228         jne   sc_retstruct1b
229         # Load %ecx with the pointer to storage for the return value
230         movl  24(%ebp),%ecx
231         movl  %eax,0(%ecx)
232         movl  %edx,4(%ecx)
233
234 sc_retstruct1b:
235         cmpl  $FFI_TYPE_SINT8,%ecx
236         jne   sc_retstruct2b
237         # Load %ecx with the pointer to storage for the return value
238         movl  24(%ebp),%ecx
239         movb  %al,0(%ecx)
240         jmp   sc_epilogue
241
242 sc_retstruct2b:
243         cmpl  $FFI_TYPE_SINT16,%ecx
244         jne   sc_retstruct
245         # Load %ecx with the pointer to storage for the return value
246         movl  24(%ebp),%ecx
247         movw  %ax,0(%ecx)
248         jmp   sc_epilogue
249
250 sc_retstruct:
251         # Nothing to do!
252
253 sc_noretval:
254 sc_epilogue:
255         movl %ebp,%esp
256         popl %ebp
257         ret
258
259 .ffi_call_STDCALL_end:
260
261         .globl _ffi_closure_SYSV
262 _ffi_closure_SYSV:
263         pushl   %ebp
264         movl    %esp, %ebp
265         subl    $40, %esp
266         leal    -24(%ebp), %edx
267         movl    %edx, -12(%ebp) /* resp */
268         leal    8(%ebp), %edx
269         movl    %edx, 4(%esp)   /* args = __builtin_dwarf_cfa () */
270         leal    -12(%ebp), %edx
271         movl    %edx, (%esp)    /* &resp */
272         call    _ffi_closure_SYSV_inner
273         movl    -12(%ebp), %ecx
274         cmpl    $FFI_TYPE_INT, %eax
275         je      .Lcls_retint
276         cmpl    $FFI_TYPE_FLOAT, %eax
277         je      .Lcls_retfloat
278         cmpl    $FFI_TYPE_DOUBLE, %eax
279         je      .Lcls_retdouble
280         cmpl    $FFI_TYPE_LONGDOUBLE, %eax
281         je      .Lcls_retldouble
282         cmpl    $FFI_TYPE_SINT64, %eax
283         je      .Lcls_retllong
284         cmpl    $FFI_TYPE_SINT8, %eax   /* 1-byte struct */
285         je      .Lcls_retstruct1
286         cmpl    $FFI_TYPE_SINT16, %eax  /* 2-bytes struct */
287         je      .Lcls_retstruct2
288 .Lcls_epilogue:
289         movl    %ebp, %esp
290         popl    %ebp
291         ret
292 .Lcls_retint:
293         movl    (%ecx), %eax
294         jmp     .Lcls_epilogue
295 .Lcls_retfloat:
296         flds    (%ecx)
297         jmp     .Lcls_epilogue
298 .Lcls_retdouble:
299         fldl    (%ecx)
300         jmp     .Lcls_epilogue
301 .Lcls_retldouble:
302         fldt    (%ecx)
303         jmp     .Lcls_epilogue
304 .Lcls_retllong:
305         movl    (%ecx), %eax
306         movl    4(%ecx), %edx
307         jmp     .Lcls_epilogue
308 .Lcls_retstruct1:
309         movsbl  (%ecx), %eax
310         jmp     .Lcls_epilogue
311 .Lcls_retstruct2:
312         movswl  (%ecx), %eax
313         jmp     .Lcls_epilogue
314 .ffi_closure_SYSV_end:
315
316 #if !FFI_NO_RAW_API
317
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
322
323         .balign 16
324         .globl _ffi_closure_raw_SYSV
325 _ffi_closure_raw_SYSV:
326         pushl   %ebp
327         movl    %esp, %ebp
328         pushl   %esi
329         subl    $36, %esp
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 */
335         leal    -24(%ebp), %edx
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
341         je      .Lrcls_retint
342         cmpl    $FFI_TYPE_FLOAT, %eax
343         je      .Lrcls_retfloat
344         cmpl    $FFI_TYPE_DOUBLE, %eax
345         je      .Lrcls_retdouble
346         cmpl    $FFI_TYPE_LONGDOUBLE, %eax
347         je      .Lrcls_retldouble
348         cmpl    $FFI_TYPE_SINT64, %eax
349         je      .Lrcls_retllong
350 .Lrcls_epilogue:
351         addl    $36, %esp
352         popl    %esi
353         popl    %ebp
354         ret
355 .Lrcls_retint:
356         movl    -24(%ebp), %eax
357         jmp     .Lrcls_epilogue
358 .Lrcls_retfloat:
359         flds    -24(%ebp)
360         jmp     .Lrcls_epilogue
361 .Lrcls_retdouble:
362         fldl    -24(%ebp)
363         jmp     .Lrcls_epilogue
364 .Lrcls_retldouble:
365         fldt    -24(%ebp)
366         jmp     .Lrcls_epilogue
367 .Lrcls_retllong:
368         movl    -24(%ebp), %eax
369         movl    -20(%ebp), %edx
370         jmp     .Lrcls_epilogue
371 .ffi_closure_raw_SYSV_end:
372
373 #endif