This is the mail archive of the gcc-patches@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]

ppc AIX vararg patch



I just committed this to the branch, because the test failure was
annoying me :-).

There's an inconsistency between the ABI implemented by gcc, and the
one the IBM compilers use.  The IBM compilers pass all structure
arguments left-aligned in the argument slot (that is, in the high
bits/lower-numbered addresses of the argument---remember, big-endian
machine).  GCC passes structures as if they were integers, that is in
the low bits of the argument slot, unless they are BLKmode (that is,
they aren't a power-of-two), in which case they are passed in the high
bits.  This is probably better, but inconsistent.

I couldn't find why it was doing this, I suspect a bug in the
machine-independent argument frobbing code.  Anyway, I'm not sure I
want to change GCC's calling convention at this point.

The previous varargs implementation wasn't expecting either of these.
It was expecting everything in the low bits of the argument slot.
This fixes it so it matches how GCC passes arguments.  It would be
easy to change this so it matches how IBM compilers pass arguments,
but not quite so useful :-).

In practise, all this only affects structures smaller than the word
size passed as parameters, which is not common.

-- 
- Geoffrey Keating <geoffk@cygnus.com>

===File ~/patches/cygnus/rs6000-psched-3-aixvaarg.patch=====
2000-01-14  Geoffrey Keating  <geoffk@cygnus.com>

	* rs6000.c (rs6000_va_arg): On AIX, padding for small arguments
	goes after the argument.

Index: rs6000.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/rs6000/rs6000.c,v
retrieving revision 1.108.2.5
diff -p -u -u -p -r1.108.2.5 rs6000.c
--- rs6000.c	2000/01/13 01:43:09	1.108.2.5
+++ rs6000.c	2000/01/19 20:22:00
@@ -1890,9 +1889,50 @@ rs6000_va_arg (valist, type)
   int indirect_p, size, rsize, n_reg, sav_ofs, sav_scale;
   rtx lab_false, lab_over, addr_rtx, r;
 
-  /* Only SVR4 needs something special.  */
+  /* For AIX, the rule is that structures are passed left-aligned in
+     their stack slot.  However, GCC does not presently do this:
+     structures which are the same size as integer types are passed
+     right-aligned, as if they were in fact integers.  This only
+     matters for structures of size 1 or 2, or 4 when TARGET_64BIT.  */
   if (DEFAULT_ABI != ABI_V4 && DEFAULT_ABI != ABI_SOLARIS)
-    return std_expand_builtin_va_arg (valist, type);
+    {
+      HOST_WIDE_INT align, rounded_size;
+      enum machine_mode mode;
+      enum direction dir;
+      int unsignedp;
+      tree addr_tree;
+
+      /* Compute the rounded size of the type.  */
+      align = PARM_BOUNDARY / BITS_PER_UNIT;
+      rounded_size = (((int_size_in_bytes (type) + align - 1) / align)
+		      * align);
+
+      addr_tree = valist;
+
+      mode = TYPE_MODE (type);
+      if (mode != BLKmode)
+	{
+	  HOST_WIDE_INT adj;
+	  adj = TREE_INT_CST_LOW (TYPE_SIZE (type)) / BITS_PER_UNIT;
+	  if (rounded_size > align)
+	    adj = rounded_size;
+	  
+	  addr_tree = build (PLUS_EXPR, TREE_TYPE (addr_tree), addr_tree,
+			     build_int_2 (rounded_size - adj, 0));
+	}
+
+      addr_rtx = expand_expr (addr_tree, NULL_RTX, Pmode, EXPAND_NORMAL);
+      addr_rtx = copy_to_reg (addr_rtx);
+      
+      /* Compute new value for AP.  */
+      t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
+		 build (PLUS_EXPR, TREE_TYPE (valist), valist,
+			build_int_2 (rounded_size, 0)));
+      TREE_SIDE_EFFECTS (t) = 1;
+      expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
+      
+      return addr_rtx;
+    }
 
   f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
   f_fpr = TREE_CHAIN (f_gpr);
============================================================

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