This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]