Commit 30255340 by Eric Botcazou Committed by Eric Botcazou

re PR libffi/60073 (64-bit libffi.call/cls_double_va.c FAILs after recent modification)

	PR libffi/60073
	* src/sparc/ffitarget.h (FFI_TARGET_SPECIFIC_VARIADIC): Define.
	(FFI_EXTRA_CIF_FIELDS): Likewise.
	(FFI_NATIVE_RAW_API): Move around.
	* src/sparc/ffi.c (ffi_prep_cif_machdep_core): New function from...
	(ffi_prep_cif_machdep): ...here.  Call ffi_prep_cif_machdep_core.
	(ffi_prep_cif_machdep_var): New function.
	(ffi_closure_sparc_inner_v9): Do not pass anonymous FP arguments in
	FP registers.
	* doc/libffi.texi (Introduction): Fix inaccuracy.

From-SVN: r207763
parent 662dae0d
2014-02-13 Eric Botcazou <ebotcazou@adacore.com>
PR libffi/60073
* src/sparc/ffitarget.h (FFI_TARGET_SPECIFIC_VARIADIC): Define.
(FFI_EXTRA_CIF_FIELDS): Likewise.
(FFI_NATIVE_RAW_API): Move around.
* src/sparc/ffi.c (ffi_prep_cif_machdep_core): New function from...
(ffi_prep_cif_machdep): ...here. Call ffi_prep_cif_machdep_core.
(ffi_prep_cif_machdep_var): New function.
(ffi_closure_sparc_inner_v9): Do not pass anonymous FP arguments in
FP registers.
* doc/libffi.texi (Introduction): Fix inaccuracy.
2013-12-10 Alan Modra <amodra@gmail.com> 2013-12-10 Alan Modra <amodra@gmail.com>
* src/powerpc/ffitarget.h: Import from upstream. * src/powerpc/ffitarget.h: Import from upstream.
...@@ -729,7 +742,7 @@ ...@@ -729,7 +742,7 @@
* src/sparc/ffi.c (ffi_prep_closure_loc): Don't ASSERT ABI test, * src/sparc/ffi.c (ffi_prep_closure_loc): Don't ASSERT ABI test,
just return FFI_BAD_ABI when things are wrong. just return FFI_BAD_ABI when things are wrong.
2012-02-11 Eric Botcazou <ebotcazou@adacore.com> 2011-02-11 Eric Botcazou <ebotcazou@adacore.com>
* src/sparc/v9.S (STACKFRAME): Bump to 176. * src/sparc/v9.S (STACKFRAME): Bump to 176.
......
...@@ -63,14 +63,14 @@ section entitled ``GNU General Public License''. ...@@ -63,14 +63,14 @@ section entitled ``GNU General Public License''.
@node Introduction @node Introduction
@chapter What is libffi? @chapter What is libffi?
Compilers for high level languages generate code that follow certain Compilers for high-level languages generate code that follow certain
conventions. These conventions are necessary, in part, for separate conventions. These conventions are necessary, in part, for separate
compilation to work. One such convention is the @dfn{calling compilation to work. One such convention is the @dfn{calling
convention}. The calling convention is a set of assumptions made by convention}. The calling convention is a set of assumptions made by
the compiler about where function arguments will be found on entry to the compiler about where function arguments will be found on entry to
a function. A calling convention also specifies where the return a function. A calling convention also specifies where the return
value for a function is found. The calling convention is also value for a function is found. The calling convention is part of
sometimes called the @dfn{ABI} or @dfn{Application Binary Interface}. what is called the @dfn{ABI} or @dfn{Application Binary Interface}.
@cindex calling convention @cindex calling convention
@cindex ABI @cindex ABI
@cindex Application Binary Interface @cindex Application Binary Interface
......
...@@ -249,7 +249,7 @@ int ffi_prep_args_v9(char *stack, extended_cif *ecif) ...@@ -249,7 +249,7 @@ int ffi_prep_args_v9(char *stack, extended_cif *ecif)
} }
/* Perform machine dependent cif processing */ /* Perform machine dependent cif processing */
ffi_status ffi_prep_cif_machdep(ffi_cif *cif) static ffi_status ffi_prep_cif_machdep_core(ffi_cif *cif)
{ {
int wordsize; int wordsize;
...@@ -334,6 +334,19 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif) ...@@ -334,6 +334,19 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
return FFI_OK; return FFI_OK;
} }
ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
{
cif->nfixedargs = cif->nargs;
return ffi_prep_cif_machdep_core (cif);
}
ffi_status ffi_prep_cif_machdep_var(ffi_cif *cif, unsigned int nfixedargs,
unsigned int ntotalargs)
{
cif->nfixedargs = nfixedargs;
return ffi_prep_cif_machdep_core (cif);
}
int ffi_v9_layout_struct(ffi_type *arg, int off, char *ret, char *intg, char *flt) int ffi_v9_layout_struct(ffi_type *arg, int off, char *ret, char *intg, char *flt)
{ {
ffi_type **ptr = &arg->elements[0]; ffi_type **ptr = &arg->elements[0];
...@@ -604,8 +617,7 @@ ffi_closure_sparc_inner_v9(ffi_closure *closure, ...@@ -604,8 +617,7 @@ ffi_closure_sparc_inner_v9(ffi_closure *closure,
/* Copy the caller's structure return address so that the closure /* Copy the caller's structure return address so that the closure
returns the data directly to the caller. */ returns the data directly to the caller. */
if (cif->flags == FFI_TYPE_VOID if (cif->flags == FFI_TYPE_VOID && cif->rtype->type == FFI_TYPE_STRUCT)
&& cif->rtype->type == FFI_TYPE_STRUCT)
{ {
rvalue = (void *) gpr[0]; rvalue = (void *) gpr[0];
/* Skip the structure return address. */ /* Skip the structure return address. */
...@@ -619,6 +631,10 @@ ffi_closure_sparc_inner_v9(ffi_closure *closure, ...@@ -619,6 +631,10 @@ ffi_closure_sparc_inner_v9(ffi_closure *closure,
/* Grab the addresses of the arguments from the stack frame. */ /* Grab the addresses of the arguments from the stack frame. */
for (i = 0; i < cif->nargs; i++) for (i = 0; i < cif->nargs; i++)
{ {
/* 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);
if (arg_types[i]->type == FFI_TYPE_STRUCT) if (arg_types[i]->type == FFI_TYPE_STRUCT)
{ {
if (arg_types[i]->size > 16) if (arg_types[i]->size > 16)
...@@ -633,7 +649,9 @@ ffi_closure_sparc_inner_v9(ffi_closure *closure, ...@@ -633,7 +649,9 @@ ffi_closure_sparc_inner_v9(ffi_closure *closure,
0, 0,
(char *) &gpr[argn], (char *) &gpr[argn],
(char *) &gpr[argn], (char *) &gpr[argn],
(char *) &fpr[argn]); named
? (char *) &fpr[argn]
: (char *) &gpr[argn]);
avalue[i] = &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;
} }
...@@ -649,6 +667,7 @@ ffi_closure_sparc_inner_v9(ffi_closure *closure, ...@@ -649,6 +667,7 @@ ffi_closure_sparc_inner_v9(ffi_closure *closure,
argn++; argn++;
#endif #endif
if (i < fp_slot_max if (i < fp_slot_max
&& named
&& (arg_types[i]->type == FFI_TYPE_FLOAT && (arg_types[i]->type == FFI_TYPE_FLOAT
|| arg_types[i]->type == FFI_TYPE_DOUBLE || arg_types[i]->type == FFI_TYPE_DOUBLE
#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
...@@ -662,7 +681,7 @@ ffi_closure_sparc_inner_v9(ffi_closure *closure, ...@@ -662,7 +681,7 @@ ffi_closure_sparc_inner_v9(ffi_closure *closure,
} }
/* Invoke the closure. */ /* Invoke the closure. */
(closure->fun) (cif, rvalue, avalue, closure->user_data); closure->fun (cif, rvalue, avalue, closure->user_data);
/* Tell ffi_closure_sparc how to perform return type promotions. */ /* Tell ffi_closure_sparc how to perform return type promotions. */
return cif->rtype->type; return cif->rtype->type;
......
...@@ -58,16 +58,17 @@ typedef enum ffi_abi { ...@@ -58,16 +58,17 @@ typedef enum ffi_abi {
} ffi_abi; } ffi_abi;
#endif #endif
#define FFI_TARGET_SPECIFIC_VARIADIC 1
#define FFI_EXTRA_CIF_FIELDS unsigned int nfixedargs
/* ---- Definitions for closures ----------------------------------------- */ /* ---- Definitions for closures ----------------------------------------- */
#define FFI_CLOSURES 1 #define FFI_CLOSURES 1
#define FFI_NATIVE_RAW_API 0
#ifdef SPARC64 #ifdef SPARC64
#define FFI_TRAMPOLINE_SIZE 24 #define FFI_TRAMPOLINE_SIZE 24
#else #else
#define FFI_TRAMPOLINE_SIZE 16 #define FFI_TRAMPOLINE_SIZE 16
#endif #endif
#define FFI_NATIVE_RAW_API 0
#endif #endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment