]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
constraints.md (wo constraint): New constraint for ISA 3.0 (power9).
authorMichael Meissner <meissner@linux.vnet.ibm.com>
Mon, 4 Jan 2016 18:22:52 +0000 (18:22 +0000)
committerMichael Meissner <meissner@gcc.gnu.org>
Mon, 4 Jan 2016 18:22:52 +0000 (18:22 +0000)
[gcc]
2016-01-04  Michael Meissner  <meissner@linux.vnet.ibm.com>

* config/rs6000/constraints.md (wo constraint): New constraint for
ISA 3.0 (power9).

* config/rs6000/rs6000.c (rs6000_debug_reg_global): Add support
for wo constraint.
(rs6000_init_hard_regno_mode_ok): Likewise.

* config/rs6000/rs6000.h (r6000_reg_class_enum): Add support for
wo constraint.

* config/rs6000/altivec.md (altivec_vperm_<mode>): Clean up vperm
expanders not to have constraints.  Add support for ISA 3.0 xxperm
instruction.  Add support for fusing xxlor with xxperm.
(altivec_vperm_<mode>_internal): Likewise.
(altivec_vperm_v8hiv16qi): Likewise.
(altivec_vperm_<mode>v16q): Likewise.
(altivec_vperm_<mode>_uns): Likewise.
(vperm_v8hiv4si): Likewise.
(vperm_v16qiv8hi): Likewise.

* doc/md.texi (RS/6000 constraints): Document wo constraint.

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

* gcc.target/powerpc/p9-permute.c: New test for xxperm code
generation.

From-SVN: r232060

gcc/ChangeLog
gcc/config/rs6000/altivec.md
gcc/config/rs6000/constraints.md
gcc/config/rs6000/rs6000.c
gcc/config/rs6000/rs6000.h
gcc/doc/md.texi
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/powerpc/p9-permute.c [new file with mode: 0644]

index 6f600f5ab580653f1330315d0811f0c384b108ac..440143feb5afcf42d96f797e82d6874c72a440bc 100644 (file)
@@ -1,3 +1,27 @@
+2016-01-04  Michael Meissner  <meissner@linux.vnet.ibm.com>
+
+       * config/rs6000/constraints.md (wo constraint): New constraint for
+       ISA 3.0 (power9).
+
+       * config/rs6000/rs6000.c (rs6000_debug_reg_global): Add support
+       for wo constraint.
+       (rs6000_init_hard_regno_mode_ok): Likewise.
+
+       * config/rs6000/rs6000.h (r6000_reg_class_enum): Add support for
+       wo constraint.
+
+       * config/rs6000/altivec.md (altivec_vperm_<mode>): Clean up vperm
+       expanders not to have constraints.  Add support for ISA 3.0 xxperm
+       instruction.  Add support for fusing xxlor with xxperm.
+       (altivec_vperm_<mode>_internal): Likewise.
+       (altivec_vperm_v8hiv16qi): Likewise.
+       (altivec_vperm_<mode>v16q): Likewise.
+       (altivec_vperm_<mode>_uns): Likewise.
+       (vperm_v8hiv4si): Likewise.
+       (vperm_v16qiv8hi): Likewise.
+
+       * doc/md.texi (RS/6000 constraints): Document wo constraint.
+
 2016-01-04  Jakub Jelinek  <jakub@redhat.com>
 
        Update copyright years.
