diff options
author | Jan Hubicka <jh@suse.cz> | 2004-01-15 00:07:04 +0100 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2004-01-14 23:07:04 +0000 |
commit | e1be55d0cb3495f770f7dff63b6863ec55855b17 (patch) | |
tree | abaeb984e878c9db1857505cdb481fa65f664f9a | |
parent | f560bf91ae0ba419d7445eb19c09a4d1ad341e75 (diff) | |
download | gcc-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
-rw-r--r-- | gcc/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/builtins.c | 22 | ||||
-rw-r--r-- | gcc/config/i386/i386.c | 12 | ||||
-rw-r--r-- | gcc/config/i386/i386.h | 2 |
4 files changed, 41 insertions, 3 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e5d5396..bd78cf1 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2004-01-15 Jan Hubicka <jh@suse.cz> + + * 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. + 2004-01-14 Joseph S. Myers <jsm@polyomino.org.uk> * c-parse.in (stmts_and_decls): Make label at end of compound 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)) diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 709e6c2..42dfca0 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -1839,6 +1839,8 @@ init_cumulative_args (CUMULATIVE_ARGS *cum, /* Argument info to initialize */ cum->nregs = ix86_regparm; cum->sse_nregs = SSE_REGPARM_MAX; cum->mmx_nregs = MMX_REGPARM_MAX; + cum->warn_sse = true; + cum->warn_mmx = true; cum->maybe_vaarg = false; /* Use ecx and edx registers if function has fastcall attribute */ @@ -1857,7 +1859,7 @@ init_cumulative_args (CUMULATIVE_ARGS *cum, /* Argument info to initialize */ are no variable arguments. If there are variable arguments, then we won't pass anything in registers */ - if (cum->nregs) + if (cum->nregs || !TARGET_MMX || !TARGET_SSE) { for (param = (fntype) ? TYPE_ARG_TYPES (fntype) : 0; param != 0; param = next_param) @@ -1868,6 +1870,10 @@ init_cumulative_args (CUMULATIVE_ARGS *cum, /* Argument info to initialize */ if (!TARGET_64BIT) { cum->nregs = 0; + cum->sse_nregs = 0; + cum->mmx_nregs = 0; + cum->warn_sse = 0; + cum->warn_mmx = 0; cum->fastcall = 0; } cum->maybe_vaarg = true; @@ -2581,7 +2587,7 @@ function_arg (CUMULATIVE_ARGS *cum, /* current arg information */ case V2DFmode: if (!type || !AGGREGATE_TYPE_P (type)) { - if (!TARGET_SSE && !warnedmmx) + if (!TARGET_SSE && !warnedmmx && cum->warn_sse) { warnedsse = true; warning ("SSE vector argument without SSE enabled " @@ -2597,7 +2603,7 @@ function_arg (CUMULATIVE_ARGS *cum, /* current arg information */ case V2SFmode: if (!type || !AGGREGATE_TYPE_P (type)) { - if (!TARGET_MMX && !warnedmmx) + if (!TARGET_MMX && !warnedmmx && cum->warn_mmx) { warnedmmx = true; warning ("MMX vector argument without MMX enabled " diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h index 791c5ce..52b193b 100644 --- a/gcc/config/i386/i386.h +++ b/gcc/config/i386/i386.h @@ -1743,6 +1743,8 @@ typedef struct ix86_args { int fastcall; /* fastcall calling convention is used */ int sse_words; /* # sse words passed so far */ int sse_nregs; /* # sse registers available for passing */ + int warn_sse; /* True when we want to warn about SSE ABI. */ + int warn_mmx; /* True when we want to warn about MMX ABI. */ int sse_regno; /* next available sse register number */ int mmx_words; /* # mmx words passed so far */ int mmx_nregs; /* # mmx registers available for passing */ |