#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/utsname.h>
#if defined(__linux__) && defined(HAVE_SYS_AUXV_H)
# include <sys/auxv.h>
#endif
#include "zbuild.h"
#include "riscv_features.h"
#define ISA_V_HWCAP (1 << ('v' - 'a'))
#define ISA_ZBC_HWCAP (1 << 29)
void Z_INTERNAL riscv_check_features_runtime(struct riscv_cpu_features *features) {
#if defined(__linux__) && defined(HAVE_SYS_AUXV_H)
unsigned long hw_cap = getauxval(AT_HWCAP);
#else
unsigned long hw_cap = 0;
#endif
features->has_rvv = hw_cap & ISA_V_HWCAP;
features->has_zbc = hw_cap & ISA_ZBC_HWCAP;
}
void Z_INTERNAL riscv_check_features(struct riscv_cpu_features *features) {
riscv_check_features_runtime(features);
#ifdef RISCV_RVV
if (features->has_rvv) {
size_t e8m1_vec_len;
intptr_t vtype_reg_val;
__asm__ volatile(
"vsetvli %0, zero, e8, m1, ta, ma\n\t"
"csrr %1, vtype"
: "=r"(e8m1_vec_len), "=r"(vtype_reg_val));
features->has_rvv = (vtype_reg_val >= 0 && e8m1_vec_len >= 16);
}
#endif
}