diff --git a/include/libyuv/cpu_id.h b/include/libyuv/cpu_id.h index a352f22f6..7a2158789 100644 --- a/include/libyuv/cpu_id.h +++ b/include/libyuv/cpu_id.h @@ -29,6 +29,7 @@ static const int kCpuHasNeonDotProd = 0x10; static const int kCpuHasNeonI8MM = 0x20; static const int kCpuHasSVE = 0x40; static const int kCpuHasSVE2 = 0x80; +static const int kCpuHasSME = 0x100; // These flags are only valid on x86 processors. static const int kCpuHasX86 = 0x8; diff --git a/source/cpu_id.cc b/source/cpu_id.cc index db6a29796..a31e89cd6 100644 --- a/source/cpu_id.cc +++ b/source/cpu_id.cc @@ -186,6 +186,7 @@ LIBYUV_API SAFEBUFFERS int ArmCpuCaps(const char* cpuinfo_name) { #define YUV_AARCH64_HWCAP_SVE (1 << 22) #define YUV_AARCH64_HWCAP2_SVE2 (1 << 1) #define YUV_AARCH64_HWCAP2_I8MM (1 << 13) +#define YUV_AARCH64_HWCAP2_SME (1 << 23) // For AArch64, but public to allow testing on any CPU. LIBYUV_API SAFEBUFFERS int AArch64CpuCaps(unsigned long hwcap, @@ -207,6 +208,9 @@ LIBYUV_API SAFEBUFFERS int AArch64CpuCaps(unsigned long hwcap, features |= kCpuHasSVE; if (hwcap2 & YUV_AARCH64_HWCAP2_SVE2) { features |= kCpuHasSVE2; + if (hwcap2 & YUV_AARCH64_HWCAP2_SME) { + features |= kCpuHasSME; + } } } } diff --git a/unit_test/cpu_test.cc b/unit_test/cpu_test.cc index 928ef5fbb..829d7eb97 100644 --- a/unit_test/cpu_test.cc +++ b/unit_test/cpu_test.cc @@ -289,6 +289,10 @@ TEST_F(LibYUVBaseTest, TestLinuxAArch64) { // Values taken from a Neoverse N2 machine. EXPECT_EQ(expected, AArch64CpuCaps(0x3fffffffU, 0x2f3ffU)); + + // Check for SME feature detection. + expected |= kCpuHasSME; + EXPECT_EQ(expected, AArch64CpuCaps(0x3fffffffU, 0x82f3ffU)); } #endif diff --git a/util/cpuid.c b/util/cpuid.c index c070946f7..50ab9ffbc 100644 --- a/util/cpuid.c +++ b/util/cpuid.c @@ -99,12 +99,14 @@ int main(int argc, const char* argv[]) { int has_neon_i8mm = TestCpuFlag(kCpuHasNeonI8MM); int has_sve = TestCpuFlag(kCpuHasSVE); int has_sve2 = TestCpuFlag(kCpuHasSVE2); + int has_sme = TestCpuFlag(kCpuHasSME); printf("Has Arm 0x%x\n", has_arm); printf("Has Neon 0x%x\n", has_neon); printf("Has Neon DotProd 0x%x\n", has_neon_dotprod); printf("Has Neon I8MM 0x%x\n", has_neon_i8mm); printf("Has SVE 0x%x\n", has_sve); printf("Has SVE2 0x%x\n", has_sve2); + printf("Has SME 0x%x\n", has_sme); } if (has_riscv) { int has_rvv = TestCpuFlag(kCpuHasRVV);