diff options
author | aph <aph@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-07-31 15:05:52 +0000 |
---|---|---|
committer | aph <aph@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-07-31 15:05:52 +0000 |
commit | f6179f0eb3c5d8180dd8cc23796b8f54ead1a57b (patch) | |
tree | 77d7eb285bfcbe2522e9774cf8c6e92ca56bd6a8 /libffi | |
parent | 1915b15f78dba46b19ab76aab06a03db5cc1825d (diff) | |
download | gcc-f6179f0eb3c5d8180dd8cc23796b8f54ead1a57b.tar.gz |
2007-07-30 Andrew Haley <aph@redhat.com>
PR testsuite/32843
* src/x86/ffi.c (ffi_prep_cif_machdep): in x86 case, add code for
signed/unsigned int8/16.
* src/x86/sysv.S (ffi_call_SYSV): Rewrite to:
Use a jump table.
Remove code to pop args from the stack after call.
Special-case signed/unsigned int8/16.
* testsuite/libffi.call/return_sc.c (main): Revert.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@127093 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libffi')
-rw-r--r-- | libffi/ChangeLog | 11 | ||||
-rw-r--r-- | libffi/src/x86/ffi.c | 5 | ||||
-rw-r--r-- | libffi/src/x86/sysv.S | 82 | ||||
-rw-r--r-- | libffi/testsuite/libffi.call/return_sc.c | 2 |
4 files changed, 78 insertions, 22 deletions
diff --git a/libffi/ChangeLog b/libffi/ChangeLog index 9c3249e5822..de4ee0a7e95 100644 --- a/libffi/ChangeLog +++ b/libffi/ChangeLog @@ -1,3 +1,14 @@ +2007-07-30 Andrew Haley <aph@redhat.com> + + PR testsuite/32843 + * src/x86/ffi.c (ffi_prep_cif_machdep): in x86 case, add code for + signed/unsigned int8/16. + * src/x86/sysv.S (ffi_call_SYSV): Rewrite to: + Use a jump table. + Remove code to pop args from the stack after call. + Special-case signed/unsigned int8/16. + * testsuite/libffi.call/return_sc.c (main): Revert. + 2007-07-26 Richard Guenther <rguenther@suse.de> PR testsuite/32843 diff --git a/libffi/src/x86/ffi.c b/libffi/src/x86/ffi.c index b6d42a889d3..45fb0b9a0b9 100644 --- a/libffi/src/x86/ffi.c +++ b/libffi/src/x86/ffi.c @@ -121,7 +121,12 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif) case FFI_TYPE_VOID: #ifdef X86 case FFI_TYPE_STRUCT: + case FFI_TYPE_UINT8: + case FFI_TYPE_UINT16: + case FFI_TYPE_SINT8: + case FFI_TYPE_SINT16: #endif + case FFI_TYPE_SINT64: case FFI_TYPE_FLOAT: case FFI_TYPE_DOUBLE: diff --git a/libffi/src/x86/sysv.S b/libffi/src/x86/sysv.S index 46759f43498..a5add26d1dc 100644 --- a/libffi/src/x86/sysv.S +++ b/libffi/src/x86/sysv.S @@ -59,16 +59,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. */ @@ -78,51 +77,84 @@ ffi_call_SYSV: 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: + 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 */ + +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 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 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 fstpt (%ecx) jmp epilogue retint64: - cmpl $FFI_TYPE_SINT64,%ecx - jne retstruct /* 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 +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 @@ -162,7 +194,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 diff --git a/libffi/testsuite/libffi.call/return_sc.c b/libffi/testsuite/libffi.call/return_sc.c index ddb26778695..19608ee7c8b 100644 --- a/libffi/testsuite/libffi.call/return_sc.c +++ b/libffi/testsuite/libffi.call/return_sc.c @@ -30,7 +30,7 @@ int main (void) sc < (signed char) 127; sc++) { ffi_call(&cif, FFI_FN(return_sc), &rint, values); - CHECK((signed char) rint == sc); + CHECK(rint == (ffi_arg) sc); } exit(0); } |