diff options
Diffstat (limited to 'Modules/_ctypes/libffi/src/sh64/ffi.c')
-rw-r--r-- | Modules/_ctypes/libffi/src/sh64/ffi.c | 59 |
1 files changed, 37 insertions, 22 deletions
diff --git a/Modules/_ctypes/libffi/src/sh64/ffi.c b/Modules/_ctypes/libffi/src/sh64/ffi.c index b17cf2c674..8fbc05ca6e 100644 --- a/Modules/_ctypes/libffi/src/sh64/ffi.c +++ b/Modules/_ctypes/libffi/src/sh64/ffi.c @@ -1,5 +1,5 @@ /* ----------------------------------------------------------------------- - ffi.c - Copyright (c) 2003, 2004 Kaz Kojima + ffi.c - Copyright (c) 2003, 2004, 2006, 2007 Kaz Kojima Copyright (c) 2008 Anthony Green SuperH SHmedia Foreign Function Interface @@ -56,9 +56,7 @@ return_type (ffi_type *arg) /* ffi_prep_args is called by the assembly routine once stack space has been allocated for the function's arguments */ -/*@-exportheader@*/ void ffi_prep_args(char *stack, extended_cif *ecif) -/*@=exportheader@*/ { register unsigned int i; register unsigned int avn; @@ -162,6 +160,7 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif) int n, m; int greg; int freg; + int fpair = -1; greg = (return_type (cif->rtype) == FFI_TYPE_STRUCT ? 1 : 0); freg = 0; @@ -177,7 +176,13 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif) cif->bytes += sizeof (UINT64) - sizeof (float); if (freg >= NFREGARG - 1) continue; - freg++; + if (fpair < 0) + { + fpair = freg; + freg += 2; + } + else + fpair = -1; cif->flags2 += ((cif->arg_types)[i]->type) << (2 * j++); break; @@ -186,7 +191,6 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif) continue; if ((freg + 1) < NFREGARG) { - freg = (freg + 1) & ~1; freg += 2; cif->flags2 += ((cif->arg_types)[i]->type) << (2 * j++); } @@ -264,9 +268,7 @@ void ffi_call(/*@dependent@*/ ffi_cif *cif, else if ((rvalue == NULL) && (cif->rtype->type == FFI_TYPE_STRUCT)) { - /*@-sysunrecog@*/ ecif.rvalue = alloca(cif->rtype->size); - /*@=sysunrecog@*/ } else ecif.rvalue = rvalue; @@ -274,10 +276,8 @@ void ffi_call(/*@dependent@*/ ffi_cif *cif, switch (cif->abi) { case FFI_SYSV: - /*@-usedef@*/ - ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes, - cif->flags, cif->flags2, ecif.rvalue, fn); - /*@=usedef@*/ + ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes, cif->flags, cif->flags2, + ecif.rvalue, fn); break; default: FFI_ASSERT(0); @@ -294,10 +294,11 @@ extern void ffi_closure_SYSV (void); extern void __ic_invalidate (void *line); ffi_status -ffi_prep_closure (ffi_closure *closure, - ffi_cif *cif, - void (*fun)(ffi_cif*, void*, void**, void*), - void *user_data) +ffi_prep_closure_loc (ffi_closure *closure, + ffi_cif *cif, + void (*fun)(ffi_cif*, void*, void**, void*), + void *user_data, + void *codeloc) { unsigned int *tramp; @@ -321,8 +322,8 @@ ffi_prep_closure (ffi_closure *closure, tramp[2] = 0xcc000010 | (((UINT32) ffi_closure_SYSV) >> 16) << 10; tramp[3] = 0xc8000010 | (((UINT32) ffi_closure_SYSV) & 0xffff) << 10; tramp[4] = 0x6bf10600; - tramp[5] = 0xcc000010 | (((UINT32) closure) >> 16) << 10; - tramp[6] = 0xc8000010 | (((UINT32) closure) & 0xffff) << 10; + tramp[5] = 0xcc000010 | (((UINT32) codeloc) >> 16) << 10; + tramp[6] = 0xc8000010 | (((UINT32) codeloc) & 0xffff) << 10; tramp[7] = 0x4401fff0; closure->cif = cif; @@ -330,7 +331,8 @@ ffi_prep_closure (ffi_closure *closure, closure->user_data = user_data; /* Flush the icache. */ - asm volatile ("ocbwb %0,0; synco; icbi %0,0; synci" : : "r" (tramp)); + asm volatile ("ocbwb %0,0; synco; icbi %1,0; synci" : : "r" (tramp), + "r"(codeloc)); return FFI_OK; } @@ -352,6 +354,7 @@ ffi_closure_helper_SYSV (ffi_closure *closure, UINT64 *rvalue, int i, avn; int greg, freg; ffi_cif *cif; + int fpair = -1; cif = closure->cif; avalue = alloca (cif->nargs * sizeof (void *)); @@ -360,7 +363,7 @@ ffi_closure_helper_SYSV (ffi_closure *closure, UINT64 *rvalue, returns the data directly to the caller. */ if (return_type (cif->rtype) == FFI_TYPE_STRUCT) { - rvalue = *pgr; + rvalue = (UINT64 *) *pgr; greg = 1; } else @@ -404,11 +407,24 @@ ffi_closure_helper_SYSV (ffi_closure *closure, UINT64 *rvalue, if ((*p_arg)->type == FFI_TYPE_FLOAT) { if (freg < NFREGARG - 1) + { + if (fpair >= 0) + { + avalue[i] = (UINT32 *) pfr + fpair; + fpair = -1; + } + else + { #ifdef __LITTLE_ENDIAN__ - avalue[i] = (UINT32 *) pfr + (1 ^ freg++); + fpair = freg; + avalue[i] = (UINT32 *) pfr + (1 ^ freg); #else - avalue[i] = (UINT32 *) pfr + freg++; + fpair = 1 ^ freg; + avalue[i] = (UINT32 *) pfr + freg; #endif + freg += 2; + } + } else #ifdef __LITTLE_ENDIAN__ avalue[i] = pgr + greg; @@ -430,7 +446,6 @@ ffi_closure_helper_SYSV (ffi_closure *closure, UINT64 *rvalue, avalue[i] = pgr + greg; else { - freg = (freg + 1) & ~1; avalue[i] = pfr + (freg >> 1); freg += 2; } |