ffi.c (ffi_prep_cif_machdep): Handle float arguments passed with FP registers correctly.
authorKaz Kojima <kkojima@gcc.gnu.org>
Wed, 15 Mar 2006 11:50:24 +0000 (11:50 +0000)
committerKaz Kojima <kkojima@gcc.gnu.org>
Wed, 15 Mar 2006 11:50:24 +0000 (11:50 +0000)
* 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
libffi/src/sh64/ffi.c
libffi/src/sh64/sysv.S

index f017dacda73312df31006ffb70bec943ef0d561e..0622223c04e1c5e86a55a564b85e4aa30ce7e14a 100644 (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,
index abf3f0d71ae30a0c34d799e09e9a0af8b16a6aad..9c40dadc410fdc9bfb159536d873d9cd99f8e7d1 100644 (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;
            }
index 19f1b51b9a75885ed8c681a63cc379ad7c45f6cb..bdee4188ec187bac7e0107d57cc1b1a291167c85 100644 (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