diff options
author | Michael Meissner <meissner@linux.vnet.ibm.com> | 2016-11-14 19:55:42 +0000 |
---|---|---|
committer | Michael Meissner <meissner@gcc.gnu.org> | 2016-11-14 19:55:42 +0000 |
commit | bcb9a772e9287057d8c20fc04c91e716ecff36fe (patch) | |
tree | acecd1905711db7abe57f78abe3b79cba4dc6c60 /gcc | |
parent | 3eb89071d6ffc652b0bde7aa0a5ea61da6ac96f6 (diff) | |
download | gcc-bcb9a772e9287057d8c20fc04c91e716ecff36fe.zip gcc-bcb9a772e9287057d8c20fc04c91e716ecff36fe.tar.gz gcc-bcb9a772e9287057d8c20fc04c91e716ecff36fe.tar.bz2 |
rs6000.c (rs6000_expand_vector_set): Add support for using xxinsertw and vinsert{b,h} on ISA 3.0.
[gcc]
2016-11-14 Michael Meissner <meissner@linux.vnet.ibm.com>
* config/rs6000/rs6000.c (rs6000_expand_vector_set): Add support
for using xxinsertw and vinsert{b,h} on ISA 3.0.
* config/rs6000/vsx.md (vsx_extract_<mode>): Update comment.
(vsx_set_<mode>_p9): New insn to generate xxinsertw and
vinsert{b,h} on ISA 3.0.
[gcc/testsuite]
2016-11-14 Michael Meissner <meissner@linux.vnet.ibm.com>
* gcc.target/powerpc/vec-set-int.c: New test.
* gcc.target/powerpc/vec-set-short.c: Likesie.
* gcc.target/powerpc/vec-set-char.c: Likewise.
From-SVN: r242397
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 11 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.c | 31 | ||||
-rw-r--r-- | gcc/config/rs6000/vsx.md | 31 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/powerpc/vec-set-char.c | 40 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/powerpc/vec-set-int.c | 40 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/powerpc/vec-set-short.c | 40 |
7 files changed, 190 insertions, 9 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index fd132b5..0044469 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2016-11-14 Michael Meissner <meissner@linux.vnet.ibm.com> + + * config/rs6000/rs6000.c (rs6000_expand_vector_set): Add support + for using xxinsertw and vinsert{b,h} on ISA 3.0. + + * config/rs6000/vsx.md (vsx_extract_<mode>): Update comment. + (vsx_set_<mode>_p9): New insn to generate xxinsertw and + vinsert{b,h} on ISA 3.0. + 2016-11-14 Thomas Preud'homme <thomas.preudhomme@arm.com> * tree-ssa-math-opts.c (find_bswap_or_nop): Zero out bytes in cmpxchg @@ -18,7 +27,7 @@ 2016-11-14 Prasad Ghangal <prasad.ghangal@gmail.com> Richard Biener <rguenther@suse.de> - + * doc/invoke.texi (fgimple): Document. * dumpfile.h (TDF_GIMPLE): Add. * dumpfile.c (dump_options): Add gimple. diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 609f267..c223434 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -7095,12 +7095,33 @@ rs6000_expand_vector_set (rtx target, rtx val, int elt) int width = GET_MODE_SIZE (inner_mode); int i; - if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode)) + if (VECTOR_MEM_VSX_P (mode)) { - rtx (*set_func) (rtx, rtx, rtx, rtx) - = ((mode == V2DFmode) ? gen_vsx_set_v2df : gen_vsx_set_v2di); - emit_insn (set_func (target, target, val, GEN_INT (elt))); - return; + rtx insn = NULL_RTX; + rtx elt_rtx = GEN_INT (elt); + + if (mode == V2DFmode) + insn = gen_vsx_set_v2df (target, target, val, elt_rtx); + + else if (mode == V2DImode) + insn = gen_vsx_set_v2di (target, target, val, elt_rtx); + + else if (TARGET_P9_VECTOR && TARGET_VSX_SMALL_INTEGER + && TARGET_UPPER_REGS_DI && TARGET_POWERPC64) + { + if (mode == V4SImode) + insn = gen_vsx_set_v4si_p9 (target, target, val, elt_rtx); + else if (mode == V8HImode) + insn = gen_vsx_set_v8hi_p9 (target, target, val, elt_rtx); + else if (mode == V16QImode) + insn = gen_vsx_set_v16qi_p9 (target, target, val, elt_rtx); + } + + if (insn) + { + emit_insn (insn); + return; + } } /* Simplify setting single element vectors like V1TImode. */ diff --git a/gcc/config/rs6000/vsx.md b/gcc/config/rs6000/vsx.md index c5a57cb..75c1625 100644 --- a/gcc/config/rs6000/vsx.md +++ b/gcc/config/rs6000/vsx.md @@ -2514,9 +2514,9 @@ FAIL; }) -;; Extraction of a single element in a small integer vector. None of the small -;; types are currently allowed in a vector register, so we extract to a DImode -;; and either do a direct move or store. +;; Extraction of a single element in a small integer vector. Until ISA 3.0, +;; none of the small types were allowed in a vector register, so we had to +;; extract to a DImode and either do a direct move or store. (define_expand "vsx_extract_<mode>" [(parallel [(set (match_operand:<VS_scalar> 0 "gpc_reg_operand") (vec_select:<VS_scalar> @@ -2839,6 +2839,31 @@ DONE; }) +;; V4SI/V8HI/V16QI set operation on ISA 3.0 +(define_insn "vsx_set_<mode>_p9" + [(set (match_operand:VSX_EXTRACT_I 0 "gpc_reg_operand" "=<VSX_EX>") + (unspec:VSX_EXTRACT_I + [(match_operand:VSX_EXTRACT_I 1 "gpc_reg_operand" "0") + (match_operand:<VS_scalar> 2 "gpc_reg_operand" "<VSX_EX>") + (match_operand:QI 3 "<VSX_EXTRACT_PREDICATE>" "n")] + UNSPEC_VSX_SET))] + "VECTOR_MEM_VSX_P (<MODE>mode) && TARGET_P9_VECTOR && TARGET_VSX_SMALL_INTEGER + && TARGET_UPPER_REGS_DI && TARGET_POWERPC64" +{ + int ele = INTVAL (operands[3]); + int nunits = GET_MODE_NUNITS (<MODE>mode); + + if (!VECTOR_ELT_ORDER_BIG) + ele = nunits - 1 - ele; + + operands[3] = GEN_INT (nunits * ele); + if (<MODE>mode == V4SImode) + return "xxinsertw %x0,%x2,%3"; + else + return "vinsert<wd> %0,%2,%3"; +} + [(set_attr "type" "vecperm")]) + ;; Expanders for builtins (define_expand "vsx_mergel_<mode>" [(use (match_operand:VSX_D 0 "vsx_register_operand" "")) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 1c3e66c..8c2c1a6 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2016-11-14 Michael Meissner <meissner@linux.vnet.ibm.com> + + * gcc.target/powerpc/vec-set-int.c: New test. + * gcc.target/powerpc/vec-set-short.c: Likesie. + * gcc.target/powerpc/vec-set-char.c: Likewise. + 2016-11-14 Jakub Jelinek <jakub@redhat.com> * g++.dg/cpp1z/feat-cxx1z.C: Test __cpp_structured_bindings macro. diff --git a/gcc/testsuite/gcc.target/powerpc/vec-set-char.c b/gcc/testsuite/gcc.target/powerpc/vec-set-char.c new file mode 100644 index 0000000..2da79ef --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/vec-set-char.c @@ -0,0 +1,40 @@ +#include <altivec.h> + +/* { dg-do compile { target { powerpc64*-*-* && lp64 } } } */ +/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */ +/* { dg-require-effective-target powerpc_p9vector_ok } */ +/* { dg-options "-mcpu=power9 -O2 -mupper-regs-di -mvsx-small-integer" } */ + +vector char +insert_0_0 (vector char v) +{ + return vec_insert (0, v, 0); +} + +vector char +insert_m1_1 (vector char v) +{ + return vec_insert (-1, v, 1); +} + +vector char +insert_5_2 (vector char v) +{ + return vec_insert (5, v, 2); +} + +vector char +insert_mem_15 (vector char v, char *p) +{ + return vec_insert (*p, v, 15); +} + +/* { dg-final { scan-assembler "vinsertb" } } */ +/* { dg-final { scan-assembler "xxspltib" } } */ +/* { dg-final { scan-assembler "vspltisb" } } */ +/* { dg-final { scan-assembler-not "mtvsrd" } } */ +/* { dg-final { scan-assembler-not "mtvsrdd" } } */ +/* { dg-final { scan-assembler-not "mtvsrwa" } } */ +/* { dg-final { scan-assembler-not "mtvsrwz" } } */ +/* { dg-final { scan-assembler-not "mfvsrd" } } */ +/* { dg-final { scan-assembler-not "mfvsrwz" } } */ diff --git a/gcc/testsuite/gcc.target/powerpc/vec-set-int.c b/gcc/testsuite/gcc.target/powerpc/vec-set-int.c new file mode 100644 index 0000000..dc97ac9 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/vec-set-int.c @@ -0,0 +1,40 @@ +#include <altivec.h> + +/* { dg-do compile { target { powerpc64*-*-* && lp64 } } } */ +/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */ +/* { dg-require-effective-target powerpc_p9vector_ok } */ +/* { dg-options "-mcpu=power9 -O2 -mupper-regs-di -mvsx-small-integer" } */ + +vector int +insert_0_0 (vector int v) +{ + return vec_insert (0, v, 0); +} + +vector int +insert_m1_1 (vector int v) +{ + return vec_insert (-1, v, 1); +} + +vector int +insert_5_2 (vector int v) +{ + return vec_insert (5, v, 2); +} + +vector int +insert_mem_3 (vector int v, int *p) +{ + return vec_insert (*p, v, 3); +} + +/* { dg-final { scan-assembler "xxinsertw" } } */ +/* { dg-final { scan-assembler "xxspltib" } } */ +/* { dg-final { scan-assembler "vspltisw" } } */ +/* { dg-final { scan-assembler-not "mtvsrd" } } */ +/* { dg-final { scan-assembler-not "mtvsrdd" } } */ +/* { dg-final { scan-assembler-not "mtvsrwa" } } */ +/* { dg-final { scan-assembler-not "mtvsrwz" } } */ +/* { dg-final { scan-assembler-not "mfvsrd" } } */ +/* { dg-final { scan-assembler-not "mfvsrwz" } } */ diff --git a/gcc/testsuite/gcc.target/powerpc/vec-set-short.c b/gcc/testsuite/gcc.target/powerpc/vec-set-short.c new file mode 100644 index 0000000..d827609 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/vec-set-short.c @@ -0,0 +1,40 @@ +#include <altivec.h> + +/* { dg-do compile { target { powerpc64*-*-* && lp64 } } } */ +/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */ +/* { dg-require-effective-target powerpc_p9vector_ok } */ +/* { dg-options "-mcpu=power9 -O2 -mupper-regs-di -mvsx-small-integer" } */ + +vector short +insert_0_0 (vector short v) +{ + return vec_insert (0, v, 0); +} + +vector short +insert_m1_1 (vector short v) +{ + return vec_insert (-1, v, 1); +} + +vector short +insert_5_2 (vector short v) +{ + return vec_insert (5, v, 2); +} + +vector short +insert_mem_7 (vector short v, short *p) +{ + return vec_insert (*p, v, 7); +} + +/* { dg-final { scan-assembler "vinserth" } } */ +/* { dg-final { scan-assembler "xxspltib" } } */ +/* { dg-final { scan-assembler "vspltish" } } */ +/* { dg-final { scan-assembler-not "mtvsrd" } } */ +/* { dg-final { scan-assembler-not "mtvsrdd" } } */ +/* { dg-final { scan-assembler-not "mtvsrwa" } } */ +/* { dg-final { scan-assembler-not "mtvsrwz" } } */ +/* { dg-final { scan-assembler-not "mfvsrd" } } */ +/* { dg-final { scan-assembler-not "mfvsrwz" } } */ |