predicates.md (const_0_to_7_operand): New predicate, recognize 0..7.
authorMichael Meissner <meissner@linux.vnet.ibm.com>
Wed, 29 Jun 2016 23:54:12 +0000 (23:54 +0000)
committerMichael Meissner <meissner@gcc.gnu.org>
Wed, 29 Jun 2016 23:54:12 +0000 (23:54 +0000)
[gcc]
2016-06-29  Michael Meissner  <meissner@linux.vnet.ibm.com>

* config/rs6000/predicates.md (const_0_to_7_operand): New
predicate, recognize 0..7.
* config/rs6000/rs6000.c (rs6000_expand_vector_extract): Add
support for doing extracts from V16QImode, V8HImode, V4SImode
under ISA 3.0.
* config/rs6000/vsx.md (VSX_EXTRACT_I): Mode iterator for ISA 3.0
vector extract support.
(VSX_EXTRACT_PREDICATE): Mode attribute to validate element number
for ISA 3.0 vector extract.
(VSX_EX): Constraints to use for ISA 3.0 vector extract.
(vsx_extract_<mode>, VSX_EXTRACT_I): Add support for doing
extracts of a constant element number from small integer vectors
on 64-bit ISA 3.0 systems.
(vsx_extract_<mode>_di): Likewise.
* config/rs6000/rs6000.h (TARGET_VEXTRACTUB): New target macro to
say when we can do ISA 3.0 vector extracts.
* config/rs6000/rs6000.md (stfiwx): Allow DImode in Altivec
registers, using the stxsiwx instruction.

[gcc/testsuite]
2016-06-29  Michael Meissner  <meissner@linux.vnet.ibm.com>

* gcc.target/powerpc/p9-extract-1.c: New file to test ISA 3.0
vector extract instructions.
* gcc.target/powerpc/p9-extract-2.c: Likewise.

From-SVN: r237864

gcc/ChangeLog
gcc/config/rs6000/predicates.md
gcc/config/rs6000/rs6000.c
gcc/config/rs6000/rs6000.h
gcc/config/rs6000/rs6000.md
gcc/config/rs6000/vsx.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/powerpc/p9-extract-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/powerpc/p9-extract-2.c [new file with mode: 0644]

index b52c94e65a8e884bb1f2c47f5cac71d26a85203c..8df7f3c4b82c148ea41a4d11c8c82c1efe0cc7d3 100644 (file)
@@ -1,3 +1,24 @@
+2016-06-29  Michael Meissner  <meissner@linux.vnet.ibm.com>
+
+       * config/rs6000/predicates.md (const_0_to_7_operand): New
+       predicate, recognize 0..7.
+       * config/rs6000/rs6000.c (rs6000_expand_vector_extract): Add
+       support for doing extracts from V16QImode, V8HImode, V4SImode
+       under ISA 3.0.
+       * config/rs6000/vsx.md (VSX_EXTRACT_I): Mode iterator for ISA 3.0
+       vector extract support.
+       (VSX_EXTRACT_PREDICATE): Mode attribute to validate element number
+       for ISA 3.0 vector extract.
+       (VSX_EX): Constraints to use for ISA 3.0 vector extract.
+       (vsx_extract_<mode>, VSX_EXTRACT_I): Add support for doing
+       extracts of a constant element number from small integer vectors
+       on 64-bit ISA 3.0 systems.
+       (vsx_extract_<mode>_di): Likewise.
+       * config/rs6000/rs6000.h (TARGET_VEXTRACTUB): New target macro to
+       say when we can do ISA 3.0 vector extracts.
+       * config/rs6000/rs6000.md (stfiwx): Allow DImode in Altivec
+       registers, using the stxsiwx instruction.
+
 2016-06-29  Jim Wilson  <jim.wilson@linaro.org>
 
        * config/aarch64/aarch64-cores.def (qdf24xx): Use qdf24xx tuning.
