Commit 2de2b3f9 by Andreas Krebbel Committed by Andreas Krebbel

S/390: arch12: Support new vector floating point modes.

This patch adds support for the new floating point vector elements (SF
and TF) introduced with arch12.

gcc/ChangeLog:

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

	* config/s390/s390.c (s390_expand_vec_compare): Support other
	vector floating point modes than just V2DF.
	(s390_expand_vcond): Likewise.
	(s390_hard_regno_mode_ok): Allow SFmode values in VRs.
	(s390_cannot_change_mode_class): Prevent mode changes between TF
	and V1TF in vector registers.
	* config/s390/s390.md (DF, SF): New mode attributes.
	("*cmp<mode>_ccs", "add<mode>3", "sub<mode>3", "mul<mode>3")
	("fma<mode>4", "fms<mode>4", "div<mode>3", "*neg<mode>2"): Add
	SFmode support for VRs.
	* config/s390/vector.md (V_HW, V_HW2, VT_HW, ti*, nonvec): Add new
	vector fp modes.
	(VFT, VF_HW): New mode iterators.
	(vw, sdx): New mode attributes.
	("addv2df3", "subv2df3", "mulv2df3", "divv2df3", "sqrtv2df2")
	("fmav2df4","fmsv2df4", "negv2df2", "absv2df2", "*negabsv2df2")
	("smaxv2df3", "sminv2df3", "*vec_cmp<VFCMP_HW_OP:code>v2df_nocc")
	("vec_cmpuneqv2df", "vec_cmpltgtv2df", "vec_orderedv2df")
	("vec_unorderedv2df"): Adjust the v2df only patterns to support
	also the new vector floating point modes.  Renaming to ...

	("add<mode>3", "sub<mode>3", "mul<mode>3", "div<mode>3")
	("sqrt<mode>2", "fma<mode>4", "fms<mode>4", "neg<mode>2")
	("abs<mode>2", "negabs<mode>2", "smax<mode>3")
	("smin<mode>3", "*vec_cmp<VFCMP_HW_OP:code><mode>_nocc")
	("vec_cmpuneq<mode>", "vec_cmpltgt<mode>", "vec_ordered<mode>")
	("vec_unordered<mode>"): ... these.

	("neg_fma<mode>4", "neg_fms<mode>4", "*smax<mode>3_vxe")
	("*smin<mode>3_vxe", "*sminv2df3_vx", "*vec_extendv4sf")
	("*vec_extendv2df"): New insn definitions.

gcc/testsuite/ChangeLog:

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

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

