diff options
author | Michael Meissner <meissner@linux.vnet.ibm.com> | 2016-08-12 19:40:37 +0000 |
---|---|---|
committer | Michael Meissner <meissner@gcc.gnu.org> | 2016-08-12 19:40:37 +0000 |
commit | e86aefb8e955a9545ffd16c960ff70cbad5fc9ad (patch) | |
tree | 4d26a414fc4a986fb7a186ae3f68288ec0678c07 | |
parent | b1ad9be2e8170ead78f7522e7647111f3bc0dc6f (diff) | |
download | gcc-e86aefb8e955a9545ffd16c960ff70cbad5fc9ad.zip gcc-e86aefb8e955a9545ffd16c960ff70cbad5fc9ad.tar.gz gcc-e86aefb8e955a9545ffd16c960ff70cbad5fc9ad.tar.bz2 |
vsx.md (vsx_concat_<mode>): Add support for the ISA 3.0 MTVSRDD instruction.
[gcc]
2016-08-12 Michael Meissner <meissner@linux.vnet.ibm.com>
* config/rs6000/vsx.md (vsx_concat_<mode>): Add support for the
ISA 3.0 MTVSRDD instruction.
(vsx_splat_<mode>): Change cpu type of MTVSRDD instruction to
vecperm.
[gcc/testsuite]
2016-08-12 Michael Meissner <meissner@linux.vnet.ibm.com>
* gcc.target/powerpc/vec-init-1.c: New tests to test various
vector initialization options.
* gcc.target/powerpc/vec-init-2.c: Likewise.
* gcc.target/powerpc/vec-init-3.c: New test to make sure MTVSRDD
is generated on ISA 3.0.
From-SVN: r239428
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/config/rs6000/vsx.md | 22 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/powerpc/vec-init-1.c | 169 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/powerpc/vec-init-2.c | 169 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/powerpc/vec-init-3.c | 12 |
6 files changed, 380 insertions, 7 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index aeb3f79..c920e7a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2016-08-12 Michael Meissner <meissner@linux.vnet.ibm.com> + + * config/rs6000/vsx.md (vsx_concat_<mode>): Add support for the + ISA 3.0 MTVSRDD instruction. + (vsx_splat_<mode>): Change cpu type of MTVSRDD instruction to + vecperm. + 2016-08-12 Bernd Edlinger <bernd.edlinger@hotmail.de> PR tree-optimization/71083 diff --git a/gcc/config/rs6000/vsx.md b/gcc/config/rs6000/vsx.md index f43a28e..f64b4d8 100644 --- a/gcc/config/rs6000/vsx.md +++ b/gcc/config/rs6000/vsx.md @@ -1925,16 +1925,24 @@ ;; Build a V2DF/V2DI vector from two scalars (define_insn "vsx_concat_<mode>" - [(set (match_operand:VSX_D 0 "vsx_register_operand" "=<VSr>,?<VSa>") + [(set (match_operand:VSX_D 0 "gpc_reg_operand" "=<VSa>,we") (vec_concat:VSX_D - (match_operand:<VS_scalar> 1 "vsx_register_operand" "<VS_64reg>,<VSa>") - (match_operand:<VS_scalar> 2 "vsx_register_operand" "<VS_64reg>,<VSa>")))] + (match_operand:<VS_scalar> 1 "gpc_reg_operand" "<VS_64reg>,r") + (match_operand:<VS_scalar> 2 "gpc_reg_operand" "<VS_64reg>,r")))] "VECTOR_MEM_VSX_P (<MODE>mode)" { - if (BYTES_BIG_ENDIAN) - return "xxpermdi %x0,%x1,%x2,0"; + if (which_alternative == 0) + return (BYTES_BIG_ENDIAN + ? "xxpermdi %x0,%x1,%x2,0" + : "xxpermdi %x0,%x2,%x1,0"); + + else if (which_alternative == 1) + return (BYTES_BIG_ENDIAN + ? "mtvsrdd %x0,%1,%2" + : "mtvsrdd %x0,%2,%1"); + else - return "xxpermdi %x0,%x2,%x1,0"; + gcc_unreachable (); } [(set_attr "type" "vecperm")]) @@ -2664,7 +2672,7 @@ xxpermdi %x0,%x1,%x1,0 lxvdsx %x0,%y1 mtvsrdd %x0,%1,%1" - [(set_attr "type" "vecperm,vecload,mftgpr")]) + [(set_attr "type" "vecperm,vecload,vecperm")]) ;; V4SI splat (ISA 3.0) ;; When SI's are allowed in VSX registers, add XXSPLTW support diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 89071d2..34c1ab7 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2016-08-12 Michael Meissner <meissner@linux.vnet.ibm.com> + + * gcc.target/powerpc/vec-init-1.c: New tests to test various + vector initialization options. + * gcc.target/powerpc/vec-init-2.c: Likewise. + * gcc.target/powerpc/vec-init-3.c: New test to make sure MTVSRDD + is generated on ISA 3.0. + 2016-08-12 Patrick Palka <ppalka@gcc.gnu.org> PR middle-end/71654 diff --git a/gcc/testsuite/gcc.target/powerpc/vec-init-1.c b/gcc/testsuite/gcc.target/powerpc/vec-init-1.c new file mode 100644 index 0000000..753330a --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/vec-init-1.c @@ -0,0 +1,169 @@ +/* { dg-do run { target { powerpc*-*-linux* } } } */ +/* { dg-require-effective-target vsx_hw } */ +/* { dg-options "-O2 -mvsx" } */ + +#include <stdlib.h> +#include <stddef.h> +#include <altivec.h> + +#define ELEMENTS -1, 2, 0, -123456 +#define SPLAT 0x01234567 + +vector int sv = (vector int) { ELEMENTS }; +vector int splat = (vector int) { SPLAT, SPLAT, SPLAT, SPLAT }; +vector int sv_global, sp_global; +static vector int sv_static, sp_static; +static const int expected[] = { ELEMENTS }; + +extern void check (vector int a) + __attribute__((__noinline__)); + +extern void check_splat (vector int a) + __attribute__((__noinline__)); + +extern vector int pack_reg (int a, int b, int c, int d) + __attribute__((__noinline__)); + +extern vector int pack_const (void) + __attribute__((__noinline__)); + +extern void pack_ptr (vector int *p, int a, int b, int c, int d) + __attribute__((__noinline__)); + +extern void pack_static (int a, int b, int c, int d) + __attribute__((__noinline__)); + +extern void pack_global (int a, int b, int c, int d) + __attribute__((__noinline__)); + +extern vector int splat_reg (int a) + __attribute__((__noinline__)); + +extern vector int splat_const (void) + __attribute__((__noinline__)); + +extern void splat_ptr (vector int *p, int a) + __attribute__((__noinline__)); + +extern void splat_static (int a) + __attribute__((__noinline__)); + +extern void splat_global (int a) + __attribute__((__noinline__)); + +void +check (vector int a) +{ + size_t i; + + for (i = 0; i < 4; i++) + if (vec_extract (a, i) != expected[i]) + abort (); +} + +void +check_splat (vector int a) +{ + size_t i; + + for (i = 0; i < 4; i++) + if (vec_extract (a, i) != SPLAT) + abort (); +} + +vector int +pack_reg (int a, int b, int c, int d) +{ + return (vector int) { a, b, c, d }; +} + +vector int +pack_const (void) +{ + return (vector int) { ELEMENTS }; +} + +void +pack_ptr (vector int *p, int a, int b, int c, int d) +{ + *p = (vector int) { a, b, c, d }; +} + +void +pack_static (int a, int b, int c, int d) +{ + sv_static = (vector int) { a, b, c, d }; +} + +void +pack_global (int a, int b, int c, int d) +{ + sv_global = (vector int) { a, b, c, d }; +} + +vector int +splat_reg (int a) +{ + return (vector int) { a, a, a, a }; +} + +vector int +splat_const (void) +{ + return (vector int) { SPLAT, SPLAT, SPLAT, SPLAT }; +} + +void +splat_ptr (vector int *p, int a) +{ + *p = (vector int) { a, a, a, a }; +} + +void +splat_static (int a) +{ + sp_static = (vector int) { a, a, a, a }; +} + +void +splat_global (int a) +{ + sp_global = (vector int) { a, a, a, a }; +} + +int main (void) +{ + vector int sv2, sv3; + + check (sv); + + check (pack_reg (ELEMENTS)); + + check (pack_const ()); + + pack_ptr (&sv2, ELEMENTS); + check (sv2); + + pack_static (ELEMENTS); + check (sv_static); + + pack_global (ELEMENTS); + check (sv_global); + + check_splat (splat); + + check_splat (splat_reg (SPLAT)); + + check_splat (splat_const ()); + + splat_ptr (&sv2, SPLAT); + check_splat (sv2); + + splat_static (SPLAT); + check_splat (sp_static); + + splat_global (SPLAT); + check_splat (sp_global); + + return 0; +} diff --git a/gcc/testsuite/gcc.target/powerpc/vec-init-2.c b/gcc/testsuite/gcc.target/powerpc/vec-init-2.c new file mode 100644 index 0000000..a9fe6f4 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/vec-init-2.c @@ -0,0 +1,169 @@ +/* { dg-do run { target { powerpc*-*-linux* && lp64 } } } */ +/* { dg-require-effective-target vsx_hw } */ +/* { dg-options "-O2 -mvsx" } */ + +#include <stdlib.h> +#include <stddef.h> +#include <altivec.h> + +#define ELEMENTS -12345678L, 9L +#define SPLAT 0x0123456789ABCDE + +vector long sv = (vector long) { ELEMENTS }; +vector long splat = (vector long) { SPLAT, SPLAT }; +vector long sv_global, sp_global; +static vector long sv_static, sp_static; +static const int expected[] = { ELEMENTS }; + +extern void check (vector long a) + __attribute__((__noinline__)); + +extern void check_splat (vector long a) + __attribute__((__noinline__)); + +extern vector long pack_reg (long a, long b) + __attribute__((__noinline__)); + +extern vector long pack_const (void) + __attribute__((__noinline__)); + +extern void pack_ptr (vector long *p, long a, long b) + __attribute__((__noinline__)); + +extern void pack_static (long a, long b) + __attribute__((__noinline__)); + +extern void pack_global (long a, long b) + __attribute__((__noinline__)); + +extern vector long splat_reg (long a) + __attribute__((__noinline__)); + +extern vector long splat_const (void) + __attribute__((__noinline__)); + +extern void splat_ptr (vector long *p, long a) + __attribute__((__noinline__)); + +extern void splat_static (long a) + __attribute__((__noinline__)); + +extern void splat_global (long a) + __attribute__((__noinline__)); + +void +check (vector long a) +{ + size_t i; + + for (i = 0; i < 2; i++) + if (vec_extract (a, i) != expected[i]) + abort (); +} + +void +check_splat (vector long a) +{ + size_t i; + + for (i = 0; i < 2; i++) + if (vec_extract (a, i) != SPLAT) + abort (); +} + +vector long +pack_reg (long a, long b) +{ + return (vector long) { a, b }; +} + +vector long +pack_const (void) +{ + return (vector long) { ELEMENTS }; +} + +void +pack_ptr (vector long *p, long a, long b) +{ + *p = (vector long) { a, b }; +} + +void +pack_static (long a, long b) +{ + sv_static = (vector long) { a, b }; +} + +void +pack_global (long a, long b) +{ + sv_global = (vector long) { a, b }; +} + +vector long +splat_reg (long a) +{ + return (vector long) { a, a }; +} + +vector long +splat_const (void) +{ + return (vector long) { SPLAT, SPLAT }; +} + +void +splat_ptr (vector long *p, long a) +{ + *p = (vector long) { a, a }; +} + +void +splat_static (long a) +{ + sp_static = (vector long) { a, a }; +} + +void +splat_global (long a) +{ + sp_global = (vector long) { a, a }; +} + +int main (void) +{ + vector long sv2, sv3; + + check (sv); + + check (pack_reg (ELEMENTS)); + + check (pack_const ()); + + pack_ptr (&sv2, ELEMENTS); + check (sv2); + + pack_static (ELEMENTS); + check (sv_static); + + pack_global (ELEMENTS); + check (sv_global); + + check_splat (splat); + + check_splat (splat_reg (SPLAT)); + + check_splat (splat_const ()); + + splat_ptr (&sv2, SPLAT); + check_splat (sv2); + + splat_static (SPLAT); + check_splat (sp_static); + + splat_global (SPLAT); + check_splat (sp_global); + + return 0; +} diff --git a/gcc/testsuite/gcc.target/powerpc/vec-init-3.c b/gcc/testsuite/gcc.target/powerpc/vec-init-3.c new file mode 100644 index 0000000..d6d5469 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/vec-init-3.c @@ -0,0 +1,12 @@ +/* { 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" } */ + +vector long +merge (long a, long b) +{ + return (vector long) { a, b }; +} + +/* { dg-final { scan-assembler "mtvsrdd" } } */ |