public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH rs6000] (small C++ patch) Add intrinsics for the new vec_* specified by the C/C++ Language Extension for the CBEA
@ 2008-10-01  2:01 Andrew Pinski
  2008-10-01  3:00 ` Mark Mitchell
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Andrew Pinski @ 2008-10-01  2:01 UTC (permalink / raw)
  To: GCC Patches, Trevor_Smigiel, David Edelsohn

[-- Attachment #1: Type: text/plain, Size: 2011 bytes --]

Hi,
  This adds the four new intrinsics that are specified by the C/C++
Language Extension for the CBEA; vec_extract, vec_insert, vec_promote,
and vec_splats.  These intrinsics do not correspond to any one
instruction but they are useful for extracting and inserting into a
vector.  They were designed to correspond to the SPU intrinsics that
are name similar.

I implemented so they get translated early on to trees so the tree
level optimizers can maybe do some optimizations on them.  Currently
the tree level optimizers don't do much but later on they could, I
have some ideas of implementing some optimizations for vectors.

I had to add some small support for C++ to support
COMPOUND_LITERAL_EXPR to say it is a lvalue.

OK? Bootstraped and tested on powerpc64-linux-gnu with no regressions.

Thanks,
Andrew Pinski

ChangeLog:
* config/rs6000/rs6000-c.c (altivec_resolve_overloaded_builtin):
Handle ALTIVEC_BUILTIN_VEC_SPLATS, ALTIVEC_BUILTIN_VEC_PROMOTE,
ALTIVEC_BUILTIN_VEC_EXTRACT, and ALTIVEC_BUILTIN_VEC_INSERT specially,
they translate to non builtins.
* config/rs6000/rs6000.c (altivec_init_builtins): Add new variable
opaque_ftype_opaque.  Define builtins __builtin_vec_splats,
__builtin_vec_promote, __builtin_vec_extract, and
__builtin_vec_insert.
* config/rs6000/rs6000.h (enum rs6000_builtins): Add
ALTIVEC_BUILTIN_VEC_EXTRACT, ALTIVEC_BUILTIN_VEC_PROMOTE,
ALTIVEC_BUILTIN_VEC_INSERT, and ALTIVEC_BUILTIN_VEC_SPLATS.
* config/rs6000/altivec.h (vec_extract): Define
(vec_insert): Define.
(vec_splats): Define.
(vec_promote): Define.

cp/ChangeLog:
* tree.c (lvalue_p_1): COMPOUND_LITERAL_EXPR is also an lvalue.

testsuite/ChangeLog:
* gcc.target/powerpc/altivec-cell-1.c: New test.
* gcc.target/powerpc/altivec-cell-2.c: New test.
* gcc.target/powerpc/altivec-cell-3.c: New test.
* gcc.target/powerpc/altivec-cell-4.c: New test.
* g++.dg/ext/altivec-cell-1.C: New test.
* g++.dg/ext/altivec-cell-2.C: New test.
* g++.dg/ext/altivec-cell-3.C: New test.
* g++.dg/ext/altivec-cell-4.C: New test.

[-- Attachment #2: addvec.diff.txt --]
[-- Type: text/plain, Size: 27391 bytes --]

Index: testsuite/gcc.target/powerpc/altivec-cell-1.c
===================================================================
--- testsuite/gcc.target/powerpc/altivec-cell-1.c	(revision 0)
+++ testsuite/gcc.target/powerpc/altivec-cell-1.c	(revision 0)
@@ -0,0 +1,34 @@
+/* { dg-do compile { target powerpc*-*-* } } */
+/* { dg-require-effective-target powerpc_altivec_ok } */
+/* { dg-options "-maltivec" } */
+
+/* Basic test for the new VMX intrinsics.  */
+#include <altivec.h>
+
+int f(vector int a, int b)
+{
+  return vec_extract (a, b);
+}
+short f1(vector short a, int b)
+{
+  return vec_extract (a, b);
+}
+vector short f2(vector short a, int b)
+{
+  return vec_insert (b, a, b);
+}
+vector float f3(vector float a, int b)
+{
+  return vec_insert (b, a, b);
+}
+
+float g(void);
+
+vector float f4(float b, int t)
+{
+  return vec_promote (g(), t);
+}
+vector float f5(float b)
+{
+  return vec_splats (g());
+}
Index: testsuite/gcc.target/powerpc/altivec-cell-5.c
===================================================================
--- testsuite/gcc.target/powerpc/altivec-cell-5.c	(revision 0)
+++ testsuite/gcc.target/powerpc/altivec-cell-5.c	(revision 0)
@@ -0,0 +1,25 @@
+/* { dg-do compile { target powerpc*-*-* } } */
+/* { dg-require-effective-target powerpc_altivec_ok } */
+/* { dg-options "-maltivec" } */
+
+/* Basic test for the new VMX intrinsics and error messages.  */
+#include <altivec.h>
+
+int main(int argc, char **argv)
+{
+vector float t;
+    vec_promote();                      /* { dg-error "vec_promote only accepts 2" } */
+    vec_promote(1.0f);                  /* { dg-error "vec_promote only accepts 2" } */
+    vec_promote(1.0f, 2, 3);            /* { dg-error "vec_promote only accepts 2" } */
+    vec_extract ();                     /* { dg-error "vec_extract only accepts 2" } */
+    vec_extract (t);                    /* { dg-error "vec_extract only accepts 2" } */
+    vec_extract (t, 2);
+    vec_extract (t, 2, 5, 6);           /* { dg-error "vec_extract only accepts 2" } */
+    vec_splats ();                      /* { dg-error "vec_splats only accepts 1" } */
+    vec_splats (t, 3);                  /* { dg-error "vec_splats only accepts 1" } */
+    vec_insert ();                      /* { dg-error "vec_insert only accepts 3" } */
+    vec_insert (t);                     /* { dg-error "vec_insert only accepts 3" } */
+    vec_insert (t, 3);                  /* { dg-error "vec_insert only accepts 3" } */
+    vec_insert (t, 3, 2, 4, 6, 6);      /* { dg-error "vec_insert only accepts 3" } */
+    return 0;
+}  
Index: testsuite/gcc.target/powerpc/altivec-cell-2.c
===================================================================
--- testsuite/gcc.target/powerpc/altivec-cell-2.c	(revision 0)
+++ testsuite/gcc.target/powerpc/altivec-cell-2.c	(revision 0)
@@ -0,0 +1,142 @@
+/* { dg-do run { target powerpc*-*-* } } */
+/* { dg-require-effective-target powerpc_altivec_ok } */
+/* { dg-options "-maltivec" } */
+/* Test the vec_extract VMX intrinsics.  */
+#include <altivec.h>
+#include "altivec_check.h"
+
+extern void abort (void);
+
+vector int a = {0, 1, 2, 3};
+vector short b = {0, 1, 2, 3, 4, 5, 6, 7};
+
+int f(vector int a, int b)
+{
+  return vec_extract (a, b);
+}
+
+int f0 (vector int a)
+{
+  return vec_extract (a, 0);
+}
+int f1 (vector int a)
+{
+  return vec_extract (a, 1);
+}
+int f2 (vector int a)
+{
+  return vec_extract (a, 2);
+}
+int f3 (vector int a)
+{
+  return vec_extract (a, 3);
+}
+int f4 (vector int a)
+{
+  return vec_extract (a, 4);
+}
+
+int g(vector short a, int b)
+{
+  return vec_extract (a, b);
+}
+
+int g0 (vector short a)
+{
+  return vec_extract (a, 0);
+}
+int g1 (vector short a)
+{
+  return vec_extract (a, 1);
+}
+int g2 (vector short a)
+{
+  return vec_extract (a, 2);
+}
+int g3 (vector short a)
+{
+  return vec_extract (a, 3);
+}
+
+int g4 (vector short a)
+{ 
+  return vec_extract (a, 4);
+}
+int g5 (vector short a)
+{ 
+  return vec_extract (a, 5);
+}
+int g6 (vector short a)
+{ 
+  return vec_extract (a, 6);
+}
+int g7 (vector short a)
+{ 
+  return vec_extract (a, 7);
+}
+int g8 (vector short a)
+{ 
+  return vec_extract (a, 8);
+}
+int main1(void) __attribute__((noinline));
+int main1(void)
+{ 
+  int i;
+  /* Check vec_extract with a non constant element numbering */
+  for(i=0;i<10;i++)
+    { 
+      if (f(a, i) != (i&0x3))
+        abort ();
+    }
+  
+  /* Check vec_extract with a constant element numbering */
+  if (f0(a) != 0)
+    abort ();
+  if (f1(a) != 1)
+    abort ();
+  if (f2(a) != 2)
+    abort ();
+  if (f3(a) != 3)
+    abort ();
+  /* Check that vec_extract works with a constant element higher than
+     the number of elements.  */
+  if (f4(a) != 0)
+    abort ();
+
+  /* Check vec_extract with a non constant element numbering */
+  for(i=0;i<10;i++)
+    {
+      if (g(b, i) != (i&0x7))
+        abort ();
+    }
+  
+  /* Check vec_extract with a constant element numbering */
+  if (g0(b) != 0)
+    abort ();
+  if (g1(b) != 1)
+    abort ();
+  if (g2(b) != 2)
+    abort ();
+  if (g3(b) != 3)
+    abort ();
+  if (g4(b) != 4)
+    abort ();
+  if (g5(b) != 5)
+    abort ();
+  if (g6(b) != 6)
+    abort ();
+  if (g7(b) != 7)
+    abort ();
+  /* Check that vec_extract works with a constant element higher than
+     the number of elements.  */
+  if (g8(b) != 0)
+    abort ();
+  
+  return 0;
+}
+
+int main(void)
+{ 
+  altivec_check();  /* Exits if AltiVec not supported */
+  return main1 ();
+}
Index: testsuite/gcc.target/powerpc/altivec-cell-3.c
===================================================================
--- testsuite/gcc.target/powerpc/altivec-cell-3.c	(revision 0)
+++ testsuite/gcc.target/powerpc/altivec-cell-3.c	(revision 0)
@@ -0,0 +1,38 @@
+/* { dg-do run { target powerpc*-*-* } } */
+/* { dg-require-effective-target powerpc_altivec_ok } */
+/* { dg-options "-maltivec" } */
+/* Test the vec_splats and vec_promote VMX intrinsics.  */
+#include <altivec.h>
+#include "altivec_check.h"
+    
+extern void abort (void);
+        
+vector int a = {0, 0, 0, 0};
+int main1(int t) __attribute__((noinline));
+int main1(int t)
+{ 
+  int i;
+  vector int b = vec_splats(0);
+  if (__builtin_memcmp (&a, &b, sizeof(vector int)))
+    abort ();
+  
+  b = vec_splats(t);
+  if (__builtin_memcmp (&a, &b, sizeof(vector int)))
+    abort ();
+  
+  b = vec_promote(0, 1);
+  if (vec_extract (b, 1) != 0)
+    abort ();
+  
+  b = vec_promote(t, t);
+  if (vec_extract (b, t) != 0)
+    abort ();
+  
+  return 0;
+} 
+    
+int main(void)
+{ 
+  altivec_check();  /* Exits if AltiVec not supported */
+  return main1 (0);
+}
Index: testsuite/gcc.target/powerpc/altivec-cell-4.c
===================================================================
--- testsuite/gcc.target/powerpc/altivec-cell-4.c	(revision 0)
+++ testsuite/gcc.target/powerpc/altivec-cell-4.c	(revision 0)
@@ -0,0 +1,43 @@
+/* { dg-do run { target powerpc*-*-* } } */
+/* { dg-require-effective-target powerpc_altivec_ok } */
+/* { dg-options "-maltivec" } */
+
+/* Test the vec_splats and vec_promote VMX intrinsics.  */
+#include <altivec.h>
+#include "altivec_check.h"
+    
+extern void abort (void);
+        
+vector int a[] = {{0, 0, 0, 0}, {1,0,0,0}, {1,2,0,0},{1,2,3,0},{1,2,3,4},{5,2,3,4},{5,6,3,4}};
+vector int c = {0,6,3,4};
+vector int d = {0,0,3,4};
+int main1(int t) __attribute__((noinline));
+int main1(int t)
+{ 
+  int i;
+  vector int b = vec_splats(0);
+  for(i = 0;i<sizeof(a)/sizeof(a[0])-1;i++)
+    { 
+	if (__builtin_memcmp (&b, &a[i], sizeof(vector int)))
+          abort ();
+        b = vec_insert(i+1, b, i);
+    } 
+  if (__builtin_memcmp (&b, &a[i], sizeof(vector int)))
+    abort ();
+  
+  b = vec_insert(0, b, 0);
+  if (__builtin_memcmp (&b, &c, sizeof(vector int)))
+    abort ();
+  
+  b = vec_insert(0, b, 1);
+  if (__builtin_memcmp (&b, &d, sizeof(vector int)))
+    abort ();
+  
+  return 0;
+} 
+  
+int main(void)
+{
+  altivec_check();  /* Exits if AltiVec not supported */
+  return main1 (0);
+}
Index: testsuite/g++.dg/ext/altivec-cell-1.C
===================================================================
--- testsuite/g++.dg/ext/altivec-cell-1.C	(revision 0)
+++ testsuite/g++.dg/ext/altivec-cell-1.C	(revision 0)
@@ -0,0 +1,94 @@
+/* { dg-do compile { target powerpc*-*-* } } */
+/* { dg-require-effective-target powerpc_altivec_ok } */
+/* { dg-options "-maltivec" } */
+
+/* Basic test for the new VMX intrinsics.  */
+#include <altivec.h>
+
+int f(vector int a, int b)
+{
+  return vec_extract (a, b);
+}
+short f1(vector short a, int b)
+{
+  return vec_extract (a, b);
+}
+vector short f2(vector short a, int b)
+{
+  return vec_insert (b, a, b);
+}
+vector float f3(vector float a, int b)
+{
+  return vec_insert (b, a, b);
+}
+
+float g(void);
+
+vector float f4(float b, int t)
+{
+  return vec_promote (g(), t);
+}
+vector float f5(float b)
+{
+  return vec_splats (g());
+}
+
+
+
+
+template <int> 
+int tf(vector int a, int b)
+{
+  return vec_extract (a, b);
+}
+template <int> 
+short tf1(vector short a, int b)
+{
+  return vec_extract (a, b);
+}
+template <int> 
+vector short tf2(vector short a, int b)
+{
+  return vec_insert (b, a, b);
+}
+template <int> 
+vector float tf3(vector float a, int b)
+{
+  return vec_insert (b, a, b);
+}
+
+template <int> 
+vector float tf4(float b, int t)
+{
+  return vec_promote (g(), t);
+}
+template <int> 
+vector float tf5(float b)
+{
+  return vec_splats (g());
+}
+
+int t(vector int a, int b)
+{
+  return tf<1>(a, b);
+}
+short t1(vector short a, int b)
+{
+  return tf1<1>(a, b);
+}
+vector short t2(vector short a, int b)
+{
+  return tf2<1>(a, b);
+}
+vector float t3(vector float a, int b)
+{
+  return tf3<1>(a, b);
+}
+vector float t4(float b, int t)
+{
+  return tf4<1>(b, t);
+}
+vector float t5(float b)
+{
+  return tf5<1>(b);
+}
Index: testsuite/g++.dg/ext/altivec-cell-2.C
===================================================================
--- testsuite/g++.dg/ext/altivec-cell-2.C	(revision 0)
+++ testsuite/g++.dg/ext/altivec-cell-2.C	(revision 0)
@@ -0,0 +1,142 @@
+/* { dg-do run { target powerpc*-*-* } } */
+/* { dg-require-effective-target powerpc_altivec_ok } */
+/* { dg-options "-maltivec" } */
+/* Test the vec_extract VMX intrinsics.  */
+#include <altivec.h>
+#include "altivec_check.h"
+
+extern "C" void abort (void);
+
+vector int a = {0, 1, 2, 3};
+vector short b = {0, 1, 2, 3, 4, 5, 6, 7};
+
+int f(vector int a, int b)
+{
+  return vec_extract (a, b);
+}
+
+int f0 (vector int a)
+{
+  return vec_extract (a, 0);
+}
+int f1 (vector int a)
+{
+  return vec_extract (a, 1);
+}
+int f2 (vector int a)
+{
+  return vec_extract (a, 2);
+}
+int f3 (vector int a)
+{
+  return vec_extract (a, 3);
+}
+int f4 (vector int a)
+{
+  return vec_extract (a, 4);
+}
+
+int g(vector short a, int b)
+{
+  return vec_extract (a, b);
+}
+
+int g0 (vector short a)
+{
+  return vec_extract (a, 0);
+}
+int g1 (vector short a)
+{
+  return vec_extract (a, 1);
+}
+int g2 (vector short a)
+{
+  return vec_extract (a, 2);
+}
+int g3 (vector short a)
+{
+  return vec_extract (a, 3);
+}
+
+int g4 (vector short a)
+{ 
+  return vec_extract (a, 4);
+}
+int g5 (vector short a)
+{ 
+  return vec_extract (a, 5);
+}
+int g6 (vector short a)
+{ 
+  return vec_extract (a, 6);
+}
+int g7 (vector short a)
+{ 
+  return vec_extract (a, 7);
+}
+int g8 (vector short a)
+{ 
+  return vec_extract (a, 8);
+}
+int main1(void) __attribute__((noinline));
+int main1(void)
+{ 
+  int i;
+  /* Check vec_extract with a non constant element numbering */
+  for(i=0;i<10;i++)
+    { 
+      if (f(a, i) != (i&0x3))
+        abort ();
+    }
+  
+  /* Check vec_extract with a constant element numbering */
+  if (f0(a) != 0)
+    abort ();
+  if (f1(a) != 1)
+    abort ();
+  if (f2(a) != 2)
+    abort ();
+  if (f3(a) != 3)
+    abort ();
+  /* Check that vec_extract works with a constant element higher than
+     the number of elements.  */
+  if (f4(a) != 0)
+    abort ();
+
+  /* Check vec_extract with a non constant element numbering */
+  for(i=0;i<10;i++)
+    {
+      if (g(b, i) != (i&0x7))
+        abort ();
+    }
+  
+  /* Check vec_extract with a constant element numbering */
+  if (g0(b) != 0)
+    abort ();
+  if (g1(b) != 1)
+    abort ();
+  if (g2(b) != 2)
+    abort ();
+  if (g3(b) != 3)
+    abort ();
+  if (g4(b) != 4)
+    abort ();
+  if (g5(b) != 5)
+    abort ();
+  if (g6(b) != 6)
+    abort ();
+  if (g7(b) != 7)
+    abort ();
+  /* Check that vec_extract works with a constant element higher than
+     the number of elements.  */
+  if (g8(b) != 0)
+    abort ();
+  
+  return 0;
+}
+
+int main(void)
+{ 
+  altivec_check();  /* Exits if AltiVec not supported */
+  return main1 ();
+}
Index: testsuite/g++.dg/ext/altivec-cell-3.C
===================================================================
--- testsuite/g++.dg/ext/altivec-cell-3.C	(revision 0)
+++ testsuite/g++.dg/ext/altivec-cell-3.C	(revision 0)
@@ -0,0 +1,38 @@
+/* { dg-do run { target powerpc*-*-* } } */
+/* { dg-require-effective-target powerpc_altivec_ok } */
+/* { dg-options "-maltivec" } */
+/* Test the vec_splats and vec_promote VMX intrinsics.  */
+#include <altivec.h>
+#include "altivec_check.h"
+    
+extern "C" void abort (void);
+        
+vector int a = {0, 0, 0, 0};
+int main1(int t) __attribute__((noinline));
+int main1(int t)
+{ 
+  int i;
+  vector int b = vec_splats(0);
+  if (__builtin_memcmp (&a, &b, sizeof(vector int)))
+    abort ();
+  
+  b = vec_splats(t);
+  if (__builtin_memcmp (&a, &b, sizeof(vector int)))
+    abort ();
+  
+  b = vec_promote(0, 1);
+  if (vec_extract (b, 1) != 0)
+    abort ();
+  
+  b = vec_promote(t, t);
+  if (vec_extract (b, t) != 0)
+    abort ();
+  
+  return 0;
+} 
+    
+int main(void)
+{ 
+  altivec_check();  /* Exits if AltiVec not supported */
+  return main1 (0);
+}
Index: testsuite/g++.dg/ext/altivec-cell-4.C
===================================================================
--- testsuite/g++.dg/ext/altivec-cell-4.C	(revision 0)
+++ testsuite/g++.dg/ext/altivec-cell-4.C	(revision 0)
@@ -0,0 +1,43 @@
+/* { dg-do run { target powerpc*-*-* } } */
+/* { dg-require-effective-target powerpc_altivec_ok } */
+/* { dg-options "-maltivec" } */
+
+/* Test the vec_splats and vec_promote VMX intrinsics.  */
+#include <altivec.h>
+#include "altivec_check.h"
+    
+extern "C" void abort (void);
+        
+vector int a[] = {{0, 0, 0, 0}, {1,0,0,0}, {1,2,0,0},{1,2,3,0},{1,2,3,4},{5,2,3,4},{5,6,3,4}};
+vector int c = {0,6,3,4};
+vector int d = {0,0,3,4};
+int main1(int t) __attribute__((noinline));
+int main1(int t)
+{ 
+  int i;
+  vector int b = vec_splats(0);
+  for(i = 0;i<sizeof(a)/sizeof(a[0])-1;i++)
+    { 
+        if (__builtin_memcmp (&b, &a[i], sizeof(vector int)))
+          abort ();
+        b = vec_insert(i+1, b, i);
+    } 
+  if (__builtin_memcmp (&b, &a[i], sizeof(vector int)))
+    abort ();
+  
+  b = vec_insert(0, b, 0);
+  if (__builtin_memcmp (&b, &c, sizeof(vector int)))
+    abort ();
+  
+  b = vec_insert(0, b, 1);
+  if (__builtin_memcmp (&b, &d, sizeof(vector int)))
+    abort ();
+  
+  return 0;
+} 
+  
+int main(void)
+{
+  altivec_check();  /* Exits if AltiVec not supported */
+  return main1 (0);
+}
Index: testsuite/g++.dg/ext/altivec-cell-5.C
===================================================================
--- testsuite/g++.dg/ext/altivec-cell-5.C	(revision 0)
+++ testsuite/g++.dg/ext/altivec-cell-5.C	(revision 0)
@@ -0,0 +1,25 @@
+/* { dg-do compile { target powerpc*-*-* } } */
+/* { dg-require-effective-target powerpc_altivec_ok } */
+/* { dg-options "-maltivec" } */
+
+/* Basic test for the new VMX intrinsics and error messages.  */
+#include <altivec.h>
+
+int main(int argc, char **argv)
+{
+vector float t;
+    vec_promote();                      /* { dg-error "vec_promote only accepts 2" } */
+    vec_promote(1.0f);                  /* { dg-error "vec_promote only accepts 2" } */
+    vec_promote(1.0f, 2, 3);            /* { dg-error "vec_promote only accepts 2" } */
+    vec_extract ();                     /* { dg-error "vec_extract only accepts 2" } */
+    vec_extract (t);                    /* { dg-error "vec_extract only accepts 2" } */
+    vec_extract (t, 2);
+    vec_extract (t, 2, 5, 6);           /* { dg-error "vec_extract only accepts 2" } */
+    vec_splats ();                      /* { dg-error "vec_splats only accepts 1" } */
+    vec_splats (t, 3);                  /* { dg-error "vec_splats only accepts 1" } */
+    vec_insert ();                      /* { dg-error "vec_insert only accepts 3" } */
+    vec_insert (t);                     /* { dg-error "vec_insert only accepts 3" } */
+    vec_insert (t, 3);                  /* { dg-error "vec_insert only accepts 3" } */
+    vec_insert (t, 3, 2, 4, 6, 6);      /* { dg-error "vec_insert only accepts 3" } */
+    return 0;
+}  
Index: cp/tree.c
===================================================================
--- cp/tree.c	(revision 140763)
+++ cp/tree.c	(working copy)
@@ -129,6 +129,7 @@ lvalue_p_1 (const_tree ref,
       return op1_lvalue_kind;
 
     case STRING_CST:
+    case COMPOUND_LITERAL_EXPR:
       return clk_ordinary;
 
     case CONST_DECL:
Index: config/rs6000/rs6000-c.c
===================================================================
--- config/rs6000/rs6000-c.c	(revision 140763)
+++ config/rs6000/rs6000-c.c	(working copy)
@@ -2685,6 +2685,200 @@ altivec_resolve_overloaded_builtin (tree
       || fcode > ALTIVEC_BUILTIN_OVERLOADED_LAST)
     return NULL_TREE;
 
+  /* For no treat vec_splats and vec_promote as the same.  */
+  if (fcode == ALTIVEC_BUILTIN_VEC_SPLATS
+      || fcode == ALTIVEC_BUILTIN_VEC_PROMOTE)
+    {
+      tree type, arg;
+      int size;
+      int i;
+      bool unsigned_p;
+      VEC(constructor_elt,gc) *vec;
+      const char *name = fcode == ALTIVEC_BUILTIN_VEC_SPLATS ? "vec_splats": "vec_promote";
+
+      if (!arglist)
+	{
+	  error ("%s only accepts %d arguments", name, (fcode == ALTIVEC_BUILTIN_VEC_PROMOTE)+1 );
+	  return error_mark_node;
+	}
+      if (fcode == ALTIVEC_BUILTIN_VEC_SPLATS && TREE_CHAIN (arglist))
+	{
+	  error ("%s only accepts 1 argument", name);
+	  return error_mark_node;
+	}
+      if (fcode == ALTIVEC_BUILTIN_VEC_PROMOTE && !TREE_CHAIN (arglist))
+	{
+	  error ("%s only accepts 2 arguments", name);
+	  return error_mark_node;
+	}
+      /* Ignore promote's element argument.  */
+      if (fcode == ALTIVEC_BUILTIN_VEC_PROMOTE
+	  && TREE_CHAIN (TREE_CHAIN (arglist)))
+	{
+	  error ("%s only accepts 2 arguments", name);
+	  return error_mark_node;
+	}
+      if (fcode == ALTIVEC_BUILTIN_VEC_PROMOTE
+	  && !INTEGRAL_TYPE_P (TREE_TYPE (TREE_VALUE (TREE_CHAIN (arglist)))))
+	goto bad;
+
+      arg = TREE_VALUE (arglist);
+      type = TREE_TYPE (arg);
+      if (!SCALAR_FLOAT_TYPE_P (type)
+	  && !INTEGRAL_TYPE_P (type))
+	goto bad;
+      unsigned_p = TYPE_UNSIGNED (type);
+      if (type == long_long_unsigned_type_node
+          || type == long_long_integer_type_node)
+	goto bad;
+      switch (TYPE_MODE (type))
+	{
+	  case SImode:
+	    type = (unsigned_p ? unsigned_V4SI_type_node : V4SI_type_node);
+	    size = 4;
+	    break;
+	  case HImode:
+	    type = (unsigned_p ? unsigned_V8HI_type_node : V8HI_type_node);
+	    size = 8;
+	    break;
+	  case QImode:
+	    type = (unsigned_p ? unsigned_V16QI_type_node : V16QI_type_node);
+	    size = 16;
+	    break;
+	  case SFmode: type = V4SF_type_node; size = 4; break;
+	  default:
+	    goto bad;
+	}
+      arg = save_expr (fold_convert (TREE_TYPE (type), arg));
+      vec = VEC_alloc (constructor_elt, gc, size);
+      for(i = 0; i < size; i++)
+	{
+	  constructor_elt *elt;
+
+	  elt = VEC_quick_push (constructor_elt, vec, NULL);
+	  elt->index = NULL_TREE;
+	  elt->value = arg;
+	}
+	return build_constructor (type, vec);
+    }
+
+  /* For now don't optimize vec_extract, that well,
+     except when the element is the 0th element. */
+  if (fcode == ALTIVEC_BUILTIN_VEC_EXTRACT)
+    {
+      tree arg1;
+      tree arg1_type;
+      tree arg2;
+      tree arg1_inner_type;
+      tree decl, stmt;
+      tree innerptrtype;
+
+      /* No second argument. */
+      if (!arglist || !TREE_CHAIN (arglist)
+	  || TREE_CHAIN (TREE_CHAIN (arglist)))
+	{
+	  error ("vec_extract only accepts 2 arguments");
+	  return error_mark_node;
+	}
+
+      arg2 = TREE_VALUE (TREE_CHAIN (arglist));
+      arg1 = TREE_VALUE (arglist);
+      arg1_type = TREE_TYPE (arg1);
+
+      if (TREE_CODE (arg1_type) != VECTOR_TYPE)
+	goto bad; 
+      if (!INTEGRAL_TYPE_P (TREE_TYPE (arg2)))
+	goto bad; 
+      /* Build *(((arg1_inner_type*)&(vector type){arg1})+arg2). */
+      arg1_inner_type = TREE_TYPE (arg1_type);
+      arg2 = build_binary_op (input_location, BIT_AND_EXPR, arg2,
+			      build_int_cst (TREE_TYPE (arg2),
+					     TYPE_VECTOR_SUBPARTS (arg1_type)
+					     - 1), 0);
+      decl = build_decl (VAR_DECL, NULL_TREE, arg1_type);
+      DECL_EXTERNAL (decl) = 0;
+      TREE_PUBLIC (decl) = 0;
+      DECL_CONTEXT (decl) = current_function_decl;
+      TREE_USED (decl) = 1;
+      TREE_TYPE (decl) = arg1_type;
+      TREE_READONLY (decl) = TYPE_READONLY (arg1_type);
+      DECL_INITIAL (decl) = arg1;
+      stmt = build1 (DECL_EXPR, arg1_type, decl);
+      TREE_ADDRESSABLE (decl) = 1;
+      SET_EXPR_LOCATION (stmt, input_location);
+      stmt = build1 (COMPOUND_LITERAL_EXPR, arg1_type, stmt);
+
+      innerptrtype = build_pointer_type (arg1_inner_type);
+
+      stmt = build_unary_op (ADDR_EXPR, stmt, 0);
+      stmt = convert (innerptrtype, stmt);
+      stmt = build_binary_op (input_location, PLUS_EXPR, stmt, arg2, 1);
+      stmt = build_indirect_ref (stmt, NULL, input_location);
+
+      return stmt;
+    }
+
+  /* For now don't optimize vec_insert, that well,
+     except when the element is the 0th element. */
+  if (fcode == ALTIVEC_BUILTIN_VEC_INSERT)
+    {
+      tree arg0;
+      tree arg1;
+      tree arg2;
+      tree arg1_type;
+      tree arg1_inner_type;
+      tree decl, stmt;
+      tree innerptrtype;
+      
+      /* No second or third arguments. */
+      if (!arglist || !TREE_CHAIN (arglist)
+	  || !TREE_CHAIN (TREE_CHAIN (arglist))
+	  || TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))))
+	{
+	  error ("vec_insert only accepts 3 arguments");
+	  return error_mark_node;
+	}
+
+      arg0 = TREE_VALUE (arglist);
+      arg1 = TREE_VALUE (TREE_CHAIN (arglist));
+      arg1_type = TREE_TYPE (arg1);
+      arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
+
+      if (TREE_CODE (arg1_type) != VECTOR_TYPE)
+	goto bad; 
+      if (!INTEGRAL_TYPE_P (TREE_TYPE (arg2)))
+	goto bad; 
+      /* Build *(((arg1_inner_type*)&(vector type){arg1})+arg2) = arg0. */
+      arg1_inner_type = TREE_TYPE (arg1_type);
+      arg2 = build_binary_op (input_location, BIT_AND_EXPR, arg2,
+			      build_int_cst (TREE_TYPE (arg2),
+					     TYPE_VECTOR_SUBPARTS (arg1_type)
+					     - 1), 0);
+      decl = build_decl (VAR_DECL, NULL_TREE, arg1_type);
+      DECL_EXTERNAL (decl) = 0;
+      TREE_PUBLIC (decl) = 0;
+      DECL_CONTEXT (decl) = current_function_decl;
+      TREE_USED (decl) = 1;
+      TREE_TYPE (decl) = arg1_type;
+      TREE_READONLY (decl) = TYPE_READONLY (arg1_type);
+      DECL_INITIAL (decl) = arg1;
+      stmt = build1 (DECL_EXPR, arg1_type, decl);
+      TREE_ADDRESSABLE (decl) = 1;
+      SET_EXPR_LOCATION (stmt, input_location);
+      stmt = build1 (COMPOUND_LITERAL_EXPR, arg1_type, stmt);
+
+      innerptrtype = build_pointer_type (arg1_inner_type);
+
+      stmt = build_unary_op (ADDR_EXPR, stmt, 0);
+      stmt = convert (innerptrtype, stmt);
+      stmt = build_binary_op (input_location, PLUS_EXPR, stmt, arg2, 1);
+      stmt = build_indirect_ref (stmt, NULL, input_location);
+      stmt = build2 (MODIFY_EXPR, TREE_TYPE (stmt), stmt,
+		     convert (TREE_TYPE (stmt), arg0));
+      stmt = build2 (COMPOUND_EXPR, arg1_type, stmt, decl);
+      return stmt;
+    }
+
   for (n = 0;
        !VOID_TYPE_P (TREE_VALUE (fnargs)) && arglist;
        fnargs = TREE_CHAIN (fnargs), arglist = TREE_CHAIN (arglist), n++)
Index: config/rs6000/rs6000.c
===================================================================
--- config/rs6000/rs6000.c	(revision 140763)
+++ config/rs6000/rs6000.c	(working copy)
@@ -9764,7 +9764,9 @@ altivec_init_builtins (void)
   tree int_ftype_opaque
     = build_function_type_list (integer_type_node,
 				opaque_V4SI_type_node, NULL_TREE);
-
+  tree opaque_ftype_opaque
+    = build_function_type (integer_type_node,
+				NULL_TREE);
   tree opaque_ftype_opaque_int
     = build_function_type_list (opaque_V4SI_type_node,
 				opaque_V4SI_type_node, integer_type_node, NULL_TREE);
@@ -9911,9 +9913,13 @@ altivec_init_builtins (void)
   def_builtin (MASK_ALTIVEC, "__builtin_vec_stvehx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEHX);
 
   def_builtin (MASK_ALTIVEC, "__builtin_vec_step", int_ftype_opaque, ALTIVEC_BUILTIN_VEC_STEP);
+  def_builtin (MASK_ALTIVEC, "__builtin_vec_splats", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_SPLATS);
+  def_builtin (MASK_ALTIVEC, "__builtin_vec_promote", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_PROMOTE);
 
   def_builtin (MASK_ALTIVEC, "__builtin_vec_sld", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_SLD);
   def_builtin (MASK_ALTIVEC, "__builtin_vec_splat", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_SPLAT);
+  def_builtin (MASK_ALTIVEC, "__builtin_vec_extract", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_EXTRACT);
+  def_builtin (MASK_ALTIVEC, "__builtin_vec_insert", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_INSERT);
   def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltw", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTW);
   def_builtin (MASK_ALTIVEC, "__builtin_vec_vsplth", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTH);
   def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltb", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTB);
Index: config/rs6000/rs6000.h
===================================================================
--- config/rs6000/rs6000.h	(revision 140763)
+++ config/rs6000/rs6000.h	(working copy)
@@ -2595,6 +2595,7 @@ enum rs6000_builtins
   ALTIVEC_BUILTIN_VEC_AND,
   ALTIVEC_BUILTIN_VEC_ANDC,
   ALTIVEC_BUILTIN_VEC_AVG,
+  ALTIVEC_BUILTIN_VEC_EXTRACT,
   ALTIVEC_BUILTIN_VEC_CEIL,
   ALTIVEC_BUILTIN_VEC_CMPB,
   ALTIVEC_BUILTIN_VEC_CMPEQ,
@@ -2796,7 +2797,10 @@ enum rs6000_builtins
   ALTIVEC_BUILTIN_VEC_VUPKLSH,
   ALTIVEC_BUILTIN_VEC_XOR,
   ALTIVEC_BUILTIN_VEC_STEP,
-  ALTIVEC_BUILTIN_OVERLOADED_LAST = ALTIVEC_BUILTIN_VEC_STEP,
+  ALTIVEC_BUILTIN_VEC_PROMOTE,
+  ALTIVEC_BUILTIN_VEC_INSERT,
+  ALTIVEC_BUILTIN_VEC_SPLATS,
+  ALTIVEC_BUILTIN_OVERLOADED_LAST = ALTIVEC_BUILTIN_VEC_SPLATS,
 
   /* SPE builtins.  */
   SPE_BUILTIN_EVADDW,
Index: config/rs6000/altivec.h
===================================================================
--- config/rs6000/altivec.h	(revision 140763)
+++ config/rs6000/altivec.h	(working copy)
@@ -290,6 +290,11 @@
 #define vec_vsubuws __builtin_vec_vsubuws
 #define vec_xor __builtin_vec_xor
 
+#define vec_extract __builtin_vec_extract
+#define vec_insert __builtin_vec_insert
+#define vec_splats __builtin_vec_splats
+#define vec_promote __builtin_vec_promote
+
 /* Predicates.
    For C++, we use templates in order to allow non-parenthesized arguments.
    For C, instead, we use macros since non-parenthesized arguments were

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH rs6000] (small C++ patch) Add intrinsics for the new vec_*  specified by the C/C++ Language Extension for the CBEA
  2008-10-01  2:01 [PATCH rs6000] (small C++ patch) Add intrinsics for the new vec_* specified by the C/C++ Language Extension for the CBEA Andrew Pinski
@ 2008-10-01  3:00 ` Mark Mitchell
  2008-10-01 17:31   ` Andrew_Pinski
  2008-10-01 14:14 ` Paolo Bonzini
  2008-10-01 14:35 ` David Edelsohn
  2 siblings, 1 reply; 6+ messages in thread
From: Mark Mitchell @ 2008-10-01  3:00 UTC (permalink / raw)
  To: Andrew Pinski; +Cc: GCC Patches, Trevor_Smigiel, David Edelsohn

Andrew Pinski wrote:

> I had to add some small support for C++ to support
> COMPOUND_LITERAL_EXPR to say it is a lvalue.
> cp/ChangeLog:
> * tree.c (lvalue_p_1): COMPOUND_LITERAL_EXPR is also an lvalue.

The C++ change is OK if compound literals are lvalues in C.  I'm
slightly surprised that they are, but if so, it makes sense to treat
them the same way in C++.

-- 
Mark Mitchell
CodeSourcery
mark@codesourcery.com
(650) 331-3385 x713

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH rs6000] (small C++ patch) Add intrinsics for the new vec_*  specified by the C/C++ Language Extension for the CBEA
  2008-10-01  2:01 [PATCH rs6000] (small C++ patch) Add intrinsics for the new vec_* specified by the C/C++ Language Extension for the CBEA Andrew Pinski
  2008-10-01  3:00 ` Mark Mitchell
