diff options
author | (no author) <(no author)@138bc75d-0d04-0410-961f-82ee72b054a4> | 2002-03-18 08:16:39 +0000 |
---|---|---|
committer | (no author) <(no author)@138bc75d-0d04-0410-961f-82ee72b054a4> | 2002-03-18 08:16:39 +0000 |
commit | 42d5e2f4650e254ffca7432968615fbd3e3e00c7 (patch) | |
tree | 7742bcd12a61d5c784fe2ceae05f31dd5e62c21c /gcc/builtins.c | |
parent | 1373952868cb7ac8a23bc9f8f292cb61ef65c652 (diff) |
This commit was manufactured by cvs2svn to create tagx86-64-merge-2002-03-18
'x86-64-merge-2002-03-18'.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/tags/x86-64-merge-2002-03-18@50948 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/builtins.c')
-rw-r--r-- | gcc/builtins.c | 51 |
1 files changed, 34 insertions, 17 deletions
diff --git a/gcc/builtins.c b/gcc/builtins.c index e3adb05feeb..442abfd779d 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -2991,37 +2991,54 @@ rtx std_expand_builtin_va_arg (valist, type) tree valist, type; { - tree addr_tree, t; - HOST_WIDE_INT align; - HOST_WIDE_INT rounded_size; + tree addr_tree, t, type_size = NULL; + tree align, alignm1; + tree rounded_size; rtx addr; /* Compute the rounded size of the type. */ - align = PARM_BOUNDARY / BITS_PER_UNIT; - rounded_size = (((int_size_in_bytes (type) + align - 1) / align) * align); + align = size_int (PARM_BOUNDARY / BITS_PER_UNIT); + alignm1 = size_int (PARM_BOUNDARY / BITS_PER_UNIT - 1); + 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 (build (MULT_EXPR, sizetype, + fold (build (TRUNC_DIV_EXPR, sizetype, + fold (build (PLUS_EXPR, sizetype, + type_size, alignm1)), + align)), + align)); /* Get AP. */ addr_tree = valist; - if (PAD_VARARGS_DOWN) + if (PAD_VARARGS_DOWN && ! integer_zerop (rounded_size)) { /* Small args are padded downward. */ - - HOST_WIDE_INT adj - = rounded_size > align ? rounded_size : int_size_in_bytes (type); - - addr_tree = build (PLUS_EXPR, TREE_TYPE (addr_tree), addr_tree, - build_int_2 (rounded_size - adj, 0)); + addr_tree = fold (build (PLUS_EXPR, TREE_TYPE (addr_tree), addr_tree, + fold (build (COND_EXPR, sizetype, + fold (build (GT_EXPR, sizetype, + rounded_size, + align)), + size_zero_node, + fold (build (MINUS_EXPR, sizetype, + rounded_size, + type_size)))))); } addr = expand_expr (addr_tree, NULL_RTX, Pmode, EXPAND_NORMAL); addr = copy_to_reg (addr); /* Compute new value for AP. */ - t = build (MODIFY_EXPR, TREE_TYPE (valist), valist, - build (PLUS_EXPR, TREE_TYPE (valist), valist, - build_int_2 (rounded_size, 0))); - TREE_SIDE_EFFECTS (t) = 1; - expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL); + if (! integer_zerop (rounded_size)) + { + t = build (MODIFY_EXPR, TREE_TYPE (valist), valist, + build (PLUS_EXPR, TREE_TYPE (valist), valist, + rounded_size)); + TREE_SIDE_EFFECTS (t) = 1; + expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL); + } return addr; } |