Commit 5cbf8c8d by David Daney Committed by David Daney

java_raw_api.c (ffi_java_raw_to_rvalue): Remove special handling for FFI_TYPE_POINTER.

2009-09-15  David Daney  <ddaney@caviumnetworks.com>

	* src/java_raw_api.c (ffi_java_raw_to_rvalue): Remove special
	handling for FFI_TYPE_POINTER.
	* src/mips/ffitarget.h (FFI_TYPE_STRUCT_D_SOFT,
	FFI_TYPE_STRUCT_F_SOFT, FFI_TYPE_STRUCT_DD_SOFT,
	FFI_TYPE_STRUCT_FF_SOFT, FFI_TYPE_STRUCT_FD_SOFT,
	FFI_TYPE_STRUCT_DF_SOFT, FFI_TYPE_STRUCT_SOFT): New defines.
	(FFI_N32_SOFT_FLOAT, FFI_N64_SOFT_FLOAT): New ffi_abi enumerations.
	(enum ffi_abi): Set FFI_DEFAULT_ABI for soft-float.
	* src/mips/n32.S (ffi_call_N32): Add handling for soft-float
	structure and pointer returns.
	(ffi_closure_N32): Add handling for pointer returns.
	* src/mips/ffi.c (ffi_prep_args, calc_n32_struct_flags,
	calc_n32_return_struct_flags): Handle soft-float.
	(ffi_prep_cif_machdep):  Handle soft-float, fix pointer handling.
	(ffi_call_N32): Declare proper argument types.
	(ffi_call, copy_struct_N32, ffi_closure_mips_inner_N32): Handle
	soft-float.

