S/390: arch12: Add support for new vector bit

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
This commit is contained in:
Andreas Krebbel 2017-03-24 14:00:43 +00:00 committed by Andreas Krebbel
parent 6654e96fc8
commit 9ec988605d
4 changed files with 100 additions and 2 deletions

View 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:

View File

@ -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
; Bitwise inversion of a vector - used for vec_cmpne
(define_insn "*not<mode>"
(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
(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"

View 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.

View File

@ -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;
}