@ 2008-10-01 14:14 ` Paolo Bonzini
  2008-10-01 14:35 ` David Edelsohn
  2 siblings, 0 replies; 6+ messages in thread
From: Paolo Bonzini @ 2008-10-01 14:14 UTC (permalink / raw)
  To: Andrew Pinski; +Cc: GCC Patches, Trevor_Smigiel, David Edelsohn

Andrew Pinski wrote:
> Hi,
>   This adds the four new intrinsics that are specified by the C/C++
> Language Extension for the CBEA; vec_extract, vec_insert, vec_promote,
> and vec_splats.  These intrinsics do not correspond to any one
> instruction but they are useful for extracting and inserting into a
> vector.  They were designed to correspond to the SPU intrinsics that
> are name similar.
> 
> I implemented so they get translated early on to trees so the tree
> level optimizers can maybe do some optimizations on them.  Currently
> the tree level optimizers don't do much but later on they could, I
> have some ideas of implementing some optimizations for vectors.
> 
> I had to add some small support for C++ to support
> COMPOUND_LITERAL_EXPR to say it is a lvalue.
> 
> OK? Bootstraped and tested on powerpc64-linux-gnu with no regressions.

It would be cool to provide these on every machine.  It is 4.5 material
of course though.  Can you create a PR and CC me?

