diff mbox series

[FFmpeg-devel] DRAFT: riscv: add Linux riscv_hwprobe()

Message ID 20230620145933.20966-1-remi@remlab.net
State New
Headers show
Series [FFmpeg-devel] DRAFT: riscv: add Linux riscv_hwprobe() | expand

Checks

Context Check Description
yinshiyou/make_loongarch64 success Make finished
yinshiyou/make_fate_loongarch64 fail Make fate failed
andriy/make_x86 success Make finished
andriy/make_fate_x86 fail Make fate failed

Commit Message

Rémi Denis-Courmont June 20, 2023, 2:59 p.m. UTC
---
 configure             |  2 ++
 libavutil/riscv/cpu.c | 54 ++++++++++++++++++++++++++++++++-----------
 2 files changed, 43 insertions(+), 13 deletions(-)
diff mbox series

Patch

diff --git a/configure b/configure
index ed9efad985..8cad88cdd2 100755
--- a/configure
+++ b/configure
@@ -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
diff --git a/libavutil/riscv/cpu.c b/libavutil/riscv/cpu.c
index a9263dbb78..36432f9777 100644
--- a/libavutil/riscv/cpu.c
+++ b/libavutil/riscv/cpu.c
@@ -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