This patch provides the tests for the new vector instructions added in patches
3 and 4.  In addition, it provides the target support for power8 systems.

Is this patch acceptable to be checked in once the previous 4 patches have been
applied?

2013-05-21  Michael Meissner  <meiss...@linux.vnet.ibm.com>

        * gcc.target/powerpc/p8vector-builtin-1.c: New test to test
        power8 builtin functions.
        * gcc/testsuite/gcc.target/powerpc/p8vector-builtin-2.c: Likewise.
        * gcc/testsuite/gcc.target/powerpc/p8vector-builtin-3.c: Likewise.
        * gcc/testsuite/gcc.target/powerpc/p8vector-builtin-4.c: Likewise.
        * gcc/testsuite/gcc.target/powerpc/p8vector-builtin-5.c: Likewise.
        * gcc/testsuite/gcc.target/powerpc/p8vector-builtin-6.c: Likewise.
        * gcc/testsuite/gcc.target/powerpc/p8vector-builtin-7.c: Likewise.
        * gcc/testsuite/gcc.target/powerpc/p8vector-vectorize-1.c: New
        tests to test power8 auto-vectorization.
        * gcc/testsuite/gcc.target/powerpc/p8vector-vectorize-2.c: Likewise.
        * gcc/testsuite/gcc.target/powerpc/p8vector-vectorize-3.c: Likewise.
        * gcc/testsuite/gcc.target/powerpc/p8vector-vectorize-4.c: Likewise.
        * gcc/testsuite/gcc.target/powerpc/p8vector-vectorize-5.c: Likewise.

        * lib/target-supports.exp (check_p8vector_hw_available): New
        function, check if we are running on a power8.
        (check_effective_target_powerpc_p8vector_ok): New function, check
        if target can compile for power8.
        (is-effective-target): Add power8 support.
        (is-effective-target-keyword): Likewise.
        (check_vect_support_and_set_flags): Likewise.

-- 
Michael Meissner, IBM
IBM, M/S 2506R, 550 King Street, Littleton, MA 01460, USA
email: meiss...@linux.vnet.ibm.com, phone: +1 (978) 899-4797
Index: gcc/testsuite/gcc.target/powerpc/p8vector-builtin-1.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/p8vector-builtin-1.c       (revision 0)
+++ gcc/testsuite/gcc.target/powerpc/p8vector-builtin-1.c       (revision 0)
@@ -0,0 +1,65 @@
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
+/* { dg-require-effective-target powerpc_p8vector_ok } */
+/* { dg-options "-mcpu=power8 -O2 -ftree-vectorize -fvect-cost-model 
-fno-unroll-loops -fno-unroll-all-loops" } */
+
+#ifndef TYPE
+#define TYPE long long
+#endif
+
+#ifndef SIGN_TYPE
+#define SIGN_TYPE signed TYPE
+#endif
+
+#ifndef UNS_TYPE
+#define UNS_TYPE unsigned TYPE
+#endif
+
+typedef vector SIGN_TYPE v_sign;
+typedef vector UNS_TYPE  v_uns;
+
+v_sign sign_add (v_sign a, v_sign b)
+{
+  return a + b;
+}
+
+v_sign sign_sub (v_sign a, v_sign b)
+{
+  return a - b;
+}
+
+v_sign sign_shift_left (v_sign a, v_sign b)
+{
+  return a << b;
+}
+
+v_sign sign_shift_right (v_sign a, v_sign b)
+{
+  return a >> b;
+}
+
+v_uns uns_add (v_uns a, v_uns b)
+{
+  return a + b;
+}
+
+v_uns uns_sub (v_uns a, v_uns b)
+{
+  return a - b;
+}
+
+v_uns uns_shift_left (v_uns a, v_uns b)
+{
+  return a << b;
+}
+
+v_uns uns_shift_right (v_uns a, v_uns b)
+{
+  return a >> b;
+}
+
+/* { dg-final { scan-assembler-times "vaddudm" 2 } } */
+/* { dg-final { scan-assembler-times "vsubudm" 2 } } */
+/* { dg-final { scan-assembler-times "vsld"    2 } } */
+/* { dg-final { scan-assembler-times "vsrad"   1 } } */
+/* { dg-final { scan-assembler-times "vsrd"    1 } } */
Index: gcc/testsuite/gcc.target/powerpc/p8vector-vectorize-1.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/p8vector-vectorize-1.c     (revision 0)
+++ gcc/testsuite/gcc.target/powerpc/p8vector-vectorize-1.c     (revision 0)
@@ -0,0 +1,200 @@
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
+/* { dg-require-effective-target powerpc_p8vector_ok } */
+/* { dg-options "-mcpu=power8 -O2 -ftree-vectorize -fvect-cost-model 
-fno-unroll-loops -fno-unroll-all-loops" } */
+
+#ifndef SIZE
+#define SIZE 1024
+#endif
+
+#ifndef ALIGN
+#define ALIGN 32
+#endif
+
+#ifndef TYPE
+#define TYPE long long
+#endif
+
+#ifndef SIGN_TYPE
+#define SIGN_TYPE signed TYPE
+#endif
+
+#ifndef UNS_TYPE
+#define UNS_TYPE unsigned TYPE
+#endif
+
+#define ALIGN_ATTR __attribute__((__aligned__(ALIGN)))
+
+SIGN_TYPE      sa[SIZE] ALIGN_ATTR;
+SIGN_TYPE      sb[SIZE] ALIGN_ATTR;
+SIGN_TYPE      sc[SIZE] ALIGN_ATTR;
+
+UNS_TYPE       ua[SIZE] ALIGN_ATTR;
+UNS_TYPE       ub[SIZE] ALIGN_ATTR;
+UNS_TYPE       uc[SIZE] ALIGN_ATTR;
+
+void
+sign_add (void)
+{
+  unsigned long i;
+
+  for (i = 0; i < SIZE; i++)
+    sa[i] = sb[i] + sc[i];
+}
+
+void
+sign_sub (void)
+{
+  unsigned long i;
+
+  for (i = 0; i < SIZE; i++)
+    sa[i] = sb[i] - sc[i];
+}
+
+void
+sign_shift_left (void)
+{
+  unsigned long i;
+
+  for (i = 0; i < SIZE; i++)
+    sa[i] = sb[i] << sc[i];
+}
+
+void
+sign_shift_right (void)
+{
+  unsigned long i;
+
+  for (i = 0; i < SIZE; i++)
+    sa[i] = sb[i] >> sc[i];
+}
+
+void
+sign_max (void)
+{
+  unsigned long i;
+
+  for (i = 0; i < SIZE; i++)
+    sa[i] = (sb[i] > sc[i]) ? sb[i] : sc[i];
+}
+
+void
+sign_min (void)
+{
+  unsigned long i;
+
+  for (i = 0; i < SIZE; i++)
+    sa[i] = (sb[i] < sc[i]) ? sb[i] : sc[i];
+}
+
+void
+sign_abs (void)
+{
+  unsigned long i;
+
+  for (i = 0; i < SIZE; i++)
+    sa[i] = (sb[i] < 0) ? -sb[i] : sb[i];      /* xor, vsubudm, vmaxsd.  */
+}
+
+void
+sign_eq (SIGN_TYPE val1, SIGN_TYPE val2)
+{
+  unsigned long i;
+
+  for (i = 0; i < SIZE; i++)
+    sa[i] = (sb[i] == sc[i]) ? val1 : val2;
+}
+
+void
+sign_lt (SIGN_TYPE val1, SIGN_TYPE val2)
+{
+  unsigned long i;
+
+  for (i = 0; i < SIZE; i++)
+    sa[i] = (sb[i] < sc[i]) ? val1 : val2;
+}
+
+void
+uns_add (void)
+{
+  unsigned long i;
+
+  for (i = 0; i < SIZE; i++)
+    ua[i] = ub[i] + uc[i];
+}
+
+void
+uns_sub (void)
+{
+  unsigned long i;
+
+  for (i = 0; i < SIZE; i++)
+    ua[i] = ub[i] - uc[i];
+}
+
+void
+uns_shift_left (void)
+{
+  unsigned long i;
+
+  for (i = 0; i < SIZE; i++)
+    ua[i] = ub[i] << uc[i];
+}
+
+void
+uns_shift_right (void)
+{
+  unsigned long i;
+
+  for (i = 0; i < SIZE; i++)
+    ua[i] = ub[i] >> uc[i];
+}
+
+void
+uns_max (void)
+{
+  unsigned long i;
+
+  for (i = 0; i < SIZE; i++)
+    ua[i] = (ub[i] > uc[i]) ? ub[i] : uc[i];
+}
+
+void
+uns_min (void)
+{
+  unsigned long i;
+
+  for (i = 0; i < SIZE; i++)
+    ua[i] = (ub[i] < uc[i]) ? ub[i] : uc[i];
+}
+
+void
+uns_eq (UNS_TYPE val1, UNS_TYPE val2)
+{
+  unsigned long i;
+
+  for (i = 0; i < SIZE; i++)
+    ua[i] = (ub[i] == uc[i]) ? val1 : val2;
+}
+
+void
+uns_lt (UNS_TYPE val1, UNS_TYPE val2)
+{
+  unsigned long i;
+
+  for (i = 0; i < SIZE; i++)
+    ua[i] = (ub[i] < uc[i]) ? val1 : val2;
+}
+
+/* { dg-final { scan-assembler-times "\[\t \]vaddudm\[\t \]"  2 } } */
+/* { dg-final { scan-assembler-times "\[\t \]vsubudm\[\t \]"  3 } } */
+/* { dg-final { scan-assembler-times "\[\t \]vmaxsd\[\t \]"   2 } } */
+/* { dg-final { scan-assembler-times "\[\t \]vmaxud\[\t \]"   1 } } */
+/* { dg-final { scan-assembler-times "\[\t \]vminsd\[\t \]"   1 } } */
+/* { dg-final { scan-assembler-times "\[\t \]vminud\[\t \]"   1 } } */
+/* { dg-final { scan-assembler-times "\[\t \]vsld\[\t \]"     2 } } */
+/* { dg-final { scan-assembler-times "\[\t \]vsrad\[\t \]"    1 } } */
+/* { dg-final { scan-assembler-times "\[\t \]vsrd\[\t \]"     1 } } */
+/* { dg-final { scan-assembler-times "\[\t \]vcmpequd\[\t \]" 2 } } */
+/* { dg-final { scan-assembler-times "\[\t \]vcmpgtsd\[\t \]" 1 } } */
+/* { dg-final { scan-assembler-times "\[\t \]vcmpgtud\[\t \]" 1 } } */
Index: gcc/testsuite/gcc.target/powerpc/p8vector-builtin-2.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/p8vector-builtin-2.c       (revision 0)
+++ gcc/testsuite/gcc.target/powerpc/p8vector-builtin-2.c       (revision 0)
@@ -0,0 +1,204 @@
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
+/* { dg-require-effective-target powerpc_p8vector_ok } */
+/* { dg-options "-mcpu=power8 -O2 -ftree-vectorize -fvect-cost-model 
-fno-unroll-loops -fno-unroll-all-loops" } */
+
+#include <altivec.h>
+
+typedef vector long long               v_sign;
+typedef vector unsigned long long      v_uns;
+typedef vector bool long long          v_bool;
+
+v_sign sign_add_1 (v_sign a, v_sign b)
+{
+  return __builtin_altivec_vaddudm (a, b);
+}
+
+v_sign sign_add_2 (v_sign a, v_sign b)
+{
+  return vec_add (a, b);
+}
+
+v_sign sign_add_3 (v_sign a, v_sign b)
+{
+  return vec_vaddudm (a, b);
+}
+
+v_sign sign_sub_1 (v_sign a, v_sign b)
+{
+  return __builtin_altivec_vsubudm (a, b);
+}
+
+v_sign sign_sub_2 (v_sign a, v_sign b)
+{
+  return vec_sub (a, b);
+}
+
+
+v_sign sign_sub_3 (v_sign a, v_sign b)
+{
+  return vec_vsubudm (a, b);
+}
+
+v_sign sign_min_1 (v_sign a, v_sign b)
+{
+  return __builtin_altivec_vminsd (a, b);
+}
+
+v_sign sign_min_2 (v_sign a, v_sign b)
+{
+  return vec_min (a, b);
+}
+
+v_sign sign_min_3 (v_sign a, v_sign b)
+{
+  return vec_vminsd (a, b);
+}
+
+v_sign sign_max_1 (v_sign a, v_sign b)
+{
+  return __builtin_altivec_vmaxsd (a, b);
+}
+
+v_sign sign_max_2 (v_sign a, v_sign b)
+{
+  return vec_max (a, b);
+}
+
+v_sign sign_max_3 (v_sign a, v_sign b)
+{
+  return vec_vmaxsd (a, b);
+}
+
+v_sign sign_abs (v_sign a)
+{
+  return vec_abs (a);          /* xor, vsubudm, vmaxsd.  */
+}
+
+v_bool sign_eq (v_sign a, v_sign b)
+{
+  return vec_cmpeq (a, b);
+}
+
+v_bool sign_lt (v_sign a, v_sign b)
+{
+  return vec_cmplt (a, b);
+}
+
+v_uns uns_add_2 (v_uns a, v_uns b)
+{
+  return vec_add (a, b);
+}
+
+v_uns uns_add_3 (v_uns a, v_uns b)
+{
+  return vec_vaddudm (a, b);
+}
+
+v_uns uns_sub_2 (v_uns a, v_uns b)
+{
+  return vec_sub (a, b);
+}
+
+v_uns uns_sub_3 (v_uns a, v_uns b)
+{
+  return vec_vsubudm (a, b);
+}
+
+v_uns uns_min_2 (v_uns a, v_uns b)
+{
+  return vec_min (a, b);
+}
+
+v_uns uns_min_3 (v_uns a, v_uns b)
+{
+  return vec_vminud (a, b);
+}
+
+v_uns uns_max_2 (v_uns a, v_uns b)
+{
+  return vec_max (a, b);
+}
+
+v_uns uns_max_3 (v_uns a, v_uns b)
+{
+  return vec_vmaxud (a, b);
+}
+
+v_bool uns_eq (v_uns a, v_uns b)
+{
+  return vec_cmpeq (a, b);
+}
+
+v_bool uns_lt (v_uns a, v_uns b)
+{
+  return vec_cmplt (a, b);
+}
+
+v_sign sign_rl_1 (v_sign a, v_sign b)
+{
+  return __builtin_altivec_vrld (a, b);
+}
+
+v_sign sign_rl_2 (v_sign a, v_uns b)
+{
+  return vec_rl (a, b);
+}
+
+v_uns uns_rl_2 (v_uns a, v_uns b)
+{
+  return vec_rl (a, b);
+}
+
+v_sign sign_sl_1 (v_sign a, v_sign b)
+{
+  return __builtin_altivec_vsld (a, b);
+}
+
+v_sign sign_sl_2 (v_sign a, v_uns b)
+{
+  return vec_sl (a, b);
+}
+
+v_sign sign_sl_3 (v_sign a, v_uns b)
+{
+  return vec_vsld (a, b);
+}
+
+v_uns uns_sl_2 (v_uns a, v_uns b)
+{
+  return vec_sl (a, b);
+}
+
+v_uns uns_sl_3 (v_uns a, v_uns b)
+{
+  return vec_vsld (a, b);
+}
+
+v_sign sign_sra_1 (v_sign a, v_sign b)
+{
+  return __builtin_altivec_vsrad (a, b);
+}
+
+v_sign sign_sra_2 (v_sign a, v_uns b)
+{
+  return vec_sra (a, b);
+}
+
+v_sign sign_sra_3 (v_sign a, v_uns b)
+{
+  return vec_vsrad (a, b);
+}
+
+/* { dg-final { scan-assembler-times "vaddudm"         5 } } */
+/* { dg-final { scan-assembler-times "vsubudm"         6 } } */
+/* { dg-final { scan-assembler-times "vmaxsd"          4 } } */
+/* { dg-final { scan-assembler-times "vminsd"          3 } } */
+/* { dg-final { scan-assembler-times "vmaxud"          2 } } */
+/* { dg-final { scan-assembler-times "vminud"          2 } } */
+/* { dg-final { scan-assembler-times "vcmpequd" 2 } } */
+/* { dg-final { scan-assembler-times "vcmpgtsd" 1 } } */
+/* { dg-final { scan-assembler-times "vcmpgtud" 1 } } */
+/* { dg-final { scan-assembler-times "vrld"     3 } } */
+/* { dg-final { scan-assembler-times "vsld"     5 } } */
+/* { dg-final { scan-assembler-times "vsrad"    3 } } */
Index: gcc/testsuite/gcc.target/powerpc/p8vector-vectorize-2.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/p8vector-vectorize-2.c     (revision 0)
+++ gcc/testsuite/gcc.target/powerpc/p8vector-vectorize-2.c     (revision 0)
@@ -0,0 +1,30 @@
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
+/* { dg-require-effective-target powerpc_p8vector_ok } */
+/* { dg-options "-mcpu=power8 -O2 -ftree-vectorize -fvect-cost-model" } */
+
+#include <stddef.h>
+
+#ifndef SIZE
+#define SIZE 1024
+#endif
+
+#ifndef ALIGN
+#define ALIGN 32
+#endif
+
+#define ALIGN_ATTR __attribute__((__aligned__(ALIGN)))
+
+long long sign_ll[SIZE]        ALIGN_ATTR;
+int      sign_i [SIZE] ALIGN_ATTR;
+
+void copy_int_to_long_long (void)
+{
+  size_t i;
+
+  for (i = 0; i < SIZE; i++)
+    sign_ll[i] = sign_i[i];
+}
+
+/* { dg-final { scan-assembler "vupkhsw" } } */
+/* { dg-final { scan-assembler "vupklsw" } } */
Index: gcc/testsuite/gcc.target/powerpc/p8vector-builtin-3.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/p8vector-builtin-3.c       (revision 0)
+++ gcc/testsuite/gcc.target/powerpc/p8vector-builtin-3.c       (revision 0)
@@ -0,0 +1,104 @@
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
+/* { dg-require-effective-target powerpc_p8vector_ok } */
+/* { dg-options "-mcpu=power8 -O3 -ftree-vectorize -fvect-cost-model" } */
+
+#include <altivec.h>
+
+typedef vector long long               vll_sign;
+typedef vector unsigned long long      vll_uns;
+typedef vector bool long long          vll_bool;
+
+typedef vector int                     vi_sign;
+typedef vector unsigned int            vi_uns;
+typedef vector bool int                        vi_bool;
+
+typedef vector short                   vs_sign;
+typedef vector unsigned short          vs_uns;
+typedef vector bool short              vs_bool;
+
+typedef vector signed char             vc_sign;
+typedef vector unsigned char           vc_uns;
+typedef vector bool char               vc_bool;
+
+
+vi_sign vi_pack_1 (vll_sign a, vll_sign b)
+{
+  return __builtin_altivec_vpkudum (a, b);
+}
+
+vi_sign vi_pack_2 (vll_sign a, vll_sign b)
+{
+  return vec_pack (a, b);
+}
+
+vi_sign vi_pack_3 (vll_sign a, vll_sign b)
+{
+  return vec_vpkudum (a, b);
+}
+
+vs_sign vs_pack_1 (vi_sign a, vi_sign b)
+{
+  return __builtin_altivec_vpkuwum (a, b);
+}
+
+vs_sign vs_pack_2 (vi_sign a, vi_sign b)
+{
+  return vec_pack (a, b);
+}
+
+vs_sign vs_pack_3 (vi_sign a, vi_sign b)
+{
+  return vec_vpkuwum (a, b);
+}
+
+vc_sign vc_pack_1 (vs_sign a, vs_sign b)
+{
+  return __builtin_altivec_vpkuhum (a, b);
+}
+
+vc_sign vc_pack_2 (vs_sign a, vs_sign b)
+{
+  return vec_pack (a, b);
+}
+
+vc_sign vc_pack_3 (vs_sign a, vs_sign b)
+{
+  return vec_vpkuhum (a, b);
+}
+
+vll_sign vll_unpack_hi_1 (vi_sign a)
+{
+  return __builtin_altivec_vupkhsw (a);
+}
+
+vll_sign vll_unpack_hi_2 (vi_sign a)
+{
+  return vec_unpackh (a);
+}
+
+vll_sign vll_unpack_hi_3 (vi_sign a)
+{
+  return __builtin_vec_vupkhsw (a);
+}
+
+vll_sign vll_unpack_lo_1 (vi_sign a)
+{
+  return vec_vupklsw (a);
+}
+
+vll_sign vll_unpack_lo_2 (vi_sign a)
+{
+  return vec_unpackl (a);
+}
+
+vll_sign vll_unpack_lo_3 (vi_sign a)
+{
+  return vec_vupklsw (a);
+}
+
+/* { dg-final { scan-assembler-times "vpkudum" 3 } } */
+/* { dg-final { scan-assembler-times "vpkuwum" 3 } } */
+/* { dg-final { scan-assembler-times "vpkuhum" 3 } } */
+/* { dg-final { scan-assembler-times "vupklsw" 3 } } */
+/* { dg-final { scan-assembler-times "vupkhsw" 3 } } */
Index: gcc/testsuite/gcc.target/powerpc/p8vector-vectorize-3.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/p8vector-vectorize-3.c     (revision 0)
+++ gcc/testsuite/gcc.target/powerpc/p8vector-vectorize-3.c     (revision 0)
@@ -0,0 +1,29 @@
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
+/* { dg-require-effective-target powerpc_p8vector_ok } */
+/* { dg-options "-mcpu=power8 -O2 -ftree-vectorize -fvect-cost-model" } */
+
+#include <stddef.h>
+
+#ifndef SIZE
+#define SIZE 1024
+#endif
+
+#ifndef ALIGN
+#define ALIGN 32
+#endif
+
+#define ALIGN_ATTR __attribute__((__aligned__(ALIGN)))
+
+long long sign_ll[SIZE]        ALIGN_ATTR;
+int      sign_i [SIZE] ALIGN_ATTR;
+
+void copy_long_long_to_int (void)
+{
+  size_t i;
+
+  for (i = 0; i < SIZE; i++)
+    sign_i[i] = sign_ll[i];
+}
+
+/* { dg-final { scan-assembler "vpkudum" } } */
Index: gcc/testsuite/gcc.target/powerpc/p8vector-builtin-4.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/p8vector-builtin-4.c       (revision 0)
+++ gcc/testsuite/gcc.target/powerpc/p8vector-builtin-4.c       (revision 0)
@@ -0,0 +1,249 @@
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
+/* { dg-require-effective-target powerpc_p8vector_ok } */
+/* { dg-options "-mcpu=power8 -O3 -ftree-vectorize -fvect-cost-model" } */
+
+#include <altivec.h>
+
+typedef vector long long               vll_sign;
+typedef vector unsigned long long      vll_uns;
+typedef vector bool long long          vll_bool;
+
+typedef vector int                     vi_sign;
+typedef vector unsigned int            vi_uns;
+typedef vector bool int                        vi_bool;
+
+typedef vector short                   vs_sign;
+typedef vector unsigned short          vs_uns;
+typedef vector bool short              vs_bool;
+
+typedef vector signed char             vc_sign;
+typedef vector unsigned char           vc_uns;
+typedef vector bool char               vc_bool;
+
+vll_sign vll_clz_1 (vll_sign a)
+{
+  return __builtin_altivec_vclzd (a);
+}
+
+vll_sign vll_clz_2 (vll_sign a)
+{
+  return vec_vclz (a);
+}
+
+vll_sign vll_clz_3 (vll_sign a)
+{
+  return vec_vclzd (a);
+}
+
+vll_uns vll_clz_4 (vll_uns a)
+{
+  return vec_vclz (a);
+}
+
+vll_uns vll_clz_5 (vll_uns a)
+{
+  return vec_vclzd (a);
+}
+
+vi_sign vi_clz_1 (vi_sign a)
+{
+  return __builtin_altivec_vclzw (a);
+}
+
+vi_sign vi_clz_2 (vi_sign a)
+{
+  return vec_vclz (a);
+}
+
+vi_sign vi_clz_3 (vi_sign a)
+{
+  return vec_vclzw (a);
+}
+
+vi_uns vi_clz_4 (vi_uns a)
+{
+  return vec_vclz (a);
+}
+
+vi_uns vi_clz_5 (vi_uns a)
+{
+  return vec_vclzw (a);
+}
+
+vs_sign vs_clz_1 (vs_sign a)
+{
+  return __builtin_altivec_vclzh (a);
+}
+
+vs_sign vs_clz_2 (vs_sign a)
+{
+  return vec_vclz (a);
+}
+
+vs_sign vs_clz_3 (vs_sign a)
+{
+  return vec_vclzh (a);
+}
+
+vs_uns vs_clz_4 (vs_uns a)
+{
+  return vec_vclz (a);
+}
+
+vs_uns vs_clz_5 (vs_uns a)
+{
+  return vec_vclzh (a);
+}
+
+vc_sign vc_clz_1 (vc_sign a)
+{
+  return __builtin_altivec_vclzb (a);
+}
+
+vc_sign vc_clz_2 (vc_sign a)
+{
+  return vec_vclz (a);
+}
+
+vc_sign vc_clz_3 (vc_sign a)
+{
+  return vec_vclzb (a);
+}
+
+vc_uns vc_clz_4 (vc_uns a)
+{
+  return vec_vclz (a);
+}
+
+vc_uns vc_clz_5 (vc_uns a)
+{
+  return vec_vclzb (a);
+}
+
+vll_sign vll_popcnt_1 (vll_sign a)
+{
+  return __builtin_altivec_vpopcntd (a);
+}
+
+vll_sign vll_popcnt_2 (vll_sign a)
+{
+  return vec_vpopcnt (a);
+}
+
+vll_sign vll_popcnt_3 (vll_sign a)
+{
+  return vec_vpopcntd (a);
+}
+
+vll_uns vll_popcnt_4 (vll_uns a)
+{
+  return vec_vpopcnt (a);
+}
+
+vll_uns vll_popcnt_5 (vll_uns a)
+{
+  return vec_vpopcntd (a);
+}
+
+vi_sign vi_popcnt_1 (vi_sign a)
+{
+  return __builtin_altivec_vpopcntw (a);
+}
+
+vi_sign vi_popcnt_2 (vi_sign a)
+{
+  return vec_vpopcnt (a);
+}
+
+vi_sign vi_popcnt_3 (vi_sign a)
+{
+  return vec_vpopcntw (a);
+}
+
+vi_uns vi_popcnt_4 (vi_uns a)
+{
+  return vec_vpopcnt (a);
+}
+
+vi_uns vi_popcnt_5 (vi_uns a)
+{
+  return vec_vpopcntw (a);
+}
+
+vs_sign vs_popcnt_1 (vs_sign a)
+{
+  return __builtin_altivec_vpopcnth (a);
+}
+
+vs_sign vs_popcnt_2 (vs_sign a)
+{
+  return vec_vpopcnt (a);
+}
+
+vs_sign vs_popcnt_3 (vs_sign a)
+{
+  return vec_vpopcnth (a);
+}
+
+vs_uns vs_popcnt_4 (vs_uns a)
+{
+  return vec_vpopcnt (a);
+}
+
+vs_uns vs_popcnt_5 (vs_uns a)
+{
+  return vec_vpopcnth (a);
+}
+
+vc_sign vc_popcnt_1 (vc_sign a)
+{
+  return __builtin_altivec_vpopcntb (a);
+}
+
+vc_sign vc_popcnt_2 (vc_sign a)
+{
+  return vec_vpopcnt (a);
+}
+
+vc_sign vc_popcnt_3 (vc_sign a)
+{
+  return vec_vpopcntb (a);
+}
+
+vc_uns vc_popcnt_4 (vc_uns a)
+{
+  return vec_vpopcnt (a);
+}
+
+vc_uns vc_popcnt_5 (vc_uns a)
+{
+  return vec_vpopcntb (a);
+}
+
+vc_uns vc_gbb_1 (vc_uns a)
+{
+  return __builtin_altivec_vgbbd (a);
+}
+
+vc_sign vc_gbb_2 (vc_sign a)
+{
+  return vec_vgbbd (a);
+}
+
+vc_uns vc_gbb_3 (vc_uns a)
+{
+  return vec_vgbbd (a);
+}
+
+/* { dg-final { scan-assembler-times "vclzd"   5 } } */
+/* { dg-final { scan-assembler-times "vclzw"   5 } } */
+/* { dg-final { scan-assembler-times "vclzh"   5 } } */
+/* { dg-final { scan-assembler-times "vclzb"   5 } } */
+
+/* { dg-final { scan-assembler-times "vpopcntd" 5 } } */
+/* { dg-final { scan-assembler-times "vpopcntw" 5 } } */
+/* { dg-final { scan-assembler-times "vpopcnth" 5 } } */
+/* { dg-final { scan-assembler-times "vpopcntb" 5 } } */
+
+/* { dg-final { scan-assembler-times "vgbbd"    3 } } */
Index: gcc/testsuite/gcc.target/powerpc/p8vector-vectorize-4.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/p8vector-vectorize-4.c     (revision 0)
+++ gcc/testsuite/gcc.target/powerpc/p8vector-vectorize-4.c     (revision 0)
@@ -0,0 +1,69 @@
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
+/* { dg-require-effective-target powerpc_p8vector_ok } */
+/* { dg-options "-mcpu=power8 -O2 -ftree-vectorize -fvect-cost-model 
-fno-unroll-loops -fno-unroll-all-loops" } */
+
+#ifndef SIZE
+#define SIZE 1024
+#endif
+
+#ifndef ALIGN
+#define ALIGN 32
+#endif
+
+#define ALIGN_ATTR __attribute__((__aligned__(ALIGN)))
+
+#define DO_BUILTIN(PREFIX, TYPE, CLZ, POPCNT)                          \
+TYPE PREFIX ## _a[SIZE] ALIGN_ATTR;                                    \
+TYPE PREFIX ## _b[SIZE] ALIGN_ATTR;                                    \
+                                                                       \
+void                                                                   \
+PREFIX ## _clz (void)                                                  \
+{                                                                      \
+  unsigned long i;                                                     \
+                                                                       \
+  for (i = 0; i < SIZE; i++)                                           \
+    PREFIX ## _a[i] = CLZ (PREFIX ## _b[i]);                           \
+}                                                                      \
+                                                                       \
+void                                                                   \
+PREFIX ## _popcnt (void)                                               \
+{                                                                      \
+  unsigned long i;                                                     \
+                                                                       \
+  for (i = 0; i < SIZE; i++)                                           \
+    PREFIX ## _a[i] = POPCNT (PREFIX ## _b[i]);                                
\
+}
+
+#if !defined(DO_LONG_LONG) && !defined(DO_LONG) && !defined(DO_INT) && 
!defined(DO_SHORT) && !defined(DO_CHAR)
+#define DO_INT 1
+#endif
+
+#if DO_LONG_LONG
+/* At the moment, only int is auto vectorized.  */
+DO_BUILTIN (sll, long long,            __builtin_clzll, __builtin_popcountll)
+DO_BUILTIN (ull, unsigned long long,   __builtin_clzll, __builtin_popcountll)
+#endif
+
+#if defined(_ARCH_PPC64) && DO_LONG
+DO_BUILTIN (sl,  long,                 __builtin_clzl,  __builtin_popcountl)
+DO_BUILTIN (ul,  unsigned long,                __builtin_clzl,  
__builtin_popcountl)
+#endif
+
+#if DO_INT
+DO_BUILTIN (si,  int,                  __builtin_clz,   __builtin_popcount)
+DO_BUILTIN (ui,  unsigned int,         __builtin_clz,   __builtin_popcount)
+#endif
+
+#if DO_SHORT
+DO_BUILTIN (ss,  short,                        __builtin_clz,   
__builtin_popcount)
+DO_BUILTIN (us,  unsigned short,       __builtin_clz,   __builtin_popcount)
+#endif
+
+#if DO_CHAR
+DO_BUILTIN (sc,  signed char,          __builtin_clz,   __builtin_popcount)
+DO_BUILTIN (uc,  unsigned char,                __builtin_clz,   
__builtin_popcount)
+#endif
+
+/* { dg-final { scan-assembler-times "vclzw"     2 } } */
+/* { dg-final { scan-assembler-times "vpopcntw"  2 } } */
Index: gcc/testsuite/gcc.target/powerpc/p8vector-builtin-5.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/p8vector-builtin-5.c       (revision 0)
+++ gcc/testsuite/gcc.target/powerpc/p8vector-builtin-5.c       (revision 0)
@@ -0,0 +1,105 @@
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
+/* { dg-require-effective-target powerpc_p8vector_ok } */
+/* { dg-options "-mcpu=power8 -O2 -ftree-vectorize -fvect-cost-model 
-fno-unroll-loops -fno-unroll-all-loops" } */
+
+#include <altivec.h>
+
+#ifndef SIZE
+#define SIZE 1024
+#endif
+
+#ifndef ALIGN
+#define ALIGN 32
+#endif
+
+#ifndef ATTR_ALIGN
+#define ATTR_ALIGN __attribute__((__aligned__(ALIGN)))
+#endif
+
+#define DOIT(TYPE, PREFIX)                                             \
+TYPE PREFIX ## _eqv_builtin (TYPE a, TYPE b)                           \
+{                                                                      \
+  return vec_eqv (a, b);                                               \
+}                                                                      \
+                                                                       \
+TYPE PREFIX ## _eqv_arith (TYPE a, TYPE b)                             \
+{                                                                      \
+  return ~(a ^ b);                                                     \
+}                                                                      \
+                                                                       \
+TYPE PREFIX ## _nand_builtin (TYPE a, TYPE b)                          \
+{                                                                      \
+  return vec_nand (a, b);                                              \
+}                                                                      \
+                                                                       \
+TYPE PREFIX ## _nand_arith1 (TYPE a, TYPE b)                           \
+{                                                                      \
+  return ~(a & b);                                                     \
+}                                                                      \
+                                                                       \
+TYPE PREFIX ## _nand_arith2 (TYPE a, TYPE b)                           \
+{                                                                      \
+  return (~a) | (~b);                                                  \
+}                                                                      \
+                                                                       \
+TYPE PREFIX ## _orc_builtin (TYPE a, TYPE b)                           \
+{                                                                      \
+  return vec_orc (a, b);                                               \
+}                                                                      \
+                                                                       \
+TYPE PREFIX ## _orc_arith1 (TYPE a, TYPE b)                            \
+{                                                                      \
+  return (~ a) | b;                                                    \
+}                                                                      \
+                                                                       \
+TYPE PREFIX ## _orc_arith2 (TYPE a, TYPE b)                            \
+{                                                                      \
+  return a | (~ b);                                                    \
+}
+
+#define DOIT_FLOAT(TYPE, PREFIX)                                       \
+TYPE PREFIX ## _eqv_builtin (TYPE a, TYPE b)                           \
+{                                                                      \
+  return vec_eqv (a, b);                                               \
+}                                                                      \
+                                                                       \
+TYPE PREFIX ## _nand_builtin (TYPE a, TYPE b)                          \
+{                                                                      \
+  return vec_nand (a, b);                                              \
+}                                                                      \
+                                                                       \
+TYPE PREFIX ## _orc_builtin (TYPE a, TYPE b)                           \
+{                                                                      \
+  return vec_orc (a, b);                                               \
+}
+
+typedef vector signed char             sign_char_vec;
+typedef vector short                   sign_short_vec;
+typedef vector int                     sign_int_vec;
+typedef vector long long               sign_llong_vec;
+
+typedef vector unsigned char           uns_char_vec;
+typedef vector unsigned short          uns_short_vec;
+typedef vector unsigned int            uns_int_vec;
+typedef vector unsigned long long      uns_llong_vec;
+
+typedef vector float                   float_vec;
+typedef vector double                  double_vec;
+
+DOIT(sign_char_vec,    sign_char)
+DOIT(sign_short_vec,   sign_short)
+DOIT(sign_int_vec,     sign_int)
+DOIT(sign_llong_vec,   sign_llong)
+
+DOIT(uns_char_vec,     uns_char)
+DOIT(uns_short_vec,    uns_short)
+DOIT(uns_int_vec,      uns_int)
+DOIT(uns_llong_vec,    uns_llong)
+
+DOIT_FLOAT(float_vec,  float)
+DOIT_FLOAT(double_vec, double)
+
+/* { dg-final { scan-assembler-times "xxleqv"  18 } } */
+/* { dg-final { scan-assembler-times "xxlnand" 26 } } */
+/* { dg-final { scan-assembler-times "xxlorc"  26 } } */
Index: gcc/testsuite/gcc.target/powerpc/p8vector-vectorize-5.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/p8vector-vectorize-5.c     (revision 0)
+++ gcc/testsuite/gcc.target/powerpc/p8vector-vectorize-5.c     (revision 0)
@@ -0,0 +1,87 @@
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
+/* { dg-require-effective-target powerpc_p8vector_ok } */
+/* { dg-options "-mcpu=power8 -O2 -ftree-vectorize -fvect-cost-model 
-fno-unroll-loops -fno-unroll-all-loops" } */
+
+#ifndef SIZE
+#define SIZE 1024
+#endif
+
+#ifndef ALIGN
+#define ALIGN 32
+#endif
+
+#ifndef ATTR_ALIGN
+#define ATTR_ALIGN __attribute__((__aligned__(ALIGN)))
+#endif
+
+#ifndef TYPE
+#define TYPE unsigned int
+#endif
+
+TYPE in1  [SIZE] ATTR_ALIGN;
+TYPE in2  [SIZE] ATTR_ALIGN;
+TYPE eqv  [SIZE] ATTR_ALIGN;
+TYPE nand1[SIZE] ATTR_ALIGN;
+TYPE nand2[SIZE] ATTR_ALIGN;
+TYPE orc1 [SIZE] ATTR_ALIGN;
+TYPE orc2 [SIZE] ATTR_ALIGN;
+
+void
+do_eqv (void)
+{
+  unsigned long i;
+
+  for (i = 0; i < SIZE; i++)
+    {
+      eqv[i] = ~(in1[i] ^ in2[i]);
+    }
+}
+
+void
+do_nand1 (void)
+{
+  unsigned long i;
+
+  for (i = 0; i < SIZE; i++)
+    {
+      nand1[i] = ~(in1[i] & in2[i]);
+    }
+}
+
+void
+do_nand2 (void)
+{
+  unsigned long i;
+
+  for (i = 0; i < SIZE; i++)
+    {
+      nand2[i] = (~in1[i]) | (~in2[i]);
+    }
+}
+
+void
+do_orc1 (void)
+{
+  unsigned long i;
+
+  for (i = 0; i < SIZE; i++)
+    {
+      orc1[i] = (~in1[i]) | in2[i];
+    }
+}
+
+void
+do_orc2 (void)
+{
+  unsigned long i;
+
+  for (i = 0; i < SIZE; i++)
+    {
+      orc1[i] = in1[i] | (~in2[i]);
+    }
+}
+
+/* { dg-final { scan-assembler-times "xxleqv"  1 } } */
+/* { dg-final { scan-assembler-times "xxlnand" 2 } } */
+/* { dg-final { scan-assembler-times "xxlorc"  2 } } */
Index: gcc/testsuite/gcc.target/powerpc/p8vector-builtin-6.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/p8vector-builtin-6.c       (revision 0)
+++ gcc/testsuite/gcc.target/powerpc/p8vector-builtin-6.c       (revision 0)
@@ -0,0 +1,10 @@
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
+/* { dg-require-effective-target powerpc_p8vector_ok } */
+/* { dg-options "-mcpu=power8 -O2" } */
+
+vector float dbl_to_float_p8 (double x) { return __builtin_vsx_xscvdpspn (x); }
+double float_to_dbl_p8 (vector float x) { return __builtin_vsx_xscvspdpn (x); }
+
+/* { dg-final { scan-assembler "xscvdpspn" } } */
+/* { dg-final { scan-assembler "xscvspdpn" } } */
Index: gcc/testsuite/gcc.target/powerpc/p8vector-builtin-7.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/p8vector-builtin-7.c       (revision 0)
+++ gcc/testsuite/gcc.target/powerpc/p8vector-builtin-7.c       (revision 0)
@@ -0,0 +1,32 @@
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
+/* { dg-require-effective-target powerpc_p8vector_ok } */
+/* { dg-options "-mcpu=power8 -O2" } */
+
+#include <altivec.h>
+
+typedef vector int             v_sign;
+typedef vector unsigned int    v_uns;
+
+v_sign even_sign (v_sign a, v_sign b)
+{
+  return vec_vmrgew (a, b);
+}
+
+v_uns even_uns (v_uns a, v_uns b)
+{
+  return vec_vmrgew (a, b);
+}
+
+v_sign odd_sign (v_sign a, v_sign b)
+{
+  return vec_vmrgow (a, b);
+}
+
+v_uns odd_uns (v_uns a, v_uns b)
+{
+  return vec_vmrgow (a, b);
+}
+
+/* { dg-final { scan-assembler-times "vmrgew" 2 } } */
+/* { dg-final { scan-assembler-times "vmrgow" 2 } } */
Index: gcc/testsuite/lib/target-supports.exp
===================================================================
--- gcc/testsuite/lib/target-supports.exp       (revision 199037)
+++ gcc/testsuite/lib/target-supports.exp       (working copy)
@@ -1311,6 +1311,32 @@ proc check_effective_target_avx_runtime 
     return 0
 }
 
