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
This commit is contained in:
parent
7d2fd07577
commit
2de2b3f93b
|
@ -1,3 +1,37 @@
|
||||||
|
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>
|
2017-03-24 Andreas Krebbel <krebbel@linux.vnet.ibm.com>
|
||||||
|
|
||||||
* config/s390/s390.md ("*adddi3_sign", "*subdi3_sign", "mulditi3")
|
* config/s390/s390.md ("*adddi3_sign", "*subdi3_sign", "mulditi3")
|
||||||
|
|
|
@ -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_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_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_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_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_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)
|
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;
|
bool neg_p = false, swap_p = false;
|
||||||
rtx tmp;
|
rtx tmp;
|
||||||
|
|
||||||
if (GET_MODE (cmp_op1) == V2DFmode)
|
if (GET_MODE_CLASS (GET_MODE (cmp_op1)) == MODE_VECTOR_FLOAT)
|
||||||
{
|
{
|
||||||
switch (cond)
|
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
|
/* We always use an integral type vector to hold the comparison
|
||||||
result. */
|
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);
|
result_target = gen_reg_rtx (result_mode);
|
||||||
|
|
||||||
/* We allow vector immediates as comparison operands that
|
/* 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
|
return ((GET_MODE_CLASS (mode) == MODE_INT
|
||||||
&& s390_class_max_nregs (VEC_REGS, mode) == 1)
|
&& s390_class_max_nregs (VEC_REGS, mode) == 1)
|
||||||
|| mode == DFmode
|
|| mode == DFmode
|
||||||
|
|| (TARGET_VXE && mode == SFmode)
|
||||||
|| s390_vector_mode_supported_p (mode));
|
|| s390_vector_mode_supported_p (mode));
|
||||||
break;
|
break;
|
||||||
case FP_REGS:
|
case FP_REGS:
|
||||||
|
@ -10256,6 +10258,13 @@ s390_cannot_change_mode_class (machine_mode from_mode,
|
||||||
machine_mode small_mode;
|
machine_mode small_mode;
|
||||||
machine_mode big_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))
|
if (GET_MODE_SIZE (from_mode) == GET_MODE_SIZE (to_mode))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
|
@ -674,6 +674,12 @@
|
||||||
(define_mode_attr DFDI [(TF "0") (DF "*") (SF "0")
|
(define_mode_attr DFDI [(TF "0") (DF "*") (SF "0")
|
||||||
(TD "0") (DD "0") (DD "0")
|
(TD "0") (DD "0") (DD "0")
|
||||||
(TI "0") (DI "*") (SI "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
|
;; This attribute is used in the operand constraint list
|
||||||
;; for instructions dealing with the sign bit of 32 or 64bit fp values.
|
;; 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"
|
(define_insn "*cmp<mode>_ccs"
|
||||||
[(set (reg CC_REGNUM)
|
[(set (reg CC_REGNUM)
|
||||||
(compare (match_operand:FP 0 "register_operand" "f,f,v")
|
(compare (match_operand:FP 0 "register_operand" "f,f,v,v")
|
||||||
(match_operand:FP 1 "general_operand" "f,R,v")))]
|
(match_operand:FP 1 "general_operand" "f,R,v,v")))]
|
||||||
"s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT"
|
"s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT"
|
||||||
"@
|
"@
|
||||||
c<xde><bt>r\t%0,%1
|
c<xde><bt>r\t%0,%1
|
||||||
c<xde>b\t%0,%1
|
c<xde>b\t%0,%1
|
||||||
wfcdb\t%0,%1"
|
wfcdb\t%0,%1
|
||||||
[(set_attr "op_type" "RRE,RXE,VRR")
|
wfcsb\t%0,%1"
|
||||||
(set_attr "cpu_facility" "*,*,vx")
|
[(set_attr "op_type" "RRE,RXE,VRR,VRR")
|
||||||
(set_attr "enabled" "*,<DSF>,<DFDI>")])
|
(set_attr "cpu_facility" "*,*,vx,vxe")
|
||||||
|
(set_attr "enabled" "*,<DSF>,<DF>,<SF>")])
|
||||||
|
|
||||||
; Compare and Branch instructions
|
; Compare and Branch instructions
|
||||||
|
|
||||||
|
@ -5159,6 +5166,7 @@
|
||||||
; extend(sf|df)(df|tf)2 instruction pattern(s).
|
; extend(sf|df)(df|tf)2 instruction pattern(s).
|
||||||
;
|
;
|
||||||
|
|
||||||
|
; wflls
|
||||||
(define_insn "*extendsfdf2_z13"
|
(define_insn "*extendsfdf2_z13"
|
||||||
[(set (match_operand:DF 0 "register_operand" "=f,f,v")
|
[(set (match_operand:DF 0 "register_operand" "=f,f,v")
|
||||||
(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "f,R,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
|
; axbr, adbr, aebr, axb, adb, aeb, adtr, axtr
|
||||||
; FIXME: wfadb does not clobber cc
|
; FIXME: wfadb does not clobber cc
|
||||||
(define_insn "add<mode>3"
|
(define_insn "add<mode>3"
|
||||||
[(set (match_operand:FP 0 "register_operand" "=f,f,f,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")
|
(plus:FP (match_operand:FP 1 "nonimmediate_operand" "%f,0,0,v,v")
|
||||||
(match_operand:FP 2 "general_operand" "f,f,R,v")))
|
(match_operand:FP 2 "general_operand" "f,f,R,v,v")))
|
||||||
(clobber (reg:CC CC_REGNUM))]
|
(clobber (reg:CC CC_REGNUM))]
|
||||||
"TARGET_HARD_FLOAT"
|
"TARGET_HARD_FLOAT"
|
||||||
"@
|
"@
|
||||||
a<xde>tr\t%0,%1,%2
|
a<xde>tr\t%0,%1,%2
|
||||||
a<xde>br\t%0,%2
|
a<xde>br\t%0,%2
|
||||||
a<xde>b\t%0,%2
|
a<xde>b\t%0,%2
|
||||||
wfadb\t%v0,%v1,%v2"
|
wfadb\t%v0,%v1,%v2
|
||||||
[(set_attr "op_type" "RRF,RRE,RXE,VRR")
|
wfasb\t%v0,%v1,%v2"
|
||||||
|
[(set_attr "op_type" "RRF,RRE,RXE,VRR,VRR")
|
||||||
(set_attr "type" "fsimp<mode>")
|
(set_attr "type" "fsimp<mode>")
|
||||||
(set_attr "cpu_facility" "*,*,*,vx")
|
(set_attr "cpu_facility" "*,*,*,vx,vxe")
|
||||||
(set_attr "enabled" "<nBFP>,<nDFP>,<DSF>,<DFDI>")])
|
(set_attr "enabled" "<nBFP>,<nDFP>,<DSF>,<DF>,<SF>")])
|
||||||
|
|
||||||
; axbr, adbr, aebr, axb, adb, aeb, adtr, axtr
|
; axbr, adbr, aebr, axb, adb, aeb, adtr, axtr
|
||||||
(define_insn "*add<mode>3_cc"
|
(define_insn "*add<mode>3_cc"
|
||||||
|
@ -6249,22 +6258,24 @@
|
||||||
; sub(tf|df|sf|td|dd)3 instruction pattern(s).
|
; 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
|
; sxbr, sdbr, sebr, sdb, seb, sxtr, sdtr
|
||||||
(define_insn "sub<mode>3"
|
(define_insn "sub<mode>3"
|
||||||
[(set (match_operand:FP 0 "register_operand" "=f,f,f,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")
|
(minus:FP (match_operand:FP 1 "register_operand" "f,0,0,v,v")
|
||||||
(match_operand:FP 2 "general_operand" "f,f,R,v")))
|
(match_operand:FP 2 "general_operand" "f,f,R,v,v")))
|
||||||
(clobber (reg:CC CC_REGNUM))]
|
(clobber (reg:CC CC_REGNUM))]
|
||||||
"TARGET_HARD_FLOAT"
|
"TARGET_HARD_FLOAT"
|
||||||
"@
|
"@
|
||||||
s<xde>tr\t%0,%1,%2
|
s<xde>tr\t%0,%1,%2
|
||||||
s<xde>br\t%0,%2
|
s<xde>br\t%0,%2
|
||||||
s<xde>b\t%0,%2
|
s<xde>b\t%0,%2
|
||||||
wfsdb\t%v0,%v1,%v2"
|
wfsdb\t%v0,%v1,%v2
|
||||||
[(set_attr "op_type" "RRF,RRE,RXE,VRR")
|
wfssb\t%v0,%v1,%v2"
|
||||||
|
[(set_attr "op_type" "RRF,RRE,RXE,VRR,VRR")
|
||||||
(set_attr "type" "fsimp<mode>")
|
(set_attr "type" "fsimp<mode>")
|
||||||
(set_attr "cpu_facility" "*,*,*,vx")
|
(set_attr "cpu_facility" "*,*,*,vx,vxe")
|
||||||
(set_attr "enabled" "<nBFP>,<nDFP>,<DSF>,<DFDI>")])
|
(set_attr "enabled" "<nBFP>,<nDFP>,<DSF>,<DF>,<SF>")])
|
||||||
|
|
||||||
; sxbr, sdbr, sebr, sdb, seb, sxtr, sdtr
|
; sxbr, sdbr, sebr, sdb, seb, sxtr, sdtr
|
||||||
(define_insn "*sub<mode>3_cc"
|
(define_insn "*sub<mode>3_cc"
|
||||||
|
@ -6736,51 +6747,54 @@
|
||||||
|
|
||||||
; mxbr, mdbr, meebr, mxb, mxb, meeb, mdtr, mxtr
|
; mxbr, mdbr, meebr, mxb, mxb, meeb, mdtr, mxtr
|
||||||
(define_insn "mul<mode>3"
|
(define_insn "mul<mode>3"
|
||||||
[(set (match_operand:FP 0 "register_operand" "=f,f,f,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")
|
(mult:FP (match_operand:FP 1 "nonimmediate_operand" "%f,0,0,v,v")
|
||||||
(match_operand:FP 2 "general_operand" "f,f,R,v")))]
|
(match_operand:FP 2 "general_operand" "f,f,R,v,v")))]
|
||||||
"TARGET_HARD_FLOAT"
|
"TARGET_HARD_FLOAT"
|
||||||
"@
|
"@
|
||||||
m<xdee>tr\t%0,%1,%2
|
m<xdee>tr\t%0,%1,%2
|
||||||
m<xdee>br\t%0,%2
|
m<xdee>br\t%0,%2
|
||||||
m<xdee>b\t%0,%2
|
m<xdee>b\t%0,%2
|
||||||
wfmdb\t%v0,%v1,%v2"
|
wfmdb\t%v0,%v1,%v2
|
||||||
[(set_attr "op_type" "RRF,RRE,RXE,VRR")
|
wfmsb\t%v0,%v1,%v2"
|
||||||
|
[(set_attr "op_type" "RRF,RRE,RXE,VRR,VRR")
|
||||||
(set_attr "type" "fmul<mode>")
|
(set_attr "type" "fmul<mode>")
|
||||||
(set_attr "cpu_facility" "*,*,*,vx")
|
(set_attr "cpu_facility" "*,*,*,vx,vxe")
|
||||||
(set_attr "enabled" "<nBFP>,<nDFP>,<DSF>,<DFDI>")])
|
(set_attr "enabled" "<nBFP>,<nDFP>,<DSF>,<DF>,<SF>")])
|
||||||
|
|
||||||
; madbr, maebr, maxb, madb, maeb
|
; madbr, maebr, maxb, madb, maeb
|
||||||
(define_insn "fma<mode>4"
|
(define_insn "fma<mode>4"
|
||||||
[(set (match_operand:DSF 0 "register_operand" "=f,f,v")
|
[(set (match_operand:DSF 0 "register_operand" "=f,f,v,v")
|
||||||
(fma:DSF (match_operand:DSF 1 "nonimmediate_operand" "%f,f,v")
|
(fma:DSF (match_operand:DSF 1 "nonimmediate_operand" "%f,f,v,v")
|
||||||
(match_operand:DSF 2 "nonimmediate_operand" "f,R,v")
|
(match_operand:DSF 2 "nonimmediate_operand" "f,R,v,v")
|
||||||
(match_operand:DSF 3 "register_operand" "0,0,v")))]
|
(match_operand:DSF 3 "register_operand" "0,0,v,v")))]
|
||||||
"TARGET_HARD_FLOAT"
|
"TARGET_HARD_FLOAT"
|
||||||
"@
|
"@
|
||||||
ma<xde>br\t%0,%1,%2
|
ma<xde>br\t%0,%1,%2
|
||||||
ma<xde>b\t%0,%1,%2
|
ma<xde>b\t%0,%1,%2
|
||||||
wfmadb\t%v0,%v1,%v2,%v3"
|
wfmadb\t%v0,%v1,%v2,%v3
|
||||||
[(set_attr "op_type" "RRE,RXE,VRR")
|
wfmasb\t%v0,%v1,%v2,%v3"
|
||||||
|
[(set_attr "op_type" "RRE,RXE,VRR,VRR")
|
||||||
(set_attr "type" "fmadd<mode>")
|
(set_attr "type" "fmadd<mode>")
|
||||||
(set_attr "cpu_facility" "*,*,vx")
|
(set_attr "cpu_facility" "*,*,vx,vxe")
|
||||||
(set_attr "enabled" "*,*,<DFDI>")])
|
(set_attr "enabled" "*,*,<DF>,<SF>")])
|
||||||
|
|
||||||
; msxbr, msdbr, msebr, msxb, msdb, mseb
|
; msxbr, msdbr, msebr, msxb, msdb, mseb
|
||||||
(define_insn "fms<mode>4"
|
(define_insn "fms<mode>4"
|
||||||
[(set (match_operand:DSF 0 "register_operand" "=f,f,v")
|
[(set (match_operand:DSF 0 "register_operand" "=f,f,v,v")
|
||||||
(fma:DSF (match_operand:DSF 1 "nonimmediate_operand" "%f,f,v")
|
(fma:DSF (match_operand:DSF 1 "nonimmediate_operand" "%f,f,v,v")
|
||||||
(match_operand:DSF 2 "nonimmediate_operand" "f,R,v")
|
(match_operand:DSF 2 "nonimmediate_operand" "f,R,v,v")
|
||||||
(neg:DSF (match_operand:DSF 3 "register_operand" "0,0,v"))))]
|
(neg:DSF (match_operand:DSF 3 "register_operand" "0,0,v,v"))))]
|
||||||
"TARGET_HARD_FLOAT"
|
"TARGET_HARD_FLOAT"
|
||||||
"@
|
"@
|
||||||
ms<xde>br\t%0,%1,%2
|
ms<xde>br\t%0,%1,%2
|
||||||
ms<xde>b\t%0,%1,%2
|
ms<xde>b\t%0,%1,%2
|
||||||
wfmsdb\t%v0,%v1,%v2,%v3"
|
wfmsdb\t%v0,%v1,%v2,%v3
|
||||||
[(set_attr "op_type" "RRE,RXE,VRR")
|
wfmssb\t%v0,%v1,%v2,%v3"
|
||||||
|
[(set_attr "op_type" "RRE,RXE,VRR,VRR")
|
||||||
(set_attr "type" "fmadd<mode>")
|
(set_attr "type" "fmadd<mode>")
|
||||||
(set_attr "cpu_facility" "*,*,vx")
|
(set_attr "cpu_facility" "*,*,vx,vxe")
|
||||||
(set_attr "enabled" "*,*,<DFDI>")])
|
(set_attr "enabled" "*,*,<DF>,<SF>")])
|
||||||
|
|
||||||
;;
|
;;
|
||||||
;;- Divide and modulo instructions.
|
;;- Divide and modulo instructions.
|
||||||
|
@ -7212,19 +7226,20 @@
|
||||||
|
|
||||||
; dxbr, ddbr, debr, dxb, ddb, deb, ddtr, dxtr
|
; dxbr, ddbr, debr, dxb, ddb, deb, ddtr, dxtr
|
||||||
(define_insn "div<mode>3"
|
(define_insn "div<mode>3"
|
||||||
[(set (match_operand:FP 0 "register_operand" "=f,f,f,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")
|
(div:FP (match_operand:FP 1 "register_operand" "f,0,0,v,v")
|
||||||
(match_operand:FP 2 "general_operand" "f,f,R,v")))]
|
(match_operand:FP 2 "general_operand" "f,f,R,v,v")))]
|
||||||
"TARGET_HARD_FLOAT"
|
"TARGET_HARD_FLOAT"
|
||||||
"@
|
"@
|
||||||
d<xde>tr\t%0,%1,%2
|
d<xde>tr\t%0,%1,%2
|
||||||
d<xde>br\t%0,%2
|
d<xde>br\t%0,%2
|
||||||
d<xde>b\t%0,%2
|
d<xde>b\t%0,%2
|
||||||
wfddb\t%v0,%v1,%v2"
|
wfddb\t%v0,%v1,%v2
|
||||||
[(set_attr "op_type" "RRF,RRE,RXE,VRR")
|
wfdsb\t%v0,%v1,%v2"
|
||||||
|
[(set_attr "op_type" "RRF,RRE,RXE,VRR,VRR")
|
||||||
(set_attr "type" "fdiv<mode>")
|
(set_attr "type" "fdiv<mode>")
|
||||||
(set_attr "cpu_facility" "*,*,*,vx")
|
(set_attr "cpu_facility" "*,*,*,vx,vxe")
|
||||||
(set_attr "enabled" "<nBFP>,<nDFP>,<DSF>,<DFDI>")])
|
(set_attr "enabled" "<nBFP>,<nDFP>,<DSF>,<DF>,<SF>")])
|
||||||
|
|
||||||
|
|
||||||
;;
|
;;
|
||||||
|
@ -8423,11 +8438,10 @@
|
||||||
|
|
||||||
(define_expand "neg<mode>2"
|
(define_expand "neg<mode>2"
|
||||||
[(parallel
|
[(parallel
|
||||||
[(set (match_operand:BFP 0 "register_operand" "=f")
|
[(set (match_operand:BFP 0 "register_operand")
|
||||||
(neg:BFP (match_operand:BFP 1 "register_operand" "f")))
|
(neg:BFP (match_operand:BFP 1 "register_operand")))
|
||||||
(clobber (reg:CC CC_REGNUM))])]
|
(clobber (reg:CC CC_REGNUM))])]
|
||||||
"TARGET_HARD_FLOAT"
|
"TARGET_HARD_FLOAT")
|
||||||
"")
|
|
||||||
|
|
||||||
; lcxbr, lcdbr, lcebr
|
; lcxbr, lcdbr, lcebr
|
||||||
(define_insn "*neg<mode>2_cc"
|
(define_insn "*neg<mode>2_cc"
|
||||||
|
@ -8463,18 +8477,20 @@
|
||||||
|
|
||||||
; lcxbr, lcdbr, lcebr
|
; lcxbr, lcdbr, lcebr
|
||||||
; FIXME: wflcdb does not clobber cc
|
; FIXME: wflcdb does not clobber cc
|
||||||
|
; FIXME: Does wflcdb ever match here?
|
||||||
(define_insn "*neg<mode>2"
|
(define_insn "*neg<mode>2"
|
||||||
[(set (match_operand:BFP 0 "register_operand" "=f,v")
|
[(set (match_operand:BFP 0 "register_operand" "=f,v,v")
|
||||||
(neg:BFP (match_operand:BFP 1 "register_operand" "f,v")))
|
(neg:BFP (match_operand:BFP 1 "register_operand" "f,v,v")))
|
||||||
(clobber (reg:CC CC_REGNUM))]
|
(clobber (reg:CC CC_REGNUM))]
|
||||||
"TARGET_HARD_FLOAT"
|
"TARGET_HARD_FLOAT"
|
||||||
"@
|
"@
|
||||||
lc<xde>br\t%0,%1
|
lc<xde>br\t%0,%1
|
||||||
wflcdb\t%0,%1"
|
wflcdb\t%0,%1
|
||||||
[(set_attr "op_type" "RRE,VRR")
|
wflcsb\t%0,%1"
|
||||||
(set_attr "cpu_facility" "*,vx")
|
[(set_attr "op_type" "RRE,VRR,VRR")
|
||||||
(set_attr "type" "fsimp<mode>,*")
|
(set_attr "cpu_facility" "*,vx,vxe")
|
||||||
(set_attr "enabled" "*,<DFDI>")])
|
(set_attr "type" "fsimp<mode>,*,*")
|
||||||
|
(set_attr "enabled" "*,<DF>,<SF>")])
|
||||||
|
|
||||||
|
|
||||||
;;
|
;;
|
||||||
|
|
|
@ -26,16 +26,16 @@
|
||||||
[V1QI V2QI V4QI V8QI V16QI V1HI V2HI V4HI V8HI V1SI V2SI V4SI V1DI V2DI V1SF
|
[V1QI V2QI V4QI V8QI V16QI V1HI V2HI V4HI V8HI V1SI V2SI V4SI V1DI V2DI V1SF
|
||||||
V2SF V4SF V1DF V2DF V1TF V1TI TI])
|
V2SF V4SF V1DF V2DF V1TF V1TI TI])
|
||||||
|
|
||||||
; All vector modes directly supported by the hardware having full vector reg size
|
; All modes directly supported by the hardware having full vector reg size
|
||||||
; V_HW2 is duplicate of V_HW for having two iterators expanding
|
; V_HW2 is duplicate of V_HW for having two iterators expanding
|
||||||
; independently e.g. vcond
|
; independently e.g. vcond
|
||||||
(define_mode_iterator V_HW [V16QI V8HI V4SI V2DI V2DF])
|
(define_mode_iterator V_HW [V16QI V8HI V4SI V2DI V2DF (V4SF "TARGET_VXE") (V1TF "TARGET_VXE")])
|
||||||
(define_mode_iterator V_HW2 [V16QI V8HI V4SI V2DI V2DF])
|
(define_mode_iterator V_HW2 [V16QI V8HI V4SI V2DI V2DF (V4SF "TARGET_VXE") (V1TF "TARGET_VXE")])
|
||||||
|
|
||||||
(define_mode_iterator V_HW_64 [V2DI V2DF])
|
(define_mode_iterator V_HW_64 [V2DI V2DF])
|
||||||
|
|
||||||
; Including TI for instructions that support it (va, vn, ...)
|
; Including TI for instructions that support it (va, vn, ...)
|
||||||
(define_mode_iterator VT_HW [V16QI V8HI V4SI V2DI V2DF V1TI TI])
|
(define_mode_iterator VT_HW [V16QI V8HI V4SI V2DI V2DF V1TI TI (V4SF "TARGET_VXE") (V1TF "TARGET_VXE")])
|
||||||
|
|
||||||
; All full size integer vector modes supported in a vector register + TImode
|
; All full size integer vector modes supported in a vector register + TImode
|
||||||
(define_mode_iterator VIT_HW [V16QI V8HI V4SI V2DI V1TI TI])
|
(define_mode_iterator VIT_HW [V16QI V8HI V4SI V2DI V1TI TI])
|
||||||
|
@ -51,6 +51,15 @@
|
||||||
(define_mode_iterator VI [V1QI V2QI V4QI V8QI V16QI V1HI V2HI V4HI V8HI V1SI V2SI V4SI V1DI V2DI])
|
(define_mode_iterator VI [V1QI V2QI V4QI V8QI V16QI V1HI V2HI V4HI V8HI V1SI V2SI V4SI V1DI V2DI])
|
||||||
(define_mode_iterator VI_QHS [V1QI V2QI V4QI V8QI V16QI V1HI V2HI V4HI V8HI V1SI V2SI V4SI])
|
(define_mode_iterator VI_QHS [V1QI V2QI V4QI V8QI V16QI V1HI V2HI V4HI V8HI V1SI V2SI V4SI])
|
||||||
|
|
||||||
|
(define_mode_iterator VFT [(V1SF "TARGET_VXE") (V2SF "TARGET_VXE") (V4SF "TARGET_VXE")
|
||||||
|
V1DF V2DF
|
||||||
|
(V1TF "TARGET_VXE")])
|
||||||
|
|
||||||
|
; FP vector modes directly supported by the HW. This does not include
|
||||||
|
; vector modes using only part of a vector register and should be used
|
||||||
|
; for instructions which might trigger IEEE exceptions.
|
||||||
|
(define_mode_iterator VF_HW [(V4SF "TARGET_VXE") V2DF (V1TF "TARGET_VXE")])
|
||||||
|
|
||||||
(define_mode_iterator V_8 [V1QI])
|
(define_mode_iterator V_8 [V1QI])
|
||||||
(define_mode_iterator V_16 [V2QI V1HI])
|
(define_mode_iterator V_16 [V2QI V1HI])
|
||||||
(define_mode_iterator V_32 [V4QI V2HI V1SI V1SF])
|
(define_mode_iterator V_32 [V4QI V2HI V1SI V1SF])
|
||||||
|
@ -59,26 +68,30 @@
|
||||||
|
|
||||||
(define_mode_iterator V_128_NOSINGLE [V16QI V8HI V4SI V4SF V2DI V2DF])
|
(define_mode_iterator V_128_NOSINGLE [V16QI V8HI V4SI V4SF V2DI V2DF])
|
||||||
|
|
||||||
; A blank for vector modes and a * for TImode. This is used to hide
|
; Empty string for all but TImode. This is used to hide the TImode
|
||||||
; the TImode expander name in case it is defined already. See addti3
|
; expander name in case it is defined already. See addti3 for an
|
||||||
; for an example.
|
; example.
|
||||||
(define_mode_attr ti* [(V1QI "") (V2QI "") (V4QI "") (V8QI "") (V16QI "")
|
(define_mode_attr ti* [(V1QI "") (V2QI "") (V4QI "") (V8QI "") (V16QI "")
|
||||||
(V1HI "") (V2HI "") (V4HI "") (V8HI "")
|
(V1HI "") (V2HI "") (V4HI "") (V8HI "")
|
||||||
(V1SI "") (V2SI "") (V4SI "")
|
(V1SI "") (V2SI "") (V4SI "")
|
||||||
(V1DI "") (V2DI "")
|
(V1DI "") (V2DI "")
|
||||||
(V1TI "*") (TI "*")])
|
(V1TI "") (TI "*")
|
||||||
|
(V1SF "") (V2SF "") (V4SF "")
|
||||||
|
(V1DF "") (V2DF "")
|
||||||
|
(V1TF "") (TF "")])
|
||||||
|
|
||||||
; The element type of the vector.
|
; The element type of the vector.
|
||||||
(define_mode_attr non_vec[(V1QI "QI") (V2QI "QI") (V4QI "QI") (V8QI "QI") (V16QI "QI")
|
(define_mode_attr non_vec[(V1QI "QI") (V2QI "QI") (V4QI "QI") (V8QI "QI") (V16QI "QI")
|
||||||
(V1HI "HI") (V2HI "HI") (V4HI "HI") (V8HI "HI")
|
(V1HI "HI") (V2HI "HI") (V4HI "HI") (V8HI "HI")
|
||||||
(V1SI "SI") (V2SI "SI") (V4SI "SI")
|
(V1SI "SI") (V2SI "SI") (V4SI "SI")
|
||||||
(V1DI "DI") (V2DI "DI")
|
(V1DI "DI") (V2DI "DI")
|
||||||
(V1TI "TI")
|
(V1TI "TI") (TI "TI")
|
||||||
(V1SF "SF") (V2SF "SF") (V4SF "SF")
|
(V1SF "SF") (V2SF "SF") (V4SF "SF")
|
||||||
(V1DF "DF") (V2DF "DF")
|
(V1DF "DF") (V2DF "DF")
|
||||||
(V1TF "TF")])
|
(V1TF "TF") (TF "TF")])
|
||||||
|
|
||||||
; The instruction suffix
|
; The instruction suffix for integer instructions and instructions
|
||||||
|
; which do not care about whether it is floating point or integer.
|
||||||
(define_mode_attr bhfgq[(V1QI "b") (V2QI "b") (V4QI "b") (V8QI "b") (V16QI "b")
|
(define_mode_attr bhfgq[(V1QI "b") (V2QI "b") (V4QI "b") (V8QI "b") (V16QI "b")
|
||||||
(V1HI "h") (V2HI "h") (V4HI "h") (V8HI "h")
|
(V1HI "h") (V2HI "h") (V4HI "h") (V8HI "h")
|
||||||
(V1SI "f") (V2SI "f") (V4SI "f")
|
(V1SI "f") (V2SI "f") (V4SI "f")
|
||||||
|
@ -105,6 +118,13 @@
|
||||||
(V1SF "V1SI") (V2SF "V2SI") (V4SF "V4SI")
|
(V1SF "V1SI") (V2SF "V2SI") (V4SF "V4SI")
|
||||||
(V1DF "V1DI") (V2DF "V2DI")
|
(V1DF "V1DI") (V2DF "V2DI")
|
||||||
(V1TF "V1TI")])
|
(V1TF "V1TI")])
|
||||||
|
(define_mode_attr vw [(SF "w") (V1SF "w") (V2SF "v") (V4SF "v")
|
||||||
|
(DF "w") (V1DF "w") (V2DF "v")
|
||||||
|
(TF "w") (V1TF "w")])
|
||||||
|
|
||||||
|
(define_mode_attr sdx [(SF "s") (V1SF "s") (V2SF "s") (V4SF "s")
|
||||||
|
(DF "d") (V1DF "d") (V2DF "d")
|
||||||
|
(TF "x") (V1TF "x")])
|
||||||
|
|
||||||
; Vector with doubled element size.
|
; Vector with doubled element size.
|
||||||
(define_mode_attr vec_double [(V1QI "V1HI") (V2QI "V1HI") (V4QI "V2HI") (V8QI "V4HI") (V16QI "V8HI")
|
(define_mode_attr vec_double [(V1QI "V1HI") (V2QI "V1HI") (V4QI "V2HI") (V8QI "V4HI") (V16QI "V8HI")
|
||||||
|
@ -1029,92 +1049,139 @@
|
||||||
;; Vector floating point arithmetic instructions
|
;; Vector floating point arithmetic instructions
|
||||||
;;
|
;;
|
||||||
|
|
||||||
(define_insn "addv2df3"
|
; vfasb, vfadb, wfasb, wfadb, wfaxb
|
||||||
[(set (match_operand:V2DF 0 "register_operand" "=v")
|
(define_insn "add<mode>3"
|
||||||
(plus:V2DF (match_operand:V2DF 1 "register_operand" "%v")
|
[(set (match_operand:VF_HW 0 "register_operand" "=v")
|
||||||
(match_operand:V2DF 2 "register_operand" "v")))]
|
(plus:VF_HW (match_operand:VF_HW 1 "register_operand" "%v")
|
||||||
|
(match_operand:VF_HW 2 "register_operand" "v")))]
|
||||||
"TARGET_VX"
|
"TARGET_VX"
|
||||||
"vfadb\t%v0,%v1,%v2"
|
"<vw>fa<sdx>b\t%v0,%v1,%v2"
|
||||||
[(set_attr "op_type" "VRR")])
|
[(set_attr "op_type" "VRR")])
|
||||||
|
|
||||||
(define_insn "subv2df3"
|
; vfssb, vfsdb, wfssb, wfsdb, wfsxb
|
||||||
[(set (match_operand:V2DF 0 "register_operand" "=v")
|
(define_insn "sub<mode>3"
|
||||||
(minus:V2DF (match_operand:V2DF 1 "register_operand" "%v")
|
[(set (match_operand:VF_HW 0 "register_operand" "=v")
|
||||||
(match_operand:V2DF 2 "register_operand" "v")))]
|
(minus:VF_HW (match_operand:VF_HW 1 "register_operand" "%v")
|
||||||
|
(match_operand:VF_HW 2 "register_operand" "v")))]
|
||||||
"TARGET_VX"
|
"TARGET_VX"
|
||||||
"vfsdb\t%v0,%v1,%v2"
|
"<vw>fs<sdx>b\t%v0,%v1,%v2"
|
||||||
[(set_attr "op_type" "VRR")])
|
[(set_attr "op_type" "VRR")])
|
||||||
|
|
||||||
(define_insn "mulv2df3"
|
; vfmsb, vfmdb, wfmsb, wfmdb, wfmxb
|
||||||
[(set (match_operand:V2DF 0 "register_operand" "=v")
|
(define_insn "mul<mode>3"
|
||||||
(mult:V2DF (match_operand:V2DF 1 "register_operand" "%v")
|
[(set (match_operand:VF_HW 0 "register_operand" "=v")
|
||||||
(match_operand:V2DF 2 "register_operand" "v")))]
|
(mult:VF_HW (match_operand:VF_HW 1 "register_operand" "%v")
|
||||||
|
(match_operand:VF_HW 2 "register_operand" "v")))]
|
||||||
"TARGET_VX"
|
"TARGET_VX"
|
||||||
"vfmdb\t%v0,%v1,%v2"
|
"<vw>fm<sdx>b\t%v0,%v1,%v2"
|
||||||
[(set_attr "op_type" "VRR")])
|
[(set_attr "op_type" "VRR")])
|
||||||
|
|
||||||
(define_insn "divv2df3"
|
; vfdsb, vfddb, wfdsb, wfddb, wfdxb
|
||||||
[(set (match_operand:V2DF 0 "register_operand" "=v")
|
(define_insn "div<mode>3"
|
||||||
(div:V2DF (match_operand:V2DF 1 "register_operand" "v")
|
[(set (match_operand:VF_HW 0 "register_operand" "=v")
|
||||||
(match_operand:V2DF 2 "register_operand" "v")))]
|
(div:VF_HW (match_operand:VF_HW 1 "register_operand" "v")
|
||||||
|
(match_operand:VF_HW 2 "register_operand" "v")))]
|
||||||
"TARGET_VX"
|
"TARGET_VX"
|
||||||
"vfddb\t%v0,%v1,%v2"
|
"<vw>fd<sdx>b\t%v0,%v1,%v2"
|
||||||
[(set_attr "op_type" "VRR")])
|
[(set_attr "op_type" "VRR")])
|
||||||
|
|
||||||
(define_insn "sqrtv2df2"
|
; vfsqsb, vfsqdb, wfsqsb, wfsqdb, wfsqxb
|
||||||
[(set (match_operand:V2DF 0 "register_operand" "=v")
|
(define_insn "sqrt<mode>2"
|
||||||
(sqrt:V2DF (match_operand:V2DF 1 "register_operand" "v")))]
|
[(set (match_operand:VF_HW 0 "register_operand" "=v")
|
||||||
|
(sqrt:VF_HW (match_operand:VF_HW 1 "register_operand" "v")))]
|
||||||
"TARGET_VX"
|
"TARGET_VX"
|
||||||
"vfsqdb\t%v0,%v1"
|
"<vw>fsq<sdx>b\t%v0,%v1"
|
||||||
[(set_attr "op_type" "VRR")])
|
[(set_attr "op_type" "VRR")])
|
||||||
|
|
||||||
(define_insn "fmav2df4"
|
; vfmasb, vfmadb, wfmasb, wfmadb, wfmaxb
|
||||||
[(set (match_operand:V2DF 0 "register_operand" "=v")
|
(define_insn "fma<mode>4"
|
||||||
(fma:V2DF (match_operand:V2DF 1 "register_operand" "%v")
|
[(set (match_operand:VF_HW 0 "register_operand" "=v")
|
||||||
(match_operand:V2DF 2 "register_operand" "v")
|
(fma:VF_HW (match_operand:VF_HW 1 "register_operand" "%v")
|
||||||
(match_operand:V2DF 3 "register_operand" "v")))]
|
(match_operand:VF_HW 2 "register_operand" "v")
|
||||||
|
(match_operand:VF_HW 3 "register_operand" "v")))]
|
||||||
"TARGET_VX"
|
"TARGET_VX"
|
||||||
"vfmadb\t%v0,%v1,%v2,%v3"
|
"<vw>fma<sdx>b\t%v0,%v1,%v2,%v3"
|
||||||
[(set_attr "op_type" "VRR")])
|
[(set_attr "op_type" "VRR")])
|
||||||
|
|
||||||
(define_insn "fmsv2df4"
|
; vfmssb, vfmsdb, wfmssb, wfmsdb, wfmsxb
|
||||||
[(set (match_operand:V2DF 0 "register_operand" "=v")
|
(define_insn "fms<mode>4"
|
||||||
(fma:V2DF (match_operand:V2DF 1 "register_operand" "%v")
|
[(set (match_operand:VF_HW 0 "register_operand" "=v")
|
||||||
(match_operand:V2DF 2 "register_operand" "v")
|
(fma:VF_HW (match_operand:VF_HW 1 "register_operand" "%v")
|
||||||
(neg:V2DF (match_operand:V2DF 3 "register_operand" "v"))))]
|
(match_operand:VF_HW 2 "register_operand" "v")
|
||||||
|
(neg:VF_HW (match_operand:VF_HW 3 "register_operand" "v"))))]
|
||||||
"TARGET_VX"
|
"TARGET_VX"
|
||||||
"vfmsdb\t%v0,%v1,%v2,%v3"
|
"<vw>fms<sdx>b\t%v0,%v1,%v2,%v3"
|
||||||
[(set_attr "op_type" "VRR")])
|
[(set_attr "op_type" "VRR")])
|
||||||
|
|
||||||
(define_insn "negv2df2"
|
; vfnmasb, vfnmadb, wfnmasb, wfnmadb, wfnmaxb
|
||||||
[(set (match_operand:V2DF 0 "register_operand" "=v")
|
(define_insn "neg_fma<mode>4"
|
||||||
(neg:V2DF (match_operand:V2DF 1 "register_operand" "v")))]
|
[(set (match_operand:VF_HW 0 "register_operand" "=v")
|
||||||
"TARGET_VX"
|
(neg:VF_HW
|
||||||
"vflcdb\t%v0,%v1"
|
(fma:VF_HW (match_operand:VF_HW 1 "register_operand" "%v")
|
||||||
|
(match_operand:VF_HW 2 "register_operand" "v")
|
||||||
|
(match_operand:VF_HW 3 "register_operand" "v"))))]
|
||||||
|
"TARGET_VXE"
|
||||||
|
"<vw>fnma<sdx>b\t%v0,%v1,%v2,%v3"
|
||||||
[(set_attr "op_type" "VRR")])
|
[(set_attr "op_type" "VRR")])
|
||||||
|
|
||||||
(define_insn "absv2df2"
|
; vfnmssb, vfnmsdb, wfnmssb, wfnmsdb, wfnmsxb
|
||||||
[(set (match_operand:V2DF 0 "register_operand" "=v")
|
(define_insn "neg_fms<mode>4"
|
||||||
(abs:V2DF (match_operand:V2DF 1 "register_operand" "v")))]
|
[(set (match_operand:VF_HW 0 "register_operand" "=v")
|
||||||
"TARGET_VX"
|
(neg:VF_HW
|
||||||
"vflpdb\t%v0,%v1"
|
(fma:VF_HW (match_operand:VF_HW 1 "register_operand" "%v")
|
||||||
|
(match_operand:VF_HW 2 "register_operand" "v")
|
||||||
|
(neg:VF_HW (match_operand:VF_HW 3 "register_operand" "v")))))]
|
||||||
|
"TARGET_VXE"
|
||||||
|
"<vw>fnms<sdx>b\t%v0,%v1,%v2,%v3"
|
||||||
[(set_attr "op_type" "VRR")])
|
[(set_attr "op_type" "VRR")])
|
||||||
|
|
||||||
(define_insn "*negabsv2df2"
|
; vflcsb, vflcdb, wflcsb, wflcdb, wflcxb
|
||||||
[(set (match_operand:V2DF 0 "register_operand" "=v")
|
(define_insn "neg<mode>2"
|
||||||
(neg:V2DF (abs:V2DF (match_operand:V2DF 1 "register_operand" "v"))))]
|
[(set (match_operand:VFT 0 "register_operand" "=v")
|
||||||
|
(neg:VFT (match_operand:VFT 1 "register_operand" "v")))]
|
||||||
"TARGET_VX"
|
"TARGET_VX"
|
||||||
"vflndb\t%v0,%v1"
|
"<vw>flc<sdx>b\t%v0,%v1"
|
||||||
|
[(set_attr "op_type" "VRR")])
|
||||||
|
|
||||||
|
; vflpsb, vflpdb, wflpsb, wflpdb, wflpxb
|
||||||
|
(define_insn "abs<mode>2"
|
||||||
|
[(set (match_operand:VFT 0 "register_operand" "=v")
|
||||||
|
(abs:VFT (match_operand:VFT 1 "register_operand" "v")))]
|
||||||
|
"TARGET_VX"
|
||||||
|
"<vw>flp<sdx>b\t%v0,%v1"
|
||||||
|
[(set_attr "op_type" "VRR")])
|
||||||
|
|
||||||
|
; vflnsb, vflndb, wflnsb, wflndb, wflnxb
|
||||||
|
(define_insn "negabs<mode>2"
|
||||||
|
[(set (match_operand:VFT 0 "register_operand" "=v")
|
||||||
|
(neg:VFT (abs:VFT (match_operand:VFT 1 "register_operand" "v"))))]
|
||||||
|
"TARGET_VX"
|
||||||
|
"<vw>fln<sdx>b\t%v0,%v1"
|
||||||
|
[(set_attr "op_type" "VRR")])
|
||||||
|
|
||||||
|
(define_expand "smax<mode>3"
|
||||||
|
[(set (match_operand:VF_HW 0 "register_operand")
|
||||||
|
(smax:VF_HW (match_operand:VF_HW 1 "register_operand")
|
||||||
|
(match_operand:VF_HW 2 "register_operand")))]
|
||||||
|
"TARGET_VX")
|
||||||
|
|
||||||
|
; vfmaxsb, vfmaxdb, wfmaxsb, wfmaxdb, wfmaxxb
|
||||||
|
(define_insn "*smax<mode>3_vxe"
|
||||||
|
[(set (match_operand:VF_HW 0 "register_operand" "=v")
|
||||||
|
(smax:VF_HW (match_operand:VF_HW 1 "register_operand" "%v")
|
||||||
|
(match_operand:VF_HW 2 "register_operand" "v")))]
|
||||||
|
"TARGET_VXE"
|
||||||
|
"<vw>fmax<sdx>b\t%v0,%v1,%v2,4"
|
||||||
[(set_attr "op_type" "VRR")])
|
[(set_attr "op_type" "VRR")])
|
||||||
|
|
||||||
; Emulate with compare + select
|
; Emulate with compare + select
|
||||||
(define_insn_and_split "smaxv2df3"
|
(define_insn_and_split "*smaxv2df3_vx"
|
||||||
[(set (match_operand:V2DF 0 "register_operand" "=v")
|
[(set (match_operand:V2DF 0 "register_operand" "=v")
|
||||||
(smax:V2DF (match_operand:V2DF 1 "register_operand" "%v")
|
(smax:V2DF (match_operand:V2DF 1 "register_operand" "%v")
|
||||||
(match_operand:V2DF 2 "register_operand" "v")))]
|
(match_operand:V2DF 2 "register_operand" "v")))]
|
||||||
"TARGET_VX"
|
"TARGET_VX && !TARGET_VXE"
|
||||||
"#"
|
"#"
|
||||||
""
|
"&& 1"
|
||||||
[(set (match_dup 3)
|
[(set (match_dup 3)
|
||||||
(gt:V2DI (match_dup 1) (match_dup 2)))
|
(gt:V2DI (match_dup 1) (match_dup 2)))
|
||||||
(set (match_dup 0)
|
(set (match_dup 0)
|
||||||
|
@ -1127,14 +1194,29 @@
|
||||||
operands[4] = CONST0_RTX (V2DImode);
|
operands[4] = CONST0_RTX (V2DImode);
|
||||||
})
|
})
|
||||||
|
|
||||||
|
(define_expand "smin<mode>3"
|
||||||
|
[(set (match_operand:VF_HW 0 "register_operand")
|
||||||
|
(smin:VF_HW (match_operand:VF_HW 1 "register_operand")
|
||||||
|
(match_operand:VF_HW 2 "register_operand")))]
|
||||||
|
"TARGET_VX")
|
||||||
|
|
||||||
|
; vfminsb, vfmindb, wfminsb, wfmindb, wfminxb
|
||||||
|
(define_insn "*smin<mode>3_vxe"
|
||||||
|
[(set (match_operand:VF_HW 0 "register_operand" "=v")
|
||||||
|
(smin:VF_HW (match_operand:VF_HW 1 "register_operand" "%v")
|
||||||
|
(match_operand:VF_HW 2 "register_operand" "v")))]
|
||||||
|
"TARGET_VXE"
|
||||||
|
"<vw>fmin<sdx>b\t%v0,%v1,%v2,4"
|
||||||
|
[(set_attr "op_type" "VRR")])
|
||||||
|
|
||||||
; Emulate with compare + select
|
; Emulate with compare + select
|
||||||
(define_insn_and_split "sminv2df3"
|
(define_insn_and_split "*sminv2df3_vx"
|
||||||
[(set (match_operand:V2DF 0 "register_operand" "=v")
|
[(set (match_operand:V2DF 0 "register_operand" "=v")
|
||||||
(smin:V2DF (match_operand:V2DF 1 "register_operand" "%v")
|
(smin:V2DF (match_operand:V2DF 1 "register_operand" "%v")
|
||||||
(match_operand:V2DF 2 "register_operand" "v")))]
|
(match_operand:V2DF 2 "register_operand" "v")))]
|
||||||
"TARGET_VX"
|
"TARGET_VX && !TARGET_VXE"
|
||||||
"#"
|
"#"
|
||||||
""
|
"&& 1"
|
||||||
[(set (match_dup 3)
|
[(set (match_dup 3)
|
||||||
(gt:V2DI (match_dup 1) (match_dup 2)))
|
(gt:V2DI (match_dup 1) (match_dup 2)))
|
||||||
(set (match_dup 0)
|
(set (match_dup 0)
|
||||||
|
@ -1166,65 +1248,66 @@
|
||||||
;;
|
;;
|
||||||
|
|
||||||
; EQ, GT, GE
|
; EQ, GT, GE
|
||||||
(define_insn "*vec_cmp<VFCMP_HW_OP:code>v2df_nocc"
|
; vfcesb, vfcedb, wfcexb, vfchsb, vfchdb, wfchxb, vfchesb, vfchedb, wfchexb
|
||||||
[(set (match_operand:V2DI 0 "register_operand" "=v")
|
(define_insn "*vec_cmp<VFCMP_HW_OP:code><mode>_nocc"
|
||||||
(VFCMP_HW_OP:V2DI (match_operand:V2DF 1 "register_operand" "v")
|
[(set (match_operand:<tointvec> 0 "register_operand" "=v")
|
||||||
(match_operand:V2DF 2 "register_operand" "v")))]
|
(VFCMP_HW_OP:<tointvec> (match_operand:VFT 1 "register_operand" "v")
|
||||||
|
(match_operand:VFT 2 "register_operand" "v")))]
|
||||||
"TARGET_VX"
|
"TARGET_VX"
|
||||||
"vfc<VFCMP_HW_OP:asm_fcmp_op>db\t%v0,%v1,%v2"
|
"<vw>fc<VFCMP_HW_OP:asm_fcmp_op><sdx>b\t%v0,%v1,%v2"
|
||||||
[(set_attr "op_type" "VRR")])
|
[(set_attr "op_type" "VRR")])
|
||||||
|
|
||||||
; Expanders for not directly supported comparisons
|
; Expanders for not directly supported comparisons
|
||||||
|
|
||||||
; UNEQ a u== b -> !(a > b | b > a)
|
; UNEQ a u== b -> !(a > b | b > a)
|
||||||
(define_expand "vec_cmpuneqv2df"
|
(define_expand "vec_cmpuneq<mode>"
|
||||||
[(set (match_operand:V2DI 0 "register_operand" "=v")
|
[(set (match_operand:<tointvec> 0 "register_operand" "=v")
|
||||||
(gt:V2DI (match_operand:V2DF 1 "register_operand" "v")
|
(gt:<tointvec> (match_operand:VFT 1 "register_operand" "v")
|
||||||
(match_operand:V2DF 2 "register_operand" "v")))
|
(match_operand:VFT 2 "register_operand" "v")))
|
||||||
(set (match_dup 3)
|
(set (match_dup 3)
|
||||||
(gt:V2DI (match_dup 2) (match_dup 1)))
|
(gt:<tointvec> (match_dup 2) (match_dup 1)))
|
||||||
(set (match_dup 0) (ior:V2DI (match_dup 0) (match_dup 3)))
|
(set (match_dup 0) (ior:<tointvec> (match_dup 0) (match_dup 3)))
|
||||||
(set (match_dup 0) (not:V2DI (match_dup 0)))]
|
(set (match_dup 0) (not:<tointvec> (match_dup 0)))]
|
||||||
"TARGET_VX"
|
"TARGET_VX"
|
||||||
{
|
{
|
||||||
operands[3] = gen_reg_rtx (V2DImode);
|
operands[3] = gen_reg_rtx (<tointvec>mode);
|
||||||
})
|
})
|
||||||
|
|
||||||
; LTGT a <> b -> a > b | b > a
|
; LTGT a <> b -> a > b | b > a
|
||||||
(define_expand "vec_cmpltgtv2df"
|
(define_expand "vec_cmpltgt<mode>"
|
||||||
[(set (match_operand:V2DI 0 "register_operand" "=v")
|
[(set (match_operand:<tointvec> 0 "register_operand" "=v")
|
||||||
(gt:V2DI (match_operand:V2DF 1 "register_operand" "v")
|
(gt:<tointvec> (match_operand:VFT 1 "register_operand" "v")
|
||||||
(match_operand:V2DF 2 "register_operand" "v")))
|
(match_operand:VFT 2 "register_operand" "v")))
|
||||||
(set (match_dup 3) (gt:V2DI (match_dup 2) (match_dup 1)))
|
(set (match_dup 3) (gt:<tointvec> (match_dup 2) (match_dup 1)))
|
||||||
(set (match_dup 0) (ior:V2DI (match_dup 0) (match_dup 3)))]
|
(set (match_dup 0) (ior:<tointvec> (match_dup 0) (match_dup 3)))]
|
||||||
"TARGET_VX"
|
"TARGET_VX"
|
||||||
{
|
{
|
||||||
operands[3] = gen_reg_rtx (V2DImode);
|
operands[3] = gen_reg_rtx (<tointvec>mode);
|
||||||
})
|
})
|
||||||
|
|
||||||
; ORDERED (a, b): a >= b | b > a
|
; ORDERED (a, b): a >= b | b > a
|
||||||
(define_expand "vec_orderedv2df"
|
(define_expand "vec_ordered<mode>"
|
||||||
[(set (match_operand:V2DI 0 "register_operand" "=v")
|
[(set (match_operand:<tointvec> 0 "register_operand" "=v")
|
||||||
(ge:V2DI (match_operand:V2DF 1 "register_operand" "v")
|
(ge:<tointvec> (match_operand:VFT 1 "register_operand" "v")
|
||||||
(match_operand:V2DF 2 "register_operand" "v")))
|
(match_operand:VFT 2 "register_operand" "v")))
|
||||||
(set (match_dup 3) (gt:V2DI (match_dup 2) (match_dup 1)))
|
(set (match_dup 3) (gt:<tointvec> (match_dup 2) (match_dup 1)))
|
||||||
(set (match_dup 0) (ior:V2DI (match_dup 0) (match_dup 3)))]
|
(set (match_dup 0) (ior:<tointvec> (match_dup 0) (match_dup 3)))]
|
||||||
"TARGET_VX"
|
"TARGET_VX"
|
||||||
{
|
{
|
||||||
operands[3] = gen_reg_rtx (V2DImode);
|
operands[3] = gen_reg_rtx (<tointvec>mode);
|
||||||
})
|
})
|
||||||
|
|
||||||
; UNORDERED (a, b): !ORDERED (a, b)
|
; UNORDERED (a, b): !ORDERED (a, b)
|
||||||
(define_expand "vec_unorderedv2df"
|
(define_expand "vec_unordered<mode>"
|
||||||
[(set (match_operand:V2DI 0 "register_operand" "=v")
|
[(set (match_operand:<tointvec> 0 "register_operand" "=v")
|
||||||
(ge:V2DI (match_operand:V2DF 1 "register_operand" "v")
|
(ge:<tointvec> (match_operand:VFT 1 "register_operand" "v")
|
||||||
(match_operand:V2DF 2 "register_operand" "v")))
|
(match_operand:VFT 2 "register_operand" "v")))
|
||||||
(set (match_dup 3) (gt:V2DI (match_dup 2) (match_dup 1)))
|
(set (match_dup 3) (gt:<tointvec> (match_dup 2) (match_dup 1)))
|
||||||
(set (match_dup 0) (ior:V2DI (match_dup 0) (match_dup 3)))
|
(set (match_dup 0) (ior:<tointvec> (match_dup 0) (match_dup 3)))
|
||||||
(set (match_dup 0) (not:V2DI (match_dup 0)))]
|
(set (match_dup 0) (not:<tointvec> (match_dup 0)))]
|
||||||
"TARGET_VX"
|
"TARGET_VX"
|
||||||
{
|
{
|
||||||
operands[3] = gen_reg_rtx (V2DImode);
|
operands[3] = gen_reg_rtx (<tointvec>mode);
|
||||||
})
|
})
|
||||||
|
|
||||||
(define_insn "*vec_load_pair<mode>"
|
(define_insn "*vec_load_pair<mode>"
|
||||||
|
@ -1563,6 +1646,28 @@
|
||||||
"vupllf\t%0,%1"
|
"vupllf\t%0,%1"
|
||||||
[(set_attr "op_type" "VRR")])
|
[(set_attr "op_type" "VRR")])
|
||||||
|
|
||||||
|
;; vector load lengthened
|
||||||
|
|
||||||
|
; vflls
|
||||||
|
(define_insn "*vec_extendv4sf"
|
||||||
|
[(set (match_operand:V2DF 0 "register_operand" "=v")
|
||||||
|
(float_extend:V2DF
|
||||||
|
(vec_select:V2SF
|
||||||
|
(match_operand:V4SF 1 "register_operand" "v")
|
||||||
|
(parallel [(const_int 0) (const_int 2)]))))]
|
||||||
|
"TARGET_VX"
|
||||||
|
"vldeb\t%v0,%v1"
|
||||||
|
[(set_attr "op_type" "VRR")])
|
||||||
|
|
||||||
|
(define_insn "*vec_extendv2df"
|
||||||
|
[(set (match_operand:V1TF 0 "register_operand" "=v")
|
||||||
|
(float_extend:V1TF
|
||||||
|
(vec_select:V1DF
|
||||||
|
(match_operand:V2DF 1 "register_operand" "v")
|
||||||
|
(parallel [(const_int 0)]))))]
|
||||||
|
"TARGET_VXE"
|
||||||
|
"wflld\t%v0,%v1"
|
||||||
|
[(set_attr "op_type" "VRR")])
|
||||||
|
|
||||||
; reduc_smin
|
; reduc_smin
|
||||||
; reduc_smax
|
; reduc_smax
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
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>
|
2017-03-24 Andreas Krebbel <krebbel@linux.vnet.ibm.com>
|
||||||
|
|
||||||
* gcc.target/s390/arch12/aghsghmgh-1.c: New test.
|
* gcc.target/s390/arch12/aghsghmgh-1.c: New test.
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
/* { 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 } } */
|
Loading…
Reference in New Issue