aboutsummaryrefslogtreecommitdiff
path: root/libffi
diff options
context:
space:
mode:
authorDavid Daney <ddaney@caviumnetworks.com>2009-09-15 17:15:33 +0000
committerDavid Daney <daney@gcc.gnu.org>2009-09-15 17:15:33 +0000
commit5cbf8c8d0b15e9971e6a054bd4e9ba39e37f6636 (patch)
treebcf96a2bec0678e59202d229d2cf488b66017407 /libffi
parent1c3c9f1247b44f08530c7c9b5288aabc2bbc6895 (diff)
downloadgcc-5cbf8c8d0b15e9971e6a054bd4e9ba39e37f6636.zip
gcc-5cbf8c8d0b15e9971e6a054bd4e9ba39e37f6636.tar.gz
gcc-5cbf8c8d0b15e9971e6a054bd4e9ba39e37f6636.tar.bz2
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
Diffstat (limited to 'libffi')
-rw-r--r--libffi/ChangeLog20
-rw-r--r--libffi/src/java_raw_api.c3
-rw-r--r--libffi/src/mips/ffi.c154
-rw-r--r--libffi/src/mips/ffitarget.h19
-rw-r--r--libffi/src/mips/n32.S57
5 files changed, 219 insertions, 34 deletions
diff --git a/libffi/ChangeLog b/libffi/ChangeLog
index a8b9228..684a0e8 100644
--- a/libffi/ChangeLog
+++ b/libffi/ChangeLog
@@ -1,3 +1,23 @@
+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>
* configure.ac (AC_PREREQ): Bump to 2.64.
diff --git a/libffi/src/java_raw_api.c b/libffi/src/java_raw_api.c
index 1f8f983..9c5383e 100644
--- a/libffi/src/java_raw_api.c
+++ b/libffi/src/java_raw_api.c
@@ -276,9 +276,6 @@ ffi_java_raw_to_rvalue (ffi_cif *cif, void *rvalue)
case FFI_TYPE_SINT16:
case FFI_TYPE_SINT32:
case FFI_TYPE_INT:
-#if FFI_SIZEOF_JAVA_RAW == 4
- case FFI_TYPE_POINTER:
-#endif
*(SINT64 *)rvalue >>= 32;
break;
diff --git a/libffi/src/mips/ffi.c b/libffi/src/mips/ffi.c
index b6887be..3143dcf 100644
--- a/libffi/src/mips/ffi.c
+++ b/libffi/src/mips/ffi.c
@@ -99,7 +99,7 @@ static void ffi_prep_args(char *stack,
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;
unsigned int a;
@@ -123,9 +123,25 @@ static void ffi_prep_args(char *stack,
/* The size of a pointer depends on the ABI */
if (type == FFI_TYPE_POINTER)
- type =
- (ecif->cif->abi == FFI_N64) ? FFI_TYPE_SINT64 : FFI_TYPE_SINT32;
+ type = (ecif->cif->abi == FFI_N64
+ || 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)
{
case FFI_TYPE_SINT8:
@@ -205,13 +221,17 @@ static void ffi_prep_args(char *stack,
definitions and generates the appropriate flags. */
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 index = 0;
ffi_type *e;
+ if (soft_float)
+ return 0;
+
while ((e = arg->elements[index]))
{
/* Align this object. */
@@ -236,7 +256,7 @@ calc_n32_struct_flags(ffi_type *arg, unsigned *loc, unsigned *arg_reg)
}
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 small = FFI_TYPE_SMALLSTRUCT;
@@ -256,6 +276,7 @@ calc_n32_return_struct_flags(ffi_type *arg)
small = FFI_TYPE_SMALLSTRUCT2;
e = arg->elements[0];
+
if (e->type == FFI_TYPE_DOUBLE)
flags = FFI_TYPE_DOUBLE;
else if (e->type == FFI_TYPE_FLOAT)
@@ -276,6 +297,8 @@ calc_n32_return_struct_flags(ffi_type *arg)
floats! This must be passed the old way. */
return small;
}
+ if (soft_float)
+ flags += FFI_TYPE_STRUCT_SOFT;
}
else
if (!flags)
@@ -382,16 +405,19 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
#ifdef FFI_MIPS_N32
/* Set the flags necessary for N32 processing */
{
+ int type;
unsigned arg_reg = 0;
unsigned loc = 0;
unsigned count = (cif->nargs < 8) ? cif->nargs : 8;
unsigned index = 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)
{
- struct_flags = calc_n32_return_struct_flags(cif->rtype);
+ struct_flags = calc_n32_return_struct_flags(soft_float, cif->rtype);
if (struct_flags == 0)
{
@@ -411,7 +437,22 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
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_DOUBLE:
@@ -423,17 +464,25 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
/* Align it. */
arg_reg = ALIGN(arg_reg, 2);
/* Treat it as two adjacent doubles. */
- cif->flags +=
- (FFI_TYPE_DOUBLE << (arg_reg * FFI_FLAG_BITS));
- arg_reg++;
- cif->flags +=
- (FFI_TYPE_DOUBLE << (arg_reg * FFI_FLAG_BITS));
- arg_reg++;
+ if (soft_float)
+ {
+ arg_reg += 2;
+ }
+ else
+ {
+ cif->flags +=
+ (FFI_TYPE_DOUBLE << (arg_reg * FFI_FLAG_BITS));
+ arg_reg++;
+ cif->flags +=
+ (FFI_TYPE_DOUBLE << (arg_reg * FFI_FLAG_BITS));
+ arg_reg++;
+ }
break;
case FFI_TYPE_STRUCT:
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);
break;
@@ -469,17 +518,43 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
case FFI_TYPE_VOID:
/* Do nothing, 'cause FFI_TYPE_VOID is 0 */
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:
+ if (soft_float)
+ {
+ cif->flags += FFI_TYPE_SINT32 << (FFI_FLAG_BITS * 8);
+ break;
+ }
+ /* else fall through */
case FFI_TYPE_DOUBLE:
- cif->flags += cif->rtype->type << (FFI_FLAG_BITS * 8);
+ if (soft_float)
+ cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 8);
+ else
+ cif->flags += cif->rtype->type << (FFI_FLAG_BITS * 8);
break;
+
case FFI_TYPE_LONGDOUBLE:
/* Long double is returned as if it were a struct containing
two doubles. */
- 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));
+ if (soft_float)
+ {
+ cif->flags += FFI_TYPE_STRUCT << (FFI_FLAG_BITS * 8);
+ 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));
+ }
break;
default:
cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 8);
@@ -499,7 +574,7 @@ extern int ffi_call_O32(void (*)(char *, extended_cif *, int, int),
/* Low level routine for calling N32 functions */
extern int ffi_call_N32(void (*)(char *, extended_cif *, int, int),
extended_cif *, unsigned,
- unsigned, unsigned *, void (*)(void));
+ unsigned, void *, void (*)(void));
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
case FFI_N32:
+ case FFI_N32_SOFT_FLOAT:
case FFI_N64:
+ case FFI_N64_SOFT_FLOAT:
{
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)
{
/* 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)
rvalue_copy = alloca(16);
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,
cif->flags, rvalue_copy, fn);
if (copy_rvalue)
- memcpy(ecif.rvalue, rvalue_copy, cif->rtype->size);
+ memcpy(ecif.rvalue, rvalue_copy + copy_offset, cif->rtype->size);
}
break;
#endif
@@ -755,7 +843,7 @@ ffi_closure_mips_inner_O32 (ffi_closure *closure,
static void
copy_struct_N32(char *target, unsigned offset, ffi_abi abi, ffi_type *type,
int argn, unsigned arg_offset, ffi_arg *ar,
- ffi_arg *fpr)
+ ffi_arg *fpr, int soft_float)
{
ffi_type **elt_typep = type->elements;
while(*elt_typep)
@@ -777,7 +865,7 @@ copy_struct_N32(char *target, unsigned offset, ffi_abi abi, ffi_type *type,
tp = target + offset;
- if (elt_type->type == FFI_TYPE_DOUBLE)
+ if (elt_type->type == FFI_TYPE_DOUBLE && !soft_float)
*(double *)tp = *(double *)fpp;
else
memcpy(tp, argp + arg_offset, elt_type->size);
@@ -815,8 +903,12 @@ ffi_closure_mips_inner_N32 (ffi_closure *closure,
ffi_arg *avalue;
ffi_type **arg_types;
int i, avn, argn;
+ int soft_float;
+ ffi_arg *argp;
cif = closure->cif;
+ soft_float = cif->abi == FFI_N64_SOFT_FLOAT
+ || cif->abi == FFI_N32_SOFT_FLOAT;
avalue = alloca (cif->nargs * sizeof (ffi_arg));
avaluep = alloca (cif->nargs * sizeof (ffi_arg));
@@ -839,9 +931,9 @@ ffi_closure_mips_inner_N32 (ffi_closure *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)
{
- ffi_arg *argp = argn >= 8 ? ar + argn : fpr + argn;
+ argp = (argn >= 8 || soft_float) ? ar + argn : fpr + argn;
#ifdef __MIPSEB__
if (arg_types[i]->type == FFI_TYPE_FLOAT && argn < 8)
avaluep[i] = ((char *) argp) + sizeof (float);
@@ -856,11 +948,15 @@ ffi_closure_mips_inner_N32 (ffi_closure *closure,
if (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 */
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)
{
@@ -901,7 +997,7 @@ ffi_closure_mips_inner_N32 (ffi_closure *closure,
it was passed in registers. */
avaluep[i] = alloca(arg_types[i]->size);
copy_struct_N32(avaluep[i], 0, cif->abi, arg_types[i],
- argn, 0, ar, fpr);
+ argn, 0, ar, fpr, soft_float);
break;
}
diff --git a/libffi/src/mips/ffitarget.h b/libffi/src/mips/ffitarget.h
index 214afe4..dd3fe73 100644
--- a/libffi/src/mips/ffitarget.h
+++ b/libffi/src/mips/ffitarget.h
@@ -95,6 +95,15 @@
#define FFI_TYPE_STRUCT_DF 189
#define FFI_TYPE_STRUCT_SMALL 93
#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
#ifdef LIBFFI_ASM
@@ -161,6 +170,8 @@ typedef enum ffi_abi {
FFI_N32,
FFI_N64,
FFI_O32_SOFT_FLOAT,
+ FFI_N32_SOFT_FLOAT,
+ FFI_N64_SOFT_FLOAT,
#ifdef FFI_MIPS_O32
#ifdef __mips_soft_float
@@ -170,9 +181,17 @@ typedef enum ffi_abi {
#endif
#else
# if _MIPS_SIM==_ABI64
+# ifdef __mips_soft_float
+ FFI_DEFAULT_ABI = FFI_N64_SOFT_FLOAT,
+# else
FFI_DEFAULT_ABI = FFI_N64,
+# endif
# else
+# ifdef __mips_soft_float
+ FFI_DEFAULT_ABI = FFI_N32_SOFT_FLOAT,
+# else
FFI_DEFAULT_ABI = FFI_N32,
+# endif
# endif
#endif
diff --git a/libffi/src/mips/n32.S b/libffi/src/mips/n32.S
index 477f30b..6f0f4c6 100644
--- a/libffi/src/mips/n32.S
+++ b/libffi/src/mips/n32.S
@@ -217,8 +217,10 @@ callit:
# Shift the return type flag over
SRL t6, 8*FFI_FLAG_BITS
-
+
+ beq t6, FFI_TYPE_SINT32, retint
bne t6, FFI_TYPE_INT, retfloat
+retint:
jal t9
REG_L t4, 4*FFI_SIZEOF_ARG($fp)
REG_S v0, 0(t4)
@@ -277,12 +279,58 @@ retstruct_d_f:
b epilogue
retstruct_f_d:
- bne t6, FFI_TYPE_STRUCT_FD, retstruct_small
+ bne t6, FFI_TYPE_STRUCT_FD, retstruct_d_soft
jal t9
REG_L t4, 4*FFI_SIZEOF_ARG($fp)
s.s $f0, 0(t4)
s.d $f2, 8(t4)
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:
bne t6, FFI_TYPE_STRUCT_SMALL, retstruct_small2
@@ -413,6 +461,11 @@ ffi_closure_N32:
jalr t9
# 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
REG_L v0, V0_OFF2($sp)
b cls_epilogue