aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Korn <dave.korn.cygwin@gmail.com>2009-07-24 10:12:16 +0000
committerDave Korn <davek@gcc.gnu.org>2009-07-24 10:12:16 +0000
commit723512bab1d6cb7805d398a05ac7c131722daaec (patch)
treed5adfebe5e95b2f17877a51afb2d4b4208c5a479
parent80927a562e1ec4a38a12f4b09b86f2f3ca9f253e (diff)
downloadgcc-723512bab1d6cb7805d398a05ac7c131722daaec.zip
gcc-723512bab1d6cb7805d398a05ac7c131722daaec.tar.gz
gcc-723512bab1d6cb7805d398a05ac7c131722daaec.tar.bz2
re PR libffi/40807 (libffi.call/return_sc.c)
PR libffi/40807 * src/x86/ffi.c (ffi_prep_cif_machdep): Also use sign/zero-extending return types for X86_WIN32. * src/x86/win32.S (_ffi_call_SYSV): Handle omitted return types. (_ffi_call_STDCALL, _ffi_closure_SYSV, _ffi_closure_raw_SYSV, _ffi_closure_STDCALL): Likewise. * src/closures.c (is_selinux_enabled): Define to const 0 for Cygwin. (dlmmap, dlmunmap): Also use these functions on Cygwin. From-SVN: r150042
-rw-r--r--libffi/ChangeLog12
-rw-r--r--libffi/src/closures.c18
-rw-r--r--libffi/src/x86/ffi.c2
-rw-r--r--libffi/src/x86/win32.S484
4 files changed, 382 insertions, 134 deletions
diff --git a/libffi/ChangeLog b/libffi/ChangeLog
index 7ba04c2..9af1e44 100644
--- a/libffi/ChangeLog
+++ b/libffi/ChangeLog
@@ -1,3 +1,15 @@
+2009-07-24 Dave Korn <dave.korn.cygwin@gmail.com>
+
+ PR libffi/40807
+ * src/x86/ffi.c (ffi_prep_cif_machdep): Also use sign/zero-extending
+ return types for X86_WIN32.
+ * src/x86/win32.S (_ffi_call_SYSV): Handle omitted return types.
+ (_ffi_call_STDCALL, _ffi_closure_SYSV, _ffi_closure_raw_SYSV,
+ _ffi_closure_STDCALL): Likewise.
+
+ * src/closures.c (is_selinux_enabled): Define to const 0 for Cygwin.
+ (dlmmap, dlmunmap): Also use these functions on Cygwin.
+
2009-07-11 Richard Sandiford <rdsandiford@googlemail.com>
PR testsuite/40699
diff --git a/libffi/src/closures.c b/libffi/src/closures.c
index 7692c85..f07ad06 100644
--- a/libffi/src/closures.c
+++ b/libffi/src/closures.c
@@ -165,7 +165,15 @@ selinux_enabled_check (void)
#define is_selinux_enabled() 0
-#endif
+#endif /* !FFI_MMAP_EXEC_SELINUX */
+
+#elif defined (__CYGWIN__)
+
+#include <sys/mman.h>
+
+/* Cygwin is Linux-like, but not quite that Linux-like. */
+#define is_selinux_enabled() 0
+
#endif /* !defined(X86_WIN32) && !defined(X86_WIN64) */
/* Declare all functions defined in dlmalloc.c as static. */
@@ -185,11 +193,11 @@ static int dlmalloc_trim(size_t) MAYBE_UNUSED;
static size_t dlmalloc_usable_size(void*) MAYBE_UNUSED;
static void dlmalloc_stats(void) MAYBE_UNUSED;
-#if !defined(X86_WIN32) && !defined(X86_WIN64)
+#if !(defined(X86_WIN32) || defined(X86_WIN64)) || defined (__CYGWIN__)
/* Use these for mmap and munmap within dlmalloc.c. */
static void *dlmmap(void *, size_t, int, int, int, off_t);
static int dlmunmap(void *, size_t);
-#endif /* !defined(X86_WIN32) && !defined(X86_WIN64) */
+#endif /* !(defined(X86_WIN32) || defined(X86_WIN64)) || defined (__CYGWIN__) */
#define mmap dlmmap
#define munmap dlmunmap
@@ -199,7 +207,7 @@ static int dlmunmap(void *, size_t);
#undef mmap
#undef munmap
-#if !defined(X86_WIN32) && !defined(X86_WIN64)
+#if !(defined(X86_WIN32) || defined(X86_WIN64)) || defined (__CYGWIN__)
/* A mutex used to synchronize access to *exec* variables in this file. */
static pthread_mutex_t open_temp_exec_file_mutex = PTHREAD_MUTEX_INITIALIZER;
@@ -514,7 +522,7 @@ segment_holding_code (mstate m, char* addr)
}
#endif
-#endif /* !defined(X86_WIN32) && !defined(X86_WIN64) */
+#endif /* !(defined(X86_WIN32) || defined(X86_WIN64)) || defined (__CYGWIN__) */
/* Allocate a chunk of memory with the given size. Returns a pointer
to the writable address, and sets *CODE to the executable
diff --git a/libffi/src/x86/ffi.c b/libffi/src/x86/ffi.c
index c89c8fc..a5f506d 100644
--- a/libffi/src/x86/ffi.c
+++ b/libffi/src/x86/ffi.c
@@ -155,7 +155,7 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
#ifdef X86
case FFI_TYPE_STRUCT:
#endif
-#if defined(X86) || defined(X86_DARWIN) || defined(X86_WIN64)
+#if defined(X86) || defined (X86_WIN32) || defined(X86_DARWIN) || defined(X86_WIN64)
case FFI_TYPE_UINT8:
case FFI_TYPE_UINT16:
case FFI_TYPE_SINT8:
diff --git a/libffi/src/x86/win32.S b/libffi/src/x86/win32.S
index a1de858..7489dab 100644
--- a/libffi/src/x86/win32.S
+++ b/libffi/src/x86/win32.S
@@ -63,86 +63,121 @@ _ffi_call_SYSV:
call *28(%ebp)
- # Remove the space we pushed for the args
- movl 16(%ebp),%ecx
- addl %ecx,%esp
-
# Load %ecx with the return type code
movl 20(%ebp),%ecx
# If the return value pointer is NULL, assume no return value.
cmpl $0,24(%ebp)
- jne retint
+ 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
+ jne .Lnoretval
fstp %st(0)
- jmp epilogue
-
-retint:
- cmpl $FFI_TYPE_INT,%ecx
- jne retfloat
+ jmp .Lepilogue
+
+0:
+ call 1f
+ # Do not insert anything here between the call and the jump table.
+.Lstore_table:
+ .long .Lnoretval /* FFI_TYPE_VOID */
+ .long .Lretint /* FFI_TYPE_INT */
+ .long .Lretfloat /* FFI_TYPE_FLOAT */
+ .long .Lretdouble /* FFI_TYPE_DOUBLE */
+ .long .Lretlongdouble /* FFI_TYPE_LONGDOUBLE */
+ .long .Lretuint8 /* FFI_TYPE_UINT8 */
+ .long .Lretsint8 /* FFI_TYPE_SINT8 */
+ .long .Lretuint16 /* FFI_TYPE_UINT16 */
+ .long .Lretsint16 /* FFI_TYPE_SINT16 */
+ .long .Lretint /* FFI_TYPE_UINT32 */
+ .long .Lretint /* FFI_TYPE_SINT32 */
+ .long .Lretint64 /* FFI_TYPE_UINT64 */
+ .long .Lretint64 /* FFI_TYPE_SINT64 */
+ .long .Lretstruct /* FFI_TYPE_STRUCT */
+ .long .Lretint /* FFI_TYPE_POINTER */
+ .long .Lretstruct1b /* FFI_TYPE_SMALL_STRUCT_1B */
+ .long .Lretstruct2b /* FFI_TYPE_SMALL_STRUCT_2B */
+ .long .Lretstruct4b /* FFI_TYPE_SMALL_STRUCT_4B */
+1:
+ add %ecx, %ecx
+ add %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 24(%ebp),%ecx
movl %eax,0(%ecx)
- jmp epilogue
+ jmp .Lepilogue
-retfloat:
- cmpl $FFI_TYPE_FLOAT,%ecx
- jne retdouble
+.Lretfloat:
# Load %ecx with the pointer to storage for the return value
movl 24(%ebp),%ecx
fstps (%ecx)
- jmp epilogue
+ jmp .Lepilogue
-retdouble:
- cmpl $FFI_TYPE_DOUBLE,%ecx
- jne retlongdouble
+.Lretdouble:
# Load %ecx with the pointer to storage for the return value
movl 24(%ebp),%ecx
fstpl (%ecx)
- jmp epilogue
+ jmp .Lepilogue
-retlongdouble:
- cmpl $FFI_TYPE_LONGDOUBLE,%ecx
- jne retint64
+.Lretlongdouble:
# Load %ecx with the pointer to storage for the return value
movl 24(%ebp),%ecx
fstpt (%ecx)
- jmp epilogue
+ jmp .Lepilogue
-retint64:
- cmpl $FFI_TYPE_SINT64,%ecx
- jne retstruct1b
+.Lretint64:
# Load %ecx with the pointer to storage for the return value
movl 24(%ebp),%ecx
movl %eax,0(%ecx)
movl %edx,4(%ecx)
-
-retstruct1b:
- cmpl $FFI_TYPE_SINT8,%ecx
- jne retstruct2b
+ jmp .Lepilogue
+
+.Lretstruct1b:
# Load %ecx with the pointer to storage for the return value
movl 24(%ebp),%ecx
movb %al,0(%ecx)
- jmp epilogue
+ jmp .Lepilogue
-retstruct2b:
- cmpl $FFI_TYPE_SINT16,%ecx
- jne retstruct
+.Lretstruct2b:
# Load %ecx with the pointer to storage for the return value
movl 24(%ebp),%ecx
movw %ax,0(%ecx)
- jmp epilogue
-
-retstruct:
+ jmp .Lepilogue
+
+.Lretstruct4b:
+ # Load %ecx with the pointer to storage for the return value
+ movl 24(%ebp),%ecx
+ movl %eax,0(%ecx)
+ jmp .Lepilogue
+
+.Lretstruct:
# Nothing to do!
-noretval:
-epilogue:
+.Lnoretval:
+.Lepilogue:
movl %ebp,%esp
popl %ebp
ret
@@ -185,77 +220,117 @@ _ffi_call_STDCALL:
# If the return value pointer is NULL, assume no return value.
cmpl $0,24(%ebp)
- jne sc_retint
+ 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 sc_noretval
+ jne .Lsc_noretval
fstp %st(0)
- jmp sc_epilogue
-
-sc_retint:
- cmpl $FFI_TYPE_INT,%ecx
- jne sc_retfloat
+ jmp .Lsc_epilogue
+
+0:
+ call 1f
+ # Do not insert anything here between the call and the jump table.
+.Lsc_store_table:
+ .long .Lsc_noretval /* FFI_TYPE_VOID */
+ .long .Lsc_retint /* FFI_TYPE_INT */
+ .long .Lsc_retfloat /* FFI_TYPE_FLOAT */
+ .long .Lsc_retdouble /* FFI_TYPE_DOUBLE */
+ .long .Lsc_retlongdouble /* FFI_TYPE_LONGDOUBLE */
+ .long .Lsc_retuint8 /* FFI_TYPE_UINT8 */
+ .long .Lsc_retsint8 /* FFI_TYPE_SINT8 */
+ .long .Lsc_retuint16 /* FFI_TYPE_UINT16 */
+ .long .Lsc_retsint16 /* FFI_TYPE_SINT16 */
+ .long .Lsc_retint /* FFI_TYPE_UINT32 */
+ .long .Lsc_retint /* FFI_TYPE_SINT32 */
+ .long .Lsc_retint64 /* FFI_TYPE_UINT64 */
+ .long .Lsc_retint64 /* FFI_TYPE_SINT64 */
+ .long .Lsc_retstruct /* FFI_TYPE_STRUCT */
+ .long .Lsc_retint /* FFI_TYPE_POINTER */
+ .long .Lsc_retstruct1b /* FFI_TYPE_SMALL_STRUCT_1B */
+ .long .Lsc_retstruct2b /* FFI_TYPE_SMALL_STRUCT_2B */
+ .long .Lsc_retstruct4b /* FFI_TYPE_SMALL_STRUCT_4B */
+
+1:
+ add %ecx, %ecx
+ add %ecx, %ecx
+ add (%esp),%ecx
+ add $4, %esp
+ jmp *(%ecx)
+
+ /* Sign/zero extend as appropriate. */
+.Lsc_retsint8:
+ movsbl %al, %eax
+ jmp .Lsc_retint
+
+.Lsc_retsint16:
+ movswl %ax, %eax
+ jmp .Lsc_retint
+
+.Lsc_retuint8:
+ movzbl %al, %eax
+ jmp .Lsc_retint
+
+.Lsc_retuint16:
+ movzwl %ax, %eax
+ jmp .Lsc_retint
+
+.Lsc_retint:
# Load %ecx with the pointer to storage for the return value
movl 24(%ebp),%ecx
movl %eax,0(%ecx)
- jmp sc_epilogue
+ jmp .Lsc_epilogue
-sc_retfloat:
- cmpl $FFI_TYPE_FLOAT,%ecx
- jne sc_retdouble
+.Lsc_retfloat:
# Load %ecx with the pointer to storage for the return value
movl 24(%ebp),%ecx
fstps (%ecx)
- jmp sc_epilogue
+ jmp .Lsc_epilogue
-sc_retdouble:
- cmpl $FFI_TYPE_DOUBLE,%ecx
- jne sc_retlongdouble
+.Lsc_retdouble:
# Load %ecx with the pointer to storage for the return value
movl 24(%ebp),%ecx
fstpl (%ecx)
- jmp sc_epilogue
+ jmp .Lsc_epilogue
-sc_retlongdouble:
- cmpl $FFI_TYPE_LONGDOUBLE,%ecx
- jne sc_retint64
+.Lsc_retlongdouble:
# Load %ecx with the pointer to storage for the return value
movl 24(%ebp),%ecx
fstpt (%ecx)
- jmp sc_epilogue
+ jmp .Lsc_epilogue
-sc_retint64:
- cmpl $FFI_TYPE_SINT64,%ecx
- jne sc_retstruct1b
+.Lsc_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 .Lsc_epilogue
-sc_retstruct1b:
- cmpl $FFI_TYPE_SINT8,%ecx
- jne sc_retstruct2b
+.Lsc_retstruct1b:
# Load %ecx with the pointer to storage for the return value
movl 24(%ebp),%ecx
movb %al,0(%ecx)
- jmp sc_epilogue
+ jmp .Lsc_epilogue
-sc_retstruct2b:
- cmpl $FFI_TYPE_SINT16,%ecx
- jne sc_retstruct
+.Lsc_retstruct2b:
# Load %ecx with the pointer to storage for the return value
movl 24(%ebp),%ecx
movw %ax,0(%ecx)
- jmp sc_epilogue
+ jmp .Lsc_epilogue
+
+.Lsc_retstruct4b:
+ # Load %ecx with the pointer to storage for the return value
+ movl 24(%ebp),%ecx
+ movl %eax,0(%ecx)
+ jmp .Lsc_epilogue
-sc_retstruct:
+.Lsc_retstruct:
# Nothing to do!
-sc_noretval:
-sc_epilogue:
+.Lsc_noretval:
+.Lsc_epilogue:
movl %ebp,%esp
popl %ebp
ret
@@ -281,46 +356,98 @@ _ffi_closure_SYSV:
movl %edx, (%esp) /* &resp */
call _ffi_closure_SYSV_inner
movl -12(%ebp), %ecx
- cmpl $FFI_TYPE_INT, %eax
- je .Lcls_retint
- 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_SINT8, %eax /* 1-byte struct */
- je .Lcls_retstruct1
- cmpl $FFI_TYPE_SINT16, %eax /* 2-bytes struct */
- je .Lcls_retstruct2
-.Lcls_epilogue:
- movl %ebp, %esp
- popl %ebp
- ret
+
+0:
+ call 1f
+ # Do not insert anything here between the call and the jump table.
+.Lcls_store_table:
+ .long .Lcls_noretval /* FFI_TYPE_VOID */
+ .long .Lcls_retint /* FFI_TYPE_INT */
+ .long .Lcls_retfloat /* FFI_TYPE_FLOAT */
+ .long .Lcls_retdouble /* FFI_TYPE_DOUBLE */
+ .long .Lcls_retldouble /* FFI_TYPE_LONGDOUBLE */
+ .long .Lcls_retuint8 /* FFI_TYPE_UINT8 */
+ .long .Lcls_retsint8 /* FFI_TYPE_SINT8 */
+ .long .Lcls_retuint16 /* FFI_TYPE_UINT16 */
+ .long .Lcls_retsint16 /* FFI_TYPE_SINT16 */
+ .long .Lcls_retint /* FFI_TYPE_UINT32 */
+ .long .Lcls_retint /* FFI_TYPE_SINT32 */
+ .long .Lcls_retllong /* FFI_TYPE_UINT64 */
+ .long .Lcls_retllong /* FFI_TYPE_SINT64 */
+ .long .Lcls_retstruct /* FFI_TYPE_STRUCT */
+ .long .Lcls_retint /* FFI_TYPE_POINTER */
+ .long .Lcls_retstruct1 /* FFI_TYPE_SMALL_STRUCT_1B */
+ .long .Lcls_retstruct2 /* FFI_TYPE_SMALL_STRUCT_2B */
+ .long .Lcls_retstruct4 /* FFI_TYPE_SMALL_STRUCT_4B */
+
+1:
+ add %eax, %eax
+ add %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_noretval:
+.Lcls_epilogue:
+ movl %ebp, %esp
+ popl %ebp
+ ret
.ffi_closure_SYSV_end:
.LFE3:
@@ -354,37 +481,94 @@ _ffi_closure_raw_SYSV:
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
- 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
+0:
+ call 1f
+ # Do not insert anything here between the call and the jump table.
+.Lrcls_store_table:
+ .long .Lrcls_noretval /* FFI_TYPE_VOID */
+ .long .Lrcls_retint /* FFI_TYPE_INT */
+ .long .Lrcls_retfloat /* FFI_TYPE_FLOAT */
+ .long .Lrcls_retdouble /* FFI_TYPE_DOUBLE */
+ .long .Lrcls_retldouble /* FFI_TYPE_LONGDOUBLE */
+ .long .Lrcls_retuint8 /* FFI_TYPE_UINT8 */
+ .long .Lrcls_retsint8 /* FFI_TYPE_SINT8 */
+ .long .Lrcls_retuint16 /* FFI_TYPE_UINT16 */
+ .long .Lrcls_retsint16 /* FFI_TYPE_SINT16 */
+ .long .Lrcls_retint /* FFI_TYPE_UINT32 */
+ .long .Lrcls_retint /* FFI_TYPE_SINT32 */
+ .long .Lrcls_retllong /* FFI_TYPE_UINT64 */
+ .long .Lrcls_retllong /* FFI_TYPE_SINT64 */
+ .long .Lrcls_retstruct /* FFI_TYPE_STRUCT */
+ .long .Lrcls_retint /* FFI_TYPE_POINTER */
+ .long .Lrcls_retstruct1 /* FFI_TYPE_SMALL_STRUCT_1B */
+ .long .Lrcls_retstruct2 /* FFI_TYPE_SMALL_STRUCT_2B */
+ .long .Lrcls_retstruct4 /* FFI_TYPE_SMALL_STRUCT_4B */
+1:
+ add %eax, %eax
+ add %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:
@@ -409,49 +593,93 @@ _ffi_closure_STDCALL:
movl %edx, (%esp) /* &resp */
call _ffi_closure_SYSV_inner
movl -12(%ebp), %ecx
- /* It would be nice to just share this code with the
- duplicate sequence in _ffi_closure_SYSV, if only
- there were some way to represent that in the EH info. */
- cmpl $FFI_TYPE_INT, %eax
- je .Lscls_retint
- cmpl $FFI_TYPE_FLOAT, %eax
- je .Lscls_retfloat
- cmpl $FFI_TYPE_DOUBLE, %eax
- je .Lscls_retdouble
- cmpl $FFI_TYPE_LONGDOUBLE, %eax
- je .Lscls_retldouble
- cmpl $FFI_TYPE_SINT64, %eax
- je .Lscls_retllong
- cmpl $FFI_TYPE_SINT8, %eax /* 1-byte struct */
- je .Lscls_retstruct1
- cmpl $FFI_TYPE_SINT16, %eax /* 2-bytes struct */
- je .Lscls_retstruct2
-.Lscls_epilogue:
- movl %ebp, %esp
- popl %ebp
- ret
+0:
+ call 1f
+ # Do not insert anything here between the call and the jump table.
+.Lscls_store_table:
+ .long .Lscls_noretval /* FFI_TYPE_VOID */
+ .long .Lscls_retint /* FFI_TYPE_INT */
+ .long .Lscls_retfloat /* FFI_TYPE_FLOAT */
+ .long .Lscls_retdouble /* FFI_TYPE_DOUBLE */
+ .long .Lscls_retldouble /* FFI_TYPE_LONGDOUBLE */
+ .long .Lscls_retuint8 /* FFI_TYPE_UINT8 */
+ .long .Lscls_retsint8 /* FFI_TYPE_SINT8 */
+ .long .Lscls_retuint16 /* FFI_TYPE_UINT16 */
+ .long .Lscls_retsint16 /* FFI_TYPE_SINT16 */
+ .long .Lscls_retint /* FFI_TYPE_UINT32 */
+ .long .Lscls_retint /* FFI_TYPE_SINT32 */
+ .long .Lscls_retllong /* FFI_TYPE_UINT64 */
+ .long .Lscls_retllong /* FFI_TYPE_SINT64 */
+ .long .Lscls_retstruct /* FFI_TYPE_STRUCT */
+ .long .Lscls_retint /* FFI_TYPE_POINTER */
+ .long .Lscls_retstruct1 /* FFI_TYPE_SMALL_STRUCT_1B */
+ .long .Lscls_retstruct2 /* FFI_TYPE_SMALL_STRUCT_2B */
+ .long .Lscls_retstruct4 /* FFI_TYPE_SMALL_STRUCT_4B */
+1:
+ add %eax, %eax
+ add %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
+ ret
.ffi_closure_STDCALL_end:
.LFE5: