This patch adds support for the new bit operations introduced with
arch12.

The patch also renames the one complement pattern to the proper RTL
standard name.

2017-03-24  Andreas Krebbel  <kreb...@linux.vnet.ibm.com>

        * config/s390/s390.c (s390_rtx_costs): Return low costs for the
        canonical form of ~AND to make sure the new instruction will be
        used.
        * config/s390/vector.md ("notand<mode>3", "ior_not<mode>3")
        ("notxor<mode>3"): Add new pattern definitions.
        ("*not<mode>"): Rename to ...
        ("one_cmpl<mode>2"): ... this.

gcc/testsuite/ChangeLog:

2017-03-24  Andreas Krebbel  <kreb...@linux.vnet.ibm.com>

        * gcc.target/s390/vxe/bitops-1.c: New test.
---
 gcc/config/s390/s390.c                       | 15 ++++++++
 gcc/config/s390/vector.md                    | 31 +++++++++++++++--
 gcc/testsuite/ChangeLog                      |  4 +++
 gcc/testsuite/gcc.target/s390/vxe/bitops-1.c | 52 ++++++++++++++++++++++++++++
 4 files changed, 100 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/s390/vxe/bitops-1.c

diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c
index c94edcc..416a15e 100644
--- a/gcc/config/s390/s390.c
+++ b/gcc/config/s390/s390.c
@@ -3373,6 +3373,21 @@ s390_rtx_costs (rtx x, machine_mode mode, int outer_code,
          *total = COSTS_N_INSNS (2);
          return true;
        }
+
+      /* ~AND on a 128 bit mode.  This can be done using a vector
+        instruction.  */
+      if (TARGET_VXE
+         && GET_CODE (XEXP (x, 0)) == NOT
+         && GET_CODE (XEXP (x, 1)) == NOT
+         && REG_P (XEXP (XEXP (x, 0), 0))
+         && REG_P (XEXP (XEXP (x, 1), 0))
+         && GET_MODE_SIZE (GET_MODE (XEXP (XEXP (x, 0), 0))) == 16
+         && s390_hard_regno_mode_ok (VR0_REGNUM,
+                                     GET_MODE (XEXP (XEXP (x, 0), 0))))
+       {
+         *total = COSTS_N_INSNS (1);
+         return true;
+       }
       /* fallthrough */
     case ASHIFT:
     case ASHIFTRT:
diff --git a/gcc/config/s390/vector.md b/gcc/config/s390/vector.md
index 7ddeb9a..68a8ed0 100644
--- a/gcc/config/s390/vector.md
+++ b/gcc/config/s390/vector.md
@@ -655,6 +655,15 @@
   "vn\t%v0,%v1,%v2"
   [(set_attr "op_type" "VRR")])
 
+; Vector not and
+
+(define_insn "notand<mode>3"
+  [(set (match_operand:VT                 0 "register_operand" "=v")
+       (ior:VT (not:VT (match_operand:VT 1 "register_operand" "%v"))
+               (not:VT (match_operand:VT 2 "register_operand"  "v"))))]
+  "TARGET_VXE"
+  "vnn\t%v0,%v1,%v2"
+  [(set_attr "op_type" "VRR")])
 
 ; Vector or
 
@@ -666,6 +675,15 @@
   "vo\t%v0,%v1,%v2"
   [(set_attr "op_type" "VRR")])
 
+; Vector or with complement
+
+(define_insn "ior_not<mode>3"
+  [(set (match_operand:VT                 0 "register_operand" "=v")
+       (ior:VT (not:VT (match_operand:VT 2 "register_operand"  "v"))
+               (match_operand:VT         1 "register_operand" "%v")))]
+  "TARGET_VXE"
+  "voc\t%v0,%v1,%v2"
+  [(set_attr "op_type" "VRR")])
 
 ; Vector xor
 
@@ -677,9 +695,18 @@
   "vx\t%v0,%v1,%v2"
   [(set_attr "op_type" "VRR")])
 
+; Vector not xor
+
+(define_insn "notxor<mode>3"
+  [(set (match_operand:VT                 0 "register_operand" "=v")
+       (not:VT (xor:VT (match_operand:VT 1 "register_operand" "%v")
+                       (match_operand:VT 2 "register_operand"  "v"))))]
+  "TARGET_VXE"
+  "vnx\t%v0,%v1,%v2"
+  [(set_attr "op_type" "VRR")])
 
-; Bitwise inversion of a vector - used for vec_cmpne
-(define_insn "*not<mode>"
+; Bitwise inversion of a vector
+(define_insn "one_cmpl<mode>2"
   [(set (match_operand:VT         0 "register_operand" "=v")
        (not:VT (match_operand:VT 1 "register_operand"  "v")))]
   "TARGET_VX"
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 9ca13ab..bbdd3c8 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,9 @@
 2017-03-24  Andreas Krebbel  <kreb...@linux.vnet.ibm.com>
 
+       * gcc.target/s390/vxe/bitops-1.c: New test.
+
+2017-03-24  Andreas Krebbel  <kreb...@linux.vnet.ibm.com>
+
        * gcc.target/s390/s390.exp: Run tests in arch12 and vxe dirs.
        * lib/target-supports.exp: Add effective target check s390_vxe.
 
diff --git a/gcc/testsuite/gcc.target/s390/vxe/bitops-1.c 
b/gcc/testsuite/gcc.target/s390/vxe/bitops-1.c
new file mode 100644
index 0000000..bdf7457
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/vxe/bitops-1.c
@@ -0,0 +1,52 @@
+/* { dg-do run } */
+/* { dg-options "-O3 -mzarch -march=arch12 --save-temps" } */
+/* { dg-require-effective-target s390_vxe } */
+
+typedef unsigned int       uv4si __attribute__((vector_size(16)));
+
+uv4si __attribute__((noinline))
+not_xor (uv4si a, uv4si b)
+{
+  return ~(a ^ b);
+}
+/* { dg-final { scan-assembler-times "vnx\t%v24,%v24,%v26" 1 } } */
+
+uv4si __attribute__((noinline))
+not_and (uv4si a, uv4si b)
+{
+  return ~(a & b);
+}
+/* { dg-final { scan-assembler-times "vnn\t%v24,%v24,%v26" 1 } } */
+
+uv4si __attribute__((noinline))
+or_not (uv4si a, uv4si b)
+{
+  return a | ~b;
+}
+/* { dg-final { scan-assembler-times "voc\t%v24,%v24,%v26" 1 } } */
+
+
+int
+main ()
+{
+  uv4si a = (uv4si){ 42, 1, 0, 2 };
+  uv4si b = (uv4si){ 42, 2, 0, 2 };
+  uv4si c;
+
+  c = not_xor (a, b);
+
+  if (c[0] != ~0 || c[1] != ~3 || c[2] != ~0 || c[3] != ~0)
+    __builtin_abort ();
+
+  c = not_and (a, b);
+
+  if (c[0] != ~42 || c[1] != ~0 || c[2] != ~0 || c[3] != ~2)
+    __builtin_abort ();
+
+  c = or_not (a, b);
+
+  if (c[0] != ~0 || c[1] != ~2 || c[2] != ~0 || c[3] != ~0)
+    __builtin_abort ();
+
+  return 0;
+}
-- 
2.9.1

Reply via email to