Commit 723512ba by Dave Korn Committed by Dave Korn

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
parent 80927a56
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> 2009-07-11 Richard Sandiford <rdsandiford@googlemail.com>
PR testsuite/40699 PR testsuite/40699
......
...@@ -165,7 +165,15 @@ selinux_enabled_check (void) ...@@ -165,7 +165,15 @@ selinux_enabled_check (void)
#define is_selinux_enabled() 0 #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) */ #endif /* !defined(X86_WIN32) && !defined(X86_WIN64) */
/* Declare all functions defined in dlmalloc.c as static. */ /* Declare all functions defined in dlmalloc.c as static. */
...@@ -185,11 +193,11 @@ static int dlmalloc_trim(size_t) MAYBE_UNUSED; ...@@ -185,11 +193,11 @@ static int dlmalloc_trim(size_t) MAYBE_UNUSED;
static size_t dlmalloc_usable_size(void*) MAYBE_UNUSED; static size_t dlmalloc_usable_size(void*) MAYBE_UNUSED;
static void dlmalloc_stats(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. */ /* Use these for mmap and munmap within dlmalloc.c. */
static void *dlmmap(void *, size_t, int, int, int, off_t); static void *dlmmap(void *, size_t, int, int, int, off_t);
static int dlmunmap(void *, size_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 mmap dlmmap
#define munmap dlmunmap #define munmap dlmunmap
...@@ -199,7 +207,7 @@ static int dlmunmap(void *, size_t); ...@@ -199,7 +207,7 @@ static int dlmunmap(void *, size_t);
#undef mmap #undef mmap
#undef munmap #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. */ /* A mutex used to synchronize access to *exec* variables in this file. */
static pthread_mutex_t open_temp_exec_file_mutex = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t open_temp_exec_file_mutex = PTHREAD_MUTEX_INITIALIZER;
...@@ -514,7 +522,7 @@ segment_holding_code (mstate m, char* addr) ...@@ -514,7 +522,7 @@ segment_holding_code (mstate m, char* addr)
} }
#endif #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 /* Allocate a chunk of memory with the given size. Returns a pointer
to the writable address, and sets *CODE to the executable to the writable address, and sets *CODE to the executable
......
...@@ -155,7 +155,7 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif) ...@@ -155,7 +155,7 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
#ifdef X86 #ifdef X86
case FFI_TYPE_STRUCT: case FFI_TYPE_STRUCT:
#endif #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_UINT8:
case FFI_TYPE_UINT16: case FFI_TYPE_UINT16:
case FFI_TYPE_SINT8: case FFI_TYPE_SINT8:
......
...@@ -63,86 +63,121 @@ _ffi_call_SYSV: ...@@ -63,86 +63,121 @@ _ffi_call_SYSV:
call *28(%ebp) 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 # Load %ecx with the return type code
movl 20(%ebp),%ecx movl 20(%ebp),%ecx
# If the return value pointer is NULL, assume no return value. # If the return value pointer is NULL, assume no return value.
cmpl $0,24(%ebp) cmpl $0,24(%ebp)
jne retint jne 0f
# Even if there is no space for the return value, we are # Even if there is no space for the return value, we are
# obliged to handle floating-point values. # obliged to handle floating-point values.
cmpl $FFI_TYPE_FLOAT,%ecx cmpl $FFI_TYPE_FLOAT,%ecx
jne noretval jne .Lnoretval
fstp %st(0) fstp %st(0)
jmp epilogue jmp .Lepilogue
retint: 0:
cmpl $FFI_TYPE_INT,%ecx call 1f
jne retfloat # 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 # Load %ecx with the pointer to storage for the return value
movl 24(%ebp),%ecx movl 24(%ebp),%ecx
movl %eax,0(%ecx) movl %eax,0(%ecx)
jmp epilogue jmp .Lepilogue
retfloat: .Lretfloat:
cmpl $FFI_TYPE_FLOAT,%ecx
jne retdouble
# Load %ecx with the pointer to storage for the return value # Load %ecx with the pointer to storage for the return value
movl 24(%ebp),%ecx movl 24(%ebp),%ecx
fstps (%ecx) fstps (%ecx)
jmp epilogue jmp .Lepilogue
retdouble: .Lretdouble:
cmpl $FFI_TYPE_DOUBLE,%ecx
jne retlongdouble
# Load %ecx with the pointer to storage for the return value # Load %ecx with the pointer to storage for the return value
movl 24(%ebp),%ecx movl 24(%ebp),%ecx
fstpl (%ecx) fstpl (%ecx)
jmp epilogue jmp .Lepilogue
retlongdouble: .Lretlongdouble:
cmpl $FFI_TYPE_LONGDOUBLE,%ecx
jne retint64
# Load %ecx with the pointer to storage for the return value # Load %ecx with the pointer to storage for the return value
movl 24(%ebp),%ecx movl 24(%ebp),%ecx
fstpt (%ecx) fstpt (%ecx)
jmp epilogue jmp .Lepilogue
retint64: .Lretint64:
cmpl $FFI_TYPE_SINT64,%ecx
jne retstruct1b
# Load %ecx with the pointer to storage for the return value # Load %ecx with the pointer to storage for the return value
movl 24(%ebp),%ecx movl 24(%ebp),%ecx
movl %eax,0(%ecx) movl %eax,0(%ecx)
movl %edx,4(%ecx) movl %edx,4(%ecx)
jmp .Lepilogue
retstruct1b:
cmpl $FFI_TYPE_SINT8,%ecx .Lretstruct1b:
jne retstruct2b
# Load %ecx with the pointer to storage for the return value # Load %ecx with the pointer to storage for the return value
movl 24(%ebp),%ecx movl 24(%ebp),%ecx
movb %al,0(%ecx) movb %al,0(%ecx)
jmp epilogue jmp .Lepilogue
retstruct2b: .Lretstruct2b:
cmpl $FFI_TYPE_SINT16,%ecx
jne retstruct
# Load %ecx with the pointer to storage for the return value # Load %ecx with the pointer to storage for the return value
movl 24(%ebp),%ecx movl 24(%ebp),%ecx
movw %ax,0(%ecx) movw %ax,0(%ecx)
jmp epilogue jmp .Lepilogue
retstruct: .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! # Nothing to do!
noretval: .Lnoretval:
epilogue: .Lepilogue:
movl %ebp,%esp movl %ebp,%esp
popl %ebp popl %ebp
ret ret
...@@ -185,77 +220,117 @@ _ffi_call_STDCALL: ...@@ -185,77 +220,117 @@ _ffi_call_STDCALL:
# If the return value pointer is NULL, assume no return value. # If the return value pointer is NULL, assume no return value.
cmpl $0,24(%ebp) cmpl $0,24(%ebp)
jne sc_retint jne 0f
# Even if there is no space for the return value, we are # Even if there is no space for the return value, we are
# obliged to handle floating-point values. # obliged to handle floating-point values.
cmpl $FFI_TYPE_FLOAT,%ecx cmpl $FFI_TYPE_FLOAT,%ecx
jne sc_noretval jne .Lsc_noretval
fstp %st(0) fstp %st(0)
jmp sc_epilogue jmp .Lsc_epilogue
sc_retint: 0:
cmpl $FFI_TYPE_INT,%ecx call 1f
jne sc_retfloat # 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 # Load %ecx with the pointer to storage for the return value
movl 24(%ebp),%ecx movl 24(%ebp),%ecx
movl %eax,0(%ecx) movl %eax,0(%ecx)
jmp sc_epilogue jmp .Lsc_epilogue
sc_retfloat: .Lsc_retfloat:
cmpl $FFI_TYPE_FLOAT,%ecx
jne sc_retdouble
# Load %ecx with the pointer to storage for the return value # Load %ecx with the pointer to storage for the return value
movl 24(%ebp),%ecx movl 24(%ebp),%ecx
fstps (%ecx) fstps (%ecx)
jmp sc_epilogue jmp .Lsc_epilogue
sc_retdouble: .Lsc_retdouble:
cmpl $FFI_TYPE_DOUBLE,%ecx
jne sc_retlongdouble
# Load %ecx with the pointer to storage for the return value # Load %ecx with the pointer to storage for the return value
movl 24(%ebp),%ecx movl 24(%ebp),%ecx
fstpl (%ecx) fstpl (%ecx)
jmp sc_epilogue jmp .Lsc_epilogue
sc_retlongdouble: .Lsc_retlongdouble:
cmpl $FFI_TYPE_LONGDOUBLE,%ecx
jne sc_retint64
# Load %ecx with the pointer to storage for the return value # Load %ecx with the pointer to storage for the return value
movl 24(%ebp),%ecx movl 24(%ebp),%ecx
fstpt (%ecx) fstpt (%ecx)
jmp sc_epilogue jmp .Lsc_epilogue
sc_retint64: .Lsc_retint64:
cmpl $FFI_TYPE_SINT64,%ecx
jne sc_retstruct1b
# Load %ecx with the pointer to storage for the return value # Load %ecx with the pointer to storage for the return value
movl 24(%ebp),%ecx movl 24(%ebp),%ecx
movl %eax,0(%ecx) movl %eax,0(%ecx)
movl %edx,4(%ecx) movl %edx,4(%ecx)
jmp .Lsc_epilogue
sc_retstruct1b: .Lsc_retstruct1b:
cmpl $FFI_TYPE_SINT8,%ecx
jne sc_retstruct2b
# Load %ecx with the pointer to storage for the return value # Load %ecx with the pointer to storage for the return value
movl 24(%ebp),%ecx movl 24(%ebp),%ecx
movb %al,0(%ecx) movb %al,0(%ecx)
jmp sc_epilogue jmp .Lsc_epilogue
sc_retstruct2b: .Lsc_retstruct2b:
cmpl $FFI_TYPE_SINT16,%ecx
jne sc_retstruct
# Load %ecx with the pointer to storage for the return value # Load %ecx with the pointer to storage for the return value
movl 24(%ebp),%ecx movl 24(%ebp),%ecx
movw %ax,0(%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! # Nothing to do!
sc_noretval: .Lsc_noretval:
sc_epilogue: .Lsc_epilogue:
movl %ebp,%esp movl %ebp,%esp
popl %ebp popl %ebp
ret ret
...@@ -281,46 +356,98 @@ _ffi_closure_SYSV: ...@@ -281,46 +356,98 @@ _ffi_closure_SYSV:
movl %edx, (%esp) /* &resp */ movl %edx, (%esp) /* &resp */
call _ffi_closure_SYSV_inner call _ffi_closure_SYSV_inner
movl -12(%ebp), %ecx movl -12(%ebp), %ecx
cmpl $FFI_TYPE_INT, %eax
je .Lcls_retint 0:
cmpl $FFI_TYPE_FLOAT, %eax call 1f
je .Lcls_retfloat # Do not insert anything here between the call and the jump table.
cmpl $FFI_TYPE_DOUBLE, %eax .Lcls_store_table:
je .Lcls_retdouble .long .Lcls_noretval /* FFI_TYPE_VOID */
cmpl $FFI_TYPE_LONGDOUBLE, %eax .long .Lcls_retint /* FFI_TYPE_INT */
je .Lcls_retldouble .long .Lcls_retfloat /* FFI_TYPE_FLOAT */
cmpl $FFI_TYPE_SINT64, %eax .long .Lcls_retdouble /* FFI_TYPE_DOUBLE */
je .Lcls_retllong .long .Lcls_retldouble /* FFI_TYPE_LONGDOUBLE */
cmpl $FFI_TYPE_SINT8, %eax /* 1-byte struct */ .long .Lcls_retuint8 /* FFI_TYPE_UINT8 */
je .Lcls_retstruct1 .long .Lcls_retsint8 /* FFI_TYPE_SINT8 */
cmpl $FFI_TYPE_SINT16, %eax /* 2-bytes struct */ .long .Lcls_retuint16 /* FFI_TYPE_UINT16 */
je .Lcls_retstruct2 .long .Lcls_retsint16 /* FFI_TYPE_SINT16 */
.Lcls_epilogue: .long .Lcls_retint /* FFI_TYPE_UINT32 */
movl %ebp, %esp .long .Lcls_retint /* FFI_TYPE_SINT32 */
popl %ebp .long .Lcls_retllong /* FFI_TYPE_UINT64 */
ret .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: .Lcls_retint:
movl (%ecx), %eax movl (%ecx), %eax
jmp .Lcls_epilogue jmp .Lcls_epilogue
.Lcls_retfloat: .Lcls_retfloat:
flds (%ecx) flds (%ecx)
jmp .Lcls_epilogue jmp .Lcls_epilogue
.Lcls_retdouble: .Lcls_retdouble:
fldl (%ecx) fldl (%ecx)
jmp .Lcls_epilogue jmp .Lcls_epilogue
.Lcls_retldouble: .Lcls_retldouble:
fldt (%ecx) fldt (%ecx)
jmp .Lcls_epilogue jmp .Lcls_epilogue
.Lcls_retllong: .Lcls_retllong:
movl (%ecx), %eax movl (%ecx), %eax
movl 4(%ecx), %edx movl 4(%ecx), %edx
jmp .Lcls_epilogue jmp .Lcls_epilogue
.Lcls_retstruct1: .Lcls_retstruct1:
movsbl (%ecx), %eax movsbl (%ecx), %eax
jmp .Lcls_epilogue jmp .Lcls_epilogue
.Lcls_retstruct2: .Lcls_retstruct2:
movswl (%ecx), %eax movswl (%ecx), %eax
jmp .Lcls_epilogue 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: .ffi_closure_SYSV_end:
.LFE3: .LFE3:
...@@ -354,37 +481,94 @@ _ffi_closure_raw_SYSV: ...@@ -354,37 +481,94 @@ _ffi_closure_raw_SYSV:
movl %esi, (%esp) /* cif */ movl %esi, (%esp) /* cif */
call *RAW_CLOSURE_FUN_OFFSET(%eax) /* closure->fun */ call *RAW_CLOSURE_FUN_OFFSET(%eax) /* closure->fun */
movl CIF_FLAGS_OFFSET(%esi), %eax /* rtype */ movl CIF_FLAGS_OFFSET(%esi), %eax /* rtype */
cmpl $FFI_TYPE_INT, %eax 0:
je .Lrcls_retint call 1f
cmpl $FFI_TYPE_FLOAT, %eax # Do not insert anything here between the call and the jump table.
je .Lrcls_retfloat .Lrcls_store_table:
cmpl $FFI_TYPE_DOUBLE, %eax .long .Lrcls_noretval /* FFI_TYPE_VOID */
je .Lrcls_retdouble .long .Lrcls_retint /* FFI_TYPE_INT */
cmpl $FFI_TYPE_LONGDOUBLE, %eax .long .Lrcls_retfloat /* FFI_TYPE_FLOAT */
je .Lrcls_retldouble .long .Lrcls_retdouble /* FFI_TYPE_DOUBLE */
cmpl $FFI_TYPE_SINT64, %eax .long .Lrcls_retldouble /* FFI_TYPE_LONGDOUBLE */
je .Lrcls_retllong .long .Lrcls_retuint8 /* FFI_TYPE_UINT8 */
.Lrcls_epilogue: .long .Lrcls_retsint8 /* FFI_TYPE_SINT8 */
addl $36, %esp .long .Lrcls_retuint16 /* FFI_TYPE_UINT16 */
popl %esi .long .Lrcls_retsint16 /* FFI_TYPE_SINT16 */
popl %ebp .long .Lrcls_retint /* FFI_TYPE_UINT32 */
ret .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: .Lrcls_retint:
movl -24(%ebp), %eax movl -24(%ebp), %eax
jmp .Lrcls_epilogue jmp .Lrcls_epilogue
.Lrcls_retfloat: .Lrcls_retfloat:
flds -24(%ebp) flds -24(%ebp)
jmp .Lrcls_epilogue jmp .Lrcls_epilogue
.Lrcls_retdouble: .Lrcls_retdouble:
fldl -24(%ebp) fldl -24(%ebp)
jmp .Lrcls_epilogue jmp .Lrcls_epilogue
.Lrcls_retldouble: .Lrcls_retldouble:
fldt -24(%ebp) fldt -24(%ebp)
jmp .Lrcls_epilogue jmp .Lrcls_epilogue
.Lrcls_retllong: .Lrcls_retllong:
movl -24(%ebp), %eax movl -24(%ebp), %eax
movl -20(%ebp), %edx movl -20(%ebp), %edx
jmp .Lrcls_epilogue 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: .ffi_closure_raw_SYSV_end:
.LFE4: .LFE4:
...@@ -409,49 +593,93 @@ _ffi_closure_STDCALL: ...@@ -409,49 +593,93 @@ _ffi_closure_STDCALL:
movl %edx, (%esp) /* &resp */ movl %edx, (%esp) /* &resp */
call _ffi_closure_SYSV_inner call _ffi_closure_SYSV_inner
movl -12(%ebp), %ecx movl -12(%ebp), %ecx
/* It would be nice to just share this code with the 0:
duplicate sequence in _ffi_closure_SYSV, if only call 1f
there were some way to represent that in the EH info. */ # Do not insert anything here between the call and the jump table.
cmpl $FFI_TYPE_INT, %eax .Lscls_store_table:
je .Lscls_retint .long .Lscls_noretval /* FFI_TYPE_VOID */
cmpl $FFI_TYPE_FLOAT, %eax .long .Lscls_retint /* FFI_TYPE_INT */
je .Lscls_retfloat .long .Lscls_retfloat /* FFI_TYPE_FLOAT */
cmpl $FFI_TYPE_DOUBLE, %eax .long .Lscls_retdouble /* FFI_TYPE_DOUBLE */
je .Lscls_retdouble .long .Lscls_retldouble /* FFI_TYPE_LONGDOUBLE */
cmpl $FFI_TYPE_LONGDOUBLE, %eax .long .Lscls_retuint8 /* FFI_TYPE_UINT8 */
je .Lscls_retldouble .long .Lscls_retsint8 /* FFI_TYPE_SINT8 */
cmpl $FFI_TYPE_SINT64, %eax .long .Lscls_retuint16 /* FFI_TYPE_UINT16 */
je .Lscls_retllong .long .Lscls_retsint16 /* FFI_TYPE_SINT16 */
cmpl $FFI_TYPE_SINT8, %eax /* 1-byte struct */ .long .Lscls_retint /* FFI_TYPE_UINT32 */
je .Lscls_retstruct1 .long .Lscls_retint /* FFI_TYPE_SINT32 */
cmpl $FFI_TYPE_SINT16, %eax /* 2-bytes struct */ .long .Lscls_retllong /* FFI_TYPE_UINT64 */
je .Lscls_retstruct2 .long .Lscls_retllong /* FFI_TYPE_SINT64 */
.Lscls_epilogue: .long .Lscls_retstruct /* FFI_TYPE_STRUCT */
movl %ebp, %esp .long .Lscls_retint /* FFI_TYPE_POINTER */
popl %ebp .long .Lscls_retstruct1 /* FFI_TYPE_SMALL_STRUCT_1B */
ret .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: .Lscls_retint:
movl (%ecx), %eax movl (%ecx), %eax
jmp .Lscls_epilogue jmp .Lscls_epilogue
.Lscls_retfloat: .Lscls_retfloat:
flds (%ecx) flds (%ecx)
jmp .Lscls_epilogue jmp .Lscls_epilogue
.Lscls_retdouble: .Lscls_retdouble:
fldl (%ecx) fldl (%ecx)
jmp .Lscls_epilogue jmp .Lscls_epilogue
.Lscls_retldouble: .Lscls_retldouble:
fldt (%ecx) fldt (%ecx)
jmp .Lscls_epilogue jmp .Lscls_epilogue
.Lscls_retllong: .Lscls_retllong:
movl (%ecx), %eax movl (%ecx), %eax
movl 4(%ecx), %edx movl 4(%ecx), %edx
jmp .Lscls_epilogue jmp .Lscls_epilogue
.Lscls_retstruct1: .Lscls_retstruct1:
movsbl (%ecx), %eax movsbl (%ecx), %eax
jmp .Lscls_epilogue jmp .Lscls_epilogue
.Lscls_retstruct2: .Lscls_retstruct2:
movswl (%ecx), %eax movswl (%ecx), %eax
jmp .Lscls_epilogue 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: .ffi_closure_STDCALL_end:
.LFE5: .LFE5:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment