aboutsummaryrefslogtreecommitdiff
path: root/gcc/builtins.c
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2004-01-15 00:07:04 +0100
committerJan Hubicka <hubicka@gcc.gnu.org>2004-01-14 23:07:04 +0000
commite1be55d0cb3495f770f7dff63b6863ec55855b17 (patch)
treeabaeb984e878c9db1857505cdb481fa65f664f9a /gcc/builtins.c
parentf560bf91ae0ba419d7445eb19c09a4d1ad341e75 (diff)
downloadgcc-e1be55d0cb3495f770f7dff63b6863ec55855b17.zip
gcc-e1be55d0cb3495f770f7dff63b6863ec55855b17.tar.gz
gcc-e1be55d0cb3495f770f7dff63b6863ec55855b17.tar.bz2
builtins.c (std_expand_builtin_va_arg): Align operand when needed.
* builtins.c (std_expand_builtin_va_arg): Align operand when needed. * i386.c (init_cumulative_args): Set warn_sse; fix handling of variadic functions accepting SSE arguments (function_arg): Warn only when asked to warn. * i386.h (ix86_args): Add warn_sse/warn_mmx fiels. From-SVN: r75892
Diffstat (limited to 'gcc/builtins.c')
-rw-r--r--gcc/builtins.c22
1 files changed, 22 insertions, 0 deletions
diff --git a/gcc/builtins.c b/gcc/builtins.c
index 5b49b08..c940899 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -3990,10 +3990,32 @@ std_expand_builtin_va_arg (tree valist, tree type)
tree align, alignm1;
tree rounded_size;
rtx addr;
+ 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);
+ boundary = FUNCTION_ARG_BOUNDARY (TYPE_MODE (type), type);
+
+ /* 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 = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
+ build (PLUS_EXPR, TREE_TYPE (valist), valist,
+ build_int_2 (boundary / BITS_PER_UNIT - 1, 0)));
+ TREE_SIDE_EFFECTS (t) = 1;
+ expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
+ }
+ t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
+ build (BIT_AND_EXPR, TREE_TYPE (valist), valist,
+ build_int_2 (~(boundary / BITS_PER_UNIT - 1), -1)));
+ TREE_SIDE_EFFECTS (t) = 1;
+ expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
+ }
if (type == error_mark_node
|| (type_size = TYPE_SIZE_UNIT (TYPE_MAIN_VARIANT (type))) == NULL
|| TREE_OVERFLOW (type_size))