===================================================================
@@ -473,6 +473,12 @@ rs6000_cpu_cpp_builtins (cpp_reader *pfile)
if (TARGET_SOFT_FLOAT || !TARGET_FPRS)
builtin_define ("__NO_FPRS__");
+ /* Whether aggregates passed by value are aligned to a 16 byte boundary
+ if their alignment is 16 bytes or larger. */
+ if ((TARGET_MACHO && rs6000_darwin64_abi)
+ || (DEFAULT_ABI == ABI_AIX && !rs6000_compat_align_parm))
+ builtin_define ("__STRUCT_PARM_ALIGN__=16");
+
/* Generate defines for Xilinx FPU. */
if (rs6000_xilinx_fpu)
{
===================================================================
@@ -462,6 +462,9 @@ ffi_prep_args64 (extended_cif *ecif, unsigned long
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;
@@ -532,6 +535,12 @@ ffi_prep_args64 (extended_cif *ecif, unsigned long
#endif
case FFI_TYPE_STRUCT:
+#ifdef __STRUCT_PARM_ALIGN__
+ align = (*ptr)->alignment;
+ if (align > __STRUCT_PARM_ALIGN__)
+ align = __STRUCT_PARM_ALIGN__;
+ next_arg.ul = ALIGN (next_arg.ul, align);
+#endif
words = ((*ptr)->size + 7) / 8;
if (next_arg.ul >= gpr_base.ul && next_arg.ul + words > gpr_end.ul)
{
@@ -1349,6 +1358,9 @@ ffi_closure_helper_LINUX64 (ffi_closure *closure,
long i, avn;
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 *));
@@ -1399,6 +1411,12 @@ ffi_closure_helper_LINUX64 (ffi_closure *closure,
break;
case FFI_TYPE_STRUCT:
+#ifdef __STRUCT_PARM_ALIGN__
+ align = arg_types[i]->alignment;
+ if (align > __STRUCT_PARM_ALIGN__)
+ align = __STRUCT_PARM_ALIGN__;
+ pst = ALIGN (pst, align);
+#endif
#ifndef __LITTLE_ENDIAN__
/* Structures with size less than eight bytes are passed
left-padded. */