[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#692508: libffi: please support arch powerpcspe



Source: libffi
Version: 3.0.10-3
Severity: wishlist
Tags: patch sid
User: debian-powerpcspe@breakpoint.cc
Usertags: powerpcspe

Hi,

please support powerpcspe [0]. libffi 3.0.10-3 contains powerpc assembler code
that ftbfs on powerpcspe. This is fixed in 3.0.11 (now in experimental). I
backported the respective fix and attached a patch. So you can choose to either
upload 3.0.11 to unstable or use the attached patch.

Thanks in advance,

Roland


[0] http://wiki.debian.org/PowerPCSPEPort


-- System Information:
Debian Release: wheezy/sid
  APT prefers unstable
  APT policy: (500, 'unstable'), (1, 'experimental')
Architecture: amd64 (x86_64)

Kernel: Linux 3.5.0 (SMP w/4 CPU cores)
Locale: LANG=en_GB.UTF-8, LC_CTYPE=en_GB.UTF-8 (charmap=UTF-8) (ignored: LC_ALL set to en_GB.UTF-8)
Shell: /bin/sh linked to /bin/dash
diff -ruN libffi-3.0.10.orig/src/powerpc/ffi.c libffi-3.0.10/src/powerpc/ffi.c
--- libffi-3.0.10.orig/src/powerpc/ffi.c	2012-11-06 21:34:20.000000000 +0000
+++ libffi-3.0.10/src/powerpc/ffi.c	2012-11-06 21:38:04.000000000 +0000
@@ -932,21 +932,22 @@
 void
 ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
 {
+  unsigned int smst_buffer[2];
   extended_cif ecif;
+  unsigned int rsize = 0;
 
   ecif.cif = cif;
   ecif.avalue = avalue;
 
-  /* If the return value is a struct and we don't have a return	*/
-  /* value address then we need to make one		        */
-
-  if ((rvalue == NULL) && (cif->rtype->type == FFI_TYPE_STRUCT))
-    {
-      ecif.rvalue = alloca(cif->rtype->size);
-    }
-  else
-    ecif.rvalue = rvalue;
-
+  /* 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);
+  }
 
   switch (cif->abi)
     {
@@ -968,6 +969,10 @@
       FFI_ASSERT (0);
       break;
     }
+
+  /* Check for a bounce-buffered return value */
+  if (rvalue && ecif.rvalue == smst_buffer)
+    memcpy(rvalue, smst_buffer, rsize);
 }
 
 
diff -ruN libffi-3.0.10.orig/src/powerpc/sysv.S libffi-3.0.10/src/powerpc/sysv.S
--- libffi-3.0.10.orig/src/powerpc/sysv.S	2012-11-06 21:34:20.000000000 +0000
+++ libffi-3.0.10/src/powerpc/sysv.S	2012-11-06 21:35:33.000000000 +0000
@@ -142,19 +142,14 @@
 #endif
 
 L(small_struct_return_value):
-	extrwi	%r6,%r31,2,19         /* number of bytes padding = shift/8 */
-	mtcrf	0x02,%r31	      /* copy flags to cr[24:27] (cr6) */
-	extrwi	%r5,%r31,5,19         /* r5 <- number of bits of padding */
-	subfic  %r6,%r6,4             /* r6 <- number of useful bytes in r3 */
-	bf-	25,L(done_return_value) /* struct in r3 ? if not, done. */
-/* smst_one_register: */
-	slw	%r3,%r3,%r5           /* Left-justify value in r3 */
-	mtxer	%r6                   /* move byte count to XER ... */
-	stswx	%r3,0,%r30            /* ... and store that many bytes */
-	bf+	26,L(done_return_value)  /* struct in r3:r4 ? */
-	add	%r6,%r6,%r30          /* adjust pointer */
-	stswi	%r4,%r6,4             /* store last four bytes */
-	b	L(done_return_value)
+	/*
+	 * The C code always allocates a properly-aligned 8-byte bounce
+	 * buffer to make this assembly code very simple.  Just write out
+	 * r3 and r4 to the buffer to allow the C code to handle the rest.
+	 */
+	stw %r3, 0(%r30)
+	stw %r4, 4(%r30)
+	b L(done_return_value)
 
 .LFE1:
 END(ffi_call_SYSV)

Reply to: