Home | History | Annotate | Download | only in x86
      1 /* -----------------------------------------------------------------------
      2    win32.S - Copyright (c) 2014  Anthony Green
      3              Copyright (c) 1996, 1998, 2001, 2002, 2009  Red Hat, Inc.
      4              Copyright (c) 2001  John Beniton
      5              Copyright (c) 2002  Ranjit Mathew
      6              Copyright (c) 2009  Daniel Witte
      7 
      8 
      9    X86 Foreign Function Interface
     10 
     11    Permission is hereby granted, free of charge, to any person obtaining
     12    a copy of this software and associated documentation files (the
     13    ``Software''), to deal in the Software without restriction, including
     14    without limitation the rights to use, copy, modify, merge, publish,
     15    distribute, sublicense, and/or sell copies of the Software, and to
     16    permit persons to whom the Software is furnished to do so, subject to
     17    the following conditions:
     18 
     19    The above copyright notice and this permission notice shall be included
     20    in all copies or substantial portions of the Software.
     21 
     22    THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
     23    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     24    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
     25    NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
     26    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
     27    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     28    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
     29    DEALINGS IN THE SOFTWARE.
     30    -----------------------------------------------------------------------
     31    */
     32 
     33 #define LIBFFI_ASM
     34 #include <fficonfig.h>
     35 #include <ffi.h>
     36 
     37 #define CIF_BYTES_OFFSET 16
     38 #define CIF_FLAGS_OFFSET 20
     39 
     40 #ifdef _MSC_VER
     41 
     42 #define CLOSURE_CIF_OFFSET ((FFI_TRAMPOLINE_SIZE + 3) AND NOT 3)
     43 
     44 .386
     45 .MODEL FLAT, C
     46 
     47 EXTRN ffi_closure_SYSV_inner:NEAR
     48 EXTRN ffi_closure_WIN32_inner:NEAR
     49 
     50 _TEXT SEGMENT
     51 
     52 ffi_call_win32 PROC NEAR,
     53     ffi_prep_args : NEAR PTR DWORD,
     54     ecif          : NEAR PTR DWORD,
     55     cif_abi       : DWORD,
     56     cif_bytes     : DWORD,
     57     cif_flags     : DWORD,
     58     rvalue        : NEAR PTR DWORD,
     59     fn            : NEAR PTR DWORD
     60 
     61         ;; Make room for all of the new args.
     62         mov  ecx, cif_bytes
     63         sub  esp, ecx
     64 
     65         mov  eax, esp
     66 
     67         ;; Call ffi_prep_args
     68         push ecif
     69         push eax
     70         call ffi_prep_args
     71         add  esp, 8
     72 
     73         ;; Prepare registers
     74         ;; EAX stores the number of register arguments
     75         cmp  eax, 0
     76         je   fun
     77         cmp  eax, 3
     78         jl   prepr_two_cmp
     79 
     80         mov  ecx, esp
     81         add  esp, 12
     82         mov  eax, DWORD PTR [ecx+8]
     83         jmp  prepr_two
     84 prepr_two_cmp:
     85         cmp  eax, 2
     86         jl   prepr_one_prep
     87         mov  ecx, esp
     88         add  esp, 8
     89 prepr_two:
     90         mov  edx, DWORD PTR [ecx+4]
     91         jmp  prepr_one
     92 prepr_one_prep:
     93         mov  ecx, esp
     94         add  esp, 4
     95 prepr_one:
     96         mov  ecx, DWORD PTR [ecx]
     97         cmp  cif_abi, 7 ;; FFI_REGISTER
     98         jne  fun
     99 
    100         xchg ecx, eax
    101 
    102 fun:
    103         ;; Call function
    104         call fn
    105 
    106         ;; Load ecx with the return type code
    107         mov  ecx, cif_flags
    108 
    109         ;; If the return value pointer is NULL, assume no return value.
    110         cmp  rvalue, 0
    111         jne  ca_jumptable
    112 
    113         ;; Even if there is no space for the return value, we are
    114         ;; obliged to handle floating-point values.
    115         cmp  ecx, FFI_TYPE_FLOAT
    116         jne  ca_epilogue
    117         fstp st(0)
    118 
    119         jmp  ca_epilogue
    120 
    121 ca_jumptable:
    122         jmp  [ca_jumpdata + 4 * ecx]
    123 ca_jumpdata:
    124         ;; Do not insert anything here between label and jump table.
    125         dd offset ca_epilogue       ;; FFI_TYPE_VOID
    126         dd offset ca_retint         ;; FFI_TYPE_INT
    127         dd offset ca_retfloat       ;; FFI_TYPE_FLOAT
    128         dd offset ca_retdouble      ;; FFI_TYPE_DOUBLE
    129         dd offset ca_retlongdouble  ;; FFI_TYPE_LONGDOUBLE
    130         dd offset ca_retuint8       ;; FFI_TYPE_UINT8
    131         dd offset ca_retsint8       ;; FFI_TYPE_SINT8
    132         dd offset ca_retuint16      ;; FFI_TYPE_UINT16
    133         dd offset ca_retsint16      ;; FFI_TYPE_SINT16
    134         dd offset ca_retint         ;; FFI_TYPE_UINT32
    135         dd offset ca_retint         ;; FFI_TYPE_SINT32
    136         dd offset ca_retint64       ;; FFI_TYPE_UINT64
    137         dd offset ca_retint64       ;; FFI_TYPE_SINT64
    138         dd offset ca_epilogue       ;; FFI_TYPE_STRUCT
    139         dd offset ca_retint         ;; FFI_TYPE_POINTER
    140         dd offset ca_retstruct1b    ;; FFI_TYPE_SMALL_STRUCT_1B
    141         dd offset ca_retstruct2b    ;; FFI_TYPE_SMALL_STRUCT_2B
    142         dd offset ca_retint         ;; FFI_TYPE_SMALL_STRUCT_4B
    143         dd offset ca_epilogue       ;; FFI_TYPE_MS_STRUCT
    144 
    145         /* Sign/zero extend as appropriate.  */
    146 ca_retuint8:
    147         movzx eax, al
    148         jmp   ca_retint
    149 
    150 ca_retsint8:
    151         movsx eax, al
    152         jmp   ca_retint
    153 
    154 ca_retuint16:
    155         movzx eax, ax
    156         jmp   ca_retint
    157 
    158 ca_retsint16:
    159         movsx eax, ax
    160         jmp   ca_retint
    161 
    162 ca_retint:
    163         ;; Load %ecx with the pointer to storage for the return value
    164         mov   ecx, rvalue
    165         mov   [ecx + 0], eax
    166         jmp   ca_epilogue
    167 
    168 ca_retint64:
    169         ;; Load %ecx with the pointer to storage for the return value
    170         mov   ecx, rvalue
    171         mov   [ecx + 0], eax
    172         mov   [ecx + 4], edx
    173         jmp   ca_epilogue
    174 
    175 ca_retfloat:
    176         ;; Load %ecx with the pointer to storage for the return value
    177         mov   ecx, rvalue
    178         fstp  DWORD PTR [ecx]
    179         jmp   ca_epilogue
    180 
    181 ca_retdouble:
    182         ;; Load %ecx with the pointer to storage for the return value
    183         mov   ecx, rvalue
    184         fstp  QWORD PTR [ecx]
    185         jmp   ca_epilogue
    186 
    187 ca_retlongdouble:
    188         ;; Load %ecx with the pointer to storage for the return value
    189         mov   ecx, rvalue
    190         fstp  TBYTE PTR [ecx]
    191         jmp   ca_epilogue
    192 
    193 ca_retstruct1b:
    194         ;; Load %ecx with the pointer to storage for the return value
    195         mov   ecx, rvalue
    196         mov   [ecx + 0], al
    197         jmp   ca_epilogue
    198 
    199 ca_retstruct2b:
    200         ;; Load %ecx with the pointer to storage for the return value
    201         mov   ecx, rvalue
    202         mov   [ecx + 0], ax
    203         jmp   ca_epilogue
    204 
    205 ca_epilogue:
    206         ;; Epilogue code is autogenerated.
    207         ret
    208 ffi_call_win32 ENDP
    209 
    210 ffi_closure_THISCALL PROC NEAR
    211         ;; Insert the register argument on the stack as the first argument
    212         xchg	DWORD PTR [esp+4], ecx
    213         xchg	DWORD PTR [esp], ecx
    214         push	ecx
    215         jmp	ffi_closure_STDCALL
    216 ffi_closure_THISCALL ENDP
    217 
    218 ffi_closure_FASTCALL PROC NEAR
    219         ;; Insert the 2 register arguments on the stack as the first argument
    220         xchg	DWORD PTR [esp+4], edx
    221         xchg	DWORD PTR [esp], ecx
    222         push	edx
    223         push	ecx
    224         jmp	ffi_closure_STDCALL
    225 ffi_closure_FASTCALL ENDP
    226 
    227 ffi_closure_REGISTER PROC NEAR
    228         ;; Insert the 3 register arguments on the stack as the first argument
    229         push	eax
    230         xchg	DWORD PTR [esp+8], ecx
    231         xchg	DWORD PTR [esp+4], edx
    232         push	ecx
    233         push	edx
    234         jmp	ffi_closure_STDCALL
    235 ffi_closure_REGISTER ENDP
    236 
    237 ffi_closure_SYSV PROC NEAR FORCEFRAME
    238     ;; the ffi_closure ctx is passed in eax by the trampoline.
    239 
    240         sub  esp, 40
    241         lea  edx, [ebp - 24]
    242         mov  [ebp - 12], edx         ;; resp
    243         lea  edx, [ebp + 8]
    244 stub::
    245         mov  [esp + 8], edx          ;; args
    246         lea  edx, [ebp - 12]
    247         mov  [esp + 4], edx          ;; &resp
    248         mov  [esp], eax              ;; closure
    249         call ffi_closure_SYSV_inner
    250         mov  ecx, [ebp - 12]
    251 
    252 cs_jumptable:
    253         jmp  [cs_jumpdata + 4 * eax]
    254 cs_jumpdata:
    255         ;; Do not insert anything here between the label and jump table.
    256         dd offset cs_epilogue       ;; FFI_TYPE_VOID
    257         dd offset cs_retint         ;; FFI_TYPE_INT
    258         dd offset cs_retfloat       ;; FFI_TYPE_FLOAT
    259         dd offset cs_retdouble      ;; FFI_TYPE_DOUBLE
    260         dd offset cs_retlongdouble  ;; FFI_TYPE_LONGDOUBLE
    261         dd offset cs_retuint8       ;; FFI_TYPE_UINT8
    262         dd offset cs_retsint8       ;; FFI_TYPE_SINT8
    263         dd offset cs_retuint16      ;; FFI_TYPE_UINT16
    264         dd offset cs_retsint16      ;; FFI_TYPE_SINT16
    265         dd offset cs_retint         ;; FFI_TYPE_UINT32
    266         dd offset cs_retint         ;; FFI_TYPE_SINT32
    267         dd offset cs_retint64       ;; FFI_TYPE_UINT64
    268         dd offset cs_retint64       ;; FFI_TYPE_SINT64
    269         dd offset cs_retstruct      ;; FFI_TYPE_STRUCT
    270         dd offset cs_retint         ;; FFI_TYPE_POINTER
    271         dd offset cs_retsint8       ;; FFI_TYPE_SMALL_STRUCT_1B
    272         dd offset cs_retsint16      ;; FFI_TYPE_SMALL_STRUCT_2B
    273         dd offset cs_retint         ;; FFI_TYPE_SMALL_STRUCT_4B
    274         dd offset cs_retmsstruct    ;; FFI_TYPE_MS_STRUCT
    275 
    276 cs_retuint8:
    277         movzx eax, BYTE PTR [ecx]
    278         jmp   cs_epilogue
    279 
    280 cs_retsint8:
    281         movsx eax, BYTE PTR [ecx]
    282         jmp   cs_epilogue
    283 
    284 cs_retuint16:
    285         movzx eax, WORD PTR [ecx]
    286         jmp   cs_epilogue
    287 
    288 cs_retsint16:
    289         movsx eax, WORD PTR [ecx]
    290         jmp   cs_epilogue
    291 
    292 cs_retint:
    293         mov   eax, [ecx]
    294         jmp   cs_epilogue
    295 
    296 cs_retint64:
    297         mov   eax, [ecx + 0]
    298         mov   edx, [ecx + 4]
    299         jmp   cs_epilogue
    300 
    301 cs_retfloat:
    302         fld   DWORD PTR [ecx]
    303         jmp   cs_epilogue
    304 
    305 cs_retdouble:
    306         fld   QWORD PTR [ecx]
    307         jmp   cs_epilogue
    308 
    309 cs_retlongdouble:
    310         fld   TBYTE PTR [ecx]
    311         jmp   cs_epilogue
    312 
    313 cs_retstruct:
    314         ;; Caller expects us to pop struct return value pointer hidden arg.
    315         ;; Epilogue code is autogenerated.
    316         ret	4
    317 
    318 cs_retmsstruct:
    319         ;; Caller expects us to return a pointer to the real return value.
    320         mov   eax, ecx
    321         ;; Caller doesn't expects us to pop struct return value pointer hidden arg.
    322         jmp   cs_epilogue
    323 
    324 cs_epilogue:
    325         ;; Epilogue code is autogenerated.
    326         ret
    327 ffi_closure_SYSV ENDP
    328 
    329 #if !FFI_NO_RAW_API
    330 
    331 #define RAW_CLOSURE_CIF_OFFSET ((FFI_TRAMPOLINE_SIZE + 3) AND NOT 3)
    332 #define RAW_CLOSURE_FUN_OFFSET (RAW_CLOSURE_CIF_OFFSET + 4)
    333 #define RAW_CLOSURE_USER_DATA_OFFSET (RAW_CLOSURE_FUN_OFFSET + 4)
    334 
    335 ffi_closure_raw_THISCALL PROC NEAR USES esi FORCEFRAME
    336         sub esp, 36
    337         mov  esi, [eax + RAW_CLOSURE_CIF_OFFSET]        ;; closure->cif
    338         mov  edx, [eax + RAW_CLOSURE_USER_DATA_OFFSET]  ;; closure->user_data
    339         mov [esp + 12], edx
    340         lea edx, [ebp + 12]
    341         jmp stubraw
    342 ffi_closure_raw_THISCALL ENDP
    343 
    344 ffi_closure_raw_SYSV PROC NEAR USES esi FORCEFRAME
    345     ;; the ffi_closure ctx is passed in eax by the trampoline.
    346 
    347         sub  esp, 40
    348         mov  esi, [eax + RAW_CLOSURE_CIF_OFFSET]        ;; closure->cif
    349         mov  edx, [eax + RAW_CLOSURE_USER_DATA_OFFSET]  ;; closure->user_data
    350         mov  [esp + 12], edx                            ;; user_data
    351         lea  edx, [ebp + 8]
    352 stubraw::
    353         mov  [esp + 8], edx                             ;; raw_args
    354         lea  edx, [ebp - 24]
    355         mov  [esp + 4], edx                             ;; &res
    356         mov  [esp], esi                                 ;; cif
    357         call DWORD PTR [eax + RAW_CLOSURE_FUN_OFFSET]   ;; closure->fun
    358         mov  eax, [esi + CIF_FLAGS_OFFSET]              ;; cif->flags
    359         lea  ecx, [ebp - 24]
    360 
    361 cr_jumptable:
    362         jmp  [cr_jumpdata + 4 * eax]
    363 cr_jumpdata:
    364         ;; Do not insert anything here between the label and jump table.
    365         dd offset cr_epilogue       ;; FFI_TYPE_VOID
    366         dd offset cr_retint         ;; FFI_TYPE_INT
    367         dd offset cr_retfloat       ;; FFI_TYPE_FLOAT
    368         dd offset cr_retdouble      ;; FFI_TYPE_DOUBLE
    369         dd offset cr_retlongdouble  ;; FFI_TYPE_LONGDOUBLE
    370         dd offset cr_retuint8       ;; FFI_TYPE_UINT8
    371         dd offset cr_retsint8       ;; FFI_TYPE_SINT8
    372         dd offset cr_retuint16      ;; FFI_TYPE_UINT16
    373         dd offset cr_retsint16      ;; FFI_TYPE_SINT16
    374         dd offset cr_retint         ;; FFI_TYPE_UINT32
    375         dd offset cr_retint         ;; FFI_TYPE_SINT32
    376         dd offset cr_retint64       ;; FFI_TYPE_UINT64
    377         dd offset cr_retint64       ;; FFI_TYPE_SINT64
    378         dd offset cr_epilogue       ;; FFI_TYPE_STRUCT
    379         dd offset cr_retint         ;; FFI_TYPE_POINTER
    380         dd offset cr_retsint8       ;; FFI_TYPE_SMALL_STRUCT_1B
    381         dd offset cr_retsint16      ;; FFI_TYPE_SMALL_STRUCT_2B
    382         dd offset cr_retint         ;; FFI_TYPE_SMALL_STRUCT_4B
    383         dd offset cr_epilogue       ;; FFI_TYPE_MS_STRUCT
    384 
    385 cr_retuint8:
    386         movzx eax, BYTE PTR [ecx]
    387         jmp   cr_epilogue
    388 
    389 cr_retsint8:
    390         movsx eax, BYTE PTR [ecx]
    391         jmp   cr_epilogue
    392 
    393 cr_retuint16:
    394         movzx eax, WORD PTR [ecx]
    395         jmp   cr_epilogue
    396 
    397 cr_retsint16:
    398         movsx eax, WORD PTR [ecx]
    399         jmp   cr_epilogue
    400 
    401 cr_retint:
    402         mov   eax, [ecx]
    403         jmp   cr_epilogue
    404 
    405 cr_retint64:
    406         mov   eax, [ecx + 0]
    407         mov   edx, [ecx + 4]
    408         jmp   cr_epilogue
    409 
    410 cr_retfloat:
    411         fld   DWORD PTR [ecx]
    412         jmp   cr_epilogue
    413 
    414 cr_retdouble:
    415         fld   QWORD PTR [ecx]
    416         jmp   cr_epilogue
    417 
    418 cr_retlongdouble:
    419         fld   TBYTE PTR [ecx]
    420         jmp   cr_epilogue
    421 
    422 cr_epilogue:
    423         ;; Epilogue code is autogenerated.
    424         ret
    425 ffi_closure_raw_SYSV ENDP
    426 
    427 #endif /* !FFI_NO_RAW_API */
    428 
    429 ffi_closure_STDCALL PROC NEAR FORCEFRAME
    430         mov  eax, [esp] ;; the ffi_closure ctx passed by the trampoline.
    431 
    432         sub  esp, 40
    433         lea  edx, [ebp - 24]
    434         mov  [ebp - 12], edx         ;; resp
    435         lea  edx, [ebp + 12]         ;; account for stub return address on stack
    436         mov  [esp + 8], edx          ;; args
    437         lea  edx, [ebp - 12]
    438         mov  [esp + 4], edx          ;; &resp
    439         mov  [esp], eax              ;; closure
    440         call ffi_closure_WIN32_inner
    441         mov  ecx, [ebp - 12]
    442 
    443         xchg [ebp + 4], eax          ;;xchg size of stack parameters and ffi_closure ctx
    444         mov  eax, DWORD PTR [eax + CLOSURE_CIF_OFFSET]
    445         mov  eax, DWORD PTR [eax + CIF_FLAGS_OFFSET]
    446 
    447 cd_jumptable:
    448         jmp  [cd_jumpdata + 4 * eax]
    449 cd_jumpdata:
    450         ;; Do not insert anything here between the label and jump table.
    451         dd offset cd_epilogue       ;; FFI_TYPE_VOID
    452         dd offset cd_retint         ;; FFI_TYPE_INT
    453         dd offset cd_retfloat       ;; FFI_TYPE_FLOAT
    454         dd offset cd_retdouble      ;; FFI_TYPE_DOUBLE
    455         dd offset cd_retlongdouble  ;; FFI_TYPE_LONGDOUBLE
    456         dd offset cd_retuint8       ;; FFI_TYPE_UINT8
    457         dd offset cd_retsint8       ;; FFI_TYPE_SINT8
    458         dd offset cd_retuint16      ;; FFI_TYPE_UINT16
    459         dd offset cd_retsint16      ;; FFI_TYPE_SINT16
    460         dd offset cd_retint         ;; FFI_TYPE_UINT32
    461         dd offset cd_retint         ;; FFI_TYPE_SINT32
    462         dd offset cd_retint64       ;; FFI_TYPE_UINT64
    463         dd offset cd_retint64       ;; FFI_TYPE_SINT64
    464         dd offset cd_epilogue       ;; FFI_TYPE_STRUCT
    465         dd offset cd_retint         ;; FFI_TYPE_POINTER
    466         dd offset cd_retsint8       ;; FFI_TYPE_SMALL_STRUCT_1B
    467         dd offset cd_retsint16      ;; FFI_TYPE_SMALL_STRUCT_2B
    468         dd offset cd_retint         ;; FFI_TYPE_SMALL_STRUCT_4B
    469 
    470 cd_retuint8:
    471         movzx eax, BYTE PTR [ecx]
    472         jmp   cd_epilogue
    473 
    474 cd_retsint8:
    475         movsx eax, BYTE PTR [ecx]
    476         jmp   cd_epilogue
    477 
    478 cd_retuint16:
    479         movzx eax, WORD PTR [ecx]
    480         jmp   cd_epilogue
    481 
    482 cd_retsint16:
    483         movsx eax, WORD PTR [ecx]
    484         jmp   cd_epilogue
    485 
    486 cd_retint:
    487         mov   eax, [ecx]
    488         jmp   cd_epilogue
    489 
    490 cd_retint64:
    491         mov   eax, [ecx + 0]
    492         mov   edx, [ecx + 4]
    493         jmp   cd_epilogue
    494 
    495 cd_retfloat:
    496         fld   DWORD PTR [ecx]
    497         jmp   cd_epilogue
    498 
    499 cd_retdouble:
    500         fld   QWORD PTR [ecx]
    501         jmp   cd_epilogue
    502 
    503 cd_retlongdouble:
    504         fld   TBYTE PTR [ecx]
    505         jmp   cd_epilogue
    506 
    507 cd_epilogue:
    508         mov   esp, ebp
    509         pop   ebp
    510         mov   ecx, [esp + 4]  ;; Return address
    511         add   esp, [esp]      ;; Parameters stack size
    512         add   esp, 8
    513         jmp   ecx
    514 ffi_closure_STDCALL ENDP
    515 
    516 _TEXT ENDS
    517 END
    518 
    519 #else
    520 
    521 #define CLOSURE_CIF_OFFSET ((FFI_TRAMPOLINE_SIZE + 3) & ~3)
    522 
    523 #if defined(SYMBOL_UNDERSCORE)
    524 #define USCORE_SYMBOL(x) _##x
    525 #else
    526 #define USCORE_SYMBOL(x) x
    527 #endif
    528         .text
    529 
    530         # This assumes we are using gas.
    531         .balign 16
    532 FFI_HIDDEN(ffi_call_win32)
    533         .globl	USCORE_SYMBOL(ffi_call_win32)
    534 #if defined(X86_WIN32) && !defined(__OS2__)
    535         .def	_ffi_call_win32;	.scl	2;	.type	32;	.endef
    536 #endif
    537 USCORE_SYMBOL(ffi_call_win32):
    538 .LFB1:
    539         pushl %ebp
    540 .LCFI0:
    541         movl  %esp,%ebp
    542 .LCFI1:
    543         # Make room for all of the new args.
    544         movl  20(%ebp),%ecx
    545         subl  %ecx,%esp
    546 
    547         movl  %esp,%eax
    548 
    549         # Call ffi_prep_args
    550         pushl 12(%ebp)
    551         pushl %eax
    552         call  *8(%ebp)
    553         addl  $8,%esp
    554 
    555         # Prepare registers
    556         # EAX stores the number of register arguments
    557         cmpl  $0, %eax
    558         je    .fun
    559         cmpl  $3, %eax
    560         jl    .prepr_two_cmp
    561 
    562         movl  %esp, %ecx
    563         addl  $12, %esp
    564         movl  8(%ecx), %eax
    565         jmp   .prepr_two
    566 .prepr_two_cmp:
    567         cmpl  $2, %eax
    568         jl    .prepr_one_prep
    569         movl  %esp, %ecx
    570         addl  $8, %esp
    571 .prepr_two:
    572         movl  4(%ecx), %edx
    573         jmp   .prepr_one
    574 .prepr_one_prep:
    575         movl  %esp, %ecx
    576         addl  $4, %esp
    577 .prepr_one:
    578         movl  (%ecx), %ecx
    579         cmpl  $7, 16(%ebp) # FFI_REGISTER
    580         jne   .fun
    581 
    582         xchgl %eax, %ecx
    583 
    584 .fun:
    585         # FIXME: Align the stack to a 128-bit boundary to avoid
    586         # potential performance hits.
    587 
    588         # Call function
    589         call  *32(%ebp)
    590 
    591         # stdcall functions pop arguments off the stack themselves
    592 
    593         # Load %ecx with the return type code
    594         movl  24(%ebp),%ecx
    595 
    596         # If the return value pointer is NULL, assume no return value.
    597         cmpl  $0,28(%ebp)
    598         jne   0f
    599 
    600         # Even if there is no space for the return value, we are
    601         # obliged to handle floating-point values.
    602         cmpl  $FFI_TYPE_FLOAT,%ecx
    603         jne   .Lnoretval
    604         fstp  %st(0)
    605 
    606         jmp   .Lepilogue
    607 
    608 0:
    609         call 1f
    610         # Do not insert anything here between the call and the jump table.
    611 .Lstore_table:
    612         .long	.Lnoretval-.Lstore_table	/* FFI_TYPE_VOID */
    613         .long	.Lretint-.Lstore_table		/* FFI_TYPE_INT */
    614         .long	.Lretfloat-.Lstore_table	/* FFI_TYPE_FLOAT */
    615         .long	.Lretdouble-.Lstore_table	/* FFI_TYPE_DOUBLE */
    616         .long	.Lretlongdouble-.Lstore_table	/* FFI_TYPE_LONGDOUBLE */
    617         .long	.Lretuint8-.Lstore_table	/* FFI_TYPE_UINT8 */
    618         .long	.Lretsint8-.Lstore_table	/* FFI_TYPE_SINT8 */
    619         .long	.Lretuint16-.Lstore_table	/* FFI_TYPE_UINT16 */
    620         .long	.Lretsint16-.Lstore_table	/* FFI_TYPE_SINT16 */
    621         .long	.Lretint-.Lstore_table		/* FFI_TYPE_UINT32 */
    622         .long	.Lretint-.Lstore_table		/* FFI_TYPE_SINT32 */
    623         .long	.Lretint64-.Lstore_table	/* FFI_TYPE_UINT64 */
    624         .long	.Lretint64-.Lstore_table	/* FFI_TYPE_SINT64 */
    625         .long	.Lretstruct-.Lstore_table	/* FFI_TYPE_STRUCT */
    626         .long	.Lretint-.Lstore_table		/* FFI_TYPE_POINTER */
    627         .long	.Lretstruct1b-.Lstore_table	/* FFI_TYPE_SMALL_STRUCT_1B */
    628         .long	.Lretstruct2b-.Lstore_table	/* FFI_TYPE_SMALL_STRUCT_2B */
    629         .long	.Lretstruct4b-.Lstore_table	/* FFI_TYPE_SMALL_STRUCT_4B */
    630         .long	.Lretstruct-.Lstore_table	/* FFI_TYPE_MS_STRUCT */
    631 1:
    632         shl	$2, %ecx
    633         add	(%esp),%ecx
    634         mov	(%ecx),%ecx
    635         add	(%esp),%ecx
    636         add	$4, %esp
    637         jmp	*%ecx
    638 
    639         /* Sign/zero extend as appropriate.  */
    640 .Lretsint8:
    641         movsbl	%al, %eax
    642         jmp	.Lretint
    643 
    644 .Lretsint16:
    645         movswl	%ax, %eax
    646         jmp	.Lretint
    647 
    648 .Lretuint8:
    649         movzbl	%al, %eax
    650         jmp	.Lretint
    651 
    652 .Lretuint16:
    653         movzwl	%ax, %eax
    654         jmp	.Lretint
    655 
    656 .Lretint:
    657         # Load %ecx with the pointer to storage for the return value
    658         movl  28(%ebp),%ecx
    659         movl  %eax,0(%ecx)
    660         jmp   .Lepilogue
    661 
    662 .Lretfloat:
    663          # Load %ecx with the pointer to storage for the return value
    664         movl  28(%ebp),%ecx
    665         fstps (%ecx)
    666         jmp   .Lepilogue
    667 
    668 .Lretdouble:
    669         # Load %ecx with the pointer to storage for the return value
    670         movl  28(%ebp),%ecx
    671         fstpl (%ecx)
    672         jmp   .Lepilogue
    673 
    674 .Lretlongdouble:
    675         # Load %ecx with the pointer to storage for the return value
    676         movl  28(%ebp),%ecx
    677         fstpt (%ecx)
    678         jmp   .Lepilogue
    679 
    680 .Lretint64:
    681         # Load %ecx with the pointer to storage for the return value
    682         movl  28(%ebp),%ecx
    683         movl  %eax,0(%ecx)
    684         movl  %edx,4(%ecx)
    685         jmp   .Lepilogue
    686 
    687 .Lretstruct1b:
    688         # Load %ecx with the pointer to storage for the return value
    689         movl  28(%ebp),%ecx
    690         movb  %al,0(%ecx)
    691         jmp   .Lepilogue
    692 
    693 .Lretstruct2b:
    694         # Load %ecx with the pointer to storage for the return value
    695         movl  28(%ebp),%ecx
    696         movw  %ax,0(%ecx)
    697         jmp   .Lepilogue
    698 
    699 .Lretstruct4b:
    700         # Load %ecx with the pointer to storage for the return value
    701         movl  28(%ebp),%ecx
    702         movl  %eax,0(%ecx)
    703         jmp   .Lepilogue
    704 
    705 .Lretstruct:
    706         # Nothing to do!
    707 
    708 .Lnoretval:
    709 .Lepilogue:
    710         movl %ebp,%esp
    711         popl %ebp
    712         ret
    713 .ffi_call_win32_end:
    714         .balign 16
    715 FFI_HIDDEN(ffi_closure_THISCALL)
    716         .globl	USCORE_SYMBOL(ffi_closure_THISCALL)
    717 #if defined(X86_WIN32) && !defined(__OS2__)
    718         .def	_ffi_closure_THISCALL;	.scl	2;	.type	32;	.endef
    719 #endif
    720 USCORE_SYMBOL(ffi_closure_THISCALL):
    721         /* Insert the register argument on the stack as the first argument */
    722         xchg	%ecx, 4(%esp)
    723         xchg	%ecx, (%esp)
    724         push	%ecx
    725         jmp	.ffi_closure_STDCALL_internal
    726 
    727         .balign 16
    728 FFI_HIDDEN(ffi_closure_FASTCALL)
    729         .globl	USCORE_SYMBOL(ffi_closure_FASTCALL)
    730 #if defined(X86_WIN32) && !defined(__OS2__)
    731         .def	_ffi_closure_FASTCALL;	.scl	2;	.type	32;	.endef
    732 #endif
    733 USCORE_SYMBOL(ffi_closure_FASTCALL):
    734         /* Insert the 2 register arguments on the stack as the first two arguments */
    735         xchg	%edx, 4(%esp)
    736         xchg	%ecx, (%esp)
    737         push	%edx
    738         push	%ecx
    739         jmp	.ffi_closure_STDCALL_internal
    740 FFI_HIDDEN(ffi_closure_REGISTER)
    741         .globl	USCORE_SYMBOL(ffi_closure_REGISTER)
    742 #if defined(X86_WIN32) && !defined(__OS2__)
    743         .def	_ffi_closure_REGISTER;	.scl	2;	.type	32;	.endef
    744 #endif
    745 USCORE_SYMBOL(ffi_closure_REGISTER):
    746         /* Insert the 3 register arguments on the stack as the first two arguments */
    747         push	%eax
    748         xchg	%ecx, 8(%esp)
    749         xchg	%edx, 4(%esp)
    750         push	%ecx
    751         push	%edx
    752         jmp	.ffi_closure_STDCALL_internal
    753 
    754 .LFE1:
    755         # This assumes we are using gas.
    756         .balign 16
    757 FFI_HIDDEN(ffi_closure_SYSV)
    758 #if defined(X86_WIN32)
    759         .globl	USCORE_SYMBOL(ffi_closure_SYSV)
    760 #if defined(X86_WIN32) && !defined(__OS2__)
    761         .def	_ffi_closure_SYSV;	.scl	2;	.type	32;	.endef
    762 #endif
    763 USCORE_SYMBOL(ffi_closure_SYSV):
    764 #endif
    765 .LFB3:
    766         pushl	%ebp
    767 .LCFI4:
    768         movl	%esp, %ebp
    769 .LCFI5:
    770         subl	$40, %esp
    771         leal	-24(%ebp), %edx
    772         movl	%edx, -12(%ebp)	/* resp */
    773         leal	8(%ebp), %edx
    774         movl	%edx, 4(%esp)	/* args = __builtin_dwarf_cfa () */
    775         leal	-12(%ebp), %edx
    776         movl	%edx, (%esp)	/* &resp */
    777 #if defined(HAVE_HIDDEN_VISIBILITY_ATTRIBUTE) || !defined(__PIC__)
    778         call	USCORE_SYMBOL(ffi_closure_SYSV_inner)
    779 #elif defined(X86_DARWIN)
    780         calll	L_ffi_closure_SYSV_inner$stub
    781 #else
    782         movl	%ebx, 8(%esp)
    783         call	1f
    784 1:      popl	%ebx
    785         addl	$_GLOBAL_OFFSET_TABLE_+[.-1b], %ebx
    786         call	ffi_closure_SYSV_inner@PLT
    787         movl	8(%esp), %ebx
    788 #endif
    789         movl	-12(%ebp), %ecx
    790 
    791 0:
    792         call	1f
    793         # Do not insert anything here between the call and the jump table.
    794 .Lcls_store_table:
    795         .long	.Lcls_noretval-.Lcls_store_table	/* FFI_TYPE_VOID */
    796         .long	.Lcls_retint-.Lcls_store_table		/* FFI_TYPE_INT */
    797         .long	.Lcls_retfloat-.Lcls_store_table	/* FFI_TYPE_FLOAT */
    798         .long	.Lcls_retdouble-.Lcls_store_table	/* FFI_TYPE_DOUBLE */
    799         .long	.Lcls_retldouble-.Lcls_store_table	/* FFI_TYPE_LONGDOUBLE */
    800         .long	.Lcls_retuint8-.Lcls_store_table	/* FFI_TYPE_UINT8 */
    801         .long	.Lcls_retsint8-.Lcls_store_table	/* FFI_TYPE_SINT8 */
    802         .long	.Lcls_retuint16-.Lcls_store_table	/* FFI_TYPE_UINT16 */
    803         .long	.Lcls_retsint16-.Lcls_store_table	/* FFI_TYPE_SINT16 */
    804         .long	.Lcls_retint-.Lcls_store_table		/* FFI_TYPE_UINT32 */
    805         .long	.Lcls_retint-.Lcls_store_table		/* FFI_TYPE_SINT32 */
    806         .long	.Lcls_retllong-.Lcls_store_table	/* FFI_TYPE_UINT64 */
    807         .long	.Lcls_retllong-.Lcls_store_table	/* FFI_TYPE_SINT64 */
    808         .long	.Lcls_retstruct-.Lcls_store_table	/* FFI_TYPE_STRUCT */
    809         .long	.Lcls_retint-.Lcls_store_table		/* FFI_TYPE_POINTER */
    810         .long	.Lcls_retstruct1-.Lcls_store_table	/* FFI_TYPE_SMALL_STRUCT_1B */
    811         .long	.Lcls_retstruct2-.Lcls_store_table	/* FFI_TYPE_SMALL_STRUCT_2B */
    812         .long	.Lcls_retstruct4-.Lcls_store_table	/* FFI_TYPE_SMALL_STRUCT_4B */
    813         .long	.Lcls_retmsstruct-.Lcls_store_table	/* FFI_TYPE_MS_STRUCT */
    814 
    815 1:
    816         shl	$2, %eax
    817         add	(%esp),%eax
    818         mov	(%eax),%eax
    819         add	(%esp),%eax
    820         add	$4, %esp
    821         jmp	*%eax
    822 
    823         /* Sign/zero extend as appropriate.  */
    824 .Lcls_retsint8:
    825         movsbl	(%ecx), %eax
    826         jmp	.Lcls_epilogue
    827 
    828 .Lcls_retsint16:
    829         movswl	(%ecx), %eax
    830         jmp	.Lcls_epilogue
    831 
    832 .Lcls_retuint8:
    833         movzbl	(%ecx), %eax
    834         jmp	.Lcls_epilogue
    835 
    836 .Lcls_retuint16:
    837         movzwl	(%ecx), %eax
    838         jmp	.Lcls_epilogue
    839 
    840 .Lcls_retint:
    841         movl	(%ecx), %eax
    842         jmp	.Lcls_epilogue
    843 
    844 .Lcls_retfloat:
    845         flds	(%ecx)
    846         jmp	.Lcls_epilogue
    847 
    848 .Lcls_retdouble:
    849         fldl	(%ecx)
    850         jmp	.Lcls_epilogue
    851 
    852 .Lcls_retldouble:
    853         fldt	(%ecx)
    854         jmp	.Lcls_epilogue
    855 
    856 .Lcls_retllong:
    857         movl	(%ecx), %eax
    858         movl	4(%ecx), %edx
    859         jmp	.Lcls_epilogue
    860 
    861 .Lcls_retstruct1:
    862         movsbl	(%ecx), %eax
    863         jmp	.Lcls_epilogue
    864 
    865 .Lcls_retstruct2:
    866         movswl	(%ecx), %eax
    867         jmp	.Lcls_epilogue
    868 
    869 .Lcls_retstruct4:
    870         movl	(%ecx), %eax
    871         jmp	.Lcls_epilogue
    872 
    873 .Lcls_retstruct:
    874         # Caller expects us to pop struct return value pointer hidden arg.
    875         movl	%ebp, %esp
    876         popl	%ebp
    877         ret	$0x4
    878 
    879 .Lcls_retmsstruct:
    880         # Caller expects us to return a pointer to the real return value.
    881         mov	%ecx, %eax
    882         # Caller doesn't expects us to pop struct return value pointer hidden arg.
    883         jmp	.Lcls_epilogue
    884 
    885 .Lcls_noretval:
    886 .Lcls_epilogue:
    887         movl	%ebp, %esp
    888         popl	%ebp
    889         ret
    890 .ffi_closure_SYSV_end:
    891 .LFE3:
    892 
    893 #if !FFI_NO_RAW_API
    894 
    895 #define RAW_CLOSURE_CIF_OFFSET ((FFI_TRAMPOLINE_SIZE + 3) & ~3)
    896 #define RAW_CLOSURE_FUN_OFFSET (RAW_CLOSURE_CIF_OFFSET + 4)
    897 #define RAW_CLOSURE_USER_DATA_OFFSET (RAW_CLOSURE_FUN_OFFSET + 4)
    898 
    899 #ifdef X86_WIN32
    900         .balign 16
    901 FFI_HIDDEN(ffi_closure_raw_THISCALL)
    902         .globl	USCORE_SYMBOL(ffi_closure_raw_THISCALL)
    903 #if defined(X86_WIN32) && !defined(__OS2__)
    904         .def	_ffi_closure_raw_THISCALL;	.scl	2;	.type	32;	.endef
    905 #endif
    906 USCORE_SYMBOL(ffi_closure_raw_THISCALL):
    907         pushl	%ebp
    908         movl	%esp, %ebp
    909         pushl	%esi
    910         subl	$36, %esp
    911         movl	RAW_CLOSURE_CIF_OFFSET(%eax), %esi	 /* closure->cif */
    912         movl	RAW_CLOSURE_USER_DATA_OFFSET(%eax), %edx /* closure->user_data */
    913         movl	%edx, 12(%esp)	/* user_data */
    914         leal	12(%ebp), %edx	/* __builtin_dwarf_cfa () */
    915         jmp	.stubraw
    916 #endif /* X86_WIN32 */
    917 
    918         # This assumes we are using gas.
    919         .balign 16
    920 #if defined(X86_WIN32)
    921         .globl	USCORE_SYMBOL(ffi_closure_raw_SYSV)
    922 #if defined(X86_WIN32) && !defined(__OS2__)
    923         .def	_ffi_closure_raw_SYSV;	.scl	2;	.type	32;	.endef
    924 #endif
    925 USCORE_SYMBOL(ffi_closure_raw_SYSV):
    926 #endif /* defined(X86_WIN32) */
    927 .LFB4:
    928         pushl	%ebp
    929 .LCFI6:
    930         movl	%esp, %ebp
    931 .LCFI7:
    932         pushl	%esi
    933 .LCFI8:
    934         subl	$36, %esp
    935         movl	RAW_CLOSURE_CIF_OFFSET(%eax), %esi	 /* closure->cif */
    936         movl	RAW_CLOSURE_USER_DATA_OFFSET(%eax), %edx /* closure->user_data */
    937         movl	%edx, 12(%esp)	/* user_data */
    938         leal	8(%ebp), %edx	/* __builtin_dwarf_cfa () */
    939 .stubraw:
    940         movl	%edx, 8(%esp)	/* raw_args */
    941         leal	-24(%ebp), %edx
    942         movl	%edx, 4(%esp)	/* &res */
    943         movl	%esi, (%esp)	/* cif */
    944         call	*RAW_CLOSURE_FUN_OFFSET(%eax)		 /* closure->fun */
    945         movl	CIF_FLAGS_OFFSET(%esi), %eax		 /* rtype */
    946 0:
    947         call	1f
    948         # Do not insert anything here between the call and the jump table.
    949 .Lrcls_store_table:
    950         .long	.Lrcls_noretval-.Lrcls_store_table	/* FFI_TYPE_VOID */
    951         .long	.Lrcls_retint-.Lrcls_store_table	/* FFI_TYPE_INT */
    952         .long	.Lrcls_retfloat-.Lrcls_store_table	/* FFI_TYPE_FLOAT */
    953         .long	.Lrcls_retdouble-.Lrcls_store_table	/* FFI_TYPE_DOUBLE */
    954         .long	.Lrcls_retldouble-.Lrcls_store_table	/* FFI_TYPE_LONGDOUBLE */
    955         .long	.Lrcls_retuint8-.Lrcls_store_table	/* FFI_TYPE_UINT8 */
    956         .long	.Lrcls_retsint8-.Lrcls_store_table	/* FFI_TYPE_SINT8 */
    957         .long	.Lrcls_retuint16-.Lrcls_store_table	/* FFI_TYPE_UINT16 */
    958         .long	.Lrcls_retsint16-.Lrcls_store_table	/* FFI_TYPE_SINT16 */
    959         .long	.Lrcls_retint-.Lrcls_store_table	/* FFI_TYPE_UINT32 */
    960         .long	.Lrcls_retint-.Lrcls_store_table	/* FFI_TYPE_SINT32 */
    961         .long	.Lrcls_retllong-.Lrcls_store_table	/* FFI_TYPE_UINT64 */
    962         .long	.Lrcls_retllong-.Lrcls_store_table	/* FFI_TYPE_SINT64 */
    963         .long	.Lrcls_retstruct-.Lrcls_store_table	/* FFI_TYPE_STRUCT */
    964         .long	.Lrcls_retint-.Lrcls_store_table	/* FFI_TYPE_POINTER */
    965         .long	.Lrcls_retstruct1-.Lrcls_store_table	/* FFI_TYPE_SMALL_STRUCT_1B */
    966         .long	.Lrcls_retstruct2-.Lrcls_store_table	/* FFI_TYPE_SMALL_STRUCT_2B */
    967         .long	.Lrcls_retstruct4-.Lrcls_store_table	/* FFI_TYPE_SMALL_STRUCT_4B */
    968         .long	.Lrcls_retstruct-.Lrcls_store_table	/* FFI_TYPE_MS_STRUCT */
    969 1:
    970         shl	$2, %eax
    971         add	(%esp),%eax
    972         mov	(%eax),%eax
    973         add	(%esp),%eax
    974         add	$4, %esp
    975         jmp	*%eax
    976 
    977         /* Sign/zero extend as appropriate.  */
    978 .Lrcls_retsint8:
    979         movsbl	-24(%ebp), %eax
    980         jmp	.Lrcls_epilogue
    981 
    982 .Lrcls_retsint16:
    983         movswl	-24(%ebp), %eax
    984         jmp	.Lrcls_epilogue
    985 
    986 .Lrcls_retuint8:
    987         movzbl	-24(%ebp), %eax
    988         jmp	.Lrcls_epilogue
    989 
    990 .Lrcls_retuint16:
    991         movzwl	-24(%ebp), %eax
    992         jmp	.Lrcls_epilogue
    993 
    994 .Lrcls_retint:
    995         movl	-24(%ebp), %eax
    996         jmp	.Lrcls_epilogue
    997 
    998 .Lrcls_retfloat:
    999         flds	-24(%ebp)
   1000         jmp	.Lrcls_epilogue
   1001 
   1002 .Lrcls_retdouble:
   1003         fldl	-24(%ebp)
   1004         jmp	.Lrcls_epilogue
   1005 
   1006 .Lrcls_retldouble:
   1007         fldt	-24(%ebp)
   1008         jmp	.Lrcls_epilogue
   1009 
   1010 .Lrcls_retllong:
   1011         movl	-24(%ebp), %eax
   1012         movl	-20(%ebp), %edx
   1013         jmp	.Lrcls_epilogue
   1014 
   1015 .Lrcls_retstruct1:
   1016         movsbl	-24(%ebp), %eax
   1017         jmp	.Lrcls_epilogue
   1018 
   1019 .Lrcls_retstruct2:
   1020         movswl	-24(%ebp), %eax
   1021         jmp	.Lrcls_epilogue
   1022 
   1023 .Lrcls_retstruct4:
   1024         movl	-24(%ebp), %eax
   1025         jmp	.Lrcls_epilogue
   1026 
   1027 .Lrcls_retstruct:
   1028         # Nothing to do!
   1029 
   1030 .Lrcls_noretval:
   1031 .Lrcls_epilogue:
   1032         addl	$36, %esp
   1033         popl	%esi
   1034         popl	%ebp
   1035         ret
   1036 .ffi_closure_raw_SYSV_end:
   1037 .LFE4:
   1038 
   1039 #endif /* !FFI_NO_RAW_API */
   1040 
   1041         # This assumes we are using gas.
   1042         .balign	16
   1043 FFI_HIDDEN(ffi_closure_STDCALL)
   1044         .globl	USCORE_SYMBOL(ffi_closure_STDCALL)
   1045 #if defined(X86_WIN32) && !defined(__OS2__)
   1046         .def	_ffi_closure_STDCALL;	.scl	2;	.type	32;	.endef
   1047 #endif
   1048 USCORE_SYMBOL(ffi_closure_STDCALL):
   1049 .ffi_closure_STDCALL_internal:
   1050         /* ffi_closure ctx is at top of the stack */
   1051         movl	(%esp), %eax
   1052 .LFB5:
   1053         pushl	%ebp
   1054 .LCFI9:
   1055         movl	%esp, %ebp
   1056 .LCFI10:
   1057         subl	$40, %esp
   1058         leal	-24(%ebp), %edx
   1059         movl	%edx, -12(%ebp)	/* resp */
   1060         leal	12(%ebp), %edx  /* account for stub return address on stack */
   1061         movl	%edx, 4(%esp)	/* args */
   1062         leal	-12(%ebp), %edx
   1063         movl	%edx, (%esp)	/* &resp */
   1064 #if defined(HAVE_HIDDEN_VISIBILITY_ATTRIBUTE) || !defined(__PIC__)
   1065         call	USCORE_SYMBOL(ffi_closure_WIN32_inner)
   1066 #elif defined(X86_DARWIN)
   1067         calll	L_ffi_closure_WIN32_inner$stub
   1068 #else
   1069         movl	%ebx, 8(%esp)
   1070         call	1f
   1071 1:      popl	%ebx
   1072         addl	$_GLOBAL_OFFSET_TABLE_+[.-1b], %ebx
   1073         call	ffi_closure_WIN32_inner@PLT
   1074         movl	8(%esp), %ebx
   1075 #endif
   1076         movl	-12(%ebp), %ecx
   1077 0:
   1078         xchgl	4(%ebp), %eax /* xchg size of stack parameters and ffi_closure ctx */
   1079         movl	CLOSURE_CIF_OFFSET(%eax), %eax
   1080         movl	CIF_FLAGS_OFFSET(%eax), %eax
   1081 
   1082         call	1f
   1083         # Do not insert anything here between the call and the jump table.
   1084 .Lscls_store_table:
   1085         .long	.Lscls_noretval-.Lscls_store_table	/* FFI_TYPE_VOID */
   1086         .long	.Lscls_retint-.Lscls_store_table	/* FFI_TYPE_INT */
   1087         .long	.Lscls_retfloat-.Lscls_store_table	/* FFI_TYPE_FLOAT */
   1088         .long	.Lscls_retdouble-.Lscls_store_table	/* FFI_TYPE_DOUBLE */
   1089         .long	.Lscls_retldouble-.Lscls_store_table	/* FFI_TYPE_LONGDOUBLE */
   1090         .long	.Lscls_retuint8-.Lscls_store_table	/* FFI_TYPE_UINT8 */
   1091         .long	.Lscls_retsint8-.Lscls_store_table	/* FFI_TYPE_SINT8 */
   1092         .long	.Lscls_retuint16-.Lscls_store_table	/* FFI_TYPE_UINT16 */
   1093         .long	.Lscls_retsint16-.Lscls_store_table	/* FFI_TYPE_SINT16 */
   1094         .long	.Lscls_retint-.Lscls_store_table	/* FFI_TYPE_UINT32 */
   1095         .long	.Lscls_retint-.Lscls_store_table	/* FFI_TYPE_SINT32 */
   1096         .long	.Lscls_retllong-.Lscls_store_table	/* FFI_TYPE_UINT64 */
   1097         .long	.Lscls_retllong-.Lscls_store_table	/* FFI_TYPE_SINT64 */
   1098         .long	.Lscls_retstruct-.Lscls_store_table	/* FFI_TYPE_STRUCT */
   1099         .long	.Lscls_retint-.Lscls_store_table	/* FFI_TYPE_POINTER */
   1100         .long	.Lscls_retstruct1-.Lscls_store_table	/* FFI_TYPE_SMALL_STRUCT_1B */
   1101         .long	.Lscls_retstruct2-.Lscls_store_table	/* FFI_TYPE_SMALL_STRUCT_2B */
   1102         .long	.Lscls_retstruct4-.Lscls_store_table	/* FFI_TYPE_SMALL_STRUCT_4B */
   1103 1:
   1104         shl	$2, %eax
   1105         add	(%esp),%eax
   1106         mov	(%eax),%eax
   1107         add	(%esp),%eax
   1108         add	$4, %esp
   1109         jmp	*%eax
   1110 
   1111         /* Sign/zero extend as appropriate.  */
   1112 .Lscls_retsint8:
   1113         movsbl	(%ecx), %eax
   1114         jmp	.Lscls_epilogue
   1115 
   1116 .Lscls_retsint16:
   1117         movswl	(%ecx), %eax
   1118         jmp	.Lscls_epilogue
   1119 
   1120 .Lscls_retuint8:
   1121         movzbl	(%ecx), %eax
   1122         jmp	.Lscls_epilogue
   1123 
   1124 .Lscls_retuint16:
   1125         movzwl	(%ecx), %eax
   1126         jmp	.Lscls_epilogue
   1127 
   1128 .Lscls_retint:
   1129         movl	(%ecx), %eax
   1130         jmp	.Lscls_epilogue
   1131 
   1132 .Lscls_retfloat:
   1133         flds	(%ecx)
   1134         jmp	.Lscls_epilogue
   1135 
   1136 .Lscls_retdouble:
   1137         fldl	(%ecx)
   1138         jmp	.Lscls_epilogue
   1139 
   1140 .Lscls_retldouble:
   1141         fldt	(%ecx)
   1142         jmp	.Lscls_epilogue
   1143 
   1144 .Lscls_retllong:
   1145         movl	(%ecx), %eax
   1146         movl	4(%ecx), %edx
   1147         jmp	.Lscls_epilogue
   1148 
   1149 .Lscls_retstruct1:
   1150         movsbl	(%ecx), %eax
   1151         jmp	.Lscls_epilogue
   1152 
   1153 .Lscls_retstruct2:
   1154         movswl	(%ecx), %eax
   1155         jmp	.Lscls_epilogue
   1156 
   1157 .Lscls_retstruct4:
   1158         movl	(%ecx), %eax
   1159         jmp	.Lscls_epilogue
   1160 
   1161 .Lscls_retstruct:
   1162         # Nothing to do!
   1163 
   1164 .Lscls_noretval:
   1165 .Lscls_epilogue:
   1166         movl	%ebp, %esp
   1167         popl	%ebp
   1168         movl	4(%esp), %ecx /* Return address */
   1169         addl	(%esp), %esp  /* Parameters stack size */
   1170         addl	$8, %esp
   1171         jmp	*%ecx
   1172 .ffi_closure_STDCALL_end:
   1173 .LFE5:
   1174 
   1175 #if defined(X86_DARWIN)
   1176 .section __IMPORT,__jump_table,symbol_stubs,self_modifying_code+pure_instructions,5
   1177 L_ffi_closure_SYSV_inner$stub:
   1178         .indirect_symbol _ffi_closure_SYSV_inner
   1179         hlt ; hlt ; hlt ; hlt ; hlt
   1180 L_ffi_closure_WIN32_inner$stub:
   1181         .indirect_symbol _ffi_closure_WIN32_inner
   1182         hlt ; hlt ; hlt ; hlt ; hlt
   1183 #endif
   1184 
   1185 #if defined(X86_WIN32) && !defined(__OS2__)
   1186         .section	.eh_frame,"w"
   1187 #endif
   1188 .Lframe1:
   1189 .LSCIE1:
   1190         .long	.LECIE1-.LASCIE1  /* Length of Common Information Entry */
   1191 .LASCIE1:
   1192         .long	0x0	/* CIE Identifier Tag */
   1193         .byte	0x1	/* CIE Version */
   1194 #ifdef __PIC__
   1195         .ascii "zR\0"	/* CIE Augmentation */
   1196 #else
   1197         .ascii "\0"	/* CIE Augmentation */
   1198 #endif
   1199         .byte	0x1	/* .uleb128 0x1; CIE Code Alignment Factor */
   1200         .byte	0x7c	/* .sleb128 -4; CIE Data Alignment Factor */
   1201         .byte	0x8	/* CIE RA Column */
   1202 #ifdef __PIC__
   1203         .byte	0x1	/* .uleb128 0x1; Augmentation size */
   1204         .byte	0x1b	/* FDE Encoding (pcrel sdata4) */
   1205 #endif
   1206         .byte	0xc	/* DW_CFA_def_cfa CFA = r4 + 4 = 4(%esp) */
   1207         .byte	0x4	/* .uleb128 0x4 */
   1208         .byte	0x4	/* .uleb128 0x4 */
   1209         .byte	0x88	/* DW_CFA_offset, column 0x8 %eip at CFA + 1 * -4 */
   1210         .byte	0x1	/* .uleb128 0x1 */
   1211         .align 4
   1212 .LECIE1:
   1213 
   1214 .LSFDE1:
   1215         .long	.LEFDE1-.LASFDE1	/* FDE Length */
   1216 .LASFDE1:
   1217         .long	.LASFDE1-.Lframe1	/* FDE CIE offset */
   1218 #if defined __PIC__ && defined HAVE_AS_X86_PCREL
   1219         .long	.LFB1-.	/* FDE initial location */
   1220 #else
   1221         .long	.LFB1
   1222 #endif
   1223         .long	.LFE1-.LFB1	/* FDE address range */
   1224 #ifdef __PIC__
   1225         .byte	0x0	/* .uleb128 0x0; Augmentation size */
   1226 #endif
   1227         /* DW_CFA_xxx CFI instructions go here.  */
   1228 
   1229         .byte	0x4	/* DW_CFA_advance_loc4 */
   1230         .long	.LCFI0-.LFB1
   1231         .byte	0xe	/* DW_CFA_def_cfa_offset CFA = r4 + 8 = 8(%esp) */
   1232         .byte	0x8	/* .uleb128 0x8 */
   1233         .byte	0x85	/* DW_CFA_offset, column 0x5 %ebp at CFA + 2 * -4 */
   1234         .byte	0x2	/* .uleb128 0x2 */
   1235 
   1236         .byte	0x4	/* DW_CFA_advance_loc4 */
   1237         .long	.LCFI1-.LCFI0
   1238         .byte	0xd	/* DW_CFA_def_cfa_register CFA = r5 = %ebp */
   1239         .byte	0x5	/* .uleb128 0x5 */
   1240 
   1241         /* End of DW_CFA_xxx CFI instructions.  */
   1242         .align 4
   1243 .LEFDE1:
   1244 
   1245 .LSFDE3:
   1246         .long	.LEFDE3-.LASFDE3	/* FDE Length */
   1247 .LASFDE3:
   1248         .long	.LASFDE3-.Lframe1	/* FDE CIE offset */
   1249 #if defined __PIC__ && defined HAVE_AS_X86_PCREL
   1250         .long	.LFB3-.	/* FDE initial location */
   1251 #else
   1252         .long	.LFB3
   1253 #endif
   1254         .long	.LFE3-.LFB3	/* FDE address range */
   1255 #ifdef __PIC__
   1256         .byte	0x0	/* .uleb128 0x0; Augmentation size */
   1257 #endif
   1258         /* DW_CFA_xxx CFI instructions go here.  */
   1259 
   1260         .byte	0x4	/* DW_CFA_advance_loc4 */
   1261         .long	.LCFI4-.LFB3
   1262         .byte	0xe	/* DW_CFA_def_cfa_offset CFA = r4 + 8 = 8(%esp) */
   1263         .byte	0x8	/* .uleb128 0x8 */
   1264         .byte	0x85	/* DW_CFA_offset, column 0x5 %ebp at CFA + 2 * -4 */
   1265         .byte	0x2	/* .uleb128 0x2 */
   1266 
   1267         .byte	0x4	/* DW_CFA_advance_loc4 */
   1268         .long	.LCFI5-.LCFI4
   1269         .byte	0xd	/* DW_CFA_def_cfa_register CFA = r5 = %ebp */
   1270         .byte	0x5	/* .uleb128 0x5 */
   1271 
   1272         /* End of DW_CFA_xxx CFI instructions.  */
   1273         .align 4
   1274 .LEFDE3:
   1275 
   1276 #if !FFI_NO_RAW_API
   1277 
   1278 .LSFDE4:
   1279         .long	.LEFDE4-.LASFDE4	/* FDE Length */
   1280 .LASFDE4:
   1281         .long	.LASFDE4-.Lframe1	/* FDE CIE offset */
   1282 #if defined __PIC__ && defined HAVE_AS_X86_PCREL
   1283         .long	.LFB4-.	/* FDE initial location */
   1284 #else
   1285         .long	.LFB4
   1286 #endif
   1287         .long	.LFE4-.LFB4	/* FDE address range */
   1288 #ifdef __PIC__
   1289         .byte	0x0	/* .uleb128 0x0; Augmentation size */
   1290 #endif
   1291         /* DW_CFA_xxx CFI instructions go here.  */
   1292 
   1293         .byte	0x4	/* DW_CFA_advance_loc4 */
   1294         .long	.LCFI6-.LFB4
   1295         .byte	0xe	/* DW_CFA_def_cfa_offset CFA = r4 + 8 = 8(%esp) */
   1296         .byte	0x8	/* .uleb128 0x8 */
   1297         .byte	0x85	/* DW_CFA_offset, column 0x5 %ebp at CFA + 2 * -4 */
   1298         .byte	0x2	/* .uleb128 0x2 */
   1299 
   1300         .byte	0x4	/* DW_CFA_advance_loc4 */
   1301         .long	.LCFI7-.LCFI6
   1302         .byte	0xd	/* DW_CFA_def_cfa_register CFA = r5 = %ebp */
   1303         .byte	0x5	/* .uleb128 0x5 */
   1304 
   1305         .byte	0x4	/* DW_CFA_advance_loc4 */
   1306         .long	.LCFI8-.LCFI7
   1307         .byte	0x86	/* DW_CFA_offset, column 0x6 %esi at CFA + 3 * -4 */
   1308         .byte	0x3	/* .uleb128 0x3 */
   1309 
   1310         /* End of DW_CFA_xxx CFI instructions.  */
   1311         .align 4
   1312 .LEFDE4:
   1313 
   1314 #endif /* !FFI_NO_RAW_API */
   1315 
   1316 .LSFDE5:
   1317         .long	.LEFDE5-.LASFDE5	/* FDE Length */
   1318 .LASFDE5:
   1319         .long	.LASFDE5-.Lframe1	/* FDE CIE offset */
   1320 #if defined __PIC__ && defined HAVE_AS_X86_PCREL
   1321         .long	.LFB5-.	/* FDE initial location */
   1322 #else
   1323         .long	.LFB5
   1324 #endif
   1325         .long	.LFE5-.LFB5	/* FDE address range */
   1326 #ifdef __PIC__
   1327         .byte	0x0	/* .uleb128 0x0; Augmentation size */
   1328 #endif
   1329         /* DW_CFA_xxx CFI instructions go here.  */
   1330 
   1331         .byte	0x4	/* DW_CFA_advance_loc4 */
   1332         .long	.LCFI9-.LFB5
   1333         .byte	0xe	/* DW_CFA_def_cfa_offset CFA = r4 + 8 = 8(%esp) */
   1334         .byte	0x8	/* .uleb128 0x8 */
   1335         .byte	0x85	/* DW_CFA_offset, column 0x5 %ebp at CFA + 2 * -4 */
   1336         .byte	0x2	/* .uleb128 0x2 */
   1337 
   1338         .byte	0x4	/* DW_CFA_advance_loc4 */
   1339         .long	.LCFI10-.LCFI9
   1340         .byte	0xd	/* DW_CFA_def_cfa_register CFA = r5 = %ebp */
   1341         .byte	0x5	/* .uleb128 0x5 */
   1342 
   1343         /* End of DW_CFA_xxx CFI instructions.  */
   1344         .align 4
   1345 .LEFDE5:
   1346 
   1347 #endif /* !_MSC_VER */
   1348 
   1349 #if defined __ELF__ && defined __linux__
   1350         .section	.note.GNU-stack,"",@progbits
   1351 #endif
   1352