riscv_features.c 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <sys/utsname.h>
  5. #if defined(__linux__) && defined(HAVE_SYS_AUXV_H)
  6. # include <sys/auxv.h>
  7. #endif
  8. #include "zbuild.h"
  9. #include "riscv_features.h"
  10. #define ISA_V_HWCAP (1 << ('v' - 'a'))
  11. int Z_INTERNAL is_kernel_version_greater_or_equal_to_6_5() {
  12. struct utsname buffer;
  13. uname(&buffer);
  14. int major, minor;
  15. if (sscanf(buffer.release, "%d.%d", &major, &minor) != 2) {
  16. // Something bad with uname()
  17. return 0;
  18. }
  19. if (major > 6 || major == 6 && minor >= 5)
  20. return 1;
  21. return 0;
  22. }
  23. void Z_INTERNAL riscv_check_features_compile_time(struct riscv_cpu_features *features) {
  24. #if defined(__riscv_v) && defined(__linux__)
  25. features->has_rvv = 1;
  26. #else
  27. features->has_rvv = 0;
  28. #endif
  29. }
  30. void Z_INTERNAL riscv_check_features_runtime(struct riscv_cpu_features *features) {
  31. #if defined(__linux__) && defined(HAVE_SYS_AUXV_H)
  32. unsigned long hw_cap = getauxval(AT_HWCAP);
  33. #else
  34. unsigned long hw_cap = 0;
  35. #endif
  36. features->has_rvv = hw_cap & ISA_V_HWCAP;
  37. }
  38. void Z_INTERNAL riscv_check_features(struct riscv_cpu_features *features) {
  39. if (is_kernel_version_greater_or_equal_to_6_5())
  40. riscv_check_features_runtime(features);
  41. else
  42. riscv_check_features_compile_time(features);
  43. }