@@ -5412,6 +5412,8 @@ elif enabled ppc; then
elif enabled riscv; then
+ check_headers sys/hwprobe.h
+
if test_cpp_condition stddef.h "__riscv_zbb"; then
enable fast_clz
fi
@@ -20,6 +20,7 @@
#include "libavutil/cpu.h"
#include "libavutil/cpu_internal.h"
+#include "libavutil/macros.h"
#include "libavutil/log.h"
#include "config.h"
@@ -27,26 +28,53 @@
#include <sys/auxv.h>
#define HWCAP_RV(letter) (1ul << ((letter) - 'A'))
#endif
+#ifdef HAVE_SYS_HWPROBE_H
+#include <sys/hwprobe.h>
+#endif
int ff_get_cpu_flags_riscv(void)
{
int ret = 0;
+#if defined (HAVE_SYS_HWPROBE_H)
+ struct riscv_hwprobe pairs[] = {
+ { RISCV_HWPROBE_KEY_BASE_BEHAVIOR, 0 },
+ { RISCV_HWPROBE_KEY_IMA_EXT_0, 0 },
+ };
+
+ if (riscv_hwprobe(pairs, FF_ARRAY_ELEMS(pairs), 0, NULL, 0) == 0) {
+ if (pairs[0].value & RISCV_HWPROBE_BASE_BEHAVIOR_IMA) {
+ ret |= AV_CPU_FLAG_RVI;
+ if (pairs[1].value & RISCV_HWPROBE_IMA_FD)
+ ret |= AV_FLAG_RVF | AV_FLAG_RVD;
+# ifdef RISCV_HWPROBE_IMA_V
+ if (pairs[1].value & RISCV_HWPROBE_IMA_V)
+ ret |= AV_CPU_FLAG_RVV_I32 | AV_CPU_FLAG_RVV_I64
+ | AV_CPU_FLAG_RVV_F32 | AV_CPU_FLAG_RVV_F64;
+# endif
+# ifdef RISCV_HWPROBE_EXT_ZBB
+ if (pairs[1].value & RISCV_HWPROBE_EXT_ZBB)
+ ret |= AV_FLAG_RVB_BASIC;
+# endif
+ } else
+#endif
#if HAVE_GETAUXVAL
- const unsigned long hwcap = getauxval(AT_HWCAP);
+ {
+ const unsigned long hwcap = getauxval(AT_HWCAP);
- if (hwcap & HWCAP_RV('I'))
- ret |= AV_CPU_FLAG_RVI;
- if (hwcap & HWCAP_RV('F'))
- ret |= AV_CPU_FLAG_RVF;
- if (hwcap & HWCAP_RV('D'))
- ret |= AV_CPU_FLAG_RVD;
- if (hwcap & HWCAP_RV('B'))
- ret |= AV_CPU_FLAG_RVB_BASIC;
+ if (hwcap & HWCAP_RV('I'))
+ ret |= AV_CPU_FLAG_RVI;
+ if (hwcap & HWCAP_RV('F'))
+ ret |= AV_CPU_FLAG_RVF;
+ if (hwcap & HWCAP_RV('D'))
+ ret |= AV_CPU_FLAG_RVD;
+ if (hwcap & HWCAP_RV('B'))
+ ret |= AV_CPU_FLAG_RVB_BASIC;
- /* The V extension implies all Zve* functional subsets */
- if (hwcap & HWCAP_RV('V'))
- ret |= AV_CPU_FLAG_RVV_I32 | AV_CPU_FLAG_RVV_I64
- | AV_CPU_FLAG_RVV_F32 | AV_CPU_FLAG_RVV_F64;
+ /* The V extension implies all Zve* functional subsets */
+ if (hwcap & HWCAP_RV('V'))
+ ret |= AV_CPU_FLAG_RVV_I32 | AV_CPU_FLAG_RVV_I64
+ | AV_CPU_FLAG_RVV_F32 | AV_CPU_FLAG_RVV_F64;
+ }
#endif
#ifdef __riscv_i