index 0db6598dffa3a78bd2f60605e2f4f4fa3f5d6717..d1f6acff97767e43461ba0220fd420a1f36d46ee 100644 (file)
   [(set_attr "type" "vecfloat")])
 
 (define_expand "altivec_vperm_<mode>"
-  [(set (match_operand:VM 0 "register_operand" "=v")
-       (unspec:VM [(match_operand:VM 1 "register_operand" "v")
-                   (match_operand:VM 2 "register_operand" "v")
-                   (match_operand:V16QI 3 "register_operand" "v")]
+  [(set (match_operand:VM 0 "register_operand" "")
+       (unspec:VM [(match_operand:VM 1 "register_operand" "")
+                   (match_operand:VM 2 "register_operand" "")
+                   (match_operand:V16QI 3 "register_operand" "")]
                   UNSPEC_VPERM))]
   "TARGET_ALTIVEC"
 {
     }
 })
 
+;; Slightly prefer vperm, since the target does not overlap the source
 (define_insn "*altivec_vperm_<mode>_internal"
-  [(set (match_operand:VM 0 "register_operand" "=v")
-       (unspec:VM [(match_operand:VM 1 "register_operand" "v")
-                   (match_operand:VM 2 "register_operand" "v")
-                   (match_operand:V16QI 3 "register_operand" "v")]
+  [(set (match_operand:VM 0 "register_operand" "=v,?wo,?&wo")
+       (unspec:VM [(match_operand:VM 1 "register_operand" "v,0,wo")
+                   (match_operand:VM 2 "register_operand" "v,wo,wo")
+                   (match_operand:V16QI 3 "register_operand" "v,wo,wo")]
                   UNSPEC_VPERM))]
   "TARGET_ALTIVEC"
-  "vperm %0,%1,%2,%3"
-  [(set_attr "type" "vecperm")])
+  "@
+   vperm %0,%1,%2,%3
+   xxperm %x0,%x2,%x3
+   xxlor %x0,%x1,%x1\t\t# xxperm fusion\;xxperm %x0,%x2,%x3"
+  [(set_attr "type" "vecperm")
+   (set_attr "length" "4,4,8")])
 
 (define_insn "altivec_vperm_v8hiv16qi"
-  [(set (match_operand:V16QI 0 "register_operand" "=v")
-       (unspec:V16QI [(match_operand:V8HI 1 "register_operand" "v")
-                      (match_operand:V8HI 2 "register_operand" "v")
-                      (match_operand:V16QI 3 "register_operand" "v")]
+  [(set (match_operand:V16QI 0 "register_operand" "=v,?wo,?&wo")
+       (unspec:V16QI [(match_operand:V8HI 1 "register_operand" "v,0,wo")
+                      (match_operand:V8HI 2 "register_operand" "v,wo,wo")
+                      (match_operand:V16QI 3 "register_operand" "v,wo,wo")]
                   UNSPEC_VPERM))]
   "TARGET_ALTIVEC"
-  "vperm %0,%1,%2,%3"
-  [(set_attr "type" "vecperm")])
+  "@
+   vperm %0,%1,%2,%3
+   xxperm %x0,%x2,%x3
+   xxlor %x0,%x1,%x1\t\t# xxperm fusion\;xxperm %x0,%x2,%x3"
+  [(set_attr "type" "vecperm")
+   (set_attr "length" "4,4,8")])
 
 (define_expand "altivec_vperm_<mode>_uns"
-  [(set (match_operand:VM 0 "register_operand" "=v")
-       (unspec:VM [(match_operand:VM 1 "register_operand" "v")
-                   (match_operand:VM 2 "register_operand" "v")
-                   (match_operand:V16QI 3 "register_operand" "v")]
+  [(set (match_operand:VM 0 "register_operand" "")
+       (unspec:VM [(match_operand:VM 1 "register_operand" "")
+                   (match_operand:VM 2 "register_operand" "")
+                   (match_operand:V16QI 3 "register_operand" "")]
                   UNSPEC_VPERM_UNS))]
   "TARGET_ALTIVEC"
 {
 })
 
 (define_insn "*altivec_vperm_<mode>_uns_internal"
-  [(set (match_operand:VM 0 "register_operand" "=v")
-       (unspec:VM [(match_operand:VM 1 "register_operand" "v")
-                   (match_operand:VM 2 "register_operand" "v")
-                   (match_operand:V16QI 3 "register_operand" "v")]
+  [(set (match_operand:VM 0 "register_operand" "=v,?wo,?&wo")
+       (unspec:VM [(match_operand:VM 1 "register_operand" "v,0,wo")
+                   (match_operand:VM 2 "register_operand" "v,wo,wo")
+                   (match_operand:V16QI 3 "register_operand" "v,wo,wo")]
                   UNSPEC_VPERM_UNS))]
   "TARGET_ALTIVEC"
-  "vperm %0,%1,%2,%3"
-  [(set_attr "type" "vecperm")])
+  "@
+   vperm %0,%1,%2,%3
+   xxperm %x0,%x2,%x3
+   xxlor %x0,%x1,%x1\t\t# xxperm fusion\;xxperm %x0,%x2,%x3"
+  [(set_attr "type" "vecperm")
+   (set_attr "length" "4,4,8")])
 
 (define_expand "vec_permv16qi"
   [(set (match_operand:V16QI 0 "register_operand" "")
   "")
 
 (define_insn "vperm_v8hiv4si"
-  [(set (match_operand:V4SI 0 "register_operand" "=v")
-        (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
-                   (match_operand:V4SI 2 "register_operand" "v")
-                   (match_operand:V16QI 3 "register_operand" "v")]
+  [(set (match_operand:V4SI 0 "register_operand" "=v,?wo,?&wo")
+        (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v,0,wo")
+                     (match_operand:V4SI 2 "register_operand" "v,wo,wo")
+                     (match_operand:V16QI 3 "register_operand" "v,wo,wo")]
                   UNSPEC_VPERMSI))]
   "TARGET_ALTIVEC"
-  "vperm %0,%1,%2,%3"
-  [(set_attr "type" "vecperm")])
+  "@
+   vperm %0,%1,%2,%3
+   xxperm %x0,%x2,%x3
+   xxlor %x0,%x1,%x1\t\t# xxperm fusion\;xxperm %x0,%x2,%x3"
+  [(set_attr "type" "vecperm")
+   (set_attr "length" "4,4,8")])
 
 (define_insn "vperm_v16qiv8hi"
-  [(set (match_operand:V8HI 0 "register_operand" "=v")
-        (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")
-                   (match_operand:V8HI 2 "register_operand" "v")
-                   (match_operand:V16QI 3 "register_operand" "v")]
+  [(set (match_operand:V8HI 0 "register_operand" "=v,?wo,?&wo")
+        (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v,0,wo")
+                     (match_operand:V8HI 2 "register_operand" "v,wo,wo")
+                     (match_operand:V16QI 3 "register_operand" "v,wo,wo")]
                   UNSPEC_VPERMHI))]
   "TARGET_ALTIVEC"
-  "vperm %0,%1,%2,%3"
-  [(set_attr "type" "vecperm")])
+  "@
+   vperm %0,%1,%2,%3
+   xxperm %x0,%x2,%x3
+   xxlor %x0,%x1,%x1\t\t# xxperm fusion\;xxperm %x0,%x2,%x3"
+  [(set_attr "type" "vecperm")
+   (set_attr "length" "4,4,8")])
 
 
 (define_expand "vec_unpacku_hi_v16qi"
index a6c8e528343c78a2b6947a62fddaf1b290e8505e..9eca7572c442f64f2b045f179d0d0242c3bf9c71 100644 (file)
@@ -99,7 +99,8 @@
 ;; There is a mode_attr that resolves to wm for SDmode and wn for SFmode
 (define_register_constraint "wn" "NO_REGS" "No register (NO_REGS).")
 
-;; wo is not currently used
+(define_register_constraint "wo" "rs6000_constraints[RS6000_CONSTRAINT_wo]"
+  "VSX register if the -mpower9-vector option was used or NO_REGS.")
 
 (define_register_constraint "wp" "rs6000_constraints[RS6000_CONSTRAINT_wp]"
   "VSX register to use for IEEE 128-bit fp TFmode, or NO_REGS.")
index f5884b88be620ebc04ce6a13df230d81b37d914b..cd5243adb0fe73ae716065dd7c6d04acc8da40e6 100644 (file)
@@ -2284,6 +2284,7 @@ rs6000_debug_reg_global (void)
           "wk reg_class = %s\n"
           "wl reg_class = %s\n"
           "wm reg_class = %s\n"
+          "wo reg_class = %s\n"
           "wp reg_class = %s\n"
           "wq reg_class = %s\n"
           "wr reg_class = %s\n"
@@ -2311,6 +2312,7 @@ rs6000_debug_reg_global (void)
           reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wk]],
           reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wl]],
           reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wm]],
+          reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wo]],
           reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wp]],
           reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wq]],
           reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wr]],
