[PATCH], PR 60672, Add xxsldwi/xxpermdi builtins to altivec.h

Michael Meissner meissner@linux.vnet.ibm.com
Thu Mar 27 17:51:00 GMT 2014


One of the users within IBM noticed that we did not provide builtins for the
XXSLDWI (vector shift left) and XXPERMDI (permute 64-bit values to make 128-bit
vector) instructions.  It turns out, we had provided these builtins, but we had
not documented them, nor did we add them to altivec.h with a user visible name.

When I added these builtins several years ago, I did not understand the naming
scheme for overloaded functions (i.e. __builtin_vec_<xxx> in the compiler, and
vec_<xxx> in altivec.h), so I added the overloaded builtin as
__builtin_vsx_xxsldwi and __builtin_vsx_xxpermdi.  This patch does not fix the
historical accident, but instead just uses the name that is created.

I can change the name, and provide a #define for somebody using the old name,
or we can just leave the compiler generating the old name, and altivec.h just
has to adapt.

I have done bootstraps and make check with no regressions.  Are these patches
ok to apply to 4.9 and backported to 4.8 when the rest of the changes go in?

[gcc]
2014-03-27  Michael Meissner  <meissner@linux.vnet.ibm.com>

	PR target/60672
	* config/rs6000/altivec.h (vec_xxsldwi): Add missing define to
	enable use of xxsldwi and xxpermdi builtin functions.
	(vec_xxpermdi): Likewise.

	* doc/extend.texi (PowerPC AltiVec/VSX Built-in Functions):
	Document use of vec_xxsldwi and vec_xxpermdi builtins.

[gcc/testsuite]
2014-03-27  Michael Meissner  <meissner@linux.vnet.ibm.com>

	PR target/60672
	* gcc.target/powerpc/pr60676.c: New file, make sure xxsldwi and
	xxpermdi builtins are supported.


-- 
Michael Meissner, IBM
IBM, M/S 2506R, 550 King Street, Littleton, MA 01460-6245, USA
email: meissner@linux.vnet.ibm.com, phone: +1 (978) 899-4797
-------------- next part --------------
Index: gcc/config/rs6000/altivec.h
===================================================================
--- gcc/config/rs6000/altivec.h	(revision 208851)
+++ gcc/config/rs6000/altivec.h	(working copy)
@@ -319,6 +319,11 @@
 #define vec_sqrt __builtin_vec_sqrt
 #define vec_vsx_ld __builtin_vec_vsx_ld
 #define vec_vsx_st __builtin_vec_vsx_st
+
+/* Note, xxsldi and xxpermdi were added as __builtin_vsx_<xxx> functions
+   instead of __builtin_vec_<xxx>  */
+#define vec_xxsldwi __builtin_vsx_xxsldwi
+#define vec_xxpermdi __builtin_vsx_xxpermdi
 #endif
 
 #ifdef _ARCH_PWR8
