OSDN Git Service

a54c23538bfa2e985cab3ea6d05ed9a5dbea14e1
[pf3gnuchains/gcc-fork.git] / libffi / src / x86 / win32.S
1 /* -----------------------------------------------------------------------
2    win32.S - Copyright (c) 1996, 1998, 2001, 2002, 2009  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         .extern ffi_prep_args
36  
37         # This assumes we are using gas.
38         .balign 16
39         .globl  _ffi_call_SYSV
40         .def    _ffi_call_SYSV; .scl    2;      .type   32;     .endef
41 _ffi_call_SYSV:
42 .LFB1:
43         pushl %ebp
44 .LCFI0:
45         movl  %esp,%ebp
46 .LCFI1:
47         # Make room for all of the new args.
48         movl  16(%ebp),%ecx                                                     
49         subl  %ecx,%esp
50  
51         movl  %esp,%eax
52  
53         # Place all of the ffi_prep_args in position
54         pushl 12(%ebp)
55         pushl %eax
56         call  *8(%ebp)
57  
58         # Return stack to previous state and call the function
59         addl  $8,%esp
60  
61         # FIXME: Align the stack to a 128-bit boundary to avoid
62         # potential performance hits.
63
64         call  *28(%ebp)
65  
66         # Remove the space we pushed for the args
67         movl  16(%ebp),%ecx
68         addl  %ecx,%esp
69  
70         # Load %ecx with the return type code
71         movl  20(%ebp),%ecx
72  
73         # If the return value pointer is NULL, assume no return value.
74         cmpl  $0,24(%ebp)
75         jne   retint
76  
77         # Even if there is no space for the return value, we are
78         # obliged to handle floating-point values.
79         cmpl  $FFI_TYPE_FLOAT,%ecx
80         jne   noretval
81         fstp  %st(0)
82  
83         jmp   epilogue
84  
85 retint:
86         cmpl  $FFI_TYPE_INT,%ecx
87         jne   retfloat
88         # Load %ecx with the pointer to storage for the return value
89         movl  24(%ebp),%ecx
90         movl  %eax,0(%ecx)
91         jmp   epilogue
92  
93 retfloat:
94         cmpl  $FFI_TYPE_FLOAT,%ecx
95         jne   retdouble   
96          # Load %ecx with the pointer to storage for the return value
97         movl  24(%ebp),%ecx
98         fstps (%ecx)
99         jmp   epilogue
100  
101 retdouble:
102         cmpl  $FFI_TYPE_DOUBLE,%ecx
103         jne   retlongdouble
104         # Load %ecx with the pointer to storage for the return value
105         movl  24(%ebp),%ecx
106         fstpl (%ecx)
107         jmp   epilogue
108  
109 retlongdouble:
110         cmpl  $FFI_TYPE_LONGDOUBLE,%ecx
111         jne   retint64
112         # Load %ecx with the pointer to storage for the return value
113         movl  24(%ebp),%ecx
114         fstpt (%ecx)
115         jmp   epilogue
116  
117 retint64:
118         cmpl  $FFI_TYPE_SINT64,%ecx
119         jne   retstruct1b
120         # Load %ecx with the pointer to storage for the return value
121         movl  24(%ebp),%ecx
122         movl  %eax,0(%ecx)
123         movl  %edx,4(%ecx)
124  
125 retstruct1b:
126         cmpl  $FFI_TYPE_SINT8,%ecx
127         jne   retstruct2b
128         # Load %ecx with the pointer to storage for the return value
129         movl  24(%ebp),%ecx
130         movb  %al,0(%ecx)
131         jmp   epilogue
132  
133 retstruct2b:
134         cmpl  $FFI_TYPE_SINT16,%ecx
135         jne   retstruct
136         # Load %ecx with the pointer to storage for the return value
137         movl  24(%ebp),%ecx
138         movw  %ax,0(%ecx)
139         jmp   epilogue
140  
141 retstruct:
142         # Nothing to do!
143  
144 noretval:
145 epilogue:
146         movl %ebp,%esp
147         popl %ebp
148         ret
149 .ffi_call_SYSV_end:
150 .LFE1:
151
152         # This assumes we are using gas.
153         .balign 16
154         .globl  _ffi_call_STDCALL
155         .def    _ffi_call_STDCALL;      .scl    2;      .type   32;     .endef
156 _ffi_call_STDCALL:
157 .LFB2:
158         pushl %ebp
159 .LCFI2:
160         movl  %esp,%ebp
161 .LCFI3:
162         # Make room for all of the new args.
163         movl  16(%ebp),%ecx 
164         subl  %ecx,%esp
165
166         movl  %esp,%eax
167
168         # Place all of the ffi_prep_args in position
169         pushl 12(%ebp)
170         pushl %eax
171         call  *8(%ebp)
172
173         # Return stack to previous state and call the function
174         addl  $8,%esp
175
176         # FIXME: Align the stack to a 128-bit boundary to avoid
177         # potential performance hits.
178
179         call  *28(%ebp)
180
181         # stdcall functions pop arguments off the stack themselves
182
183         # Load %ecx with the return type code
184         movl  20(%ebp),%ecx
185
186         # If the return value pointer is NULL, assume no return value.
187         cmpl  $0,24(%ebp)
188         jne   sc_retint
189
190         # Even if there is no space for the return value, we are
191         # obliged to handle floating-point values.
192         cmpl  $FFI_TYPE_FLOAT,%ecx
193         jne   sc_noretval
194         fstp  %st(0)
195
196         jmp   sc_epilogue
197
198 sc_retint:
199         cmpl  $FFI_TYPE_INT,%ecx
200         jne   sc_retfloat
201         # Load %ecx with the pointer to storage for the return value
202         movl  24(%ebp),%ecx
203         movl  %eax,0(%ecx)
204         jmp   sc_epilogue
205
206 sc_retfloat:
207         cmpl  $FFI_TYPE_FLOAT,%ecx
208         jne   sc_retdouble
209          # Load %ecx with the pointer to storage for the return value
210         movl  24(%ebp),%ecx
211         fstps (%ecx)
212         jmp   sc_epilogue
213
214 sc_retdouble:
215         cmpl  $FFI_TYPE_DOUBLE,%ecx
216         jne   sc_retlongdouble
217         # Load %ecx with the pointer to storage for the return value
218         movl  24(%ebp),%ecx
219         fstpl (%ecx)
220         jmp   sc_epilogue
221
222 sc_retlongdouble:
223         cmpl  $FFI_TYPE_LONGDOUBLE,%ecx
224         jne   sc_retint64
225         # Load %ecx with the pointer to storage for the return value
226         movl  24(%ebp),%ecx
227         fstpt (%ecx)
228         jmp   sc_epilogue
229
230 sc_retint64:
231         cmpl  $FFI_TYPE_SINT64,%ecx
232         jne   sc_retstruct1b
233         # Load %ecx with the pointer to storage for the return value
234         movl  24(%ebp),%ecx
235         movl  %eax,0(%ecx)
236         movl  %edx,4(%ecx)
237
238 sc_retstruct1b:
239         cmpl  $FFI_TYPE_SINT8,%ecx
240         jne   sc_retstruct2b
241         # Load %ecx with the pointer to storage for the return value
242         movl  24(%ebp),%ecx
243         movb  %al,0(%ecx)
244         jmp   sc_epilogue
245
246 sc_retstruct2b:
247         cmpl  $FFI_TYPE_SINT16,%ecx
248         jne   sc_retstruct
249         # Load %ecx with the pointer to storage for the return value
250         movl  24(%ebp),%ecx
251         movw  %ax,0(%ecx)
252         jmp   sc_epilogue
253
254 sc_retstruct:
255         # Nothing to do!
256
257 sc_noretval:
258 sc_epilogue:
259         movl %ebp,%esp
260         popl %ebp
261         ret
262 .ffi_call_STDCALL_end:
263 .LFE2:
264
265         # This assumes we are using gas.
266         .balign 16
267         .globl  _ffi_closure_SYSV
268         .def    _ffi_closure_SYSV;      .scl    2;      .type   32;     .endef
269 _ffi_closure_SYSV:
270 .LFB3:
271         pushl   %ebp
272 .LCFI4:
273         movl    %esp, %ebp
274 .LCFI5:
275         subl    $40, %esp
276         leal    -24(%ebp), %edx
277         movl    %edx, -12(%ebp) /* resp */
278         leal    8(%ebp), %edx
279         movl    %edx, 4(%esp)   /* args = __builtin_dwarf_cfa () */
280         leal    -12(%ebp), %edx
281         movl    %edx, (%esp)    /* &resp */
282         call    _ffi_closure_SYSV_inner
283         movl    -12(%ebp), %ecx
284         cmpl    $FFI_TYPE_INT, %eax
285         je      .Lcls_retint
286         cmpl    $FFI_TYPE_FLOAT, %eax
287         je      .Lcls_retfloat
288         cmpl    $FFI_TYPE_DOUBLE, %eax
289         je      .Lcls_retdouble
290         cmpl    $FFI_TYPE_LONGDOUBLE, %eax
291         je      .Lcls_retldouble
292         cmpl    $FFI_TYPE_SINT64, %eax
293         je      .Lcls_retllong
294         cmpl    $FFI_TYPE_SINT8, %eax   /* 1-byte struct */
295         je      .Lcls_retstruct1
296         cmpl    $FFI_TYPE_SINT16, %eax  /* 2-bytes struct */
297         je      .Lcls_retstruct2
298 .Lcls_epilogue:
299         movl    %ebp, %esp
300         popl    %ebp
301         ret
302 .Lcls_retint:
303         movl    (%ecx), %eax
304         jmp     .Lcls_epilogue
305 .Lcls_retfloat:
306         flds    (%ecx)
307         jmp     .Lcls_epilogue
308 .Lcls_retdouble:
309         fldl    (%ecx)
310         jmp     .Lcls_epilogue
311 .Lcls_retldouble:
312         fldt    (%ecx)
313         jmp     .Lcls_epilogue
314 .Lcls_retllong:
315         movl    (%ecx), %eax
316         movl    4(%ecx), %edx
317         jmp     .Lcls_epilogue
318 .Lcls_retstruct1:
319         movsbl  (%ecx), %eax
320         jmp     .Lcls_epilogue
321 .Lcls_retstruct2:
322         movswl  (%ecx), %eax
323         jmp     .Lcls_epilogue
324 .ffi_closure_SYSV_end:
325 .LFE3:
326
327 #if !FFI_NO_RAW_API
328
329 #define RAW_CLOSURE_CIF_OFFSET ((FFI_TRAMPOLINE_SIZE + 3) & ~3)
330 #define RAW_CLOSURE_FUN_OFFSET (RAW_CLOSURE_CIF_OFFSET + 4)
331 #define RAW_CLOSURE_USER_DATA_OFFSET (RAW_CLOSURE_FUN_OFFSET + 4)
332 #define CIF_FLAGS_OFFSET 20
333
334         # This assumes we are using gas.
335         .balign 16
336         .globl  _ffi_closure_raw_SYSV
337         .def    _ffi_closure_raw_SYSV;  .scl    2;      .type   32;     .endef
338 _ffi_closure_raw_SYSV:
339 .LFB4:
340         pushl   %ebp
341 .LCFI6:
342         movl    %esp, %ebp
343 .LCFI7:
344         pushl   %esi
345 .LCFI8:
346         subl    $36, %esp
347         movl    RAW_CLOSURE_CIF_OFFSET(%eax), %esi       /* closure->cif */
348         movl    RAW_CLOSURE_USER_DATA_OFFSET(%eax), %edx /* closure->user_data */
349         movl    %edx, 12(%esp)  /* user_data */
350         leal    8(%ebp), %edx   /* __builtin_dwarf_cfa () */
351         movl    %edx, 8(%esp)   /* raw_args */
352         leal    -24(%ebp), %edx
353         movl    %edx, 4(%esp)   /* &res */
354         movl    %esi, (%esp)    /* cif */
355         call    *RAW_CLOSURE_FUN_OFFSET(%eax)            /* closure->fun */
356         movl    CIF_FLAGS_OFFSET(%esi), %eax             /* rtype */
357         cmpl    $FFI_TYPE_INT, %eax
358         je      .Lrcls_retint
359         cmpl    $FFI_TYPE_FLOAT, %eax
360         je      .Lrcls_retfloat
361         cmpl    $FFI_TYPE_DOUBLE, %eax
362         je      .Lrcls_retdouble
363         cmpl    $FFI_TYPE_LONGDOUBLE, %eax
364         je      .Lrcls_retldouble
365         cmpl    $FFI_TYPE_SINT64, %eax
366         je      .Lrcls_retllong
367 .Lrcls_epilogue:
368         addl    $36, %esp
369         popl    %esi
370         popl    %ebp
371         ret
372 .Lrcls_retint:
373         movl    -24(%ebp), %eax
374         jmp     .Lrcls_epilogue
375 .Lrcls_retfloat:
376         flds    -24(%ebp)
377         jmp     .Lrcls_epilogue
378 .Lrcls_retdouble:
379         fldl    -24(%ebp)
380         jmp     .Lrcls_epilogue
381 .Lrcls_retldouble:
382         fldt    -24(%ebp)
383         jmp     .Lrcls_epilogue
384 .Lrcls_retllong:
385         movl    -24(%ebp), %eax
386         movl    -20(%ebp), %edx
387         jmp     .Lrcls_epilogue
388 .ffi_closure_raw_SYSV_end:
389 .LFE4:
390
391 #endif /* !FFI_NO_RAW_API */
392
393
394         .section        .eh_frame,"w"
395 .Lframe1:
396 .LSCIE1:
397         .long   .LECIE1-.LASCIE1  /* Length of Common Information Entry */
398 .LASCIE1:
399         .long   0x0     /* CIE Identifier Tag */
400         .byte   0x1     /* CIE Version */
401 #ifdef __PIC__
402         .ascii "zR\0"   /* CIE Augmentation */
403 #else
404         .ascii "\0"     /* CIE Augmentation */
405 #endif
406         .byte   0x1     /* .uleb128 0x1; CIE Code Alignment Factor */
407         .byte   0x7c    /* .sleb128 -4; CIE Data Alignment Factor */
408         .byte   0x8     /* CIE RA Column */
409 #ifdef __PIC__
410         .byte   0x1     /* .uleb128 0x1; Augmentation size */
411         .byte   0x1b    /* FDE Encoding (pcrel sdata4) */
412 #endif
413         .byte   0xc     /* DW_CFA_def_cfa CFA = r4 + 4 = 4(%esp) */
414         .byte   0x4     /* .uleb128 0x4 */
415         .byte   0x4     /* .uleb128 0x4 */
416         .byte   0x88    /* DW_CFA_offset, column 0x8 %eip at CFA + 1 * -4 */
417         .byte   0x1     /* .uleb128 0x1 */
418         .align 4
419 .LECIE1:
420
421 .LSFDE1:
422         .long   .LEFDE1-.LASFDE1        /* FDE Length */
423 .LASFDE1:
424         .long   .LASFDE1-.Lframe1       /* FDE CIE offset */
425 #if defined __PIC__ && defined HAVE_AS_X86_PCREL
426         .long   .LFB1-. /* FDE initial location */
427 #else
428         .long   .LFB1
429 #endif
430         .long   .LFE1-.LFB1     /* FDE address range */
431 #ifdef __PIC__
432         .byte   0x0     /* .uleb128 0x0; Augmentation size */
433 #endif
434         /* DW_CFA_xxx CFI instructions go here.  */
435
436         .byte   0x4     /* DW_CFA_advance_loc4 */
437         .long   .LCFI0-.LFB1
438         .byte   0xe     /* DW_CFA_def_cfa_offset CFA = r4 + 8 = 8(%esp) */
439         .byte   0x8     /* .uleb128 0x8 */
440         .byte   0x85    /* DW_CFA_offset, column 0x5 %ebp at CFA + 2 * -4 */
441         .byte   0x2     /* .uleb128 0x2 */
442
443         .byte   0x4     /* DW_CFA_advance_loc4 */
444         .long   .LCFI1-.LCFI0
445         .byte   0xd     /* DW_CFA_def_cfa_register CFA = r5 = %ebp */
446         .byte   0x5     /* .uleb128 0x5 */
447
448         /* End of DW_CFA_xxx CFI instructions.  */
449         .align 4
450 .LEFDE1:
451
452
453 .LSFDE2:
454         .long   .LEFDE2-.LASFDE2        /* FDE Length */
455 .LASFDE2:
456         .long   .LASFDE2-.Lframe1       /* FDE CIE offset */
457 #if defined __PIC__ && defined HAVE_AS_X86_PCREL
458         .long   .LFB2-. /* FDE initial location */
459 #else
460         .long   .LFB2
461 #endif
462         .long   .LFE2-.LFB2     /* FDE address range */
463 #ifdef __PIC__
464         .byte   0x0     /* .uleb128 0x0; Augmentation size */
465 #endif
466         /* DW_CFA_xxx CFI instructions go here.  */
467
468         .byte   0x4     /* DW_CFA_advance_loc4 */
469         .long   .LCFI2-.LFB2
470         .byte   0xe     /* DW_CFA_def_cfa_offset CFA = r4 + 8 = 8(%esp) */
471         .byte   0x8     /* .uleb128 0x8 */
472         .byte   0x85    /* DW_CFA_offset, column 0x5 %ebp at CFA + 2 * -4 */
473         .byte   0x2     /* .uleb128 0x2 */
474
475         .byte   0x4     /* DW_CFA_advance_loc4 */
476         .long   .LCFI3-.LCFI2
477         .byte   0xd     /* DW_CFA_def_cfa_register CFA = r5 = %ebp */
478         .byte   0x5     /* .uleb128 0x5 */
479
480         /* End of DW_CFA_xxx CFI instructions.  */
481         .align 4
482 .LEFDE2:
483
484
485 .LSFDE3:
486         .long   .LEFDE3-.LASFDE3        /* FDE Length */
487 .LASFDE3:
488         .long   .LASFDE3-.Lframe1       /* FDE CIE offset */
489 #if defined __PIC__ && defined HAVE_AS_X86_PCREL
490         .long   .LFB3-. /* FDE initial location */
491 #else
492         .long   .LFB3
493 #endif
494         .long   .LFE3-.LFB3     /* FDE address range */
495 #ifdef __PIC__
496         .byte   0x0     /* .uleb128 0x0; Augmentation size */
497 #endif
498         /* DW_CFA_xxx CFI instructions go here.  */
499
500         .byte   0x4     /* DW_CFA_advance_loc4 */
501         .long   .LCFI4-.LFB3
502         .byte   0xe     /* DW_CFA_def_cfa_offset CFA = r4 + 8 = 8(%esp) */
503         .byte   0x8     /* .uleb128 0x8 */
504         .byte   0x85    /* DW_CFA_offset, column 0x5 %ebp at CFA + 2 * -4 */
505         .byte   0x2     /* .uleb128 0x2 */
506
507         .byte   0x4     /* DW_CFA_advance_loc4 */
508         .long   .LCFI5-.LCFI4
509         .byte   0xd     /* DW_CFA_def_cfa_register CFA = r5 = %ebp */
510         .byte   0x5     /* .uleb128 0x5 */
511
512         /* End of DW_CFA_xxx CFI instructions.  */
513         .align 4
514 .LEFDE3:
515
516 #if !FFI_NO_RAW_API
517
518 .LSFDE4:
519         .long   .LEFDE4-.LASFDE4        /* FDE Length */
520 .LASFDE4:
521         .long   .LASFDE4-.Lframe1       /* FDE CIE offset */
522 #if defined __PIC__ && defined HAVE_AS_X86_PCREL
523         .long   .LFB4-. /* FDE initial location */
524 #else
525         .long   .LFB4
526 #endif
527         .long   .LFE4-.LFB4     /* FDE address range */
528 #ifdef __PIC__
529         .byte   0x0     /* .uleb128 0x0; Augmentation size */
530 #endif
531         /* DW_CFA_xxx CFI instructions go here.  */
532
533         .byte   0x4     /* DW_CFA_advance_loc4 */
534         .long   .LCFI6-.LFB4
535         .byte   0xe     /* DW_CFA_def_cfa_offset CFA = r4 + 8 = 8(%esp) */
536         .byte   0x8     /* .uleb128 0x8 */
537         .byte   0x85    /* DW_CFA_offset, column 0x5 %ebp at CFA + 2 * -4 */
538         .byte   0x2     /* .uleb128 0x2 */
539
540         .byte   0x4     /* DW_CFA_advance_loc4 */
541         .long   .LCFI7-.LCFI6
542         .byte   0xd     /* DW_CFA_def_cfa_register CFA = r5 = %ebp */
543         .byte   0x5     /* .uleb128 0x5 */
544
545         .byte   0x4     /* DW_CFA_advance_loc4 */
546         .long   .LCFI8-.LCFI7
547         .byte   0x86    /* DW_CFA_offset, column 0x6 %esi at CFA + 3 * -4 */
548         .byte   0x3     /* .uleb128 0x3 */
549
550         /* End of DW_CFA_xxx CFI instructions.  */
551         .align 4
552 .LEFDE4:
553
554 #endif /* !FFI_NO_RAW_API */