This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] re-enable -mabi=no-altivec on powerpc64-linux
- From: Janis Johnson <janis187 at us dot ibm dot com>
- To: gcc-patches at gcc dot gnu dot org, amodra at bigpond dot net dot au
- Date: Mon, 04 Feb 2008 10:30:21 -0800
- Subject: [PATCH] re-enable -mabi=no-altivec on powerpc64-linux
- Reply-to: janis187 at us dot ibm dot com
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;
+}