This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
powerpc64 builtin_va_arg and variable size structures
- From: Alan Modra <amodra at bigpond dot net dot au>
- To: gcc at gcc dot gnu dot org
- Cc: David Edelsohn <dje at watson dot ibm dot com>, Geoffrey Keating <geoffk at geoffk dot org>
- Date: Tue, 1 Apr 2003 11:07:28 +0930
- Subject: powerpc64 builtin_va_arg and variable size structures
gcc.c-torture/execute/20020412-1.c fails on powerpc64-linux due to
a mismatch between the way variable size structures are pushed, and
the way the standard builtin_va_arg reads them.
In rs6000.c:function_arg, we have
if (type && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
return NULL_RTX;
which results in variable size structures not being placed in the
register param stack area. Instead, any remaining space in the reg
param stack area is skipped, and the arg is pushed to the stack past
this area. The following demo patch fixes this by adjusting the arg
pointer during builtin_va_arg processing, but I'd actually rather
see the the above two lines removed as I can't see anything in the
PPC64 ABI that mandates special treatment for variable size
structures. Can someone say why function_arg behaves this way?
* config/rs6000/rs6000.c (rs6000_va_arg): Match function_arg
treatment of variable sized structures.
--- gcc-ppc64-33.orig/gcc/config/rs6000/rs6000.c 2003-03-20 14:34:23.000000000 +1030
+++ gcc-ppc64-33/gcc/config/rs6000/rs6000.c 2003-04-01 09:17:04.000000000 +0930
@@ -3547,7 +3547,19 @@ rs6000_va_arg (valist, type)
rtx lab_false, lab_over, addr_rtx, r;
if (DEFAULT_ABI != ABI_V4)
- return std_expand_builtin_va_arg (valist, type);
+ {
+ if (TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
+ {
+ t = make_tree (TREE_TYPE (valist), virtual_incoming_args_rtx);
+ t = build (PLUS_EXPR, TREE_TYPE (valist),
+ t, build_int_2 (TARGET_64BIT ? 64 : 32, 0));
+ t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
+ build (MAX_EXPR, TREE_TYPE (valist), valist, t));
+ TREE_SIDE_EFFECTS (t) = 1;
+ expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
+ }
+ return std_expand_builtin_va_arg (valist, type);
+ }
f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
f_fpr = TREE_CHAIN (f_gpr);
--
Alan Modra
IBM OzLabs - Linux Technology Centre