public inbox for libffi-discuss@sourceware.org
 help / color / mirror / Atom feed
From: Andreas Tobler <andreast-list@fgznet.ch>
To: libffi-discuss@sourceware.org, Anthony Green <green@redhat.com>
Subject: [patch] fix sysv ppc small struct ffi_call
Date: Thu, 07 Feb 2013 20:58:00 -0000	[thread overview]
Message-ID: <51141577.7070802@fgznet.ch> (raw)

[-- Attachment #1: Type: text/plain, Size: 590 bytes --]

Hi Anthony,

Unfortunately almost a year too late I noticed a severe breakage in the
area of small structs with the sysv ABI on powerpc. Not the gcc_sysv.
At the time when the soft float patch for ppc went in this breakage
happened.

This is the git commit:

https://github.com/atgreen/libffi/commit/52891f8a93f9b8de801cca4cf05639422dc9773e

Attached the patch which fixes that. I tested on ppc-unknown-freebsd and
ppc-unknown-linux, no regressions.

Would you mind applying this patch for the 3.0.12 spin?

And thank you for applying the first fix where LONGDOUBLE==DOUBLE.

TIA!

Andreas

[-- Attachment #2: libffi_sysv_ppc.diff --]
[-- Type: text/plain, Size: 3269 bytes --]

--- src/powerpc/ffi.c.orig	2013-02-07 19:51:28.000000000 +0100
+++ src/powerpc/ffi.c	2013-02-07 19:56:08.000000000 +0100
@@ -48,6 +48,11 @@
 
   FLAG_RETURNS_128BITS  = 1 << (31-27), /* cr6  */
 
+  FLAG_SYSV_SMST_R4     = 1 << (31-26), /* use r4 for FFI_SYSV 8 byte
+					   structs.  */
+  FLAG_SYSV_SMST_R3     = 1 << (31-25), /* use r3 for FFI_SYSV 4 byte
+					   structs.  */
+
   FLAG_ARG_NEEDS_COPY   = 1 << (31- 7),
 #ifndef __NO_FPRS__
   FLAG_FP_ARGUMENTS     = 1 << (31- 6), /* cr1.eq; specified by ABI */
@@ -686,18 +691,35 @@
       break;
 
     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
-       * in memory.
-       *
-       * NOTE: The assembly code can safely assume that it just needs to
-       *       store both r3 and r4 into a 8-byte word-aligned buffer, as
-       *       we allocate a temporary buffer in ffi_call() if this flag is
-       *       set.
-       */
-      if (cif->abi == FFI_SYSV && size <= 8)
-	flags |= FLAG_RETURNS_SMST;
+      if (cif->abi == FFI_SYSV)
+	{
+	  /* 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
+	     in memory.  */
+
+	  /* Treat structs with size <= 8 bytes.  */
+	  if (size <= 8)
+	    {
+	      flags |= FLAG_RETURNS_SMST;
+	      /* These structs are returned in r3. We pack the type and the
+		 precalculated shift value (needed in the sysv.S) into flags.
+		 The same applies for the structs returned in r3/r4.  */
+	      if (size <= 4)
+		{
+		  flags |= FLAG_SYSV_SMST_R3;
+		  flags |= 8 * (4 - size) << 8;
+		  break;
+		}
+	      /* These structs are returned in r3 and r4. See above.   */
+	      if  (size <= 8)
+		{
+		  flags |= FLAG_SYSV_SMST_R3 | FLAG_SYSV_SMST_R4;
+		  flags |= 8 * (8 - size) << 8;
+		  break;
+		}
+	    }
+	}
+
       intarg_count++;
       flags |= FLAG_RETVAL_REFERENCE;
       /* Fall through.  */
--- src/powerpc/sysv.S.orig	2013-02-07 19:50:25.000000000 +0100
+++ src/powerpc/sysv.S	2013-02-07 19:51:06.000000000 +0100
@@ -142,14 +142,19 @@
 #endif
 
 L(small_struct_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)
+	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)
 
 .LFE1:
 END(ffi_call_SYSV)

             reply	other threads:[~2013-02-07 20:58 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-02-07 20:58 Andreas Tobler [this message]
2013-02-08 20:33 ` Anthony Green

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=51141577.7070802@fgznet.ch \
    --to=andreast-list@fgznet.ch \
    --cc=green@redhat.com \
    --cc=libffi-discuss@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).