================ @@ -2002,6 +2003,76 @@ bool sys::getHostCPUFeatures(StringMap<bool> &Features) { return true; } +#elif defined(__linux__) && defined(__riscv) +// struct riscv_hwprobe +struct RISCVHwProbe { + int64_t Key; + uint64_t Value; +}; +bool sys::getHostCPUFeatures(StringMap<bool> &Features) { + RISCVHwProbe Query[]{{/*RISCV_HWPROBE_KEY_BASE_BEHAVIOR=*/3, 0}, + {/*RISCV_HWPROBE_KEY_IMA_EXT_0=*/4, 0}}; + int Ret = syscall(/*__NR_riscv_hwprobe=*/258, /*pairs=*/Query, + /*pair_count=*/std::size(Query), /*cpu_count=*/0, + /*cpus=*/0, /*flags=*/0); + if (Ret != 0) + return false; + + uint64_t BaseMask = Query[0].Value; + // Check whether RISCV_HWPROBE_BASE_BEHAVIOR_IMA is set. + if (BaseMask & 1) { + Features["i"] = true; + Features["m"] = true; + Features["a"] = true; + } + + uint64_t ExtMask = Query[1].Value; ---------------- preames wrote:
I think this is likely to be fine in practice. >From https://docs.kernel.org/arch/riscv/hwprobe.html, I see "If a key is >unknown to the kernel, its key field will be cleared to -1, and its value set >to 0. " If I'm reading that properly, if RISCV_HWPROBE_KEY_IMA_EXT_0 isn't a >valid key, it is the kernel's responsible for clearing all bits to zero, so >this code should work. https://github.com/llvm/llvm-project/pull/94352 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits