First patch in a series adding MC layer support for SVE2.1.
This patch adds the following feature:
sve2p1
Some of the existing SVE instructions added for SME are now
also available under the sve2p1 feature, which are now guarded
by the HasSVE2p1orSME predicate.
The reference can be found here:
https://developer.arm.com/documentation/ddi0602/2022-09
Differential Revision: https://reviews.llvm.org/D136352
AARCH64_ARCH_EXT_NAME("sve2-sm4", AArch64::AEK_SVE2SM4, "+sve2-sm4", "-sve2-sm4")
AARCH64_ARCH_EXT_NAME("sve2-sha3", AArch64::AEK_SVE2SHA3, "+sve2-sha3", "-sve2-sha3")
AARCH64_ARCH_EXT_NAME("sve2-bitperm", AArch64::AEK_SVE2BITPERM, "+sve2-bitperm", "-sve2-bitperm")
+AARCH64_ARCH_EXT_NAME("sve2p1", AArch64::AEK_SVE2p1, "+sve2p1", "-sve2p1")
AARCH64_ARCH_EXT_NAME("rcpc", AArch64::AEK_RCPC, "+rcpc", "-rcpc")
AARCH64_ARCH_EXT_NAME("rng", AArch64::AEK_RAND, "+rand", "-rand")
AARCH64_ARCH_EXT_NAME("memtag", AArch64::AEK_MTE, "+mte", "-mte")
AEK_MOPS = 1ULL << 41, // FEAT_MOPS
AEK_PERFMON = 1ULL << 42, // FEAT_PMUv3
AEK_SME2 = 1ULL << 43, // FEAT_SME2
+ AEK_SVE2p1 = 1ULL << 44, // FEAT_SVE2p1
};
enum class ArchKind {
def FeatureSVE2BitPerm : SubtargetFeature<"sve2-bitperm", "HasSVE2BitPerm", "true",
"Enable bit permutation SVE2 instructions (FEAT_SVE_BitPerm)", [FeatureSVE2]>;
+def FeatureSVE2p1: SubtargetFeature<"sve2p1", "HasSVE2p1", "true",
+ "Enable Scalable Vector Extension 2.1 instructions", [FeatureSVE2]>;
+
def FeatureZCRegMove : SubtargetFeature<"zcm", "HasZeroCycleRegMove", "true",
"Has zero-cycle register moves">;
}
def SMEUnsupported : AArch64Unsupported {
- let F = [HasSME, HasSMEF64F64, HasSMEI16I64, HasSME2];
+ let F = [HasSME, HasSMEF64F64, HasSMEI16I64, HasSME2, HasSVE2p1_or_HasSME2];
}
include "AArch64SchedA53.td"
AssemblerPredicateWithAll<(all_of FeatureSVE), "sve">;
def HasSVE2 : Predicate<"Subtarget->hasSVE2()">,
AssemblerPredicateWithAll<(all_of FeatureSVE2), "sve2">;
+def HasSVE2p1 : Predicate<"Subtarget->hasSVE2p1()">,
+ AssemblerPredicate<(any_of FeatureSVE2p1), "sve2p1">;
def HasSVE2AES : Predicate<"Subtarget->hasSVE2AES()">,
AssemblerPredicateWithAll<(all_of FeatureSVE2AES), "sve2-aes">;
def HasSVE2SM4 : Predicate<"Subtarget->hasSVE2SM4()">,
: Predicate<"Subtarget->hasSVE2() || Subtarget->hasSME()">,
AssemblerPredicateWithAll<(any_of FeatureSVE2, FeatureSME),
"sve2 or sme">;
+def HasSVE2p1_or_HasSME
+ : Predicate<"Subtarget->hasSVE2p1() || Subtarget->hasSME()">,
+ AssemblerPredicate<(any_of FeatureSME, FeatureSVE2p1), "sme or sve2p1">;
+def HasSVE2p1_or_HasSME2
+ : Predicate<"Subtarget->hasSVE2p1() || Subtarget->hasSME2()">,
+ AssemblerPredicate<(any_of FeatureSME2, FeatureSVE2p1), "sme2 or sve2p1">;
// A subset of NEON instructions are legal in Streaming SVE execution mode,
// they should be enabled if either has been specified.
def HasNEONorSME
def OBSCURE_COPY : Pseudo<(outs GPR64:$dst), (ins GPR64:$idx), []>, Sched<[]> { }
def : Pat<(i64 (AArch64ObscureCopy (i64 GPR64:$idx))),
(OBSCURE_COPY GPR64:$idx)>;
-
-//===----------------------------------------------------------------------===//
-// SVE2 instructions
-//===----------------------------------------------------------------------===//
-
-defm REVD_ZPmZ : sve2_int_perm_revd<"revd", AArch64revd_mt>;
-
-defm SCLAMP_ZZZ : sve2_clamp<"sclamp", 0b0, int_aarch64_sve_sclamp>;
-defm UCLAMP_ZZZ : sve2_clamp<"uclamp", 0b1, int_aarch64_sve_uclamp>;
-
-defm PSEL_PPPRI : sve2_int_perm_sel_p<"psel", int_aarch64_sve_psel>;
-
} // End let Predicates = [HasSME]
//===----------------------------------------------------------------------===//
defm BDEP_ZZZ : sve2_misc_bitwise<0b1101, "bdep", int_aarch64_sve_bdep_x>;
defm BGRP_ZZZ : sve2_misc_bitwise<0b1110, "bgrp", int_aarch64_sve_bgrp_x>;
} // End HasSVE2BitPerm
+
+//===----------------------------------------------------------------------===//
+// SME or SVE2.1 instructions
+//===----------------------------------------------------------------------===//
+
+let Predicates = [HasSVE2p1_or_HasSME] in {
+defm REVD_ZPmZ : sve2_int_perm_revd<"revd", AArch64revd_mt>;
+
+defm SCLAMP_ZZZ : sve2_clamp<"sclamp", 0b0, int_aarch64_sve_sclamp>;
+defm UCLAMP_ZZZ : sve2_clamp<"uclamp", 0b1, int_aarch64_sve_uclamp>;
+
+defm PSEL_PPPRI : sve2_int_perm_sel_p<"psel", int_aarch64_sve_psel>;
+} // End HasSVE2p1_or_HasSME
{"sve2-sm4", {AArch64::FeatureSVE2SM4}},
{"sve2-sha3", {AArch64::FeatureSVE2SHA3}},
{"sve2-bitperm", {AArch64::FeatureSVE2BitPerm}},
+ {"sve2p1", {AArch64::FeatureSVE2p1}},
{"ls64", {AArch64::FeatureLS64}},
{"xs", {AArch64::FeatureXS}},
{"pauth", {AArch64::FeaturePAuth}},
--- /dev/null
+// RUN: not llvm-mc -triple aarch64 -filetype asm -o - %s 2>&1 | FileCheck %s
+
+.arch armv9-a+sve2p1
+.arch armv9-a+nosve2p1
+sclamp z0.s, z1.s, z2.s
+// CHECK: error: instruction requires: sme or sve2p1
+// CHECK: sclamp z0.s, z1.s, z2.s
--- /dev/null
+// RUN: llvm-mc -triple aarch64 -filetype asm -o - %s 2>&1 | FileCheck %s
+
+.arch armv9-a+sve2p1
+sclamp z0.s, z1.s, z2.s
+// CHECK: sclamp z0.s, z1.s, z2.s
--- /dev/null
+// RUN: not llvm-mc -triple aarch64 -filetype asm -o - %s 2>&1 | FileCheck %s
+
+.arch_extension sve2p1
+.arch_extension nosve2p1
+sclamp z0.s, z1.s, z2.s
+// CHECK: error: instruction requires: sme or sve2p1
+// CHECK: sclamp z0.s, z1.s, z2.s
--- /dev/null
+// RUN: llvm-mc -triple aarch64 -filetype asm -o - %s 2>&1 | FileCheck %s
+
+.arch_extension sve2p1
+sclamp z0.s, z1.s, z2.s
+// CHECK: sclamp z0.s, z1.s, z2.s
--- /dev/null
+// This test verifies SVE2p1 implies SVE2.
+
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sve2p1 2>&1 < %s \
+// RUN: | FileCheck %s
+
+cmla z0.b, z1.b, z2.b, #0
+// CHECK: cmla z0.b, z1.b, z2.b, #0
AArch64::AEK_BRBE, AArch64::AEK_PAUTH, AArch64::AEK_FLAGM,
AArch64::AEK_SME, AArch64::AEK_SMEF64F64, AArch64::AEK_SMEI16I64,
AArch64::AEK_SME2, AArch64::AEK_HBC, AArch64::AEK_MOPS,
- AArch64::AEK_PERFMON};
+ AArch64::AEK_PERFMON, AArch64::AEK_SVE2p1};
std::vector<StringRef> Features;
EXPECT_TRUE(llvm::is_contained(Features, "+sve2-sm4"));
EXPECT_TRUE(llvm::is_contained(Features, "+sve2-sha3"));
EXPECT_TRUE(llvm::is_contained(Features, "+sve2-bitperm"));
+ EXPECT_TRUE(llvm::is_contained(Features, "+sve2p1"));
EXPECT_TRUE(llvm::is_contained(Features, "+rcpc"));
EXPECT_TRUE(llvm::is_contained(Features, "+rand"));
EXPECT_TRUE(llvm::is_contained(Features, "+mte"));
{"sve2-aes", "nosve2-aes", "+sve2-aes", "-sve2-aes"},
{"sve2-sm4", "nosve2-sm4", "+sve2-sm4", "-sve2-sm4"},
{"sve2-sha3", "nosve2-sha3", "+sve2-sha3", "-sve2-sha3"},
+ {"sve2p1", "nosve2p1", "+sve2p1", "-sve2p1"},
{"sve2-bitperm", "nosve2-bitperm", "+sve2-bitperm", "-sve2-bitperm"},
{"dotprod", "nodotprod", "+dotprod", "-dotprod"},
{"rcpc", "norcpc", "+rcpc", "-rcpc"},