S/390: arch12: Add support for new vector bit
authorAndreas Krebbel <krebbel@linux.vnet.ibm.com>
Fri, 24 Mar 2017 14:00:43 +0000 (14:00 +0000)
committerAndreas Krebbel <krebbel@gcc.gnu.org>
Fri, 24 Mar 2017 14:00:43 +0000 (14:00 +0000)
 operations.

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  <krebbel@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  <krebbel@linux.vnet.ibm.com>

* gcc.target/s390/vxe/bitops-1.c: New test.

From-SVN: r246453

gcc/config/s390/s390.c
gcc/config/s390/vector.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/s390/vxe/bitops-1.c [new file with mode: 0644]

index c94edcc7a6238357272c9f5e6e09c9de9714b73e..416a15ed549dc24c68b720d918b1e93a7a2e47b2 100644 (file)
@@ -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:
index 7ddeb9a2f9c5d5021af0c7e3dfc38d72c88798bb..68a8ed095a36a2a3676fc06e2aee9fd7c6685b01 100644 (file)
   "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
 
   "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
 
   "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"
index 4c59d68fb94783f675b6021b7f4de5715bd8906d..1a74e0dac65007378789ce6783a52524df83ac50 100644 (file)
@@ -1,3 +1,7 @@
+2017-03-24  Andreas Krebbel  <krebbel@linux.vnet.ibm.com>
+
+       * gcc.target/s390/vxe/bitops-1.c: New test.
+
 2017-03-24  Andreas Krebbel  <krebbel@linux.vnet.ibm.com>
 
        * gcc.target/s390/s390.exp: Run tests in arch12 and vxe dirs.
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 (file)
index 0000000..bdf7457
--- /dev/null
@@ -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;
+}