summaryrefslogtreecommitdiff
path: root/libffi
diff options
context:
space:
mode:
authorkkojima <kkojima@138bc75d-0d04-0410-961f-82ee72b054a4>2006-03-15 11:50:24 +0000
committerkkojima <kkojima@138bc75d-0d04-0410-961f-82ee72b054a4>2006-03-15 11:50:24 +0000
commitcd10a5a729c74479d5e4845fcc07f61492978885 (patch)
tree9435cef835d70c2e699f1ebc93176d8bd6e6cb0f /libffi
parent340690bfda9c870fc2a84a5fcc8c48ccb3bb8fdb (diff)
downloadgcc-cd10a5a729c74479d5e4845fcc07f61492978885.tar.gz
* 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@112083 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libffi')
-rw-r--r--libffi/ChangeLog7
-rw-r--r--libffi/src/sh64/ffi.c33
-rw-r--r--libffi/src/sh64/sysv.S18
3 files changed, 46 insertions, 12 deletions
diff --git a/libffi/ChangeLog b/libffi/ChangeLog
index f017dacda73..0622223c04e 100644
--- a/libffi/ChangeLog
+++ b/libffi/ChangeLog
@@ -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,
diff --git a/libffi/src/sh64/ffi.c b/libffi/src/sh64/ffi.c
index abf3f0d71ae..9c40dadc410 100644
--- a/libffi/src/sh64/ffi.c
+++ b/libffi/src/sh64/ffi.c
@@ -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;
}
diff --git a/libffi/src/sh64/sysv.S b/libffi/src/sh64/sysv.S
index 19f1b51b9a7..bdee4188ec1 100644
--- a/libffi/src/sh64/sysv.S
+++ b/libffi/src/sh64/sysv.S
@@ -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