Thanks,

Paolo

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH rs6000] (small C++ patch) Add intrinsics for the new vec_* specified by the C/C++ Language Extension for the CBEA
  2008-10-01  2:01 [PATCH rs6000] (small C++ patch) Add intrinsics for the new vec_* specified by the C/C++ Language Extension for the CBEA Andrew Pinski
  2008-10-01  3:00 ` Mark Mitchell
  2008-10-01 14:14 ` Paolo Bonzini
@ 2008-10-01 14:35 ` David Edelsohn
  2 siblings, 0 replies; 6+ messages in thread
From: David Edelsohn @ 2008-10-01 14:35 UTC (permalink / raw)
  To: Andrew Pinski; +Cc: GCC Patches, Trevor_Smigiel

* config/rs6000/rs6000-c.c (altivec_resolve_overloaded_builtin):
Handle ALTIVEC_BUILTIN_VEC_SPLATS, ALTIVEC_BUILTIN_VEC_PROMOTE,
ALTIVEC_BUILTIN_VEC_EXTRACT, and ALTIVEC_BUILTIN_VEC_INSERT specially,
they translate to non builtins.
* config/rs6000/rs6000.c (altivec_init_builtins): Add new variable
opaque_ftype_opaque.  Define builtins __builtin_vec_splats,
__builtin_vec_promote, __builtin_vec_extract, and
__builtin_vec_insert.
* config/rs6000/rs6000.h (enum rs6000_builtins): Add
ALTIVEC_BUILTIN_VEC_EXTRACT, ALTIVEC_BUILTIN_VEC_PROMOTE,
ALTIVEC_BUILTIN_VEC_INSERT, and ALTIVEC_BUILTIN_VEC_SPLATS.
* config/rs6000/altivec.h (vec_extract): Define
(vec_insert): Define.
(vec_splats): Define.
(vec_promote): Define.

cp/ChangeLog:
* tree.c (lvalue_p_1): COMPOUND_LITERAL_EXPR is also an lvalue.

testsuite/ChangeLog:
* gcc.target/powerpc/altivec-cell-1.c: New test.
* gcc.target/powerpc/altivec-cell-2.c: New test.
* gcc.target/powerpc/altivec-cell-3.c: New test.
* gcc.target/powerpc/altivec-cell-4.c: New test.
* g++.dg/ext/altivec-cell-1.C: New test.
* g++.dg/ext/altivec-cell-2.C: New test.
* g++.dg/ext/altivec-cell-3.C: New test.
* g++.dg/ext/altivec-cell-4.C: New test.

Okay.

Index: config/rs6000/rs6000-c.c
===================================================================
--- config/rs6000/rs6000-c.c	(revision 140763)
+++ config/rs6000/rs6000-c.c	(working copy)
@@ -2685,6 +2685,200 @@ altivec_resolve_overloaded_builtin (tree
       || fcode > ALTIVEC_BUILTIN_OVERLOADED_LAST)
     return NULL_TREE;

+  /* For no treat vec_splats and vec_promote as the same.  */

Spelling: "For now"?

Thanks, David

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH rs6000] (small C++ patch) Add intrinsics for the new vec_* specified  by the C/C++ Language Extension for the CBEA
  2008-10-01  3:00 ` Mark Mitchell
