Switch to quilt. Rebase to latest GCC.

This commit is contained in:
Anthony Green
2009-12-23 23:46:22 -05:00
parent ce806772f0
commit f8c7a245bf
8 changed files with 44669 additions and 0 deletions

928
patches/avr32 Normal file
View File

@@ -0,0 +1,928 @@
Index: plibffi/src/avr32/ffi.c
===================================================================
--- /dev/null
+++ plibffi/src/avr32/ffi.c
@@ -0,0 +1,421 @@
+/* -----------------------------------------------------------------------
+ ffi.c - Copyright (c) 2009 Bradley Smith <brad@brad-smith.co.uk>
+
+ AVR32 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
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
+ ----------------------------------------------------------------------- */
+
+#include <ffi.h>
+#include <ffi_common.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <asm/unistd.h>
+
+/* #define DEBUG */
+
+extern void ffi_call_SYSV(void (*)(char *, extended_cif *), extended_cif *,
+ unsigned int, unsigned int, unsigned int*, unsigned int,
+ void (*fn)(void));
+extern void ffi_closure_SYSV (ffi_closure *);
+
+unsigned int pass_struct_on_stack(ffi_type *type)
+{
+ if(type->type != FFI_TYPE_STRUCT)
+ return 0;
+
+ if(type->alignment < type->size &&
+ !(type->size == 4 || type->size == 8) &&
+ !(type->size == 8 && type->alignment >= 4))
+ return 1;
+
+ if(type->size == 3 || type->size == 5 || type->size == 6 ||
+ type->size == 7)
+ return 1;
+
+ return 0;
+}
+
+/* ffi_prep_args is called by the assembly routine once stack space
+ * has been allocated for the function's arguments
+ *
+ * This is annoyingly complex since we need to keep track of used
+ * registers.
+ */
+
+void ffi_prep_args(char *stack, extended_cif *ecif)
+{
+ unsigned int i;
+ void **p_argv;
+ ffi_type **p_arg;
+ char *reg_base = stack;
+ char *stack_base = stack + 20;
+ unsigned int stack_offset = 0;
+ unsigned int reg_mask = 0;
+
+ p_argv = ecif->avalue;
+
+ /* If cif->flags is struct then we know it's not passed in registers */
+ if(ecif->cif->flags == FFI_TYPE_STRUCT)
+ {
+ *(void**)reg_base = ecif->rvalue;
+ reg_mask |= 1;
+ }
+
+ for(i = 0, p_arg = ecif->cif->arg_types; i < ecif->cif->nargs;
+ i++, p_arg++)
+ {
+ size_t z = (*p_arg)->size;
+ int alignment = (*p_arg)->alignment;
+ int type = (*p_arg)->type;
+ char *addr = 0;
+
+ if(z % 4 != 0)
+ z += (4 - z % 4);
+
+ if(reg_mask != 0x1f)
+ {
+ if(pass_struct_on_stack(*p_arg))
+ {
+ addr = stack_base + stack_offset;
+ stack_offset += z;
+ }
+ else if(z == sizeof(int))
+ {
+ char index = 0;
+
+ while((reg_mask >> index) & 1)
+ index++;
+
+ addr = reg_base + (index * 4);
+ reg_mask |= (1 << index);
+ }
+ else if(z == 2 * sizeof(int))
+ {
+ if(!((reg_mask >> 1) & 1))
+ {
+ addr = reg_base + 4;
+ reg_mask |= (3 << 1);
+ }
+ else if(!((reg_mask >> 3) & 1))
+ {
+ addr = reg_base + 12;
+ reg_mask |= (3 << 3);
+ }
+ }
+ }
+
+ if(!addr)
+ {
+ addr = stack_base + stack_offset;
+ stack_offset += z;
+ }
+
+ if(type == FFI_TYPE_STRUCT && (*p_arg)->elements[1] == NULL)
+ type = (*p_arg)->elements[0]->type;
+
+ switch(type)
+ {
+ case FFI_TYPE_UINT8:
+ *(unsigned int *)addr = (unsigned int)*(UINT8 *)(*p_argv);
+ break;
+ case FFI_TYPE_SINT8:
+ *(signed int *)addr = (signed int)*(SINT8 *)(*p_argv);
+ break;
+ case FFI_TYPE_UINT16:
+ *(unsigned int *)addr = (unsigned int)*(UINT16 *)(*p_argv);
+ break;
+ case FFI_TYPE_SINT16:
+ *(signed int *)addr = (signed int)*(SINT16 *)(*p_argv);
+ break;
+ default:
+ memcpy(addr, *p_argv, z);
+ }
+
+ p_argv++;
+ }
+
+#ifdef DEBUG
+ /* Debugging */
+ for(i = 0; i < 5; i++)
+ {
+ if((reg_mask & (1 << i)) == 0)
+ printf("r%d: (unused)\n", 12 - i);
+ else
+ printf("r%d: 0x%08x\n", 12 - i, ((unsigned int*)reg_base)[i]);
+ }
+
+ for(i = 0; i < stack_offset / 4; i++)
+ {
+ printf("sp+%d: 0x%08x\n", i*4, ((unsigned int*)stack_base)[i]);
+ }
+#endif
+}
+
+/* Perform machine dependent cif processing */
+ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
+{
+ /* Round the stack up to a multiple of 8 bytes. This isn't needed
+ * everywhere, but it is on some platforms, and it doesn't harm
+ * anything when it isn't needed. */
+ cif->bytes = (cif->bytes + 7) & ~7;
+
+ /* Flag to indicate that he return value is in fact a struct */
+ cif->rstruct_flag = 0;
+
+ /* Set the return type flag */
+ switch(cif->rtype->type)
+ {
+ case FFI_TYPE_SINT8:
+ case FFI_TYPE_UINT8:
+ cif->flags = (unsigned)FFI_TYPE_UINT8;
+ break;
+ case FFI_TYPE_SINT16:
+ case FFI_TYPE_UINT16:
+ cif->flags = (unsigned)FFI_TYPE_UINT16;
+ break;
+ case FFI_TYPE_FLOAT:
+ case FFI_TYPE_SINT32:
+ case FFI_TYPE_UINT32:
+ case FFI_TYPE_POINTER:
+ cif->flags = (unsigned)FFI_TYPE_UINT32;
+ break;
+ case FFI_TYPE_DOUBLE:
+ case FFI_TYPE_SINT64:
+ case FFI_TYPE_UINT64:
+ cif->flags = (unsigned)FFI_TYPE_UINT64;
+ break;
+ case FFI_TYPE_STRUCT:
+ cif->rstruct_flag = 1;
+ if(!pass_struct_on_stack(cif->rtype))
+ {
+ if(cif->rtype->size <= 1)
+ cif->flags = (unsigned)FFI_TYPE_UINT8;
+ else if(cif->rtype->size <= 2)
+ cif->flags = (unsigned)FFI_TYPE_UINT16;
+ else if(cif->rtype->size <= 4)
+ cif->flags = (unsigned)FFI_TYPE_UINT32;
+ else if(cif->rtype->size <= 8)
+ cif->flags = (unsigned)FFI_TYPE_UINT64;
+ else
+ cif->flags = (unsigned)cif->rtype->type;
+ }
+ else
+ cif->flags = (unsigned)cif->rtype->type;
+ break;
+ default:
+ cif->flags = (unsigned)cif->rtype->type;
+ break;
+ }
+
+ return FFI_OK;
+}
+
+void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
+{
+ extended_cif ecif;
+
+ unsigned int size = 0, i = 0;
+ ffi_type **p_arg;
+
+ ecif.cif = cif;
+ ecif.avalue = avalue;
+
+ for(i = 0, p_arg = cif->arg_types; i < cif->nargs; i++, p_arg++)
+ size += (*p_arg)->size + (4 - (*p_arg)->size % 4);
+
+ /* If the return value is a struct and we don't have a return value
+ * address then we need to make one */
+
+ /* If cif->flags is struct then it's not suitable for registers */
+ if((rvalue == NULL) && (cif->flags == FFI_TYPE_STRUCT))
+ ecif.rvalue = alloca(cif->rtype->size);
+ else
+ ecif.rvalue = rvalue;
+
+ switch(cif->abi)
+ {
+ case FFI_SYSV:
+ ffi_call_SYSV(ffi_prep_args, &ecif, size, cif->flags,
+ ecif.rvalue, cif->rstruct_flag, fn);
+ break;
+ default:
+ FFI_ASSERT(0);
+ break;
+ }
+}
+
+static void ffi_prep_incoming_args_SYSV(char *stack, void **rvalue,
+ void **avalue, ffi_cif *cif)
+{
+ register unsigned int i, reg_mask = 0;
+ register void **p_argv;
+ register ffi_type **p_arg;
+ register char *reg_base = stack;
+ register char *stack_base = stack + 20;
+ register unsigned int stack_offset = 0;
+
+#ifdef DEBUG
+ /* Debugging */
+ for(i = 0; i < cif->nargs + 7; i++)
+ {
+ printf("sp+%d: 0x%08x\n", i*4, ((unsigned int*)stack)[i]);
+ }
+#endif
+
+ /* If cif->flags is struct then we know it's not passed in registers */
+ if(cif->flags == FFI_TYPE_STRUCT)
+ {
+ *rvalue = *(void **)reg_base;
+ reg_mask |= 1;
+ }
+
+ p_argv = avalue;
+
+ for(i = 0, p_arg = cif->arg_types; i < cif->nargs; i++, p_arg++)
+ {
+ size_t z = (*p_arg)->size;
+ int alignment = (*p_arg)->alignment;
+
+ *p_argv = 0;
+
+ if(z % 4 != 0)
+ z += (4 - z % 4);
+
+ if(reg_mask != 0x1f)
+ {
+ if(pass_struct_on_stack(*p_arg))
+ {
+ *p_argv = (void*)stack_base + stack_offset;
+ stack_offset += z;
+ }
+ else if(z <= sizeof(int))
+ {
+ char index = 0;
+
+ while((reg_mask >> index) & 1)
+ index++;
+
+ *p_argv = (void*)reg_base + (index * 4);
+ reg_mask |= (1 << index);
+ }
+ else if(z == 2 * sizeof(int))
+ {
+ if(!((reg_mask >> 1) & 1))
+ {
+ *p_argv = (void*)reg_base + 4;
+ reg_mask |= (3 << 1);
+ }
+ else if(!((reg_mask >> 3) & 1))
+ {
+ *p_argv = (void*)reg_base + 12;
+ reg_mask |= (3 << 3);
+ }
+ }
+ }
+
+ if(!*p_argv)
+ {
+ *p_argv = (void*)stack_base + stack_offset;
+ stack_offset += z;
+ }
+
+ if((*p_arg)->type != FFI_TYPE_STRUCT ||
+ (*p_arg)->elements[1] == NULL)
+ {
+ if(alignment == 1)
+ **(unsigned int**)p_argv <<= 24;
+ else if(alignment == 2)
+ **(unsigned int**)p_argv <<= 16;
+ }
+
+ p_argv++;
+ }
+
+#ifdef DEBUG
+ /* Debugging */
+ for(i = 0; i < cif->nargs; i++)
+ {
+ printf("sp+%d: 0x%08x\n", i*4, *(((unsigned int**)avalue)[i]));
+ }
+#endif
+}
+
+/* This function is jumped to by the trampoline */
+
+unsigned int ffi_closure_SYSV_inner(ffi_closure *closure, void **respp,
+ void *args)
+{
+ ffi_cif *cif;
+ void **arg_area;
+ unsigned int i, size = 0;
+ ffi_type **p_arg;
+
+ cif = closure->cif;
+
+ for(i = 0, p_arg = cif->arg_types; i < cif->nargs; i++, p_arg++)
+ size += (*p_arg)->size + (4 - (*p_arg)->size % 4);
+
+ arg_area = (void **)alloca(size);
+
+ /* this call will initialize ARG_AREA, such that each element in that
+ * array points to the corresponding value on the stack; and if the
+ * function returns a structure, it will re-set RESP to point to the
+ * structure return address. */
+
+ ffi_prep_incoming_args_SYSV(args, respp, arg_area, cif);
+
+ (closure->fun)(cif, *respp, arg_area, closure->user_data);
+
+ return cif->flags;
+}
+
+ffi_status ffi_prep_closure_loc(ffi_closure* closure, ffi_cif* cif,
+ void (*fun)(ffi_cif*, void*, void**, void*), void *user_data,
+ void *codeloc)
+{
+ FFI_ASSERT(cif->abi == FFI_SYSV);
+
+ unsigned char *__tramp = (unsigned char*)(&closure->tramp[0]);
+ unsigned int __fun = (unsigned int)(&ffi_closure_SYSV);
+ unsigned int __ctx = (unsigned int)(codeloc);
+ unsigned int __rstruct_flag = (unsigned int)(cif->rstruct_flag);
+ unsigned int __inner = (unsigned int)(&ffi_closure_SYSV_inner);
+ *(unsigned int*) &__tramp[0] = 0xebcd1f00; /* pushm r8-r12 */
+ *(unsigned int*) &__tramp[4] = 0xfefc0010; /* ld.w r12, pc[16] */
+ *(unsigned int*) &__tramp[8] = 0xfefb0010; /* ld.w r11, pc[16] */
+ *(unsigned int*) &__tramp[12] = 0xfefa0010; /* ld.w r10, pc[16] */
+ *(unsigned int*) &__tramp[16] = 0xfeff0010; /* ld.w pc, pc[16] */
+ *(unsigned int*) &__tramp[20] = __ctx;
+ *(unsigned int*) &__tramp[24] = __rstruct_flag;
+ *(unsigned int*) &__tramp[28] = __inner;
+ *(unsigned int*) &__tramp[32] = __fun;
+ syscall(__NR_cacheflush, 0, (&__tramp[0]), 36);
+
+ closure->cif = cif;
+ closure->user_data = user_data;
+ closure->fun = fun;
+
+ return FFI_OK;
+}
+
Index: plibffi/src/avr32/ffitarget.h
===================================================================
--- /dev/null
+++ plibffi/src/avr32/ffitarget.h
@@ -0,0 +1,50 @@
+/* -----------------------------------------------------------------*-C-*-
+ ffitarget.h - Copyright (c) 2009 Bradley Smith <brad@brad-smith.co.uk>
+ Target configuration macros for AVR32.
+
+ 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
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
+
+ ----------------------------------------------------------------------- */
+
+#ifndef LIBFFI_TARGET_H
+#define LIBFFI_TARGET_H
+
+#ifndef LIBFFI_ASM
+typedef unsigned long ffi_arg;
+typedef signed long ffi_sarg;
+
+typedef enum ffi_abi {
+ FFI_FIRST_ABI = 0,
+ FFI_SYSV,
+ FFI_DEFAULT_ABI = FFI_SYSV,
+ FFI_LAST_ABI = FFI_DEFAULT_ABI + 1
+} ffi_abi;
+#endif
+
+#define FFI_EXTRA_CIF_FIELDS unsigned int rstruct_flag
+
+/* Definitions for closures */
+
+#define FFI_CLOSURES 1
+#define FFI_TRAMPOLINE_SIZE 36
+#define FFI_NATIVE_RAW_API 0
+
+#endif
Index: plibffi/src/avr32/sysv.S
===================================================================
--- /dev/null
+++ plibffi/src/avr32/sysv.S
@@ -0,0 +1,208 @@
+/* -----------------------------------------------------------------------
+ sysv.S - Copyright (c) 2009 Bradley Smith <brad@brad-smith.co.uk>
+
+ AVR32 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
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ --------------------------------------------------------------------- */
+
+#define LIBFFI_ASM
+#include <fficonfig.h>
+#include <ffi.h>
+
+ /* r12: ffi_prep_args
+ * r11: &ecif
+ * r10: size
+ * r9: cif->flags
+ * r8: ecif.rvalue
+ * sp+0: cif->rstruct_flag
+ * sp+4: fn */
+
+ .text
+ .align 1
+ .globl ffi_call_SYSV
+ .type ffi_call_SYSV, @function
+ffi_call_SYSV:
+ stm --sp, r0,r1,lr
+ stm --sp, r8-r12
+ mov r0, sp
+
+ /* Make room for all of the new args. */
+ sub sp, r10
+ /* Pad to make way for potential skipped registers */
+ sub sp, 20
+
+ /* Call ffi_prep_args(stack, &ecif). */
+ /* r11 already set */
+ mov r1, r12
+ mov r12, sp
+ icall r1
+
+ /* Save new argument size */
+ mov r1, r12
+
+ /* Move first 5 parameters in registers. */
+ ldm sp++, r8-r12
+
+ /* call (fn) (...). */
+ ld.w r1, r0[36]
+ icall r1
+
+ /* Remove the space we pushed for the args. */
+ mov sp, r0
+
+ /* Load r1 with the rstruct flag. */
+ ld.w r1, sp[32]
+
+ /* Load r9 with the return type code. */
+ ld.w r9, sp[12]
+
+ /* Load r8 with the return value pointer. */
+ ld.w r8, sp[16]
+
+ /* If the return value pointer is NULL, assume no return value. */
+ cp.w r8, 0
+ breq .Lend
+
+ /* Check if return type is actually a struct */
+ cp.w r1, 0
+ breq 1f
+
+ /* Return 8bit */
+ cp.w r9, FFI_TYPE_UINT8
+ breq .Lstore8
+
+ /* Return 16bit */
+ cp.w r9, FFI_TYPE_UINT16
+ breq .Lstore16
+
+1:
+ /* Return 32bit */
+ cp.w r9, FFI_TYPE_UINT32
+ breq .Lstore32
+ cp.w r9, FFI_TYPE_UINT16
+ breq .Lstore32
+ cp.w r9, FFI_TYPE_UINT8
+ breq .Lstore32
+
+ /* Return 64bit */
+ cp.w r9, FFI_TYPE_UINT64
+ breq .Lstore64
+
+ /* Didn't match anything */
+ bral .Lend
+
+.Lstore64:
+ st.w r8[0], r11
+ st.w r8[4], r10
+ bral .Lend
+
+.Lstore32:
+ st.w r8[0], r12
+ bral .Lend
+
+.Lstore16:
+ st.h r8[0], r12
+ bral .Lend
+
+.Lstore8:
+ st.b r8[0], r12
+ bral .Lend
+
+.Lend:
+ sub sp, -20
+ ldm sp++, r0,r1,pc
+
+ .size ffi_call_SYSV, . - ffi_call_SYSV
+
+
+ /* r12: __ctx
+ * r11: __rstruct_flag
+ * r10: __inner */
+
+ .align 1
+ .globl ffi_closure_SYSV
+ .type ffi_closure_SYSV, @function
+ffi_closure_SYSV:
+ stm --sp, r0,lr
+ mov r0, r11
+ mov r8, r10
+ sub r10, sp, -8
+ sub sp, 12
+ st.w sp[8], sp
+ sub r11, sp, -8
+ icall r8
+
+ /* Check if return type is actually a struct */
+ cp.w r0, 0
+ breq 1f
+
+ /* Return 8bit */
+ cp.w r12, FFI_TYPE_UINT8
+ breq .Lget8
+
+ /* Return 16bit */
+ cp.w r12, FFI_TYPE_UINT16
+ breq .Lget16
+
+1:
+ /* Return 32bit */
+ cp.w r12, FFI_TYPE_UINT32
+ breq .Lget32
+ cp.w r12, FFI_TYPE_UINT16
+ breq .Lget32
+ cp.w r12, FFI_TYPE_UINT8
+ breq .Lget32
+
+ /* Return 64bit */
+ cp.w r12, FFI_TYPE_UINT64
+ breq .Lget64
+
+ /* Didn't match anything */
+ bral .Lclend
+
+.Lget64:
+ ld.w r11, sp[0]
+ ld.w r10, sp[4]
+ bral .Lclend
+
+.Lget32:
+ ld.w r12, sp[0]
+ bral .Lclend
+
+.Lget16:
+ ld.uh r12, sp[0]
+ bral .Lclend
+
+.Lget8:
+ ld.ub r12, sp[0]
+ bral .Lclend
+
+.Lclend:
+ sub sp, -12
+ ldm sp++, r0,lr
+ sub sp, -20
+ mov pc, lr
+
+ .size ffi_closure_SYSV, . - ffi_closure_SYSV
+
+#if defined __ELF__ && defined __linux__
+ .section .note.GNU-stack,"",@progbits
+#endif
Index: plibffi/Makefile.am
===================================================================
--- plibffi.orig/Makefile.am
+++ plibffi/Makefile.am
@@ -7,6 +7,7 @@ SUBDIRS = include testsuite man
EXTRA_DIST = LICENSE ChangeLog.v1 ChangeLog.libgcj configure.host \
src/alpha/ffi.c src/alpha/osf.S src/alpha/ffitarget.h \
src/arm/ffi.c src/arm/sysv.S src/arm/ffitarget.h \
+ src/avr32/ffi.c src/avr32/sysv.S src/avr32/ffitarget.h \
src/cris/ffi.c src/cris/sysv.S src/cris/ffitarget.h \
src/ia64/ffi.c src/ia64/ffitarget.h src/ia64/ia64_flags.h \
src/ia64/unix.S \
@@ -140,6 +141,9 @@ endif
if ARM
nodist_libffi_la_SOURCES += src/arm/sysv.S src/arm/ffi.c
endif
+if AVR32
+nodist_libffi_la_SOURCES += src/avr32/sysv.S src/avr32/ffi.c
+endif
if LIBFFI_CRIS
nodist_libffi_la_SOURCES += src/cris/sysv.S src/cris/ffi.c
endif
Index: plibffi/configure
===================================================================
--- plibffi.orig/configure
+++ plibffi/configure
@@ -813,6 +813,8 @@ FRV_FALSE
FRV_TRUE
LIBFFI_CRIS_FALSE
LIBFFI_CRIS_TRUE
+AVR32_FALSE
+AVR32_TRUE
ARM_FALSE
ARM_TRUE
POWERPC_FREEBSD_FALSE
@@ -4770,13 +4772,13 @@ if test "${lt_cv_nm_interface+set}" = se
else
lt_cv_nm_interface="BSD nm"
echo "int some_variable = 0;" > conftest.$ac_ext
- (eval echo "\"\$as_me:4773: $ac_compile\"" >&5)
+ (eval echo "\"\$as_me:4775: $ac_compile\"" >&5)
(eval "$ac_compile" 2>conftest.err)
cat conftest.err >&5
- (eval echo "\"\$as_me:4776: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
+ (eval echo "\"\$as_me:4778: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
(eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
cat conftest.err >&5
- (eval echo "\"\$as_me:4779: output\"" >&5)
+ (eval echo "\"\$as_me:4781: output\"" >&5)
cat conftest.out >&5
if $GREP 'External.*some_variable' conftest.out > /dev/null; then
lt_cv_nm_interface="MS dumpbin"
@@ -5982,7 +5984,7 @@ ia64-*-hpux*)
;;
*-*-irix6*)
# Find out which ABI we are using.
- echo '#line 5985 "configure"' > conftest.$ac_ext
+ echo '#line 5987 "configure"' > conftest.$ac_ext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>&5
ac_status=$?
@@ -7835,11 +7837,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:7838: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:7840: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:7842: \$? = $ac_status" >&5
+ echo "$as_me:7844: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
@@ -8174,11 +8176,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:8177: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:8179: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:8181: \$? = $ac_status" >&5
+ echo "$as_me:8183: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
@@ -8279,11 +8281,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:8282: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:8284: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
- echo "$as_me:8286: \$? = $ac_status" >&5
+ echo "$as_me:8288: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
@@ -8334,11 +8336,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:8337: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:8339: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
- echo "$as_me:8341: \$? = $ac_status" >&5
+ echo "$as_me:8343: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
@@ -11137,7 +11139,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 11140 "configure"
+#line 11142 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -11233,7 +11235,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 11236 "configure"
+#line 11238 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -12155,6 +12157,10 @@ case "$host" in
TARGET=X86_64; TARGETDIR=x86
;;
+ avr32*-*-*)
+ TARGET=AVR32; TARGETDIR=avr32
+ ;;
+
cris-*-*)
TARGET=LIBFFI_CRIS; TARGETDIR=cris
;;
@@ -12391,6 +12397,14 @@ else
ARM_FALSE=
fi
+ if test x$TARGET = xAVR32; then
+ AVR32_TRUE=
+ AVR32_FALSE='#'
+else
+ AVR32_TRUE='#'
+ AVR32_FALSE=
+fi
+
if test x$TARGET = xLIBFFI_CRIS; then
LIBFFI_CRIS_TRUE=
LIBFFI_CRIS_FALSE='#'
@@ -14483,6 +14497,16 @@ _ACEOF
fi
fi
+case "$target" in
+ i?86-apple-darwin10*)
+
+cat >>confdefs.h <<\_ACEOF
+#define FFI_MMAP_EXEC_WRIT 1
+_ACEOF
+
+ ;;
+esac
+
{ $as_echo "$as_me:$LINENO: checking whether .eh_frame section should be read-only" >&5
$as_echo_n "checking whether .eh_frame section should be read-only... " >&6; }
if test "${libffi_cv_ro_eh_frame+set}" = set; then
@@ -14895,6 +14919,13 @@ $as_echo "$as_me: error: conditional \"A
Usually this means the macro was only invoked conditionally." >&2;}
{ (exit 1); exit 1; }; }
fi
+if test -z "${AVR32_TRUE}" && test -z "${AVR32_FALSE}"; then
+ { { $as_echo "$as_me:$LINENO: error: conditional \"AVR32\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+$as_echo "$as_me: error: conditional \"AVR32\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+ { (exit 1); exit 1; }; }
+fi
if test -z "${LIBFFI_CRIS_TRUE}" && test -z "${LIBFFI_CRIS_FALSE}"; then
{ { $as_echo "$as_me:$LINENO: error: conditional \"LIBFFI_CRIS\" was never defined.
Usually this means the macro was only invoked conditionally." >&5
Index: plibffi/configure.ac
===================================================================
--- plibffi.orig/configure.ac
+++ plibffi/configure.ac
@@ -58,6 +58,10 @@ case "$host" in
TARGET=X86_64; TARGETDIR=x86
;;
+ avr32*-*-*)
+ TARGET=AVR32; TARGETDIR=avr32
+ ;;
+
cris-*-*)
TARGET=LIBFFI_CRIS; TARGETDIR=cris
;;
@@ -180,6 +184,7 @@ AM_CONDITIONAL(POWERPC_AIX, test x$TARGE
AM_CONDITIONAL(POWERPC_DARWIN, test x$TARGET = xPOWERPC_DARWIN)
AM_CONDITIONAL(POWERPC_FREEBSD, test x$TARGET = xPOWERPC_FREEBSD)
AM_CONDITIONAL(ARM, test x$TARGET = xARM)
+AM_CONDITIONAL(AVR32, test x$TARGET = xAVR32)
AM_CONDITIONAL(LIBFFI_CRIS, test x$TARGET = xLIBFFI_CRIS)
AM_CONDITIONAL(FRV, test x$TARGET = xFRV)
AM_CONDITIONAL(S390, test x$TARGET = xS390)
Index: plibffi/ChangeLog.libffi
===================================================================
--- plibffi.orig/ChangeLog.libffi
+++ plibffi/ChangeLog.libffi
@@ -1,3 +1,14 @@
+2009-10-05 Bradley Smith <brad@brad-smith.co.uk>
+
+ * configure.ac, Makefile.am, src/avr32/ffi.c,
+ src/avr32/ffitarget.h,
+ src/avr32/sysv.S: Add AVR32 port.
+ * testsuite/libffi.call/cls_dbls_struct.c,
+ testsuite/libffi.call/cls_double_va.c,
+ testsuite/libffi.call/cls_longdouble_va.c,
+ testsuite/libffi.call/huge_struct.c: Mark expected failures on
+ AVR32.
+
2009-10-27 Samuli Suominen <ssuominen@gentoo.org>
* configure.ac: Undefine _AC_ARG_VAR_PRECIOUS for autoconf 2.64.

39
patches/fix-docs Normal file
View File

@@ -0,0 +1,39 @@
Index: plibffi/ChangeLog.libffi
===================================================================
--- plibffi.orig/ChangeLog.libffi
+++ plibffi/ChangeLog.libffi
@@ -1,3 +1,8 @@
+2009-10-11 Matthias Klose <doko@ubuntu.com>
+
+ * man/ffi_call.3: Fix #include in examples.
+ * doc/libffi.texi: Add dircategory.
+
2009-10-23 Frank Everdij <f.p.x.everdij@tudelft.nl>
* include/ffi.h.in: Placed '__GNUC__' ifdef around
Index: plibffi/doc/libffi.texi
===================================================================
--- plibffi.orig/doc/libffi.texi
+++ plibffi/doc/libffi.texi
@@ -31,7 +31,7 @@ section entitled ``GNU General Public Li
@end quotation
@end copying
-@dircategory
+@dircategory Development
@direntry
* libffi: (libffi). Portable foreign-function interface library.
@end direntry
Index: plibffi/man/ffi_call.3
===================================================================
--- plibffi.orig/man/ffi_call.3
+++ plibffi/man/ffi_call.3
@@ -43,7 +43,7 @@ integral type must be used to hold
the return value.
.Sh EXAMPLES
.Bd -literal
-#include <ffi/ffi.h>
+#include <ffi.h>
#include <stdio.h>
unsigned char

5
patches/series Normal file
View File

@@ -0,0 +1,5 @@
stand-alone
avr32
snow-leopard
sgi-mips
fix-docs

195
patches/sgi-mips Normal file
View File

@@ -0,0 +1,195 @@
Index: plibffi/ChangeLog.libffi
===================================================================
--- plibffi.orig/ChangeLog.libffi
+++ plibffi/ChangeLog.libffi
@@ -1,3 +1,19 @@
+2009-10-23 Frank Everdij <f.p.x.everdij@tudelft.nl>
+
+ * include/ffi.h.in: Placed '__GNUC__' ifdef around
+ '__attribute__((aligned(8)))' in ffi_closure, fixes compile for
+ IRIX MIPSPro c99.
+ * include/ffi_common.h: Added '__sgi' define to non
+ '__attribute__((__mode__()))' integer typedefs.
+ * src/mips/ffi.c (ffi_call, ffi_closure_mips_inner_O32,
+ ffi_closure_mips_inner_N32): Added 'defined(_MIPSEB)' to BE check.
+ (ffi_closure_mips_inner_O32, ffi_closure_mips_inner_N32): Added
+ FFI_LONGDOUBLE support and alignment(N32 only).
+ * src/mips/ffitarget.h: Corrected '#include <sgidefs.h>' for IRIX and
+ fixed non '__attribute__((__mode__()))' integer typedefs.
+ * src/mips/n32.S: Put '#ifdef linux' around '.abicalls' and '.eh_frame'
+ since they are Linux/GNU Assembler specific.
+
2009-10-27 Abdulaziz Ghuloum <aghuloum@gmail.com>
* configure.ac (FFI_MMAP_EXEC_WRIT): Define for snow
Index: plibffi/include/ffi.h.in
===================================================================
--- plibffi.orig/include/ffi.h.in
+++ plibffi/include/ffi.h.in
@@ -256,7 +256,11 @@ typedef struct {
ffi_cif *cif;
void (*fun)(ffi_cif*,void*,void**,void*);
void *user_data;
+#ifdef __GNUC__
} ffi_closure __attribute__((aligned (8)));
+#else
+} ffi_closure;
+#endif
void *ffi_closure_alloc (size_t size, void **code);
void ffi_closure_free (void *);
Index: plibffi/include/ffi_common.h
===================================================================
--- plibffi.orig/include/ffi_common.h
+++ plibffi/include/ffi_common.h
@@ -84,15 +84,21 @@ typedef struct
} extended_cif;
/* Terse sized type definitions. */
-#ifdef _MSC_VER
+#if defined(_MSC_VER) || defined(__sgi)
typedef unsigned char UINT8;
typedef signed char SINT8;
typedef unsigned short UINT16;
typedef signed short SINT16;
typedef unsigned int UINT32;
typedef signed int SINT32;
+# ifdef _MSC_VER
typedef unsigned __int64 UINT64;
typedef signed __int64 SINT64;
+# else
+# include <inttypes.h>
+typedef uint64_t UINT64;
+typedef int64_t SINT64;
+# endif
#else
typedef unsigned int UINT8 __attribute__((__mode__(__QI__)));
typedef signed int SINT8 __attribute__((__mode__(__QI__)));
Index: plibffi/src/mips/ffi.c
===================================================================
--- plibffi.orig/src/mips/ffi.c
+++ plibffi/src/mips/ffi.c
@@ -625,7 +625,7 @@ void ffi_call(ffi_cif *cif, void (*fn)(v
{
rvalue_copy = alloca (8);
copy_rvalue = 1;
-#ifdef __MIPSEB__
+#if defined(__MIPSEB__) || defined(_MIPSEB)
copy_offset = 4;
#endif
}
@@ -772,9 +772,10 @@ ffi_closure_mips_inner_O32 (ffi_closure
{
if (i < 2 && !seen_int &&
(arg_types[i]->type == FFI_TYPE_FLOAT ||
- arg_types[i]->type == FFI_TYPE_DOUBLE))
+ arg_types[i]->type == FFI_TYPE_DOUBLE ||
+ arg_types[i]->type == FFI_TYPE_LONGDOUBLE))
{
-#ifdef __MIPSEB__
+#if defined(__MIPSEB__) || defined(_MIPSEB)
if (arg_types[i]->type == FFI_TYPE_FLOAT)
avaluep[i] = ((char *) &fpr[i]) + sizeof (float);
else
@@ -931,10 +932,16 @@ ffi_closure_mips_inner_N32 (ffi_closure
while (i < avn)
{
if (arg_types[i]->type == FFI_TYPE_FLOAT
- || arg_types[i]->type == FFI_TYPE_DOUBLE)
+ || arg_types[i]->type == FFI_TYPE_DOUBLE
+ || arg_types[i]->type == FFI_TYPE_LONGDOUBLE)
{
argp = (argn >= 8 || soft_float) ? ar + argn : fpr + argn;
-#ifdef __MIPSEB__
+ if ((arg_types[i]->type == FFI_TYPE_LONGDOUBLE) && ((unsigned)argp & (arg_types[i]->alignment-1)))
+ {
+ argp=(ffi_arg*)ALIGN(argp,arg_types[i]->alignment);
+ argn++;
+ }
+#if defined(__MIPSEB__) || defined(_MIPSEB)
if (arg_types[i]->type == FFI_TYPE_FLOAT && argn < 8)
avaluep[i] = ((char *) argp) + sizeof (float);
else
Index: plibffi/src/mips/ffitarget.h
===================================================================
--- plibffi.orig/src/mips/ffitarget.h
+++ plibffi/src/mips/ffitarget.h
@@ -28,7 +28,10 @@
#define LIBFFI_TARGET_H
#ifdef linux
-#include <asm/sgidefs.h>
+# include <asm/sgidefs.h>
+#else
+# include <sgidefs.h>
+#endif
# ifndef _ABIN32
# define _ABIN32 _MIPS_SIM_NABI32
# endif
@@ -38,7 +41,6 @@
# ifndef _ABIO32
# define _ABIO32 _MIPS_SIM_ABI32
# endif
-#endif
#if !defined(_MIPS_SIM)
-- something is very wrong --
@@ -154,7 +156,8 @@
# endif /* _MIPS_SIM==_ABI64 */
#endif /* !FFI_MIPS_O32 */
#else /* !LIBFFI_ASM */
-#ifdef FFI_MIPS_O32
+# ifdef __GNUC__
+# ifdef FFI_MIPS_O32
/* O32 stack frames have 32bit integer args */
typedef unsigned int ffi_arg __attribute__((__mode__(__SI__)));
typedef signed int ffi_sarg __attribute__((__mode__(__SI__)));
@@ -162,7 +165,18 @@ typedef signed int ffi_sarg __attr
/* N32 and N64 frames have 64bit integer args */
typedef unsigned int ffi_arg __attribute__((__mode__(__DI__)));
typedef signed int ffi_sarg __attribute__((__mode__(__DI__)));
-#endif
+# endif
+# else
+# ifdef FFI_MIPS_O32
+/* O32 stack frames have 32bit integer args */
+typedef __uint32_t ffi_arg;
+typedef __int32_t ffi_sarg;
+# else
+/* N32 and N64 frames have 64bit integer args */
+typedef __uint64_t ffi_arg;
+typedef __int64_t ffi_sarg;
+# endif
+# endif /* __GNUC__ */
typedef enum ffi_abi {
FFI_FIRST_ABI = 0,
Index: plibffi/src/mips/n32.S
===================================================================
--- plibffi.orig/src/mips/n32.S
+++ plibffi/src/mips/n32.S
@@ -40,7 +40,9 @@
#define SIZEOF_FRAME ( 8 * FFI_SIZEOF_ARG )
+#ifdef linux
.abicalls
+#endif
.text
.align 2
.globl ffi_call_N32
@@ -527,6 +529,7 @@ cls_epilogue:
.LFE2:
.end ffi_closure_N32
+#ifdef linux
.section .eh_frame,"aw",@progbits
.Lframe1:
.4byte .LECIE1-.LSCIE1 # length
@@ -583,5 +586,6 @@ cls_epilogue:
.uleb128 (SIZEOF_FRAME2 - RA_OFF2)/4
.align EH_FRAME_ALIGN
.LEFDE3:
+#endif /* linux */
#endif

76
patches/snow-leopard Normal file
View File

@@ -0,0 +1,76 @@
Index: plibffi/src/closures.c
===================================================================
--- plibffi.orig/src/closures.c
+++ plibffi/src/closures.c
@@ -214,6 +214,8 @@ static int dlmunmap(void *, size_t);
#if !(defined(X86_WIN32) || defined(X86_WIN64)) || defined (__CYGWIN__)
+#if FFI_MMAP_EXEC_SELINUX
+
/* A mutex used to synchronize access to *exec* variables in this file. */
static pthread_mutex_t open_temp_exec_file_mutex = PTHREAD_MUTEX_INITIALIZER;
@@ -483,6 +485,27 @@ dlmmap (void *start, size_t length, int
return dlmmap_locked (start, length, prot, flags, offset);
}
+#else
+
+static void *
+dlmmap (void *start, size_t length, int prot,
+ int flags, int fd, off_t offset)
+{
+
+ assert (start == NULL && length % malloc_getpagesize == 0
+ && prot == (PROT_READ | PROT_WRITE)
+ && flags == (MAP_PRIVATE | MAP_ANONYMOUS)
+ && fd == -1 && offset == 0);
+
+#if FFI_CLOSURE_TEST
+ printf ("mapping in %zi\n", length);
+#endif
+
+ return mmap (start, length, prot | PROT_EXEC, flags, fd, offset);
+}
+
+#endif
+
/* Release memory at the given address, as well as the corresponding
executable page if it's separate. */
static int
Index: plibffi/ChangeLog.libffi
===================================================================
--- plibffi.orig/ChangeLog.libffi
+++ plibffi/ChangeLog.libffi
@@ -1,3 +1,11 @@
+2009-10-27 Abdulaziz Ghuloum <aghuloum@gmail.com>
+
+ * configure.ac (FFI_MMAP_EXEC_WRIT): Define for snow
+ leopard (i?86-apple-darwin10*).
+ * configure: Rebuilt.
+ * fficonfig.h.in: Rebuilt.
+ * src/closures.c (dlmmap): Define version for snow leopard.
+
2009-10-05 Bradley Smith <brad@brad-smith.co.uk>
* configure.ac, Makefile.am, src/avr32/ffi.c,
Index: plibffi/configure.ac
===================================================================
--- plibffi.orig/configure.ac
+++ plibffi/configure.ac
@@ -274,6 +274,14 @@ if test x$TARGET = xX86 || test x$TARGET
fi
fi
+case "$target" in
+ i?86-apple-darwin10*)
+ AC_DEFINE(FFI_MMAP_EXEC_WRIT, 1,
+ [Cannot use malloc on this target, so, we revert to
+ alternative means])
+ ;;
+esac
+
AC_CACHE_CHECK([whether .eh_frame section should be read-only],
libffi_cv_ro_eh_frame, [
libffi_cv_ro_eh_frame=no

43286
patches/stand-alone Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,70 @@
/* Area: closure_call
Purpose: Check return value float.
Limitations: none.
PR: 41908.
Originator: <rfm@gnu.org> 20091102 */
/* { dg-do run } */
#include "ffitest.h"
typedef struct cls_struct_combined {
float a;
float b;
float c;
float d;
} cls_struct_combined;
void cls_struct_combined_fn(struct cls_struct_combined arg)
{
printf("%g %g %g %g\n",
arg.a, arg.b,
arg.c, arg.d);
fflush(stdout);
}
static void
cls_struct_combined_gn(ffi_cif* cif __UNUSED__, void* resp __UNUSED__,
void** args, void* userdata __UNUSED__)
{
struct cls_struct_combined a0;
a0 = *(struct cls_struct_combined*)(args[0]);
cls_struct_combined_fn(a0);
}
int main (void)
{
ffi_cif cif;
void *code;
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
ffi_type* cls_struct_fields0[5];
ffi_type cls_struct_type0;
ffi_type* dbl_arg_types[5];
cls_struct_type0.size = 0;
cls_struct_type0.alignment = 0;
cls_struct_type0.type = FFI_TYPE_STRUCT;
cls_struct_type0.elements = cls_struct_fields0;
struct cls_struct_combined g_dbl = {4.0, 5.0, 1.0, 8.0};
cls_struct_fields0[0] = &ffi_type_float;
cls_struct_fields0[1] = &ffi_type_float;
cls_struct_fields0[2] = &ffi_type_float;
cls_struct_fields0[3] = &ffi_type_float;
cls_struct_fields0[4] = NULL;
dbl_arg_types[0] = &cls_struct_type0;
dbl_arg_types[1] = NULL;
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ffi_type_void,
dbl_arg_types) == FFI_OK);
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_combined_gn, NULL, code) == FFI_OK);
((void(*)(cls_struct_combined)) (code))(g_dbl);
/* { dg-output "4 5 1 8" } */
exit(0);
}

View File

@@ -0,0 +1,70 @@
/* Area: closure_call
Purpose: Check return value float.
Limitations: none.
PR: 41908.
Originator: <rfm@gnu.org> 20091102 */
/* { dg-do run } */
#include "ffitest.h"
typedef struct cls_struct_combined {
float a;
float b;
float c;
float d;
} cls_struct_combined;
void cls_struct_combined_fn(struct cls_struct_combined arg)
{
printf("%g %g %g %g\n",
arg.a, arg.b,
arg.c, arg.d);
fflush(stdout);
}
static void
cls_struct_combined_gn(ffi_cif* cif __UNUSED__, void* resp __UNUSED__,
void** args, void* userdata __UNUSED__)
{
struct cls_struct_combined a0;
a0 = *(struct cls_struct_combined*)(args[0]);
cls_struct_combined_fn(a0);
}
int main (void)
{
ffi_cif cif;
void *code;
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
ffi_type* cls_struct_fields0[5];
ffi_type cls_struct_type0;
ffi_type* dbl_arg_types[5];
cls_struct_type0.size = 0;
cls_struct_type0.alignment = 0;
cls_struct_type0.type = FFI_TYPE_STRUCT;
cls_struct_type0.elements = cls_struct_fields0;
struct cls_struct_combined g_dbl = {4.0, 5.0, 1.0, 8.0};
cls_struct_fields0[0] = &ffi_type_float;
cls_struct_fields0[1] = &ffi_type_float;
cls_struct_fields0[2] = &ffi_type_float;
cls_struct_fields0[3] = &ffi_type_float;
cls_struct_fields0[4] = NULL;
dbl_arg_types[0] = &cls_struct_type0;
dbl_arg_types[1] = NULL;
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ffi_type_void,
dbl_arg_types) == FFI_OK);
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_combined_gn, NULL, code) == FFI_OK);
((void(*)(cls_struct_combined)) (code))(g_dbl);
/* { dg-output "4 5 1 8" } */
exit(0);
}