x86: Rewrite closures
authorRichard Henderson <rth@twiddle.net>
Wed, 5 Nov 2014 09:15:25 +0000 (10:15 +0100)
committerRichard Henderson <rth@twiddle.net>
Wed, 12 Nov 2014 08:15:54 +0000 (09:15 +0100)
Move everything into sysv.S, removing win32.S and freebsd.S.
Handle all abis with a single ffi_closure_inner function.
Move complexity of the raw THISCALL trampoline into assembly
instead of the trampoline itself.
Only push the context for the REGISTER abi; let the rest
receive it in a register.

Makefile.am
src/x86/ffi.c
src/x86/ffitarget.h
src/x86/freebsd.S [deleted file]
src/x86/sysv.S
src/x86/win32.S [deleted file]

index 3d1ecae..97a7bd3 100644 (file)
@@ -37,8 +37,8 @@ EXTRA_DIST = LICENSE ChangeLog.v1 ChangeLog.libgcj                    \
         src/sh64/sysv.S src/sh64/ffitarget.h src/sparc/v8.S            \
         src/sparc/v9.S src/sparc/ffitarget.h src/sparc/ffi.c           \
         src/x86/darwin64.S src/x86/ffi.c src/x86/sysv.S                \
-        src/x86/win32.S src/x86/darwin.S src/x86/ffiw64.c src/x86/win64.S \
-        src/x86/freebsd.S src/x86/ffi64.c src/x86/unix64.S             \
+        src/x86/darwin.S src/x86/ffiw64.c src/x86/win64.S              \
+        src/x86/ffi64.c src/x86/unix64.S                               \
         src/x86/ffitarget.h src/pa/ffitarget.h src/pa/ffi.c            \
         src/pa/linux.S src/pa/hpux32.S src/frv/ffi.c src/bfin/ffi.c    \
         src/bfin/ffitarget.h src/bfin/sysv.S src/frv/eabi.S            \
@@ -126,22 +126,19 @@ if BFIN
 nodist_libffi_la_SOURCES += src/bfin/ffi.c src/bfin/sysv.S
 endif
 if X86
-nodist_libffi_la_SOURCES += src/x86/ffi.c src/x86/sysv.S src/x86/win32.S
+nodist_libffi_la_SOURCES += src/x86/ffi.c src/x86/sysv.S
 endif
 if X86_FREEBSD
-nodist_libffi_la_SOURCES += src/x86/ffi.c src/x86/freebsd.S src/x86/win32.S
+nodist_libffi_la_SOURCES += src/x86/ffi.c src/x86/sysv.S
 endif
 if X86_WIN32
-nodist_libffi_la_SOURCES += src/x86/ffi.c src/x86/win32.S
+nodist_libffi_la_SOURCES += src/x86/ffi.c src/x86/sysv.S
 endif
 if X86_WIN64
 nodist_libffi_la_SOURCES += src/x86/ffiw64.c src/x86/win64.S
 endif
 if X86_DARWIN
 nodist_libffi_la_SOURCES += src/x86/ffi.c src/x86/darwin.S src/x86/ffi64.c src/x86/darwin64.S
-if X86_DARWIN32
-nodist_libffi_la_SOURCES += src/x86/win32.S
-endif
 endif
 if SPARC
 nodist_libffi_la_SOURCES += src/sparc/ffi.c src/sparc/v8.S src/sparc/v9.S
index 1c77bb8..40e47d2 100644 (file)
@@ -321,224 +321,105 @@ ffi_call (ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
 
 /** private members **/
 
-/* The following __attribute__((regparm(1))) decorations will have no effect
-   on MSVC or SUNPRO_C -- standard conventions apply. */
-static unsigned int ffi_prep_incoming_args (char *stack, void **ret,
-                                            void** args, ffi_cif* cif);
-void FFI_HIDDEN ffi_closure_SYSV (ffi_closure *)
-     __attribute__ ((regparm(1)));
-unsigned int FFI_HIDDEN ffi_closure_SYSV_inner (ffi_closure *, void **, void *)
-     __attribute__ ((regparm(1)));
-unsigned int FFI_HIDDEN ffi_closure_WIN32_inner (ffi_closure *, void **, void *)
-     __attribute__ ((regparm(1)));
-void FFI_HIDDEN ffi_closure_raw_SYSV (ffi_raw_closure *)
-     __attribute__ ((regparm(1)));
-#ifdef X86_WIN32
-void FFI_HIDDEN ffi_closure_raw_THISCALL (ffi_raw_closure *)
-     __attribute__ ((regparm(1)));
-#endif
-void FFI_HIDDEN ffi_closure_STDCALL (ffi_closure *);
-void FFI_HIDDEN ffi_closure_THISCALL (ffi_closure *);
-void FFI_HIDDEN ffi_closure_FASTCALL (ffi_closure *);
-void FFI_HIDDEN ffi_closure_REGISTER (ffi_closure *);
-
-/* This function is jumped to by the trampoline */
+void FFI_HIDDEN ffi_closure_i386(void);
+void FFI_HIDDEN ffi_closure_STDCALL(void);
+void FFI_HIDDEN ffi_closure_REGISTER(void);
 
-unsigned int FFI_HIDDEN __attribute__ ((regparm(1)))
-ffi_closure_SYSV_inner (ffi_closure *closure, void **respp, void *args)
+struct closure_frame
 {
-  /* our various things...  */
-  ffi_cif       *cif;
-  void         **arg_area;
-
-  cif         = closure->cif;
-  arg_area    = (void**) alloca (cif->nargs * sizeof (void*));  
-
-  /* this call will initialize ARG_AREA, such that each
-   * element in that array points to the corresponding 
-   * value on the stack; and if the function returns
-   * a structure, it will change RESP to point to the
-   * structure return address.  */
-
-  ffi_prep_incoming_args(args, respp, arg_area, cif);
-
-  (closure->fun) (cif, *respp, arg_area, closure->user_data);
-
-  return cif->flags;
-}
+  unsigned rettemp[4];                         /* 0 */
+  unsigned regs[3];                            /* 16-24 */
+  ffi_cif *cif;                                        /* 28 */
+  void (*fun)(ffi_cif*,void*,void**,void*);    /* 32 */
+  void *user_data;                             /* 36 */
+};
 
-unsigned int FFI_HIDDEN __attribute__ ((regparm(1)))
-ffi_closure_WIN32_inner (ffi_closure *closure, void **respp, void *args)
+int FFI_HIDDEN __declspec(fastcall)
+ffi_closure_inner (struct closure_frame *frame, char *stack)
 {
-  /* our various things...  */
-  ffi_cif       *cif;
-  void         **arg_area;
-  unsigned int   ret;
-
-  cif         = closure->cif;
-  arg_area    = (void**) alloca (cif->nargs * sizeof (void*));  
-
-  /* this call will initialize ARG_AREA, such that each
-   * element in that array points to the corresponding 
-   * value on the stack; and if the function returns
-   * a structure, it will change RESP to point to the
-   * structure return address.  */
-
-  ret = ffi_prep_incoming_args(args, respp, arg_area, cif);
-
-  (closure->fun) (cif, *respp, arg_area, closure->user_data);
-
-  return ret;
-}
+  ffi_cif *cif = frame->cif;
+  int cabi, i, n, flags, dir, narg_reg;
+  const struct abi_params *pabi;
+  ffi_type **arg_types;
+  char *argp;
+  void *rvalue;
+  void **avalue;
 
-static unsigned int
-ffi_prep_incoming_args(char *stack, void **rvalue, void **avalue,
-                       ffi_cif *cif)
-{
-  register unsigned int i;
-  register void **p_argv;
-  register char *argp;
-  register ffi_type **p_arg;
-  const int cabi = cif->abi;
-  const int dir = (cabi == FFI_PASCAL || cabi == FFI_REGISTER) ? -1 : +1;
-  const unsigned int max_stack_count = (cabi == FFI_THISCALL) ? 1
-                                     : (cabi == FFI_FASTCALL) ? 2
-                                     : (cabi == FFI_REGISTER) ? 3
-                                     : 0;
-  unsigned int passed_regs = 0;
-  void *p_stack_data[3] = { stack - 1 };
-
-  argp = stack;
-  argp += max_stack_count * FFI_SIZEOF_ARG;
-
-  if ((cif->flags == FFI_TYPE_STRUCT
-       || cif->flags == FFI_TYPE_MS_STRUCT))
-    {
-      if (passed_regs < max_stack_count)
-        {
-          *rvalue = *(void**) (stack + (passed_regs*FFI_SIZEOF_ARG));
-          ++passed_regs;
-        }
-      else
-        {
-          *rvalue = *(void **) argp;
-          argp += sizeof(void *);
-        }
-    }
+  cabi = cif->abi;
+  flags = cif->flags;
+  narg_reg = 0;
+  rvalue = frame->rettemp;
+  pabi = &abi_params[cabi];
+  dir = pabi->dir;
+  argp = (dir < 0 ? stack + cif->bytes : stack);
 
-  /* Do register arguments first  */
-  for (i = 0, p_arg = cif->arg_types; 
-       i < cif->nargs && passed_regs < max_stack_count;
-       i++, p_arg++)
+  switch (flags)
     {
-      if ((*p_arg)->type == FFI_TYPE_FLOAT
-         || (*p_arg)->type == FFI_TYPE_STRUCT)
-        continue;
-
-      size_t sz = (*p_arg)->size;
-      if(sz == 0 || sz > FFI_SIZEOF_ARG)
-        continue;
-
-      p_stack_data[passed_regs] = avalue + i;
-      avalue[i] = stack + (passed_regs*FFI_SIZEOF_ARG);
-      ++passed_regs;
+    case X86_RET_STRUCTARG:
+      if (pabi->nregs > 0)
+       {
+         rvalue = (void *)frame->regs[pabi->regs[0]];
+         narg_reg = 1;
+         frame->rettemp[0] = (unsigned)rvalue;
+         break;
+       }
+      /* fallthru */
+    case X86_RET_STRUCTPOP:
+      rvalue = *(void **)argp;
+      argp += sizeof(void *);
+      break;
     }
 
-  p_arg = cif->arg_types;
-  p_argv = avalue;
-  if (dir < 0)
-    {
-      const int nargs = cif->nargs - 1;
-      if (nargs > 0)
-      {
-        p_arg  += nargs;
-        p_argv += nargs;
-      }
-    }
+  n = cif->nargs;
+  avalue = alloca(sizeof(void *) * n);
 
-  for (i = cif->nargs;
-       i != 0;
-       i--, p_arg += dir, p_argv += dir)
+  arg_types = cif->arg_types;
+  for (i = 0; i < n; ++i)
     {
-      /* Align if necessary */
-      if ((sizeof(void*) - 1) & (size_t) argp)
-        argp = (char *) ALIGN(argp, sizeof(void*));
-
-      size_t z = (*p_arg)->size;
+      size_t z = arg_types[i]->size;
+      int t = arg_types[i]->type;
+      void *valp;
 
-      if (passed_regs > 0
-          && z <= FFI_SIZEOF_ARG
-          && (p_argv == p_stack_data[0]
-            || p_argv == p_stack_data[1]
-            || p_argv == p_stack_data[2]))
-        {
-          /* Already assigned a register value */
-          continue;
-        }
+      if (z <= FFI_SIZEOF_ARG && t != FFI_TYPE_STRUCT)
+       {
+         if (t != FFI_TYPE_FLOAT && narg_reg < pabi->nregs)
+           valp = &frame->regs[pabi->regs[narg_reg++]];
+         else if (dir < 0)
+           {
+             argp -= 4;
+             valp = argp;
+           }
+         else
+           {
+             valp = argp;
+             argp += 4;
+           }
+       }
       else
-        {
-          /* because we're little endian, this is what it turns into.   */
-          *p_argv = (void*) argp;
-        }
+       {
+         size_t za = ALIGN (z, FFI_SIZEOF_ARG);
+         if (dir < 0)
+           {
+             argp -= za;
+             valp = argp;
+           }
+         else
+           {
+             valp = argp;
+             argp += za;
+           }
+       }
 
-      argp += z;
+      avalue[i] = valp;
     }
 
-  return (size_t)argp - (size_t)stack;
-}
+  frame->fun (cif, rvalue, avalue, frame->user_data);
 
