From patchwork Sat Jul 24 08:36:14 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [Darwin,2/2] fix PPC64 ABI Date: Fri, 23 Jul 2010 22:36:14 -0000 From: IainS X-Patchwork-Id: 59852 Message-Id: <9C2B0543-065F-4BFB-B3E1-C2E138A54927@sandoe-acoustics.co.uk> To: GCC Patches Cc: mrs@gcc.gnu.org, David Edelsohn Hi, 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. I've made it such that there is no impact at all for non-darwin. The impact for darwin is restricted to the single m64 ABI case. OK for trunk and 4.5 when it re-opens? Iain gcc/ PR target/29090 * config/rs6000/rs6000.c (rs6000_gimplify_va_arg): Special-case the Darwin64 ABI, for zero-sized objects. + valist_tmp = fold_convert (build_pointer_type (type), valist_tmp); + return build_va_arg_indirect_ref (valist_tmp); + } +#endif + if (DEFAULT_ABI != ABI_V4) { if (targetm.calls.split_complex_arg && TREE_CODE (type) == COMPLEX_TYPE) Index: gcc/config/rs6000/rs6000.c =================================================================== --- gcc/config/rs6000/rs6000.c (revision 162457) +++ gcc/config/rs6000/rs6000.c (working copy) @@ -8931,6 +8995,51 @@ rs6000_gimplify_va_arg (tree valist, tree type, gi return build_va_arg_indirect_ref (t); } +#if TARGET_MACHO + /* 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 (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. */