+2019-08-14 Richard Sandiford <richard.sandiford@arm.com>
+
+ * config/aarch64/iterators.md (VNx4SI_ONLY, VNx2DF_ONLY): New mode
+ iterators.
+ (SVE_BHSI, SVE_SDI): Tweak comment.
+ (SVE_HSDI): Likewise. Fix definition.
+ (SVE_SDF): New mode iterator.
+ (elem_bits): New mode attribute.
+ (SVE_COND_FCVT): New int iterator.
+ * config/aarch64/aarch64-sve.md
+ (*<SVE_COND_ICVTF:optab>v16hsf<SVE_HSDI:mode>2)
+ (*<SVE_COND_ICVTF:optab>vnx4sf<SVE_SDI:mode>2)
+ (*<SVE_COND_ICVTF:optab>vnx2df<SVE_SDI:mode>2): Merge into...
+ (*aarch64_sve_<SVE_COND_ICVTF:optab>_nontrunc<SVE_F:mode><SVE_HSDI:mode>)
+ (*aarch64_sve_<SVE_COND_ICVTF:optab>_trunc<VNx2DF_ONLY:mode><VNx4SI_ONLY:mode>):
+ ...these new patterns.
+ (*<SVE_COND_FCVTI:optab><SVE_HSDI:mode>vnx8hf2)
+ (*<SVE_COND_FCVTI:optab><SVE_SDI:mode>vnx4sf2)
+ (aarch64_sve_<SVE_COND_FCVTI:optab><SVE_SDI:mode>vnx2df2):
+ Merge into...
+ (*aarch64_sve_<SVE_COND_FCVTI:optab>_nonextend<SVE_HSDI:mode><SVE_F:mode>)
+ (aarch64_sve_<SVE_COND_FCVTI:optab>_extend<VNx4SI_ONLY:mode><VNx2DF_ONLY:mode>):
+ ...these new patterns.
+ (vec_unpack<su_optab>_float_<perm_hilo>_vnx4si): Update accordingly.
+ (*trunc<Vwide><SVE_SDF:mode>2): Replace with...
+ (*aarch64_sve_<SVE_COND_FCVT:optab>_trunc<SVE_SDF:mode><SVE_HSF:mode>):
+ ...this new pattern.
+ (aarch64_sve_extend<SVE_HSDF:mode><Vwide>2): Replace with...
+ (aarch64_sve_<SVE_COND_FCVT:optab>_nontrunc<SVE_HSF:mode><SVE_SDF:mode>):
+ ...this new pattern.
+ (vec_unpacks_<perm_hilo>_<mode>): Update accordingly.
+
2019-08-14 Richard Sandiford <richard.sandiford@arm.com>
* config/aarch64/aarch64.md (UNSPEC_FLOAT_CONVERT): Delete.
}
)
-;; Conversion of SF to DI, SI or HI, predicated with a PTRUE.
-(define_insn "*<optab>v16hsf<mode>2"
+;; Predicated float-to-integer conversion, either to the same width or wider.
+(define_insn "*aarch64_sve_<optab>_nontrunc<SVE_F:mode><SVE_HSDI:mode>"
[(set (match_operand:SVE_HSDI 0 "register_operand" "=w")
(unspec:SVE_HSDI
- [(match_operand:<VPRED> 1 "register_operand" "Upl")
+ [(match_operand:<SVE_HSDI:VPRED> 1 "register_operand" "Upl")
(match_operand:SI 3 "aarch64_sve_gp_strictness")
- (match_operand:VNx8HF 2 "register_operand" "w")]
- SVE_COND_FCVTI))]
- "TARGET_SVE"
- "fcvtz<su>\t%0.<Vetype>, %1/m, %2.h"
-)
-
-;; Conversion of SF to DI or SI, predicated with a PTRUE.
-(define_insn "*<optab>vnx4sf<mode>2"
- [(set (match_operand:SVE_SDI 0 "register_operand" "=w")
- (unspec:SVE_SDI
- [(match_operand:<VPRED> 1 "register_operand" "Upl")
- (match_operand:SI 3 "aarch64_sve_gp_strictness")
- (match_operand:VNx4SF 2 "register_operand" "w")]
+ (match_operand:SVE_F 2 "register_operand" "w")]
SVE_COND_FCVTI))]
- "TARGET_SVE"
- "fcvtz<su>\t%0.<Vetype>, %1/m, %2.s"
+ "TARGET_SVE && <SVE_HSDI:elem_bits> >= <SVE_F:elem_bits>"
+ "fcvtz<su>\t%0.<SVE_HSDI:Vetype>, %1/m, %2.<SVE_F:Vetype>"
)
-;; Conversion of DF to DI or SI, predicated with a PTRUE.
-(define_insn "*<optab>vnx2df<mode>2"
- [(set (match_operand:SVE_SDI 0 "register_operand" "=w")
- (unspec:SVE_SDI
+;; Predicated narrowing float-to-integer conversion.
+(define_insn "*aarch64_sve_<optab>_trunc<VNx2DF_ONLY:mode><VNx4SI_ONLY:mode>"
+ [(set (match_operand:VNx4SI_ONLY 0 "register_operand" "=w")
+ (unspec:VNx4SI_ONLY
[(match_operand:VNx2BI 1 "register_operand" "Upl")
(match_operand:SI 3 "aarch64_sve_gp_strictness")
- (match_operand:VNx2DF 2 "register_operand" "w")]
+ (match_operand:VNx2DF_ONLY 2 "register_operand" "w")]
SVE_COND_FCVTI))]
"TARGET_SVE"
- "fcvtz<su>\t%0.<Vetype>, %1/m, %2.d"
+ "fcvtz<su>\t%0.<VNx4SI_ONLY:Vetype>, %1/m, %2.<VNx2DF_ONLY:Vetype>"
)
;; -------------------------------------------------------------------------
}
)
-;; Conversion of DI, SI or HI to the same number of HFs, predicated
-;; with a PTRUE.
-(define_insn "*<optab><mode>vnx8hf2"
- [(set (match_operand:VNx8HF 0 "register_operand" "=w")
- (unspec:VNx8HF
- [(match_operand:<VPRED> 1 "register_operand" "Upl")
+;; Predicated integer-to-float conversion, either to the same width or
+;; narrower.
+(define_insn "*aarch64_sve_<optab>_nonextend<SVE_HSDI:mode><SVE_F:mode>"
+ [(set (match_operand:SVE_F 0 "register_operand" "=w")
+ (unspec:SVE_F
+ [(match_operand:<SVE_HSDI:VPRED> 1 "register_operand" "Upl")
(match_operand:SI 3 "aarch64_sve_gp_strictness")
(match_operand:SVE_HSDI 2 "register_operand" "w")]
SVE_COND_ICVTF))]
- "TARGET_SVE"
- "<su>cvtf\t%0.h, %1/m, %2.<Vetype>"
-)
-
-;; Conversion of DI or SI to the same number of SFs, predicated with a PTRUE.
-(define_insn "*<optab><mode>vnx4sf2"
- [(set (match_operand:VNx4SF 0 "register_operand" "=w")
- (unspec:VNx4SF
- [(match_operand:<VPRED> 1 "register_operand" "Upl")
- (match_operand:SI 3 "aarch64_sve_gp_strictness")
- (match_operand:SVE_SDI 2 "register_operand" "w")]
- SVE_COND_ICVTF))]
- "TARGET_SVE"
- "<su>cvtf\t%0.s, %1/m, %2.<Vetype>"
+ "TARGET_SVE && <SVE_HSDI:elem_bits> >= <SVE_F:elem_bits>"
+ "<su>cvtf\t%0.<SVE_F:Vetype>, %1/m, %2.<SVE_HSDI:Vetype>"
)
-;; Conversion of DI or SI to DF, predicated with a PTRUE.
-(define_insn "aarch64_sve_<optab><mode>vnx2df2"
- [(set (match_operand:VNx2DF 0 "register_operand" "=w")
- (unspec:VNx2DF
+;; Predicated widening integer-to-float conversion.
+(define_insn "aarch64_sve_<optab>_extend<VNx4SI_ONLY:mode><VNx2DF_ONLY:mode>"
+ [(set (match_operand:VNx2DF_ONLY 0 "register_operand" "=w")
+ (unspec:VNx2DF_ONLY
[(match_operand:VNx2BI 1 "register_operand" "Upl")
(match_operand:SI 3 "aarch64_sve_gp_strictness")
- (match_operand:SVE_SDI 2 "register_operand" "w")]
+ (match_operand:VNx4SI_ONLY 2 "register_operand" "w")]
SVE_COND_ICVTF))]
"TARGET_SVE"
- "<su>cvtf\t%0.d, %1/m, %2.<Vetype>"
+ "<su>cvtf\t%0.<VNx2DF_ONLY:Vetype>, %1/m, %2.<VNx4SI_ONLY:Vetype>"
)
;; -------------------------------------------------------------------------
(temp, operands[1], operands[1]));
rtx ptrue = aarch64_ptrue_reg (VNx2BImode);
rtx strictness = gen_int_mode (SVE_RELAXED_GP, SImode);
- emit_insn (gen_aarch64_sve_<FLOATUORS:optab>vnx4sivnx2df2
+ emit_insn (gen_aarch64_sve_<FLOATUORS:optab>_extendvnx4sivnx2df
(operands[0], ptrue, temp, strictness));
DONE;
}
}
)
-;; Conversion of DFs to the same number of SFs, or SFs to the same number
-;; of HFs.
-(define_insn "*trunc<Vwide><mode>2"
+;; Predicated float-to-float truncation.
+(define_insn "*aarch64_sve_<optab>_trunc<SVE_SDF:mode><SVE_HSF:mode>"
[(set (match_operand:SVE_HSF 0 "register_operand" "=w")
(unspec:SVE_HSF
- [(match_operand:<VWIDE_PRED> 1 "register_operand" "Upl")
+ [(match_operand:<SVE_SDF:VPRED> 1 "register_operand" "Upl")
(match_operand:SI 3 "aarch64_sve_gp_strictness")
- (match_operand:<VWIDE> 2 "register_operand" "w")]
- UNSPEC_COND_FCVT))]
- "TARGET_SVE"
- "fcvt\t%0.<Vetype>, %1/m, %2.<Vewtype>"
+ (match_operand:SVE_SDF 2 "register_operand" "w")]
+ SVE_COND_FCVT))]
+ "TARGET_SVE && <SVE_SDF:elem_bits> > <SVE_HSF:elem_bits>"
+ "fcvt\t%0.<SVE_HSF:Vetype>, %1/m, %2.<SVE_SDF:Vetype>"
)
;; -------------------------------------------------------------------------
(temp, operands[1], operands[1]));
rtx ptrue = aarch64_ptrue_reg (<VWIDE_PRED>mode);
rtx strictness = gen_int_mode (SVE_RELAXED_GP, SImode);
- emit_insn (gen_aarch64_sve_extend<mode><Vwide>2
+ emit_insn (gen_aarch64_sve_fcvt_nontrunc<mode><Vwide>
(operands[0], ptrue, temp, strictness));
DONE;
}
)
-;; Conversion of SFs to the same number of DFs, or HFs to the same number
-;; of SFs.
-(define_insn "aarch64_sve_extend<mode><Vwide>2"
- [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
- (unspec:<VWIDE>
- [(match_operand:<VWIDE_PRED> 1 "register_operand" "Upl")
+;; Predicated float-to-float extension.
+(define_insn "aarch64_sve_<optab>_nontrunc<SVE_HSF:mode><SVE_SDF:mode>"
+ [(set (match_operand:SVE_SDF 0 "register_operand" "=w")
+ (unspec:SVE_SDF
+ [(match_operand:<SVE_SDF:VPRED> 1 "register_operand" "Upl")
(match_operand:SI 3 "aarch64_sve_gp_strictness")
(match_operand:SVE_HSF 2 "register_operand" "w")]
- UNSPEC_COND_FCVT))]
- "TARGET_SVE"
- "fcvt\t%0.<Vewtype>, %1/m, %2.<Vetype>"
+ SVE_COND_FCVT))]
+ "TARGET_SVE && <SVE_SDF:elem_bits> > <SVE_HSF:elem_bits>"
+ "fcvt\t%0.<SVE_SDF:Vetype>, %1/m, %2.<SVE_HSF:Vetype>"
)
;; -------------------------------------------------------------------------
(define_mode_iterator SVE_ALL [VNx16QI VNx8HI VNx4SI VNx2DI
VNx8HF VNx4SF VNx2DF])
+;; Iterators for single modes, for "@" patterns.
+(define_mode_iterator VNx4SI_ONLY [VNx4SI])
+(define_mode_iterator VNx2DF_ONLY [VNx2DF])
+
;; All SVE vector structure modes.
(define_mode_iterator SVE_STRUCT [VNx32QI VNx16HI VNx8SI VNx4DI
VNx16HF VNx8SF VNx4DF
;; All SVE vector modes that have 8-bit, 16-bit or 32-bit elements.
(define_mode_iterator SVE_BHS [VNx16QI VNx8HI VNx4SI VNx8HF VNx4SF])
-;; All SVE integer vector modes that have 8-bit, 16-bit or 32-bit elements.
+;; SVE integer vector modes that have 8-bit, 16-bit or 32-bit elements.
(define_mode_iterator SVE_BHSI [VNx16QI VNx8HI VNx4SI])
-;; All SVE integer vector modes that have 16-bit, 32-bit or 64-bit elements.
-(define_mode_iterator SVE_HSDI [VNx16QI VNx8HI VNx4SI])
+;; SVE integer vector modes that have 16-bit, 32-bit or 64-bit elements.
+(define_mode_iterator SVE_HSDI [VNx8HI VNx4SI VNx2DI])
-;; All SVE floating-point vector modes that have 16-bit or 32-bit elements.
+;; SVE floating-point vector modes that have 16-bit or 32-bit elements.
(define_mode_iterator SVE_HSF [VNx8HF VNx4SF])
+;; SVE integer vector modes that have 32-bit or 64-bit elements.
+(define_mode_iterator SVE_SDI [VNx4SI VNx2DI])
+
+;; SVE floating-point vector modes that have 32-bit or 64-bit elements.
+(define_mode_iterator SVE_SDF [VNx4SF VNx2DF])
+
;; All SVE vector modes that have 16-bit, 32-bit or 64-bit elements.
(define_mode_iterator SVE_HSD [VNx8HI VNx4SI VNx2DI VNx8HF VNx4SF VNx2DF])
;; All SVE vector modes that have 64-bit elements.
(define_mode_iterator SVE_D [VNx2DI VNx2DF])
-;; All SVE integer vector modes that have 32-bit or 64-bit elements.
-(define_mode_iterator SVE_SDI [VNx4SI VNx2DI])
-
;; All SVE integer vector modes.
(define_mode_iterator SVE_I [VNx16QI VNx8HI VNx4SI VNx2DI])
(define_mode_attr sizem1 [(QI "#7") (HI "#15") (SI "#31") (DI "#63")
(HF "#15") (SF "#31") (DF "#63")])
+;; The number of bits in a vector element, or controlled by a predicate
+;; element.
+(define_mode_attr elem_bits [(VNx8HI "16") (VNx4SI "32") (VNx2DI "64")
+ (VNx8HF "16") (VNx4SF "32") (VNx2DF "64")])
+
;; Attribute to describe constants acceptable in logical operations
(define_mode_attr lconst [(SI "K") (DI "L")])
UNSPEC_COND_FRINTZ
UNSPEC_COND_FSQRT])
+(define_int_iterator SVE_COND_FCVT [UNSPEC_COND_FCVT])
(define_int_iterator SVE_COND_FCVTI [UNSPEC_COND_FCVTZS UNSPEC_COND_FCVTZU])
(define_int_iterator SVE_COND_ICVTF [UNSPEC_COND_SCVTF UNSPEC_COND_UCVTF])