rs6000.c (rs6000_expand_vector_set): Add support for using xxinsertw and vinsert...
authorMichael Meissner <meissner@linux.vnet.ibm.com>
Mon, 14 Nov 2016 19:55:42 +0000 (19:55 +0000)
committerMichael Meissner <meissner@gcc.gnu.org>
Mon, 14 Nov 2016 19:55:42 +0000 (19:55 +0000)
[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

gcc/ChangeLog
gcc/config/rs6000/rs6000.c
gcc/config/rs6000/vsx.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/powerpc/vec-set-char.c [new file with mode: 0644]
gcc/testsuite/gcc.target/powerpc/vec-set-int.c [new file with mode: 0644]
gcc/testsuite/gcc.target/powerpc/vec-set-short.c [new file with mode: 0644]

index fd132b5acef60dac84d45c032298417618993b6b..0044469e970d14714e5d290210ebcac99abf194b 100644 (file)
@@ -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.
index 609f26707c26b167adea98b16e5b658ec09a8fc7..c2234345f32bd062dd41b77d9678a5f0e0878088 100644 (file)
@@ -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.  */
index c5a57cbebb620993ea5a667ad20c15e1868400b4..75c16252f8ca66c48e1b04f9d7716b5746f74a45 100644 (file)
     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>
   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" ""))
index 1c3e66cdc8e9d0782ddb45b5e9a9b55e1752d75b..8c2c1a692396b01549db0fb8eb50caef1950bd7a 100644 (file)
@@ -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 (file)
index 0000000..2da79ef
--- /dev/null
@@ -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 (file)
index 0000000..dc97ac9
--- /dev/null
@@ -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 (file)
index 0000000..d827609
--- /dev/null
@@ -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"  } } */