index 0174667b800268a3a408c6a62bf059959ac69e9e..6436d5eb3a1ef536c78b76adf1028dfc8eef204c 100644 (file)
   (and (match_code "const_int")
        (match_test "IN_RANGE (INTVAL (op), 2, 3)")))
 
+;; Match op = 0..7.
+(define_predicate "const_0_to_7_operand"
+  (and (match_code "const_int")
+       (match_test "IN_RANGE (INTVAL (op), 0, 7)")))
+
 ;; Match op = 0..15
 (define_predicate "const_0_to_15_operand"
   (and (match_code "const_int")
index 62ad3e876d9b095b303ad6debc571d2be0a80aaa..b6e4df05077e3816d2d864d431cb2e2bdffb7618 100644 (file)
@@ -6916,6 +6916,30 @@ rs6000_expand_vector_extract (rtx target, rtx vec, int elt)
        case V4SFmode:
          emit_insn (gen_vsx_extract_v4sf (target, vec, GEN_INT (elt)));
          return;
+       case V16QImode:
+         if (TARGET_VEXTRACTUB)
+           {
+             emit_insn (gen_vsx_extract_v16qi (target, vec, GEN_INT (elt)));
+             return;
+           }
+         else
+           break;
+       case V8HImode:
+         if (TARGET_VEXTRACTUB)
+           {
+             emit_insn (gen_vsx_extract_v8hi (target, vec, GEN_INT (elt)));
+             return;
+           }
+         else
+           break;
+       case V4SImode:
+         if (TARGET_VEXTRACTUB)
+           {
+             emit_insn (gen_vsx_extract_v4si (target, vec, GEN_INT (elt)));
+             return;
+           }
+         else
+           break;
        }
     }
 
index 604d560718d4b2e2ea78606a3f1929a836943f17..f835f439416f10428183a349f4d36a9a8b0aab8c 100644 (file)
@@ -599,6 +599,9 @@ extern int rs6000_vector_align[];
 #define TARGET_VADDUQM         (TARGET_P8_VECTOR && TARGET_POWERPC64)
 #define TARGET_DIRECT_MOVE_128 (TARGET_P9_VECTOR && TARGET_DIRECT_MOVE \
                                 && TARGET_POWERPC64)
