Imported Upstream version 1.0.0
[platform/upstream/js.git] / js / src / ctypes / 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              Copyright (c) 2009  Daniel Witte
6                         
7  
8    X86 Foreign Function Interface
9  
10    Permission is hereby granted, free of charge, to any person obtaining
11    a copy of this software and associated documentation files (the
12    ``Software''), to deal in the Software without restriction, including
13    without limitation the rights to use, copy, modify, merge, publish,
14    distribute, sublicense, and/or sell copies of the Software, and to
15    permit persons to whom the Software is furnished to do so, subject to
16    the following conditions:
17  
18    The above copyright notice and this permission notice shall be included
19    in all copies or substantial portions of the Software.
20  
21    THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
22    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24    NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
25    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
26    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
28    DEALINGS IN THE SOFTWARE.
29    -----------------------------------------------------------------------
30    */
31  
32 #define LIBFFI_ASM
33 #include <fficonfig.h>
34 #include <ffi.h>
35
36 #ifdef _MSC_VER
37
38 .386
39 .MODEL FLAT, C
40
41 EXTRN ffi_closure_SYSV_inner:NEAR
42
43 _TEXT SEGMENT
44
45 ffi_call_win32 PROC NEAR,
46     ffi_prep_args : NEAR PTR DWORD,
47     ecif          : NEAR PTR DWORD,
48     cif_bytes     : DWORD,
49     cif_flags     : DWORD,
50     rvalue        : NEAR PTR DWORD,
51     fn            : NEAR PTR DWORD
52
53         ;; Make room for all of the new args.
54         mov  ecx, cif_bytes
55         sub  esp, ecx
56
57         mov  eax, esp
58
59         ;; Place all of the ffi_prep_args in position
60         push ecif
61         push eax
62         call ffi_prep_args
63
64         ;; Return stack to previous state and call the function
65         add  esp, 8
66
67         call fn
68
69         ;; cdecl:   we restore esp in the epilogue, so there's no need to
70         ;;          remove the space we pushed for the args.
71         ;; stdcall: the callee has already cleaned the stack.
72
73         ;; Load ecx with the return type code
74         mov  ecx, cif_flags
75
76         ;; If the return value pointer is NULL, assume no return value.
77         cmp  rvalue, 0
78         jne  ca_jumptable
79
80         ;; Even if there is no space for the return value, we are
81         ;; obliged to handle floating-point values.
82         cmp  ecx, FFI_TYPE_FLOAT
83         jne  ca_epilogue
84         fstp st(0)
85
86         jmp  ca_epilogue
87
88 ca_jumptable:
89         jmp  [ca_jumpdata + 4 * ecx]
90 ca_jumpdata:
91         ;; Do not insert anything here between label and jump table.
92         dd offset ca_epilogue       ;; FFI_TYPE_VOID
93         dd offset ca_retint         ;; FFI_TYPE_INT
94         dd offset ca_retfloat       ;; FFI_TYPE_FLOAT
95         dd offset ca_retdouble      ;; FFI_TYPE_DOUBLE
96         dd offset ca_retlongdouble  ;; FFI_TYPE_LONGDOUBLE
97         dd offset ca_retint8        ;; FFI_TYPE_UINT8
98         dd offset ca_retint8        ;; FFI_TYPE_SINT8
99         dd offset ca_retint16       ;; FFI_TYPE_UINT16
100         dd offset ca_retint16       ;; FFI_TYPE_SINT16
101         dd offset ca_retint         ;; FFI_TYPE_UINT32
102         dd offset ca_retint         ;; FFI_TYPE_SINT32
103         dd offset ca_retint64       ;; FFI_TYPE_UINT64
104         dd offset ca_retint64       ;; FFI_TYPE_SINT64
105         dd offset ca_epilogue       ;; FFI_TYPE_STRUCT
106         dd offset ca_retint         ;; FFI_TYPE_POINTER
107         dd offset ca_retint8        ;; FFI_TYPE_SMALL_STRUCT_1B
108         dd offset ca_retint16       ;; FFI_TYPE_SMALL_STRUCT_2B
109         dd offset ca_retint         ;; FFI_TYPE_SMALL_STRUCT_4B
110
111 ca_retint8:
112         ;; Load %ecx with the pointer to storage for the return value
113         mov   ecx, rvalue
114         mov   [ecx + 0], al
115         jmp   ca_epilogue
116
117 ca_retint16:
118         ;; Load %ecx with the pointer to storage for the return value
119         mov   ecx, rvalue
120         mov   [ecx + 0], ax
121         jmp   ca_epilogue
122
123 ca_retint:
124         ;; Load %ecx with the pointer to storage for the return value
125         mov   ecx, rvalue
126         mov   [ecx + 0], eax
127         jmp   ca_epilogue
128
129 ca_retint64:
130         ;; Load %ecx with the pointer to storage for the return value
131         mov   ecx, rvalue
132         mov   [ecx + 0], eax
133         mov   [ecx + 4], edx
134         jmp   ca_epilogue
135
136 ca_retfloat:
137         ;; Load %ecx with the pointer to storage for the return value
138         mov   ecx, rvalue
139         fstp  DWORD PTR [ecx]
140         jmp   ca_epilogue
141
142 ca_retdouble:
143         ;; Load %ecx with the pointer to storage for the return value
144         mov   ecx, rvalue
145         fstp  QWORD PTR [ecx]
146         jmp   ca_epilogue
147
148 ca_retlongdouble:
149         ;; Load %ecx with the pointer to storage for the return value
150         mov   ecx, rvalue
151         fstp  TBYTE PTR [ecx]
152         jmp   ca_epilogue
153
154 ca_epilogue:
155         ;; Epilogue code is autogenerated.
156         ret
157 ffi_call_win32 ENDP
158
159 ffi_closure_SYSV PROC NEAR FORCEFRAME
160     ;; the ffi_closure ctx is passed in eax by the trampoline.
161
162         sub  esp, 40
163         lea  edx, [ebp - 24]
164         mov  [ebp - 12], edx         ;; resp
165         lea  edx, [ebp + 8]
166         mov  [esp + 8], edx          ;; args
167         lea  edx, [ebp - 12]
168         mov  [esp + 4], edx          ;; &resp
169         mov  [esp], eax              ;; closure
170         call ffi_closure_SYSV_inner
171         mov  ecx, [ebp - 12]
172
173 cs_jumptable:
174         jmp  [cs_jumpdata + 4 * eax]
175 cs_jumpdata:
176         ;; Do not insert anything here between the label and jump table.
177         dd offset cs_epilogue       ;; FFI_TYPE_VOID
178         dd offset cs_retint         ;; FFI_TYPE_INT
179         dd offset cs_retfloat       ;; FFI_TYPE_FLOAT
180         dd offset cs_retdouble      ;; FFI_TYPE_DOUBLE
181         dd offset cs_retlongdouble  ;; FFI_TYPE_LONGDOUBLE
182         dd offset cs_retint8        ;; FFI_TYPE_UINT8
183         dd offset cs_retint8        ;; FFI_TYPE_SINT8
184         dd offset cs_retint16       ;; FFI_TYPE_UINT16
185         dd offset cs_retint16       ;; FFI_TYPE_SINT16
186         dd offset cs_retint         ;; FFI_TYPE_UINT32
187         dd offset cs_retint         ;; FFI_TYPE_SINT32
188         dd offset cs_retint64       ;; FFI_TYPE_UINT64
189         dd offset cs_retint64       ;; FFI_TYPE_SINT64
190         dd offset cs_retstruct      ;; FFI_TYPE_STRUCT
191         dd offset cs_retint         ;; FFI_TYPE_POINTER
192         dd offset cs_retint8        ;; FFI_TYPE_SMALL_STRUCT_1B
193         dd offset cs_retint16       ;; FFI_TYPE_SMALL_STRUCT_2B
194         dd offset cs_retint         ;; FFI_TYPE_SMALL_STRUCT_4B
195
196 cs_retint8:
197         mov   al, [ecx]
198         jmp   cs_epilogue
199
200 cs_retint16:
201         mov   ax, [ecx]
202         jmp   cs_epilogue
203
204 cs_retint:
205         mov   eax, [ecx]
206         jmp   cs_epilogue
207
208 cs_retint64:
209         mov   eax, [ecx + 0]
210         mov   edx, [ecx + 4]
211         jmp   cs_epilogue
212
213 cs_retfloat:
214         fld   DWORD PTR [ecx]
215         jmp   cs_epilogue
216
217 cs_retdouble:
218         fld   QWORD PTR [ecx]
219         jmp   cs_epilogue
220
221 cs_retlongdouble:
222         fld   TBYTE PTR [ecx]
223         jmp   cs_epilogue
224
225 cs_retstruct:
226         ;; Caller expects us to pop struct return value pointer hidden arg.
227         ;; Epilogue code is autogenerated.
228         ret     4
229
230 cs_epilogue:
231         ;; Epilogue code is autogenerated.
232         ret
233 ffi_closure_SYSV ENDP
234
235 #if !FFI_NO_RAW_API
236
237 #define RAW_CLOSURE_CIF_OFFSET ((FFI_TRAMPOLINE_SIZE + 3) AND NOT 3)
238 #define RAW_CLOSURE_FUN_OFFSET (RAW_CLOSURE_CIF_OFFSET + 4)
239 #define RAW_CLOSURE_USER_DATA_OFFSET (RAW_CLOSURE_FUN_OFFSET + 4)
240 #define CIF_FLAGS_OFFSET 20
241
242 ffi_closure_raw_SYSV PROC NEAR USES esi
243     ;; the ffi_closure ctx is passed in eax by the trampoline.
244
245         sub  esp, 40
246         mov  esi, [eax + RAW_CLOSURE_CIF_OFFSET]        ;; closure->cif
247         mov  edx, [eax + RAW_CLOSURE_USER_DATA_OFFSET]  ;; closure->user_data
248         mov  [esp + 12], edx                            ;; user_data
249         lea  edx, [ebp + 8]
250         mov  [esp + 8], edx                             ;; raw_args
251         lea  edx, [ebp - 24]
252         mov  [esp + 4], edx                             ;; &res
253         mov  [esp], esi                                 ;; cif
254         call DWORD PTR [eax + RAW_CLOSURE_FUN_OFFSET]   ;; closure->fun
255         mov  eax, [esi + CIF_FLAGS_OFFSET]              ;; cif->flags
256         lea  ecx, [ebp - 24]
257
258 cr_jumptable:
259         jmp  [cr_jumpdata + 4 * eax]
260 cr_jumpdata:
261         ;; Do not insert anything here between the label and jump table.
262         dd offset cr_epilogue       ;; FFI_TYPE_VOID
263         dd offset cr_retint         ;; FFI_TYPE_INT
264         dd offset cr_retfloat       ;; FFI_TYPE_FLOAT
265         dd offset cr_retdouble      ;; FFI_TYPE_DOUBLE
266         dd offset cr_retlongdouble  ;; FFI_TYPE_LONGDOUBLE
267         dd offset cr_retint8        ;; FFI_TYPE_UINT8
268         dd offset cr_retint8        ;; FFI_TYPE_SINT8
269         dd offset cr_retint16       ;; FFI_TYPE_UINT16
270         dd offset cr_retint16       ;; FFI_TYPE_SINT16
271         dd offset cr_retint         ;; FFI_TYPE_UINT32
272         dd offset cr_retint         ;; FFI_TYPE_SINT32
273         dd offset cr_retint64       ;; FFI_TYPE_UINT64
274         dd offset cr_retint64       ;; FFI_TYPE_SINT64
275         dd offset cr_epilogue       ;; FFI_TYPE_STRUCT
276         dd offset cr_retint         ;; FFI_TYPE_POINTER
277         dd offset cr_retint8        ;; FFI_TYPE_SMALL_STRUCT_1B
278         dd offset cr_retint16       ;; FFI_TYPE_SMALL_STRUCT_2B
279         dd offset cr_retint         ;; FFI_TYPE_SMALL_STRUCT_4B
280
281 cr_retint8:
282         mov   al, [ecx]
283         jmp   cr_epilogue
284
285 cr_retint16:
286         mov   ax, [ecx]
287         jmp   cr_epilogue
288
289 cr_retint:
290         mov   eax, [ecx]
291         jmp   cr_epilogue
292
293 cr_retint64:
294         mov   eax, [ecx + 0]
295         mov   edx, [ecx + 4]
296         jmp   cr_epilogue
297
298 cr_retfloat:
299         fld   DWORD PTR [ecx]
300         jmp   cr_epilogue
301
302 cr_retdouble:
303         fld   QWORD PTR [ecx]
304         jmp   cr_epilogue
305
306 cr_retlongdouble:
307         fld   TBYTE PTR [ecx]
308         jmp   cr_epilogue
309
310 cr_epilogue:
311         ;; Epilogue code is autogenerated.
312         ret
313 ffi_closure_raw_SYSV ENDP
314
315 #endif /* !FFI_NO_RAW_API */
316
317 ffi_closure_STDCALL PROC NEAR FORCEFRAME
318     ;; the ffi_closure ctx is passed in eax by the trampoline.
319
320         sub  esp, 40
321         lea  edx, [ebp - 24]
322         mov  [ebp - 12], edx         ;; resp
323         lea  edx, [ebp + 12]         ;; account for stub return address on stack
324         mov  [esp + 8], edx          ;; args
325         lea  edx, [ebp - 12]
326         mov  [esp + 4], edx          ;; &resp
327         mov  [esp], eax              ;; closure
328         call ffi_closure_SYSV_inner
329         mov  ecx, [ebp - 12]
330
331 cd_jumptable:
332         jmp  [cd_jumpdata + 4 * eax]
333 cd_jumpdata:
334         ;; Do not insert anything here between the label and jump table.
335         dd offset cd_epilogue       ;; FFI_TYPE_VOID
336         dd offset cd_retint         ;; FFI_TYPE_INT
337         dd offset cd_retfloat       ;; FFI_TYPE_FLOAT
338         dd offset cd_retdouble      ;; FFI_TYPE_DOUBLE
339         dd offset cd_retlongdouble  ;; FFI_TYPE_LONGDOUBLE
340         dd offset cd_retint8        ;; FFI_TYPE_UINT8
341         dd offset cd_retint8        ;; FFI_TYPE_SINT8
342         dd offset cd_retint16       ;; FFI_TYPE_UINT16
343         dd offset cd_retint16       ;; FFI_TYPE_SINT16
344         dd offset cd_retint         ;; FFI_TYPE_UINT32
345         dd offset cd_retint         ;; FFI_TYPE_SINT32
346         dd offset cd_retint64       ;; FFI_TYPE_UINT64
347         dd offset cd_retint64       ;; FFI_TYPE_SINT64
348         dd offset cd_epilogue       ;; FFI_TYPE_STRUCT
349         dd offset cd_retint         ;; FFI_TYPE_POINTER
350         dd offset cd_retint8        ;; FFI_TYPE_SMALL_STRUCT_1B
351         dd offset cd_retint16       ;; FFI_TYPE_SMALL_STRUCT_2B
352         dd offset cd_retint         ;; FFI_TYPE_SMALL_STRUCT_4B
353
354 cd_retint8:
355         mov   al, [ecx]
356         jmp   cd_epilogue
357
358 cd_retint16:
359         mov   ax, [ecx]
360         jmp   cd_epilogue
361
362 cd_retint:
363         mov   eax, [ecx]
364         jmp   cd_epilogue
365
366 cd_retint64:
367         mov   eax, [ecx + 0]
368         mov   edx, [ecx + 4]
369         jmp   cd_epilogue
370
371 cd_retfloat:
372         fld   DWORD PTR [ecx]
373         jmp   cd_epilogue
374
375 cd_retdouble:
376         fld   QWORD PTR [ecx]
377         jmp   cd_epilogue
378
379 cd_retlongdouble:
380         fld   TBYTE PTR [ecx]
381         jmp   cd_epilogue
382
383 cd_epilogue:
384         ;; Epilogue code is autogenerated.
385         ret
386 ffi_closure_STDCALL ENDP
387
388 _TEXT ENDS
389 END
390
391 #else
392
393         .text
394  
395         # This assumes we are using gas.
396         .balign 16
397         .globl  _ffi_call_win32
398 #ifndef __OS2__
399         .def    _ffi_call_win32;        .scl    2;      .type   32;     .endef
400 #endif
401 _ffi_call_win32:
402 .LFB1:
403         pushl %ebp
404 .LCFI0:
405         movl  %esp,%ebp
406 .LCFI1:
407         # Make room for all of the new args.
408         movl  16(%ebp),%ecx                                                     
409         subl  %ecx,%esp
410  
411         movl  %esp,%eax
412  
413         # Place all of the ffi_prep_args in position
414         pushl 12(%ebp)
415         pushl %eax
416         call  *8(%ebp)
417  
418         # Return stack to previous state and call the function
419         addl  $8,%esp
420  
421         # FIXME: Align the stack to a 128-bit boundary to avoid
422         # potential performance hits.
423
424         call  *28(%ebp)
425  
426         # stdcall functions pop arguments off the stack themselves
427
428         # Load %ecx with the return type code
429         movl  20(%ebp),%ecx
430  
431         # If the return value pointer is NULL, assume no return value.
432         cmpl  $0,24(%ebp)
433         jne   0f
434  
435         # Even if there is no space for the return value, we are
436         # obliged to handle floating-point values.
437         cmpl  $FFI_TYPE_FLOAT,%ecx
438         jne   .Lnoretval
439         fstp  %st(0)
440  
441         jmp   .Lepilogue
442
443 0:
444         call    1f
445         # Do not insert anything here between the call and the jump table.
446 .Lstore_table:
447         .long   .Lnoretval              /* FFI_TYPE_VOID */
448         .long   .Lretint                /* FFI_TYPE_INT */
449         .long   .Lretfloat              /* FFI_TYPE_FLOAT */
450         .long   .Lretdouble             /* FFI_TYPE_DOUBLE */
451         .long   .Lretlongdouble         /* FFI_TYPE_LONGDOUBLE */
452         .long   .Lretuint8              /* FFI_TYPE_UINT8 */
453         .long   .Lretsint8              /* FFI_TYPE_SINT8 */
454         .long   .Lretuint16             /* FFI_TYPE_UINT16 */
455         .long   .Lretsint16             /* FFI_TYPE_SINT16 */
456         .long   .Lretint                /* FFI_TYPE_UINT32 */
457         .long   .Lretint                /* FFI_TYPE_SINT32 */
458         .long   .Lretint64              /* FFI_TYPE_UINT64 */
459         .long   .Lretint64              /* FFI_TYPE_SINT64 */
460         .long   .Lretstruct             /* FFI_TYPE_STRUCT */
461         .long   .Lretint                /* FFI_TYPE_POINTER */
462         .long   .Lretstruct1b           /* FFI_TYPE_SMALL_STRUCT_1B */
463         .long   .Lretstruct2b           /* FFI_TYPE_SMALL_STRUCT_2B */
464         .long   .Lretstruct4b           /* FFI_TYPE_SMALL_STRUCT_4B */
465 1:
466         add     %ecx, %ecx
467         add     %ecx, %ecx
468         add     (%esp),%ecx
469         add     $4, %esp
470         jmp     *(%ecx)
471
472         /* Sign/zero extend as appropriate.  */
473 .Lretsint8:
474         movsbl  %al, %eax
475         jmp     .Lretint
476
477 .Lretsint16:
478         movswl  %ax, %eax
479         jmp     .Lretint
480
481 .Lretuint8:
482         movzbl  %al, %eax
483         jmp     .Lretint
484
485 .Lretuint16:
486         movzwl  %ax, %eax
487         jmp     .Lretint
488
489 .Lretint:
490         # Load %ecx with the pointer to storage for the return value
491         movl  24(%ebp),%ecx
492         movl  %eax,0(%ecx)
493         jmp   .Lepilogue
494  
495 .Lretfloat:
496          # Load %ecx with the pointer to storage for the return value
497         movl  24(%ebp),%ecx
498         fstps (%ecx)
499         jmp   .Lepilogue
500  
501 .Lretdouble:
502         # Load %ecx with the pointer to storage for the return value
503         movl  24(%ebp),%ecx
504         fstpl (%ecx)
505         jmp   .Lepilogue
506  
507 .Lretlongdouble:
508         # Load %ecx with the pointer to storage for the return value
509         movl  24(%ebp),%ecx
510         fstpt (%ecx)
511         jmp   .Lepilogue
512  
513 .Lretint64:
514         # Load %ecx with the pointer to storage for the return value
515         movl  24(%ebp),%ecx
516         movl  %eax,0(%ecx)
517         movl  %edx,4(%ecx)
518         jmp   .Lepilogue
519
520 .Lretstruct1b:
521         # Load %ecx with the pointer to storage for the return value
522         movl  24(%ebp),%ecx
523         movb  %al,0(%ecx)
524         jmp   .Lepilogue
525  
526 .Lretstruct2b:
527         # Load %ecx with the pointer to storage for the return value
528         movl  24(%ebp),%ecx
529         movw  %ax,0(%ecx)
530         jmp   .Lepilogue
531
532 .Lretstruct4b:
533         # Load %ecx with the pointer to storage for the return value
534         movl  24(%ebp),%ecx
535         movl  %eax,0(%ecx)
536         jmp   .Lepilogue
537
538 .Lretstruct:
539         # Nothing to do!
540  
541 .Lnoretval:
542 .Lepilogue:
543         movl %ebp,%esp
544         popl %ebp
545         ret
546 .ffi_call_win32_end:
547 .LFE1:
548
549         # This assumes we are using gas.
550         .balign 16
551         .globl  _ffi_closure_SYSV
552 #ifndef __OS2__
553         .def    _ffi_closure_SYSV;      .scl    2;      .type   32;     .endef
554 #endif
555 _ffi_closure_SYSV:
556 .LFB3:
557         pushl   %ebp
558 .LCFI4:
559         movl    %esp, %ebp
560 .LCFI5:
561         subl    $40, %esp
562         leal    -24(%ebp), %edx
563         movl    %edx, -12(%ebp) /* resp */
564         leal    8(%ebp), %edx
565         movl    %edx, 4(%esp)   /* args = __builtin_dwarf_cfa () */
566         leal    -12(%ebp), %edx
567         movl    %edx, (%esp)    /* &resp */
568         call    _ffi_closure_SYSV_inner
569         movl    -12(%ebp), %ecx
570
571 0:
572         call    1f
573         # Do not insert anything here between the call and the jump table.
574 .Lcls_store_table:
575         .long   .Lcls_noretval          /* FFI_TYPE_VOID */
576         .long   .Lcls_retint            /* FFI_TYPE_INT */
577         .long   .Lcls_retfloat          /* FFI_TYPE_FLOAT */
578         .long   .Lcls_retdouble         /* FFI_TYPE_DOUBLE */
579         .long   .Lcls_retldouble        /* FFI_TYPE_LONGDOUBLE */
580         .long   .Lcls_retuint8          /* FFI_TYPE_UINT8 */
581         .long   .Lcls_retsint8          /* FFI_TYPE_SINT8 */
582         .long   .Lcls_retuint16         /* FFI_TYPE_UINT16 */
583         .long   .Lcls_retsint16         /* FFI_TYPE_SINT16 */
584         .long   .Lcls_retint            /* FFI_TYPE_UINT32 */
585         .long   .Lcls_retint            /* FFI_TYPE_SINT32 */
586         .long   .Lcls_retllong          /* FFI_TYPE_UINT64 */
587         .long   .Lcls_retllong          /* FFI_TYPE_SINT64 */
588         .long   .Lcls_retstruct         /* FFI_TYPE_STRUCT */
589         .long   .Lcls_retint            /* FFI_TYPE_POINTER */
590         .long   .Lcls_retstruct1        /* FFI_TYPE_SMALL_STRUCT_1B */
591         .long   .Lcls_retstruct2        /* FFI_TYPE_SMALL_STRUCT_2B */
592         .long   .Lcls_retstruct4        /* FFI_TYPE_SMALL_STRUCT_4B */
593
594 1:
595         add     %eax, %eax
596         add     %eax, %eax
597         add     (%esp),%eax
598         add     $4, %esp
599         jmp     *(%eax)
600
601         /* Sign/zero extend as appropriate.  */
602 .Lcls_retsint8:
603         movsbl  (%ecx), %eax
604         jmp     .Lcls_epilogue
605
606 .Lcls_retsint16:
607         movswl  (%ecx), %eax
608         jmp     .Lcls_epilogue
609
610 .Lcls_retuint8:
611         movzbl  (%ecx), %eax
612         jmp     .Lcls_epilogue
613
614 .Lcls_retuint16:
615         movzwl  (%ecx), %eax
616         jmp     .Lcls_epilogue
617
618 .Lcls_retint:
619         movl    (%ecx), %eax
620         jmp     .Lcls_epilogue
621
622 .Lcls_retfloat:
623         flds    (%ecx)
624         jmp     .Lcls_epilogue
625
626 .Lcls_retdouble:
627         fldl    (%ecx)
628         jmp     .Lcls_epilogue
629
630 .Lcls_retldouble:
631         fldt    (%ecx)
632         jmp     .Lcls_epilogue
633
634 .Lcls_retllong:
635         movl    (%ecx), %eax
636         movl    4(%ecx), %edx
637         jmp     .Lcls_epilogue
638
639 .Lcls_retstruct1:
640         movsbl  (%ecx), %eax
641         jmp     .Lcls_epilogue
642
643 .Lcls_retstruct2:
644         movswl  (%ecx), %eax
645         jmp     .Lcls_epilogue
646
647 .Lcls_retstruct4:
648         movl    (%ecx), %eax
649         jmp     .Lcls_epilogue
650
651 .Lcls_retstruct:
652         # Caller expects us to pop struct return value pointer hidden arg.
653         movl    %ebp, %esp
654         popl    %ebp
655         ret     $0x4
656
657 .Lcls_noretval:
658 .Lcls_epilogue:
659         movl    %ebp, %esp
660         popl    %ebp
661         ret
662 .ffi_closure_SYSV_end:
663 .LFE3:
664
665 #if !FFI_NO_RAW_API
666
667 #define RAW_CLOSURE_CIF_OFFSET ((FFI_TRAMPOLINE_SIZE + 3) & ~3)
668 #define RAW_CLOSURE_FUN_OFFSET (RAW_CLOSURE_CIF_OFFSET + 4)
669 #define RAW_CLOSURE_USER_DATA_OFFSET (RAW_CLOSURE_FUN_OFFSET + 4)
670 #define CIF_FLAGS_OFFSET 20
671
672         # This assumes we are using gas.
673         .balign 16
674         .globl  _ffi_closure_raw_SYSV
675 #ifndef __OS2__
676         .def    _ffi_closure_raw_SYSV;  .scl    2;      .type   32;     .endef
677 #endif
678 _ffi_closure_raw_SYSV:
679 .LFB4:
680         pushl   %ebp
681 .LCFI6:
682         movl    %esp, %ebp
683 .LCFI7:
684         pushl   %esi
685 .LCFI8:
686         subl    $36, %esp
687         movl    RAW_CLOSURE_CIF_OFFSET(%eax), %esi       /* closure->cif */
688         movl    RAW_CLOSURE_USER_DATA_OFFSET(%eax), %edx /* closure->user_data */
689         movl    %edx, 12(%esp)  /* user_data */
690         leal    8(%ebp), %edx   /* __builtin_dwarf_cfa () */
691         movl    %edx, 8(%esp)   /* raw_args */
692         leal    -24(%ebp), %edx
693         movl    %edx, 4(%esp)   /* &res */
694         movl    %esi, (%esp)    /* cif */
695         call    *RAW_CLOSURE_FUN_OFFSET(%eax)            /* closure->fun */
696         movl    CIF_FLAGS_OFFSET(%esi), %eax             /* rtype */
697 0:
698         call    1f
699         # Do not insert anything here between the call and the jump table.
700 .Lrcls_store_table:
701         .long   .Lrcls_noretval         /* FFI_TYPE_VOID */
702         .long   .Lrcls_retint           /* FFI_TYPE_INT */
703         .long   .Lrcls_retfloat         /* FFI_TYPE_FLOAT */
704         .long   .Lrcls_retdouble        /* FFI_TYPE_DOUBLE */
705         .long   .Lrcls_retldouble       /* FFI_TYPE_LONGDOUBLE */
706         .long   .Lrcls_retuint8         /* FFI_TYPE_UINT8 */
707         .long   .Lrcls_retsint8         /* FFI_TYPE_SINT8 */
708         .long   .Lrcls_retuint16        /* FFI_TYPE_UINT16 */
709         .long   .Lrcls_retsint16        /* FFI_TYPE_SINT16 */
710         .long   .Lrcls_retint           /* FFI_TYPE_UINT32 */
711         .long   .Lrcls_retint           /* FFI_TYPE_SINT32 */
712         .long   .Lrcls_retllong         /* FFI_TYPE_UINT64 */
713         .long   .Lrcls_retllong         /* FFI_TYPE_SINT64 */
714         .long   .Lrcls_retstruct        /* FFI_TYPE_STRUCT */
715         .long   .Lrcls_retint           /* FFI_TYPE_POINTER */
716         .long   .Lrcls_retstruct1       /* FFI_TYPE_SMALL_STRUCT_1B */
717         .long   .Lrcls_retstruct2       /* FFI_TYPE_SMALL_STRUCT_2B */
718         .long   .Lrcls_retstruct4       /* FFI_TYPE_SMALL_STRUCT_4B */
719 1:
720         add     %eax, %eax
721         add     %eax, %eax
722         add     (%esp),%eax
723         add     $4, %esp
724         jmp     *(%eax)
725
726         /* Sign/zero extend as appropriate.  */
727 .Lrcls_retsint8:
728         movsbl  -24(%ebp), %eax
729         jmp     .Lrcls_epilogue
730
731 .Lrcls_retsint16:
732         movswl  -24(%ebp), %eax
733         jmp     .Lrcls_epilogue
734
735 .Lrcls_retuint8:
736         movzbl  -24(%ebp), %eax
737         jmp     .Lrcls_epilogue
738
739 .Lrcls_retuint16:
740         movzwl  -24(%ebp), %eax
741         jmp     .Lrcls_epilogue
742
743 .Lrcls_retint:
744         movl    -24(%ebp), %eax
745         jmp     .Lrcls_epilogue
746
747 .Lrcls_retfloat:
748         flds    -24(%ebp)
749         jmp     .Lrcls_epilogue
750
751 .Lrcls_retdouble:
752         fldl    -24(%ebp)
753         jmp     .Lrcls_epilogue
754
755 .Lrcls_retldouble:
756         fldt    -24(%ebp)
757         jmp     .Lrcls_epilogue
758
759 .Lrcls_retllong:
760         movl    -24(%ebp), %eax
761         movl    -20(%ebp), %edx
762         jmp     .Lrcls_epilogue
763
764 .Lrcls_retstruct1:
765         movsbl  -24(%ebp), %eax
766         jmp     .Lrcls_epilogue
767
768 .Lrcls_retstruct2:
769         movswl  -24(%ebp), %eax
770         jmp     .Lrcls_epilogue
771
772 .Lrcls_retstruct4:
773         movl    -24(%ebp), %eax
774         jmp     .Lrcls_epilogue
775
776 .Lrcls_retstruct:
777         # Nothing to do!
778
779 .Lrcls_noretval:
780 .Lrcls_epilogue:
781         addl    $36, %esp
782         popl    %esi
783         popl    %ebp
784         ret
785 .ffi_closure_raw_SYSV_end:
786 .LFE4:
787
788 #endif /* !FFI_NO_RAW_API */
789
790         # This assumes we are using gas.
791         .balign 16
792         .globl  _ffi_closure_STDCALL
793 #ifndef __OS2__
794         .def    _ffi_closure_STDCALL;   .scl    2;      .type   32;     .endef
795 #endif
796 _ffi_closure_STDCALL:
797 .LFB5:
798         pushl   %ebp
799 .LCFI9:
800         movl    %esp, %ebp
801 .LCFI10:
802         subl    $40, %esp
803         leal    -24(%ebp), %edx
804         movl    %edx, -12(%ebp) /* resp */
805         leal    12(%ebp), %edx  /* account for stub return address on stack */
806         movl    %edx, 4(%esp)   /* args */
807         leal    -12(%ebp), %edx
808         movl    %edx, (%esp)    /* &resp */
809         call    _ffi_closure_SYSV_inner
810         movl    -12(%ebp), %ecx
811 0:
812         call    1f
813         # Do not insert anything here between the call and the jump table.
814 .Lscls_store_table:
815         .long   .Lscls_noretval         /* FFI_TYPE_VOID */
816         .long   .Lscls_retint           /* FFI_TYPE_INT */
817         .long   .Lscls_retfloat         /* FFI_TYPE_FLOAT */
818         .long   .Lscls_retdouble        /* FFI_TYPE_DOUBLE */
819         .long   .Lscls_retldouble       /* FFI_TYPE_LONGDOUBLE */
820         .long   .Lscls_retuint8         /* FFI_TYPE_UINT8 */
821         .long   .Lscls_retsint8         /* FFI_TYPE_SINT8 */
822         .long   .Lscls_retuint16        /* FFI_TYPE_UINT16 */
823         .long   .Lscls_retsint16        /* FFI_TYPE_SINT16 */
824         .long   .Lscls_retint           /* FFI_TYPE_UINT32 */
825         .long   .Lscls_retint           /* FFI_TYPE_SINT32 */
826         .long   .Lscls_retllong         /* FFI_TYPE_UINT64 */
827         .long   .Lscls_retllong         /* FFI_TYPE_SINT64 */
828         .long   .Lscls_retstruct        /* FFI_TYPE_STRUCT */
829         .long   .Lscls_retint           /* FFI_TYPE_POINTER */
830         .long   .Lscls_retstruct1       /* FFI_TYPE_SMALL_STRUCT_1B */
831         .long   .Lscls_retstruct2       /* FFI_TYPE_SMALL_STRUCT_2B */
832         .long   .Lscls_retstruct4       /* FFI_TYPE_SMALL_STRUCT_4B */
833 1:
834         add     %eax, %eax
835         add     %eax, %eax
836         add     (%esp),%eax
837         add     $4, %esp
838         jmp     *(%eax)
839
840         /* Sign/zero extend as appropriate.  */
841 .Lscls_retsint8:
842         movsbl  (%ecx), %eax
843         jmp     .Lscls_epilogue
844
845 .Lscls_retsint16:
846         movswl  (%ecx), %eax
847         jmp     .Lscls_epilogue
848
849 .Lscls_retuint8:
850         movzbl  (%ecx), %eax
851         jmp     .Lscls_epilogue
852
853 .Lscls_retuint16:
854         movzwl  (%ecx), %eax
855         jmp     .Lscls_epilogue
856
857 .Lscls_retint:
858         movl    (%ecx), %eax
859         jmp     .Lscls_epilogue
860
861 .Lscls_retfloat:
862         flds    (%ecx)
863         jmp     .Lscls_epilogue
864
865 .Lscls_retdouble:
866         fldl    (%ecx)
867         jmp     .Lscls_epilogue
868
869 .Lscls_retldouble:
870         fldt    (%ecx)
871         jmp     .Lscls_epilogue
872
873 .Lscls_retllong:
874         movl    (%ecx), %eax
875         movl    4(%ecx), %edx
876         jmp     .Lscls_epilogue
877
878 .Lscls_retstruct1:
879         movsbl  (%ecx), %eax
880         jmp     .Lscls_epilogue
881
882 .Lscls_retstruct2:
883         movswl  (%ecx), %eax
884         jmp     .Lscls_epilogue
885
886 .Lscls_retstruct4:
887         movl    (%ecx), %eax
888         jmp     .Lscls_epilogue
889
890 .Lscls_retstruct:
891         # Nothing to do!
892
893 .Lscls_noretval:
894 .Lscls_epilogue:
895         movl    %ebp, %esp
896         popl    %ebp
897         ret
898 .ffi_closure_STDCALL_end:
899 .LFE5:
900
901 #ifndef __OS2__
902         .section        .eh_frame,"w"
903 #endif
904 .Lframe1:
905 .LSCIE1:
906         .long   .LECIE1-.LASCIE1  /* Length of Common Information Entry */
907 .LASCIE1:
908         .long   0x0     /* CIE Identifier Tag */
909         .byte   0x1     /* CIE Version */
910 #ifdef __PIC__
911         .ascii "zR\0"   /* CIE Augmentation */
912 #else
913         .ascii "\0"     /* CIE Augmentation */
914 #endif
915         .byte   0x1     /* .uleb128 0x1; CIE Code Alignment Factor */
916         .byte   0x7c    /* .sleb128 -4; CIE Data Alignment Factor */
917         .byte   0x8     /* CIE RA Column */
918 #ifdef __PIC__
919         .byte   0x1     /* .uleb128 0x1; Augmentation size */
920         .byte   0x1b    /* FDE Encoding (pcrel sdata4) */
921 #endif
922         .byte   0xc     /* DW_CFA_def_cfa CFA = r4 + 4 = 4(%esp) */
923         .byte   0x4     /* .uleb128 0x4 */
924         .byte   0x4     /* .uleb128 0x4 */
925         .byte   0x88    /* DW_CFA_offset, column 0x8 %eip at CFA + 1 * -4 */
926         .byte   0x1     /* .uleb128 0x1 */
927         .align 4
928 .LECIE1:
929
930 .LSFDE1:
931         .long   .LEFDE1-.LASFDE1        /* FDE Length */
932 .LASFDE1:
933         .long   .LASFDE1-.Lframe1       /* FDE CIE offset */
934 #if defined __PIC__ && defined HAVE_AS_X86_PCREL
935         .long   .LFB1-. /* FDE initial location */
936 #else
937         .long   .LFB1
938 #endif
939         .long   .LFE1-.LFB1     /* FDE address range */
940 #ifdef __PIC__
941         .byte   0x0     /* .uleb128 0x0; Augmentation size */
942 #endif
943         /* DW_CFA_xxx CFI instructions go here.  */
944
945         .byte   0x4     /* DW_CFA_advance_loc4 */
946         .long   .LCFI0-.LFB1
947         .byte   0xe     /* DW_CFA_def_cfa_offset CFA = r4 + 8 = 8(%esp) */
948         .byte   0x8     /* .uleb128 0x8 */
949         .byte   0x85    /* DW_CFA_offset, column 0x5 %ebp at CFA + 2 * -4 */
950         .byte   0x2     /* .uleb128 0x2 */
951
952         .byte   0x4     /* DW_CFA_advance_loc4 */
953         .long   .LCFI1-.LCFI0
954         .byte   0xd     /* DW_CFA_def_cfa_register CFA = r5 = %ebp */
955         .byte   0x5     /* .uleb128 0x5 */
956
957         /* End of DW_CFA_xxx CFI instructions.  */
958         .align 4
959 .LEFDE1:
960
961
962 .LSFDE3:
963         .long   .LEFDE3-.LASFDE3        /* FDE Length */
964 .LASFDE3:
965         .long   .LASFDE3-.Lframe1       /* FDE CIE offset */
966 #if defined __PIC__ && defined HAVE_AS_X86_PCREL
967         .long   .LFB3-. /* FDE initial location */
968 #else
969         .long   .LFB3
970 #endif
971         .long   .LFE3-.LFB3     /* FDE address range */
972 #ifdef __PIC__
973         .byte   0x0     /* .uleb128 0x0; Augmentation size */
974 #endif
975         /* DW_CFA_xxx CFI instructions go here.  */
976
977         .byte   0x4     /* DW_CFA_advance_loc4 */
978         .long   .LCFI4-.LFB3
979         .byte   0xe     /* DW_CFA_def_cfa_offset CFA = r4 + 8 = 8(%esp) */
980         .byte   0x8     /* .uleb128 0x8 */
981         .byte   0x85    /* DW_CFA_offset, column 0x5 %ebp at CFA + 2 * -4 */
982         .byte   0x2     /* .uleb128 0x2 */
983
984         .byte   0x4     /* DW_CFA_advance_loc4 */
985         .long   .LCFI5-.LCFI4
986         .byte   0xd     /* DW_CFA_def_cfa_register CFA = r5 = %ebp */
987         .byte   0x5     /* .uleb128 0x5 */
988
989         /* End of DW_CFA_xxx CFI instructions.  */
990         .align 4
991 .LEFDE3:
992
993 #if !FFI_NO_RAW_API
994
995 .LSFDE4:
996         .long   .LEFDE4-.LASFDE4        /* FDE Length */
997 .LASFDE4:
998         .long   .LASFDE4-.Lframe1       /* FDE CIE offset */
999 #if defined __PIC__ && defined HAVE_AS_X86_PCREL
1000         .long   .LFB4-. /* FDE initial location */
1001 #else
1002         .long   .LFB4
1003 #endif
1004         .long   .LFE4-.LFB4     /* FDE address range */
1005 #ifdef __PIC__
1006         .byte   0x0     /* .uleb128 0x0; Augmentation size */
1007 #endif
1008         /* DW_CFA_xxx CFI instructions go here.  */
1009
1010         .byte   0x4     /* DW_CFA_advance_loc4 */
1011         .long   .LCFI6-.LFB4
1012         .byte   0xe     /* DW_CFA_def_cfa_offset CFA = r4 + 8 = 8(%esp) */
1013         .byte   0x8     /* .uleb128 0x8 */
1014         .byte   0x85    /* DW_CFA_offset, column 0x5 %ebp at CFA + 2 * -4 */
1015         .byte   0x2     /* .uleb128 0x2 */
1016
1017         .byte   0x4     /* DW_CFA_advance_loc4 */
1018         .long   .LCFI7-.LCFI6
1019         .byte   0xd     /* DW_CFA_def_cfa_register CFA = r5 = %ebp */
1020         .byte   0x5     /* .uleb128 0x5 */
1021
1022         .byte   0x4     /* DW_CFA_advance_loc4 */
1023         .long   .LCFI8-.LCFI7
1024         .byte   0x86    /* DW_CFA_offset, column 0x6 %esi at CFA + 3 * -4 */
1025         .byte   0x3     /* .uleb128 0x3 */
1026
1027         /* End of DW_CFA_xxx CFI instructions.  */
1028         .align 4
1029 .LEFDE4:
1030
1031 #endif /* !FFI_NO_RAW_API */
1032
1033 .LSFDE5:
1034         .long   .LEFDE5-.LASFDE5        /* FDE Length */
1035 .LASFDE5:
1036         .long   .LASFDE5-.Lframe1       /* FDE CIE offset */
1037 #if defined __PIC__ && defined HAVE_AS_X86_PCREL
1038         .long   .LFB5-. /* FDE initial location */
1039 #else
1040         .long   .LFB5
1041 #endif
1042         .long   .LFE5-.LFB5     /* FDE address range */
1043 #ifdef __PIC__
1044         .byte   0x0     /* .uleb128 0x0; Augmentation size */
1045 #endif
1046         /* DW_CFA_xxx CFI instructions go here.  */
1047
1048         .byte   0x4     /* DW_CFA_advance_loc4 */
1049         .long   .LCFI9-.LFB5
1050         .byte   0xe     /* DW_CFA_def_cfa_offset CFA = r4 + 8 = 8(%esp) */
1051         .byte   0x8     /* .uleb128 0x8 */
1052         .byte   0x85    /* DW_CFA_offset, column 0x5 %ebp at CFA + 2 * -4 */
1053         .byte   0x2     /* .uleb128 0x2 */
1054
1055         .byte   0x4     /* DW_CFA_advance_loc4 */
1056         .long   .LCFI10-.LCFI9
1057         .byte   0xd     /* DW_CFA_def_cfa_register CFA = r5 = %ebp */
1058         .byte   0x5     /* .uleb128 0x5 */
1059
1060         /* End of DW_CFA_xxx CFI instructions.  */
1061         .align 4
1062 .LEFDE5:
1063
1064 #endif /* !_MSC_VER */
1065