aboutsummaryrefslogtreecommitdiff
path: root/gcc/builtins.c
diff options
context:
space:
mode:
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
commit42d5e2f4650e254ffca7432968615fbd3e3e00c7 (patch)
tree7742bcd12a61d5c784fe2ceae05f31dd5e62c21c /gcc/builtins.c
parent1373952868cb7ac8a23bc9f8f292cb61ef65c652 (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.c51
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;
}