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