From patchwork Sat Jul 24 08:36:14 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Iain Sandoe X-Patchwork-Id: 59852 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id 3B61FB6EFE for ; Sat, 24 Jul 2010 18:36:55 +1000 (EST) Received: (qmail 14609 invoked by alias); 24 Jul 2010 08:36:53 -0000 Received: (qmail 14597 invoked by uid 22791); 24 Jul 2010 08:36:52 -0000 X-SWARE-Spam-Status: No, hits=-2.1 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_NONE X-Spam-Check-By: sourceware.org Received: from c2bthomr10.btconnect.com (HELO c2bthomr10.btconnect.com) (213.123.20.128) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Sat, 24 Jul 2010 08:36:22 +0000 Received: from thor.office (host81-138-1-83.in-addr.btopenworld.com [81.138.1.83]) by c2bthomr10.btconnect.com with ESMTP id FVZ19103; Sat, 24 Jul 2010 09:36:15 +0100 (BST) X-Mirapoint-IP-Reputation: reputation=Fair-1, source=Queried, refid=0001.0A0B0301.4C4AA5FE.02E9, actions=tag Message-Id: <9C2B0543-065F-4BFB-B3E1-C2E138A54927@sandoe-acoustics.co.uk> From: IainS To: GCC Patches Mime-Version: 1.0 (Apple Message framework v936) Subject: [Patch Darwin 2/2] fix PPC64 ABI Date: Sat, 24 Jul 2010 09:36:14 +0100 Cc: mrs@gcc.gnu.org, David Edelsohn X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org 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. */