@ 2008-10-01 17:31   ` Andrew_Pinski
  2008-10-01 18:38     ` Mark Mitchell
  0 siblings, 1 reply; 6+ messages in thread
From: Andrew_Pinski @ 2008-10-01 17:31 UTC (permalink / raw)
  To: Mark Mitchell; +Cc: David Edelsohn, GCC Patches, Trevor_Smigiel

Mark Mitchell <mark@codesourcery.com> wrote on 09/30/2008 07:59:33 PM:

> Andrew Pinski wrote:
> 
> > I had to add some small support for C++ to support
> > COMPOUND_LITERAL_EXPR to say it is a lvalue.
> > cp/ChangeLog:
> > * tree.c (lvalue_p_1): COMPOUND_LITERAL_EXPR is also an lvalue.
> 
> The C++ change is OK if compound literals are lvalues in C.  I'm
> slightly surprised that they are, but if so, it makes sense to treat
> them the same way in C++.

I wonder why you are surprised they are lvalues for C, they were designed 
(as I understand it) to provide an anonymous variable.

Anyways here is the quote from the C99 standard which says they are 
lvalues, C99 6.5.2.5/5:
If the type name specifies an array of unknown size, the size is 
determined by the initializer list as specified in 6.7.8, and the type of 
the compound literal is that of the completed array type. Otherwise (when 
the type name specifies an object type), the type of the compound literal 
is that specified by the type name. In either case, the result is an 
lvalue.

