OSDN Git Service

PR libffi/40807
[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,
21    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23    NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
24    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
25    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27    DEALINGS IN THE SOFTWARE.
28    -----------------------------------------------------------------------
29    */
30  
31 #define LIBFFI_ASM
32 #include <fficonfig.h>
33 #include <ffi.h>
34  
35         .text
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         # Load %ecx with the return type code
67         movl  20(%ebp),%ecx
68  
69         # If the return value pointer is NULL, assume no return value.
70         cmpl  $0,24(%ebp)
71         jne   0f
72  
73         # Even if there is no space for the return value, we are
74         # obliged to handle floating-point values.
75         cmpl  $FFI_TYPE_FLOAT,%ecx
76         jne   .Lnoretval
77         fstp  %st(0)
78  
79         jmp   .Lepilogue
80
81 0:
82         call    1f
83         # Do not insert anything here between the call and the jump table.
84 .Lstore_table:
85         .long   .Lnoretval              /* FFI_TYPE_VOID */
86         .long   .Lretint                /* FFI_TYPE_INT */
87         .long   .Lretfloat              /* FFI_TYPE_FLOAT */
88         .long   .Lretdouble             /* FFI_TYPE_DOUBLE */
89         .long   .Lretlongdouble         /* FFI_TYPE_LONGDOUBLE */
90         .long   .Lretuint8              /* FFI_TYPE_UINT8 */
91         .long   .Lretsint8              /* FFI_TYPE_SINT8 */
92         .long   .Lretuint16             /* FFI_TYPE_UINT16 */
93         .long   .Lretsint16             /* FFI_TYPE_SINT16 */
94         .long   .Lretint                /* FFI_TYPE_UINT32 */
95         .long   .Lretint                /* FFI_TYPE_SINT32 */
96         .long   .Lretint64              /* FFI_TYPE_UINT64 */
97         .long   .Lretint64              /* FFI_TYPE_SINT64 */
98         .long   .Lretstruct             /* FFI_TYPE_STRUCT */
99         .long   .Lretint                /* FFI_TYPE_POINTER */
100         .long   .Lretstruct1b           /* FFI_TYPE_SMALL_STRUCT_1B */
101         .long   .Lretstruct2b           /* FFI_TYPE_SMALL_STRUCT_2B */
102         .long   .Lretstruct4b           /* FFI_TYPE_SMALL_STRUCT_4B */
103 1:
104         add     %ecx, %ecx
105         add     %ecx, %ecx
106         add     (%esp),%ecx
107         add     $4, %esp
108         jmp     *(%ecx)
109
110         /* Sign/zero extend as appropriate.  */
111 .Lretsint8:
112         movsbl  %al, %eax
113         jmp     .Lretint
114
115 .Lretsint16:
116         movswl  %ax, %eax
117         jmp     .Lretint
118
119 .Lretuint8:
120         movzbl  %al, %eax
121         jmp     .Lretint
122
123 .Lretuint16:
124         movzwl  %ax, %eax
125         jmp     .Lretint
126
127 .Lretint:
128         # Load %ecx with the pointer to storage for the return value
129         movl  24(%ebp),%ecx
130         movl  %eax,0(%ecx)
131         jmp   .Lepilogue
132  
133 .Lretfloat:
134          # Load %ecx with the pointer to storage for the return value
135         movl  24(%ebp),%ecx
136         fstps (%ecx)
137         jmp   .Lepilogue
138  
139 .Lretdouble:
140         # Load %ecx with the pointer to storage for the return value
141         movl  24(%ebp),%ecx
142         fstpl (%ecx)
143         jmp   .Lepilogue
144  
145 .Lretlongdouble:
146         # Load %ecx with the pointer to storage for the return value
147         movl  24(%ebp),%ecx
148         fstpt (%ecx)
149         jmp   .Lepilogue
150  
151 .Lretint64:
152         # Load %ecx with the pointer to storage for the return value
153         movl  24(%ebp),%ecx
154         movl  %eax,0(%ecx)
155         movl  %edx,4(%ecx)
156         jmp   .Lepilogue
157
158 .Lretstruct1b:
159         # Load %ecx with the pointer to storage for the return value
160         movl  24(%ebp),%ecx
161         movb  %al,0(%ecx)
162         jmp   .Lepilogue
163  
164 .Lretstruct2b:
165         # Load %ecx with the pointer to storage for the return value
166         movl  24(%ebp),%ecx
167         movw  %ax,0(%ecx)
168         jmp   .Lepilogue
169
170 .Lretstruct4b:
171         # Load %ecx with the pointer to storage for the return value
172         movl  24(%ebp),%ecx
173         movl  %eax,0(%ecx)
174         jmp   .Lepilogue
175
176 .Lretstruct:
177         # Nothing to do!
178  
179 .Lnoretval:
180 .Lepilogue:
181         movl %ebp,%esp
182         popl %ebp
183         ret
184 .ffi_call_SYSV_end:
185 .LFE1:
186
187         # This assumes we are using gas.
188         .balign 16
189         .globl  _ffi_call_STDCALL
190         .def    _ffi_call_STDCALL;      .scl    2;      .type   32;     .endef
191 _ffi_call_STDCALL:
192 .LFB2:
193         pushl %ebp
194 .LCFI2:
195         movl  %esp,%ebp
196 .LCFI3:
197         # Make room for all of the new args.
198         movl  16(%ebp),%ecx 
199         subl  %ecx,%esp
200
201         movl  %esp,%eax
202
203         # Place all of the ffi_prep_args in position
204         pushl 12(%ebp)
205         pushl %eax
206         call  *8(%ebp)
207
208         # Return stack to previous state and call the function
209         addl  $8,%esp
210
211         # FIXME: Align the stack to a 128-bit boundary to avoid
212         # potential performance hits.
213
214         call  *28(%ebp)
215
216         # stdcall functions pop arguments off the stack themselves
217
218         # Load %ecx with the return type code
219         movl  20(%ebp),%ecx
220
221         # If the return value pointer is NULL, assume no return value.
222         cmpl  $0,24(%ebp)
223         jne   0f
224
225         # Even if there is no space for the return value, we are
226         # obliged to handle floating-point values.
227         cmpl  $FFI_TYPE_FLOAT,%ecx
228         jne   .Lsc_noretval
229         fstp  %st(0)
230
231         jmp   .Lsc_epilogue
232
233 0:
234         call    1f
235         # Do not insert anything here between the call and the jump table.
236 .Lsc_store_table:
237         .long   .Lsc_noretval           /* FFI_TYPE_VOID */
238         .long   .Lsc_retint             /* FFI_TYPE_INT */
239         .long   .Lsc_retfloat           /* FFI_TYPE_FLOAT */
240         .long   .Lsc_retdouble          /* FFI_TYPE_DOUBLE */
241         .long   .Lsc_retlongdouble      /* FFI_TYPE_LONGDOUBLE */
242         .long   .Lsc_retuint8           /* FFI_TYPE_UINT8 */
243         .long   .Lsc_retsint8           /* FFI_TYPE_SINT8 */
244         .long   .Lsc_retuint16          /* FFI_TYPE_UINT16 */
245         .long   .Lsc_retsint16          /* FFI_TYPE_SINT16 */
246         .long   .Lsc_retint             /* FFI_TYPE_UINT32 */
247         .long   .Lsc_retint             /* FFI_TYPE_SINT32 */
248         .long   .Lsc_retint64           /* FFI_TYPE_UINT64 */
249         .long   .Lsc_retint64           /* FFI_TYPE_SINT64 */
250         .long   .Lsc_retstruct          /* FFI_TYPE_STRUCT */
251         .long   .Lsc_retint             /* FFI_TYPE_POINTER */
252         .long   .Lsc_retstruct1b        /* FFI_TYPE_SMALL_STRUCT_1B */
253         .long   .Lsc_retstruct2b        /* FFI_TYPE_SMALL_STRUCT_2B */
254         .long   .Lsc_retstruct4b        /* FFI_TYPE_SMALL_STRUCT_4B */
255
256 1:
257         add     %ecx, %ecx
258         add     %ecx, %ecx
259         add     (%esp),%ecx
260         add     $4, %esp
261         jmp     *(%ecx)
262
263         /* Sign/zero extend as appropriate.  */
264 .Lsc_retsint8:
265         movsbl  %al, %eax
266         jmp     .Lsc_retint
267
268 .Lsc_retsint16:
269         movswl  %ax, %eax
270         jmp     .Lsc_retint
271
272 .Lsc_retuint8:
273         movzbl  %al, %eax
274         jmp     .Lsc_retint
275
276 .Lsc_retuint16:
277         movzwl  %ax, %eax
278         jmp     .Lsc_retint
279
280 .Lsc_retint:
281         # Load %ecx with the pointer to storage for the return value
282         movl  24(%ebp),%ecx
283         movl  %eax,0(%ecx)
284         jmp   .Lsc_epilogue
285
286 .Lsc_retfloat:
287          # Load %ecx with the pointer to storage for the return value
288         movl  24(%ebp),%ecx
289         fstps (%ecx)
290         jmp   .Lsc_epilogue
291
292 .Lsc_retdouble:
293         # Load %ecx with the pointer to storage for the return value
294         movl  24(%ebp),%ecx
295         fstpl (%ecx)
296         jmp   .Lsc_epilogue
297
298 .Lsc_retlongdouble:
299         # Load %ecx with the pointer to storage for the return value
300         movl  24(%ebp),%ecx
301         fstpt (%ecx)
302         jmp   .Lsc_epilogue
303
304 .Lsc_retint64:
305         # Load %ecx with the pointer to storage for the return value
306         movl  24(%ebp),%ecx
307         movl  %eax,0(%ecx)
308         movl  %edx,4(%ecx)
309         jmp   .Lsc_epilogue
310
311 .Lsc_retstruct1b:
312         # Load %ecx with the pointer to storage for the return value
313         movl  24(%ebp),%ecx
314         movb  %al,0(%ecx)
315         jmp   .Lsc_epilogue
316
317 .Lsc_retstruct2b:
318         # Load %ecx with the pointer to storage for the return value
319         movl  24(%ebp),%ecx
320         movw  %ax,0(%ecx)
321         jmp   .Lsc_epilogue
322
323 .Lsc_retstruct4b:
324         # Load %ecx with the pointer to storage for the return value
325         movl  24(%ebp),%ecx
326         movl  %eax,0(%ecx)
327         jmp   .Lsc_epilogue
328
329 .Lsc_retstruct:
330         # Nothing to do!
331
332 .Lsc_noretval:
333 .Lsc_epilogue:
334         movl %ebp,%esp
335         popl %ebp
336         ret
337 .ffi_call_STDCALL_end:
338 .LFE2:
339
340         # This assumes we are using gas.
341         .balign 16
342         .globl  _ffi_closure_SYSV
343         .def    _ffi_closure_SYSV;      .scl    2;      .type   32;     .endef
344 _ffi_closure_SYSV:
345 .LFB3:
346         pushl   %ebp
347 .LCFI4:
348         movl    %esp, %ebp
349 .LCFI5:
350         subl    $40, %esp
351         leal    -24(%ebp), %edx
352         movl    %edx, -12(%ebp) /* resp */
353         leal    8(%ebp), %edx
354         movl    %edx, 4(%esp)   /* args = __builtin_dwarf_cfa () */
355         leal    -12(%ebp), %edx
356         movl    %edx, (%esp)    /* &resp */
357         call    _ffi_closure_SYSV_inner
358         movl    -12(%ebp), %ecx
359
360 0:
361         call    1f
362         # Do not insert anything here between the call and the jump table.
363 .Lcls_store_table:
364         .long   .Lcls_noretval          /* FFI_TYPE_VOID */
365         .long   .Lcls_retint            /* FFI_TYPE_INT */
366         .long   .Lcls_retfloat          /* FFI_TYPE_FLOAT */
367         .long   .Lcls_retdouble         /* FFI_TYPE_DOUBLE */
368         .long   .Lcls_retldouble        /* FFI_TYPE_LONGDOUBLE */
369         .long   .Lcls_retuint8          /* FFI_TYPE_UINT8 */
370         .long   .Lcls_retsint8          /* FFI_TYPE_SINT8 */
371         .long   .Lcls_retuint16         /* FFI_TYPE_UINT16 */
372         .long   .Lcls_retsint16         /* FFI_TYPE_SINT16 */
373         .long   .Lcls_retint            /* FFI_TYPE_UINT32 */
374         .long   .Lcls_retint            /* FFI_TYPE_SINT32 */
375         .long   .Lcls_retllong          /* FFI_TYPE_UINT64 */
376         .long   .Lcls_retllong          /* FFI_TYPE_SINT64 */
377         .long   .Lcls_retstruct         /* FFI_TYPE_STRUCT */
378         .long   .Lcls_retint            /* FFI_TYPE_POINTER */
379         .long   .Lcls_retstruct1        /* FFI_TYPE_SMALL_STRUCT_1B */
380         .long   .Lcls_retstruct2        /* FFI_TYPE_SMALL_STRUCT_2B */
381         .long   .Lcls_retstruct4        /* FFI_TYPE_SMALL_STRUCT_4B */
382
383 1:
384         add     %eax, %eax
385         add     %eax, %eax
386         add     (%esp),%eax
387         add     $4, %esp
388         jmp     *(%eax)
389
390         /* Sign/zero extend as appropriate.  */
391 .Lcls_retsint8:
392         movsbl  (%ecx), %eax
393         jmp     .Lcls_epilogue
394
395 .Lcls_retsint16:
396         movswl  (%ecx), %eax
397         jmp     .Lcls_epilogue
398
399 .Lcls_retuint8:
400         movzbl  (%ecx), %eax
401         jmp     .Lcls_epilogue
402
403 .Lcls_retuint16:
404         movzwl  (%ecx), %eax
405         jmp     .Lcls_epilogue
406
407 .Lcls_retint:
408         movl    (%ecx), %eax
409         jmp     .Lcls_epilogue
410
411 .Lcls_retfloat:
412         flds    (%ecx)
413         jmp     .Lcls_epilogue
414
415 .Lcls_retdouble:
416         fldl    (%ecx)
417         jmp     .Lcls_epilogue
418
419 .Lcls_retldouble:
420         fldt    (%ecx)
421         jmp     .Lcls_epilogue
422
423 .Lcls_retllong:
424         movl    (%ecx), %eax
425         movl    4(%ecx), %edx
426         jmp     .Lcls_epilogue
427
428 .Lcls_retstruct1:
429         movsbl  (%ecx), %eax
430         jmp     .Lcls_epilogue
431
432 .Lcls_retstruct2:
433         movswl  (%ecx), %eax
434         jmp     .Lcls_epilogue
435
436 .Lcls_retstruct4:
437         movl    (%ecx), %eax
438         jmp     .Lcls_epilogue
439
440 .Lcls_retstruct:
441         # Caller expects us to pop struct return value pointer hidden arg.
442         movl    %ebp, %esp
443         popl    %ebp
444         ret     $0x4
445
446 .Lcls_noretval:
447 .Lcls_epilogue:
448         movl    %ebp, %esp
449         popl    %ebp
450         ret
451 .ffi_closure_SYSV_end:
452 .LFE3:
453
454 #if !FFI_NO_RAW_API
455
456 #define RAW_CLOSURE_CIF_OFFSET ((FFI_TRAMPOLINE_SIZE + 3) & ~3)
457 #define RAW_CLOSURE_FUN_OFFSET (RAW_CLOSURE_CIF_OFFSET + 4)
458 #define RAW_CLOSURE_USER_DATA_OFFSET (RAW_CLOSURE_FUN_OFFSET + 4)
459 #define CIF_FLAGS_OFFSET 20
460
461         # This assumes we are using gas.
462         .balign 16
463         .globl  _ffi_closure_raw_SYSV
464         .def    _ffi_closure_raw_SYSV;  .scl    2;      .type   32;     .endef
465 _ffi_closure_raw_SYSV:
466 .LFB4:
467         pushl   %ebp
468 .LCFI6:
469         movl    %esp, %ebp
470 .LCFI7:
471         pushl   %esi
472 .LCFI8:
473         subl    $36, %esp
474         movl    RAW_CLOSURE_CIF_OFFSET(%eax), %esi       /* closure->cif */
475         movl    RAW_CLOSURE_USER_DATA_OFFSET(%eax), %edx /* closure->user_data */
476         movl    %edx, 12(%esp)  /* user_data */
477         leal    8(%ebp), %edx   /* __builtin_dwarf_cfa () */
478         movl    %edx, 8(%esp)   /* raw_args */
479         leal    -24(%ebp), %edx
480         movl    %edx, 4(%esp)   /* &res */
481         movl    %esi, (%esp)    /* cif */
482         call    *RAW_CLOSURE_FUN_OFFSET(%eax)            /* closure->fun */
483         movl    CIF_FLAGS_OFFSET(%esi), %eax             /* rtype */
484 0:
485         call    1f
486         # Do not insert anything here between the call and the jump table.
487 .Lrcls_store_table:
488         .long   .Lrcls_noretval         /* FFI_TYPE_VOID */
489         .long   .Lrcls_retint           /* FFI_TYPE_INT */
490         .long   .Lrcls_retfloat         /* FFI_TYPE_FLOAT */
491         .long   .Lrcls_retdouble        /* FFI_TYPE_DOUBLE */
492         .long   .Lrcls_retldouble       /* FFI_TYPE_LONGDOUBLE */
493         .long   .Lrcls_retuint8         /* FFI_TYPE_UINT8 */
494         .long   .Lrcls_retsint8         /* FFI_TYPE_SINT8 */
495         .long   .Lrcls_retuint16        /* FFI_TYPE_UINT16 */
496         .long   .Lrcls_retsint16        /* FFI_TYPE_SINT16 */
497         .long   .Lrcls_retint           /* FFI_TYPE_UINT32 */
498         .long   .Lrcls_retint           /* FFI_TYPE_SINT32 */
499         .long   .Lrcls_retllong         /* FFI_TYPE_UINT64 */
500         .long   .Lrcls_retllong         /* FFI_TYPE_SINT64 */
501         .long   .Lrcls_retstruct        /* FFI_TYPE_STRUCT */
502         .long   .Lrcls_retint           /* FFI_TYPE_POINTER */
503         .long   .Lrcls_retstruct1       /* FFI_TYPE_SMALL_STRUCT_1B */
504         .long   .Lrcls_retstruct2       /* FFI_TYPE_SMALL_STRUCT_2B */
505         .long   .Lrcls_retstruct4       /* FFI_TYPE_SMALL_STRUCT_4B */
506 1:
507         add     %eax, %eax
508         add     %eax, %eax
509         add     (%esp),%eax
510         add     $4, %esp
511         jmp     *(%eax)
512
513         /* Sign/zero extend as appropriate.  */
514 .Lrcls_retsint8:
515         movsbl  -24(%ebp), %eax
516         jmp     .Lrcls_epilogue
517
518 .Lrcls_retsint16:
519         movswl  -24(%ebp), %eax
520         jmp     .Lrcls_epilogue
521
522 .Lrcls_retuint8:
523         movzbl  -24(%ebp), %eax
524         jmp     .Lrcls_epilogue
525
526 .Lrcls_retuint16:
527         movzwl  -24(%ebp), %eax
528         jmp     .Lrcls_epilogue
529
530 .Lrcls_retint:
531         movl    -24(%ebp), %eax
532         jmp     .Lrcls_epilogue
533
534 .Lrcls_retfloat:
535         flds    -24(%ebp)
536         jmp     .Lrcls_epilogue
537
538 .Lrcls_retdouble:
539         fldl    -24(%ebp)
540         jmp     .Lrcls_epilogue
541
542 .Lrcls_retldouble:
543         fldt    -24(%ebp)
544         jmp     .Lrcls_epilogue
545
546 .Lrcls_retllong:
547         movl    -24(%ebp), %eax
548         movl    -20(%ebp), %edx
549         jmp     .Lrcls_epilogue
550
551 .Lrcls_retstruct1:
552         movsbl  -24(%ebp), %eax
553         jmp     .Lrcls_epilogue
554
555 .Lrcls_retstruct2:
556         movswl  -24(%ebp), %eax
557         jmp     .Lrcls_epilogue
558
559 .Lrcls_retstruct4:
560         movl    -24(%ebp), %eax
561         jmp     .Lrcls_epilogue
562
563 .Lrcls_retstruct:
564         # Nothing to do!
565
566 .Lrcls_noretval:
567 .Lrcls_epilogue:
568         addl    $36, %esp
569         popl    %esi
570         popl    %ebp
571         ret
572 .ffi_closure_raw_SYSV_end:
573 .LFE4:
574
575 #endif /* !FFI_NO_RAW_API */
576
577         # This assumes we are using gas.
578         .balign 16
579         .globl  _ffi_closure_STDCALL
580         .def    _ffi_closure_STDCALL;   .scl    2;      .type   32;     .endef
581 _ffi_closure_STDCALL:
582 .LFB5:
583         pushl   %ebp
584 .LCFI9:
585         movl    %esp, %ebp
586 .LCFI10:
587         subl    $40, %esp
588         leal    -24(%ebp), %edx
589         movl    %edx, -12(%ebp) /* resp */
590         leal    12(%ebp), %edx  /* account for stub return address on stack */
591         movl    %edx, 4(%esp)   /* args */
592         leal    -12(%ebp), %edx
593         movl    %edx, (%esp)    /* &resp */
594         call    _ffi_closure_SYSV_inner
595         movl    -12(%ebp), %ecx
596 0:
597         call    1f
598         # Do not insert anything here between the call and the jump table.
599 .Lscls_store_table:
600         .long   .Lscls_noretval         /* FFI_TYPE_VOID */
601         .long   .Lscls_retint           /* FFI_TYPE_INT */
602         .long   .Lscls_retfloat         /* FFI_TYPE_FLOAT */
603         .long   .Lscls_retdouble        /* FFI_TYPE_DOUBLE */
604         .long   .Lscls_retldouble       /* FFI_TYPE_LONGDOUBLE */
605         .long   .Lscls_retuint8         /* FFI_TYPE_UINT8 */
606         .long   .Lscls_retsint8         /* FFI_TYPE_SINT8 */
607         .long   .Lscls_retuint16        /* FFI_TYPE_UINT16 */
608         .long   .Lscls_retsint16        /* FFI_TYPE_SINT16 */
609         .long   .Lscls_retint           /* FFI_TYPE_UINT32 */
610         .long   .Lscls_retint           /* FFI_TYPE_SINT32 */
611         .long   .Lscls_retllong         /* FFI_TYPE_UINT64 */
612         .long   .Lscls_retllong         /* FFI_TYPE_SINT64 */
613         .long   .Lscls_retstruct        /* FFI_TYPE_STRUCT */
614         .long   .Lscls_retint           /* FFI_TYPE_POINTER */
615         .long   .Lscls_retstruct1       /* FFI_TYPE_SMALL_STRUCT_1B */
616         .long   .Lscls_retstruct2       /* FFI_TYPE_SMALL_STRUCT_2B */
617         .long   .Lscls_retstruct4       /* FFI_TYPE_SMALL_STRUCT_4B */
618 1:
619         add     %eax, %eax
620         add     %eax, %eax
621         add     (%esp),%eax
622         add     $4, %esp
623         jmp     *(%eax)
624
625         /* Sign/zero extend as appropriate.  */
626 .Lscls_retsint8:
627         movsbl  (%ecx), %eax
628         jmp     .Lscls_epilogue
629
630 .Lscls_retsint16:
631         movswl  (%ecx), %eax
632         jmp     .Lscls_epilogue
633
634 .Lscls_retuint8:
635         movzbl  (%ecx), %eax
636         jmp     .Lscls_epilogue
637
638 .Lscls_retuint16:
639         movzwl  (%ecx), %eax
640         jmp     .Lscls_epilogue
641
642 .Lscls_retint:
643         movl    (%ecx), %eax
644         jmp     .Lscls_epilogue
645
646 .Lscls_retfloat:
647         flds    (%ecx)
648         jmp     .Lscls_epilogue
649
650 .Lscls_retdouble:
651         fldl    (%ecx)
652         jmp     .Lscls_epilogue
653
654 .Lscls_retldouble:
655         fldt    (%ecx)
656         jmp     .Lscls_epilogue
657
658 .Lscls_retllong:
659         movl    (%ecx), %eax
660         movl    4(%ecx), %edx
661         jmp     .Lscls_epilogue
662
663 .Lscls_retstruct1:
664         movsbl  (%ecx), %eax
665         jmp     .Lscls_epilogue
666
667 .Lscls_retstruct2:
668         movswl  (%ecx), %eax
669         jmp     .Lscls_epilogue
670
671 .Lscls_retstruct4:
672         movl    (%ecx), %eax
673         jmp     .Lscls_epilogue
674
675 .Lscls_retstruct:
676         # Nothing to do!
677
678 .Lscls_noretval:
679 .Lscls_epilogue:
680         movl    %ebp, %esp
681         popl    %ebp
682         ret
683 .ffi_closure_STDCALL_end:
684 .LFE5:
685
686         .section        .eh_frame,"w"
687 .Lframe1:
688 .LSCIE1:
689         .long   .LECIE1-.LASCIE1  /* Length of Common Information Entry */
690 .LASCIE1:
691         .long   0x0     /* CIE Identifier Tag */
692         .byte   0x1     /* CIE Version */
693 #ifdef __PIC__
694         .ascii "zR\0"   /* CIE Augmentation */
695 #else
696         .ascii "\0"     /* CIE Augmentation */
697 #endif
698         .byte   0x1     /* .uleb128 0x1; CIE Code Alignment Factor */
699         .byte   0x7c    /* .sleb128 -4; CIE Data Alignment Factor */
700         .byte   0x8     /* CIE RA Column */
701 #ifdef __PIC__
702         .byte   0x1     /* .uleb128 0x1; Augmentation size */
703         .byte   0x1b    /* FDE Encoding (pcrel sdata4) */
704 #endif
705         .byte   0xc     /* DW_CFA_def_cfa CFA = r4 + 4 = 4(%esp) */
706         .byte   0x4     /* .uleb128 0x4 */
707         .byte   0x4     /* .uleb128 0x4 */
708         .byte   0x88    /* DW_CFA_offset, column 0x8 %eip at CFA + 1 * -4 */
709         .byte   0x1     /* .uleb128 0x1 */
710         .align 4
711 .LECIE1:
712
713 .LSFDE1:
714         .long   .LEFDE1-.LASFDE1        /* FDE Length */
715 .LASFDE1:
716         .long   .LASFDE1-.Lframe1       /* FDE CIE offset */
717 #if defined __PIC__ && defined HAVE_AS_X86_PCREL
718         .long   .LFB1-. /* FDE initial location */
719 #else
720         .long   .LFB1
721 #endif
722         .long   .LFE1-.LFB1     /* FDE address range */
723 #ifdef __PIC__
724         .byte   0x0     /* .uleb128 0x0; Augmentation size */
725 #endif
726         /* DW_CFA_xxx CFI instructions go here.  */
727
728         .byte   0x4     /* DW_CFA_advance_loc4 */
729         .long   .LCFI0-.LFB1
730         .byte   0xe     /* DW_CFA_def_cfa_offset CFA = r4 + 8 = 8(%esp) */
731         .byte   0x8     /* .uleb128 0x8 */
732         .byte   0x85    /* DW_CFA_offset, column 0x5 %ebp at CFA + 2 * -4 */
733         .byte   0x2     /* .uleb128 0x2 */
734
735         .byte   0x4     /* DW_CFA_advance_loc4 */
736         .long   .LCFI1-.LCFI0
737         .byte   0xd     /* DW_CFA_def_cfa_register CFA = r5 = %ebp */
738         .byte   0x5     /* .uleb128 0x5 */
739
740         /* End of DW_CFA_xxx CFI instructions.  */
741         .align 4
742 .LEFDE1:
743
744
745 .LSFDE2:
746         .long   .LEFDE2-.LASFDE2        /* FDE Length */
747 .LASFDE2:
748         .long   .LASFDE2-.Lframe1       /* FDE CIE offset */
749 #if defined __PIC__ && defined HAVE_AS_X86_PCREL
750         .long   .LFB2-. /* FDE initial location */
751 #else
752         .long   .LFB2
753 #endif
754         .long   .LFE2-.LFB2     /* FDE address range */
755 #ifdef __PIC__
756         .byte   0x0     /* .uleb128 0x0; Augmentation size */
757 #endif
758         /* DW_CFA_xxx CFI instructions go here.  */
759
760         .byte   0x4     /* DW_CFA_advance_loc4 */
761         .long   .LCFI2-.LFB2
762         .byte   0xe     /* DW_CFA_def_cfa_offset CFA = r4 + 8 = 8(%esp) */
763         .byte   0x8     /* .uleb128 0x8 */
764         .byte   0x85    /* DW_CFA_offset, column 0x5 %ebp at CFA + 2 * -4 */
765         .byte   0x2     /* .uleb128 0x2 */
766
767         .byte   0x4     /* DW_CFA_advance_loc4 */
768         .long   .LCFI3-.LCFI2
769         .byte   0xd     /* DW_CFA_def_cfa_register CFA = r5 = %ebp */
770         .byte   0x5     /* .uleb128 0x5 */
771
772         /* End of DW_CFA_xxx CFI instructions.  */
773         .align 4
774 .LEFDE2:
775
776
777 .LSFDE3:
778         .long   .LEFDE3-.LASFDE3        /* FDE Length */
779 .LASFDE3:
780         .long   .LASFDE3-.Lframe1       /* FDE CIE offset */
781 #if defined __PIC__ && defined HAVE_AS_X86_PCREL
782         .long   .LFB3-. /* FDE initial location */
783 #else
784         .long   .LFB3
785 #endif
786         .long   .LFE3-.LFB3     /* FDE address range */
787 #ifdef __PIC__
788         .byte   0x0     /* .uleb128 0x0; Augmentation size */
789 #endif
790         /* DW_CFA_xxx CFI instructions go here.  */
791
792         .byte   0x4     /* DW_CFA_advance_loc4 */
793         .long   .LCFI4-.LFB3
794         .byte   0xe     /* DW_CFA_def_cfa_offset CFA = r4 + 8 = 8(%esp) */
795         .byte   0x8     /* .uleb128 0x8 */
796         .byte   0x85    /* DW_CFA_offset, column 0x5 %ebp at CFA + 2 * -4 */
797         .byte   0x2     /* .uleb128 0x2 */
798
799         .byte   0x4     /* DW_CFA_advance_loc4 */
800         .long   .LCFI5-.LCFI4
801         .byte   0xd     /* DW_CFA_def_cfa_register CFA = r5 = %ebp */
802         .byte   0x5     /* .uleb128 0x5 */
803
804         /* End of DW_CFA_xxx CFI instructions.  */
805         .align 4
806 .LEFDE3:
807
808 #if !FFI_NO_RAW_API
809
810 .LSFDE4:
811         .long   .LEFDE4-.LASFDE4        /* FDE Length */
812 .LASFDE4:
813         .long   .LASFDE4-.Lframe1       /* FDE CIE offset */
814 #if defined __PIC__ && defined HAVE_AS_X86_PCREL
815         .long   .LFB4-. /* FDE initial location */
816 #else
817         .long   .LFB4
818 #endif
819         .long   .LFE4-.LFB4     /* FDE address range */
820 #ifdef __PIC__
821         .byte   0x0     /* .uleb128 0x0; Augmentation size */
822 #endif
823         /* DW_CFA_xxx CFI instructions go here.  */
824
825         .byte   0x4     /* DW_CFA_advance_loc4 */
826         .long   .LCFI6-.LFB4
827         .byte   0xe     /* DW_CFA_def_cfa_offset CFA = r4 + 8 = 8(%esp) */
828         .byte   0x8     /* .uleb128 0x8 */
829         .byte   0x85    /* DW_CFA_offset, column 0x5 %ebp at CFA + 2 * -4 */
830         .byte   0x2     /* .uleb128 0x2 */
831
832         .byte   0x4     /* DW_CFA_advance_loc4 */
833         .long   .LCFI7-.LCFI6
834         .byte   0xd     /* DW_CFA_def_cfa_register CFA = r5 = %ebp */
835         .byte   0x5     /* .uleb128 0x5 */
836
837         .byte   0x4     /* DW_CFA_advance_loc4 */
838         .long   .LCFI8-.LCFI7
839         .byte   0x86    /* DW_CFA_offset, column 0x6 %esi at CFA + 3 * -4 */
840         .byte   0x3     /* .uleb128 0x3 */
841
842         /* End of DW_CFA_xxx CFI instructions.  */
843         .align 4
844 .LEFDE4:
845
846 #endif /* !FFI_NO_RAW_API */
847
848 .LSFDE5:
849         .long   .LEFDE5-.LASFDE5        /* FDE Length */
850 .LASFDE5:
851         .long   .LASFDE5-.Lframe1       /* FDE CIE offset */
852 #if defined __PIC__ && defined HAVE_AS_X86_PCREL
853         .long   .LFB5-. /* FDE initial location */
854 #else
855         .long   .LFB5
856 #endif
857         .long   .LFE5-.LFB5     /* FDE address range */
858 #ifdef __PIC__
859         .byte   0x0     /* .uleb128 0x0; Augmentation size */
860 #endif
861         /* DW_CFA_xxx CFI instructions go here.  */
862
863         .byte   0x4     /* DW_CFA_advance_loc4 */
864         .long   .LCFI9-.LFB5
865         .byte   0xe     /* DW_CFA_def_cfa_offset CFA = r4 + 8 = 8(%esp) */
866         .byte   0x8     /* .uleb128 0x8 */
867         .byte   0x85    /* DW_CFA_offset, column 0x5 %ebp at CFA + 2 * -4 */
868         .byte   0x2     /* .uleb128 0x2 */
869
870         .byte   0x4     /* DW_CFA_advance_loc4 */
871         .long   .LCFI10-.LCFI9
872         .byte   0xd     /* DW_CFA_def_cfa_register CFA = r5 = %ebp */
873         .byte   0x5     /* .uleb128 0x5 */
874
875         /* End of DW_CFA_xxx CFI instructions.  */
876         .align 4
877 .LEFDE5: