summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKelvin Nilsen <kelvin@gcc.gnu.org>2020-05-11 10:04:03 -0500
committerBill Schmidt <wschmidt@linux.ibm.com>2020-05-11 10:04:03 -0500
commit894ac7bce590dc5036c7f1477b881dc767ce2e5a (patch)
treed9db3eeb9215e08be7f2d60f934326d31d29ad9a
parenta1821a249d998894dd38b14d5298647e8d7b5dc8 (diff)
rs6000: Add vector pdep/pext
Add support for the vpdepd and vpextd instructions that perform vector parallel bit deposit and vector parallel bit extract. [gcc] 2020-05-11 Kelvin Nilsen <kelvin@gcc.gnu.org> Bill Schmidt <wschmidt@linux.ibm.com> * config/rs6000/altivec.h (vec_pdep): New macro implementing new built-in function. (vec_pext): Likewise. * config/rs6000/altivec.md (UNSPEC_VPDEPD): New constant. (UNSPEC_VPEXTD): Likewise. (vpdepd): New insn. (vpextd): Likewise. * config/rs6000/rs6000-builtin.def (__builtin_altivec_vpdepd): New built-in function. (__builtin_altivec_vpextd): Likewise. * config/rs6000/rs6000-call.c (builtin_function_type): Add handling for FUTURE_BUILTIN_VPDEPD and FUTURE_BUILTIN_VPEXTD cases. * doc/extend.texi (PowerPC Altivec Built-in Functions Available for a Future Architecture): Add description of vec_pdep and vec_pext built-in functions. [gcc/testsuite] 2020-05-11 Kelvin Nilsen <kelvin@gcc.gnu.org> * gcc.target/powerpc/vec-pdep-0.c: New. * gcc.target/powerpc/vec-pdep-1.c: New. * gcc.target/powerpc/vec-pext-0.c: New. * gcc.target/powerpc/vec-pext-1.c: New.
-rw-r--r--gcc/ChangeLog20
-rw-r--r--gcc/config/rs6000/altivec.h3
-rw-r--r--gcc/config/rs6000/altivec.md20
-rw-r--r--gcc/config/rs6000/rs6000-builtin.def2
-rw-r--r--gcc/config/rs6000/rs6000-call.c2
-rw-r--r--gcc/doc/extend.texi15
-rw-r--r--gcc/testsuite/ChangeLog7
-rw-r--r--gcc/testsuite/gcc.target/powerpc/vec-pdep-0.c61
-rw-r--r--gcc/testsuite/gcc.target/powerpc/vec-pdep-1.c53
-rw-r--r--gcc/testsuite/gcc.target/powerpc/vec-pext-0.c53
-rw-r--r--gcc/testsuite/gcc.target/powerpc/vec-pext-1.c52
11 files changed, 288 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index b5f64d5c03b..34c7bc0918d 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,6 +1,26 @@
2020-05-11 Kelvin Nilsen <kelvin@gcc.gnu.org>
Bill Schmidt <wschmidt@linux.ibm.com>
+ * config/rs6000/altivec.h (vec_pdep): New macro implementing new
+ built-in function.
+ (vec_pext): Likewise.
+ * config/rs6000/altivec.md (UNSPEC_VPDEPD): New constant.
+ (UNSPEC_VPEXTD): Likewise.
+ (vpdepd): New insn.
+ (vpextd): Likewise.
+ * config/rs6000/rs6000-builtin.def (__builtin_altivec_vpdepd): New
+ built-in function.
+ (__builtin_altivec_vpextd): Likewise.
+ * config/rs6000/rs6000-call.c (builtin_function_type): Add
+ handling for FUTURE_BUILTIN_VPDEPD and FUTURE_BUILTIN_VPEXTD
+ cases.
+ * doc/extend.texi (PowerPC Altivec Built-in Functions Available
+ for a Future Architecture): Add description of vec_pdep and
+ vec_pext built-in functions.
+
+2020-05-11 Kelvin Nilsen <kelvin@gcc.gnu.org>
+ Bill Schmidt <wschmidt@linux.ibm.com>
+
* config/rs6000/altivec.h (vec_clzm): New macro.
(vec_ctzm): Likewise.
* config/rs6000/altivec.md (UNSPEC_VCLZDM): New constant.
diff --git a/gcc/config/rs6000/altivec.h b/gcc/config/rs6000/altivec.h
index e1e75ad0f1e..12dfcd8d2bf 100644
--- a/gcc/config/rs6000/altivec.h
+++ b/gcc/config/rs6000/altivec.h
@@ -691,6 +691,9 @@ __altivec_scalar_pred(vec_any_nle,
with support for different vector argument and result types. */
#define vec_clzm(a, b) __builtin_altivec_vclzdm (a, b)
#define vec_ctzm(a, b) __builtin_altivec_vctzdm (a, b)
+#define vec_pdep(a, b) __builtin_altivec_vpdepd (a, b)
+#define vec_pext(a, b) __builtin_altivec_vpextd (a, b)
+
#endif
#endif /* _ALTIVEC_H */
diff --git a/gcc/config/rs6000/altivec.md b/gcc/config/rs6000/altivec.md
index 5ef4889ba55..33ba57855bc 100644
--- a/gcc/config/rs6000/altivec.md
+++ b/gcc/config/rs6000/altivec.md
@@ -162,6 +162,8 @@
UNSPEC_VRLNM
UNSPEC_VCLZDM
UNSPEC_VCTZDM
+ UNSPEC_VPDEPD
+ UNSPEC_VPEXTD
])
(define_c_enum "unspecv"
@@ -4116,6 +4118,24 @@
"vctzdm %0,%1,%2"
[(set_attr "type" "vecsimple")])
+(define_insn "vpdepd"
+ [(set (match_operand:V2DI 0 "altivec_register_operand" "=v")
+ (unspec:V2DI [(match_operand:V2DI 1 "altivec_register_operand" "v")
+ (match_operand:V2DI 2 "altivec_register_operand" "v")]
+ UNSPEC_VPDEPD))]
+ "TARGET_FUTURE"
+ "vpdepd %0,%1,%2"
+ [(set_attr "type" "vecsimple")])
+
+(define_insn "vpextd"
+ [(set (match_operand:V2DI 0 "altivec_register_operand" "=v")
+ (unspec:V2DI [(match_operand:V2DI 1 "altivec_register_operand" "v")
+ (match_operand:V2DI 2 "altivec_register_operand" "v")]
+ UNSPEC_VPEXTD))]
+ "TARGET_FUTURE"
+ "vpextd %0,%1,%2"
+ [(set_attr "type" "vecsimple")])
+
(define_expand "bcd<bcd_add_sub>_<code>"
[(parallel [(set (reg:CCFP CR6_REGNO)
diff --git a/gcc/config/rs6000/rs6000-builtin.def b/gcc/config/rs6000/rs6000-builtin.def
index 9293e7cf4fb..776fc542ebf 100644
--- a/gcc/config/rs6000/rs6000-builtin.def
+++ b/gcc/config/rs6000/rs6000-builtin.def
@@ -2518,6 +2518,8 @@ BU_P9_OVERLOAD_2 (CMPEQB, "byte_in_set")
/* Future architecture vector built-ins. */
BU_FUTURE_V_2 (VCLZDM, "vclzdm", CONST, vclzdm)
BU_FUTURE_V_2 (VCTZDM, "vctzdm", CONST, vctzdm)
+BU_FUTURE_V_2 (VPDEPD, "vpdepd", CONST, vpdepd)
+BU_FUTURE_V_2 (VPEXTD, "vpextd", CONST, vpextd)
/* 1 argument crypto functions. */
BU_CRYPTO_1 (VSBOX, "vsbox", CONST, crypto_vsbox_v2di)
diff --git a/gcc/config/rs6000/rs6000-call.c b/gcc/config/rs6000/rs6000-call.c
index 2a4ce5bd340..ab6ba576605 100644
--- a/gcc/config/rs6000/rs6000-call.c
+++ b/gcc/config/rs6000/rs6000-call.c
@@ -12928,6 +12928,8 @@ builtin_function_type (machine_mode mode_ret, machine_mode mode_arg0,
case P8V_BUILTIN_ORC_V1TI_UNS:
case FUTURE_BUILTIN_VCLZDM:
case FUTURE_BUILTIN_VCTZDM:
+ case FUTURE_BUILTIN_VPDEPD:
+ case FUTURE_BUILTIN_VPEXTD:
h.uns_p[0] = 1;
h.uns_p[1] = 1;
h.uns_p[2] = 1;
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index aa8ab3a8dc5..23c7aa6fb79 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -20713,6 +20713,21 @@ Perform a vector count trailing zeros under bit mask operation, as if
implemented by the Future @code{vctzdm} instruction.
@findex vec_ctzm
+@smallexample
+@exdent vector unsigned long long int
+@exdent vec_pdep (vector unsigned long long int, vector unsigned long long int)
+@end smallexample
+Perform a vector parallel bits deposit operation, as if implemented by
+the Future @code{vpdepd} instruction.
+@findex vec_pdep
+
+@smallexample
+@exdent vector unsigned long long int
+@exdent vec_pext (vector unsigned long long int, vector unsigned long long int)
+@end smallexample
+Perform a vector parallel bit extract operation, as if implemented by
+the Future @code{vpextd} instruction.
+@findex vec_pext
@node PowerPC Hardware Transactional Memory Built-in Functions
@subsection PowerPC Hardware Transactional Memory Built-in Functions
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index db274eed95a..05b409a0587 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,10 @@
+2020-05-11 Kelvin Nilsen <kelvin@gcc.gnu.org>
+
+ * gcc.target/powerpc/vec-pdep-0.c: New.
+ * gcc.target/powerpc/vec-pdep-1.c: New.
+ * gcc.target/powerpc/vec-pext-0.c: New.
+ * gcc.target/powerpc/vec-pext-1.c: New.
+
2020-05-11 Richard Biener <rguenther@suse.de>
PR tree-optimization/94988
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-pdep-0.c b/gcc/testsuite/gcc.target/powerpc/vec-pdep-0.c
new file mode 100644
index 00000000000..541b0aa6f45
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-pdep-0.c
@@ -0,0 +1,61 @@
+/* { dg-do compile } */
+/* { dg-options "-mdejagnu-cpu=future" } */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+vector unsigned long long int
+do_vec_pdep (vector unsigned long long int source,
+ vector unsigned long long int mask) {
+ return vec_pdep (source, mask);
+}
+
+int
+vectors_equal (vector unsigned long long int a,
+ vector unsigned long long int b)
+{
+ return (a[0] == b[0]) && (a[1] == b[1]);
+}
+
+int
+main (int argc, char *argv [])
+{
+ vector unsigned long long int source_a = { 0xa5f07e3cull, 0x7e3ca5f0ull };
+ vector unsigned long long int source_b = { 0x3ca5f07eull, 0x5a0fe7c3ull };
+
+ vector unsigned long long int mask_a = { 0xffff0000ull, 0x0000ffffull };
+ vector unsigned long long int mask_b = { 0x0f0f0f0full, 0xf0f0f0f0ull };
+
+ /* See pdepd-0.c for derivation of expected results.
+
+ result_aa [0] is compute (source [0], mask [0];
+ result_aa [1] is compute (source [1], mask [1].
+
+ result_ab [0] is compute (source [0], mask [2];
+ result_ab [1] is compute (source [1], mask [3].
+
+ result_ba [0] is compute (source [2], mask [0];
+ result_ba [1] is compute (source [3], mask [1].
+
+ result_bb [0] is compute (source [2], mask [2];
+ result_bb [1] is compute (source [3], mask [3]. */
+
+ vector unsigned long long int result_aa = { 0x7e3c0000ull, 0x0000a5f0ull };
+ vector unsigned long long int result_ab = { 0x070e030cull, 0xa050f000ull };
+ vector unsigned long long int result_ba = { 0xf07e0000ull, 0x0000e7c3ull };
+ vector unsigned long long int result_bb = { 0x0f00070eull, 0xe070c030ull };
+
+ if (!vec_all_eq (do_vec_pdep (source_a, mask_a), result_aa))
+ abort ();
+ if (!vec_all_eq (do_vec_pdep (source_a, mask_b), result_ab))
+ abort ();
+ if (!vec_all_eq (do_vec_pdep (source_b, mask_a), result_ba))
+ abort ();
+ if (!vec_all_eq (do_vec_pdep (source_b, mask_b), result_bb))
+ abort ();
+
+ return 0;
+}
+
+/* { dg-final { scan-assembler {\mvpdepd\M} } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-pdep-1.c b/gcc/testsuite/gcc.target/powerpc/vec-pdep-1.c
new file mode 100644
index 00000000000..75249c50eee
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-pdep-1.c
@@ -0,0 +1,53 @@
+/* { dg-do run } */
+/* { dg-require-effective-target powerpc_future_hw } */
+/* { dg-options "-mdejagnu-cpu=future" } */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+vector unsigned long long int
+do_vec_pdep (vector unsigned long long int source,
+ vector unsigned long long int mask) {
+ return vec_pdep (source, mask);
+}
+
+int
+main (int argc, char *argv [])
+{
+ vector unsigned long long int source_a = { 0xa5f07e3cull, 0x7e3ca5f0ull };
+ vector unsigned long long int source_b = { 0x3ca5f07eull, 0x5a0fe7c3ull };
+
+ vector unsigned long long int mask_a = { 0xffff0000ull, 0x0000ffffull };
+ vector unsigned long long int mask_b = { 0x0f0f0f0full, 0xf0f0f0f0ull };
+
+ /* See pdepd-0.c for derivation of expected results.
+
+ result_aa [0] is compute (source [0], mask [0];
+ result_aa [1] is compute (source [1], mask [1].
+
+ result_ab [0] is compute (source [0], mask [2];
+ result_ab [1] is compute (source [1], mask [3].
+
+ result_ba [0] is compute (source [2], mask [0];
+ result_ba [1] is compute (source [3], mask [1].
+
+ result_bb [0] is compute (source [2], mask [2];
+ result_bb [1] is compute (source [3], mask [3]. */
+
+ vector unsigned long long int result_aa = { 0x7e3c0000ull, 0x0000a5f0ull };
+ vector unsigned long long int result_ab = { 0x070e030cull, 0xa050f000ull };
+ vector unsigned long long int result_ba = { 0xf07e0000ull, 0x0000e7c3ull };
+ vector unsigned long long int result_bb = { 0x0f00070eull, 0xe070c030ull };
+
+ if (!vec_all_eq (do_vec_pdep (source_a, mask_a), result_aa))
+ abort ();
+ if (!vec_all_eq (do_vec_pdep (source_a, mask_b), result_ab))
+ abort ();
+ if (!vec_all_eq (do_vec_pdep (source_b, mask_a), result_ba))
+ abort ();
+ if (!vec_all_eq (do_vec_pdep (source_b, mask_b), result_bb))
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-pext-0.c b/gcc/testsuite/gcc.target/powerpc/vec-pext-0.c
new file mode 100644
index 00000000000..1d12f048dbd
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-pext-0.c
@@ -0,0 +1,53 @@
+/* { dg-do compile } */
+/* { dg-options "-mdejagnu-cpu=future" } */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+vector unsigned long long int
+do_vec_pext (vector unsigned long long int source,
+ vector unsigned long long int mask) {
+ return vec_pext (source, mask);
+}
+
+int main (int argc, char *argv [])
+{
+ vector unsigned long long int source_a = { 0xa5f07e3cull, 0x7e3ca5f0ull };
+ vector unsigned long long int source_b = { 0x3ca5f07eull, 0x5a0fe7c3ull };
+
+ vector unsigned long long int mask_a = { 0xffff0000ull, 0x0000ffffull };
+ vector unsigned long long int mask_b = { 0x0f0f0f0full, 0xf0f0f0f0ull };
+
+ /* See pextd-0.c for derivation of expected results.
+
+ result_aa [0] is compute (source [0], mask [0];
+ result_aa [1] is compute (source [1], mask [1].
+
+ result_ab [0] is compute (source [0], mask [2];
+ result_ab [1] is compute (source [1], mask [3].
+
+ result_ba [0] is compute (source [2], mask [0];
+ result_ba [1] is compute (source [3], mask [1].
+
+ result_bb [0] is compute (source [2], mask [2];
+ result_bb [1] is compute (source [3], mask [3]. */
+
+ vector unsigned long long int result_aa = { 0x0000a5f0ull, 0x0000a5f0ull };
+ vector unsigned long long int result_ab = { 0x000050ecull, 0x000073afull };
+ vector unsigned long long int result_ba = { 0x00003ca5ull, 0x0000e7c3ull };
+ vector unsigned long long int result_bb = { 0x0000c50eull, 0x000050ecull };
+
+ if (!vec_all_eq (do_vec_pext (source_a, mask_a), result_aa))
+ abort ();
+ if (!vec_all_eq (do_vec_pext (source_a, mask_b),result_ab))
+ abort ();
+ if (!vec_all_eq (do_vec_pext (source_b, mask_a), result_ba))
+ abort ();
+ if (!vec_all_eq (do_vec_pext (source_b, mask_b), result_bb))
+ abort ();
+
+ return 0;
+}
+
+/* { dg-final { scan-assembler {\mvpextd\M} } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-pext-1.c b/gcc/testsuite/gcc.target/powerpc/vec-pext-1.c
new file mode 100644
index 00000000000..db1b95e729a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-pext-1.c
@@ -0,0 +1,52 @@
+/* { dg-do run } */
+/* { dg-require-effective-target powerpc_future_hw } */
+/* { dg-options "-mdejagnu-cpu=future" } */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+vector unsigned long long int
+do_vec_pext (vector unsigned long long int source,
+ vector unsigned long long int mask) {
+ return vec_pext (source, mask);
+}
+
+int main (int argc, char *argv [])
+{
+ vector unsigned long long int source_a = { 0xa5f07e3cull, 0x7e3ca5f0ull };
+ vector unsigned long long int source_b = { 0x3ca5f07eull, 0x5a0fe7c3ull };
+
+ vector unsigned long long int mask_a = { 0xffff0000ull, 0x0000ffffull };
+ vector unsigned long long int mask_b = { 0x0f0f0f0full, 0xf0f0f0f0ull };
+
+ /* See pextd-0.c for derivation of expected results.
+
+ result_aa [0] is compute (source [0], mask [0];
+ result_aa [1] is compute (source [1], mask [1].
+
+ result_ab [0] is compute (source [0], mask [2];
+ result_ab [1] is compute (source [1], mask [3].
+
+ result_ba [0] is compute (source [2], mask [0];
+ result_ba [1] is compute (source [3], mask [1].
+
+ result_bb [0] is compute (source [2], mask [2];
+ result_bb [1] is compute (source [3], mask [3]. */
+
+ vector unsigned long long int result_aa = { 0x0000a5f0ull, 0x0000a5f0ull };
+ vector unsigned long long int result_ab = { 0x000050ecull, 0x000073afull };
+ vector unsigned long long int result_ba = { 0x00003ca5ull, 0x0000e7c3ull };
+ vector unsigned long long int result_bb = { 0x0000c50eull, 0x000050ecull };
+
+ if (!vec_all_eq (do_vec_pext (source_a, mask_a), result_aa))
+ abort ();
+ if (!vec_all_eq (do_vec_pext (source_a, mask_b),result_ab))
+ abort ();
+ if (!vec_all_eq (do_vec_pext (source_b, mask_a), result_ba))
+ abort ();
+ if (!vec_all_eq (do_vec_pext (source_b, mask_b), result_bb))
+ abort ();
+
+ return 0;
+}