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
*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:
"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"
+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.
--- /dev/null
+/* { 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;
+}