From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 31951 invoked by alias); 13 Nov 2013 15:20:44 -0000 Mailing-List: contact libffi-discuss-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libffi-discuss-owner@sourceware.org Received: (qmail 31939 invoked by uid 89); 13 Nov 2013 15:20:44 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-0.2 required=5.0 tests=AWL,BAYES_50,FREEMAIL_FROM,RCVD_IN_DNSWL_NONE,RDNS_NONE,SPF_PASS,URIBL_BLOCKED autolearn=no version=3.3.2 X-HELO: mail-pd0-f176.google.com Received: from Unknown (HELO mail-pd0-f176.google.com) (209.85.192.176) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-SHA encrypted) ESMTPS; Wed, 13 Nov 2013 15:20:43 +0000 Received: by mail-pd0-f176.google.com with SMTP id r10so529635pdi.7 for ; Wed, 13 Nov 2013 07:20:35 -0800 (PST) X-Received: by 10.68.166.67 with SMTP id ze3mr9463305pbb.173.1384356035310; Wed, 13 Nov 2013 07:20:35 -0800 (PST) Received: from bubble.grove.modra.org ([101.166.26.37]) by mx.google.com with ESMTPSA id py4sm45096637pbb.33.2013.11.13.07.20.33 for (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Wed, 13 Nov 2013 07:20:34 -0800 (PST) Received: by bubble.grove.modra.org (Postfix, from userid 1000) id 0175AEA006D; Thu, 14 Nov 2013 01:50:30 +1030 (CST) Date: Wed, 13 Nov 2013 15:20:00 -0000 From: Alan Modra To: libffi-discuss@sourceware.org Subject: Align powerpc64 structs passed by value as per ABI Message-ID: <20131113152030.GE20756@bubble.grove.modra.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.5.21 (2010-09-15) X-SW-Source: 2013/txt/msg00203.txt.bz2 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