@@ -3019,7 +3021,11 @@ rs6000_init_hard_regno_mode_ok (bool global_init_p)
   if (TARGET_P9_DFORM)
     rs6000_constraints[RS6000_CONSTRAINT_wb] = ALTIVEC_REGS;
 
-  /* Support for new direct moves.  */
+  /* Support for ISA 3.0 (power9) vectors.  */
+  if (TARGET_P9_VECTOR)
+    rs6000_constraints[RS6000_CONSTRAINT_wo] = VSX_REGS;
+
+  /* Support for new direct moves (ISA 3.0 + 64bit).  */
   if (TARGET_DIRECT_MOVE_128)
     rs6000_constraints[RS6000_CONSTRAINT_we] = VSX_REGS;
 
index 8538df9f840e78bd1304c439d0836a1f09fe4ec7..6b0e64e693d3526b8716890d5a7a7f4e2ee0262b 100644 (file)
@@ -1535,6 +1535,7 @@ enum r6000_reg_class_enum {
   RS6000_CONSTRAINT_wk,                /* FPR/VSX register for DFmode direct moves. */
   RS6000_CONSTRAINT_wl,                /* FPR register for LFIWAX */
   RS6000_CONSTRAINT_wm,                /* VSX register for direct move */
+  RS6000_CONSTRAINT_wo,                /* VSX register for power9 vector.  */
   RS6000_CONSTRAINT_wp,                /* VSX reg for IEEE 128-bit fp TFmode. */
   RS6000_CONSTRAINT_wq,                /* VSX reg for IEEE 128-bit fp KFmode.  */
   RS6000_CONSTRAINT_wr,                /* GPR register if 64-bit  */
index 6dc43db228c1d7d58d670c529b0770fe9120edb6..faf39106fb0485483d799e0a1569c1302ed18887 100644 (file)
@@ -3102,8 +3102,8 @@ Any VSX register if the -mvsx option was used or NO_REGS.
 
 When using any of the register constraints (@code{wa}, @code{wd},
 @code{wf}, @code{wg}, @code{wh}, @code{wi}, @code{wj}, @code{wk},
-@code{wl}, @code{wm}, @code{wp}, @code{wq}, @code{ws}, @code{wt},
-@code{wu}, @code{wv}, @code{ww}, or @code{wy})
+@code{wl}, @code{wm}, @code{wo}, @code{wp}, @code{wq}, @code{ws},
+@code{wt}, @code{wu}, @code{wv}, @code{ww}, or @code{wy})
 that take VSX registers, you must use @code{%x<n>} in the template so
 that the correct register is used.  Otherwise the register number
 output in the assembly file will be incorrect if an Altivec register
