mirror of
https://github.com/partic2/libffi
synced 2026-11-10 10:07:19 +00:00
add support for go closure support on mips
This commit is contained in:
+65
-13
@@ -581,14 +581,15 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
|
||||
/* Low level routine for calling O32 functions */
|
||||
extern int ffi_call_O32(void (*)(char *, extended_cif *, int, int),
|
||||
extended_cif *, unsigned,
|
||||
unsigned, unsigned *, void (*)(void));
|
||||
unsigned, unsigned *, void (*)(void), void *closure);
|
||||
|
||||
/* Low level routine for calling N32 functions */
|
||||
extern int ffi_call_N32(void (*)(char *, extended_cif *, int, int),
|
||||
extended_cif *, unsigned,
|
||||
unsigned, void *, void (*)(void));
|
||||
unsigned, void *, void (*)(void), void *closure);
|
||||
|
||||
void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
|
||||
void ffi_call_int(ffi_cif *cif, void (*fn)(void), void *rvalue,
|
||||
void **avalue, void *closure)
|
||||
{
|
||||
extended_cif ecif;
|
||||
|
||||
@@ -610,7 +611,7 @@ void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
|
||||
case FFI_O32:
|
||||
case FFI_O32_SOFT_FLOAT:
|
||||
ffi_call_O32(ffi_prep_args, &ecif, cif->bytes,
|
||||
cif->flags, ecif.rvalue, fn);
|
||||
cif->flags, ecif.rvalue, fn, closure);
|
||||
break;
|
||||
#endif
|
||||
|
||||
@@ -642,7 +643,7 @@ void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
|
||||
#endif
|
||||
}
|
||||
ffi_call_N32(ffi_prep_args, &ecif, cif->bytes,
|
||||
cif->flags, rvalue_copy, fn);
|
||||
cif->flags, rvalue_copy, fn, closure);
|
||||
if (copy_rvalue)
|
||||
memcpy(ecif.rvalue, rvalue_copy + copy_offset, cif->rtype->size);
|
||||
}
|
||||
@@ -655,6 +656,20 @@ 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)
|
||||
{
|
||||
ffi_call_int (cif, fn, rvalue, avalue, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
ffi_call_go (ffi_cif *cif, void (*fn)(void), void *rvalue,
|
||||
void **avalue, void *closure)
|
||||
{
|
||||
ffi_call_int (cif, fn, rvalue, avalue, closure);
|
||||
}
|
||||
|
||||
|
||||
#if FFI_CLOSURES
|
||||
#if defined(FFI_MIPS_O32)
|
||||
extern void ffi_closure_O32(void);
|
||||
@@ -762,17 +777,17 @@ ffi_prep_closure_loc (ffi_closure *closure,
|
||||
* Based on the similar routine for sparc.
|
||||
*/
|
||||
int
|
||||
ffi_closure_mips_inner_O32 (ffi_closure *closure,
|
||||
ffi_closure_mips_inner_O32 (ffi_cif *cif,
|
||||
void (*fun)(ffi_cif*, void*, void**, void*),
|
||||
void *user_data;
|
||||
void *rvalue, ffi_arg *ar,
|
||||
double *fpr)
|
||||
{
|
||||
ffi_cif *cif;
|
||||
void **avaluep;
|
||||
ffi_arg *avalue;
|
||||
ffi_type **arg_types;
|
||||
int i, avn, argn, seen_int;
|
||||
|
||||
cif = closure->cif;
|
||||
avalue = alloca (cif->nargs * sizeof (ffi_arg));
|
||||
avaluep = alloca (cif->nargs * sizeof (ffi_arg));
|
||||
|
||||
@@ -840,7 +855,7 @@ ffi_closure_mips_inner_O32 (ffi_closure *closure,
|
||||
}
|
||||
|
||||
/* Invoke the closure. */
|
||||
(closure->fun) (cif, rvalue, avaluep, closure->user_data);
|
||||
fun(cif, rvalue, avaluep, user_data);
|
||||
|
||||
if (cif->abi == FFI_O32_SOFT_FLOAT)
|
||||
{
|
||||
@@ -916,11 +931,12 @@ copy_struct_N32(char *target, unsigned offset, ffi_abi abi, ffi_type *type,
|
||||
*
|
||||
*/
|
||||
int
|
||||
ffi_closure_mips_inner_N32 (ffi_closure *closure,
|
||||
ffi_closure_mips_inner_N32 (ffi_cif *cif,
|
||||
void (*fun)(ffi_cif*, void*, void**, void*),
|
||||
void *user_data,
|
||||
void *rvalue, ffi_arg *ar,
|
||||
ffi_arg *fpr)
|
||||
{
|
||||
ffi_cif *cif;
|
||||
void **avaluep;
|
||||
ffi_arg *avalue;
|
||||
ffi_type **arg_types;
|
||||
@@ -928,7 +944,6 @@ ffi_closure_mips_inner_N32 (ffi_closure *closure,
|
||||
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));
|
||||
@@ -1040,11 +1055,48 @@ ffi_closure_mips_inner_N32 (ffi_closure *closure,
|
||||
}
|
||||
|
||||
/* Invoke the closure. */
|
||||
(closure->fun) (cif, rvalue, avaluep, closure->user_data);
|
||||
fun (cif, rvalue, avaluep, user_data);
|
||||
|
||||
return cif->flags >> (FFI_FLAG_BITS * 8);
|
||||
}
|
||||
|
||||
#endif /* FFI_MIPS_N32 */
|
||||
|
||||
#if defined(FFI_MIPS_O32)
|
||||
extern void ffi_closure_O32(void);
|
||||
#else
|
||||
extern void ffi_closure_N32(void);
|
||||
#endif /* FFI_MIPS_O32 */
|
||||
|
||||
void
|
||||
ffi_status
|
||||
ffi_prep_go_closure (ffi_go_closure* closure, ffi_cif* cif,
|
||||
void (*fun)(ffi_cif*,void*,void**,void*))
|
||||
{
|
||||
void * fn;
|
||||
|
||||
#if defined(FFI_MIPS_O32)
|
||||
if (cif->abi != FFI_O32 && cif->abi != FFI_O32_SOFT_FLOAT)
|
||||
return FFI_BAD_ABI;
|
||||
fn = ffi_go_closure_O32;
|
||||
#else
|
||||
#if _MIPS_SIM ==_ABIN32
|
||||
if (cif->abi != FFI_N32
|
||||
&& cif->abi != FFI_N32_SOFT_FLOAT)
|
||||
return FFI_BAD_ABI;
|
||||
#else
|
||||
if (cif->abi != FFI_N64
|
||||
&& cif->abi != FFI_N64_SOFT_FLOAT)
|
||||
return FFI_BAD_ABI;
|
||||
#endif
|
||||
fn = ffi_go_closure_N32;
|
||||
#endif /* FFI_MIPS_O32 */
|
||||
|
||||
closure->tramp = (void *)fn;
|
||||
closure->cif = cif;
|
||||
closure->fun = fun;
|
||||
|
||||
return FFI_OK;
|
||||
}
|
||||
|
||||
#endif /* FFI_CLOSURES */
|
||||
|
||||
Reference in New Issue
Block a user