From-SVN: r151726
parent 1c3c9f12
2009-09-15 David Daney <ddaney@caviumnetworks.com>
* src/java_raw_api.c (ffi_java_raw_to_rvalue): Remove special
handling for FFI_TYPE_POINTER.
* src/mips/ffitarget.h (FFI_TYPE_STRUCT_D_SOFT,
FFI_TYPE_STRUCT_F_SOFT, FFI_TYPE_STRUCT_DD_SOFT,
FFI_TYPE_STRUCT_FF_SOFT, FFI_TYPE_STRUCT_FD_SOFT,
FFI_TYPE_STRUCT_DF_SOFT, FFI_TYPE_STRUCT_SOFT): New defines.
(FFI_N32_SOFT_FLOAT, FFI_N64_SOFT_FLOAT): New ffi_abi enumerations.
(enum ffi_abi): Set FFI_DEFAULT_ABI for soft-float.
* src/mips/n32.S (ffi_call_N32): Add handling for soft-float
structure and pointer returns.
(ffi_closure_N32): Add handling for pointer returns.
* src/mips/ffi.c (ffi_prep_args, calc_n32_struct_flags,
calc_n32_return_struct_flags): Handle soft-float.
(ffi_prep_cif_machdep): Handle soft-float, fix pointer handling.
(ffi_call_N32): Declare proper argument types.
(ffi_call, copy_struct_N32, ffi_closure_mips_inner_N32): Handle
soft-float.
2009-08-24 Ralf Wildenhues <Ralf.Wildenhues@gmx.de> 2009-08-24 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
* configure.ac (AC_PREREQ): Bump to 2.64. * configure.ac (AC_PREREQ): Bump to 2.64.
......
...@@ -276,9 +276,6 @@ ffi_java_raw_to_rvalue (ffi_cif *cif, void *rvalue) ...@@ -276,9 +276,6 @@ ffi_java_raw_to_rvalue (ffi_cif *cif, void *rvalue)
case FFI_TYPE_SINT16: case FFI_TYPE_SINT16:
case FFI_TYPE_SINT32: case FFI_TYPE_SINT32:
case FFI_TYPE_INT: case FFI_TYPE_INT:
#if FFI_SIZEOF_JAVA_RAW == 4
case FFI_TYPE_POINTER:
#endif
*(SINT64 *)rvalue >>= 32; *(SINT64 *)rvalue >>= 32;
break; break;
......
...@@ -99,7 +99,7 @@ static void ffi_prep_args(char *stack, ...@@ -99,7 +99,7 @@ static void ffi_prep_args(char *stack,
p_argv = ecif->avalue; p_argv = ecif->avalue;
for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types; i; i--, p_arg++) for (i = 0, p_arg = ecif->cif->arg_types; i < ecif->cif->nargs; i++, p_arg++)
{ {
size_t z; size_t z;
unsigned int a; unsigned int a;
...@@ -123,9 +123,25 @@ static void ffi_prep_args(char *stack, ...@@ -123,9 +123,25 @@ static void ffi_prep_args(char *stack,
/* The size of a pointer depends on the ABI */ /* The size of a pointer depends on the ABI */
if (type == FFI_TYPE_POINTER) if (type == FFI_TYPE_POINTER)
type = type = (ecif->cif->abi == FFI_N64
(ecif->cif->abi == FFI_N64) ? FFI_TYPE_SINT64 : FFI_TYPE_SINT32; || ecif->cif->abi == FFI_N64_SOFT_FLOAT)
? FFI_TYPE_SINT64 : FFI_TYPE_SINT32;
if (i < 8 && (ecif->cif->abi == FFI_N32_SOFT_FLOAT
|| ecif->cif->abi == FFI_N64_SOFT_FLOAT))
{
switch (type)
{
case FFI_TYPE_FLOAT:
type = FFI_TYPE_UINT32;
break;
case FFI_TYPE_DOUBLE:
type = FFI_TYPE_UINT64;
break;
default:
break;
}
}
switch (type) switch (type)
{ {
case FFI_TYPE_SINT8: case FFI_TYPE_SINT8:
...@@ -205,13 +221,17 @@ static void ffi_prep_args(char *stack, ...@@ -205,13 +221,17 @@ static void ffi_prep_args(char *stack,
definitions and generates the appropriate flags. */ definitions and generates the appropriate flags. */
static unsigned static unsigned
calc_n32_struct_flags(ffi_type *arg, unsigned *loc, unsigned *arg_reg) calc_n32_struct_flags(int soft_float, ffi_type *arg,
unsigned *loc, unsigned *arg_reg)
{ {
unsigned flags = 0; unsigned flags = 0;
unsigned index = 0; unsigned index = 0;
ffi_type *e; ffi_type *e;
if (soft_float)
return 0;
while ((e = arg->elements[index])) while ((e = arg->elements[index]))
{ {
/* Align this object. */ /* Align this object. */
...@@ -236,7 +256,7 @@ calc_n32_struct_flags(ffi_type *arg, unsigned *loc, unsigned *arg_reg) ...@@ -236,7 +256,7 @@ calc_n32_struct_flags(ffi_type *arg, unsigned *loc, unsigned *arg_reg)
} }
static unsigned static unsigned
calc_n32_return_struct_flags(ffi_type *arg) calc_n32_return_struct_flags(int soft_float, ffi_type *arg)
{ {
unsigned flags = 0; unsigned flags = 0;
unsigned small = FFI_TYPE_SMALLSTRUCT; unsigned small = FFI_TYPE_SMALLSTRUCT;
...@@ -256,6 +276,7 @@ calc_n32_return_struct_flags(ffi_type *arg) ...@@ -256,6 +276,7 @@ calc_n32_return_struct_flags(ffi_type *arg)
small = FFI_TYPE_SMALLSTRUCT2; small = FFI_TYPE_SMALLSTRUCT2;
e = arg->elements[0]; e = arg->elements[0];
if (e->type == FFI_TYPE_DOUBLE) if (e->type == FFI_TYPE_DOUBLE)
flags = FFI_TYPE_DOUBLE; flags = FFI_TYPE_DOUBLE;
else if (e->type == FFI_TYPE_FLOAT) else if (e->type == FFI_TYPE_FLOAT)
...@@ -276,6 +297,8 @@ calc_n32_return_struct_flags(ffi_type *arg) ...@@ -276,6 +297,8 @@ calc_n32_return_struct_flags(ffi_type *arg)
floats! This must be passed the old way. */ floats! This must be passed the old way. */
return small; return small;
} }
if (soft_float)
flags += FFI_TYPE_STRUCT_SOFT;
} }
else else
if (!flags) if (!flags)
...@@ -382,16 +405,19 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif) ...@@ -382,16 +405,19 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
#ifdef FFI_MIPS_N32 #ifdef FFI_MIPS_N32
/* Set the flags necessary for N32 processing */ /* Set the flags necessary for N32 processing */
{ {
int type;
unsigned arg_reg = 0; unsigned arg_reg = 0;
unsigned loc = 0; unsigned loc = 0;
unsigned count = (cif->nargs < 8) ? cif->nargs : 8; unsigned count = (cif->nargs < 8) ? cif->nargs : 8;
unsigned index = 0; unsigned index = 0;
unsigned struct_flags = 0; unsigned struct_flags = 0;
int soft_float = (cif->abi == FFI_N32_SOFT_FLOAT
|| cif->abi == FFI_N64_SOFT_FLOAT);
if (cif->rtype->type == FFI_TYPE_STRUCT) if (cif->rtype->type == FFI_TYPE_STRUCT)
{ {
struct_flags = calc_n32_return_struct_flags(cif->rtype); struct_flags = calc_n32_return_struct_flags(soft_float, cif->rtype);
if (struct_flags == 0) if (struct_flags == 0)
{ {
...@@ -411,7 +437,22 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif) ...@@ -411,7 +437,22 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
while (count-- > 0 && arg_reg < 8) while (count-- > 0 && arg_reg < 8)
{ {
switch ((cif->arg_types)[index]->type) type = (cif->arg_types)[index]->type;
if (soft_float)
{
switch (type)
{
case FFI_TYPE_FLOAT:
type = FFI_TYPE_UINT32;
break;
case FFI_TYPE_DOUBLE:
type = FFI_TYPE_UINT64;
break;
default:
break;
}
}
switch (type)
{ {
case FFI_TYPE_FLOAT: case FFI_TYPE_FLOAT:
case FFI_TYPE_DOUBLE: case FFI_TYPE_DOUBLE:
...@@ -423,17 +464,25 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif) ...@@ -423,17 +464,25 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
/* Align it. */ /* Align it. */
arg_reg = ALIGN(arg_reg, 2); arg_reg = ALIGN(arg_reg, 2);
/* Treat it as two adjacent doubles. */ /* Treat it as two adjacent doubles. */
if (soft_float)
{
arg_reg += 2;
}
else
{
cif->flags += cif->flags +=
(FFI_TYPE_DOUBLE << (arg_reg * FFI_FLAG_BITS)); (FFI_TYPE_DOUBLE << (arg_reg * FFI_FLAG_BITS));
arg_reg++; arg_reg++;
cif->flags += cif->flags +=
(FFI_TYPE_DOUBLE << (arg_reg * FFI_FLAG_BITS)); (FFI_TYPE_DOUBLE << (arg_reg * FFI_FLAG_BITS));
arg_reg++; arg_reg++;
}
break; break;
case FFI_TYPE_STRUCT: case FFI_TYPE_STRUCT:
loc = arg_reg * FFI_SIZEOF_ARG; loc = arg_reg * FFI_SIZEOF_ARG;
cif->flags += calc_n32_struct_flags((cif->arg_types)[index], cif->flags += calc_n32_struct_flags(soft_float,
(cif->arg_types)[index],
&loc, &arg_reg); &loc, &arg_reg);
break; break;
...@@ -470,16 +519,42 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif) ...@@ -470,16 +519,42 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
/* Do nothing, 'cause FFI_TYPE_VOID is 0 */ /* Do nothing, 'cause FFI_TYPE_VOID is 0 */
break; break;
case FFI_TYPE_POINTER:
if (cif->abi == FFI_N32_SOFT_FLOAT || cif->abi == FFI_N32)
cif->flags += FFI_TYPE_SINT32 << (FFI_FLAG_BITS * 8);
else
cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 8);
break;
case FFI_TYPE_FLOAT: case FFI_TYPE_FLOAT:
if (soft_float)
{
cif->flags += FFI_TYPE_SINT32 << (FFI_FLAG_BITS * 8);
break;
}
/* else fall through */
case FFI_TYPE_DOUBLE: case FFI_TYPE_DOUBLE:
if (soft_float)
cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 8);
else
cif->flags += cif->rtype->type << (FFI_FLAG_BITS * 8); cif->flags += cif->rtype->type << (FFI_FLAG_BITS * 8);
break; break;
case FFI_TYPE_LONGDOUBLE: case FFI_TYPE_LONGDOUBLE:
/* Long double is returned as if it were a struct containing /* Long double is returned as if it were a struct containing
two doubles. */ two doubles. */
if (soft_float)
{
cif->flags += FFI_TYPE_STRUCT << (FFI_FLAG_BITS * 8); cif->flags += FFI_TYPE_STRUCT << (FFI_FLAG_BITS * 8);
cif->flags += (FFI_TYPE_DOUBLE + (FFI_TYPE_DOUBLE << FFI_FLAG_BITS)) cif->flags += FFI_TYPE_SMALLSTRUCT2 << (4 + (FFI_FLAG_BITS * 8));
}
else
{
cif->flags += FFI_TYPE_STRUCT << (FFI_FLAG_BITS * 8);
cif->flags += (FFI_TYPE_DOUBLE
+ (FFI_TYPE_DOUBLE << FFI_FLAG_BITS))
<< (4 + (FFI_FLAG_BITS * 8)); << (4 + (FFI_FLAG_BITS * 8));
}
break; break;
default: default:
cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 8); cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 8);
...@@ -499,7 +574,7 @@ extern int ffi_call_O32(void (*)(char *, extended_cif *, int, int), ...@@ -499,7 +574,7 @@ extern int ffi_call_O32(void (*)(char *, extended_cif *, int, int),
/* Low level routine for calling N32 functions */ /* Low level routine for calling N32 functions */
extern int ffi_call_N32(void (*)(char *, extended_cif *, int, int), extern int ffi_call_N32(void (*)(char *, extended_cif *, int, int),
extended_cif *, unsigned, extended_cif *, unsigned,
unsigned, unsigned *, void (*)(void)); unsigned, void *, void (*)(void));
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)
{ {
...@@ -529,10 +604,13 @@ void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) ...@@ -529,10 +604,13 @@ void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
#ifdef FFI_MIPS_N32 #ifdef FFI_MIPS_N32
case FFI_N32: case FFI_N32:
case FFI_N32_SOFT_FLOAT:
case FFI_N64: case FFI_N64:
case FFI_N64_SOFT_FLOAT:
{ {
int copy_rvalue = 0; int copy_rvalue = 0;
void *rvalue_copy = ecif.rvalue; int copy_offset = 0;
char *rvalue_copy = ecif.rvalue;
if (cif->rtype->type == FFI_TYPE_STRUCT && cif->rtype->size < 16) if (cif->rtype->type == FFI_TYPE_STRUCT && cif->rtype->size < 16)
{ {
/* For structures smaller than 16 bytes we clobber memory /* For structures smaller than 16 bytes we clobber memory
...@@ -541,10 +619,20 @@ void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) ...@@ -541,10 +619,20 @@ void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
rvalue_copy = alloca(16); rvalue_copy = alloca(16);
copy_rvalue = 1; copy_rvalue = 1;
} }
else if (cif->rtype->type == FFI_TYPE_FLOAT
&& (cif->abi == FFI_N64_SOFT_FLOAT
|| cif->abi == FFI_N32_SOFT_FLOAT))
{
rvalue_copy = alloca (8);
copy_rvalue = 1;
#ifdef __MIPSEB__
copy_offset = 4;
#endif
}
ffi_call_N32(ffi_prep_args, &ecif, cif->bytes, ffi_call_N32(ffi_prep_args, &ecif, cif->bytes,
cif->flags, rvalue_copy, fn); cif->flags, rvalue_copy, fn);
if (copy_rvalue) if (copy_rvalue)
memcpy(ecif.rvalue, rvalue_copy, cif->rtype->size); memcpy(ecif.rvalue, rvalue_copy + copy_offset, cif->rtype->size);
} }
break; break;
#endif #endif
...@@ -755,7 +843,7 @@ ffi_closure_mips_inner_O32 (ffi_closure *closure, ...@@ -755,7 +843,7 @@ ffi_closure_mips_inner_O32 (ffi_closure *closure,
static void static void
copy_struct_N32(char *target, unsigned offset, ffi_abi abi, ffi_type *type, copy_struct_N32(char *target, unsigned offset, ffi_abi abi, ffi_type *type,
int argn, unsigned arg_offset, ffi_arg *ar, int argn, unsigned arg_offset, ffi_arg *ar,
ffi_arg *fpr) ffi_arg *fpr, int soft_float)
{ {
ffi_type **elt_typep = type->elements; ffi_type **elt_typep = type->elements;
while(*elt_typep) while(*elt_typep)
...@@ -777,7 +865,7 @@ copy_struct_N32(char *target, unsigned offset, ffi_abi abi, ffi_type *type, ...@@ -777,7 +865,7 @@ copy_struct_N32(char *target, unsigned offset, ffi_abi abi, ffi_type *type,
tp = target + offset; tp = target + offset;
if (elt_type->type == FFI_TYPE_DOUBLE) if (elt_type->type == FFI_TYPE_DOUBLE && !soft_float)
*(double *)tp = *(double *)fpp; *(double *)tp = *(double *)fpp;
else else
memcpy(tp, argp + arg_offset, elt_type->size); memcpy(tp, argp + arg_offset, elt_type->size);
...@@ -815,8 +903,12 @@ ffi_closure_mips_inner_N32 (ffi_closure *closure, ...@@ -815,8 +903,12 @@ ffi_closure_mips_inner_N32 (ffi_closure *closure,
ffi_arg *avalue; ffi_arg *avalue;
ffi_type **arg_types; ffi_type **arg_types;
int i, avn, argn; int i, avn, argn;
int soft_float;
ffi_arg *argp;
cif = closure->cif; cif = closure->cif;
soft_float = cif->abi == FFI_N64_SOFT_FLOAT
|| cif->abi == FFI_N32_SOFT_FLOAT;
avalue = alloca (cif->nargs * sizeof (ffi_arg)); avalue = alloca (cif->nargs * sizeof (ffi_arg));
avaluep = alloca (cif->nargs * sizeof (ffi_arg)); avaluep = alloca (cif->nargs * sizeof (ffi_arg));
...@@ -841,7 +933,7 @@ ffi_closure_mips_inner_N32 (ffi_closure *closure, ...@@ -841,7 +933,7 @@ ffi_closure_mips_inner_N32 (ffi_closure *closure,
if (arg_types[i]->type == FFI_TYPE_FLOAT if (arg_types[i]->type == FFI_TYPE_FLOAT
|| arg_types[i]->type == FFI_TYPE_DOUBLE) || arg_types[i]->type == FFI_TYPE_DOUBLE)
{ {
ffi_arg *argp = argn >= 8 ? ar + argn : fpr + argn; argp = (argn >= 8 || soft_float) ? ar + argn : fpr + argn;
#ifdef __MIPSEB__ #ifdef __MIPSEB__
if (arg_types[i]->type == FFI_TYPE_FLOAT && argn < 8) if (arg_types[i]->type == FFI_TYPE_FLOAT && argn < 8)
avaluep[i] = ((char *) argp) + sizeof (float); avaluep[i] = ((char *) argp) + sizeof (float);
...@@ -856,11 +948,15 @@ ffi_closure_mips_inner_N32 (ffi_closure *closure, ...@@ -856,11 +948,15 @@ ffi_closure_mips_inner_N32 (ffi_closure *closure,
if (arg_types[i]->alignment > sizeof(ffi_arg)) if (arg_types[i]->alignment > sizeof(ffi_arg))
argn = ALIGN(argn, arg_types[i]->alignment / sizeof(ffi_arg)); argn = ALIGN(argn, arg_types[i]->alignment / sizeof(ffi_arg));
ffi_arg *argp = ar + argn; argp = ar + argn;
/* The size of a pointer depends on the ABI */ /* The size of a pointer depends on the ABI */
if (type == FFI_TYPE_POINTER) if (type == FFI_TYPE_POINTER)
type = (cif->abi == FFI_N64) ? FFI_TYPE_SINT64 : FFI_TYPE_SINT32; type = (cif->abi == FFI_N64 || cif->abi == FFI_N64_SOFT_FLOAT)
? FFI_TYPE_SINT64 : FFI_TYPE_SINT32;
if (soft_float && type == FFI_TYPE_FLOAT)
type = FFI_TYPE_UINT32;
switch (type) switch (type)
{ {
...@@ -901,7 +997,7 @@ ffi_closure_mips_inner_N32 (ffi_closure *closure, ...@@ -901,7 +997,7 @@ ffi_closure_mips_inner_N32 (ffi_closure *closure,
it was passed in registers. */ it was passed in registers. */
avaluep[i] = alloca(arg_types[i]->size); avaluep[i] = alloca(arg_types[i]->size);
copy_struct_N32(avaluep[i], 0, cif->abi, arg_types[i], copy_struct_N32(avaluep[i], 0, cif->abi, arg_types[i],
argn, 0, ar, fpr); argn, 0, ar, fpr, soft_float);
break; break;
} }
......
...@@ -95,6 +95,15 @@ ...@@ -95,6 +95,15 @@
#define FFI_TYPE_STRUCT_DF 189 #define FFI_TYPE_STRUCT_DF 189
#define FFI_TYPE_STRUCT_SMALL 93 #define FFI_TYPE_STRUCT_SMALL 93
#define FFI_TYPE_STRUCT_SMALL2 109 #define FFI_TYPE_STRUCT_SMALL2 109
/* and for n32 soft float, add 16 * 2^4 */
#define FFI_TYPE_STRUCT_D_SOFT 317
#define FFI_TYPE_STRUCT_F_SOFT 301
#define FFI_TYPE_STRUCT_DD_SOFT 509
#define FFI_TYPE_STRUCT_FF_SOFT 429
#define FFI_TYPE_STRUCT_FD_SOFT 493
#define FFI_TYPE_STRUCT_DF_SOFT 445
#define FFI_TYPE_STRUCT_SOFT 16
#endif #endif
#ifdef LIBFFI_ASM #ifdef LIBFFI_ASM
...@@ -161,6 +170,8 @@ typedef enum ffi_abi { ...@@ -161,6 +170,8 @@ typedef enum ffi_abi {
FFI_N32, FFI_N32,
FFI_N64, FFI_N64,
FFI_O32_SOFT_FLOAT, FFI_O32_SOFT_FLOAT,
FFI_N32_SOFT_FLOAT,
FFI_N64_SOFT_FLOAT,
#ifdef FFI_MIPS_O32 #ifdef FFI_MIPS_O32
#ifdef __mips_soft_float #ifdef __mips_soft_float
...@@ -170,10 +181,18 @@ typedef enum ffi_abi { ...@@ -170,10 +181,18 @@ typedef enum ffi_abi {
#endif #endif
#else #else
# if _MIPS_SIM==_ABI64 # if _MIPS_SIM==_ABI64
# ifdef __mips_soft_float
FFI_DEFAULT_ABI = FFI_N64_SOFT_FLOAT,
# else
FFI_DEFAULT_ABI = FFI_N64, FFI_DEFAULT_ABI = FFI_N64,
# endif
# else
# ifdef __mips_soft_float
FFI_DEFAULT_ABI = FFI_N32_SOFT_FLOAT,
# else # else
FFI_DEFAULT_ABI = FFI_N32, FFI_DEFAULT_ABI = FFI_N32,
# endif # endif
# endif
#endif #endif
FFI_LAST_ABI = FFI_DEFAULT_ABI + 1 FFI_LAST_ABI = FFI_DEFAULT_ABI + 1
......
...@@ -218,7 +218,9 @@ callit: ...@@ -218,7 +218,9 @@ callit:
# Shift the return type flag over # Shift the return type flag over
SRL t6, 8*FFI_FLAG_BITS SRL t6, 8*FFI_FLAG_BITS
beq t6, FFI_TYPE_SINT32, retint
bne t6, FFI_TYPE_INT, retfloat bne t6, FFI_TYPE_INT, retfloat
retint:
jal t9 jal t9
REG_L t4, 4*FFI_SIZEOF_ARG($fp) REG_L t4, 4*FFI_SIZEOF_ARG($fp)
REG_S v0, 0(t4) REG_S v0, 0(t4)
...@@ -277,13 +279,59 @@ retstruct_d_f: ...@@ -277,13 +279,59 @@ retstruct_d_f:
b epilogue b epilogue
retstruct_f_d: retstruct_f_d:
bne t6, FFI_TYPE_STRUCT_FD, retstruct_small bne t6, FFI_TYPE_STRUCT_FD, retstruct_d_soft
jal t9 jal t9
REG_L t4, 4*FFI_SIZEOF_ARG($fp) REG_L t4, 4*FFI_SIZEOF_ARG($fp)
s.s $f0, 0(t4) s.s $f0, 0(t4)
s.d $f2, 8(t4) s.d $f2, 8(t4)
b epilogue b epilogue
retstruct_d_soft:
bne t6, FFI_TYPE_STRUCT_D_SOFT, retstruct_f_soft
jal t9
REG_L t4, 4*FFI_SIZEOF_ARG($fp)
sd v0, 0(t4)
b epilogue
retstruct_f_soft:
bne t6, FFI_TYPE_STRUCT_F_SOFT, retstruct_d_d_soft
jal t9
REG_L t4, 4*FFI_SIZEOF_ARG($fp)
sw v0, 0(t4)
b epilogue
retstruct_d_d_soft:
bne t6, FFI_TYPE_STRUCT_DD_SOFT, retstruct_f_f_soft
jal t9
REG_L t4, 4*FFI_SIZEOF_ARG($fp)
sd v0, 0(t4)
sd v1, 8(t4)
b epilogue
retstruct_f_f_soft:
bne t6, FFI_TYPE_STRUCT_FF_SOFT, retstruct_d_f_soft
jal t9
REG_L t4, 4*FFI_SIZEOF_ARG($fp)
sw v0, 0(t4)
sw v1, 4(t4)
b epilogue
retstruct_d_f_soft:
bne t6, FFI_TYPE_STRUCT_DF_SOFT, retstruct_f_d_soft
jal t9
REG_L t4, 4*FFI_SIZEOF_ARG($fp)
sd v0, 0(t4)
sw v1, 8(t4)
b epilogue
retstruct_f_d_soft:
bne t6, FFI_TYPE_STRUCT_FD_SOFT, retstruct_small
jal t9
REG_L t4, 4*FFI_SIZEOF_ARG($fp)
sw v0, 0(t4)
sd v1, 8(t4)
b epilogue
retstruct_small: retstruct_small:
bne t6, FFI_TYPE_STRUCT_SMALL, retstruct_small2 bne t6, FFI_TYPE_STRUCT_SMALL, retstruct_small2
jal t9 jal t9
...@@ -413,6 +461,11 @@ ffi_closure_N32: ...@@ -413,6 +461,11 @@ ffi_closure_N32:
jalr t9 jalr t9
# Return flags are in v0 # Return flags are in v0
bne v0, FFI_TYPE_SINT32, cls_retint
lw v0, V0_OFF2($sp)
b cls_epilogue
cls_retint:
bne v0, FFI_TYPE_INT, cls_retfloat bne v0, FFI_TYPE_INT, cls_retfloat
REG_L v0, V0_OFF2($sp) REG_L v0, V0_OFF2($sp)
b cls_epilogue b cls_epilogue
......
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