This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Reinstate powerpc bounce buffer copying in ffi.c


The first patch in the series is a little different to the
corresponding upstream libffi patch, because there I needed to revert
some fixes first.  The second patch in the series is entirely missing
due to the testsuite already being fixed in gcc.

This patch properly copies the bounce buffer to destination, and only
uses the bounce buffer for FFI_SYSV.  I also fix an accounting error
in integer register usage.

	* src/powerpc/ffi.c (ffi_prep_cif_machdep): Do not consume an
	int arg when returning a small struct for FFI_SYSV ABI.
	(ffi_call): Only use bounce buffer when FLAG_RETURNS_SMST.
	Properly copy bounce buffer to destination.

diff -urp gcc-virgin/libffi/src/powerpc/ffi.c gcc1/libffi/src/powerpc/ffi.c
--- gcc-virgin/libffi/src/powerpc/ffi.c	2013-06-25 09:36:39.259402853 +0930
+++ gcc1/libffi/src/powerpc/ffi.c	2013-11-15 23:06:57.313036827 +1030
@@ -691,7 +691,7 @@
     case FFI_TYPE_STRUCT:
       /*
        * The final SYSV ABI says that structures smaller or equal 8 bytes
-       * are returned in r3/r4. The FFI_GCC_SYSV ABI instead returns them
+       * are returned in r3/r4.  The FFI_GCC_SYSV ABI instead returns them
        * in memory.
        *
        * NOTE: The assembly code can safely assume that it just needs to
@@ -700,7 +700,10 @@
        *       set.
        */
       if (cif->abi == FFI_SYSV && size <= 8)
-	flags |= FLAG_RETURNS_SMST;
+	{
+	  flags |= FLAG_RETURNS_SMST;
+	  break;
+	}
       intarg_count++;
       flags |= FLAG_RETVAL_REFERENCE;
       /* Fall through.  */
@@ -919,30 +922,25 @@
 {
   /*
    * The final SYSV ABI says that structures smaller or equal 8 bytes
-   * are returned in r3/r4. The FFI_GCC_SYSV ABI instead returns them
+   * are returned in r3/r4.  The FFI_GCC_SYSV ABI instead returns them
    * in memory.
    *
-   * Just to keep things simple for the assembly code, we will always
-   * bounce-buffer struct return values less than or equal to 8 bytes.
-   * This allows the ASM to handle SYSV small structures by directly
-   * writing r3 and r4 to memory without worrying about struct size.
+   * We bounce-buffer SYSV small struct return values so that sysv.S
+   * can write r3 and r4 to memory without worrying about struct size.
    */
   unsigned int smst_buffer[2];
   extended_cif ecif;
-  unsigned int rsize = 0;
 
   ecif.cif = cif;
   ecif.avalue = avalue;
 
-  /* Ensure that we have a valid struct return value */
   ecif.rvalue = rvalue;
-  if (cif->rtype->type == FFI_TYPE_STRUCT) {
-    rsize = cif->rtype->size;
-    if (rsize <= 8)
-      ecif.rvalue = smst_buffer;
-    else if (!rvalue)
-      ecif.rvalue = alloca(rsize);
-  }
+  if ((cif->flags & FLAG_RETURNS_SMST) != 0)
+    ecif.rvalue = smst_buffer;
+  /* Ensure that we have a valid struct return value.
+     FIXME: Isn't this just papering over a user problem?  */
+  else if (!rvalue && cif->rtype->type == FFI_TYPE_STRUCT)
+    ecif.rvalue = alloca (cif->rtype->size);
 
   switch (cif->abi)
     {
@@ -967,7 +965,21 @@
 
   /* Check for a bounce-buffered return value */
   if (rvalue && ecif.rvalue == smst_buffer)
-    memcpy(rvalue, smst_buffer, rsize);
+    {
+      unsigned int rsize = cif->rtype->size;
+#ifndef __LITTLE_ENDIAN__
+      /* The SYSV ABI returns a structure of up to 4 bytes in size
+	 left-padded in r3.  */
+      if (rsize <= 4)
+	memcpy (rvalue, (char *) smst_buffer + 4 - rsize, rsize);
+      /* The SYSV ABI returns a structure of up to 8 bytes in size
+	 left-padded in r3/r4.  */
+      else if (rsize <= 8)
+	memcpy (rvalue, (char *) smst_buffer + 8 - rsize, rsize);
+      else
+#endif
+	memcpy (rvalue, smst_buffer, rsize);
+    }
 }
 
 

-- 
Alan Modra
Australia Development Lab, IBM


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]