Index: src/x86/ffi.c =================================================================== --- src/x86/ffi.c (revision 131248) +++ src/x86/ffi.c (working copy) @@ -3,9 +3,10 @@ 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 ``Software''), to deal in the Software without restriction, including @@ -121,10 +122,13 @@ 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 @@ 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) { Index: src/x86/ffitarget.h =================================================================== --- src/x86/ffitarget.h (revision 131248) +++ src/x86/ffitarget.h (working copy) @@ -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 @@ /* ---- 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 Index: src/x86/darwin.S =================================================================== --- src/x86/darwin.S (revision 131248) +++ src/x86/darwin.S (working copy) @@ -1,8 +1,9 @@ /* ----------------------------------------------------------------------- - 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 ``Software''), to deal in the Software without restriction, including @@ -60,16 +61,15 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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