From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 10375 invoked by alias); 10 Jul 2004 01:55:49 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 10363 invoked from network); 10 Jul 2004 01:55:47 -0000 Received: from unknown (HELO mx2.redhat.com) (66.187.237.31) by sourceware.org with SMTP; 10 Jul 2004 01:55:47 -0000 Received: from int-mx2.corp.redhat.com (int-mx2.corp.redhat.com [172.16.27.26]) by mx2.redhat.com (8.12.10/8.12.10) with ESMTP id i6A1q7St021901 for ; Fri, 9 Jul 2004 21:52:08 -0400 Received: from potter.sfbay.redhat.com (potter.sfbay.redhat.com [172.16.27.15]) by int-mx2.corp.redhat.com (8.11.6/8.11.6) with ESMTP id i6A1tkw23403; Fri, 9 Jul 2004 21:55:46 -0400 Received: from frothingslosh.sfbay.redhat.com (frothingslosh.sfbay.redhat.com [172.16.24.27]) by potter.sfbay.redhat.com (8.11.6/8.11.6) with ESMTP id i6A1tjP07840; Fri, 9 Jul 2004 18:55:45 -0700 Received: from frothingslosh.sfbay.redhat.com (localhost.localdomain [127.0.0.1]) by frothingslosh.sfbay.redhat.com (8.12.10/8.12.10) with ESMTP id i6A1tjQw013192; Fri, 9 Jul 2004 18:55:45 -0700 Received: (from rth@localhost) by frothingslosh.sfbay.redhat.com (8.12.10/8.12.10/Submit) id i6A1tjZ2013190; Fri, 9 Jul 2004 18:55:45 -0700 X-Authentication-Warning: frothingslosh.sfbay.redhat.com: rth set sender to rth@redhat.com using -f Date: Sat, 10 Jul 2004 03:55:00 -0000 From: Richard Henderson To: Richard Sandiford , gcc-patches@gcc.gnu.org, Eric Christopher Subject: Re: gimple va_arg for mips Message-ID: <20040710015545.GA13182@redhat.com> Mail-Followup-To: Richard Henderson , Richard Sandiford , gcc-patches@gcc.gnu.org, Eric Christopher References: <20040709025645.GF14883@redhat.com> <87zn69wtkd.fsf@redhat.com> <20040709093834.GA7754@redhat.com> <87oempwke9.fsf@redhat.com> <20040709105543.GA8189@redhat.com> <87658xvzpn.fsf@redhat.com> <20040709191217.GD10458@redhat.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20040709191217.GD10458@redhat.com> User-Agent: Mutt/1.4.1i X-SW-Source: 2004-07/txt/msg01047.txt.bz2 On Fri, Jul 09, 2004 at 12:12:17PM -0700, Richard Henderson wrote: > You're right. I think this check was supposed to be for ARGS_GROW_DOWNWARD. > I wonder how this has gone unnoticed so long... I'll fix it. Like so. Fully tested on i686; I'll build a mips-sim sometime this weekend, but feel free to beat me to it. r~ * builtins.c (std_gimplify_va_arg_expr): Deny ARGS_GROW_DOWNWARD. Always align upward to arg boundary. Use size_in_bytes/round_up. Maintain type-correctness of constants. * stor-layout.c (round_up, round_down): Special-case powers of 2. Index: builtins.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/builtins.c,v retrieving revision 1.355 diff -c -p -d -r1.355 builtins.c *** builtins.c 9 Jul 2004 23:04:32 -0000 1.355 --- builtins.c 10 Jul 2004 01:49:24 -0000 *************** expand_builtin_va_arg (tree valist, tree *** 4473,4544 **** tree std_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p, tree *post_p) { ! tree addr, t, type_size = NULL; ! tree align, alignm1, malign; ! tree rounded_size; ! tree valist_tmp; ! HOST_WIDE_INT boundary; /* Compute the rounded size of the type. */ ! align = size_int (PARM_BOUNDARY / BITS_PER_UNIT); ! alignm1 = size_int (PARM_BOUNDARY / BITS_PER_UNIT - 1); ! malign = size_int (-(PARM_BOUNDARY / BITS_PER_UNIT)); boundary = FUNCTION_ARG_BOUNDARY (TYPE_MODE (type), type); valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL); /* va_list pointer is aligned to PARM_BOUNDARY. If argument actually requires greater alignment, we must perform dynamic alignment. */ - if (boundary > PARM_BOUNDARY) { ! if (!PAD_VARARGS_DOWN) ! { ! t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp, ! build2 (PLUS_EXPR, TREE_TYPE (valist), valist_tmp, ! build_int_2 (boundary / BITS_PER_UNIT - 1, 0))); ! gimplify_and_add (t, pre_p); ! } t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp, ! build2 (BIT_AND_EXPR, TREE_TYPE (valist), valist_tmp, ! build_int_2 (~(boundary / BITS_PER_UNIT - 1), -1))); gimplify_and_add (t, pre_p); - } - if (type == error_mark_node - || (type_size = TYPE_SIZE_UNIT (TYPE_MAIN_VARIANT (type))) == NULL - || TREE_OVERFLOW (type_size)) - rounded_size = size_zero_node; - else - { - rounded_size = fold (build2 (PLUS_EXPR, sizetype, type_size, alignm1)); - rounded_size = fold (build2 (BIT_AND_EXPR, sizetype, - rounded_size, malign)); } /* Reduce rounded_size so it's sharable with the postqueue. */ gimplify_expr (&rounded_size, pre_p, post_p, is_gimple_val, fb_rvalue); /* Get AP. */ addr = valist_tmp; ! if (PAD_VARARGS_DOWN && ! integer_zerop (rounded_size)) { /* Small args are padded downward. */ ! addr = fold (build2 (PLUS_EXPR, TREE_TYPE (addr), addr, ! fold (build3 (COND_EXPR, sizetype, ! fold (build2 (GT_EXPR, sizetype, ! rounded_size, ! align)), ! size_zero_node, ! fold (build2 (MINUS_EXPR, ! sizetype, ! rounded_size, ! type_size)))))); } /* Compute new value for AP. */ ! t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, ! fold (build2 (PLUS_EXPR, TREE_TYPE (valist), ! valist_tmp, rounded_size))); gimplify_and_add (t, pre_p); addr = fold_convert (build_pointer_type (type), addr); --- 4473,4533 ---- tree std_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p, tree *post_p) { ! tree addr, t, type_size, rounded_size, valist_tmp; ! unsigned int align, boundary; ! ! #ifdef ARGS_GROW_DOWNWARD ! /* All of the alignment and movement below is for args-grow-up machines. ! As of 2004, there are only 3 ARGS_GROW_DOWNWARD targets, and they all ! implement their own specialized gimplify_va_arg_expr routines. */ ! abort (); ! #endif /* Compute the rounded size of the type. */ ! align = PARM_BOUNDARY / BITS_PER_UNIT; boundary = FUNCTION_ARG_BOUNDARY (TYPE_MODE (type), type); + /* Hoist the valist value into a temporary for the moment. */ valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL); /* va_list pointer is aligned to PARM_BOUNDARY. If argument actually requires greater alignment, we must perform dynamic alignment. */ if (boundary > PARM_BOUNDARY) { ! unsigned byte_bound = boundary / BITS_PER_UNIT; ! ! t = fold_convert (TREE_TYPE (valist), size_int (byte_bound - 1)); t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp, ! build2 (PLUS_EXPR, TREE_TYPE (valist), valist_tmp, t)); ! gimplify_and_add (t, pre_p); ! ! t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp, ! build2 (BIT_AND_EXPR, TREE_TYPE (valist), valist_tmp, t)); gimplify_and_add (t, pre_p); } + type_size = size_in_bytes (type); + rounded_size = round_up (type_size, align); + /* Reduce rounded_size so it's sharable with the postqueue. */ gimplify_expr (&rounded_size, pre_p, post_p, is_gimple_val, fb_rvalue); /* Get AP. */ addr = valist_tmp; ! if (PAD_VARARGS_DOWN && !integer_zerop (rounded_size)) { /* Small args are padded downward. */ ! t = fold (build2 (GT_EXPR, sizetype, rounded_size, size_int (align))); ! t = fold (build3 (COND_EXPR, sizetype, t, size_zero_node, ! size_binop (MINUS_EXPR, rounded_size, type_size))); ! t = fold_convert (TREE_TYPE (addr), t); ! addr = build2 (PLUS_EXPR, TREE_TYPE (addr), addr, t); } /* Compute new value for AP. */ ! t = fold_convert (TREE_TYPE (valist), rounded_size); ! t = build2 (PLUS_EXPR, TREE_TYPE (valist), valist_tmp, t); ! t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t); gimplify_and_add (t, pre_p); addr = fold_convert (build_pointer_type (type), addr); Index: stor-layout.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/stor-layout.c,v retrieving revision 1.194 diff -c -p -d -r1.194 stor-layout.c *** stor-layout.c 3 Jul 2004 00:15:43 -0000 1.194 --- stor-layout.c 10 Jul 2004 01:49:24 -0000 *************** get_mode_alignment (enum machine_mode mo *** 274,282 **** tree round_up (tree value, int divisor) { ! tree arg = size_int_type (divisor, TREE_TYPE (value)); ! return size_binop (MULT_EXPR, size_binop (CEIL_DIV_EXPR, value, arg), arg); } /* Likewise, but round down. */ --- 274,297 ---- tree round_up (tree value, int divisor) { ! tree t; ! /* If divisor is a power of two, simplify this to bit manipulation. */ ! if (divisor == (divisor & -divisor)) ! { ! t = size_int_type (divisor - 1, TREE_TYPE (value)); ! value = size_binop (PLUS_EXPR, value, t); ! t = size_int_type (-divisor, TREE_TYPE (value)); ! value = size_binop (BIT_AND_EXPR, value, t); ! } ! else ! { ! t = size_int_type (divisor, TREE_TYPE (value)); ! value = size_binop (CEIL_DIV_EXPR, value, t); ! value = size_binop (MULT_EXPR, value, t); ! } ! ! return value; } /* Likewise, but round down. */ *************** round_up (tree value, int divisor) *** 284,292 **** tree round_down (tree value, int divisor) { ! tree arg = size_int_type (divisor, TREE_TYPE (value)); ! return size_binop (MULT_EXPR, size_binop (FLOOR_DIV_EXPR, value, arg), arg); } /* Subroutine of layout_decl: Force alignment required for the data type. --- 299,320 ---- tree round_down (tree value, int divisor) { ! tree t; ! /* If divisor is a power of two, simplify this to bit manipulation. */ ! if (divisor == (divisor & -divisor)) ! { ! t = size_int_type (-divisor, TREE_TYPE (value)); ! value = size_binop (BIT_AND_EXPR, value, t); ! } ! else ! { ! t = size_int_type (divisor, TREE_TYPE (value)); ! value = size_binop (FLOOR_DIV_EXPR, value, t); ! value = size_binop (MULT_EXPR, value, t); ! } ! ! return value; } /* Subroutine of layout_decl: Force alignment required for the data type.