+# Return 1 if the target supports executing power8 vector instructions, 0
+# otherwise.  Cache the result.
+
+proc check_p8vector_hw_available { } {
+    return [check_cached_effective_target p8vector_hw_available {
+       # Some simulators are known to not support VSX/power8 instructions.
+       # For now, disable on Darwin
+       if { [istarget powerpc-*-eabi] || [istarget powerpc*-*-eabispe] || 
[istarget *-*-darwin*]} {
+           expr 0
+       } else {
+           set options "-mpower8-vector"
+           check_runtime_nocache p8vector_hw_available {
+               int main()
+               {
+               #ifdef __MACH__
+                 asm volatile ("xxlorc vs0,vs0,vs0");
+               #else
+                 asm volatile ("xxlorc 0,0,0");
+               #endif
+                 return 0;
+               }
+           } $options
+       }
+    }]
+}
+
 # Return 1 if the target supports executing VSX instructions, 0
 # otherwise.  Cache the result.
 
@@ -2749,6 +2775,33 @@ proc check_effective_target_powerpc_alti
     }
 }
 
+# Return 1 if this is a PowerPC target supporting -mpower8-vector
+
+proc check_effective_target_powerpc_p8vector_ok { } {
+    if { ([istarget powerpc*-*-*]
+         && ![istarget powerpc-*-linux*paired*])
+        || [istarget rs6000-*-*] } {
+       # AltiVec is not supported on AIX before 5.3.
+       if { [istarget powerpc*-*-aix4*]
+            || [istarget powerpc*-*-aix5.1*] 
+            || [istarget powerpc*-*-aix5.2*] } {
+           return 0
+       }
+       return [check_no_compiler_messages powerpc_p8vector_ok object {
+           int main (void) {
+#ifdef __MACH__
+               asm volatile ("xxlorc vs0,vs0,vs0");
+#else
+               asm volatile ("xxlorc 0,0,0");
+#endif
+               return 0;
+           }
+       } "-mpower8-vector"]
+    } else {
+       return 0
+    }
+}
+
 # Return 1 if this is a PowerPC target supporting -mvsx
 
 proc check_effective_target_powerpc_vsx_ok { } {
@@ -4576,6 +4629,7 @@ proc is-effective-target { arg } {
        switch $arg {
          "vmx_hw"         { set selected [check_vmx_hw_available] }
          "vsx_hw"         { set selected [check_vsx_hw_available] }
+         "p8vector_hw"    { set selected [check_p8vector_hw_available] }
          "ppc_recip_hw"   { set selected [check_ppc_recip_hw_available] }
          "named_sections" { set selected [check_named_sections_available] }
          "gc_sections"    { set selected [check_gc_sections_available] }
@@ -4597,6 +4651,7 @@ proc is-effective-target-keyword { arg }
        switch $arg {
          "vmx_hw"         { return 1 }
          "vsx_hw"         { return 1 }
+         "p8vector_hw"    { return 1 }
          "ppc_recip_hw"   { return 1 }
          "named_sections" { return 1 }
          "gc_sections"    { return 1 }
@@ -5181,7 +5236,9 @@ proc check_vect_support_and_set_flags { 
         }
 
         lappend DEFAULT_VECTCFLAGS "-maltivec"
-        if [check_vsx_hw_available] {
+        if [check_p8vector_hw_available] {
+            lappend DEFAULT_VECTCFLAGS "-mpower8-vector" 
"-mno-allow-movmisalign"
+        } elseif [check_vsx_hw_available] {
             lappend DEFAULT_VECTCFLAGS "-mvsx" "-mno-allow-movmisalign"
         }
 

Reply via email to