From 4b316a1e8ba8bc6fd2c837906b84eead4162a14d Mon Sep 17 00:00:00 2001 From: Iain Sandoe Date: Tue, 27 Jul 2010 13:26:34 +0000 Subject: [PATCH] re PR target/29090 (gcc.dg-struct-layout-1 failures on Darwin PPC at -m64) PR target/29090 * config/rs6000/rs6000.c (rs6000_gimplify_va_arg): Special-case the Darwin64 ABI, for zero-sized objects. From-SVN: r162568 --- gcc/config/rs6000/rs6000.c | 44 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index e8fad12caad..d5ceb35dbbb 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -8995,6 +8995,50 @@ rs6000_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p, return build_va_arg_indirect_ref (t); } + /* We need to deal with the fact that the darwin ppc64 ABI is defined by an + earlier version of gcc, with the property that it always applied alignment + adjustments to the va-args (even for zero-sized types). The cheapest way + to deal with this is to replicate the effect of the part of + std_gimplify_va_arg_expr that carries out the align adjust, for the case + of relevance. + We don't need to check for pass-by-reference because of the test above. + We can return a simplifed answer, since we know there's no offset to add. */ + + if (TARGET_MACHO + && rs6000_darwin64_abi + && integer_zerop (TYPE_SIZE (type))) + { + unsigned HOST_WIDE_INT align, boundary; + tree valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL); + align = PARM_BOUNDARY / BITS_PER_UNIT; + boundary = FUNCTION_ARG_BOUNDARY (TYPE_MODE (type), type); + if (boundary > MAX_SUPPORTED_STACK_ALIGNMENT) + boundary = MAX_SUPPORTED_STACK_ALIGNMENT; + boundary /= BITS_PER_UNIT; + if (boundary > align) + { + tree t ; + /* This updates arg ptr by the amount that would be necessary + to align the zero-sized (but not zero-alignment) item. */ + t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp, + fold_build2 (POINTER_PLUS_EXPR, + TREE_TYPE (valist), + valist_tmp, size_int (boundary - 1))); + gimplify_and_add (t, pre_p); + + t = fold_convert (sizetype, valist_tmp); + t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp, + fold_convert (TREE_TYPE (valist), + fold_build2 (BIT_AND_EXPR, sizetype, t, + size_int (-boundary)))); + t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t); + gimplify_and_add (t, pre_p); + } + /* Since it is zero-sized there's no increment for the item itself. */ + valist_tmp = fold_convert (build_pointer_type (type), valist_tmp); + return build_va_arg_indirect_ref (valist_tmp); + } + if (DEFAULT_ABI != ABI_V4) { if (targetm.calls.split_complex_arg && TREE_CODE (type) == COMPLEX_TYPE) -- 2.30.2