+#define TARGET_VEXTRACTUB      (TARGET_P9_VECTOR && TARGET_DIRECT_MOVE \
+                                && TARGET_UPPER_REGS_DF \
+                                && TARGET_UPPER_REGS_DI && TARGET_POWERPC64)
 
 /* Byte/char syncs were added as phased in for ISA 2.06B, but are not present
    in power7, so conditionalize them on p8 features.  TImode syncs need quad
index 12f5d6fd288b363eb74956ba780393fd098f6282..81d189be1667cb071877f30dadafda72005ab6c9 100644 (file)
 
 ; An UNSPEC is used so we don't have to support SImode in FP registers.
 (define_insn "stfiwx"
-  [(set (match_operand:SI 0 "memory_operand" "=Z")
-       (unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "d")]
+  [(set (match_operand:SI 0 "memory_operand" "=Z,Z")
+       (unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "d,wv")]
                   UNSPEC_STFIWX))]
   "TARGET_PPC_GFXOPT"
-  "stfiwx %1,%y0"
+  "@
+   stfiwx %1,%y0
+   stxsiwx %x1,%y0"
   [(set_attr "type" "fpstore")])
 
 ;; If we don't have a direct conversion to single precision, don't enable this
index 4fa7f6a181c3479aa694c5f440234ca99cedad62..2e1d41d61431b9cd8bd02a8e92eb3c5aec22c7e0 100644 (file)
 (define_mode_iterator VSINT_84  [V4SI V2DI DI])
 (define_mode_iterator VSINT_842 [V8HI V4SI V2DI])
 
+;; Iterator for ISA 3.0 vector extract/insert of integer vectors
+(define_mode_iterator VSX_EXTRACT_I [V16QI V8HI V4SI])
+
+;; Mode attribute to give the correct predicate for ISA 3.0 vector extract and
+;; insert to validate the operand number.
+(define_mode_attr VSX_EXTRACT_PREDICATE [(V16QI "const_0_to_15_operand")
+                                        (V8HI  "const_0_to_7_operand")
+                                        (V4SI  "const_0_to_3_operand")])
+
+;; Mode attribute to give the constraint for vector extract and insert
+;; operations.
+(define_mode_attr VSX_EX [(V16QI "v")
+                         (V8HI  "v")
+                         (V4SI  "wa")])
+
 ;; Constants for creating unspecs
 (define_c_enum "unspec"
   [UNSPEC_VSX_CONCAT
     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.
+(define_insn_and_split  "vsx_extract_<mode>"
+  [(set (match_operand:<VS_scalar> 0 "nonimmediate_operand" "=r,Z")
+       (vec_select:<VS_scalar>
+        (match_operand:VSX_EXTRACT_I 1 "gpc_reg_operand" "<VSX_EX>,<VSX_EX>")
+        (parallel [(match_operand:QI 2 "<VSX_EXTRACT_PREDICATE>" "n,n")])))
+   (clobber (match_scratch:DI 3 "=<VSX_EX>,<VSX_EX>"))]
+  "VECTOR_MEM_VSX_P (<MODE>mode) && TARGET_VEXTRACTUB"
+  "#"
+  "&& (reload_completed || MEM_P (operands[0]))"
+  [(const_int 0)]
+{
+  rtx dest = operands[0];
+  rtx src = operands[1];
+  rtx element = operands[2];
+  rtx di_tmp = operands[3];
+
+  if (GET_CODE (di_tmp) == SCRATCH)
+    di_tmp = gen_reg_rtx (DImode);
+
+  emit_insn (gen_vsx_extract_<mode>_di (di_tmp, src, element));
+
+  if (REG_P (dest))
+    emit_move_insn (gen_rtx_REG (DImode, REGNO (dest)), di_tmp);
+  else if (SUBREG_P (dest))
+    emit_move_insn (gen_rtx_REG (DImode, subreg_regno (dest)), di_tmp);
+  else if (MEM_P (operands[0]))
+    {
+      if (can_create_pseudo_p ())
+       dest = rs6000_address_for_fpconvert (dest);
+
+      if (<MODE>mode == V16QImode)
+       emit_insn (gen_p9_stxsibx (dest, di_tmp));
+      else if (<MODE>mode == V8HImode)
+       emit_insn (gen_p9_stxsihx (dest, di_tmp));
+      else if (<MODE>mode == V4SImode)
+       emit_insn (gen_stfiwx (dest, di_tmp));
+      else
+       gcc_unreachable ();
+    }
+  else
+    gcc_unreachable ();
+
+  DONE;
+}
+  [(set_attr "type" "vecsimple,fpstore")])
+
+(define_insn  "vsx_extract_<mode>_di"
+  [(set (match_operand:DI 0 "gpc_reg_operand" "=<VSX_EX>")
+       (zero_extend:DI
+        (vec_select:<VS_scalar>
+         (match_operand:VSX_EXTRACT_I 1 "gpc_reg_operand" "<VSX_EX>")
+         (parallel [(match_operand:QI 2 "<VSX_EXTRACT_PREDICATE>" "n")]))))]
+  "VECTOR_MEM_VSX_P (<MODE>mode) && TARGET_VEXTRACTUB"
+{
+  int element = INTVAL (operands[2]);
+  int unit_size = GET_MODE_UNIT_SIZE (<MODE>mode);
+  int offset = ((VECTOR_ELT_ORDER_BIG)
+               ? unit_size * element
+               : unit_size * (GET_MODE_NUNITS (<MODE>mode) - 1 - element));
+
+  operands[2] = GEN_INT (offset);
+  if (unit_size == 4)
+    return "xxextractuw %x0,%x1,%2";
+  else
+    return "vextractu<wd> %0,%1,%2";
+}
+  [(set_attr "type" "vecsimple")])
+
+
 ;; Expanders for builtins
 (define_expand "vsx_mergel_<mode>"
   [(use (match_operand:VSX_D 0 "vsx_register_operand" ""))
index 83cacd4d466f1480ff916d2951784e7e9b398376..9763bacb9d30e71cedb44a8d1ac78aa36d7cc143 100644 (file)
@@ -1,3 +1,9 @@
+2016-06-29  Michael Meissner  <meissner@linux.vnet.ibm.com>
+
+       * gcc.target/powerpc/p9-extract-1.c: New file to test ISA 3.0
+       vector extract instructions.
+       * gcc.target/powerpc/p9-extract-2.c: Likewise.
+
 2016-06-29  Jerry DeLisle  <jvdelisle@gcc.gnu.org>
 
        PR fortran/71686
diff --git a/gcc/testsuite/gcc.target/powerpc/p9-extract-1.c b/gcc/testsuite/gcc.target/powerpc/p9-extract-1.c
new file mode 100644 (file)
index 0000000..1aefc8f
--- /dev/null
@@ -0,0 +1,26 @@
+/* { 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" } */
+
+#include <altivec.h>
+
+int extract_int_0 (vector int a) { return vec_extract (a, 0); }
+int extract_int_3 (vector int a) { return vec_extract (a, 3); }
+
+int extract_short_0 (vector short a) { return vec_extract (a, 0); }
+int extract_short_3 (vector short a) { return vec_extract (a, 7); }
+
+int extract_schar_0 (vector signed char a) { return vec_extract (a, 0); }
+int extract_schar_3 (vector signed char a) { return vec_extract (a, 15); }
+
+/* { dg-final { scan-assembler     "vextractub"  } } */
+/* { dg-final { scan-assembler     "vextractuh"  } } */
+/* { dg-final { scan-assembler     "xxextractuw" } } */
+/* { dg-final { scan-assembler     "mfvsrd"      } } */
+/* { dg-final { scan-assembler-not "stxvd2x"     } } */
+/* { dg-final { scan-assembler-not "stxv"        } } */
+/* { dg-final { scan-assembler-not "lwa"         } } */
+/* { dg-final { scan-assembler-not "lwz"         } } */
+/* { dg-final { scan-assembler-not "lha"         } } */
+/* { dg-final { scan-assembler-not "lhz"         } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/p9-extract-2.c b/gcc/testsuite/gcc.target/powerpc/p9-extract-2.c
new file mode 100644 (file)
index 0000000..34f9bdd
--- /dev/null
@@ -0,0 +1,27 @@
+/* { 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" } */
+
+#include <altivec.h>
+
+void extract_int_0 (int *p, vector int a) { *p = vec_extract (a, 0); }
+void extract_int_3 (int *p, vector int a) { *p = vec_extract (a, 3); }
+
+void extract_short_0 (short *p, vector short a) { *p = vec_extract (a, 0); }
+void extract_short_3 (short *p, vector short a) { *p = vec_extract (a, 7); }
+
+void extract_schar_0 (signed char *p, vector signed char a) { *p = vec_extract (a, 0); }
+void extract_schar_3 (signed char *p, vector signed char a) { *p = vec_extract (a, 15); }
+
+/* { dg-final { scan-assembler     "vextractub"      } } */
+/* { dg-final { scan-assembler     "vextractuh"      } } */
+/* { dg-final { scan-assembler     "xxextractuw"     } } */
+/* { dg-final { scan-assembler     "stxsibx"         } } */
+/* { dg-final { scan-assembler     "stxsihx"         } } */
+/* { dg-final { scan-assembler     "stfiwx\|stxsiwx" } } */
+/* { dg-final { scan-assembler-not "mfvsrd"          } } */
+/* { dg-final { scan-assembler-not "stxvd2x"         } } */
+/* { dg-final { scan-assembler-not "stxv"            } } */
+/* { dg-final { scan-assembler-not "lwa"             } } */
+/* { dg-final { scan-assembler-not "stw"             } } */