@@ -3175,6 +3175,9 @@ VSX register if direct move instructions are enabled, or NO_REGS.
 @item wn
 No register (NO_REGS).
 
+@item wo
+VSX register to use for ISA 3.0 vector instructions, or NO_REGS.
+
 @item wp
 VSX register to use for IEEE 128-bit floating point TFmode, or NO_REGS.
 
index b29ab02c28cafd99a6852ee644d89ae13abe6bf9..1953ba5337ba1f0e10d69301db246022c526fce9 100644 (file)
@@ -1,3 +1,8 @@
+2016-01-04  Michael Meissner  <meissner@linux.vnet.ibm.com>
+
+       * gcc.target/powerpc/p9-permute.c: New test for xxperm code
+       generation.
+
 2016-01-04  Jakub Jelinek  <jakub@redhat.com>
 
        Update copyright years.
diff --git a/gcc/testsuite/gcc.target/powerpc/p9-permute.c b/gcc/testsuite/gcc.target/powerpc/p9-permute.c
new file mode 100644 (file)
index 0000000..3496d5e
--- /dev/null
@@ -0,0 +1,20 @@
+/* { dg-do compile { target { powerpc64le-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
+/* { dg-options "-mcpu=power9 -O2" } */
+
+#include <altivec.h>
+
+vector long long
+permute (vector long long *p, vector long long *q, vector unsigned char mask)
+{
+  vector long long a = *p;
+  vector long long b = *q;
+
+  /* Force a, b to be in FPR registers.  */
+  __asm__ (" # a: %x0, b: %x1" : "+d" (a), "+d" (b));
+
+  return vec_perm (a, b, mask);
+}
+
+/* { dg-final { scan-assembler    "xxperm" } } */
+/* { dg-final { scan-assembler-not "vperm"  } } */