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]

[PATCH] re-enable -mabi=no-altivec on powerpc64-linux


This patch is needed before we can default to the AltiVec ABI for
32-bit powerpc-linux; see PR 34526.

On powerpc*-linux the option -mabi=no-alltivec has been broken since
revision 99284, which changed the way that options are handled for the
rs6000 back end.  Before that change, rs6000_override_options set
rs6000_altivec_abi to the appropriate default before calling
rs6000_parse_abi_options, which could change rs6000_altivec_abi.  After
that revision the -mabi option is handled _before_ the call to
rs6000_override_options

This patch uses an existing mechanism, rs6000_explicit_options.abi, to
determine whether there has been an explicit request for the ABI before
setting it to the default value.  New tests check combinations of
-maltivec and -mabi=altivec for powerpc*-linux to check that the
requested ABI is being used.

Before this patch, rs6000_explicit_options.abi was explicitly NOT set
for -mabi=no-altivec (by the comment with "???").  Alan, please take a
look to see if I broke something for SPE.  Perhaps there should be
separate fields for altivec_abi and spec_abi?

Bootstrapped and regression tested on powerpc64-linux for -m32/-m64.
OK for mainline?

2008-02-04  Janis Johnson  <janis187@us.ibm.com>

	* config/rs6000/rs6000.c (rs6000_altivec_abi): Clarify comment.
	(rs6000_override_options): Default to AltiVec ABI only if no
	abi option was specified.
	(rs6000_handle_option): Record that explicit ABI option was seen.

	* gcc.target/powerpc/ppc32-elf-altivec-abi-1.c: New test.
	* gcc.target/powerpc/ppc32-elf-altivec-abi-2.c: New test.
	* gcc.target/powerpc/ppc32-elf-altivec-abi-3.c: New test.
	* gcc.target/powerpc/ppc64-elf-altivec-abi-1.c: New test.
	* gcc.target/powerpc/ppc64-elf-altivec-abi-2.c: New test.
	* gcc.target/powerpc/ppc64-elf-altivec-abi-3.c: New test.

Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c	(revision 132048)
+++ gcc/config/rs6000/rs6000.c	(working copy)
@@ -171,7 +171,7 @@
 /* IEEE quad extended precision long double. */
 int rs6000_ieeequad;
 
-/* Whether -mabi=altivec has appeared.  */
+/* Whether to use AltiVec ABI.  */
 int rs6000_altivec_abi;
 
 /* Nonzero if we want SPE ABI extensions.  */
@@ -1590,10 +1590,11 @@
   if (TARGET_XCOFF && TARGET_ALTIVEC)
     rs6000_altivec_abi = 1;
 
-  /* Set Altivec ABI as default for PowerPC64 Linux.  */
+  /* Altivec ABI is default for PowerPC64 Linux.  */
   if (TARGET_ELF && TARGET_64BIT)
     {
-      rs6000_altivec_abi = 1;
+      if (! rs6000_explicit_options.abi)
+	rs6000_altivec_abi = 1;
       TARGET_ALTIVEC_VRSAVE = 1;
     }
 
