[AArch64] Add SME feature detection on Linux

This commit just adds the kCpuHasSME to represent that the CPU has the
Arm Scalable Matrix Extension enabled, but this commit does not
introduce any code to actually use it yet.

Add a test to check that the HWCAP value is interpreted correctly.

Change-Id: I2de7bca26ca44ff3ee278b59108298a299a171b7
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/5598869
Reviewed-by: Justin Green <greenjustin@google.com>
Reviewed-by: Frank Barchard <fbarchard@chromium.org>
This commit is contained in:
George Steed 2024-05-20 18:29:01 +01:00 committed by Frank Barchard
parent 910f8e3645
commit c8974cf8d4
4 changed files with 11 additions and 0 deletions

View File

@ -29,6 +29,7 @@ static const int kCpuHasNeonDotProd = 0x10;
static const int kCpuHasNeonI8MM = 0x20; static const int kCpuHasNeonI8MM = 0x20;
static const int kCpuHasSVE = 0x40; static const int kCpuHasSVE = 0x40;
static const int kCpuHasSVE2 = 0x80; static const int kCpuHasSVE2 = 0x80;
static const int kCpuHasSME = 0x100;
// These flags are only valid on x86 processors. // These flags are only valid on x86 processors.
static const int kCpuHasX86 = 0x8; static const int kCpuHasX86 = 0x8;

View File

@ -186,6 +186,7 @@ LIBYUV_API SAFEBUFFERS int ArmCpuCaps(const char* cpuinfo_name) {
#define YUV_AARCH64_HWCAP_SVE (1 << 22) #define YUV_AARCH64_HWCAP_SVE (1 << 22)
#define YUV_AARCH64_HWCAP2_SVE2 (1 << 1) #define YUV_AARCH64_HWCAP2_SVE2 (1 << 1)
#define YUV_AARCH64_HWCAP2_I8MM (1 << 13) #define YUV_AARCH64_HWCAP2_I8MM (1 << 13)
#define YUV_AARCH64_HWCAP2_SME (1 << 23)
// For AArch64, but public to allow testing on any CPU. // For AArch64, but public to allow testing on any CPU.
LIBYUV_API SAFEBUFFERS int AArch64CpuCaps(unsigned long hwcap, LIBYUV_API SAFEBUFFERS int AArch64CpuCaps(unsigned long hwcap,
@ -207,6 +208,9 @@ LIBYUV_API SAFEBUFFERS int AArch64CpuCaps(unsigned long hwcap,
features |= kCpuHasSVE; features |= kCpuHasSVE;
if (hwcap2 & YUV_AARCH64_HWCAP2_SVE2) { if (hwcap2 & YUV_AARCH64_HWCAP2_SVE2) {
features |= kCpuHasSVE2; features |= kCpuHasSVE2;
if (hwcap2 & YUV_AARCH64_HWCAP2_SME) {
features |= kCpuHasSME;
}
} }
} }
} }

View File

@ -289,6 +289,10 @@ TEST_F(LibYUVBaseTest, TestLinuxAArch64) {
// Values taken from a Neoverse N2 machine. // Values taken from a Neoverse N2 machine.
EXPECT_EQ(expected, AArch64CpuCaps(0x3fffffffU, 0x2f3ffU)); EXPECT_EQ(expected, AArch64CpuCaps(0x3fffffffU, 0x2f3ffU));
// Check for SME feature detection.
expected |= kCpuHasSME;
EXPECT_EQ(expected, AArch64CpuCaps(0x3fffffffU, 0x82f3ffU));
} }
#endif #endif

View File

@ -99,12 +99,14 @@ int main(int argc, const char* argv[]) {
int has_neon_i8mm = TestCpuFlag(kCpuHasNeonI8MM); int has_neon_i8mm = TestCpuFlag(kCpuHasNeonI8MM);
int has_sve = TestCpuFlag(kCpuHasSVE); int has_sve = TestCpuFlag(kCpuHasSVE);
int has_sve2 = TestCpuFlag(kCpuHasSVE2); int has_sve2 = TestCpuFlag(kCpuHasSVE2);
int has_sme = TestCpuFlag(kCpuHasSME);
printf("Has Arm 0x%x\n", has_arm); printf("Has Arm 0x%x\n", has_arm);
printf("Has Neon 0x%x\n", has_neon); printf("Has Neon 0x%x\n", has_neon);
printf("Has Neon DotProd 0x%x\n", has_neon_dotprod); printf("Has Neon DotProd 0x%x\n", has_neon_dotprod);
printf("Has Neon I8MM 0x%x\n", has_neon_i8mm); printf("Has Neon I8MM 0x%x\n", has_neon_i8mm);
printf("Has SVE 0x%x\n", has_sve); printf("Has SVE 0x%x\n", has_sve);
printf("Has SVE2 0x%x\n", has_sve2); printf("Has SVE2 0x%x\n", has_sve2);
printf("Has SME 0x%x\n", has_sme);
} }
if (has_riscv) { if (has_riscv) {
int has_rvv = TestCpuFlag(kCpuHasRVV); int has_rvv = TestCpuFlag(kCpuHasRVV);