diff options
author | Andrew Haley <aph@redhat.com> | 2007-07-31 15:05:52 +0000 |
---|---|---|
committer | Andrew Haley <aph@gcc.gnu.org> | 2007-07-31 15:05:52 +0000 |
commit | 387cfbba39c9e620b9e7425dbee7c32f8ff5f5f0 (patch) | |
tree | 77d7eb285bfcbe2522e9774cf8c6e92ca56bd6a8 /libffi/src | |
parent | 2bde7ae91a1edba5968c32ceb6f10b7b5ea98bfa (diff) | |
download | gcc-387cfbba39c9e620b9e7425dbee7c32f8ff5f5f0.zip gcc-387cfbba39c9e620b9e7425dbee7c32f8ff5f5f0.tar.gz gcc-387cfbba39c9e620b9e7425dbee7c32f8ff5f5f0.tar.bz2 |
re PR testsuite/32843 (libffi.call/return_sc.c)
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.
From-SVN: r127093
Diffstat (limited to 'libffi/src')
-rw-r--r-- | libffi/src/x86/ffi.c | 5 | ||||
-rw-r--r-- | libffi/src/x86/sysv.S | 82 |
2 files changed, 66 insertions, 21 deletions
diff --git a/libffi/src/x86/ffi.c b/libffi/src/x86/ffi.c index b6d42a88..45fb0b9 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 46759f4..a5add26 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 |