diff --git a/README.md b/README.md index d2b65af..957e9c3 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,14 @@ int main() // now, tell me if this cpu has avx2 int has_avx2 = ruapu_supports("avx2"); + // loop all supported features + const char* const* supported = ruapu_rua(); + while (*supported) + { + fprintf(stderr, "%s\n", *supported); + supported++; + } + return 0; } ``` diff --git a/main.c b/main.c index 31ab095..933b5af 100644 --- a/main.c +++ b/main.c @@ -113,5 +113,12 @@ int main() #endif + const char* const* supported = ruapu_rua(); + while (*supported) + { + fprintf(stderr, "%s\n", *supported); + supported++; + } + return 0; } diff --git a/ruapu.h b/ruapu.h index 91e991a..5ef56a6 100644 --- a/ruapu.h +++ b/ruapu.h @@ -15,6 +15,8 @@ void ruapu_init(); int ruapu_supports(const char* isa); +const char* const* ruapu_rua(); + #ifdef RUAPU_IMPLEMENTATION #include @@ -261,10 +263,9 @@ struct ruapu_isa_entry { const char* isa; ruapu_some_inst inst; - int capable; }; -#define RUAPU_ISAENTRY(isa) { #isa, (ruapu_some_inst)ruapu_some_##isa, 0 }, +#define RUAPU_ISAENTRY(isa) { #isa, (ruapu_some_inst)ruapu_some_##isa }, struct ruapu_isa_entry g_ruapu_isa_map[] = { @@ -370,26 +371,42 @@ RUAPU_ISAENTRY(orvdx64) #undef RUAPU_ISAENTRY +const char* g_ruapu_isa_supported[sizeof(g_ruapu_isa_map) / sizeof(g_ruapu_isa_map[0]) + 1] = { 0 }; + #if defined __openrisc__ static void ruapu_detect_openrisc_isa() { uint32_t value; uint16_t addr = U(0x0000); asm volatile ("l.mfspr %0, r0, %1" : "=r" (value) : "K" (addr)); + size_t j = 0; for (size_t i = 0; i < sizeof(g_ruapu_isa_map) / sizeof(g_ruapu_isa_map[0]); i++) { - g_ruapu_isa_map[0].capable = ((value) >> (5 + i)) & 0x1; + int capable = ((value) >> (5 + i)) & 0x1; + if (capable) + { + g_ruapu_isa_supported[j] = g_ruapu_isa_map[i].isa; + j++; + } } + g_ruapu_isa_supported[j] = 0; } #endif void ruapu_init() { #if defined _WIN32 || defined __ANDROID__ || defined __linux__ || defined __APPLE__ || defined __FreeBSD__ || defined __NetBSD__ || defined __OpenBSD__ + size_t j = 0; for (size_t i = 0; i < sizeof(g_ruapu_isa_map) / sizeof(g_ruapu_isa_map[0]); i++) { - g_ruapu_isa_map[i].capable = ruapu_detect_isa(g_ruapu_isa_map[i].inst); + int capable = ruapu_detect_isa(g_ruapu_isa_map[i].inst); + if (capable) + { + g_ruapu_isa_supported[j] = g_ruapu_isa_map[i].isa; + j++; + } } + g_ruapu_isa_supported[j] = 0; #elif defined __openrisc__ ruapu_detect_openrisc_isa(); #else @@ -402,17 +419,23 @@ void ruapu_init() int ruapu_supports(const char* isa) { - for (size_t i = 0; i < sizeof(g_ruapu_isa_map) / sizeof(g_ruapu_isa_map[0]); i++) + const char* const* isa_supported = g_ruapu_isa_supported; + while (*isa_supported) { - if (strcmp(g_ruapu_isa_map[i].isa, isa) == 0) - { - return g_ruapu_isa_map[i].capable; - } + if (strcmp(*isa_supported, isa) == 0) + return 1; + + isa_supported++; } return 0; } +const char* const* ruapu_rua() +{ + return g_ruapu_isa_supported; +} + #endif // RUAPU_IMPLEMENTATION #ifdef __cplusplus