@@ -2194,9 +2195,9 @@
 	}
       else if (! strcmp (arg, "no-altivec"))
 	{
-	  /* ??? Don't set rs6000_explicit_options.abi here, to allow
-	     the default for rs6000_spe_abi to be chosen later.  */
+	  rs6000_explicit_options.abi = true;
 	  rs6000_altivec_abi = 0;
+	  rs6000_spe_abi = 0;
 	}
       else if (! strcmp (arg, "spe"))
 	{
Index: gcc/testsuite/gcc.target/powerpc/ppc32-elf-altivec-abi-1.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/ppc32-elf-altivec-abi-1.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/ppc32-elf-altivec-abi-1.c	(revision 0)
@@ -0,0 +1,67 @@
+/* { dg-do run { target { powerpc*-*-linux* && { ilp32 && vmx_hw } } } } */
+/* { dg-options "-std=gnu99 -O2 -fno-strict-aliasing -maltivec -mabi=altivec" } */
+
+/* Check that arguments are passed according to the requested ABI.  */
+
+extern void abort (void);
+int failcnt = 0;
+
+/* Support compiling the test to report individual failures; default is
+   to abort as soon as a check fails.  */
+#ifdef DBG
+#include <stdio.h>
+#define FAILURE { printf ("failed at line %d\n", __LINE__); failcnt++; }
+#else
+#define FAILURE abort ();
+#endif
+
+typedef int __attribute__((vector_size(16))) v4si;
+
+v4si g0 = { 101, 102, 103, 104 };
+v4si g1 = { 201, 202, 203, 204 };
+v4si g2 = { 301, 302, 303, 304 };
+v4si g3 = { 401, 402, 403, 404 };
+
+/* With the AltiVec ABI, the first four vector arguments are passed in
+   vector registers 2 through 5.  */
+
+typedef struct vpt
+{
+  v4si vr[4];
+} vec_parms_t;
+
+vec_parms_t gparms;
+
+#define save_vec_parms(lparms)				\
+    asm volatile ("lis 11,gparms@ha\n\t"		\
+		  "la 11,gparms@l(11)\n\t"		\
+		  "stvx 2,0,11\n\t"			\
+		  "addi 11,11,16\n\t"			\
+		  "stvx 3,0,11\n\t"			\
+		  "addi 11,11,16\n\t"			\
+		  "stvx 4,0,11\n\t"			\
+		  "addi 11,11,16\n\t"			\
+		  "stvx 5,0,11\n\t":::"11", "memory");	\
+		  lparms = gparms;
+
+void __attribute__ ((noinline))
+func0 (v4si a0, v4si a1, v4si a2, v4si a3)
+{
+  vec_parms_t lparms;
+  save_vec_parms (lparms);
+  if (__builtin_memcmp (&lparms.vr[0], &g0, 16) != 0) FAILURE
+  if (__builtin_memcmp (&lparms.vr[1], &g1, 16) != 0) FAILURE
+  if (__builtin_memcmp (&lparms.vr[2], &g2, 16) != 0) FAILURE
+  if (__builtin_memcmp (&lparms.vr[3], &g3, 16) != 0) FAILURE
+}
+
+int
+main (void)
+{
+  func0 (g0, g1, g2, g3);
+
+  if (failcnt != 0)
+    abort ();
+
+  return 0;
+}
Index: gcc/testsuite/gcc.target/powerpc/ppc64-elf-altivec-abi-2.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/ppc64-elf-altivec-abi-2.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/ppc64-elf-altivec-abi-2.c	(revision 0)
@@ -0,0 +1,63 @@
+/* { dg-do run { target { powerpc*-*-linux* && { lp64 && vmx_hw } } } } */
+/* { dg-options "-w -std=gnu99 -O2 -fno-strict-aliasing -maltivec -mabi=no-altivec" } */
+
+/* Check that arguments are passed according to the requested ABI.  */
+
+extern void abort (void);
+int failcnt = 0;
+
+/* Support compiling the test to report individual failures; default is
+   to abort as soon as a check fails.  */
+#ifdef DBG
+#include <stdio.h>
+#define FAILURE { printf ("failed at line %d\n", __LINE__); failcnt++; }
+#else
+#define FAILURE abort ();
+#endif
+
+typedef int __attribute__((vector_size(16))) v4si;
+
+v4si g0 = { 101, 102, 103, 104 };
+v4si g1 = { 201, 202, 203, 204 };
+v4si g2 = { 301, 302, 303, 304 };
+v4si g3 = { 401, 402, 403, 404 };
+
+/* With the non-AltiVec ABI, vector arguments are passed by reference
+   via general registers.  */
+
+typedef struct vpt
+{
+  v4si *gr[4];
+} vec_parms_t;
+
+vec_parms_t gparms;
+
+#define save_vec_parms(lparms)				\
+    asm volatile ("ld 11,gparms@got(2)\n\t"		\
+		  "std 3,0(11)\n\t"			\
+		  "std 4,8(11)\n\t"			\
+		  "std 5,16(11)\n\t"			\
+		  "std 6,24(11)\n\t":::"11", "memory");	\
+		  lparms = gparms;
+
+void __attribute__ ((noinline))
+func0 (v4si a0, v4si a1, v4si a2, v4si a3)
+{
+  vec_parms_t lparms;
+  save_vec_parms (lparms);
+  if (__builtin_memcmp (lparms.gr[0], &g0, 16) != 0) FAILURE
+  if (__builtin_memcmp (lparms.gr[1], &g1, 16) != 0) FAILURE
+  if (__builtin_memcmp (lparms.gr[2], &g2, 16) != 0) FAILURE
+  if (__builtin_memcmp (lparms.gr[3], &g3, 16) != 0) FAILURE
+}
+
+int
+main (void)
+{
+  func0 (g0, g1, g2, g3);
+
+  if (failcnt != 0)
+    abort ();
+
+  return 0;
+}
Index: gcc/testsuite/gcc.target/powerpc/ppc32-elf-altivec-abi-2.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/ppc32-elf-altivec-abi-2.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/ppc32-elf-altivec-abi-2.c	(revision 0)
@@ -0,0 +1,65 @@
+/* { dg-do run { target { powerpc*-*-linux* && { ilp32 && vmx_hw } } } } */
+/* { dg-options "-w -std=gnu99 -O2 -fno-strict-aliasing -maltivec -mabi=no-altivec" } */
+
+/* Check that arguments are passed according to the requested ABI.  */
+
+extern void abort (void);
+int failcnt = 0;
+
+/* Support compiling the test to report individual failures; default is
+   to abort as soon as a check fails.  */
+#ifdef DBG
+#include <stdio.h>
+#define FAILURE { printf ("failed at line %d\n", __LINE__); failcnt++; }
+#else
+#define FAILURE abort ();
+#endif
+
+typedef int __attribute__((vector_size(16))) v4si;
+
+v4si g0 = { 101, 102, 103, 104 };
+v4si g1 = { 201, 202, 203, 204 };
+v4si g2 = { 301, 302, 303, 304 };
+v4si g3 = { 401, 402, 403, 404 };
+
+/* With the non-AltiVec ABI, vector arguments are passed by reference
+   via general registers.  */
+
+typedef struct vpt
+{
+  v4si *gr[4];
+} vec_parms_t;
+
+vec_parms_t gparms;
+
+#define save_vec_parms(lparms)				\
+    asm volatile ("lis 11,gparms@ha\n\t"		\
+                  "la 11,gparms@l(11)\n\t"		\
+                  "st 3,0(11)\n\t"		        \
+	          "st 4,4(11)\n\t"			\
+	          "st 5,8(11)\n\t"			\
+	          "st 6,12(11)\n\t":::"11", "memory");	\
+                  lparms = gparms;
+
+void __attribute__ ((noinline))
+func0 (v4si a0, v4si a1, v4si a2, v4si a3)
+{
+  vec_parms_t lparms;
+  save_vec_parms (lparms);
+
+  if (__builtin_memcmp (lparms.gr[0], &g0, 16) != 0) FAILURE
+  if (__builtin_memcmp (lparms.gr[1], &g1, 16) != 0) FAILURE
+  if (__builtin_memcmp (lparms.gr[2], &g2, 16) != 0) FAILURE
+  if (__builtin_memcmp (lparms.gr[3], &g3, 16) != 0) FAILURE
+}
+
+int
+main (void)
+{
+  func0 (g0, g1, g2, g3);
+
+  if (failcnt != 0)
+    abort ();
+
+  return 0;
+}
Index: gcc/testsuite/gcc.target/powerpc/ppc64-elf-altivec-abi-3.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/ppc64-elf-altivec-abi-3.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/ppc64-elf-altivec-abi-3.c	(revision 0)
@@ -0,0 +1,63 @@
+/* { dg-do run { target { powerpc*-*-linux* && lp64 } } } */
+/* { dg-options "-w -std=gnu99 -O2 -fno-strict-aliasing -mno-altivec -mabi=no-altivec" } */
+
+/* Check that arguments are passed according to the requested ABI.  */
+
+extern void abort (void);
+int failcnt = 0;
+
+/* Support compiling the test to report individual failures; default is
+   to abort as soon as a check fails.  */
+#ifdef DBG
+#include <stdio.h>
+#define FAILURE { printf ("failed at line %d\n", __LINE__); failcnt++; }
+#else
+#define FAILURE abort ();
+#endif
+
+typedef int __attribute__((vector_size(16))) v4si;
+
+v4si g0 = { 101, 102, 103, 104 };
+v4si g1 = { 201, 202, 203, 204 };
+v4si g2 = { 301, 302, 303, 304 };
+v4si g3 = { 401, 402, 403, 404 };
+
+/* With the non-AltiVec ABI, vector arguments are passed by reference
+   via general registers.  */
+
+typedef struct vpt
+{
+  v4si *gr[4];
+} vec_parms_t;
+
+vec_parms_t gparms;
+
+#define save_vec_parms(lparms)				\
+    asm volatile ("ld 11,gparms@got(2)\n\t"		\
+		  "std 3,0(11)\n\t"			\
+		  "std 4,8(11)\n\t"			\
+		  "std 5,16(11)\n\t"			\
+		  "std 6,24(11)\n\t":::"11", "memory");	\
+		  lparms = gparms;
+
+void __attribute__ ((noinline))
+func0 (v4si a0, v4si a1, v4si a2, v4si a3)
+{
+  vec_parms_t lparms;
+  save_vec_parms (lparms);
+  if (__builtin_memcmp (lparms.gr[0], &g0, 16) != 0) FAILURE
+  if (__builtin_memcmp (lparms.gr[1], &g1, 16) != 0) FAILURE
+  if (__builtin_memcmp (lparms.gr[2], &g2, 16) != 0) FAILURE
+  if (__builtin_memcmp (lparms.gr[3], &g3, 16) != 0) FAILURE
+}
+
+int
+main (void)
+{
+  func0 (g0, g1, g2, g3);
+
+  if (failcnt != 0)
+    abort ();
+
+  return 0;
+}
Index: gcc/testsuite/gcc.target/powerpc/ppc32-elf-altivec-abi-3.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/ppc32-elf-altivec-abi-3.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/ppc32-elf-altivec-abi-3.c	(revision 0)
@@ -0,0 +1,65 @@
+/* { dg-do run { target { powerpc*-*-linux* && ilp32 } } } */
+/* { dg-options "-w -std=gnu99 -O2 -fno-strict-aliasing -mno-altivec -mabi=no-altivec" } */
+
+/* Check that arguments are passed according to the requested ABI.  */
+
+extern void abort (void);
+int failcnt = 0;
+
+/* Support compiling the test to report individual failures; default is
+   to abort as soon as a check fails.  */
+#ifdef DBG
+#include <stdio.h>
+#define FAILURE { printf ("failed at line %d\n", __LINE__); failcnt++; }
+#else
+#define FAILURE abort ();
+#endif
+
+typedef int __attribute__((vector_size(16))) v4si;
+
+v4si g0 = { 101, 102, 103, 104 };
+v4si g1 = { 201, 202, 203, 204 };
+v4si g2 = { 301, 302, 303, 304 };
+v4si g3 = { 401, 402, 403, 404 };
+
+/* With the non-AltiVec ABI, vector arguments are passed by reference
+   via general registers.  */
+
+typedef struct vpt
+{
+  v4si *gr[4];
+} vec_parms_t;
+
+vec_parms_t gparms;
+
+#define save_vec_parms(lparms)				\
+    asm volatile ("lis 11,gparms@ha\n\t"		\
+                  "la 11,gparms@l(11)\n\t"		\
+                  "st 3,0(11)\n\t"		        \
+	          "st 4,4(11)\n\t"			\
+	          "st 5,8(11)\n\t"			\
+	          "st 6,12(11)\n\t":::"11", "memory");	\
+                  lparms = gparms;
+
+void __attribute__ ((noinline))
+func0 (v4si a0, v4si a1, v4si a2, v4si a3)
+{
+  vec_parms_t lparms;
+  save_vec_parms (lparms);
+
+  if (__builtin_memcmp (lparms.gr[0], &g0, 16) != 0) FAILURE
+  if (__builtin_memcmp (lparms.gr[1], &g1, 16) != 0) FAILURE
+  if (__builtin_memcmp (lparms.gr[2], &g2, 16) != 0) FAILURE
+  if (__builtin_memcmp (lparms.gr[3], &g3, 16) != 0) FAILURE
+}
+
+int
+main (void)
+{
+  func0 (g0, g1, g2, g3);
+
+  if (failcnt != 0)
+    abort ();
+
+  return 0;
+}
Index: gcc/testsuite/gcc.target/powerpc/ppc64-elf-altivec-abi-1.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/ppc64-elf-altivec-abi-1.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/ppc64-elf-altivec-abi-1.c	(revision 0)
@@ -0,0 +1,66 @@
+/* { dg-do run { target { powerpc*-*-linux* && { lp64 && vmx_hw } } } } */
+/* { dg-options "-std=gnu99 -O2 -fno-strict-aliasing -maltivec -mabi=altivec" } */
+
+/* Check that arguments are passed according to the requested ABI.  */
+
+extern void abort (void);
+int failcnt = 0;
+
+/* Support compiling the test to report individual failures; default is
+   to abort as soon as a check fails.  */
+#ifdef DBG
+#include <stdio.h>
+#define FAILURE { printf ("failed at line %d\n", __LINE__); failcnt++; }
+#else
+#define FAILURE abort ();
+#endif
+
+typedef int __attribute__((vector_size(16))) v4si;
+
+v4si g0 = { 101, 102, 103, 104 };
+v4si g1 = { 201, 202, 203, 204 };
+v4si g2 = { 301, 302, 303, 304 };
+v4si g3 = { 401, 402, 403, 404 };
+
+/* With the AltiVec ABI, the first four vector arguments are passed in
+   vector registers 2 through 5.  */
+
+typedef struct vpt
+{
+  v4si vr[4];
+} vec_parms_t;
+
+vec_parms_t gparms;
+
+#define save_vec_parms(lparms)				\
+    asm volatile ("ld 11,gparms@got(2)\n\t"		\
+		  "stvx 2,0,11\n\t"			\
+		  "addi 11,11,16\n\t"			\
+		  "stvx 3,0,11\n\t"			\
+		  "addi 11,11,16\n\t"			\
+		  "stvx 4,0,11\n\t"			\
+		  "addi 11,11,16\n\t"			\
+		  "stvx 5,0,11\n\t":::"11", "memory");	\
+		  lparms = gparms;
+
+void __attribute__ ((noinline))
+func0 (v4si a0, v4si a1, v4si a2, v4si a3)
+{
+  vec_parms_t lparms;
+  save_vec_parms (lparms);
+  if (__builtin_memcmp (&lparms.vr[0], &g0, 16) != 0) FAILURE
+  if (__builtin_memcmp (&lparms.vr[1], &g1, 16) != 0) FAILURE
+  if (__builtin_memcmp (&lparms.vr[2], &g2, 16) != 0) FAILURE
+  if (__builtin_memcmp (&lparms.vr[3], &g3, 16) != 0) FAILURE
+}
+
+int
+main (void)
+{
+  func0 (g0, g1, g2, g3);
+
+  if (failcnt != 0)
+    abort ();
+
+  return 0;
+}



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