-/* How to make a trampoline.  Derived from gcc/config/i386/i386.c. */
-
-#define FFI_INIT_TRAMPOLINE(TRAMP,FUN,CTX) \
-{ unsigned char *__tramp = (unsigned char*)(TRAMP); \
-   unsigned int  __fun = (unsigned int)(FUN); \
-   unsigned int  __ctx = (unsigned int)(CTX); \
-   unsigned int  __dis = __fun - (__ctx + 10);  \
-   *(unsigned char*) &__tramp[0] = 0xb8; \
-   *(unsigned int*)  &__tramp[1] = __ctx; /* movl __ctx, %eax */ \
-   *(unsigned char*) &__tramp[5] = 0xe9; \
-   *(unsigned int*)  &__tramp[6] = __dis; /* jmp __fun  */ \
- }
-
-#define FFI_INIT_TRAMPOLINE_RAW_THISCALL(TRAMP,FUN,CTX,SIZE) \
-{ unsigned char *__tramp = (unsigned char*)(TRAMP); \
-   unsigned int  __fun = (unsigned int)(FUN); \
-   unsigned int  __ctx = (unsigned int)(CTX); \
-   unsigned int  __dis = __fun - (__ctx + 49);  \
-   unsigned short __size = (unsigned short)(SIZE); \
-   *(unsigned int *) &__tramp[0] = 0x8324048b;      /* mov (%esp), %eax */ \
-   *(unsigned int *) &__tramp[4] = 0x4c890cec;      /* sub $12, %esp */ \
-   *(unsigned int *) &__tramp[8] = 0x04890424;      /* mov %ecx, 4(%esp) */ \
-   *(unsigned char*) &__tramp[12] = 0x24;           /* mov %eax, (%esp) */ \
-   *(unsigned char*) &__tramp[13] = 0xb8; \
-   *(unsigned int *) &__tramp[14] = __size;         /* mov __size, %eax */ \
-   *(unsigned int *) &__tramp[18] = 0x08244c8d;     /* lea 8(%esp), %ecx */ \
-   *(unsigned int *) &__tramp[22] = 0x4802e8c1;     /* shr $2, %eax ; dec %eax */ \
-   *(unsigned short*) &__tramp[26] = 0x0b74;        /* jz 1f */ \
-   *(unsigned int *) &__tramp[28] = 0x8908518b;     /* 2b: mov 8(%ecx), %edx */ \
-   *(unsigned int *) &__tramp[32] = 0x04c18311;     /* mov %edx, (%ecx) ; add $4, %ecx */ \
-   *(unsigned char*) &__tramp[36] = 0x48;           /* dec %eax */ \
-   *(unsigned short*) &__tramp[37] = 0xf575;        /* jnz 2b ; 1f: */ \
-   *(unsigned char*) &__tramp[39] = 0xb8; \
-   *(unsigned int*)  &__tramp[40] = __ctx;          /* movl __ctx, %eax */ \
-   *(unsigned char *)  &__tramp[44] = 0xe8; \
-   *(unsigned int*)  &__tramp[45] = __dis;          /* call __fun  */ \
-   *(unsigned char*)  &__tramp[49] = 0xc2;          /* ret  */ \
-   *(unsigned short*)  &__tramp[50] = (__size + 8); /* ret (__size + 8)  */ \
- }
-
-#define FFI_INIT_TRAMPOLINE_WIN32(TRAMP,FUN,CTX)  \
-{ unsigned char *__tramp = (unsigned char*)(TRAMP); \
-   unsigned int  __fun = (unsigned int)(FUN); \
-   unsigned int  __ctx = (unsigned int)(CTX); \
-   unsigned int  __dis = __fun - (__ctx + 10); \
-   *(unsigned char*) &__tramp[0] = 0x68; \
-   *(unsigned int*)  &__tramp[1] = __ctx; /* push __ctx */ \
-   *(unsigned char*) &__tramp[5] = 0xe9; \
-   *(unsigned int*)  &__tramp[6] = __dis; /* jmp __fun  */ \
- }
-
-/* the cif must already be prep'ed */
+  if (cabi == FFI_STDCALL)
+    return flags + (cif->bytes << X86_RET_POP_SHIFT);
+  else
+    return flags;
+}
 
 ffi_status
 ffi_prep_closure_loc (ffi_closure* closure,
@@ -547,50 +428,40 @@ ffi_prep_closure_loc (ffi_closure* closure,
                       void *user_data,
                       void *codeloc)
 {
-  if (cif->abi == FFI_SYSV)
-    {
-      FFI_INIT_TRAMPOLINE (&closure->tramp[0],
-                           &ffi_closure_SYSV,
-                           (void*)codeloc);
-    }
-  else if (cif->abi == FFI_REGISTER)
-    {
-      FFI_INIT_TRAMPOLINE_WIN32 (&closure->tramp[0],
-                                   &ffi_closure_REGISTER,
-                                   (void*)codeloc);
-    }
-  else if (cif->abi == FFI_FASTCALL)
-    {
-      FFI_INIT_TRAMPOLINE_WIN32 (&closure->tramp[0],
-                                   &ffi_closure_FASTCALL,
-                                   (void*)codeloc);
-    }
-  else if (cif->abi == FFI_THISCALL)
-    {
-      FFI_INIT_TRAMPOLINE_WIN32 (&closure->tramp[0],
-                                   &ffi_closure_THISCALL,
-                                   (void*)codeloc);
-    }
-  else if (cif->abi == FFI_STDCALL || cif->abi == FFI_PASCAL)
-    {
-      FFI_INIT_TRAMPOLINE_WIN32 (&closure->tramp[0],
-                                   &ffi_closure_STDCALL,
-                                   (void*)codeloc);
-    }
-  else if (cif->abi == FFI_MS_CDECL)
-    {
-      FFI_INIT_TRAMPOLINE (&closure->tramp[0],
-                           &ffi_closure_SYSV,
-                           (void*)codeloc);
-    }
-  else
+  char *tramp = closure->tramp;
+  void (*dest)(void);
+  int op = 0xb8;  /* movl imm, %eax */
+
+  switch (cif->abi)
     {
+    case FFI_SYSV:
+    case FFI_THISCALL:
+    case FFI_FASTCALL:
+    case FFI_MS_CDECL:
+      dest = ffi_closure_i386;
+      break;
+    case FFI_STDCALL:
+    case FFI_PASCAL:
+      dest = ffi_closure_STDCALL;
+      break;
+    case FFI_REGISTER:
+      dest = ffi_closure_REGISTER;
+      op = 0x68;  /* pushl imm */
+    default:
       return FFI_BAD_ABI;
     }
-    
-  closure->cif  = cif;
+
+  /* movl or pushl immediate.  */
+  tramp[0] = op;
+  *(void **)(tramp + 1) = codeloc;
+
+  /* jmp dest */
+  tramp[5] = 0xe9;
+  *(unsigned *)(tramp + 6) = (unsigned)dest - ((unsigned)codeloc + 10);
+
+  closure->cif = cif;
+  closure->fun = fun;
   closure->user_data = user_data;
-  closure->fun  = fun;
 
   return FFI_OK;
 }
@@ -599,13 +470,18 @@ ffi_prep_closure_loc (ffi_closure* closure,
 
 #if !FFI_NO_RAW_API
 
+void FFI_HIDDEN ffi_closure_raw_SYSV(void);
+void FFI_HIDDEN ffi_closure_raw_THISCALL(void);
+
 ffi_status
-ffi_prep_raw_closure_loc (ffi_raw_closureclosure,
-                          ffi_cifcif,
+ffi_prep_raw_closure_loc (ffi_raw_closure *closure,
+                          ffi_cif *cif,
                           void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
                           void *user_data,
                           void *codeloc)
 {
+  char *tramp = closure->tramp;
+  void (*dest)(void);
   int i;
 
   /* We currently don't support certain kinds of arguments for raw
@@ -613,28 +489,33 @@ ffi_prep_raw_closure_loc (ffi_raw_closure* closure,
      language routine, since it would require argument processing,
      something we don't do now for performance.  */
   for (i = cif->nargs-1; i >= 0; i--)
-    {
-      FFI_ASSERT (cif->arg_types[i]->type != FFI_TYPE_STRUCT);
-      FFI_ASSERT (cif->arg_types[i]->type != FFI_TYPE_LONGDOUBLE);
-    }
+    switch (cif->arg_types[i]->type)
+      {
+      case FFI_TYPE_STRUCT:
+      case FFI_TYPE_LONGDOUBLE:
+       return FFI_BAD_TYPEDEF;
+      }
 
   switch (cif->abi)
     {
-#ifdef X86_WIN32
     case FFI_THISCALL:
-      FFI_INIT_TRAMPOLINE_RAW_THISCALL (&closure->tramp[0],
-                                       &ffi_closure_raw_THISCALL,
-                                       codeloc, cif->bytes);
+      dest = ffi_closure_raw_THISCALL;
       break;
-#endif
     case FFI_SYSV:
-      FFI_INIT_TRAMPOLINE (&closure->tramp[0], &ffi_closure_raw_SYSV,
-                          codeloc);
+      dest = ffi_closure_raw_SYSV;
       break;
     default:
       return FFI_BAD_ABI;
     }
 
+  /* movl imm, %eax.  */
+  tramp[0] = 0xb8;
+  *(void **)(tramp + 1) = codeloc;
+
+  /* jmp dest */
+  tramp[5] = 0xe9;
+  *(unsigned *)(tramp + 6) = (unsigned)dest - ((unsigned)codeloc + 10);
+
   closure->cif = cif;
   closure->fun = fun;
   closure->user_data = user_data;
index 91e429c..8fff29f 100644 (file)
@@ -129,11 +129,7 @@ typedef enum ffi_abi {
 # define FFI_NATIVE_RAW_API 0
 # define FFI_GO_CLOSURES 1
 #else
-# ifdef X86_WIN32
-#  define FFI_TRAMPOLINE_SIZE 52
-# else
-#  define FFI_TRAMPOLINE_SIZE 10
-# endif
+# define FFI_TRAMPOLINE_SIZE 12
 # define FFI_NATIVE_RAW_API 1  /* x86 has native raw api support */
 #endif
 
diff --git a/src/x86/freebsd.S b/src/x86/freebsd.S
deleted file mode 100644 (file)
index 97e0b4e..0000000
+++ /dev/null
@@ -1,463 +0,0 @@
-/* -----------------------------------------------------------------------
-   freebsd.S - Copyright (c) 1996, 1998, 2001, 2002, 2003, 2005  Red Hat, Inc.
-              Copyright (c) 2008  Björn König
-       
-   X86 Foreign Function Interface for FreeBSD
-
-   Permission is hereby granted, free of charge, to any person obtaining
-   a copy of this software and associated documentation files (the
-   ``Software''), to deal in the Software without restriction, including
-   without limitation the rights to use, copy, modify, merge, publish,
-   distribute, sublicense, and/or sell copies of the Software, and to
-   permit persons to whom the Software is furnished to do so, subject to
-   the following conditions:
-
-   The above copyright notice and this permission notice shall be included
-   in all copies or substantial portions of the Software.
-
-   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
-   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-   DEALINGS IN THE SOFTWARE.
------------------------------------------------------------------------ */
-
-#ifndef __x86_64__
-
-#define LIBFFI_ASM     
-#include <fficonfig.h>
-#include <ffi.h>
-
-.text
-
-.globl ffi_prep_args
-
-       .align 4
-.globl ffi_call_SYSV
-        .type    ffi_call_SYSV,@function
-
-ffi_call_SYSV:
-.LFB1:
-        pushl %ebp
-.LCFI0:
-        movl  %esp,%ebp
-.LCFI1:
-       /* Make room for all of the new args.  */
-       movl  16(%ebp),%ecx
-       subl  %ecx,%esp
-
-       /* Align the stack pointer to 16-bytes */
-       andl  $0xfffffff0, %esp
-
-       movl  %esp,%eax
-
-       /* Place all of the ffi_prep_args in position  */
-       pushl 12(%ebp)
-       pushl %eax
-       call  *8(%ebp)
-
-       /* Return stack to previous state and call the function  */
-       addl  $8,%esp   
-
-       call  *28(%ebp)
-
-       /* Load %ecx with the return type code  */
-       movl  20(%ebp),%ecx     
-
-       /* Protect %esi.  We're going to pop it in the epilogue.  */
-       pushl %esi
-
-       /* If the return value pointer is NULL, assume no return value.  */
-       cmpl  $0,24(%ebp)
-       jne  0f
-
-       /* Even if there is no space for the return value, we are 
-          obliged to handle floating-point values.  */
-       cmpl  $FFI_TYPE_FLOAT,%ecx
-       jne   noretval
-       fstp  %st(0)
-
-        jmp   epilogue
-
-0:
-       call  1f
-
-.Lstore_table:
-       .long   noretval-.Lstore_table  /* FFI_TYPE_VOID */
-       .long   retint-.Lstore_table    /* FFI_TYPE_INT */
-       .long   retfloat-.Lstore_table  /* FFI_TYPE_FLOAT */
-       .long   retdouble-.Lstore_table /* FFI_TYPE_DOUBLE */
-       .long   retlongdouble-.Lstore_table     /* FFI_TYPE_LONGDOUBLE */
-       .long   retuint8-.Lstore_table  /* FFI_TYPE_UINT8 */
-       .long   retsint8-.Lstore_table  /* FFI_TYPE_SINT8 */
-       .long   retuint16-.Lstore_table /* FFI_TYPE_UINT16 */
-       .long   retsint16-.Lstore_table /* FFI_TYPE_SINT16 */
-       .long   retint-.Lstore_table    /* FFI_TYPE_UINT32 */
-       .long   retint-.Lstore_table    /* FFI_TYPE_SINT32 */
-       .long   retint64-.Lstore_table  /* FFI_TYPE_UINT64 */
-       .long   retint64-.Lstore_table  /* FFI_TYPE_SINT64 */
-       .long   retstruct-.Lstore_table /* FFI_TYPE_STRUCT */
-       .long   retint-.Lstore_table    /* FFI_TYPE_POINTER */
-       .long   retstruct1b-.Lstore_table       /* FFI_TYPE_SMALL_STRUCT_1B */
-       .long   retstruct2b-.Lstore_table       /* FFI_TYPE_SMALL_STRUCT_2B */
-
-1:
-       pop  %esi
-       add  (%esi, %ecx, 4), %esi
-       jmp  *%esi
-
-       /* Sign/zero extend as appropriate.  */
-retsint8:
-       movsbl  %al, %eax
-       jmp  retint
-
-retsint16:
-       movswl  %ax, %eax
-       jmp  retint
-
-retuint8:
-       movzbl  %al, %eax
-       jmp  retint
-
-retuint16:
-       movzwl  %ax, %eax
-       jmp  retint
-
-retfloat:
-       /* Load %ecx with the pointer to storage for the return value  */
-       movl  24(%ebp),%ecx     
-       fstps (%ecx)
-       jmp   epilogue
-
-retdouble:
-       /* Load %ecx with the pointer to storage for the return value  */
-       movl  24(%ebp),%ecx     
-       fstpl (%ecx)
-       jmp   epilogue
-
-retlongdouble:
-       /* Load %ecx with the pointer to storage for the return value  */
-       movl  24(%ebp),%ecx     
-       fstpt (%ecx)
-       jmp   epilogue
-       
-retint64:      
-       /* Load %ecx with the pointer to storage for the return value  */
-       movl  24(%ebp),%ecx     
-       movl  %eax,0(%ecx)
-       movl  %edx,4(%ecx)
-       jmp   epilogue
-       
-retstruct1b:
-       /* Load %ecx with the pointer to storage for the return value  */
-       movl  24(%ebp),%ecx
-       movb  %al,0(%ecx)
-       jmp   epilogue
-
-retstruct2b:
-       /* Load %ecx with the pointer to storage for the return value  */
-       movl  24(%ebp),%ecx
-       movw  %ax,0(%ecx)
-       jmp   epilogue
-
-retint:
-       /* Load %ecx with the pointer to storage for the return value  */
-       movl  24(%ebp),%ecx     
-       movl  %eax,0(%ecx)
-
-retstruct:
-       /* Nothing to do!  */
-
-noretval:
-epilogue:
-        popl %esi
-        movl %ebp,%esp
-        popl %ebp
-        ret
-.LFE1:
-.ffi_call_SYSV_end:
-        .size    ffi_call_SYSV,.ffi_call_SYSV_end-ffi_call_SYSV
-
-       .align  4
-FFI_HIDDEN (ffi_closure_SYSV)
-.globl ffi_closure_SYSV
-       .type   ffi_closure_SYSV, @function
-
-ffi_closure_SYSV:
-.LFB2:
-       pushl   %ebp
-.LCFI2:
-       movl    %esp, %ebp
-.LCFI3:
-       subl    $40, %esp
-       leal    -24(%ebp), %edx
-       movl    %edx, -12(%ebp) /* resp */
-       leal    8(%ebp), %edx
-       movl    %edx, 4(%esp)   /* args = __builtin_dwarf_cfa () */
-       leal    -12(%ebp), %edx
-       movl    %edx, (%esp)    /* &resp */
-#if defined HAVE_HIDDEN_VISIBILITY_ATTRIBUTE || !defined __PIC__
-       call    ffi_closure_SYSV_inner
-#else
-       movl    %ebx, 8(%esp)
-.LCFI7:
-       call    1f
-1:     popl    %ebx
-       addl    $_GLOBAL_OFFSET_TABLE_+[.-1b], %ebx
-       call    ffi_closure_SYSV_inner@PLT
-       movl    8(%esp), %ebx
-#endif
-       movl    -12(%ebp), %ecx
-       cmpl    $FFI_TYPE_INT, %eax
-       je      .Lcls_retint
-
-       /* Handle FFI_TYPE_UINT8, FFI_TYPE_SINT8, FFI_TYPE_UINT16,
-          FFI_TYPE_SINT16, FFI_TYPE_UINT32, FFI_TYPE_SINT32.  */
-       cmpl    $FFI_TYPE_UINT64, %eax
-       jge     0f
-       cmpl    $FFI_TYPE_UINT8, %eax
-       jge     .Lcls_retint
-       
-0:     cmpl    $FFI_TYPE_FLOAT, %eax
-       je      .Lcls_retfloat
-       cmpl    $FFI_TYPE_DOUBLE, %eax
-       je      .Lcls_retdouble
-       cmpl    $FFI_TYPE_LONGDOUBLE, %eax
-       je      .Lcls_retldouble
-       cmpl    $FFI_TYPE_SINT64, %eax
-       je      .Lcls_retllong
-       cmpl    $FFI_TYPE_SMALL_STRUCT_1B, %eax
-       je      .Lcls_retstruct1b
-       cmpl    $FFI_TYPE_SMALL_STRUCT_2B, %eax
-       je      .Lcls_retstruct2b
-       cmpl    $FFI_TYPE_STRUCT, %eax
-       je      .Lcls_retstruct
-.Lcls_epilogue:
-       movl    %ebp, %esp
-       popl    %ebp
-       ret
-.Lcls_retint:
-       movl    (%ecx), %eax
-       jmp     .Lcls_epilogue
-.Lcls_retfloat:
-       flds    (%ecx)
-       jmp     .Lcls_epilogue
-.Lcls_retdouble:
-       fldl    (%ecx)
-       jmp     .Lcls_epilogue
-.Lcls_retldouble:
-       fldt    (%ecx)
-       jmp     .Lcls_epilogue
-.Lcls_retllong:
-       movl    (%ecx), %eax
-       movl    4(%ecx), %edx
-       jmp     .Lcls_epilogue
-.Lcls_retstruct1b:
-       movsbl  (%ecx), %eax
-       jmp     .Lcls_epilogue
-.Lcls_retstruct2b:
-       movswl  (%ecx), %eax
-       jmp     .Lcls_epilogue
-.Lcls_retstruct:
-       movl    %ebp, %esp
-       popl    %ebp
-       ret     $4
-.LFE2:
-       .size   ffi_closure_SYSV, .-ffi_closure_SYSV
-
-#if !FFI_NO_RAW_API
-
-#define RAW_CLOSURE_CIF_OFFSET ((FFI_TRAMPOLINE_SIZE + 3) & ~3)
-#define RAW_CLOSURE_FUN_OFFSET (RAW_CLOSURE_CIF_OFFSET + 4)
-#define RAW_CLOSURE_USER_DATA_OFFSET (RAW_CLOSURE_FUN_OFFSET + 4)
-#define CIF_FLAGS_OFFSET 20
-
-       .align  4
-FFI_HIDDEN (ffi_closure_raw_SYSV)
-.globl ffi_closure_raw_SYSV
-       .type   ffi_closure_raw_SYSV, @function
-
-ffi_closure_raw_SYSV:
-.LFB3:
-       pushl   %ebp
-.LCFI4:
-       movl    %esp, %ebp
-.LCFI5:
-       pushl   %esi
-.LCFI6:
-       subl    $36, %esp
-       movl    RAW_CLOSURE_CIF_OFFSET(%eax), %esi       /* closure->cif */
-       movl    RAW_CLOSURE_USER_DATA_OFFSET(%eax), %edx /* closure->user_data */
-       movl    %edx, 12(%esp)  /* user_data */
-       leal    8(%ebp), %edx   /* __builtin_dwarf_cfa () */
-       movl    %edx, 8(%esp)   /* raw_args */
-       leal    -24(%ebp), %edx
-       movl    %edx, 4(%esp)   /* &res */
-       movl    %esi, (%esp)    /* cif */
-       call    *RAW_CLOSURE_FUN_OFFSET(%eax)            /* closure->fun */
-       movl    CIF_FLAGS_OFFSET(%esi), %eax             /* rtype */
-       cmpl    $FFI_TYPE_INT, %eax
-       je      .Lrcls_retint
-
-       /* Handle FFI_TYPE_UINT8, FFI_TYPE_SINT8, FFI_TYPE_UINT16,
-          FFI_TYPE_SINT16, FFI_TYPE_UINT32, FFI_TYPE_SINT32.  */
-       cmpl    $FFI_TYPE_UINT64, %eax
-       jge     0f
-       cmpl    $FFI_TYPE_UINT8, %eax
-       jge     .Lrcls_retint
-0:
-       cmpl    $FFI_TYPE_FLOAT, %eax
-       je      .Lrcls_retfloat
-       cmpl    $FFI_TYPE_DOUBLE, %eax
-       je      .Lrcls_retdouble
-       cmpl    $FFI_TYPE_LONGDOUBLE, %eax
-       je      .Lrcls_retldouble
-       cmpl    $FFI_TYPE_SINT64, %eax
-       je      .Lrcls_retllong
-.Lrcls_epilogue:
-       addl    $36, %esp
-       popl    %esi
-       popl    %ebp
-       ret
-.Lrcls_retint:
-       movl    -24(%ebp), %eax
-       jmp     .Lrcls_epilogue
-.Lrcls_retfloat:
-       flds    -24(%ebp)
-       jmp     .Lrcls_epilogue
-.Lrcls_retdouble:
-       fldl    -24(%ebp)
-       jmp     .Lrcls_epilogue
-.Lrcls_retldouble:
-       fldt    -24(%ebp)
-       jmp     .Lrcls_epilogue
-.Lrcls_retllong:
-       movl    -24(%ebp), %eax
-       movl    -20(%ebp), %edx
-       jmp     .Lrcls_epilogue
-.LFE3:
-       .size   ffi_closure_raw_SYSV, .-ffi_closure_raw_SYSV
-#endif
-
-       .section        .eh_frame,EH_FRAME_FLAGS,@progbits
-.Lframe1:
-       .long   .LECIE1-.LSCIE1 /* Length of Common Information Entry */
-.LSCIE1:
-       .long   0x0     /* CIE Identifier Tag */
-       .byte   0x1     /* CIE Version */
-#ifdef __PIC__
-       .ascii "zR\0"   /* CIE Augmentation */
-#else
-       .ascii "\0"     /* CIE Augmentation */
-#endif
-       .byte   0x1     /* .uleb128 0x1; CIE Code Alignment Factor */
-       .byte   0x7c    /* .sleb128 -4; CIE Data Alignment Factor */
-       .byte   0x8     /* CIE RA Column */
-#ifdef __PIC__
-       .byte   0x1     /* .uleb128 0x1; Augmentation size */
-       .byte   0x1b    /* FDE Encoding (pcrel sdata4) */
-#endif
-       .byte   0xc     /* DW_CFA_def_cfa */
-       .byte   0x4     /* .uleb128 0x4 */
-       .byte   0x4     /* .uleb128 0x4 */
-       .byte   0x88    /* DW_CFA_offset, column 0x8 */
-       .byte   0x1     /* .uleb128 0x1 */
-       .align 4
-.LECIE1:
-.LSFDE1:
-       .long   .LEFDE1-.LASFDE1        /* FDE Length */
-.LASFDE1:
-       .long   .LASFDE1-.Lframe1       /* FDE CIE offset */
-#ifdef __PIC__
-       .long   .LFB1-. /* FDE initial location */
-#else
-       .long   .LFB1   /* FDE initial location */
-#endif
-       .long   .LFE1-.LFB1     /* FDE address range */
-#ifdef __PIC__
-       .byte   0x0     /* .uleb128 0x0; Augmentation size */
-#endif
-       .byte   0x4     /* DW_CFA_advance_loc4 */
-       .long   .LCFI0-.LFB1
-       .byte   0xe     /* DW_CFA_def_cfa_offset */
-       .byte   0x8     /* .uleb128 0x8 */
-       .byte   0x85    /* DW_CFA_offset, column 0x5 */
-       .byte   0x2     /* .uleb128 0x2 */
-       .byte   0x4     /* DW_CFA_advance_loc4 */
-       .long   .LCFI1-.LCFI0
-       .byte   0xd     /* DW_CFA_def_cfa_register */
-       .byte   0x5     /* .uleb128 0x5 */
-       .align 4
-.LEFDE1:
-.LSFDE2:
-       .long   .LEFDE2-.LASFDE2        /* FDE Length */
-.LASFDE2:
-       .long   .LASFDE2-.Lframe1       /* FDE CIE offset */
-#ifdef __PIC__
-       .long   .LFB2-. /* FDE initial location */
-#else
-       .long   .LFB2
-#endif
-       .long   .LFE2-.LFB2     /* FDE address range */
-#ifdef __PIC__
-       .byte   0x0     /* .uleb128 0x0; Augmentation size */
-#endif
-       .byte   0x4     /* DW_CFA_advance_loc4 */
-       .long   .LCFI2-.LFB2
-       .byte   0xe     /* DW_CFA_def_cfa_offset */
-       .byte   0x8     /* .uleb128 0x8 */
-       .byte   0x85    /* DW_CFA_offset, column 0x5 */
-       .byte   0x2     /* .uleb128 0x2 */
-       .byte   0x4     /* DW_CFA_advance_loc4 */
-       .long   .LCFI3-.LCFI2
-       .byte   0xd     /* DW_CFA_def_cfa_register */
-       .byte   0x5     /* .uleb128 0x5 */
-#if !defined HAVE_HIDDEN_VISIBILITY_ATTRIBUTE && defined __PIC__
-       .byte   0x4     /* DW_CFA_advance_loc4 */
-       .long   .LCFI7-.LCFI3
-       .byte   0x83    /* DW_CFA_offset, column 0x3 */
-       .byte   0xa     /* .uleb128 0xa */
-#endif
-       .align 4
-.LEFDE2:
-
-#if !FFI_NO_RAW_API
-
-.LSFDE3:
-       .long   .LEFDE3-.LASFDE3        /* FDE Length */
-.LASFDE3:
-       .long   .LASFDE3-.Lframe1       /* FDE CIE offset */
-#ifdef __PIC__
-       .long   .LFB3-. /* FDE initial location */
-#else
-       .long   .LFB3
-#endif
-       .long   .LFE3-.LFB3     /* FDE address range */
-#ifdef __PIC__
-       .byte   0x0     /* .uleb128 0x0; Augmentation size */
-#endif
-       .byte   0x4     /* DW_CFA_advance_loc4 */
-       .long   .LCFI4-.LFB3
-       .byte   0xe     /* DW_CFA_def_cfa_offset */
-       .byte   0x8     /* .uleb128 0x8 */
-       .byte   0x85    /* DW_CFA_offset, column 0x5 */
-       .byte   0x2     /* .uleb128 0x2 */
-       .byte   0x4     /* DW_CFA_advance_loc4 */
-       .long   .LCFI5-.LCFI4
-       .byte   0xd     /* DW_CFA_def_cfa_register */
-       .byte   0x5     /* .uleb128 0x5 */
-       .byte   0x4     /* DW_CFA_advance_loc4 */
-       .long   .LCFI6-.LCFI5
-       .byte   0x86    /* DW_CFA_offset, column 0x6 */
-       .byte   0x3     /* .uleb128 0x3 */
-       .align 4
-.LEFDE3:
-
-#endif
-
-#endif /* ifndef __x86_64__ */
-
-       .section .note.GNU-stack,"",%progbits
index d0b8417..7b898ae 100644 (file)
 
 /* This is declared as
 
-   void ffi_call_i386(struct ffi_call_frame *frame, char *argp)
+   void ffi_call_i386(struct call_frame *frame, char *argp)
         __attribute__((fastcall));
 
-   This the arguments are present in
+   Thus the arguments are present in
 
         ecx: frame
         edx: argp
@@ -170,181 +170,478 @@ E(X86_RET_UNUSED15)
        cfi_endproc
 ENDF(C(ffi_call_i386))
 
-       .align  4
-FFI_HIDDEN (ffi_closure_SYSV)
-.globl ffi_closure_SYSV
-       .type   ffi_closure_SYSV, @function
+/* The inner helper is declared as
 
-ffi_closure_SYSV:
-       cfi_startproc
-       pushl   %ebp
-       cfi_adjust_cfa_offset(4)
-       cfi_rel_offset(%ebp, 0)
-       movl    %esp, %ebp
-       cfi_def_cfa_register(%ebp)
-       subl    $40, %esp
-       leal    -24(%ebp), %edx
-       movl    %edx, -12(%ebp) /* resp */
-       leal    8(%ebp), %edx
-#ifdef __SUNPRO_C
-       /* The SUNPRO compiler doesn't support GCC's regparm function
-          attribute, so we have to pass all three arguments to
-          ffi_closure_SYSV_inner on the stack.  */
-       movl    %edx, 8(%esp)   /* args = __builtin_dwarf_cfa () */
-       leal    -12(%ebp), %edx
-       movl    %edx, 4(%esp)   /* &resp */
-       movl    %eax, (%esp)    /* closure */
-#else
-       movl    %edx, 4(%esp)   /* args = __builtin_dwarf_cfa () */
-       leal    -12(%ebp), %edx
-       movl    %edx, (%esp)    /* &resp */
+   void ffi_closure_inner(struct closure_frame *frame, char *argp)
+       __attribute_((fastcall))
+
+   Thus the arguments are placed in
+
+       ecx:    frame
+       edx:    argp
+*/
+
+/* Macros to help setting up the closure_data structure.  */
+
+#define closure_FS     (16 + 3*4 + 3*4 + 4)
+
+.macro FFI_CLOSURE_SAVE_REGS
+       movl    %eax, 16+R_EAX*4(%esp)
+       movl    %edx, 16+R_EDX*4(%esp)
+       movl    %ecx, 16+R_ECX*4(%esp)
+.endm
+
+.macro FFI_CLOSURE_COPY_TRAMP_DATA chain
+       movl    FFI_TRAMPOLINE_SIZE(%eax), %edx         /* copy cif */
+       movl    FFI_TRAMPOLINE_SIZE+4(%eax), %ecx       /* copy fun */
+       movl    FFI_TRAMPOLINE_SIZE+8(%eax), %eax       /* copy user_data */
+       movl    %edx, 28(%esp)
+       movl    %ecx, 32(%esp)
+       movl    %eax, 36(%esp)
+.endm
+
+.macro FFI_CLOSURE_CALL_INNER
+       movl    %esp, %ecx                      /* load closure_data */
+       leal    closure_FS+4(%esp), %edx        /* load incoming stack */
+#ifdef __PIC__
+       movl    %ebx, 40(%esp)                  /* save ebx */
+       cfi_rel_offset(%ebx, 40)
+       call    __x86.get_pc_thunk.bx           /* load got register */
+       addl    $C(_GLOBAL_OFFSET_TABLE_), %ebx
 #endif
 #if defined HAVE_HIDDEN_VISIBILITY_ATTRIBUTE || !defined __PIC__
-       call    ffi_closure_SYSV_inner
+       call    C(ffi_closure_inner)
 #else
-       movl    %ebx, 8(%esp)
-       cfi_offset(%ebx, -40)
-       call    1f
-1:     popl    %ebx
-       addl    $_GLOBAL_OFFSET_TABLE_+[.-1b], %ebx
-       call    ffi_closure_SYSV_inner@PLT
-       movl    8(%esp), %ebx
+       call    C(ffi_closure_inner)@PLT
+#endif
+.endm
+
+.macro FFI_CLOSURE_MASK_AND_JUMP
+       andl    $X86_RET_TYPE_MASK, %eax
+#ifdef __PIC__
+       leal    0f@GOTOFF(%ebx, %eax, 8), %eax
+       movl    40(%esp), %ebx                  /* restore ebx */
        cfi_restore(%ebx)
+#else
+       leal    0f(, %eax, 8), %eax
 #endif
-       movl    -12(%ebp), %ecx
-       cmpl    $FFI_TYPE_INT, %eax
-       je      .Lcls_retint
-
-       /* Handle FFI_TYPE_UINT8, FFI_TYPE_SINT8, FFI_TYPE_UINT16,
-          FFI_TYPE_SINT16, FFI_TYPE_UINT32, FFI_TYPE_SINT32.  */
-       cmpl    $FFI_TYPE_UINT64, %eax
-       jge     0f
-       cmpl    $FFI_TYPE_UINT8, %eax
-       jge     .Lcls_retint
-       
-0:     cmpl    $FFI_TYPE_FLOAT, %eax
-       je      .Lcls_retfloat
-       cmpl    $FFI_TYPE_DOUBLE, %eax
-       je      .Lcls_retdouble
-       cmpl    $FFI_TYPE_LONGDOUBLE, %eax
-       je      .Lcls_retldouble
-       cmpl    $FFI_TYPE_SINT64, %eax
-       je      .Lcls_retllong
-       cmpl    $FFI_TYPE_STRUCT, %eax
-       je      .Lcls_retstruct
-.Lcls_epilogue:
-       movl    %ebp, %esp
-       popl    %ebp
+       jmp     *%eax
+.endm
+
+/* The closure entry points are reached from the ffi_closure trampoline.
+   On entry, %eax contains the address of the ffi_closure.  */
+
+       .align  16
+       .globl  C(ffi_closure_i386)
+       FFI_HIDDEN(C(ffi_closure_i386))
+
+C(ffi_closure_i386):
+       cfi_startproc
+       subl    $closure_FS, %esp
+       cfi_adjust_cfa_offset(closure_FS)
+
+       FFI_CLOSURE_SAVE_REGS
+       FFI_CLOSURE_COPY_TRAMP_DATA
+       FFI_CLOSURE_CALL_INNER
+       FFI_CLOSURE_MASK_AND_JUMP
+
+       .align  8
+0:
+E(X86_RET_FLOAT)
+       flds    (%esp)
+       jmp     9f
+E(X86_RET_DOUBLE)
+       fldl    (%esp)
+       jmp     9f
+E(X86_RET_LDOUBLE)
+       fldt    (%esp)
+       jmp     9f
+E(X86_RET_SINT8)
+       movsbl  (%esp), %eax
+       jmp     9f
+E(X86_RET_SINT16)
+       movswl  (%esp), %eax
+       jmp     9f
+E(X86_RET_UINT8)
+       movzbl  (%esp), %eax
+       jmp     9f
+E(X86_RET_UINT16)
+       movzwl  (%esp), %eax
+       jmp     9f
+E(X86_RET_INT64)
+       movl    4(%esp), %edx
+       /* fallthru */
+E(X86_RET_INT32)
+       movl    (%esp), %eax
+       /* fallthru */
+E(X86_RET_VOID)
+9:     addl    $closure_FS, %esp
+       cfi_adjust_cfa_offset(-closure_FS)
        ret
-.Lcls_retint:
-       movl    (%ecx), %eax
-       jmp     .Lcls_epilogue
-.Lcls_retfloat:
-       flds    (%ecx)
-       jmp     .Lcls_epilogue
-.Lcls_retdouble:
-       fldl    (%ecx)
-       jmp     .Lcls_epilogue
-.Lcls_retldouble:
-       fldt    (%ecx)
-       jmp     .Lcls_epilogue
-.Lcls_retllong:
-       movl    (%ecx), %eax
-       movl    4(%ecx), %edx
-       jmp     .Lcls_epilogue
-.Lcls_retstruct:
-       movl    %ebp, %esp
-       popl    %ebp
+       cfi_adjust_cfa_offset(closure_FS)
+E(X86_RET_STRUCTPOP)
+       addl    $closure_FS, %esp
+       cfi_adjust_cfa_offset(-closure_FS)
        ret     $4
+       cfi_adjust_cfa_offset(closure_FS)
+E(X86_RET_STRUCTARG)
+       movl    (%esp), %eax
+       jmp     9b
+E(X86_RET_STRUCT_1B)
+       movzbl  (%esp), %eax
+       jmp     9b
+E(X86_RET_STRUCT_2B)
+       movzwl  (%esp), %eax
+       jmp     9b
+
+       /* Fill out the table so that bad values are predictable.  */
+E(X86_RET_UNUSED14)
+       ud2
+E(X86_RET_UNUSED15)
+       ud2
+
+       cfi_endproc
+ENDF(C(ffi_closure_i386))
+
+/* For REGISTER, we have no available parameter registers, and so we
+   enter here having pushed the closure onto the stack.  */
+
+       .align  16
+       .globl  C(ffi_closure_REGISTER)
+       FFI_HIDDEN(C(ffi_closure_REGISTER))
+C(ffi_closure_REGISTER):
+       cfi_startproc
+       cfi_def_cfa(%esp, 8)
+       cfi_offset(%eip, -8)
+       subl    $closure_FS-4, %esp
+       cfi_adjust_cfa_offset(closure_FS-4)
+
+       FFI_CLOSURE_SAVE_REGS
+
+       movl    closure_FS-4(%esp), %ecx        /* load retaddr */
+       movl    closure_FS(%esp), %eax          /* load closure */
+       movl    %ecx, closure_FS(%esp)          /* move retaddr */
+       jmp     0f
+
+       cfi_endproc
+ENDF(C(ffi_closure_REGISTER))
+
+/* For STDCALL (and others), we need to pop N bytes of arguments off
+   the stack following the closure.  The amount needing to be popped
+   is returned to us from ffi_closure_inner.  */
+
+       .align  16
+       .globl  C(ffi_closure_STDCALL)
+       FFI_HIDDEN(C(ffi_closure_STDCALL))
+C(ffi_closure_STDCALL):
+       cfi_startproc
+       subl    $closure_FS, %esp
+       cfi_adjust_cfa_offset(closure_FS)
+
+       FFI_CLOSURE_SAVE_REGS
+0:
+       FFI_CLOSURE_COPY_TRAMP_DATA
+       FFI_CLOSURE_CALL_INNER
+
+       movl    %eax, %ecx
+       shrl    $X86_RET_POP_SHIFT, %ecx        /* isolate pop count */
+       leal    closure_FS(%esp, %ecx), %ecx    /* compute popped esp */
+       movl    closure_FS(%esp), %edx          /* move return address */
+       movl    %edx, (%ecx)
+
+       /* New pseudo-stack frame based off ecx.  This is unwind trickery
+          in that the CFA *has* changed, to the proper popped stack address.
+          Note that the location to which we moved the return address
+          is the new CFA-4, so that's unchanged.  */
+       cfi_def_cfa(%ecx, 4)
+       /* Normally esp is unwound to CFA + the caller's ARGS_SIZE.
+          We've just set the CFA to that final value.  Tell the unwinder
+          to restore esp from CFA without the ARGS_SIZE:
+          DW_CFA_val_expression %esp, DW_OP_call_frame_cfa.  */
+       cfi_escape(0x16, 4, 1, 0x9c)
+
+       FFI_CLOSURE_MASK_AND_JUMP
+
+       .align  8
+0:
+E(X86_RET_FLOAT)
+       flds    (%esp)
+       movl    %ecx, %esp
+       ret
+E(X86_RET_DOUBLE)
+       fldl    (%esp)
+       movl    %ecx, %esp
+       ret
+E(X86_RET_LDOUBLE)
+       fldt    (%esp)
+       movl    %ecx, %esp
+       ret
+E(X86_RET_SINT8)
+       movsbl  (%esp), %eax
+       movl    %ecx, %esp
+       ret
+E(X86_RET_SINT16)
+       movswl  (%esp), %eax
+       movl    %ecx, %esp
+       ret
+E(X86_RET_UINT8)
+       movzbl  (%esp), %eax
+       movl    %ecx, %esp
+       ret
+E(X86_RET_UINT16)
+       movzwl  (%esp), %eax
+       movl    %ecx, %esp
+       ret
+E(X86_RET_INT64)
+       popl    %eax
+       popl    %edx
+       movl    %ecx, %esp
+       ret
+E(X86_RET_INT32)
+       movl    (%esp), %eax
+       movl    %ecx, %esp
+       ret
+E(X86_RET_VOID)
+       movl    %ecx, %esp
+       ret
+E(X86_RET_STRUCTPOP)
+       movl    %ecx, %esp
+       ret
+E(X86_RET_STRUCTARG)
+       movl    (%esp), %eax
+       movl    %ecx, %esp
+       ret
+E(X86_RET_STRUCT_1B)
+       movzbl  (%esp), %eax
+       movl    %ecx, %esp
+       ret
+E(X86_RET_STRUCT_2B)
+       movzwl  (%esp), %eax
+       movl    %ecx, %esp
+       ret
+
+       /* Fill out the table so that bad values are predictable.  */
+E(X86_RET_UNUSED14)
+       ud2
+E(X86_RET_UNUSED15)
+       ud2
+
        cfi_endproc
-       .size   ffi_closure_SYSV, .-ffi_closure_SYSV
+ENDF(C(ffi_closure_STDCALL))
 
 #if !FFI_NO_RAW_API
 
-/* Precalculate for e.g. the Solaris 10/x86 assembler.  */
-#if FFI_TRAMPOLINE_SIZE == 10
-#define RAW_CLOSURE_CIF_OFFSET 12
-#define RAW_CLOSURE_FUN_OFFSET 16
-#define RAW_CLOSURE_USER_DATA_OFFSET 20
-#elif FFI_TRAMPOLINE_SIZE == 24
-#define RAW_CLOSURE_CIF_OFFSET 24
-#define RAW_CLOSURE_FUN_OFFSET 28
-#define RAW_CLOSURE_USER_DATA_OFFSET 32
+#define raw_closure_S_FS       (16+16+12)
+
+       .align  16
+       .globl  C(ffi_closure_raw_SYSV)
+       FFI_HIDDEN(C(ffi_closure_raw_SYSV))
+C(ffi_closure_raw_SYSV):
+       cfi_startproc
+       subl    $raw_closure_S_FS, %esp
+       cfi_adjust_cfa_offset(raw_closure_S_FS)
+       movl    %ebx, raw_closure_S_FS-4(%esp)
+       cfi_rel_offset(%ebx, raw_closure_S_FS-4)
+
+       movl    FFI_TRAMPOLINE_SIZE+8(%eax), %edx       /* load cl->user_data */
+       movl    %edx, 12(%esp)
+       leal    raw_closure_S_FS+4(%esp), %edx          /* load raw_args */
+       movl    %edx, 8(%esp)
+       leal    16(%esp), %edx                          /* load &res */
+       movl    %edx, 4(%esp)
+       movl    FFI_TRAMPOLINE_SIZE(%eax), %ebx         /* load cl->cif */
+       movl    %ebx, (%esp)
+       call    *FFI_TRAMPOLINE_SIZE+4(%eax)            /* call cl->fun */
+
+       movl    20(%ebx), %eax                          /* load cif->flags */
+       andl    $X86_RET_TYPE_MASK, %eax
+#ifdef __PIC__
+       call    __x86.get_pc_thunk.bx
+1:     leal    0f-1b(%ebx, %eax, 8), %eax
 #else
-#define RAW_CLOSURE_CIF_OFFSET ((FFI_TRAMPOLINE_SIZE + 3) & ~3)
-#define RAW_CLOSURE_FUN_OFFSET (RAW_CLOSURE_CIF_OFFSET + 4)
-#define RAW_CLOSURE_USER_DATA_OFFSET (RAW_CLOSURE_FUN_OFFSET + 4)
+       leal    0f(,%eax, 8), %eax
 #endif
-#define CIF_FLAGS_OFFSET 20
+       movl    raw_closure_S_FS-4(%esp), %ebx
+       cfi_restore(%ebx)
+       jmp     *%eax
+
+       .align  8
+0:
+E(X86_RET_FLOAT)
+       flds    16(%esp)
+       jmp     9f
+E(X86_RET_DOUBLE)
+       fldl    16(%esp)
+       jmp     9f
+E(X86_RET_LDOUBLE)
+       fldt    16(%esp)
+       jmp     9f
+E(X86_RET_SINT8)
+       movsbl  16(%esp), %eax
+       jmp     9f
+E(X86_RET_SINT16)
+       movswl  16(%esp), %eax
+       jmp     9f
+E(X86_RET_UINT8)
+       movzbl  16(%esp), %eax
+       jmp     9f
+E(X86_RET_UINT16)
+       movzwl  16(%esp), %eax
+       jmp     9f
+E(X86_RET_INT64)
+       movl    16+4(%esp), %edx
+       /* fallthru */
+E(X86_RET_INT32)
+       movl    16(%esp), %eax
+       /* fallthru */
+E(X86_RET_VOID)
+9:     addl    $raw_closure_S_FS, %esp
+       cfi_adjust_cfa_offset(-raw_closure_S_FS)
+       ret
+       cfi_adjust_cfa_offset(raw_closure_S_FS)
+E(X86_RET_STRUCTPOP)
+       addl    $raw_closure_S_FS, %esp
+       cfi_adjust_cfa_offset(-raw_closure_S_FS)
+       ret     $4
+       cfi_adjust_cfa_offset(raw_closure_S_FS)
+E(X86_RET_STRUCTARG)
+       movl    16(%esp), %eax
+       jmp     9b
+E(X86_RET_STRUCT_1B)
+       movzbl  16(%esp), %eax
+       jmp     9b
+E(X86_RET_STRUCT_2B)
+       movzwl  16(%esp), %eax
+       jmp     9b
+
+       /* Fill out the table so that bad values are predictable.  */
+E(X86_RET_UNUSED14)
+       ud2
+E(X86_RET_UNUSED15)
+       ud2
 
-       .align  4
-FFI_HIDDEN (ffi_closure_raw_SYSV)
-.globl ffi_closure_raw_SYSV
-       .type   ffi_closure_raw_SYSV, @function
+       cfi_endproc
+ENDF(C(ffi_closure_raw_SYSV))
+
+#undef raw_closure_S_FS
+#define raw_closure_T_FS       (16+16+8)
 
-ffi_closure_raw_SYSV:
+       .align  16
+       .globl  C(ffi_closure_raw_THISCALL)
+       FFI_HIDDEN(C(ffi_closure_raw_THISCALL))
+C(ffi_closure_raw_THISCALL):
        cfi_startproc
-       pushl   %ebp
+       /* Rearrange the stack such that %ecx is the first argument.
+          This means moving the return address.  */
+       popl    %edx
+       cfi_adjust_cfa_offset(-4)
+       cfi_register(%eip, %edx)
+       pushl   %ecx
        cfi_adjust_cfa_offset(4)
-       cfi_rel_offset(%ebp, 0)
-       movl    %esp, %ebp
-       cfi_def_cfa_register(%ebp)
-       pushl   %esi
-       cfi_offset(%esi, -12)
-       subl    $36, %esp
-       movl    RAW_CLOSURE_CIF_OFFSET(%eax), %esi       /* closure->cif */
-       movl    RAW_CLOSURE_USER_DATA_OFFSET(%eax), %edx /* closure->user_data */
-       movl    %edx, 12(%esp)  /* user_data */
-       leal    8(%ebp), %edx   /* __builtin_dwarf_cfa () */
-       movl    %edx, 8(%esp)   /* raw_args */
-       leal    -24(%ebp), %edx
-       movl    %edx, 4(%esp)   /* &res */
-       movl    %esi, (%esp)    /* cif */
-       call    *RAW_CLOSURE_FUN_OFFSET(%eax)            /* closure->fun */
-       movl    CIF_FLAGS_OFFSET(%esi), %eax             /* rtype */
-       cmpl    $FFI_TYPE_INT, %eax
-       je      .Lrcls_retint
-
-       /* Handle FFI_TYPE_UINT8, FFI_TYPE_SINT8, FFI_TYPE_UINT16,
-          FFI_TYPE_SINT16, FFI_TYPE_UINT32, FFI_TYPE_SINT32.  */
-       cmpl    $FFI_TYPE_UINT64, %eax
-       jge     0f
-       cmpl    $FFI_TYPE_UINT8, %eax
-       jge     .Lrcls_retint
+       pushl   %edx
+       cfi_adjust_cfa_offset(4)
+       cfi_rel_offset(%eip, 0)
+       subl    $raw_closure_T_FS, %esp
+       cfi_adjust_cfa_offset(raw_closure_T_FS)
+       movl    %ebx, raw_closure_T_FS-4(%esp)
+       cfi_offset(%ebx, raw_closure_T_FS-4)
+
+       movl    FFI_TRAMPOLINE_SIZE+8(%eax), %edx       /* load cl->user_data */
+       movl    %edx, 12(%esp)
+       leal    raw_closure_T_FS+4(%esp), %edx          /* load raw_args */
+       movl    %edx, 8(%esp)
+       leal    16(%esp), %edx                          /* load &res */
+       movl    %edx, 4(%esp)
+       movl    FFI_TRAMPOLINE_SIZE(%eax), %ebx         /* load cl->cif */
+       movl    %ebx, (%esp)
+       call    *FFI_TRAMPOLINE_SIZE+4(%eax)            /* call cl->fun */
+
+       movl    20(%ebx), %eax                          /* load cif->flags */
+       andl    $X86_RET_TYPE_MASK, %eax
+#ifdef __PIC__
+       call    __x86.get_pc_thunk.bx
+1:     leal    0f-1b(%ebx, %eax, 8), %eax
+#else
+       leal    0f(,%eax, 8), %eax
+#endif
+       movl    raw_closure_T_FS-4(%esp), %ebx
+       cfi_restore(%ebx)
+       jmp     *%eax
+
+       .align  8
 0:
-       cmpl    $FFI_TYPE_FLOAT, %eax
-       je      .Lrcls_retfloat
-       cmpl    $FFI_TYPE_DOUBLE, %eax
-       je      .Lrcls_retdouble
-       cmpl    $FFI_TYPE_LONGDOUBLE, %eax
-       je      .Lrcls_retldouble
-       cmpl    $FFI_TYPE_SINT64, %eax
-       je      .Lrcls_retllong
-.Lrcls_epilogue:
-       addl    $36, %esp
-       popl    %esi
-       popl    %ebp
-       ret
-.Lrcls_retint:
-       movl    -24(%ebp), %eax
-       jmp     .Lrcls_epilogue
-.Lrcls_retfloat:
-       flds    -24(%ebp)
-       jmp     .Lrcls_epilogue
-.Lrcls_retdouble:
-       fldl    -24(%ebp)
-       jmp     .Lrcls_epilogue
-.Lrcls_retldouble:
-       fldt    -24(%ebp)
-       jmp     .Lrcls_epilogue
-.Lrcls_retllong:
-       movl    -24(%ebp), %eax
-       movl    -20(%ebp), %edx
-       jmp     .Lrcls_epilogue
+E(X86_RET_FLOAT)
+       flds    16(%esp)
+       jmp     9f
+E(X86_RET_DOUBLE)
+       fldl    16(%esp)
+       jmp     9f
+E(X86_RET_LDOUBLE)
+       fldt    16(%esp)
+       jmp     9f
+E(X86_RET_SINT8)
+       movsbl  16(%esp), %eax
+       jmp     9f
+E(X86_RET_SINT16)
+       movswl  16(%esp), %eax
+       jmp     9f
+E(X86_RET_UINT8)
+       movzbl  16(%esp), %eax
+       jmp     9f
+E(X86_RET_UINT16)
+       movzwl  16(%esp), %eax
+       jmp     9f
+E(X86_RET_INT64)
+       movl    16+4(%esp), %edx
+       /* fallthru */
+E(X86_RET_INT32)
+       movl    16(%esp), %eax
+       /* fallthru */
+E(X86_RET_VOID)
+9:     addl    $raw_closure_T_FS, %esp
+       cfi_adjust_cfa_offset(-raw_closure_T_FS)
+       /* Remove the extra %ecx argument we pushed.  */
+       ret     $4
+       cfi_adjust_cfa_offset(raw_closure_T_FS)
+E(X86_RET_STRUCTPOP)
+       addl    $raw_closure_T_FS, %esp
+       cfi_adjust_cfa_offset(-raw_closure_T_FS)
+       ret     $8
+       cfi_adjust_cfa_offset(raw_closure_T_FS)
+E(X86_RET_STRUCTARG)
+       movl    16(%esp), %eax
+       jmp     9b
+E(X86_RET_STRUCT_1B)
+       movzbl  16(%esp), %eax
+       jmp     9b
+E(X86_RET_STRUCT_2B)
+       movzwl  16(%esp), %eax
+       jmp     9b
+
+       /* Fill out the table so that bad values are predictable.  */
+E(X86_RET_UNUSED14)
+       ud2
+E(X86_RET_UNUSED15)
+       ud2
+
        cfi_endproc
-       .size   ffi_closure_raw_SYSV, .-ffi_closure_raw_SYSV
+ENDF(C(ffi_closure_raw_THISCALL))
 
 #endif /* !FFI_NO_RAW_API */
+
+#if defined(__PIC__)
+       .section .text.__x86.get_pc_thunk.bx,"axG",@progbits,__x86.get_pc_thunk.bx,comdat
+       .globl  __x86.get_pc_thunk.bx
+       .hidden __x86.get_pc_thunk.bx
+       .type   __x86.get_pc_thunk.bx,@function
+__x86.get_pc_thunk.bx:
+       cfi_startproc
+       movl    (%esp), %ebx
+       ret
+       cfi_endproc
+       .size   __x86.get_pc_thunk.bx, . - __x86.get_pc_thunk.bx
+#endif /* __PIC__ */
+
 #endif /* ifndef __x86_64__ */
 #if defined __ELF__ && defined __linux__
        .section        .note.GNU-stack,"",@progbits
diff --git a/src/x86/win32.S b/src/x86/win32.S
deleted file mode 100644 (file)
index 3680bf5..0000000
+++ /dev/null
@@ -1,1351 +0,0 @@
-/* -----------------------------------------------------------------------
-   win32.S - Copyright (c) 2014  Anthony Green
-             Copyright (c) 1996, 1998, 2001, 2002, 2009  Red Hat, Inc.
-             Copyright (c) 2001  John Beniton
-             Copyright (c) 2002  Ranjit Mathew
-             Copyright (c) 2009  Daniel Witte
-
-
-   X86 Foreign Function Interface
-   Permission is hereby granted, free of charge, to any person obtaining
-   a copy of this software and associated documentation files (the
-   ``Software''), to deal in the Software without restriction, including
-   without limitation the rights to use, copy, modify, merge, publish,
-   distribute, sublicense, and/or sell copies of the Software, and to
-   permit persons to whom the Software is furnished to do so, subject to
-   the following conditions:
-   The above copyright notice and this permission notice shall be included
-   in all copies or substantial portions of the Software.
-   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
-   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-   DEALINGS IN THE SOFTWARE.
-   -----------------------------------------------------------------------
-   */
-#define LIBFFI_ASM
-#include <fficonfig.h>
-#include <ffi.h>
-
-#define CIF_BYTES_OFFSET 16
-#define CIF_FLAGS_OFFSET 20
-
-#ifdef _MSC_VER
-
-#define CLOSURE_CIF_OFFSET ((FFI_TRAMPOLINE_SIZE + 3) AND NOT 3)
-
-.386
-.MODEL FLAT, C
-
-EXTRN ffi_closure_SYSV_inner:NEAR
-EXTRN ffi_closure_WIN32_inner:NEAR
-
-_TEXT SEGMENT
-
-ffi_call_win32 PROC NEAR,
-    ffi_prep_args : NEAR PTR DWORD,
-    ecif          : NEAR PTR DWORD,
-    cif_abi       : DWORD,
-    cif_bytes     : DWORD,
-    cif_flags     : DWORD,
-    rvalue        : NEAR PTR DWORD,
-    fn            : NEAR PTR DWORD
-
-        ;; Make room for all of the new args.
-        mov  ecx, cif_bytes
-        sub  esp, ecx
-
-        mov  eax, esp
-
-        ;; Call ffi_prep_args
-        push ecif
-        push eax
-        call ffi_prep_args
-        add  esp, 8
-
-        ;; Prepare registers
-        ;; EAX stores the number of register arguments
-        cmp  eax, 0
-        je   fun
-        cmp  eax, 3
-        jl   prepr_two_cmp
-        
-        mov  ecx, esp
-        add  esp, 12
-        mov  eax, DWORD PTR [ecx+8]
-        jmp  prepr_two
-prepr_two_cmp:
-        cmp  eax, 2
-        jl   prepr_one_prep
-        mov  ecx, esp
-        add  esp, 8
-prepr_two:
-        mov  edx, DWORD PTR [ecx+4]
-        jmp  prepr_one
-prepr_one_prep:
-        mov  ecx, esp
-        add  esp, 4
-prepr_one:
-        mov  ecx, DWORD PTR [ecx]
-        cmp  cif_abi, 7 ;; FFI_REGISTER
-        jne  fun
-
-        xchg ecx, eax
-
-fun:
-        ;; Call function
-        call fn
-
-        ;; Load ecx with the return type code
-        mov  ecx, cif_flags
-
-        ;; If the return value pointer is NULL, assume no return value.
-        cmp  rvalue, 0
-        jne  ca_jumptable
-
-        ;; Even if there is no space for the return value, we are
-        ;; obliged to handle floating-point values.
-        cmp  ecx, FFI_TYPE_FLOAT
-        jne  ca_epilogue
-        fstp st(0)
-
-        jmp  ca_epilogue
-
-ca_jumptable:
-        jmp  [ca_jumpdata + 4 * ecx]
-ca_jumpdata:
-        ;; Do not insert anything here between label and jump table.
-        dd offset ca_epilogue       ;; FFI_TYPE_VOID
-        dd offset ca_retint         ;; FFI_TYPE_INT
-        dd offset ca_retfloat       ;; FFI_TYPE_FLOAT
-        dd offset ca_retdouble      ;; FFI_TYPE_DOUBLE
-        dd offset ca_retlongdouble  ;; FFI_TYPE_LONGDOUBLE
-        dd offset ca_retuint8       ;; FFI_TYPE_UINT8
-        dd offset ca_retsint8       ;; FFI_TYPE_SINT8
-        dd offset ca_retuint16      ;; FFI_TYPE_UINT16
-        dd offset ca_retsint16      ;; FFI_TYPE_SINT16
-        dd offset ca_retint         ;; FFI_TYPE_UINT32
-        dd offset ca_retint         ;; FFI_TYPE_SINT32
-        dd offset ca_retint64       ;; FFI_TYPE_UINT64
-        dd offset ca_retint64       ;; FFI_TYPE_SINT64
-        dd offset ca_epilogue       ;; FFI_TYPE_STRUCT
-        dd offset ca_retint         ;; FFI_TYPE_POINTER
-        dd offset ca_retstruct1b    ;; FFI_TYPE_SMALL_STRUCT_1B
-        dd offset ca_retstruct2b    ;; FFI_TYPE_SMALL_STRUCT_2B
-        dd offset ca_retint         ;; FFI_TYPE_SMALL_STRUCT_4B
-        dd offset ca_epilogue       ;; FFI_TYPE_MS_STRUCT
-
-        /* Sign/zero extend as appropriate.  */
-ca_retuint8:
-        movzx eax, al
-        jmp   ca_retint
-
-ca_retsint8:
-        movsx eax, al
-        jmp   ca_retint
-
-ca_retuint16:
-        movzx eax, ax
-        jmp   ca_retint
-
-ca_retsint16:
-        movsx eax, ax
-        jmp   ca_retint
-
-ca_retint:
-        ;; Load %ecx with the pointer to storage for the return value
-        mov   ecx, rvalue
-        mov   [ecx + 0], eax
-        jmp   ca_epilogue
-
-ca_retint64:
-        ;; Load %ecx with the pointer to storage for the return value
-        mov   ecx, rvalue
-        mov   [ecx + 0], eax
-        mov   [ecx + 4], edx
-        jmp   ca_epilogue
-
-ca_retfloat:
-        ;; Load %ecx with the pointer to storage for the return value
-        mov   ecx, rvalue
-        fstp  DWORD PTR [ecx]
-        jmp   ca_epilogue
-
-ca_retdouble:
-        ;; Load %ecx with the pointer to storage for the return value
-        mov   ecx, rvalue
-        fstp  QWORD PTR [ecx]
-        jmp   ca_epilogue
-
-ca_retlongdouble:
-        ;; Load %ecx with the pointer to storage for the return value
-        mov   ecx, rvalue
-        fstp  TBYTE PTR [ecx]
-        jmp   ca_epilogue
-
-ca_retstruct1b:
-        ;; Load %ecx with the pointer to storage for the return value
-        mov   ecx, rvalue
-        mov   [ecx + 0], al
-        jmp   ca_epilogue
-
-ca_retstruct2b:
-        ;; Load %ecx with the pointer to storage for the return value
-        mov   ecx, rvalue
-        mov   [ecx + 0], ax
-        jmp   ca_epilogue
-
-ca_epilogue:
-        ;; Epilogue code is autogenerated.
-        ret
-ffi_call_win32 ENDP
-
-ffi_closure_THISCALL PROC NEAR
-        ;; Insert the register argument on the stack as the first argument
-        xchg   DWORD PTR [esp+4], ecx
-        xchg   DWORD PTR [esp], ecx
-        push   ecx
-        jmp    ffi_closure_STDCALL
-ffi_closure_THISCALL ENDP
-
-ffi_closure_FASTCALL PROC NEAR
-        ;; Insert the 2 register arguments on the stack as the first argument
-        xchg   DWORD PTR [esp+4], edx
-        xchg   DWORD PTR [esp], ecx
-        push   edx
-        push   ecx
-        jmp    ffi_closure_STDCALL
-ffi_closure_FASTCALL ENDP
-
-ffi_closure_REGISTER PROC NEAR
-        ;; Insert the 3 register arguments on the stack as the first argument
-        push   eax
-        xchg   DWORD PTR [esp+8], ecx
-        xchg   DWORD PTR [esp+4], edx
-        push   ecx
-        push   edx
-        jmp    ffi_closure_STDCALL
-ffi_closure_REGISTER ENDP
-
-ffi_closure_SYSV PROC NEAR FORCEFRAME
-    ;; the ffi_closure ctx is passed in eax by the trampoline.
-
-        sub  esp, 40
-        lea  edx, [ebp - 24]
-        mov  [ebp - 12], edx         ;; resp
-        lea  edx, [ebp + 8]
-stub::
-        mov  [esp + 8], edx          ;; args
-        lea  edx, [ebp - 12]
-        mov  [esp + 4], edx          ;; &resp
-        mov  [esp], eax              ;; closure
-        call ffi_closure_SYSV_inner
-        mov  ecx, [ebp - 12]
-
-cs_jumptable:
-        jmp  [cs_jumpdata + 4 * eax]
-cs_jumpdata:
-        ;; Do not insert anything here between the label and jump table.
-        dd offset cs_epilogue       ;; FFI_TYPE_VOID
-        dd offset cs_retint         ;; FFI_TYPE_INT
-        dd offset cs_retfloat       ;; FFI_TYPE_FLOAT
-        dd offset cs_retdouble      ;; FFI_TYPE_DOUBLE
-        dd offset cs_retlongdouble  ;; FFI_TYPE_LONGDOUBLE
-        dd offset cs_retuint8       ;; FFI_TYPE_UINT8
-        dd offset cs_retsint8       ;; FFI_TYPE_SINT8
-        dd offset cs_retuint16      ;; FFI_TYPE_UINT16
-        dd offset cs_retsint16      ;; FFI_TYPE_SINT16
-        dd offset cs_retint         ;; FFI_TYPE_UINT32
-        dd offset cs_retint         ;; FFI_TYPE_SINT32
-        dd offset cs_retint64       ;; FFI_TYPE_UINT64
-        dd offset cs_retint64       ;; FFI_TYPE_SINT64
-        dd offset cs_retstruct      ;; FFI_TYPE_STRUCT
-        dd offset cs_retint         ;; FFI_TYPE_POINTER
-        dd offset cs_retsint8       ;; FFI_TYPE_SMALL_STRUCT_1B
-        dd offset cs_retsint16      ;; FFI_TYPE_SMALL_STRUCT_2B
-        dd offset cs_retint         ;; FFI_TYPE_SMALL_STRUCT_4B
-        dd offset cs_retmsstruct    ;; FFI_TYPE_MS_STRUCT
-
-cs_retuint8:
-        movzx eax, BYTE PTR [ecx]
-        jmp   cs_epilogue
-
-cs_retsint8:
-        movsx eax, BYTE PTR [ecx]
-        jmp   cs_epilogue
-
-cs_retuint16:
-        movzx eax, WORD PTR [ecx]
-        jmp   cs_epilogue
-
-cs_retsint16:
-        movsx eax, WORD PTR [ecx]
-        jmp   cs_epilogue
-
-cs_retint:
-        mov   eax, [ecx]
-        jmp   cs_epilogue
-
-cs_retint64:
-        mov   eax, [ecx + 0]
-        mov   edx, [ecx + 4]
-        jmp   cs_epilogue
-
-cs_retfloat:
-        fld   DWORD PTR [ecx]
-        jmp   cs_epilogue
-
-cs_retdouble:
-        fld   QWORD PTR [ecx]
-        jmp   cs_epilogue
-
-cs_retlongdouble:
-        fld   TBYTE PTR [ecx]
-        jmp   cs_epilogue
-
-cs_retstruct:
-        ;; Caller expects us to pop struct return value pointer hidden arg.
-        ;; Epilogue code is autogenerated.
-        ret    4
-
-cs_retmsstruct:
-        ;; Caller expects us to return a pointer to the real return value.
-        mov   eax, ecx
-        ;; Caller doesn't expects us to pop struct return value pointer hidden arg.
-        jmp   cs_epilogue
-
-cs_epilogue:
-        ;; Epilogue code is autogenerated.
-        ret
-ffi_closure_SYSV ENDP
-
-#if !FFI_NO_RAW_API
-
-#define RAW_CLOSURE_CIF_OFFSET ((FFI_TRAMPOLINE_SIZE + 3) AND NOT 3)
-#define RAW_CLOSURE_FUN_OFFSET (RAW_CLOSURE_CIF_OFFSET + 4)
-#define RAW_CLOSURE_USER_DATA_OFFSET (RAW_CLOSURE_FUN_OFFSET + 4)
-
-ffi_closure_raw_THISCALL PROC NEAR USES esi FORCEFRAME
-        sub esp, 36
-        mov  esi, [eax + RAW_CLOSURE_CIF_OFFSET]        ;; closure->cif
-        mov  edx, [eax + RAW_CLOSURE_USER_DATA_OFFSET]  ;; closure->user_data
-        mov [esp + 12], edx
-        lea edx, [ebp + 12]
-        jmp stubraw
-ffi_closure_raw_THISCALL ENDP
-
-ffi_closure_raw_SYSV PROC NEAR USES esi FORCEFRAME
-    ;; the ffi_closure ctx is passed in eax by the trampoline.
-
-        sub  esp, 40
-        mov  esi, [eax + RAW_CLOSURE_CIF_OFFSET]        ;; closure->cif
-        mov  edx, [eax + RAW_CLOSURE_USER_DATA_OFFSET]  ;; closure->user_data
-        mov  [esp + 12], edx                            ;; user_data
-        lea  edx, [ebp + 8]
-stubraw::
-        mov  [esp + 8], edx                             ;; raw_args
-        lea  edx, [ebp - 24]
-        mov  [esp + 4], edx                             ;; &res
-        mov  [esp], esi                                 ;; cif
-        call DWORD PTR [eax + RAW_CLOSURE_FUN_OFFSET]   ;; closure->fun
-        mov  eax, [esi + CIF_FLAGS_OFFSET]              ;; cif->flags
-        lea  ecx, [ebp - 24]
-
-cr_jumptable:
-        jmp  [cr_jumpdata + 4 * eax]
-cr_jumpdata:
-        ;; Do not insert anything here between the label and jump table.
-        dd offset cr_epilogue       ;; FFI_TYPE_VOID
-        dd offset cr_retint         ;; FFI_TYPE_INT
-        dd offset cr_retfloat       ;; FFI_TYPE_FLOAT
-        dd offset cr_retdouble      ;; FFI_TYPE_DOUBLE
-        dd offset cr_retlongdouble  ;; FFI_TYPE_LONGDOUBLE
-        dd offset cr_retuint8       ;; FFI_TYPE_UINT8
-        dd offset cr_retsint8       ;; FFI_TYPE_SINT8
-        dd offset cr_retuint16      ;; FFI_TYPE_UINT16
-        dd offset cr_retsint16      ;; FFI_TYPE_SINT16
-        dd offset cr_retint         ;; FFI_TYPE_UINT32
-        dd offset cr_retint         ;; FFI_TYPE_SINT32
-        dd offset cr_retint64       ;; FFI_TYPE_UINT64
-        dd offset cr_retint64       ;; FFI_TYPE_SINT64
-        dd offset cr_epilogue       ;; FFI_TYPE_STRUCT
-        dd offset cr_retint         ;; FFI_TYPE_POINTER
-        dd offset cr_retsint8       ;; FFI_TYPE_SMALL_STRUCT_1B
-        dd offset cr_retsint16      ;; FFI_TYPE_SMALL_STRUCT_2B
-        dd offset cr_retint         ;; FFI_TYPE_SMALL_STRUCT_4B
-        dd offset cr_epilogue       ;; FFI_TYPE_MS_STRUCT
-
-cr_retuint8:
-        movzx eax, BYTE PTR [ecx]
-        jmp   cr_epilogue
-
-cr_retsint8:
-        movsx eax, BYTE PTR [ecx]
-        jmp   cr_epilogue
-
-cr_retuint16:
-        movzx eax, WORD PTR [ecx]
-        jmp   cr_epilogue
-
-cr_retsint16:
-        movsx eax, WORD PTR [ecx]
-        jmp   cr_epilogue
-
-cr_retint:
-        mov   eax, [ecx]
-        jmp   cr_epilogue
-
-cr_retint64:
-        mov   eax, [ecx + 0]
-        mov   edx, [ecx + 4]
-        jmp   cr_epilogue
-
-cr_retfloat:
-        fld   DWORD PTR [ecx]
-        jmp   cr_epilogue
-
-cr_retdouble:
-        fld   QWORD PTR [ecx]
-        jmp   cr_epilogue
-
-cr_retlongdouble:
-        fld   TBYTE PTR [ecx]
-        jmp   cr_epilogue
-
-cr_epilogue:
-        ;; Epilogue code is autogenerated.
-        ret
-ffi_closure_raw_SYSV ENDP
-
-#endif /* !FFI_NO_RAW_API */
-
-ffi_closure_STDCALL PROC NEAR FORCEFRAME
-        mov  eax, [esp] ;; the ffi_closure ctx passed by the trampoline.
-
-        sub  esp, 40
-        lea  edx, [ebp - 24]
-        mov  [ebp - 12], edx         ;; resp
-        lea  edx, [ebp + 12]         ;; account for stub return address on stack
-        mov  [esp + 8], edx          ;; args
-        lea  edx, [ebp - 12]
-        mov  [esp + 4], edx          ;; &resp
-        mov  [esp], eax              ;; closure
-        call ffi_closure_WIN32_inner
-        mov  ecx, [ebp - 12]
-
-        xchg [ebp + 4], eax          ;;xchg size of stack parameters and ffi_closure ctx
-        mov  eax, DWORD PTR [eax + CLOSURE_CIF_OFFSET]
-        mov  eax, DWORD PTR [eax + CIF_FLAGS_OFFSET]
-
-cd_jumptable:
-        jmp  [cd_jumpdata + 4 * eax]
-cd_jumpdata:
-        ;; Do not insert anything here between the label and jump table.
-        dd offset cd_epilogue       ;; FFI_TYPE_VOID
-        dd offset cd_retint         ;; FFI_TYPE_INT
-        dd offset cd_retfloat       ;; FFI_TYPE_FLOAT
-        dd offset cd_retdouble      ;; FFI_TYPE_DOUBLE
-        dd offset cd_retlongdouble  ;; FFI_TYPE_LONGDOUBLE
-        dd offset cd_retuint8       ;; FFI_TYPE_UINT8
-        dd offset cd_retsint8       ;; FFI_TYPE_SINT8
-        dd offset cd_retuint16      ;; FFI_TYPE_UINT16
-        dd offset cd_retsint16      ;; FFI_TYPE_SINT16
-        dd offset cd_retint         ;; FFI_TYPE_UINT32
-        dd offset cd_retint         ;; FFI_TYPE_SINT32
-        dd offset cd_retint64       ;; FFI_TYPE_UINT64
-        dd offset cd_retint64       ;; FFI_TYPE_SINT64
-        dd offset cd_epilogue       ;; FFI_TYPE_STRUCT
-        dd offset cd_retint         ;; FFI_TYPE_POINTER
-        dd offset cd_retsint8       ;; FFI_TYPE_SMALL_STRUCT_1B
-        dd offset cd_retsint16      ;; FFI_TYPE_SMALL_STRUCT_2B
-        dd offset cd_retint         ;; FFI_TYPE_SMALL_STRUCT_4B
-
-cd_retuint8:
-        movzx eax, BYTE PTR [ecx]
-        jmp   cd_epilogue
-
-cd_retsint8:
-        movsx eax, BYTE PTR [ecx]
-        jmp   cd_epilogue
-
-cd_retuint16:
-        movzx eax, WORD PTR [ecx]
-        jmp   cd_epilogue
-
-cd_retsint16:
-        movsx eax, WORD PTR [ecx]
-        jmp   cd_epilogue
-
-cd_retint:
-        mov   eax, [ecx]
-        jmp   cd_epilogue
-
-cd_retint64:
-        mov   eax, [ecx + 0]
-        mov   edx, [ecx + 4]
-        jmp   cd_epilogue
-
-cd_retfloat:
-        fld   DWORD PTR [ecx]
-        jmp   cd_epilogue
-
-cd_retdouble:
-        fld   QWORD PTR [ecx]
-        jmp   cd_epilogue
-
-cd_retlongdouble:
-        fld   TBYTE PTR [ecx]
-        jmp   cd_epilogue
-
-cd_epilogue:
-        mov   esp, ebp
-        pop   ebp
-        mov   ecx, [esp + 4]  ;; Return address
-        add   esp, [esp]      ;; Parameters stack size
-        add   esp, 8
-        jmp   ecx
-ffi_closure_STDCALL ENDP
-
-_TEXT ENDS
-END
-
-#else
-
-#define CLOSURE_CIF_OFFSET ((FFI_TRAMPOLINE_SIZE + 3) & ~3)
-
-#if defined(SYMBOL_UNDERSCORE)
-#define USCORE_SYMBOL(x) _##x
-#else
-#define USCORE_SYMBOL(x) x
-#endif
-        .text
-        # This assumes we are using gas.
-        .balign 16
-FFI_HIDDEN(ffi_call_win32)
-        .globl USCORE_SYMBOL(ffi_call_win32)
-#if defined(X86_WIN32) && !defined(__OS2__)
-        .def   _ffi_call_win32;        .scl    2;      .type   32;     .endef
-#endif
-USCORE_SYMBOL(ffi_call_win32):
-.LFB1:
-        pushl %ebp
-.LCFI0:
-        movl  %esp,%ebp
-.LCFI1:
-        # Make room for all of the new args.
-        movl  20(%ebp),%ecx                                                     
-        subl  %ecx,%esp
-        movl  %esp,%eax
-        # Call ffi_prep_args
-        pushl 12(%ebp)
-        pushl %eax
-        call  *8(%ebp)
-        addl  $8,%esp
-
-        # Prepare registers
-        # EAX stores the number of register arguments
-        cmpl  $0, %eax
-        je    .fun
-        cmpl  $3, %eax
-        jl    .prepr_two_cmp
-        
-        movl  %esp, %ecx
-        addl  $12, %esp
-        movl  8(%ecx), %eax
-        jmp   .prepr_two
-.prepr_two_cmp:
-        cmpl  $2, %eax
-        jl    .prepr_one_prep
-        movl  %esp, %ecx
-        addl  $8, %esp
-.prepr_two:
-        movl  4(%ecx), %edx
-        jmp   .prepr_one
-.prepr_one_prep:
-        movl  %esp, %ecx
-        addl  $4, %esp
-.prepr_one:
-        movl  (%ecx), %ecx
-        cmpl  $7, 16(%ebp) # FFI_REGISTER
-        jne   .fun
-
-        xchgl %eax, %ecx
-        
-.fun:
-        # FIXME: Align the stack to a 128-bit boundary to avoid
-        # potential performance hits.
-
-        # Call function
-        call  *32(%ebp)
-        # stdcall functions pop arguments off the stack themselves
-
-        # Load %ecx with the return type code
-        movl  24(%ebp),%ecx
-        # If the return value pointer is NULL, assume no return value.
-        cmpl  $0,28(%ebp)
-        jne   0f
-        # Even if there is no space for the return value, we are
-        # obliged to handle floating-point values.
-        cmpl  $FFI_TYPE_FLOAT,%ecx
-        jne   .Lnoretval
-        fstp  %st(0)
-        jmp   .Lepilogue
-
-0:
-        call 1f
-        # Do not insert anything here between the call and the jump table.
-.Lstore_table:
-        .long  .Lnoretval-.Lstore_table        /* FFI_TYPE_VOID */
-        .long  .Lretint-.Lstore_table          /* FFI_TYPE_INT */
-        .long  .Lretfloat-.Lstore_table        /* FFI_TYPE_FLOAT */
-        .long  .Lretdouble-.Lstore_table       /* FFI_TYPE_DOUBLE */
-        .long  .Lretlongdouble-.Lstore_table   /* FFI_TYPE_LONGDOUBLE */
-        .long  .Lretuint8-.Lstore_table        /* FFI_TYPE_UINT8 */
-        .long  .Lretsint8-.Lstore_table        /* FFI_TYPE_SINT8 */
-        .long  .Lretuint16-.Lstore_table       /* FFI_TYPE_UINT16 */
-        .long  .Lretsint16-.Lstore_table       /* FFI_TYPE_SINT16 */
-        .long  .Lretint-.Lstore_table          /* FFI_TYPE_UINT32 */
-        .long  .Lretint-.Lstore_table          /* FFI_TYPE_SINT32 */
-        .long  .Lretint64-.Lstore_table        /* FFI_TYPE_UINT64 */
-        .long  .Lretint64-.Lstore_table        /* FFI_TYPE_SINT64 */
-        .long  .Lretstruct-.Lstore_table       /* FFI_TYPE_STRUCT */
-        .long  .Lretint-.Lstore_table          /* FFI_TYPE_POINTER */
-        .long  .Lretstruct1b-.Lstore_table     /* FFI_TYPE_SMALL_STRUCT_1B */
-        .long  .Lretstruct2b-.Lstore_table     /* FFI_TYPE_SMALL_STRUCT_2B */
-        .long  .Lretstruct4b-.Lstore_table     /* FFI_TYPE_SMALL_STRUCT_4B */
-        .long  .Lretstruct-.Lstore_table       /* FFI_TYPE_MS_STRUCT */
-1:
-        shl    $2, %ecx
-        add    (%esp),%ecx
-        mov    (%ecx),%ecx
-        add    (%esp),%ecx
-        add    $4, %esp
-        jmp    *%ecx
-
-        /* Sign/zero extend as appropriate.  */
-.Lretsint8:
-        movsbl %al, %eax
-        jmp    .Lretint
-
-.Lretsint16:
-        movswl %ax, %eax
-        jmp    .Lretint
-
-.Lretuint8:
-        movzbl %al, %eax
-        jmp    .Lretint
-
-.Lretuint16:
-        movzwl %ax, %eax
-        jmp    .Lretint
-
-.Lretint:
-        # Load %ecx with the pointer to storage for the return value
-        movl  28(%ebp),%ecx
-        movl  %eax,0(%ecx)
-        jmp   .Lepilogue
-.Lretfloat:
-         # Load %ecx with the pointer to storage for the return value
-        movl  28(%ebp),%ecx
-        fstps (%ecx)
-        jmp   .Lepilogue
-.Lretdouble:
-        # Load %ecx with the pointer to storage for the return value
-        movl  28(%ebp),%ecx
-        fstpl (%ecx)
-        jmp   .Lepilogue
-.Lretlongdouble:
-        # Load %ecx with the pointer to storage for the return value
-        movl  28(%ebp),%ecx
-        fstpt (%ecx)
-        jmp   .Lepilogue
-.Lretint64:
-        # Load %ecx with the pointer to storage for the return value
-        movl  28(%ebp),%ecx
-        movl  %eax,0(%ecx)
-        movl  %edx,4(%ecx)
-        jmp   .Lepilogue
-
-.Lretstruct1b:
-        # Load %ecx with the pointer to storage for the return value
-        movl  28(%ebp),%ecx
-        movb  %al,0(%ecx)
-        jmp   .Lepilogue
-.Lretstruct2b:
-        # Load %ecx with the pointer to storage for the return value
-        movl  28(%ebp),%ecx
-        movw  %ax,0(%ecx)
-        jmp   .Lepilogue
-
-.Lretstruct4b:
-        # Load %ecx with the pointer to storage for the return value
-        movl  28(%ebp),%ecx
-        movl  %eax,0(%ecx)
-        jmp   .Lepilogue
-
-.Lretstruct:
-        # Nothing to do!
-.Lnoretval:
-.Lepilogue:
-        movl %ebp,%esp
-        popl %ebp
-        ret
-.ffi_call_win32_end:
-        .balign 16
-FFI_HIDDEN(ffi_closure_THISCALL)
-        .globl USCORE_SYMBOL(ffi_closure_THISCALL)
-#if defined(X86_WIN32) && !defined(__OS2__)
-        .def   _ffi_closure_THISCALL;  .scl    2;      .type   32;     .endef
-#endif
-USCORE_SYMBOL(ffi_closure_THISCALL):
-        /* Insert the register argument on the stack as the first argument */
-        xchg   %ecx, 4(%esp)
-        xchg   %ecx, (%esp)
-        push   %ecx
-        jmp    .ffi_closure_STDCALL_internal
-
-        .balign 16
-FFI_HIDDEN(ffi_closure_FASTCALL)
-        .globl USCORE_SYMBOL(ffi_closure_FASTCALL)
-#if defined(X86_WIN32) && !defined(__OS2__)
-        .def   _ffi_closure_FASTCALL;  .scl    2;      .type   32;     .endef
-#endif
-USCORE_SYMBOL(ffi_closure_FASTCALL):
-        /* Insert the 2 register arguments on the stack as the first two arguments */
-        xchg   %edx, 4(%esp)
-        xchg   %ecx, (%esp)
-        push   %edx
-        push   %ecx
-        jmp    .ffi_closure_STDCALL_internal
-FFI_HIDDEN(ffi_closure_REGISTER)
-        .globl USCORE_SYMBOL(ffi_closure_REGISTER)
-#if defined(X86_WIN32) && !defined(__OS2__)
-        .def   _ffi_closure_REGISTER;  .scl    2;      .type   32;     .endef
-#endif
-USCORE_SYMBOL(ffi_closure_REGISTER):
-        /* Insert the 3 register arguments on the stack as the first two arguments */
-        push   %eax
-        xchg   %ecx, 8(%esp)
-        xchg   %edx, 4(%esp)
-        push   %ecx
-        push   %edx
-        jmp    .ffi_closure_STDCALL_internal
-
-.LFE1:
-        # This assumes we are using gas.
-        .balign 16
-FFI_HIDDEN(ffi_closure_SYSV)
-#if defined(X86_WIN32)
-        .globl USCORE_SYMBOL(ffi_closure_SYSV)
-#if defined(X86_WIN32) && !defined(__OS2__)
-        .def   _ffi_closure_SYSV;      .scl    2;      .type   32;     .endef
-#endif
-USCORE_SYMBOL(ffi_closure_SYSV):
-#endif
-.LFB3:
-        pushl  %ebp
-.LCFI4:
-        movl   %esp, %ebp
-.LCFI5:
-        subl   $40, %esp
-        leal   -24(%ebp), %edx
-        movl   %edx, -12(%ebp) /* resp */
-        leal   8(%ebp), %edx
-        movl   %edx, 4(%esp)   /* args = __builtin_dwarf_cfa () */
-        leal   -12(%ebp), %edx
-        movl   %edx, (%esp)    /* &resp */
-#if defined(HAVE_HIDDEN_VISIBILITY_ATTRIBUTE) || !defined(__PIC__)
-        call   USCORE_SYMBOL(ffi_closure_SYSV_inner)
-#elif defined(X86_DARWIN)
-        calll  L_ffi_closure_SYSV_inner$stub
-#else
-        movl   %ebx, 8(%esp)
-        call   1f
-1:      popl   %ebx
-        addl   $_GLOBAL_OFFSET_TABLE_+[.-1b], %ebx
-        call   ffi_closure_SYSV_inner@PLT
-        movl   8(%esp), %ebx
-#endif
-        movl   -12(%ebp), %ecx
-
-0:
-        call   1f
-        # Do not insert anything here between the call and the jump table.
-.Lcls_store_table:
-        .long  .Lcls_noretval-.Lcls_store_table        /* FFI_TYPE_VOID */
-        .long  .Lcls_retint-.Lcls_store_table          /* FFI_TYPE_INT */
-        .long  .Lcls_retfloat-.Lcls_store_table        /* FFI_TYPE_FLOAT */
-        .long  .Lcls_retdouble-.Lcls_store_table       /* FFI_TYPE_DOUBLE */
-        .long  .Lcls_retldouble-.Lcls_store_table      /* FFI_TYPE_LONGDOUBLE */
-        .long  .Lcls_retuint8-.Lcls_store_table        /* FFI_TYPE_UINT8 */
-        .long  .Lcls_retsint8-.Lcls_store_table        /* FFI_TYPE_SINT8 */
-        .long  .Lcls_retuint16-.Lcls_store_table       /* FFI_TYPE_UINT16 */
-        .long  .Lcls_retsint16-.Lcls_store_table       /* FFI_TYPE_SINT16 */
-        .long  .Lcls_retint-.Lcls_store_table          /* FFI_TYPE_UINT32 */
-        .long  .Lcls_retint-.Lcls_store_table          /* FFI_TYPE_SINT32 */
-        .long  .Lcls_retllong-.Lcls_store_table        /* FFI_TYPE_UINT64 */
-        .long  .Lcls_retllong-.Lcls_store_table        /* FFI_TYPE_SINT64 */
-        .long  .Lcls_retstruct-.Lcls_store_table       /* FFI_TYPE_STRUCT */
-        .long  .Lcls_retint-.Lcls_store_table          /* FFI_TYPE_POINTER */
-        .long  .Lcls_retstruct1-.Lcls_store_table      /* FFI_TYPE_SMALL_STRUCT_1B */
-        .long  .Lcls_retstruct2-.Lcls_store_table      /* FFI_TYPE_SMALL_STRUCT_2B */
-        .long  .Lcls_retstruct4-.Lcls_store_table      /* FFI_TYPE_SMALL_STRUCT_4B */
-        .long  .Lcls_retmsstruct-.Lcls_store_table     /* FFI_TYPE_MS_STRUCT */
-
-1:
-        shl    $2, %eax
-        add    (%esp),%eax
-        mov    (%eax),%eax
-        add    (%esp),%eax
-        add    $4, %esp
-        jmp    *%eax
-
-        /* Sign/zero extend as appropriate.  */
-.Lcls_retsint8:
-        movsbl (%ecx), %eax
-        jmp    .Lcls_epilogue
-
-.Lcls_retsint16:
-        movswl (%ecx), %eax
-        jmp    .Lcls_epilogue
-
-.Lcls_retuint8:
-        movzbl (%ecx), %eax
-        jmp    .Lcls_epilogue
-
-.Lcls_retuint16:
-        movzwl (%ecx), %eax
-        jmp    .Lcls_epilogue
-
-.Lcls_retint:
-        movl   (%ecx), %eax
-        jmp    .Lcls_epilogue
-
-.Lcls_retfloat:
-        flds   (%ecx)
-        jmp    .Lcls_epilogue
-
-.Lcls_retdouble:
-        fldl   (%ecx)
-        jmp    .Lcls_epilogue
-
-.Lcls_retldouble:
-        fldt   (%ecx)
-        jmp    .Lcls_epilogue
-
-.Lcls_retllong:
-        movl   (%ecx), %eax
-        movl   4(%ecx), %edx
-        jmp    .Lcls_epilogue
-
-.Lcls_retstruct1:
-        movsbl (%ecx), %eax
-        jmp    .Lcls_epilogue
-
-.Lcls_retstruct2:
-        movswl (%ecx), %eax
-        jmp    .Lcls_epilogue
-
-.Lcls_retstruct4:
-        movl   (%ecx), %eax
-        jmp    .Lcls_epilogue
-
-.Lcls_retstruct:
-        # Caller expects us to pop struct return value pointer hidden arg.
-        movl   %ebp, %esp
-        popl   %ebp
-        ret    $0x4
-
-.Lcls_retmsstruct:
-        # Caller expects us to return a pointer to the real return value.
-        mov    %ecx, %eax
-        # Caller doesn't expects us to pop struct return value pointer hidden arg.
-        jmp    .Lcls_epilogue
-
-.Lcls_noretval:
-.Lcls_epilogue:
-        movl   %ebp, %esp
-        popl   %ebp
-        ret
-.ffi_closure_SYSV_end:
-.LFE3:
-
-#if !FFI_NO_RAW_API
-
-#define RAW_CLOSURE_CIF_OFFSET ((FFI_TRAMPOLINE_SIZE + 3) & ~3)
-#define RAW_CLOSURE_FUN_OFFSET (RAW_CLOSURE_CIF_OFFSET + 4)
-#define RAW_CLOSURE_USER_DATA_OFFSET (RAW_CLOSURE_FUN_OFFSET + 4)
-
-#ifdef X86_WIN32
-        .balign 16
-FFI_HIDDEN(ffi_closure_raw_THISCALL)
-        .globl USCORE_SYMBOL(ffi_closure_raw_THISCALL)
-#if defined(X86_WIN32) && !defined(__OS2__)
-        .def   _ffi_closure_raw_THISCALL;      .scl    2;      .type   32;     .endef
-#endif
-USCORE_SYMBOL(ffi_closure_raw_THISCALL):
-        pushl  %ebp
-        movl   %esp, %ebp
-        pushl  %esi
-        subl   $36, %esp
-        movl   RAW_CLOSURE_CIF_OFFSET(%eax), %esi       /* closure->cif */
-        movl   RAW_CLOSURE_USER_DATA_OFFSET(%eax), %edx /* closure->user_data */
-        movl   %edx, 12(%esp)  /* user_data */
-        leal   12(%ebp), %edx  /* __builtin_dwarf_cfa () */
-        jmp    .stubraw
-#endif /* X86_WIN32 */
-
-        # This assumes we are using gas.
-        .balign 16
-#if defined(X86_WIN32)
-        .globl USCORE_SYMBOL(ffi_closure_raw_SYSV)
-#if defined(X86_WIN32) && !defined(__OS2__)
-        .def   _ffi_closure_raw_SYSV;  .scl    2;      .type   32;     .endef
-#endif
-USCORE_SYMBOL(ffi_closure_raw_SYSV):
-#endif /* defined(X86_WIN32) */
-.LFB4:
-        pushl  %ebp
-.LCFI6:
-        movl   %esp, %ebp
-.LCFI7:
-        pushl  %esi
-.LCFI8:
-        subl   $36, %esp
-        movl   RAW_CLOSURE_CIF_OFFSET(%eax), %esi       /* closure->cif */
-        movl   RAW_CLOSURE_USER_DATA_OFFSET(%eax), %edx /* closure->user_data */
-        movl   %edx, 12(%esp)  /* user_data */
-        leal   8(%ebp), %edx   /* __builtin_dwarf_cfa () */
-.stubraw:
-        movl   %edx, 8(%esp)   /* raw_args */
-        leal   -24(%ebp), %edx
-        movl   %edx, 4(%esp)   /* &res */
-        movl   %esi, (%esp)    /* cif */
-        call   *RAW_CLOSURE_FUN_OFFSET(%eax)            /* closure->fun */
-        movl   CIF_FLAGS_OFFSET(%esi), %eax             /* rtype */
-0:
-        call   1f
-        # Do not insert anything here between the call and the jump table.
-.Lrcls_store_table:
-        .long  .Lrcls_noretval-.Lrcls_store_table      /* FFI_TYPE_VOID */
-        .long  .Lrcls_retint-.Lrcls_store_table        /* FFI_TYPE_INT */
-        .long  .Lrcls_retfloat-.Lrcls_store_table      /* FFI_TYPE_FLOAT */
-        .long  .Lrcls_retdouble-.Lrcls_store_table     /* FFI_TYPE_DOUBLE */
-        .long  .Lrcls_retldouble-.Lrcls_store_table    /* FFI_TYPE_LONGDOUBLE */
-        .long  .Lrcls_retuint8-.Lrcls_store_table      /* FFI_TYPE_UINT8 */
-        .long  .Lrcls_retsint8-.Lrcls_store_table      /* FFI_TYPE_SINT8 */
-        .long  .Lrcls_retuint16-.Lrcls_store_table     /* FFI_TYPE_UINT16 */
-        .long  .Lrcls_retsint16-.Lrcls_store_table     /* FFI_TYPE_SINT16 */
-        .long  .Lrcls_retint-.Lrcls_store_table        /* FFI_TYPE_UINT32 */
-        .long  .Lrcls_retint-.Lrcls_store_table        /* FFI_TYPE_SINT32 */
-        .long  .Lrcls_retllong-.Lrcls_store_table      /* FFI_TYPE_UINT64 */
-        .long  .Lrcls_retllong-.Lrcls_store_table      /* FFI_TYPE_SINT64 */
-        .long  .Lrcls_retstruct-.Lrcls_store_table     /* FFI_TYPE_STRUCT */
-        .long  .Lrcls_retint-.Lrcls_store_table        /* FFI_TYPE_POINTER */
-        .long  .Lrcls_retstruct1-.Lrcls_store_table    /* FFI_TYPE_SMALL_STRUCT_1B */
-        .long  .Lrcls_retstruct2-.Lrcls_store_table    /* FFI_TYPE_SMALL_STRUCT_2B */
-        .long  .Lrcls_retstruct4-.Lrcls_store_table    /* FFI_TYPE_SMALL_STRUCT_4B */
-        .long  .Lrcls_retstruct-.Lrcls_store_table     /* FFI_TYPE_MS_STRUCT */
-1:
-        shl    $2, %eax
-        add    (%esp),%eax
-        mov    (%eax),%eax
-        add    (%esp),%eax
-        add    $4, %esp
-        jmp    *%eax
-
-        /* Sign/zero extend as appropriate.  */
-.Lrcls_retsint8:
-        movsbl -24(%ebp), %eax
-        jmp    .Lrcls_epilogue
-
-.Lrcls_retsint16:
-        movswl -24(%ebp), %eax
-        jmp    .Lrcls_epilogue
-
-.Lrcls_retuint8:
-        movzbl -24(%ebp), %eax
-        jmp    .Lrcls_epilogue
-
-.Lrcls_retuint16:
-        movzwl -24(%ebp), %eax
-        jmp    .Lrcls_epilogue
-
-.Lrcls_retint:
-        movl   -24(%ebp), %eax
-        jmp    .Lrcls_epilogue
-
-.Lrcls_retfloat:
-        flds   -24(%ebp)
-        jmp    .Lrcls_epilogue
-
-.Lrcls_retdouble:
-        fldl   -24(%ebp)
-        jmp    .Lrcls_epilogue
-
-.Lrcls_retldouble:
-        fldt   -24(%ebp)
-        jmp    .Lrcls_epilogue
-
-.Lrcls_retllong:
-        movl   -24(%ebp), %eax
-        movl   -20(%ebp), %edx
-        jmp    .Lrcls_epilogue
-
-.Lrcls_retstruct1:
-        movsbl -24(%ebp), %eax
-        jmp    .Lrcls_epilogue
-
-.Lrcls_retstruct2:
-        movswl -24(%ebp), %eax
-        jmp    .Lrcls_epilogue
-
-.Lrcls_retstruct4:
-        movl   -24(%ebp), %eax
-        jmp    .Lrcls_epilogue
-
-.Lrcls_retstruct:
-        # Nothing to do!
-
-.Lrcls_noretval:
-.Lrcls_epilogue:
-        addl   $36, %esp
-        popl   %esi
-        popl   %ebp
-        ret
-.ffi_closure_raw_SYSV_end:
-.LFE4:
-
-#endif /* !FFI_NO_RAW_API */
-
-        # This assumes we are using gas.
-        .balign        16
-FFI_HIDDEN(ffi_closure_STDCALL)
-        .globl USCORE_SYMBOL(ffi_closure_STDCALL)
-#if defined(X86_WIN32) && !defined(__OS2__)
-        .def   _ffi_closure_STDCALL;   .scl    2;      .type   32;     .endef
-#endif
-USCORE_SYMBOL(ffi_closure_STDCALL):
-.ffi_closure_STDCALL_internal:
-        /* ffi_closure ctx is at top of the stack */
-        movl   (%esp), %eax
-.LFB5:
-        pushl  %ebp
-.LCFI9:
-        movl   %esp, %ebp
-.LCFI10:
-        subl   $40, %esp
-        leal   -24(%ebp), %edx
-        movl   %edx, -12(%ebp) /* resp */
-        leal   12(%ebp), %edx  /* account for stub return address on stack */
-        movl   %edx, 4(%esp)   /* args */
-        leal   -12(%ebp), %edx
-        movl   %edx, (%esp)    /* &resp */
-#if defined(HAVE_HIDDEN_VISIBILITY_ATTRIBUTE) || !defined(__PIC__)
-        call   USCORE_SYMBOL(ffi_closure_WIN32_inner)
-#elif defined(X86_DARWIN)
-        calll  L_ffi_closure_WIN32_inner$stub
-#else
-        movl   %ebx, 8(%esp)
-        call   1f
-1:      popl   %ebx
-        addl   $_GLOBAL_OFFSET_TABLE_+[.-1b], %ebx
-        call   ffi_closure_WIN32_inner@PLT
-        movl   8(%esp), %ebx
-#endif
-        movl   -12(%ebp), %ecx
-0:
-        xchgl  4(%ebp), %eax /* xchg size of stack parameters and ffi_closure ctx */
-        movl   CLOSURE_CIF_OFFSET(%eax), %eax
-        movl   CIF_FLAGS_OFFSET(%eax), %eax
-
-        call   1f
-        # Do not insert anything here between the call and the jump table.
-.Lscls_store_table:
-        .long  .Lscls_noretval-.Lscls_store_table      /* FFI_TYPE_VOID */
-        .long  .Lscls_retint-.Lscls_store_table        /* FFI_TYPE_INT */
-        .long  .Lscls_retfloat-.Lscls_store_table      /* FFI_TYPE_FLOAT */
-        .long  .Lscls_retdouble-.Lscls_store_table     /* FFI_TYPE_DOUBLE */
-        .long  .Lscls_retldouble-.Lscls_store_table    /* FFI_TYPE_LONGDOUBLE */
-        .long  .Lscls_retuint8-.Lscls_store_table      /* FFI_TYPE_UINT8 */
-        .long  .Lscls_retsint8-.Lscls_store_table      /* FFI_TYPE_SINT8 */
-        .long  .Lscls_retuint16-.Lscls_store_table     /* FFI_TYPE_UINT16 */
-        .long  .Lscls_retsint16-.Lscls_store_table     /* FFI_TYPE_SINT16 */
-        .long  .Lscls_retint-.Lscls_store_table        /* FFI_TYPE_UINT32 */
-        .long  .Lscls_retint-.Lscls_store_table        /* FFI_TYPE_SINT32 */
-        .long  .Lscls_retllong-.Lscls_store_table      /* FFI_TYPE_UINT64 */
-        .long  .Lscls_retllong-.Lscls_store_table      /* FFI_TYPE_SINT64 */
-        .long  .Lscls_retstruct-.Lscls_store_table     /* FFI_TYPE_STRUCT */
-        .long  .Lscls_retint-.Lscls_store_table        /* FFI_TYPE_POINTER */
-        .long  .Lscls_retstruct1-.Lscls_store_table    /* FFI_TYPE_SMALL_STRUCT_1B */
-        .long  .Lscls_retstruct2-.Lscls_store_table    /* FFI_TYPE_SMALL_STRUCT_2B */
-        .long  .Lscls_retstruct4-.Lscls_store_table    /* FFI_TYPE_SMALL_STRUCT_4B */
-1:
-        shl    $2, %eax
-        add    (%esp),%eax
-        mov    (%eax),%eax
-        add    (%esp),%eax
-        add    $4, %esp
-        jmp    *%eax
-
-        /* Sign/zero extend as appropriate.  */
-.Lscls_retsint8:
-        movsbl (%ecx), %eax
-        jmp    .Lscls_epilogue
-
-.Lscls_retsint16:
-        movswl (%ecx), %eax
-        jmp    .Lscls_epilogue
-
-.Lscls_retuint8:
-        movzbl (%ecx), %eax
-        jmp    .Lscls_epilogue
-
-.Lscls_retuint16:
-        movzwl (%ecx), %eax
-        jmp    .Lscls_epilogue
-
-.Lscls_retint:
-        movl   (%ecx), %eax
-        jmp    .Lscls_epilogue
-
-.Lscls_retfloat:
-        flds   (%ecx)
-        jmp    .Lscls_epilogue
-
-.Lscls_retdouble:
-        fldl   (%ecx)
-        jmp    .Lscls_epilogue
-
-.Lscls_retldouble:
-        fldt   (%ecx)
-        jmp    .Lscls_epilogue
-
-.Lscls_retllong:
-        movl   (%ecx), %eax
-        movl   4(%ecx), %edx
-        jmp    .Lscls_epilogue
-
-.Lscls_retstruct1:
-        movsbl (%ecx), %eax
-        jmp    .Lscls_epilogue
-
-.Lscls_retstruct2:
-        movswl (%ecx), %eax
-        jmp    .Lscls_epilogue
-
-.Lscls_retstruct4:
-        movl   (%ecx), %eax
-        jmp    .Lscls_epilogue
-
-.Lscls_retstruct:
-        # Nothing to do!
-
-.Lscls_noretval:
-.Lscls_epilogue:
-        movl   %ebp, %esp
-        popl   %ebp
-        movl   4(%esp), %ecx /* Return address */
-        addl   (%esp), %esp  /* Parameters stack size */
-        addl   $8, %esp
-        jmp    *%ecx
-.ffi_closure_STDCALL_end:
-.LFE5:
-
-#if defined(X86_DARWIN)
-.section __IMPORT,__jump_table,symbol_stubs,self_modifying_code+pure_instructions,5
-L_ffi_closure_SYSV_inner$stub:
-        .indirect_symbol _ffi_closure_SYSV_inner
-        hlt ; hlt ; hlt ; hlt ; hlt
-L_ffi_closure_WIN32_inner$stub:
-        .indirect_symbol _ffi_closure_WIN32_inner
-        hlt ; hlt ; hlt ; hlt ; hlt
-#endif
-
-#if defined(X86_WIN32) && !defined(__OS2__)
-        .section       .eh_frame,"w"
-#endif
-.Lframe1:
-.LSCIE1:
-        .long  .LECIE1-.LASCIE1  /* Length of Common Information Entry */
-.LASCIE1:
-        .long  0x0     /* CIE Identifier Tag */
-        .byte  0x1     /* CIE Version */
-#ifdef __PIC__
-        .ascii "zR\0"  /* CIE Augmentation */
-#else
-        .ascii "\0"    /* CIE Augmentation */
-#endif
-        .byte  0x1     /* .uleb128 0x1; CIE Code Alignment Factor */
-        .byte  0x7c    /* .sleb128 -4; CIE Data Alignment Factor */
-        .byte  0x8     /* CIE RA Column */
-#ifdef __PIC__
-        .byte  0x1     /* .uleb128 0x1; Augmentation size */
-        .byte  0x1b    /* FDE Encoding (pcrel sdata4) */
-#endif
-        .byte  0xc     /* DW_CFA_def_cfa CFA = r4 + 4 = 4(%esp) */
-        .byte  0x4     /* .uleb128 0x4 */
-        .byte  0x4     /* .uleb128 0x4 */
-        .byte  0x88    /* DW_CFA_offset, column 0x8 %eip at CFA + 1 * -4 */
-        .byte  0x1     /* .uleb128 0x1 */
-        .align 4
-.LECIE1:
-
-.LSFDE1:
-        .long  .LEFDE1-.LASFDE1        /* FDE Length */
-.LASFDE1:
-        .long  .LASFDE1-.Lframe1       /* FDE CIE offset */
-#if defined __PIC__ && defined HAVE_AS_X86_PCREL
-        .long  .LFB1-. /* FDE initial location */
-#else
-        .long  .LFB1
-#endif
-        .long  .LFE1-.LFB1     /* FDE address range */
-#ifdef __PIC__
-        .byte  0x0     /* .uleb128 0x0; Augmentation size */
-#endif
-        /* DW_CFA_xxx CFI instructions go here.  */
-
-        .byte  0x4     /* DW_CFA_advance_loc4 */
-        .long  .LCFI0-.LFB1
-        .byte  0xe     /* DW_CFA_def_cfa_offset CFA = r4 + 8 = 8(%esp) */
-        .byte  0x8     /* .uleb128 0x8 */
-        .byte  0x85    /* DW_CFA_offset, column 0x5 %ebp at CFA + 2 * -4 */
-        .byte  0x2     /* .uleb128 0x2 */
-
-        .byte  0x4     /* DW_CFA_advance_loc4 */
-        .long  .LCFI1-.LCFI0
-        .byte  0xd     /* DW_CFA_def_cfa_register CFA = r5 = %ebp */
-        .byte  0x5     /* .uleb128 0x5 */
-
-        /* End of DW_CFA_xxx CFI instructions.  */
-        .align 4
-.LEFDE1:
-
-.LSFDE3:
-        .long  .LEFDE3-.LASFDE3        /* FDE Length */
-.LASFDE3:
-        .long  .LASFDE3-.Lframe1       /* FDE CIE offset */
-#if defined __PIC__ && defined HAVE_AS_X86_PCREL
-        .long  .LFB3-. /* FDE initial location */
-#else
-        .long  .LFB3
-#endif
-        .long  .LFE3-.LFB3     /* FDE address range */
-#ifdef __PIC__
-        .byte  0x0     /* .uleb128 0x0; Augmentation size */
-#endif
-        /* DW_CFA_xxx CFI instructions go here.  */
-
-        .byte  0x4     /* DW_CFA_advance_loc4 */
-        .long  .LCFI4-.LFB3
-        .byte  0xe     /* DW_CFA_def_cfa_offset CFA = r4 + 8 = 8(%esp) */
-        .byte  0x8     /* .uleb128 0x8 */
-        .byte  0x85    /* DW_CFA_offset, column 0x5 %ebp at CFA + 2 * -4 */
-        .byte  0x2     /* .uleb128 0x2 */
-
-        .byte  0x4     /* DW_CFA_advance_loc4 */
-        .long  .LCFI5-.LCFI4
-        .byte  0xd     /* DW_CFA_def_cfa_register CFA = r5 = %ebp */
-        .byte  0x5     /* .uleb128 0x5 */
-
-        /* End of DW_CFA_xxx CFI instructions.  */
-        .align 4
-.LEFDE3:
-
-#if !FFI_NO_RAW_API
-
-.LSFDE4:
-        .long  .LEFDE4-.LASFDE4        /* FDE Length */
-.LASFDE4:
-        .long  .LASFDE4-.Lframe1       /* FDE CIE offset */
-#if defined __PIC__ && defined HAVE_AS_X86_PCREL
-        .long  .LFB4-. /* FDE initial location */
-#else
-        .long  .LFB4
-#endif
-        .long  .LFE4-.LFB4     /* FDE address range */
-#ifdef __PIC__
-        .byte  0x0     /* .uleb128 0x0; Augmentation size */
-#endif
-        /* DW_CFA_xxx CFI instructions go here.  */
-
-        .byte  0x4     /* DW_CFA_advance_loc4 */
-        .long  .LCFI6-.LFB4
-        .byte  0xe     /* DW_CFA_def_cfa_offset CFA = r4 + 8 = 8(%esp) */
-        .byte  0x8     /* .uleb128 0x8 */
-        .byte  0x85    /* DW_CFA_offset, column 0x5 %ebp at CFA + 2 * -4 */
-        .byte  0x2     /* .uleb128 0x2 */
-
-        .byte  0x4     /* DW_CFA_advance_loc4 */
-        .long  .LCFI7-.LCFI6
-        .byte  0xd     /* DW_CFA_def_cfa_register CFA = r5 = %ebp */
-        .byte  0x5     /* .uleb128 0x5 */
-
-        .byte  0x4     /* DW_CFA_advance_loc4 */
-        .long  .LCFI8-.LCFI7
-        .byte  0x86    /* DW_CFA_offset, column 0x6 %esi at CFA + 3 * -4 */
-        .byte  0x3     /* .uleb128 0x3 */
-
-        /* End of DW_CFA_xxx CFI instructions.  */
-        .align 4
-.LEFDE4:
-
-#endif /* !FFI_NO_RAW_API */
-
-.LSFDE5:
-        .long  .LEFDE5-.LASFDE5        /* FDE Length */
-.LASFDE5:
-        .long  .LASFDE5-.Lframe1       /* FDE CIE offset */
-#if defined __PIC__ && defined HAVE_AS_X86_PCREL
-        .long  .LFB5-. /* FDE initial location */
-#else
-        .long  .LFB5
-#endif
-        .long  .LFE5-.LFB5     /* FDE address range */
-#ifdef __PIC__
-        .byte  0x0     /* .uleb128 0x0; Augmentation size */
-#endif
-        /* DW_CFA_xxx CFI instructions go here.  */
-
-        .byte  0x4     /* DW_CFA_advance_loc4 */
-        .long  .LCFI9-.LFB5
-        .byte  0xe     /* DW_CFA_def_cfa_offset CFA = r4 + 8 = 8(%esp) */
-        .byte  0x8     /* .uleb128 0x8 */
-        .byte  0x85    /* DW_CFA_offset, column 0x5 %ebp at CFA + 2 * -4 */
-        .byte  0x2     /* .uleb128 0x2 */
-
-        .byte  0x4     /* DW_CFA_advance_loc4 */
-        .long  .LCFI10-.LCFI9
-        .byte  0xd     /* DW_CFA_def_cfa_register CFA = r5 = %ebp */
-        .byte  0x5     /* .uleb128 0x5 */
-
-        /* End of DW_CFA_xxx CFI instructions.  */
-        .align 4
-.LEFDE5:
-
-#endif /* !_MSC_VER */
-
-#if defined __ELF__ && defined __linux__
-        .section       .note.GNU-stack,"",@progbits
-#endif