Index: gcc/doc/extend.texi
===================================================================
--- gcc/doc/extend.texi	(revision 208851)
+++ gcc/doc/extend.texi	(working copy)
@@ -14859,6 +14859,35 @@ void vec_vsx_st (vector unsigned char, i
 void vec_vsx_st (vector bool char, int, vector bool char *);
 void vec_vsx_st (vector bool char, int, unsigned char *);
 void vec_vsx_st (vector bool char, int, signed char *);
+
+vector double vec_xxpermdi (vector double, vector double, int);
+vector float vec_xxpermdi (vector float, vector float, int);
+vector long long vec_xxpermdi (vector long long, vector long long, int);
+vector unsigned long long vec_xxpermdi (vector unsigned long long,
+                                        vector unsigned long long, int);
+vector int vec_xxpermdi (vector int, vector int, int);
+vector unsigned int vec_xxpermdi (vector unsigned int,
+                                  vector unsigned int, int);
+vector short vec_xxpermdi (vector short, vector short, int);
+vector unsigned short vec_xxpermdi (vector unsigned short,
+                                    vector unsigned short, int);
+vector signed char vec_xxpermdi (vector signed char, vector signed char, int);
+vector unsigned char vec_xxpermdi (vector unsigned char,
+                                   vector unsigned char, int);
+
+vector double vec_xxsldi (vector double, vector double, int);
+vector float vec_xxsldi (vector float, vector float, int);
+vector long long vec_xxsldi (vector long long, vector long long, int);
+vector unsigned long long vec_xxsldi (vector unsigned long long,
+                                      vector unsigned long long, int);
+vector int vec_xxsldi (vector int, vector int, int);
+vector unsigned int vec_xxsldi (vector unsigned int, vector unsigned int, int);
+vector short vec_xxsldi (vector short, vector short, int);
+vector unsigned short vec_xxsldi (vector unsigned short,
+                                  vector unsigned short, int);
+vector signed char vec_xxsldi (vector signed char, vector signed char, int);
+vector unsigned char vec_xxsldi (vector unsigned char,
+                                 vector unsigned char, int);
 @end smallexample
 
 Note that the @samp{vec_ld} and @samp{vec_st} built-in functions always
Index: gcc/testsuite/gcc.target/powerpc/pr60676.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/pr60676.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/pr60676.c	(revision 0)
@@ -0,0 +1,128 @@
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
+/* { dg-require-effective-target powerpc_vsx_ok } */
+/* { dg-options "-O3 -mcpu=power7" } */
+/* { dg-final { scan-assembler "xxsldwi"  } } */
+/* { dg-final { scan-assembler "xxpermdi" } } */
+
+#include <altivec.h>
+
+vector double
+v2df_shift (vector double a, vector double b)
+{
+  return vec_xxsldwi (a, b, 1);
+}
+
+vector float
+v4sf_shift (vector float a, vector float b)
+{
+  return vec_xxsldwi (a, b, 1);
+}
+
+vector long long
+v2di_shift (vector long long a, vector long long b)
+{
+  return vec_xxsldwi (a, b, 1);
+}
+
+vector unsigned long long
+v2diu_shift (vector unsigned long long a, vector unsigned long long b)
+{
+  return vec_xxsldwi (a, b, 1);
+}
+
+vector int
+v4si_shift (vector int a, vector int b)
+{
+  return vec_xxsldwi (a, b, 1);
+}
+
+vector unsigned int
+v4siu_shift (vector unsigned int a, vector unsigned int b)
+{
+  return vec_xxsldwi (a, b, 1);
+}
+
+vector short
+v8hi_shift (vector short a, vector short b)
+{
+  return vec_xxsldwi (a, b, 1);
+}
+
+vector unsigned short
+v8hiu_shift (vector unsigned short a, vector unsigned short b)
+{
+  return vec_xxsldwi (a, b, 1);
+}
+
+vector signed char
+v16qi_shift (vector signed char a, vector signed char b)
+{
+  return vec_xxsldwi (a, b, 1);
+}
+
+vector unsigned char
+v16qiu_shift (vector unsigned char a, vector unsigned char b)
+{
+  return vec_xxsldwi (a, b, 1);
+}
+
+vector double
+v2df_permute (vector double a, vector double b)
+{
+  return vec_xxpermdi (a, b, 1);
+}
+
+vector float
+v4sf_permute (vector float a, vector float b)
+{
+  return vec_xxpermdi (a, b, 1);
+}
+
+vector long long
+v2di_permute (vector long long a, vector long long b)
+{
+  return vec_xxpermdi (a, b, 1);
+}
+
+vector unsigned long long
+v2diu_permute (vector unsigned long long a, vector unsigned long long b)
+{
+  return vec_xxpermdi (a, b, 1);
+}
+
+vector int
+v4si_permute (vector int a, vector int b)
+{
+  return vec_xxpermdi (a, b, 1);
+}
+
+vector unsigned int
+v4siu_permute (vector unsigned int a, vector unsigned int b)
+{
+  return vec_xxpermdi (a, b, 1);
+}
+
+vector short
+v8hi_permute (vector short a, vector short b)
+{
+  return vec_xxpermdi (a, b, 1);
+}
+
+vector unsigned short
+v8hiu_permute (vector unsigned short a, vector unsigned short b)
+{
+  return vec_xxpermdi (a, b, 1);
+}
+
+vector signed char
+v16qi_permute (vector signed char a, vector signed char b)
+{
+  return vec_xxpermdi (a, b, 1);
+}
+
+vector unsigned char
+v16qiu_permute (vector unsigned char a, vector unsigned char b)
+{
+  return vec_xxpermdi (a, b, 1);
+}


More information about the Gcc-patches mailing list