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]
Other format: [Raw text]

Re: Yet more rs6000 function arg passing fixes


Ping.

On Wed, May 12, 2004 at 11:28:14PM +0930, Alan Modra wrote:
> 	* config/rs6000/rs6000.c (rs6000_mixed_function_arg): Rewrite.
> 	(function_arg): Use rs6000_arg_size rather than CLASS_MAX_NREGS in
> 	calculating gpr size for altivec.  Simplify and correct
> 	rs6000_mixed_function_arg calls.  Call rs6000_mixed_function_arg
> 	for ABI_V4 gpr case too.  Fix off-by-one error in long double
> 	reg test.  Generate the correct PARALLEL to handle long double
> 	for ABI_AIX 32-bit.  Use this for -m32 -mpowerpc64 fpr case too.
> 	(function_arg_partial_nregs): Align before calculating regs left.
> 	Don't return info on partial fprs when we need info on gprs.
> 	Correct long double fpr off-by-one error.

> I suppose I should polish them up so they can be added to the gcc
> testsuite.

	* gcc.dg/abi1.c: New file.
	* gcc.dg/abi2.c: New file.

OK to install this too?

Index: gcc/testsuite/gcc.dg/abi1.c
===================================================================
RCS file: gcc/testsuite/gcc.dg/abi1.c
diff -N gcc/testsuite/gcc.dg/abi1.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gcc/testsuite/gcc.dg/abi1.c	18 May 2004 02:20:42 -0000
@@ -0,0 +1,222 @@
+/* Test that function args can be passed in various positions to both fixed
+   and variable arg functions.  */
+/* { dg-do run } */
+/* { dg-options "-O" } */
+
+#if DEBUG
+#include <stdio.h>
+#define DBG(x) fputs (x, stdout); fflush (stdout);
+#else
+#define DBG(x)
+#endif
+
+#define TEST_FUNCS(NAME, TYPE, PADT, VAL, VAL2) \
+void NAME##_f0 (TYPE a, PADT b)						\
+{									\
+  if (a != VAL || b != VAL2)						\
+    abort ();								\
+}									\
+									\
+void NAME##_f1 (PADT z0, TYPE a, PADT b)				\
+{									\
+  if (z0 != (PADT) 0							\
+      || a != VAL || b != VAL2)						\
+    abort ();								\
+}									\
+									\
+void NAME##_f2 (PADT z0, PADT z1, TYPE a, PADT b)			\
+{									\
+  if (z0 != (PADT) 0							\
+      || z1 != (PADT) 0							\
+      || a != VAL || b != VAL2)						\
+    abort ();								\
+}									\
+									\
+void NAME##_f3 (PADT z0, PADT z1, PADT z2, TYPE a, PADT b)		\
+{									\
+  if (z0 != (PADT) 0							\
+      || z1 != (PADT) 0							\
+      || z2 != (PADT) 0							\
+      || a != VAL || b != VAL2)						\
+    abort ();								\
+}									\
+									\
+void NAME##_f4 (PADT z0, PADT z1, PADT z2, PADT z3, TYPE a, PADT b)	\
+{									\
+  if (z0 != (PADT) 0							\
+      || z1 != (PADT) 0							\
+      || z2 != (PADT) 0							\
+      || z3 != (PADT) 0							\
+      || a != VAL || b != VAL2)						\
+    abort ();								\
+}									\
+									\
+void NAME##_f5 (PADT z0, PADT z1, PADT z2, PADT z3, PADT z4, TYPE a,	\
+		PADT b)							\
+{									\
+  if (z0 != (PADT) 0							\
+      || z1 != (PADT) 0							\
+      || z2 != (PADT) 0							\
+      || z3 != (PADT) 0							\
+      || z4 != (PADT) 0							\
+      || a != VAL || b != VAL2)						\
+    abort ();								\
+}									\
+									\
+void NAME##_f6 (PADT z0, PADT z1, PADT z2, PADT z3, PADT z4, PADT z5,	\
+		TYPE a, PADT b)						\
+{									\
+  if (z0 != (PADT) 0							\
+      || z1 != (PADT) 0							\
+      || z2 != (PADT) 0							\
+      || z3 != (PADT) 0							\
+      || z4 != (PADT) 0							\
+      || z5 != (PADT) 0							\
+      || a != VAL || b != VAL2)						\
+    abort ();								\
+}									\
+									\
+void NAME##_f7 (PADT z0, PADT z1, PADT z2, PADT z3, PADT z4, PADT z5,	\
+		PADT z6, TYPE a, PADT b)				\
+{									\
+  if (z0 != (PADT) 0							\
+      || z1 != (PADT) 0							\
+      || z2 != (PADT) 0							\
+      || z3 != (PADT) 0							\
+      || z4 != (PADT) 0							\
+      || z5 != (PADT) 0							\
+      || z6 != (PADT) 0							\
+      || a != VAL || b != VAL2)						\
+    abort ();								\
+}									\
+									\
+void NAME##_f8 (PADT z0, PADT z1, PADT z2, PADT z3, PADT z4, PADT z5,	\
+		PADT z6, PADT z7, TYPE a, PADT b)			\
+{									\
+  if (z0 != (PADT) 0							\
+      || z1 != (PADT) 0							\
+      || z2 != (PADT) 0							\
+      || z3 != (PADT) 0							\
+      || z4 != (PADT) 0							\
+      || z5 != (PADT) 0							\
+      || z6 != (PADT) 0							\
+      || z7 != (PADT) 0							\
+      || a != VAL || b != VAL2)						\
+    abort ();								\
+}									\
+									\
+void NAME##_f9 (PADT z0, PADT z1, PADT z2, PADT z3, PADT z4, PADT z5,	\
+		PADT z6, PADT z7, PADT z8, TYPE a, PADT b)		\
+{									\
+  if (z0 != (PADT) 0							\
+      || z1 != (PADT) 0							\
+      || z2 != (PADT) 0							\
+      || z3 != (PADT) 0							\
+      || z4 != (PADT) 0							\
+      || z5 != (PADT) 0							\
+      || z6 != (PADT) 0							\
+      || z7 != (PADT) 0							\
+      || z8 != (PADT) 0							\
+      || a != VAL || b != VAL2)						\
+    abort ();								\
+}									\
+									\
+void NAME##_fv (int n, ...)						\
+{									\
+  __builtin_va_list ap;							\
+									\
+  __builtin_va_start (ap, n);						\
+									\
+  while (n-- != 0)							\
+    if (__builtin_va_arg (ap, PADT) != (PADT) 0)			\
+      abort ();								\
+									\
+  if (__builtin_va_arg (ap, TYPE) != VAL)				\
+    abort ();								\
+									\
+  if (__builtin_va_arg (ap, PADT) != VAL2)				\
+    abort ();								\
+									\
+  __builtin_va_end (ap);						\
+}									\
+									\
+void NAME##_doit (void)							\
+{									\
+  NAME##_f0 (VAL, VAL2);						\
+  DBG (".");								\
+  NAME##_f1 ((PADT) 0, VAL, VAL2);					\
+  DBG (".");								\
+  NAME##_f2 ((PADT) 0, (PADT) 0, VAL, VAL2);				\
+  DBG (".");								\
+  NAME##_f3 ((PADT) 0, (PADT) 0, (PADT) 0, VAL, VAL2);			\
+  DBG (".");								\
+  NAME##_f4 ((PADT) 0, (PADT) 0, (PADT) 0, (PADT) 0, VAL, VAL2);	\
+  DBG (".");								\
+  NAME##_f5 ((PADT) 0, (PADT) 0, (PADT) 0, (PADT) 0, (PADT) 0,		\
+	     VAL, VAL2);						\
+  DBG (".");								\
+  NAME##_f6 ((PADT) 0, (PADT) 0, (PADT) 0, (PADT) 0, (PADT) 0,		\
+	     (PADT) 0, VAL, VAL2);					\
+  DBG (".");								\
+  NAME##_f7 ((PADT) 0, (PADT) 0, (PADT) 0, (PADT) 0, (PADT) 0,		\
+	     (PADT) 0, (PADT) 0, VAL, VAL2);				\
+  DBG (".");								\
+  NAME##_f8 ((PADT) 0, (PADT) 0, (PADT) 0, (PADT) 0, (PADT) 0,		\
+	     (PADT) 0, (PADT) 0, (PADT) 0, VAL, VAL2);			\
+  DBG (".");								\
+  NAME##_f9 ((PADT) 0, (PADT) 0, (PADT) 0, (PADT) 0, (PADT) 0,		\
+	     (PADT) 0, (PADT) 0, (PADT) 0, (PADT) 0, VAL, VAL2);	\
+  DBG (".");								\
+  NAME##_fv (0, VAL, VAL2);						\
+  DBG (".");								\
+  NAME##_fv (1, (PADT) 0, VAL, VAL2);					\
+  DBG (".");								\
+  NAME##_fv (2, (PADT) 0, (PADT) 0, VAL, VAL2);				\
+  DBG (".");								\
+  NAME##_fv (3, (PADT) 0, (PADT) 0, (PADT) 0, VAL, VAL2);		\
+  DBG (".");								\
+  NAME##_fv (4, (PADT) 0, (PADT) 0, (PADT) 0, (PADT) 0, VAL, VAL2);	\
+  DBG (".");								\
+  NAME##_fv (5, (PADT) 0, (PADT) 0, (PADT) 0, (PADT) 0, (PADT) 0,	\
+	     VAL, VAL2);						\
+  DBG (".");								\
+  NAME##_fv (6, (PADT) 0, (PADT) 0, (PADT) 0, (PADT) 0, (PADT) 0,	\
+	     (PADT) 0, VAL, VAL2);					\
+  DBG (".");								\
+  NAME##_fv (7, (PADT) 0, (PADT) 0, (PADT) 0, (PADT) 0, (PADT) 0,	\
+	     (PADT) 0, (PADT) 0, VAL, VAL2);				\
+  DBG (".");								\
+  NAME##_fv (8, (PADT) 0, (PADT) 0, (PADT) 0, (PADT) 0, (PADT) 0,	\
+	     (PADT) 0, (PADT) 0, (PADT) 0, VAL, VAL2);			\
+  DBG ("\n");								\
+}
+
+TEST_FUNCS (longlong_i, long long, int,
+	    1234LL, -987)
+TEST_FUNCS (longlong_d, long long, double,
+	    1234LL, -987.0)
+TEST_FUNCS (complexint_i, _Complex int, int,
+	    1234 + 567i, -987)
+TEST_FUNCS (complexint_d, _Complex int, double,
+	    1234 + 567i, -987.0)
+TEST_FUNCS (complexdouble_i, _Complex double, int,
+	    1234.0 + 567.0i, -987)
+TEST_FUNCS (complexdouble_d, _Complex double, double,
+	    1234.0 + 567.0i, -987.0)
+TEST_FUNCS (complexlonglong_i, _Complex long long, int,
+	    1234LL + 567LLi, -987)
+TEST_FUNCS (complexlonglong_d, _Complex long long, double,
+	    1234LL + 567LLi, -987.0)
+
+int main (void)
+{
+  longlong_i_doit ();
+  longlong_d_doit ();
+  complexint_i_doit ();
+  complexint_d_doit ();
+  complexdouble_i_doit ();
+  complexdouble_d_doit ();
+  complexlonglong_i_doit ();
+  complexlonglong_d_doit ();
+  exit (0);
+}
Index: gcc/testsuite/gcc.dg/abi2.c
===================================================================
RCS file: gcc/testsuite/gcc.dg/abi2.c
diff -N gcc/testsuite/gcc.dg/abi2.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gcc/testsuite/gcc.dg/abi2.c	18 May 2004 02:20:42 -0000
@@ -0,0 +1,223 @@
+/* Test that function args can be passed in various positions to both fixed
+   and variable arg functions.  */
+/* { dg-do run { target powerpc*-*-* } } */
+/* { dg-options "-O -mabi=no-altivec -mno-altivec -mlong-double-128" } */
+
+
+#if DEBUG
+#include <stdio.h>
+#define DBG(x) fputs (x, stdout); fflush (stdout);
+#else
+#define DBG(x)
+#endif
+
+#define vector __attribute__ ((vector_size (16)))
+
+vector int v1 = {1, 2, 3, 4};
+vector float v2 = {1.0, 2.0, 3.0, 4.0};
+long double d = 1234.0L + 0x0.abcdp-70L;
+_Complex long double cd = 234.0L + 0x0.abcp-70L + 567.0Li +0x0defp-70Li;
+
+#define TEST_FUNCS(NAME, TYPE, PADT, VAL, VAL2) \
+void NAME##_f0 (TYPE a, PADT b)						\
+{									\
+  if (memcmp (&a, &VAL, sizeof (a)) != 0 || b != VAL2)			\
+    abort ();								\
+}									\
+									\
+void NAME##_f1 (PADT z0, TYPE a, PADT b)				\
+{									\
+  if (z0 != (PADT) 0							\
+      || memcmp (&a, &VAL, sizeof (a)) != 0 || b != VAL2)		\
+    abort ();								\
+}									\
+									\
+void NAME##_f2 (PADT z0, PADT z1, TYPE a, PADT b)			\
+{									\
+  if (z0 != (PADT) 0							\
+      || z1 != (PADT) 0							\
+      || memcmp (&a, &VAL, sizeof (a)) != 0 || b != VAL2)		\
+    abort ();								\
+}									\
+									\
+void NAME##_f3 (PADT z0, PADT z1, PADT z2, TYPE a, PADT b)		\
+{									\
+  if (z0 != (PADT) 0							\
+      || z1 != (PADT) 0							\
+      || z2 != (PADT) 0							\
+      || memcmp (&a, &VAL, sizeof (a)) != 0 || b != VAL2)		\
+    abort ();								\
+}									\
+									\
+void NAME##_f4 (PADT z0, PADT z1, PADT z2, PADT z3, TYPE a, PADT b)	\
+{									\
+  if (z0 != (PADT) 0							\
+      || z1 != (PADT) 0							\
+      || z2 != (PADT) 0							\
+      || z3 != (PADT) 0							\
+      || memcmp (&a, &VAL, sizeof (a)) != 0 || b != VAL2)		\
+    abort ();								\
+}									\
+									\
+void NAME##_f5 (PADT z0, PADT z1, PADT z2, PADT z3, PADT z4, TYPE a,	\
+		PADT b)							\
+{									\
+  if (z0 != (PADT) 0							\
+      || z1 != (PADT) 0							\
+      || z2 != (PADT) 0							\
+      || z3 != (PADT) 0							\
+      || z4 != (PADT) 0							\
+      || memcmp (&a, &VAL, sizeof (a)) != 0 || b != VAL2)		\
+    abort ();								\
+}									\
+									\
+void NAME##_f6 (PADT z0, PADT z1, PADT z2, PADT z3, PADT z4, PADT z5,	\
+		TYPE a, PADT b)						\
+{									\
+  if (z0 != (PADT) 0							\
+      || z1 != (PADT) 0							\
+      || z2 != (PADT) 0							\
+      || z3 != (PADT) 0							\
+      || z4 != (PADT) 0							\
+      || z5 != (PADT) 0							\
+      || memcmp (&a, &VAL, sizeof (a)) != 0 || b != VAL2)		\
+    abort ();								\
+}									\
+									\
+void NAME##_f7 (PADT z0, PADT z1, PADT z2, PADT z3, PADT z4, PADT z5,	\
+		PADT z6, TYPE a, PADT b)				\
+{									\
+  if (z0 != (PADT) 0							\
+      || z1 != (PADT) 0							\
+      || z2 != (PADT) 0							\
+      || z3 != (PADT) 0							\
+      || z4 != (PADT) 0							\
+      || z5 != (PADT) 0							\
+      || z6 != (PADT) 0							\
+      || memcmp (&a, &VAL, sizeof (a)) != 0 || b != VAL2)		\
+    abort ();								\
+}									\
+									\
+void NAME##_f8 (PADT z0, PADT z1, PADT z2, PADT z3, PADT z4, PADT z5,	\
+		PADT z6, PADT z7, TYPE a, PADT b)			\
+{									\
+  if (z0 != (PADT) 0							\
+      || z1 != (PADT) 0							\
+      || z2 != (PADT) 0							\
+      || z3 != (PADT) 0							\
+      || z4 != (PADT) 0							\
+      || z5 != (PADT) 0							\
+      || z6 != (PADT) 0							\
+      || z7 != (PADT) 0							\
+      || memcmp (&a, &VAL, sizeof (a)) != 0 || b != VAL2)		\
+    abort ();								\
+}									\
+									\
+void NAME##_f9 (PADT z0, PADT z1, PADT z2, PADT z3, PADT z4, PADT z5,	\
+		PADT z6, PADT z7, PADT z8, TYPE a, PADT b)		\
+{									\
+  if (z0 != (PADT) 0							\
+      || z1 != (PADT) 0							\
+      || z2 != (PADT) 0							\
+      || z3 != (PADT) 0							\
+      || z4 != (PADT) 0							\
+      || z5 != (PADT) 0							\
+      || z6 != (PADT) 0							\
+      || z7 != (PADT) 0							\
+      || z8 != (PADT) 0							\
+      || memcmp (&a, &VAL, sizeof (a)) != 0 || b != VAL2)		\
+    abort ();								\
+}									\
+									\
+void NAME##_fv (int n, ...)						\
+{									\
+  __builtin_va_list ap;							\
+  TYPE x;								\
+  __builtin_va_start (ap, n);						\
+									\
+  while (n-- != 0)							\
+    if (__builtin_va_arg (ap, PADT) != (PADT) 0)			\
+      abort ();								\
+									\
+  x = __builtin_va_arg (ap, TYPE);					\
+  if (memcmp (&x, &VAL, sizeof (x)) != 0 )				\
+    abort ();								\
+									\
+  if (__builtin_va_arg (ap, PADT) != VAL2)				\
+    abort ();								\
+									\
+  __builtin_va_end (ap);						\
+}									\
+									\
+void NAME##_doit (void)							\
+{									\
+  NAME##_f0 (VAL, VAL2);						\
+  DBG (".");								\
+  NAME##_f1 ((PADT) 0, VAL, VAL2);					\
+  DBG (".");								\
+  NAME##_f2 ((PADT) 0, (PADT) 0, VAL, VAL2);				\
+  DBG (".");								\
+  NAME##_f3 ((PADT) 0, (PADT) 0, (PADT) 0, VAL, VAL2);			\
+  DBG (".");								\
+  NAME##_f4 ((PADT) 0, (PADT) 0, (PADT) 0, (PADT) 0, VAL, VAL2);	\
+  DBG (".");								\
+  NAME##_f5 ((PADT) 0, (PADT) 0, (PADT) 0, (PADT) 0, (PADT) 0,		\
+	     VAL, VAL2);						\
+  DBG (".");								\
+  NAME##_f6 ((PADT) 0, (PADT) 0, (PADT) 0, (PADT) 0, (PADT) 0,		\
+	     (PADT) 0, VAL, VAL2);					\
+  DBG (".");								\
+  NAME##_f7 ((PADT) 0, (PADT) 0, (PADT) 0, (PADT) 0, (PADT) 0,		\
+	     (PADT) 0, (PADT) 0, VAL, VAL2);				\
+  DBG (".");								\
+  NAME##_f8 ((PADT) 0, (PADT) 0, (PADT) 0, (PADT) 0, (PADT) 0,		\
+	     (PADT) 0, (PADT) 0, (PADT) 0, VAL, VAL2);			\
+  DBG (".");								\
+  NAME##_f9 ((PADT) 0, (PADT) 0, (PADT) 0, (PADT) 0, (PADT) 0,		\
+	     (PADT) 0, (PADT) 0, (PADT) 0, (PADT) 0, VAL, VAL2);	\
+  DBG (".");								\
+  NAME##_fv (0, VAL, VAL2);						\
+  DBG (".");								\
+  NAME##_fv (1, (PADT) 0, VAL, VAL2);					\
+  DBG (".");								\
+  NAME##_fv (2, (PADT) 0, (PADT) 0, VAL, VAL2);				\
+  DBG (".");								\
+  NAME##_fv (3, (PADT) 0, (PADT) 0, (PADT) 0, VAL, VAL2);		\
+  DBG (".");								\
+  NAME##_fv (4, (PADT) 0, (PADT) 0, (PADT) 0, (PADT) 0, VAL, VAL2);	\
+  DBG (".");								\
+  NAME##_fv (5, (PADT) 0, (PADT) 0, (PADT) 0, (PADT) 0, (PADT) 0,	\
+	     VAL, VAL2);						\
+  DBG (".");								\
+  NAME##_fv (6, (PADT) 0, (PADT) 0, (PADT) 0, (PADT) 0, (PADT) 0,	\
+	     (PADT) 0, VAL, VAL2);					\
+  DBG (".");								\
+  NAME##_fv (7, (PADT) 0, (PADT) 0, (PADT) 0, (PADT) 0, (PADT) 0,	\
+	     (PADT) 0, (PADT) 0, VAL, VAL2);				\
+  DBG (".");								\
+  NAME##_fv (8, (PADT) 0, (PADT) 0, (PADT) 0, (PADT) 0, (PADT) 0,	\
+	     (PADT) 0, (PADT) 0, (PADT) 0, VAL, VAL2);			\
+  DBG ("\n");								\
+}
+
+TEST_FUNCS (longdouble_i, long double, int, d, -987)
+TEST_FUNCS (longdouble_d, long double, double, d, -987.0)
+TEST_FUNCS (complexlongdouble_i, _Complex long double, int, cd, -987)
+TEST_FUNCS (complexlongdouble_d, _Complex long double, double, cd, -987.0)
+TEST_FUNCS (vecint_i, vector int, int, v1, -987)
+TEST_FUNCS (vecint_d, vector int, double, v1, -987.0)
+TEST_FUNCS (vecfloat_i, vector float, int, v2, -987)
+TEST_FUNCS (vecfloat_d, vector float, double, v2, -987.0)
+
+int main (void)
+{
+  longdouble_i_doit ();
+  longdouble_d_doit ();
+  complexlongdouble_i_doit ();
+  complexlongdouble_d_doit ();
+  vecint_i_doit ();
+  vecint_d_doit ();
+  vecfloat_i_doit ();
+  vecfloat_d_doit ();
+  exit (0);
+}

-- 
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]