public inbox for libffi-discuss@sourceware.org
 help / color / mirror / Atom feed
* Align powerpc64 structs passed by value as per ABI
@ 2013-11-13 15:20 Alan Modra
  0 siblings, 0 replies; only message in thread
From: Alan Modra @ 2013-11-13 15:20 UTC (permalink / raw)
  To: libffi-discuss

The powerpc64 ABIs align structs passed by value, a fact ignored by
gcc for quite some time.  Since gcc now does the correct alignment,
libffi needs to follow suit.  This ought to be made selectable via
a new abi value, and the #ifdefs removed from ffi.c along with many
other #ifdefs present there and in assembly.  I'll do that with a
followup patch sometime.

This is a revised version of
https://sourceware.org/ml/libffi-discuss/2013/msg00162.html

	* src/powerpc/ffi.c (ffi_prep_args64): Align struct parameters
	according to __STRUCT_PARM_ALIGN__.
	(ffi_prep_cif_machdep_core): Likewise.
	(ffi_closure_helper_LINUX64): Likewise.

diff --git a/src/powerpc/ffi.c b/src/powerpc/ffi.c
index 094ee9c..cd63e26 100644
--- a/src/powerpc/ffi.c
+++ b/src/powerpc/ffi.c
@@ -434,6 +434,7 @@ ffi_prep_args64 (extended_cif *ecif, unsigned long *const stack)
     unsigned long *ul;
     float *f;
     double *d;
+    size_t p;
   } valp;
 
   /* 'stacktop' points at the previous backchain pointer.  */
@@ -468,6 +469,9 @@ ffi_prep_args64 (extended_cif *ecif, unsigned long *const stack)
     double **d;
   } p_argv;
   unsigned long gprvalue;
+#ifdef __STRUCT_PARM_ALIGN__
+  unsigned long align;
+#endif
 
   stacktop.c = (char *) stack + bytes;
   gpr_base.ul = stacktop.ul - ASM_NEEDS_REGISTERS64 - NUM_GPR_ARG_REGISTERS64;
@@ -544,6 +548,13 @@ ffi_prep_args64 (extended_cif *ecif, unsigned long *const stack)
 #endif
 
 	case FFI_TYPE_STRUCT:
+#ifdef __STRUCT_PARM_ALIGN__
+	  align = (*ptr)->alignment;
+	  if (align > __STRUCT_PARM_ALIGN__)
+	    align = __STRUCT_PARM_ALIGN__;
+	  if (align > 1)
+	    next_arg.p = ALIGN (next_arg.p, align);
+#endif
 	  words = ((*ptr)->size + 7) / 8;
 	  if (next_arg.ul >= gpr_base.ul && next_arg.ul + words > gpr_end.ul)
 	    {
@@ -834,6 +845,10 @@ ffi_prep_cif_machdep_core (ffi_cif *cif)
   else
     for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
       {
+#ifdef __STRUCT_PARM_ALIGN__
+	unsigned int align;
+#endif
+
 	switch ((*ptr)->type)
 	  {
 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
@@ -849,6 +864,14 @@ ffi_prep_cif_machdep_core (ffi_cif *cif)
 	    break;
 
 	  case FFI_TYPE_STRUCT:
+#ifdef __STRUCT_PARM_ALIGN__
+	    align = (*ptr)->alignment;
+	    if (align > __STRUCT_PARM_ALIGN__)
+	      align = __STRUCT_PARM_ALIGN__;
+	    align = align / 8;
+	    if (align > 1)
+	      intarg_count = ALIGN (intarg_count, align);
+#endif
 	    intarg_count += ((*ptr)->size + 7) / 8;
 	    break;
 
@@ -1389,6 +1412,9 @@ ffi_closure_helper_LINUX64 (ffi_closure *closure, void *rvalue,
   unsigned long i, avn, nfixedargs;
   ffi_cif *cif;
   ffi_dblfl *end_pfr = pfr + NUM_FPR_ARG_REGISTERS64;
+#ifdef __STRUCT_PARM_ALIGN__
+  unsigned long align;
+#endif
 
   cif = closure->cif;
   avalue = alloca (cif->nargs * sizeof (void *));
@@ -1443,6 +1469,13 @@ ffi_closure_helper_LINUX64 (ffi_closure *closure, void *rvalue,
 	  break;
 
 	case FFI_TYPE_STRUCT:
+#ifdef __STRUCT_PARM_ALIGN__
+	  align = arg_types[i]->alignment;
+	  if (align > __STRUCT_PARM_ALIGN__)
+	    align = __STRUCT_PARM_ALIGN__;
+	  if (align > 1)
+	    pst = (unsigned long *) ALIGN ((size_t) pst, align);
+#endif
 #ifndef __LITTLE_ENDIAN__
 	  /* Structures with size less than eight bytes are passed
 	     left-padded.  */

-- 
Alan Modra
Australia Development Lab, IBM

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2013-11-13 15:20 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-11-13 15:20 Align powerpc64 structs passed by value as per ABI Alan Modra

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).