Switch to quilt. Rebase to latest GCC.
This commit is contained in:
928
patches/avr32
Normal file
928
patches/avr32
Normal 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
39
patches/fix-docs
Normal 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
5
patches/series
Normal file
@@ -0,0 +1,5 @@
|
||||
stand-alone
|
||||
avr32
|
||||
snow-leopard
|
||||
sgi-mips
|
||||
fix-docs
|
||||
195
patches/sgi-mips
Normal file
195
patches/sgi-mips
Normal 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
76
patches/snow-leopard
Normal 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
43286
patches/stand-alone
Normal file
File diff suppressed because it is too large
Load Diff
70
testsuite/libffi.call/.svn/text-base/testclosure.c.svn-base
Normal file
70
testsuite/libffi.call/.svn/text-base/testclosure.c.svn-base
Normal 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);
|
||||
}
|
||||
70
testsuite/libffi.call/testclosure.c
Normal file
70
testsuite/libffi.call/testclosure.c
Normal 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);
|
||||
}
|
||||
Reference in New Issue
Block a user