summaryrefslogtreecommitdiffstats
path: root/libffi
diff options
context:
space:
mode:
authorebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>2014-02-17 12:00:04 +0000
committerebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>2014-02-17 12:00:04 +0000
commit6b5229ed95ac50728f05fe5f3fd02d697775a5db (patch)
treee9c8ff8c5a9087761fabdc82c7e4d0f52bf96aea /libffi
parent389b04c1383e280dd59325590d1490b84336eeb8 (diff)
downloadppe42-gcc-6b5229ed95ac50728f05fe5f3fd02d697775a5db.tar.gz
ppe42-gcc-6b5229ed95ac50728f05fe5f3fd02d697775a5db.zip
PR libffi/60073
* src/sparc/v8.S: Assemble only if !SPARC64. * src/sparc/v9.S: Remove obsolete comment. * src/sparc/ffitarget.h (enum ffi_abi): Add FFI_COMPAT_V9. (V8_ABI_P): New macro. (V9_ABI_P): Likewise. (FFI_EXTRA_CIF_FIELDS): Define only if SPARC64. * src/sparc/ffi.c (ffi_prep_args_v8): Compile only if !SPARC64. (ffi_prep_args_v9): Compile only if SPARC64. (ffi_prep_cif_machdep_core): Use V9_ABI_P predicate. (ffi_prep_cif_machdep): Guard access to nfixedargs field. (ffi_prep_cif_machdep_var): Likewise. (ffi_v9_layout_struct): Compile only if SPARC64. (ffi_call): Deal with FFI_V8PLUS and FFI_COMPAT_V9 and fix warnings. (ffi_prep_closure_loc): Use V9_ABI_P and V8_ABI_P predicates. (ffi_closure_sparc_inner_v8): Compile only if !SPARC64. (ffi_closure_sparc_inner_v9): Compile only if SPARC64. Guard access to nfixedargs field. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@207822 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libffi')
-rw-r--r--libffi/ChangeLog21
-rw-r--r--libffi/src/sparc/ffi.c401
-rw-r--r--libffi/src/sparc/ffitarget.h13
-rw-r--r--libffi/src/sparc/v8.S5
-rw-r--r--libffi/src/sparc/v9.S4
5 files changed, 257 insertions, 187 deletions
diff --git a/libffi/ChangeLog b/libffi/ChangeLog
index f4fe5178cfe..80e94ed77ca 100644
--- a/libffi/ChangeLog
+++ b/libffi/ChangeLog
@@ -1,3 +1,24 @@
+2014-02-17 Eric Botcazou <ebotcazou@adacore.com>
+
+ PR libffi/60073
+ * src/sparc/v8.S: Assemble only if !SPARC64.
+ * src/sparc/v9.S: Remove obsolete comment.
+ * src/sparc/ffitarget.h (enum ffi_abi): Add FFI_COMPAT_V9.
+ (V8_ABI_P): New macro.
+ (V9_ABI_P): Likewise.
+ (FFI_EXTRA_CIF_FIELDS): Define only if SPARC64.
+ * src/sparc/ffi.c (ffi_prep_args_v8): Compile only if !SPARC64.
+ (ffi_prep_args_v9): Compile only if SPARC64.
+ (ffi_prep_cif_machdep_core): Use V9_ABI_P predicate.
+ (ffi_prep_cif_machdep): Guard access to nfixedargs field.
+ (ffi_prep_cif_machdep_var): Likewise.
+ (ffi_v9_layout_struct): Compile only if SPARC64.
+ (ffi_call): Deal with FFI_V8PLUS and FFI_COMPAT_V9 and fix warnings.
+ (ffi_prep_closure_loc): Use V9_ABI_P and V8_ABI_P predicates.
+ (ffi_closure_sparc_inner_v8): Compile only if !SPARC64.
+ (ffi_closure_sparc_inner_v9): Compile only if SPARC64. Guard access
+ to nfixedargs field.
+
2014-02-13 Eric Botcazou <ebotcazou@adacore.com>
PR libffi/60073
diff --git a/libffi/src/sparc/ffi.c b/libffi/src/sparc/ffi.c
index a4ee84ec514..77e38220657 100644
--- a/libffi/src/sparc/ffi.c
+++ b/libffi/src/sparc/ffi.c
@@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------
ffi.c - Copyright (c) 2011 Anthony Green
Copyright (c) 1996, 2003-2004, 2007-2008 Red Hat, Inc.
-
+
SPARC Foreign Function Interface
Permission is hereby granted, free of charge, to any person obtaining
@@ -34,93 +34,10 @@
/* ffi_prep_args is called by the assembly routine once stack space
has been allocated for the function's arguments */
-void ffi_prep_args_v8(char *stack, extended_cif *ecif)
-{
- int i;
- void **p_argv;
- char *argp;
- ffi_type **p_arg;
-
- /* Skip 16 words for the window save area */
- argp = stack + 16*sizeof(int);
-
- /* This should only really be done when we are returning a structure,
- however, it's faster just to do it all the time...
-
- if ( ecif->cif->rtype->type == FFI_TYPE_STRUCT ) */
- *(int *) argp = (long)ecif->rvalue;
-
- /* And 1 word for the structure return value. */
- argp += sizeof(int);
-
-#ifdef USING_PURIFY
- /* Purify will probably complain in our assembly routine, unless we
- zero out this memory. */
-
- ((int*)argp)[0] = 0;
- ((int*)argp)[1] = 0;
- ((int*)argp)[2] = 0;
- ((int*)argp)[3] = 0;
- ((int*)argp)[4] = 0;
- ((int*)argp)[5] = 0;
-#endif
-
- p_argv = ecif->avalue;
-
- for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types; i; i--, p_arg++)
- {
- size_t z;
-
- if ((*p_arg)->type == FFI_TYPE_STRUCT
-#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
- || (*p_arg)->type == FFI_TYPE_LONGDOUBLE
-#endif
- )
- {
- *(unsigned int *) argp = (unsigned long)(* p_argv);
- z = sizeof(int);
- }
- else
- {
- z = (*p_arg)->size;
- if (z < sizeof(int))
- {
- z = sizeof(int);
- switch ((*p_arg)->type)
- {
- case FFI_TYPE_SINT8:
- *(signed int *) argp = *(SINT8 *)(* p_argv);
- break;
-
- case FFI_TYPE_UINT8:
- *(unsigned int *) argp = *(UINT8 *)(* p_argv);
- break;
-
- case FFI_TYPE_SINT16:
- *(signed int *) argp = *(SINT16 *)(* p_argv);
- break;
-
- case FFI_TYPE_UINT16:
- *(unsigned int *) argp = *(UINT16 *)(* p_argv);
- break;
-
- default:
- FFI_ASSERT(0);
- }
- }
- else
- {
- memcpy(argp, *p_argv, z);
- }
- }
- p_argv++;
- argp += z;
- }
-
- return;
-}
+#ifdef SPARC64
-int ffi_prep_args_v9(char *stack, extended_cif *ecif)
+int
+ffi_prep_args_v9(char *stack, extended_cif *ecif)
{
int i, ret = 0;
int tmp;
@@ -248,12 +165,105 @@ int ffi_prep_args_v9(char *stack, extended_cif *ecif)
return ret;
}
+#else
+
+void
+ffi_prep_args_v8(char *stack, extended_cif *ecif)
+{
+ int i;
+ void **p_argv;
+ char *argp;
+ ffi_type **p_arg;
+
+ /* Skip 16 words for the window save area */
+ argp = stack + 16*sizeof(int);
+
+ /* This should only really be done when we are returning a structure,
+ however, it's faster just to do it all the time...
+
+ if ( ecif->cif->rtype->type == FFI_TYPE_STRUCT ) */
+ *(int *) argp = (long)ecif->rvalue;
+
+ /* And 1 word for the structure return value. */
+ argp += sizeof(int);
+
+#ifdef USING_PURIFY
+ /* Purify will probably complain in our assembly routine, unless we
+ zero out this memory. */
+
+ ((int*)argp)[0] = 0;
+ ((int*)argp)[1] = 0;
+ ((int*)argp)[2] = 0;
+ ((int*)argp)[3] = 0;
+ ((int*)argp)[4] = 0;
+ ((int*)argp)[5] = 0;
+#endif
+
+ p_argv = ecif->avalue;
+
+ for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types; i; i--, p_arg++)
+ {
+ size_t z;
+
+ if ((*p_arg)->type == FFI_TYPE_STRUCT
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+ || (*p_arg)->type == FFI_TYPE_LONGDOUBLE
+#endif
+ )
+ {
+ *(unsigned int *) argp = (unsigned long)(* p_argv);
+ z = sizeof(int);
+ }
+ else
+ {
+ z = (*p_arg)->size;
+ if (z < sizeof(int))
+ {
+ z = sizeof(int);
+ switch ((*p_arg)->type)
+ {
+ case FFI_TYPE_SINT8:
+ *(signed int *) argp = *(SINT8 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_UINT8:
+ *(unsigned int *) argp = *(UINT8 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_SINT16:
+ *(signed int *) argp = *(SINT16 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_UINT16:
+ *(unsigned int *) argp = *(UINT16 *)(* p_argv);
+ break;
+
+ default:
+ FFI_ASSERT(0);
+ }
+ }
+ else
+ {
+ memcpy(argp, *p_argv, z);
+ }
+ }
+ p_argv++;
+ argp += z;
+ }
+
+ return;
+}
+
+#endif
+
/* Perform machine dependent cif processing */
-static ffi_status ffi_prep_cif_machdep_core(ffi_cif *cif)
+
+static
+ffi_status ffi_prep_cif_machdep_core(ffi_cif *cif)
{
int wordsize;
- if (cif->abi != FFI_V9)
+ if (!V9_ABI_P (cif->abi))
{
wordsize = 4;
@@ -303,7 +313,7 @@ static ffi_status ffi_prep_cif_machdep_core(ffi_cif *cif)
break;
case FFI_TYPE_STRUCT:
- if (cif->abi == FFI_V9 && cif->rtype->size > 32)
+ if (V9_ABI_P (cif->abi) && cif->rtype->size > 32)
cif->flags = FFI_TYPE_VOID;
else
cif->flags = FFI_TYPE_STRUCT;
@@ -313,7 +323,7 @@ static ffi_status ffi_prep_cif_machdep_core(ffi_cif *cif)
case FFI_TYPE_UINT8:
case FFI_TYPE_SINT16:
case FFI_TYPE_UINT16:
- if (cif->abi == FFI_V9)
+ if (V9_ABI_P (cif->abi))
cif->flags = FFI_TYPE_INT;
else
cif->flags = cif->rtype->type;
@@ -321,7 +331,7 @@ static ffi_status ffi_prep_cif_machdep_core(ffi_cif *cif)
case FFI_TYPE_SINT64:
case FFI_TYPE_UINT64:
- if (cif->abi == FFI_V9)
+ if (V9_ABI_P (cif->abi))
cif->flags = FFI_TYPE_INT;
else
cif->flags = FFI_TYPE_SINT64;
@@ -334,20 +344,31 @@ static ffi_status ffi_prep_cif_machdep_core(ffi_cif *cif)
return FFI_OK;
}
-ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
+ffi_status
+ffi_prep_cif_machdep(ffi_cif *cif)
{
- cif->nfixedargs = cif->nargs;
+#ifdef SPARC64
+ if (cif->abi != FFI_COMPAT_V9)
+ cif->nfixedargs = cif->nargs;
+#endif
return ffi_prep_cif_machdep_core (cif);
}
-ffi_status ffi_prep_cif_machdep_var(ffi_cif *cif, unsigned int nfixedargs,
- unsigned int ntotalargs)
+ffi_status
+ffi_prep_cif_machdep_var(ffi_cif *cif, unsigned int nfixedargs,
+ unsigned int ntotalargs)
{
- cif->nfixedargs = nfixedargs;
+#ifdef SPARC64
+ if (cif->abi != FFI_COMPAT_V9)
+ cif->nfixedargs = nfixedargs;
+#endif
return ffi_prep_cif_machdep_core (cif);
}
-int ffi_v9_layout_struct(ffi_type *arg, int off, char *ret, char *intg, char *flt)
+#ifdef SPARC64
+
+int
+ffi_v9_layout_struct(ffi_type *arg, int off, char *ret, char *intg, char *flt)
{
ffi_type **ptr = &arg->elements[0];
@@ -380,6 +401,7 @@ int ffi_v9_layout_struct(ffi_type *arg, int off, char *ret, char *intg, char *fl
return off;
}
+#endif
#ifdef SPARC64
extern int ffi_call_v9(void *, extended_cif *, unsigned,
@@ -389,33 +411,37 @@ extern int ffi_call_v8(void *, extended_cif *, unsigned,
unsigned, unsigned *, void (*fn)(void));
#endif
-void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
+void
+ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
{
extended_cif ecif;
+#ifdef SPARC64
void *rval = rvalue;
+#endif
ecif.cif = cif;
ecif.avalue = avalue;
-
- /* If the return value is a struct and we don't have a return */
- /* value address then we need to make one */
-
ecif.rvalue = rvalue;
+
+ /* If the return value is a struct and we don't have a return value address,
+ then we need to make one. */
if (cif->rtype->type == FFI_TYPE_STRUCT)
{
+ if (ecif.rvalue == NULL)
+ ecif.rvalue = alloca(cif->rtype->size);
+
+#ifdef SPARC64
if (cif->rtype->size <= 32)
rval = alloca(64);
else
- {
- rval = NULL;
- if (rvalue == NULL)
- ecif.rvalue = alloca(cif->rtype->size);
- }
+ rval = NULL;
+#endif
}
switch (cif->abi)
{
case FFI_V8:
+ case FFI_V8PLUS:
#ifdef SPARC64
/* We don't yet support calling 32bit code from 64bit */
FFI_ASSERT(0);
@@ -430,7 +456,7 @@ void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
/* behind "call", so we alloc some executable space for it. */
/* l7 is used, we need to make sure v8.S doesn't use %l7. */
unsigned int *call_struct = NULL;
- ffi_closure_alloc(32, &call_struct);
+ ffi_closure_alloc(32, (void **)&call_struct);
if (call_struct)
{
unsigned long f = (unsigned long)fn;
@@ -450,7 +476,7 @@ void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
/* SPARC v8 requires 5 instructions for flush to be visible */
asm volatile ("nop; nop; nop; nop; nop");
ffi_call_v8(ffi_prep_args_v8, &ecif, cif->bytes,
- cif->flags, rvalue, call_struct);
+ cif->flags, rvalue, (void (*)(void)) call_struct);
ffi_closure_free(call_struct);
}
else
@@ -466,12 +492,13 @@ void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
}
#endif
break;
+ case FFI_COMPAT_V9:
case FFI_V9:
#ifdef SPARC64
- ffi_call_v9(ffi_prep_args_v9, &ecif, cif->bytes,
- cif->flags, rval, fn);
+ ffi_call_v9(ffi_prep_args_v9, &ecif, cif->bytes, cif->flags, rval, fn);
if (rvalue && rval && cif->rtype->type == FFI_TYPE_STRUCT)
- ffi_v9_layout_struct(cif->rtype, 0, (char *)rvalue, (char *)rval, ((char *)rval)+32);
+ ffi_v9_layout_struct(cif->rtype, 0, (char *)rvalue, (char *)rval,
+ ((char *)rval)+32);
#else
/* And vice versa */
FFI_ASSERT(0);
@@ -502,7 +529,7 @@ ffi_prep_closure_loc (ffi_closure* closure,
#ifdef SPARC64
/* Trampoline address is equal to the closure address. We take advantage
of that to reduce the trampoline size by 8 bytes. */
- if (cif->abi != FFI_V9)
+ if (!V9_ABI_P (cif->abi))
return FFI_BAD_ABI;
fn = (unsigned long) ffi_closure_v9;
tramp[0] = 0x83414000; /* rd %pc, %g1 */
@@ -512,7 +539,7 @@ ffi_prep_closure_loc (ffi_closure* closure,
*((unsigned long *) &tramp[4]) = fn;
#else
unsigned long ctx = (unsigned long) codeloc;
- if (cif->abi != FFI_V8)
+ if (!V8_ABI_P (cif->abi))
return FFI_BAD_ABI;
fn = (unsigned long) ffi_closure_v8;
tramp[0] = 0x03000000 | fn >> 10; /* sethi %hi(fn), %g1 */
@@ -537,74 +564,11 @@ ffi_prep_closure_loc (ffi_closure* closure,
return FFI_OK;
}
-int
-ffi_closure_sparc_inner_v8(ffi_closure *closure,
- void *rvalue, unsigned long *gpr, unsigned long *scratch)
-{
- ffi_cif *cif;
- ffi_type **arg_types;
- void **avalue;
- int i, argn;
-
- cif = closure->cif;
- arg_types = cif->arg_types;
- avalue = alloca(cif->nargs * sizeof(void *));
-
- /* Copy the caller's structure return address so that the closure
- returns the data directly to the caller. */
- if (cif->flags == FFI_TYPE_STRUCT
-#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
- || cif->flags == FFI_TYPE_LONGDOUBLE
-#endif
- )
- rvalue = (void *) gpr[0];
-
- /* Always skip the structure return address. */
- argn = 1;
-
- /* Grab the addresses of the arguments from the stack frame. */
- for (i = 0; i < cif->nargs; i++)
- {
- if (arg_types[i]->type == FFI_TYPE_STRUCT
-#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
- || arg_types[i]->type == FFI_TYPE_LONGDOUBLE
-#endif
- )
- {
- /* Straight copy of invisible reference. */
- avalue[i] = (void *)gpr[argn++];
- }
- else if ((arg_types[i]->type == FFI_TYPE_DOUBLE
- || arg_types[i]->type == FFI_TYPE_SINT64
- || arg_types[i]->type == FFI_TYPE_UINT64)
- /* gpr is 8-byte aligned. */
- && (argn % 2) != 0)
- {
- /* Align on a 8-byte boundary. */
- scratch[0] = gpr[argn];
- scratch[1] = gpr[argn+1];
- avalue[i] = scratch;
- scratch -= 2;
- argn += 2;
- }
- else
- {
- /* Always right-justify. */
- argn += ALIGN(arg_types[i]->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
- avalue[i] = ((char *) &gpr[argn]) - arg_types[i]->size;
- }
- }
-
- /* Invoke the closure. */
- (closure->fun) (cif, rvalue, avalue, closure->user_data);
-
- /* Tell ffi_closure_sparc how to perform return type promotions. */
- return cif->rtype->type;
-}
+#ifdef SPARC64
int
-ffi_closure_sparc_inner_v9(ffi_closure *closure,
- void *rvalue, unsigned long *gpr, double *fpr)
+ffi_closure_sparc_inner_v9(ffi_closure *closure, void *rvalue,
+ unsigned long *gpr, double *fpr)
{
ffi_cif *cif;
ffi_type **arg_types;
@@ -633,7 +597,8 @@ ffi_closure_sparc_inner_v9(ffi_closure *closure,
{
/* If the function is variadic, FP arguments are passed in FP
registers only if the corresponding parameter is named. */
- const int named = (i < cif->nfixedargs);
+ const int named
+ = (cif->abi == FFI_COMPAT_V9 ? 1 : i < cif->nfixedargs);
if (arg_types[i]->type == FFI_TYPE_STRUCT)
{
@@ -653,7 +618,8 @@ ffi_closure_sparc_inner_v9(ffi_closure *closure,
? (char *) &fpr[argn]
: (char *) &gpr[argn]);
avalue[i] = &gpr[argn];
- argn += ALIGN(arg_types[i]->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
+ argn
+ += ALIGN(arg_types[i]->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
}
}
else
@@ -686,3 +652,72 @@ ffi_closure_sparc_inner_v9(ffi_closure *closure,
/* Tell ffi_closure_sparc how to perform return type promotions. */
return cif->rtype->type;
}
+
+#else
+
+int
+ffi_closure_sparc_inner_v8(ffi_closure *closure, void *rvalue,
+ unsigned long *gpr, unsigned long *scratch)
+{
+ ffi_cif *cif;
+ ffi_type **arg_types;
+ void **avalue;
+ int i, argn;
+
+ cif = closure->cif;
+ arg_types = cif->arg_types;
+ avalue = alloca(cif->nargs * sizeof(void *));
+
+ /* Copy the caller's structure return address so that the closure
+ returns the data directly to the caller. */
+ if (cif->flags == FFI_TYPE_STRUCT
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+ || cif->flags == FFI_TYPE_LONGDOUBLE
+#endif
+ )
+ rvalue = (void *) gpr[0];
+
+ /* Always skip the structure return address. */
+ argn = 1;
+
+ /* Grab the addresses of the arguments from the stack frame. */
+ for (i = 0; i < cif->nargs; i++)
+ {
+ if (arg_types[i]->type == FFI_TYPE_STRUCT
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+ || arg_types[i]->type == FFI_TYPE_LONGDOUBLE
+#endif
+ )
+ {
+ /* Straight copy of invisible reference. */
+ avalue[i] = (void *)gpr[argn++];
+ }
+ else if ((arg_types[i]->type == FFI_TYPE_DOUBLE
+ || arg_types[i]->type == FFI_TYPE_SINT64
+ || arg_types[i]->type == FFI_TYPE_UINT64)
+ /* gpr is 8-byte aligned. */
+ && (argn % 2) != 0)
+ {
+ /* Align on a 8-byte boundary. */
+ scratch[0] = gpr[argn];
+ scratch[1] = gpr[argn+1];
+ avalue[i] = scratch;
+ scratch -= 2;
+ argn += 2;
+ }
+ else
+ {
+ /* Always right-justify. */
+ argn += ALIGN(arg_types[i]->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
+ avalue[i] = ((char *) &gpr[argn]) - arg_types[i]->size;
+ }
+ }
+
+ /* Invoke the closure. */
+ closure->fun (cif, rvalue, avalue, closure->user_data);
+
+ /* Tell ffi_closure_sparc how to perform return type promotions. */
+ return cif->rtype->type;
+}
+
+#endif
diff --git a/libffi/src/sparc/ffitarget.h b/libffi/src/sparc/ffitarget.h
index a1f5e494820..6489ac05fd4 100644
--- a/libffi/src/sparc/ffitarget.h
+++ b/libffi/src/sparc/ffitarget.h
@@ -48,6 +48,8 @@ typedef enum ffi_abi {
FFI_FIRST_ABI = 0,
FFI_V8,
FFI_V8PLUS,
+ /* See below for the COMPAT_V9 rationale. */
+ FFI_COMPAT_V9,
FFI_V9,
FFI_LAST_ABI,
#ifdef SPARC64
@@ -58,8 +60,19 @@ typedef enum ffi_abi {
} ffi_abi;
#endif
+#define V8_ABI_P(abi) ((abi) == FFI_V8 || (abi) == FFI_V8PLUS)
+#define V9_ABI_P(abi) ((abi) == FFI_COMPAT_V9 || (abi) == FFI_V9)
+
#define FFI_TARGET_SPECIFIC_VARIADIC 1
+
+/* The support of variadic functions was broken in the original implementation
+ of the FFI_V9 ABI. This has been fixed by adding one extra field to the
+ CIF structure (nfixedargs field), which means that the ABI of libffi itself
+ has changed. In order to support applications using the original ABI, we
+ have renamed FFI_V9 into FFI_COMPAT_V9 and defined a new FFI_V9 value. */
+#ifdef SPARC64
#define FFI_EXTRA_CIF_FIELDS unsigned int nfixedargs
+#endif
/* ---- Definitions for closures ----------------------------------------- */
diff --git a/libffi/src/sparc/v8.S b/libffi/src/sparc/v8.S
index 2c4eb60a0fb..7ec6e1c1194 100644
--- a/libffi/src/sparc/v8.S
+++ b/libffi/src/sparc/v8.S
@@ -1,6 +1,6 @@
/* -----------------------------------------------------------------------
v8.S - Copyright (c) 1996, 1997, 2003, 2004, 2008 Red Hat, Inc.
-
+
SPARC Foreign Function Interface
Permission is hereby granted, free of charge, to any person obtaining
@@ -28,6 +28,8 @@
#include <fficonfig.h>
#include <ffi.h>
+#ifndef SPARC64
+
#define STACKFRAME 96 /* Minimum stack framesize for SPARC */
#define ARGS (64+4) /* Offset of register area in frame */
@@ -307,6 +309,7 @@ done2:
.byte 0x1f ! uleb128 0x1f
.align WS
.LLEFDE2:
+#endif
#if defined __ELF__ && defined __linux__
.section .note.GNU-stack,"",@progbits
diff --git a/libffi/src/sparc/v9.S b/libffi/src/sparc/v9.S
index bf31a2b5110..2c97673e351 100644
--- a/libffi/src/sparc/v9.S
+++ b/libffi/src/sparc/v9.S
@@ -1,6 +1,6 @@
/* -----------------------------------------------------------------------
v9.S - Copyright (c) 2000, 2003, 2004, 2008 Red Hat, Inc.
-
+
SPARC 64-bit Foreign Function Interface
Permission is hereby granted, free of charge, to any person obtaining
@@ -29,8 +29,6 @@
#include <ffi.h>
#ifdef SPARC64
-/* Only compile this in for 64bit builds, because otherwise the object file
- will have inproper architecture due to used instructions. */
#define STACKFRAME 176 /* Minimum stack framesize for SPARC 64-bit */
#define STACK_BIAS 2047
OpenPOWER on IntegriCloud