builtins.c (stabilize_va_list): Stabilize array type va_list to a pointer type, not the base record type.

* builtins.c (stabilize_va_list): Stabilize array type va_list
        to a pointer type, not the base record type.
        (expand_builtin_va_copy): Dereference the pointers explicitly;
        use the correct size for the copy.

        * rs6000.c (rs6000_va_start): Dereference valist to get to the record.
        (rs6000_va_arg): Likewise.

From-SVN: r29690
This commit is contained in:
Richard Henderson 1999-09-28 01:15:38 -07:00 committed by Richard Henderson
parent 5e49cb95ea
commit 8ebecc3b1c
3 changed files with 72 additions and 24 deletions

View File

@ -1,3 +1,13 @@
Tue Sep 28 01:11:05 1999 Richard Henderson <rth@cygnus.com>
* builtins.c (stabilize_va_list): Stabilize array type va_list
to a pointer type, not the base record type.
(expand_builtin_va_copy): Dereference the pointers explicitly;
use the correct size for the copy.
* rs6000.c (rs6000_va_start): Dereference valist to get to the record.
(rs6000_va_arg): Likewise.
Mon Sep 27 23:27:21 1999 Richard Henderson <rth@cygnus.com>
* rtl.h (struct rtx_def): Move gc_mark to align mode field.

View File

@ -1826,40 +1826,64 @@ stabilize_va_list (valist, was_ptr)
tree valist;
int was_ptr;
{
int is_array = TREE_CODE (va_list_type_node) == ARRAY_TYPE;
if (was_ptr)
if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
{
/* If stdarg.h took the address of an array-type valist that was passed
as a parameter, we'll have taken the address of the parameter itself
rather than the array as we'd intended. Undo this mistake. */
if (is_array
&& TREE_CODE (valist) == ADDR_EXPR
&& TREE_CODE (TREE_TYPE (TREE_OPERAND (valist, 0))) == POINTER_TYPE)
if (was_ptr)
{
STRIP_NOPS (valist);
/* Two cases: either &array, which decomposed to
<ptr <array <record> valist>>
or &ptr, which turned into
<ptr <ptr <record>>>
In the first case we'll need to put the ADDR_EXPR back
after frobbing the types as if &array[0]. */
if (TREE_CODE (valist) != ADDR_EXPR)
abort ();
valist = TREE_OPERAND (valist, 0);
if (TREE_SIDE_EFFECTS (valist))
valist = save_expr (valist);
}
if (TYPE_MAIN_VARIANT (TREE_TYPE (valist))
== TYPE_MAIN_VARIANT (va_list_type_node))
{
tree pt = build_pointer_type (TREE_TYPE (va_list_type_node));
valist = build1 (ADDR_EXPR, pt, valist);
TREE_SIDE_EFFECTS (valist)
= TREE_SIDE_EFFECTS (TREE_OPERAND (valist, 0));
}
else
{
if (TREE_SIDE_EFFECTS (valist))
valist = save_expr (valist);
valist = fold (build1 (INDIRECT_REF, va_list_type_node, valist));
if (! POINTER_TYPE_P (TREE_TYPE (valist))
|| (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (valist)))
!= TYPE_MAIN_VARIANT (TREE_TYPE (va_list_type_node))))
abort ();
}
}
else if (TREE_SIDE_EFFECTS (valist))
{
if (is_array)
if (TREE_SIDE_EFFECTS (valist))
valist = save_expr (valist);
else
}
else
{
if (! was_ptr)
{
valist = build1 (ADDR_EXPR, build_pointer_type (va_list_type_node),
valist);
tree pt;
if (! TREE_SIDE_EFFECTS (valist))
return valist;
pt = build_pointer_type (va_list_type_node);
valist = fold (build1 (ADDR_EXPR, pt, valist));
TREE_SIDE_EFFECTS (valist) = 1;
valist = save_expr (valist);
valist = fold (build1 (INDIRECT_REF, va_list_type_node, valist));
}
if (TREE_SIDE_EFFECTS (valist))
valist = save_expr (valist);
valist = fold (build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)),
valist));
}
return valist;
@ -2095,10 +2119,22 @@ expand_builtin_va_copy (arglist)
}
else
{
emit_block_move (expand_expr (dst, NULL_RTX, Pmode, EXPAND_NORMAL),
expand_expr (src, NULL_RTX, Pmode, EXPAND_NORMAL),
expand_expr (TYPE_SIZE (va_list_type_node), NULL_RTX,
VOIDmode, EXPAND_NORMAL),
rtx dstb, srcb, size;
/* Evaluate to pointers. */
dstb = expand_expr (dst, NULL_RTX, Pmode, EXPAND_NORMAL);
srcb = expand_expr (src, NULL_RTX, Pmode, EXPAND_NORMAL);
size = expand_expr (TYPE_SIZE_UNIT (va_list_type_node), NULL_RTX,
VOIDmode, EXPAND_NORMAL);
/* "Dereference" to BLKmode memories. */
dstb = gen_rtx_MEM (BLKmode, dstb);
MEM_ALIAS_SET (dstb) = get_alias_set (TREE_TYPE (TREE_TYPE (dst)));
srcb = gen_rtx_MEM (BLKmode, srcb);
MEM_ALIAS_SET (srcb) = get_alias_set (TREE_TYPE (TREE_TYPE (src)));
/* Copy. */
emit_block_move (dstb, srcb, size,
TYPE_ALIGN (va_list_type_node) / BITS_PER_UNIT);
}

View File

@ -1833,6 +1833,7 @@ rs6000_va_start (stdarg_p, valist, nextarg)
f_ovf = TREE_CHAIN (f_fpr);
f_sav = TREE_CHAIN (f_ovf);
valist = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)), valist);
gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr);
fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr);
ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf);
@ -1893,6 +1894,7 @@ rs6000_va_arg (valist, type)
f_ovf = TREE_CHAIN (f_fpr);
f_sav = TREE_CHAIN (f_ovf);
valist = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)), valist);
gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr);
fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr);
ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf);