[v1.05][ARM] Properly implement SVE detection

This commit is contained in:
Dr-Noob
2024-08-01 15:38:48 +01:00
parent 5798d51d4e
commit 26af5ff83e
7 changed files with 46 additions and 80 deletions

View File

@@ -142,6 +142,20 @@ void init_cpu_info(struct cpuInfo* cpu) {
cpu->next_cpu = NULL;
}
// https://learn.arm.com/learning-paths/servers-and-cloud-computing/sve/sve_basics/#:~:text=Using%20a%20text%20editor%20of%20your%20choice%2C%20copy,svcntb%28%29%29%3B%20%7D%20This%20program%20prints%20the%20vector%20length
static inline uint32_t sve_cntb(void) {
uint32_t x0 = 0;
#ifdef __ARM_FEATURE_SVE
__asm volatile("cntb %0"
: "=r"(x0));
printf("cntb=%d\n", x0);
#endif
return x0;
}
// We assume all cpus share the same hardware
// capabilities but I'm not sure it is always
// true...
@@ -168,6 +182,15 @@ struct features* get_features_info(void) {
feat->SHA1 = hwcaps & HWCAP_SHA1;
feat->SHA2 = hwcaps & HWCAP_SHA2;
feat->NEON = hwcaps & HWCAP_ASIMD;
feat->SVE = hwcaps & HWCAP_SVE;
hwcaps = getauxval(AT_HWCAP2);
if (errno == ENOENT) {
printWarn("Unable to retrieve AT_HWCAP2 using getauxval");
}
else {
feat->SVE2 = hwcaps & HWCAP2_SVE2;
}
}
#else
else {
@@ -183,6 +206,8 @@ struct features* get_features_info(void) {
feat->CRC32 = hwcaps & HWCAP2_CRC32;
feat->SHA1 = hwcaps & HWCAP2_SHA1;
feat->SHA2 = hwcaps & HWCAP2_SHA2;
feat->SVE = false;
feat->SVE2 = false;
}
#endif // ifdef __aarch64__
#elif defined __APPLE__ || __MACH__
@@ -192,8 +217,13 @@ struct features* get_features_info(void) {
feat->SHA1 = true;
feat->SHA2 = true;
feat->NEON = true;
feat->SVE = false;
feat->SVE2 = false;
#endif // ifdef __linux__
if (feat->SVE || feat->SVE2)
feat->cntb = sve_cntb();
return feat;
}
@@ -430,7 +460,7 @@ char* get_str_topology(struct cpuInfo* cpu, struct topology* topo, bool dual_soc
char* get_str_features(struct cpuInfo* cpu) {
struct features* feat = cpu->feat;
uint32_t max_len = strlen("NEON,SHA1,SHA2,AES,CRC32,") + 1;
uint32_t max_len = strlen("NEON,SHA1,SHA2,AES,CRC32,SVE,SVE2") + 1;
uint32_t len = 0;
char* string = ecalloc(max_len, sizeof(char));
@@ -438,6 +468,14 @@ char* get_str_features(struct cpuInfo* cpu) {
strcat(string, "NEON,");
len += 5;
}
if(feat->SVE) {
strcat(string, "SVE,");
len += 4;
}
if(feat->SVE2) {
strcat(string, "SVE2,");
len += 5;
}
if(feat->SHA1) {
strcat(string, "SHA1,");
len += 5;