From 697701ad65fdb31eadfbd1927d6da6845b558bbd Mon Sep 17 00:00:00 2001 From: Kaz Kojima Date: Wed, 15 Mar 2006 11:50:24 +0000 Subject: [PATCH] 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 --- libffi/ChangeLog | 7 +++++++ libffi/src/sh64/ffi.c | 33 ++++++++++++++++++++++++++------- libffi/src/sh64/sysv.S | 18 +++++++++++++----- 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 + + * 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 * 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