Thanks,
Andrew Pinski

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH rs6000] (small C++ patch) Add intrinsics for the new vec_*  specified by the C/C++ Language Extension for the CBEA
  2008-10-01 17:31   ` Andrew_Pinski
@ 2008-10-01 18:38     ` Mark Mitchell
  0 siblings, 0 replies; 6+ messages in thread
From: Mark Mitchell @ 2008-10-01 18:38 UTC (permalink / raw)
  To: Andrew_Pinski; +Cc: David Edelsohn, GCC Patches, Trevor_Smigiel

Andrew_Pinski@PlayStation.Sony.Com wrote:
> Mark Mitchell <mark@codesourcery.com> wrote on 09/30/2008 07:59:33 PM:
> 
>> Andrew Pinski wrote:
>>
>>> I had to add some small support for C++ to support
>>> COMPOUND_LITERAL_EXPR to say it is a lvalue.
>>> cp/ChangeLog:
>>> * tree.c (lvalue_p_1): COMPOUND_LITERAL_EXPR is also an lvalue.
>> The C++ change is OK if compound literals are lvalues in C.  I'm
>> slightly surprised that they are, but if so, it makes sense to treat
>> them the same way in C++.
> 
> I wonder why you are surprised they are lvalues for C, they were designed 
> (as I understand it) to provide an anonymous variable.

I just wasn't sure they were lvalues; there are situations where a
structure is not an lvalue.  I guess you can just color me dumb.

Thanks for the reference; in that case, the C++ patch is OK.

-- 
Mark Mitchell
CodeSourcery
mark@codesourcery.com
(650) 331-3385 x713

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2008-10-01 17:39 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-10-01  2:01 [PATCH rs6000] (small C++ patch) Add intrinsics for the new vec_* specified by the C/C++ Language Extension for the CBEA Andrew Pinski
2008-10-01  3:00 ` Mark Mitchell
2008-10-01 17:31   ` Andrew_Pinski
2008-10-01 18:38     ` Mark Mitchell
2008-10-01 14:14 ` Paolo Bonzini
2008-10-01 14:35 ` David Edelsohn

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).