ffi.c (ffi_prep_cif_machdep): Handle float arguments passed with FP registers correctly.

* src/sh64/ffi.c (ffi_prep_cif_machdep): Handle float arguments
	passed with FP registers correctly.
	(ffi_closure_helper_SYSV): Likewise.
	* src/sh64/sysv.S: Likewise.

From-SVN: r112083
This commit is contained in:
Kaz Kojima 2006-03-15 11:50:24 +00:00
parent 8b96512fcc
commit 697701ad65
3 changed files with 46 additions and 12 deletions

View File

@ -1,3 +1,10 @@
2006-03-15 Kaz Kojima <kkojima@gcc.gnu.org>
* src/sh64/ffi.c (ffi_prep_cif_machdep): Handle float arguments
passed with FP registers correctly.
(ffi_closure_helper_SYSV): Likewise.
* src/sh64/sysv.S: Likewise.
2006-03-01 Andreas Tobler <a.tobler@schweiz.ch>
* testsuite/libffi.special/unwindtest.cc (closure_test_fn): Mark cif,

View File

@ -1,5 +1,5 @@
/* -----------------------------------------------------------------------
ffi.c - Copyright (c) 2003, 2004 Kaz Kojima
ffi.c - Copyright (c) 2003, 2004, 2006 Kaz Kojima
SuperH SHmedia Foreign Function Interface
@ -160,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;
@ -175,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;
@ -184,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++);
}
@ -350,6 +356,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 *));
@ -358,7 +365,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
@ -402,11 +409,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;
@ -428,7 +448,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;
}

View File

@ -1,5 +1,5 @@
/* -----------------------------------------------------------------------
sysv.S - Copyright (c) 2003, 2004 Kaz Kojima
sysv.S - Copyright (c) 2003, 2004, 2006 Kaz Kojima
SuperH SHmedia Foreign Function Interface
@ -84,6 +84,7 @@ ENTRY(ffi_call_SYSV)
addi r15, 64, r22
movi 0, r0
movi 0, r1
movi -1, r23
pt/l 1f, tr1
bnei/l r29, FFI_TYPE_STRUCT, tr1
@ -106,9 +107,6 @@ ENTRY(ffi_call_SYSV)
.L_pass_d:
addi r0, 1, r0
addi r1, 1, r1
andi r1, ~1, r1
pt/l 3f, tr0
movi 12, r20
bge/l r1, r20, tr0
@ -158,13 +156,23 @@ ENTRY(ffi_call_SYSV)
addi.l r15, 8, r15
3:
pt/l .L_pass, tr0
addi r1, 1, r1
blink tr0, r63
.L_pop_f:
pt/l .L_pop_f_tbl, tr1
pt/l 5f, tr2
gettr tr1, r20
bge/l r23, r63, tr2
add r1, r63, r23
shlli r1, 3, r21
addi r1, 2, r1
add r20, r21, r20
ptabs/l r20, tr1
blink tr1, r63
5:
addi r23, 1, r21
movi -1, r23
shlli r21, 3, r21
add r20, r21, r20
ptabs/l r20, tr1
blink tr1, r63