diff options
author | David Daney <ddaney@caviumnetworks.com> | 2009-09-15 17:15:33 +0000 |
---|---|---|
committer | David Daney <daney@gcc.gnu.org> | 2009-09-15 17:15:33 +0000 |
commit | 5cbf8c8d0b15e9971e6a054bd4e9ba39e37f6636 (patch) | |
tree | bcf96a2bec0678e59202d229d2cf488b66017407 /libffi | |
parent | 1c3c9f1247b44f08530c7c9b5288aabc2bbc6895 (diff) | |
download | gcc-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/ChangeLog | 20 | ||||
-rw-r--r-- | libffi/src/java_raw_api.c | 3 | ||||
-rw-r--r-- | libffi/src/mips/ffi.c | 154 | ||||
-rw-r--r-- | libffi/src/mips/ffitarget.h | 19 | ||||
-rw-r--r-- | libffi/src/mips/n32.S | 57 |
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 |