diff options
author | Andreas Tobler <a.tobler@schweiz.org> | 2008-01-05 20:49:41 +0000 |
---|---|---|
committer | Andreas Tobler <andreast@gcc.gnu.org> | 2008-01-05 21:49:41 +0100 |
commit | d7b07cc7304ad61bcdf4a1eb7a5a7a15fe856b04 (patch) | |
tree | 1e5407100f6d327c2575e12a2213ac4154a55522 /libffi/src | |
parent | 5a37a60ccbdcbb5ae1c416d7292a0080f7aa0eb5 (diff) | |
download | gcc-d7b07cc7304ad61bcdf4a1eb7a5a7a15fe856b04.zip gcc-d7b07cc7304ad61bcdf4a1eb7a5a7a15fe856b04.tar.gz gcc-d7b07cc7304ad61bcdf4a1eb7a5a7a15fe856b04.tar.bz2 |
re PR testsuite/32843 (libffi.call/return_sc.c)
2008-01-05 Andreas Tobler <a.tobler@schweiz.org>
PR testsuite/32843
* src/x86/ffi.c (ffi_prep_cif_machdep): Add code for
signed/unsigned int8/16 for X86_DARWIN.
Updated copyright info.
Handle one and two byte structs with special cif->flags.
* src/x86/ffitarget.h: Add special types for one and two byte structs.
Updated copyright info.
* src/x86/darwin.S (ffi_call_SYSV): Rewrite to use a jump table like
sysv.S
Remove code to pop args from the stack after call.
Special-case signed/unsigned for int8/16, one and two byte structs.
(ffi_closure_raw_SYSV): Handle FFI_TYPE_UINT8,
FFI_TYPE_SINT8, FFI_TYPE_UINT16, FFI_TYPE_SINT16, FFI_TYPE_UINT32,
FFI_TYPE_SINT32.
Updated copyright info.
From-SVN: r131343
Diffstat (limited to 'libffi/src')
-rw-r--r-- | libffi/src/x86/darwin.S | 149 | ||||
-rw-r--r-- | libffi/src/x86/ffi.c | 12 | ||||
-rw-r--r-- | libffi/src/x86/ffitarget.h | 4 |
3 files changed, 106 insertions, 59 deletions
diff --git a/libffi/src/x86/darwin.S b/libffi/src/x86/darwin.S index aec9b82..eeee802 100644 --- a/libffi/src/x86/darwin.S +++ b/libffi/src/x86/darwin.S @@ -1,7 +1,8 @@ /* ----------------------------------------------------------------------- - sysv.S - Copyright (c) 1996, 1998, 2001, 2002, 2003, 2005 Red Hat, Inc. - - X86 Foreign Function Interface + darwin.S - Copyright (c) 1996, 1998, 2001, 2002, 2003, 2005 Red Hat, Inc. + Copyright (C) 2008 Free Software Foundation, Inc. + + 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 @@ -60,16 +61,15 @@ _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 + /* 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 retint + jne 0f /* Even if there is no space for the return value, we are obliged to handle floating-point values. */ @@ -77,79 +77,102 @@ _ffi_call_SYSV: jne noretval fstp %st(0) - jmp epilogue - -retint: - cmpl $FFI_TYPE_INT,%ecx - jne retfloat - /* Load %ecx with the pointer to storage for the return value */ - movl 24(%ebp),%ecx - movl %eax,0(%ecx) jmp epilogue +0: + .align 4 + 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: - cmpl $FFI_TYPE_FLOAT,%ecx - jne retdouble /* Load %ecx with the pointer to storage for the return value */ - movl 24(%ebp),%ecx + movl 24(%ebp),%ecx fstps (%ecx) jmp epilogue retdouble: - cmpl $FFI_TYPE_DOUBLE,%ecx - jne retlongdouble /* Load %ecx with the pointer to storage for the return value */ - movl 24(%ebp),%ecx + movl 24(%ebp),%ecx fstpl (%ecx) jmp epilogue retlongdouble: - cmpl $FFI_TYPE_LONGDOUBLE,%ecx - jne retint64 /* Load %ecx with the pointer to storage for the return value */ - movl 24(%ebp),%ecx + movl 24(%ebp),%ecx fstpt (%ecx) jmp epilogue - -retint64: - cmpl $FFI_TYPE_SINT64,%ecx - jne retstruct1b + +retint64: /* Load %ecx with the pointer to storage for the return value */ - movl 24(%ebp),%ecx + movl 24(%ebp),%ecx movl %eax,0(%ecx) movl %edx,4(%ecx) jmp epilogue - -retstruct1b: - cmpl $FFI_TYPE_SINT8,%ecx - jne retstruct2b + +retstruct1b: /* Load %ecx with the pointer to storage for the return value */ - movl 24(%ebp),%ecx + movl 24(%ebp),%ecx movb %al,0(%ecx) jmp epilogue -retstruct2b: - cmpl $FFI_TYPE_SINT16,%ecx - jne retstruct +retstruct2b: /* Load %ecx with the pointer to storage for the return value */ - movl 24(%ebp),%ecx + 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: - cmpl $FFI_TYPE_STRUCT,%ecx - jne noretval /* Nothing to do! */ - addl $4,%esp - popl %ebp - ret noretval: epilogue: - addl $8,%esp - movl %ebp,%esp - popl %ebp - ret + popl %esi + movl %ebp,%esp + popl %ebp + ret + .LFE1: .ffi_call_SYSV_end: @@ -177,7 +200,15 @@ _ffi_closure_SYSV: movl -12(%ebp), %ecx cmpl $FFI_TYPE_INT, %eax je .Lcls_retint - cmpl $FFI_TYPE_FLOAT, %eax + + /* 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 @@ -185,10 +216,10 @@ _ffi_closure_SYSV: je .Lcls_retldouble cmpl $FFI_TYPE_SINT64, %eax je .Lcls_retllong - cmpl $FFI_TYPE_SINT8, %eax - je .Lcls_retstruct1 - cmpl $FFI_TYPE_SINT16, %eax - je .Lcls_retstruct2 + 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: @@ -211,10 +242,10 @@ _ffi_closure_SYSV: movl (%ecx), %eax movl 4(%ecx), %edx jmp .Lcls_epilogue -.Lcls_retstruct1: +.Lcls_retstruct1b: movsbl (%ecx), %eax jmp .Lcls_epilogue -.Lcls_retstruct2: +.Lcls_retstruct2b: movswl (%ecx), %eax jmp .Lcls_epilogue .Lcls_retstruct: @@ -256,6 +287,14 @@ _ffi_closure_raw_SYSV: 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 diff --git a/libffi/src/x86/ffi.c b/libffi/src/x86/ffi.c index 45fb0b9..04fca5e 100644 --- a/libffi/src/x86/ffi.c +++ b/libffi/src/x86/ffi.c @@ -3,8 +3,9 @@ Copyright (c) 2002 Ranjit Mathew Copyright (c) 2002 Bo Thorsen Copyright (c) 2002 Roger Sayle - - x86 Foreign Function Interface + Copyright (C) 2008 Free Software Foundation, Inc. + + 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 @@ -121,10 +122,13 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif) case FFI_TYPE_VOID: #ifdef X86 case FFI_TYPE_STRUCT: +#else +# if defined(X86) || defined(X86_DARWIN) case FFI_TYPE_UINT8: case FFI_TYPE_UINT16: case FFI_TYPE_SINT8: case FFI_TYPE_SINT16: +# endif #endif case FFI_TYPE_SINT64: @@ -142,11 +146,11 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif) case FFI_TYPE_STRUCT: if (cif->rtype->size == 1) { - cif->flags = FFI_TYPE_SINT8; /* same as char size */ + cif->flags = FFI_TYPE_SMALL_STRUCT_1B; /* same as char size */ } else if (cif->rtype->size == 2) { - cif->flags = FFI_TYPE_SINT16; /* same as short size */ + cif->flags = FFI_TYPE_SMALL_STRUCT_2B; /* same as short size */ } else if (cif->rtype->size == 4) { diff --git a/libffi/src/x86/ffitarget.h b/libffi/src/x86/ffitarget.h index c44490f..3a1427c 100644 --- a/libffi/src/x86/ffitarget.h +++ b/libffi/src/x86/ffitarget.h @@ -1,5 +1,7 @@ /* -----------------------------------------------------------------*-C-*- ffitarget.h - Copyright (c) 1996-2003 Red Hat, Inc. + Copyright (C) 2008 Free Software Foundation, Inc. + Target configuration macros for x86 and x86-64. Permission is hereby granted, free of charge, to any person obtaining @@ -68,6 +70,8 @@ typedef enum ffi_abi { /* ---- Definitions for closures ----------------------------------------- */ #define FFI_CLOSURES 1 +#define FFI_TYPE_SMALL_STRUCT_1B (FFI_TYPE_LAST + 1) +#define FFI_TYPE_SMALL_STRUCT_2B (FFI_TYPE_LAST + 2) #if defined (X86_64) || (defined (__x86_64__) && defined (X86_DARWIN)) #define FFI_TRAMPOLINE_SIZE 24 |