From-SVN: r246458
parent 7d2fd075
2017-03-24 Andreas Krebbel <krebbel@linux.vnet.ibm.com>
* config/s390/s390.c (s390_expand_vec_compare): Support other
vector floating point modes than just V2DF.
(s390_expand_vcond): Likewise.
(s390_hard_regno_mode_ok): Allow SFmode values in VRs.
(s390_cannot_change_mode_class): Prevent mode changes between TF
and V1TF in vector registers.
* config/s390/s390.md (DF, SF): New mode attributes.
("*cmp<mode>_ccs", "add<mode>3", "sub<mode>3", "mul<mode>3")
("fma<mode>4", "fms<mode>4", "div<mode>3", "*neg<mode>2"): Add
SFmode support for VRs.
* config/s390/vector.md (V_HW, V_HW2, VT_HW, ti*, nonvec): Add new
vector fp modes.
(VFT, VF_HW): New mode iterators.
(vw, sdx): New mode attributes.
("addv2df3", "subv2df3", "mulv2df3", "divv2df3", "sqrtv2df2")
("fmav2df4","fmsv2df4", "negv2df2", "absv2df2", "*negabsv2df2")
("smaxv2df3", "sminv2df3", "*vec_cmp<VFCMP_HW_OP:code>v2df_nocc")
("vec_cmpuneqv2df", "vec_cmpltgtv2df", "vec_orderedv2df")
("vec_unorderedv2df"): Adjust the v2df only patterns to support
also the new vector floating point modes. Renaming to ...
("add<mode>3", "sub<mode>3", "mul<mode>3", "div<mode>3")
("sqrt<mode>2", "fma<mode>4", "fms<mode>4", "neg<mode>2")
("abs<mode>2", "negabs<mode>2", "smax<mode>3")
("smin<mode>3", "*vec_cmp<VFCMP_HW_OP:code><mode>_nocc")
("vec_cmpuneq<mode>", "vec_cmpltgt<mode>", "vec_ordered<mode>")
("vec_unordered<mode>"): ... these.
("neg_fma<mode>4", "neg_fms<mode>4", "*smax<mode>3_vxe")
("*smin<mode>3_vxe", "*sminv2df3_vx", "*vec_extendv4sf")
("*vec_extendv2df"): New insn definitions.
2017-03-24 Andreas Krebbel <krebbel@linux.vnet.ibm.com>
* config/s390/s390.md ("*adddi3_sign", "*subdi3_sign", "mulditi3")
("mulditi3_2", "*muldi3_sign"): New patterns.
("muldi3", "*muldi3", "mulsi3", "*mulsi3"): Add an expander and
......
......@@ -2496,7 +2496,7 @@ B_DEF (s390_vec_ctsl, vec_ctsl, 0,
B_DEF (s390_vec_ctul, vec_ctul, 0, B_VX, O2_U3, BT_FN_UV2DI_V2DF_INT) /* vclgdb */
B_DEF (s390_vcgdb, vec_df_to_di_s64, 0, B_VX, O2_U3, BT_FN_V2DI_V2DF_INT) /* vcgdb */
B_DEF (s390_vclgdb, vec_df_to_di_u64, 0, B_VX, O2_U3, BT_FN_UV2DI_V2DF_INT) /* vclgdb */
B_DEF (s390_vfidb, vfidb, 0, B_VX, O2_U4 | O3_U3, BT_FN_V2DF_V2DF_UCHAR_UCHAR)
B_DEF (s390_vfidb, vfiv2df, 0, B_VX, O2_U4 | O3_U3, BT_FN_V2DF_V2DF_UCHAR_UCHAR)
B_DEF (s390_vec_ld2f, vec_ld2f, 0, B_VX, 0, BT_FN_V2DF_FLTCONSTPTR) /* vldeb */
B_DEF (s390_vec_st2f, vec_st2f, 0, B_VX, 0, BT_FN_VOID_V2DF_FLTPTR) /* vledb */
B_DEF (s390_vfmadb, fmav2df4, 0, B_VX, 0, BT_FN_V2DF_V2DF_V2DF_V2DF)
......
......@@ -6201,7 +6201,7 @@ s390_expand_vec_compare (rtx target, enum rtx_code cond,
bool neg_p = false, swap_p = false;
rtx tmp;
if (GET_MODE (cmp_op1) == V2DFmode)
if (GET_MODE_CLASS (GET_MODE (cmp_op1)) == MODE_VECTOR_FLOAT)
{
switch (cond)
{
......@@ -6447,7 +6447,8 @@ s390_expand_vcond (rtx target, rtx then, rtx els,
/* We always use an integral type vector to hold the comparison
result. */
result_mode = cmp_mode == V2DFmode ? V2DImode : cmp_mode;
result_mode = mode_for_vector (int_mode_for_mode (GET_MODE_INNER (cmp_mode)),
GET_MODE_NUNITS (cmp_mode));
result_target = gen_reg_rtx (result_mode);
/* We allow vector immediates as comparison operands that
......@@ -10112,6 +10113,7 @@ s390_hard_regno_mode_ok (unsigned int regno, machine_mode mode)
return ((GET_MODE_CLASS (mode) == MODE_INT
&& s390_class_max_nregs (VEC_REGS, mode) == 1)
|| mode == DFmode
|| (TARGET_VXE && mode == SFmode)
|| s390_vector_mode_supported_p (mode));
break;
case FP_REGS:
......@@ -10256,6 +10258,13 @@ s390_cannot_change_mode_class (machine_mode from_mode,
machine_mode small_mode;
machine_mode big_mode;
/* V1TF and TF have different representations in vector
registers. */
if (reg_classes_intersect_p (VEC_REGS, rclass)
&& ((from_mode == V1TFmode && to_mode == TFmode)
|| (from_mode == TFmode && to_mode == V1TFmode)))
return 1;
if (GET_MODE_SIZE (from_mode) == GET_MODE_SIZE (to_mode))
return 0;
......
......@@ -674,6 +674,12 @@
(define_mode_attr DFDI [(TF "0") (DF "*") (SF "0")
(TD "0") (DD "0") (DD "0")
(TI "0") (DI "*") (SI "0")])
(define_mode_attr DF [(TF "0") (DF "*") (SF "0")
(TD "0") (DD "0") (DD "0")
(TI "0") (DI "0") (SI "0")])
(define_mode_attr SF [(TF "0") (DF "0") (SF "*")
(TD "0") (DD "0") (DD "0")
(TI "0") (DI "0") (SI "0")])
;; This attribute is used in the operand constraint list
;; for instructions dealing with the sign bit of 32 or 64bit fp values.
......@@ -1325,20 +1331,21 @@
})
; cxtr, cdtr, cxbr, cdbr, cebr, cdb, ceb, wfcdb
; VX: TFmode in FPR pairs: use cxbr instead of wfcxb
; cxtr, cdtr, cxbr, cdbr, cebr, cdb, ceb, wfcsb, wfcdb
(define_insn "*cmp<mode>_ccs"
[(set (reg CC_REGNUM)
(compare (match_operand:FP 0 "register_operand" "f,f,v")
(match_operand:FP 1 "general_operand" "f,R,v")))]
(compare (match_operand:FP 0 "register_operand" "f,f,v,v")
(match_operand:FP 1 "general_operand" "f,R,v,v")))]
"s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT"
"@
c<xde><bt>r\t%0,%1
c<xde>b\t%0,%1
wfcdb\t%0,%1"
[(set_attr "op_type" "RRE,RXE,VRR")
(set_attr "cpu_facility" "*,*,vx")
(set_attr "enabled" "*,<DSF>,<DFDI>")])
wfcdb\t%0,%1
wfcsb\t%0,%1"
[(set_attr "op_type" "RRE,RXE,VRR,VRR")
(set_attr "cpu_facility" "*,*,vx,vxe")
(set_attr "enabled" "*,<DSF>,<DF>,<SF>")])
; Compare and Branch instructions
......@@ -5159,6 +5166,7 @@
; extend(sf|df)(df|tf)2 instruction pattern(s).
;
; wflls
(define_insn "*extendsfdf2_z13"
[(set (match_operand:DF 0 "register_operand" "=f,f,v")
(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "f,R,v")))]
......@@ -5811,20 +5819,21 @@
; axbr, adbr, aebr, axb, adb, aeb, adtr, axtr
; FIXME: wfadb does not clobber cc
(define_insn "add<mode>3"
[(set (match_operand:FP 0 "register_operand" "=f,f,f,v")
(plus:FP (match_operand:FP 1 "nonimmediate_operand" "%f,0,0,v")
(match_operand:FP 2 "general_operand" "f,f,R,v")))
[(set (match_operand:FP 0 "register_operand" "=f,f,f,v,v")
(plus:FP (match_operand:FP 1 "nonimmediate_operand" "%f,0,0,v,v")
(match_operand:FP 2 "general_operand" "f,f,R,v,v")))
(clobber (reg:CC CC_REGNUM))]
"TARGET_HARD_FLOAT"
"@
a<xde>tr\t%0,%1,%2
a<xde>br\t%0,%2
a<xde>b\t%0,%2
wfadb\t%v0,%v1,%v2"
[(set_attr "op_type" "RRF,RRE,RXE,VRR")
wfadb\t%v0,%v1,%v2
wfasb\t%v0,%v1,%v2"
[(set_attr "op_type" "RRF,RRE,RXE,VRR,VRR")
(set_attr "type" "fsimp<mode>")
(set_attr "cpu_facility" "*,*,*,vx")
(set_attr "enabled" "<nBFP>,<nDFP>,<DSF>,<DFDI>")])
(set_attr "cpu_facility" "*,*,*,vx,vxe")
(set_attr "enabled" "<nBFP>,<nDFP>,<DSF>,<DF>,<SF>")])
; axbr, adbr, aebr, axb, adb, aeb, adtr, axtr
(define_insn "*add<mode>3_cc"
......@@ -6249,22 +6258,24 @@
; sub(tf|df|sf|td|dd)3 instruction pattern(s).
;
; FIXME: (clobber (match_scratch:CC 3 "=c,c,c,X,X")) does not work - why?
; sxbr, sdbr, sebr, sdb, seb, sxtr, sdtr
(define_insn "sub<mode>3"
[(set (match_operand:FP 0 "register_operand" "=f,f,f,v")
(minus:FP (match_operand:FP 1 "register_operand" "f,0,0,v")
(match_operand:FP 2 "general_operand" "f,f,R,v")))
[(set (match_operand:FP 0 "register_operand" "=f,f,f,v,v")
(minus:FP (match_operand:FP 1 "register_operand" "f,0,0,v,v")
(match_operand:FP 2 "general_operand" "f,f,R,v,v")))
(clobber (reg:CC CC_REGNUM))]
"TARGET_HARD_FLOAT"
"@
s<xde>tr\t%0,%1,%2
s<xde>br\t%0,%2
s<xde>b\t%0,%2
wfsdb\t%v0,%v1,%v2"
[(set_attr "op_type" "RRF,RRE,RXE,VRR")
wfsdb\t%v0,%v1,%v2
wfssb\t%v0,%v1,%v2"
[(set_attr "op_type" "RRF,RRE,RXE,VRR,VRR")
(set_attr "type" "fsimp<mode>")
(set_attr "cpu_facility" "*,*,*,vx")
(set_attr "enabled" "<nBFP>,<nDFP>,<DSF>,<DFDI>")])
(set_attr "cpu_facility" "*,*,*,vx,vxe")
(set_attr "enabled" "<nBFP>,<nDFP>,<DSF>,<DF>,<SF>")])
; sxbr, sdbr, sebr, sdb, seb, sxtr, sdtr
(define_insn "*sub<mode>3_cc"
......@@ -6736,51 +6747,54 @@
; mxbr, mdbr, meebr, mxb, mxb, meeb, mdtr, mxtr
(define_insn "mul<mode>3"
[(set (match_operand:FP 0 "register_operand" "=f,f,f,v")
(mult:FP (match_operand:FP 1 "nonimmediate_operand" "%f,0,0,v")
(match_operand:FP 2 "general_operand" "f,f,R,v")))]
[(set (match_operand:FP 0 "register_operand" "=f,f,f,v,v")
(mult:FP (match_operand:FP 1 "nonimmediate_operand" "%f,0,0,v,v")
(match_operand:FP 2 "general_operand" "f,f,R,v,v")))]
"TARGET_HARD_FLOAT"
"@
m<xdee>tr\t%0,%1,%2
m<xdee>br\t%0,%2
m<xdee>b\t%0,%2
wfmdb\t%v0,%v1,%v2"
[(set_attr "op_type" "RRF,RRE,RXE,VRR")
wfmdb\t%v0,%v1,%v2
wfmsb\t%v0,%v1,%v2"
[(set_attr "op_type" "RRF,RRE,RXE,VRR,VRR")
(set_attr "type" "fmul<mode>")
(set_attr "cpu_facility" "*,*,*,vx")
(set_attr "enabled" "<nBFP>,<nDFP>,<DSF>,<DFDI>")])
(set_attr "cpu_facility" "*,*,*,vx,vxe")
(set_attr "enabled" "<nBFP>,<nDFP>,<DSF>,<DF>,<SF>")])
; madbr, maebr, maxb, madb, maeb
(define_insn "fma<mode>4"
[(set (match_operand:DSF 0 "register_operand" "=f,f,v")
(fma:DSF (match_operand:DSF 1 "nonimmediate_operand" "%f,f,v")
(match_operand:DSF 2 "nonimmediate_operand" "f,R,v")
(match_operand:DSF 3 "register_operand" "0,0,v")))]
[(set (match_operand:DSF 0 "register_operand" "=f,f,v,v")
(fma:DSF (match_operand:DSF 1 "nonimmediate_operand" "%f,f,v,v")
(match_operand:DSF 2 "nonimmediate_operand" "f,R,v,v")
(match_operand:DSF 3 "register_operand" "0,0,v,v")))]
"TARGET_HARD_FLOAT"
"@
ma<xde>br\t%0,%1,%2
ma<xde>b\t%0,%1,%2
wfmadb\t%v0,%v1,%v2,%v3"
[(set_attr "op_type" "RRE,RXE,VRR")
wfmadb\t%v0,%v1,%v2,%v3
wfmasb\t%v0,%v1,%v2,%v3"
[(set_attr "op_type" "RRE,RXE,VRR,VRR")
(set_attr "type" "fmadd<mode>")
(set_attr "cpu_facility" "*,*,vx")
(set_attr "enabled" "*,*,<DFDI>")])
(set_attr "cpu_facility" "*,*,vx,vxe")
(set_attr "enabled" "*,*,<DF>,<SF>")])
; msxbr, msdbr, msebr, msxb, msdb, mseb
(define_insn "fms<mode>4"
[(set (match_operand:DSF 0 "register_operand" "=f,f,v")
(fma:DSF (match_operand:DSF 1 "nonimmediate_operand" "%f,f,v")
(match_operand:DSF 2 "nonimmediate_operand" "f,R,v")
(neg:DSF (match_operand:DSF 3 "register_operand" "0,0,v"))))]
[(set (match_operand:DSF 0 "register_operand" "=f,f,v,v")
(fma:DSF (match_operand:DSF 1 "nonimmediate_operand" "%f,f,v,v")
(match_operand:DSF 2 "nonimmediate_operand" "f,R,v,v")
(neg:DSF (match_operand:DSF 3 "register_operand" "0,0,v,v"))))]
"TARGET_HARD_FLOAT"
"@
ms<xde>br\t%0,%1,%2
ms<xde>b\t%0,%1,%2
wfmsdb\t%v0,%v1,%v2,%v3"
[(set_attr "op_type" "RRE,RXE,VRR")
wfmsdb\t%v0,%v1,%v2,%v3
wfmssb\t%v0,%v1,%v2,%v3"
[(set_attr "op_type" "RRE,RXE,VRR,VRR")
(set_attr "type" "fmadd<mode>")
(set_attr "cpu_facility" "*,*,vx")
(set_attr "enabled" "*,*,<DFDI>")])
(set_attr "cpu_facility" "*,*,vx,vxe")
(set_attr "enabled" "*,*,<DF>,<SF>")])
;;
;;- Divide and modulo instructions.
......@@ -7212,19 +7226,20 @@
; dxbr, ddbr, debr, dxb, ddb, deb, ddtr, dxtr
(define_insn "div<mode>3"
[(set (match_operand:FP 0 "register_operand" "=f,f,f,v")
(div:FP (match_operand:FP 1 "register_operand" "f,0,0,v")
(match_operand:FP 2 "general_operand" "f,f,R,v")))]
[(set (match_operand:FP 0 "register_operand" "=f,f,f,v,v")
(div:FP (match_operand:FP 1 "register_operand" "f,0,0,v,v")
(match_operand:FP 2 "general_operand" "f,f,R,v,v")))]
"TARGET_HARD_FLOAT"
"@
d<xde>tr\t%0,%1,%2
d<xde>br\t%0,%2
d<xde>b\t%0,%2
wfddb\t%v0,%v1,%v2"
[(set_attr "op_type" "RRF,RRE,RXE,VRR")
wfddb\t%v0,%v1,%v2
wfdsb\t%v0,%v1,%v2"
[(set_attr "op_type" "RRF,RRE,RXE,VRR,VRR")
(set_attr "type" "fdiv<mode>")
(set_attr "cpu_facility" "*,*,*,vx")
(set_attr "enabled" "<nBFP>,<nDFP>,<DSF>,<DFDI>")])
(set_attr "cpu_facility" "*,*,*,vx,vxe")
(set_attr "enabled" "<nBFP>,<nDFP>,<DSF>,<DF>,<SF>")])
;;
......@@ -8423,11 +8438,10 @@
(define_expand "neg<mode>2"
[(parallel
[(set (match_operand:BFP 0 "register_operand" "=f")
(neg:BFP (match_operand:BFP 1 "register_operand" "f")))
[(set (match_operand:BFP 0 "register_operand")
(neg:BFP (match_operand:BFP 1 "register_operand")))
(clobber (reg:CC CC_REGNUM))])]
"TARGET_HARD_FLOAT"
"")
"TARGET_HARD_FLOAT")
; lcxbr, lcdbr, lcebr
(define_insn "*neg<mode>2_cc"
......@@ -8463,18 +8477,20 @@
; lcxbr, lcdbr, lcebr
; FIXME: wflcdb does not clobber cc
; FIXME: Does wflcdb ever match here?
(define_insn "*neg<mode>2"
[(set (match_operand:BFP 0 "register_operand" "=f,v")
(neg:BFP (match_operand:BFP 1 "register_operand" "f,v")))
[(set (match_operand:BFP 0 "register_operand" "=f,v,v")
(neg:BFP (match_operand:BFP 1 "register_operand" "f,v,v")))
(clobber (reg:CC CC_REGNUM))]
"TARGET_HARD_FLOAT"
"@
lc<xde>br\t%0,%1
wflcdb\t%0,%1"
[(set_attr "op_type" "RRE,VRR")
(set_attr "cpu_facility" "*,vx")
(set_attr "type" "fsimp<mode>,*")
(set_attr "enabled" "*,<DFDI>")])
wflcdb\t%0,%1
wflcsb\t%0,%1"
[(set_attr "op_type" "RRE,VRR,VRR")
(set_attr "cpu_facility" "*,vx,vxe")
(set_attr "type" "fsimp<mode>,*,*")
(set_attr "enabled" "*,<DF>,<SF>")])
;;
......
2017-03-24 Andreas Krebbel <krebbel@linux.vnet.ibm.com>
* gcc.target/s390/vxe/negfma-1.c: New test.
2017-03-24 Andreas Krebbel <krebbel@linux.vnet.ibm.com>
* gcc.target/s390/arch12/aghsghmgh-1.c: New test.
* gcc.target/s390/arch12/mul-1.c: New test.
* gcc.target/s390/arch12/mul-2.c: New test.
......
/* { dg-do compile } */
/* { dg-options "-O3 -mzarch -march=arch12" } */
typedef float v4sf __attribute__((vector_size(16)));
typedef double v2df __attribute__((vector_size(16)));
typedef long double v1tf __attribute__((vector_size(16)));
v4sf
neg_vfnmasb (v4sf a, v4sf b, v4sf c)
{
return -(a * b + c);
}
/* { dg-final { scan-assembler-times "vfnmasb\t%v24,%v24,%v26,%v28" 1 } } */
v2df
neg_vfnmadb (v2df a, v2df b, v2df c)
{
return -(a * b + c);
}
/* { dg-final { scan-assembler-times "vfnmadb\t%v24,%v24,%v26,%v28" 1 } } */
v1tf
neg_wfnmaxb (v1tf a, v1tf b, v1tf c)
{
return -(a * b + c);
}
/* { dg-final { scan-assembler-times "wfnmaxb\t%v24,%v24,%v26,%v28" 1 } } */
v4sf
neg_vfnmssb (v4sf a, v4sf b, v4sf c)
{
return -(a * b - c);
}
/* { dg-final { scan-assembler-times "vfnmssb\t%v24,%v24,%v26,%v28" 1 } } */
v2df
neg_vfnmsdb (v2df a, v2df b, v2df c)
{
return -(a * b - c);
}
/* { dg-final { scan-assembler-times "vfnmsdb\t%v24,%v24,%v26,%v28" 1 } } */
v1tf
neg_wfnmsxb (v1tf a, v1tf b, v1tf c)
{
return -(a * b - c);
}
/* { dg-final { scan-assembler-times "wfnmsxb\t%v24,%v24,%v26,%v28" 1 } } */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment