defm vstrwq: scatter_offset_both<T.All32, u32, 2>;
defm vstrdq: scatter_offset_both<T.Int64, u64, 3>;
-multiclass PredicatedImmediateVectorShift<
- Immediate immtype, string predIntrName, list<dag> unsignedFlag = []> {
- foreach predIntr = [IRInt<predIntrName, [Vector, Predicate]>] in {
- def _m_n: Intrinsic<Vector, (args Vector:$inactive, Vector:$v,
- immtype:$sh, Predicate:$pred),
- !con((predIntr $v, $sh), !dag(predIntr, unsignedFlag, ?),
- (predIntr $pred, $inactive))>;
- def _x_n: Intrinsic<Vector, (args Vector:$v, immtype:$sh,
- Predicate:$pred),
- !con((predIntr $v, $sh), !dag(predIntr, unsignedFlag, ?),
- (predIntr $pred, (undef Vector)))>;
- }
-}
-
let params = T.Int in {
def vshlq_n: Intrinsic<Vector, (args Vector:$v, imm_0toNm1:$sh),
(shl $v, (splat (Scalar $sh)))>;
- defm vshlq: PredicatedImmediateVectorShift<imm_0toNm1, "shl_imm_predicated">;
+ defm vshlq: IntrinsicMX<Vector, (args Vector:$v, imm_0toNm1:$sh,
+ Predicate:$pred),
+ (IRInt<"shl_imm_predicated", [Vector, Predicate]>
+ $v, $sh, $pred, $inactive), "_n">;
let pnt = PNT_NType in {
def vshrq_n: Intrinsic<Vector, (args Vector:$v, imm_1toN:$sh),
(immshr $v, $sh, (unsignedflag Scalar))>;
- defm vshrq: PredicatedImmediateVectorShift<imm_1toN, "shr_imm_predicated",
- [(unsignedflag Scalar)]>;
+ defm vshrq: IntrinsicMX<Vector, (args Vector:$v, imm_1toN:$sh,
+ Predicate:$pred),
+ (IRInt<"shr_imm_predicated", [Vector, Predicate]>
+ $v, $sh, (unsignedflag Scalar), $pred, $inactive), "_n">;
}
}
multiclass VectorComplexAddPred<dag not_halving, dag angle> {
def "" : Intrinsic<Vector, (args Vector:$a, Vector:$b),
(IRInt<"vcaddq", [Vector]> not_halving, angle, $a, $b)>;
- def _m : Intrinsic<Vector, (args Vector:$inactive, Vector:$a, Vector:$b,
- Predicate:$pred),
+ defm "" : IntrinsicMX<Vector, (args Vector:$a, Vector:$b, Predicate:$pred),
(IRInt<"vcaddq_predicated", [Vector, Predicate]>
not_halving, angle, $inactive, $a, $b, $pred)>;
- def _x : Intrinsic<Vector, (args Vector:$a, Vector:$b, Predicate:$pred),
- (IRInt<"vcaddq_predicated", [Vector, Predicate]>
- not_halving, angle, (undef Vector), $a, $b, $pred)>;
}
multiclass VectorComplexMulPred<dag angle> {
def "" : Intrinsic<Vector, (args Vector:$a, Vector:$b),
(IRInt<"vcmulq", [Vector]> angle, $a, $b)>;
- def _m : Intrinsic<Vector, (args Vector:$inactive, Vector:$a, Vector:$b,
- Predicate:$pred),
+ defm "" : IntrinsicMX<Vector, (args Vector:$a, Vector:$b, Predicate:$pred),
(IRInt<"vcmulq_predicated", [Vector, Predicate]> angle, $inactive, $a, $b,
$pred)>;
- def _x : Intrinsic<Vector, (args Vector:$a, Vector:$b, Predicate:$pred),
- (IRInt<"vcmulq_predicated", [Vector, Predicate]> angle, (undef Vector), $a,
- $b, $pred)>;
}
multiclass VectorComplexMLAPred<dag angle> {
string basename = basename_;
}
+// A wrapper to define both _m and _x versions of a predicated
+// intrinsic.
+multiclass IntrinsicMX<Type rettype, dag arguments, dag cg,
+ string nameSuffix = "",
+ PolymorphicNameType pnt_x = PNT_Type> {
+ // The _m variant takes an initial parameter called $inactive, which
+ // provides the input value of the output register, i.e. all the
+ // inactive lanes in the predicated operation take their values from
+ // this.
+ def "_m" # nameSuffix:
+ Intrinsic<rettype, !con((args rettype:$inactive), arguments), cg>;
+
+ // The _x variant leaves off that parameter, and simply uses an
+ // undef value of the same type.
+ def "_x" # nameSuffix:
+ Intrinsic<rettype, arguments, (seq (undef rettype):$inactive, cg)> {
+ // Allow overriding of the polymorphic name type, because
+ // sometimes the _m and _x variants polymorph differently
+ // (typically because the type of the inactive parameter can be
+ // used as a disambiguator if it's present).
+ let pnt = pnt_x;
+ }
+}
+
// -----------------------------------------------------------------------------
// Convenience lists of parameter types. 'T' is just a container record, so you
// can define a typical intrinsic with 'let Params = T.Usual', or similar,