diff mbox series

[FFmpeg-devel,05/31] lavu/cpu: CPU flags for the RISC-V Vector extension

Message ID 20220926145251.56351-5-remi@remlab.net
State Accepted
Commit 0c0a3deb1826638915775daa7cefb891a300060b
Headers show
Series initial RISC-V CPU extensions | expand

Checks

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

Commit Message

Rémi Denis-Courmont Sept. 26, 2022, 2:52 p.m. UTC
From: Rémi Denis-Courmont <remi@remlab.net>

RVV defines a total of 12 different extensions, including:

- 5 different instruction subsets:
  - Zve32x: 8-, 16- and 32-bit integers,
  - Zve32f: Zve32x plus single precision floats,
  - Zve64x: Zve32x plus 64-bit integers,
  - Zve64f: Zve32f plus Zve64x,
  - Zve64d: Zve64f plus double precision floats.

- 6 different vector lengths:
  - Zvl32b (embedded only),
  - Zvl64b (embedded only),
  - Zvl128b,
  - Zvl256b,
  - Zvl512b,
  - Zvl1024b,

- and the V extension proper: equivalent to Zve64f and Zvl128b.

In total, there are 6 different possible sets of supported instructions
(including the empty set), but for convenience we allocate one bit for
each type sets: up-to-32-bit ints (RVV_I32), floats (RVV_F32),
64-bit ints (RVV_I64) and doubles (RVV_F64).

Whence the vector size is needed, it can be retrieved by reading the
unprivileged read-only vlenb CSR. This should probably be a separate
helper macro if needed at a later point.
---
 libavutil/cpu.c           |  4 ++++
 libavutil/cpu.h           |  4 ++++
 libavutil/riscv/cpu.c     | 19 +++++++++++++++++++
 tests/checkasm/checkasm.c |  4 ++++
 4 files changed, 31 insertions(+)
diff mbox series

Patch

diff --git a/libavutil/cpu.c b/libavutil/cpu.c
index 8b6eef9873..5818fd9c1c 100644
--- a/libavutil/cpu.c
+++ b/libavutil/cpu.c
@@ -184,6 +184,10 @@  int av_parse_cpu_caps(unsigned *flags, const char *s)
         { "rvi",      NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_RVI      },    .unit = "flags" },
         { "rvf",      NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_RVF      },    .unit = "flags" },
         { "rvd",      NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_RVD      },    .unit = "flags" },
+        { "rvv-i32",  NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_RVV_I32 },     .unit = "flags" },
+        { "rvv-f32",  NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_RVV_F32 },     .unit = "flags" },
+        { "rvv-i64",  NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_RVV_I64 },     .unit = "flags" },
+        { "rvv",      NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_RVV_F64 },     .unit = "flags" },
 #endif
         { NULL },
     };
diff --git a/libavutil/cpu.h b/libavutil/cpu.h
index 9aae2ccc7a..18f42af015 100644
--- a/libavutil/cpu.h
+++ b/libavutil/cpu.h
@@ -82,6 +82,10 @@ 
 #define AV_CPU_FLAG_RVI          (1 << 0) ///< I (full GPR bank)
 #define AV_CPU_FLAG_RVF          (1 << 1) ///< F (single precision FP)
 #define AV_CPU_FLAG_RVD          (1 << 2) ///< D (double precision FP)
+#define AV_CPU_FLAG_RVV_I32      (1 << 3) ///< Vectors of 8/16/32-bit int's */
+#define AV_CPU_FLAG_RVV_F32      (1 << 4) ///< Vectors of float's */
+#define AV_CPU_FLAG_RVV_I64      (1 << 5) ///< Vectors of 64-bit int's */
+#define AV_CPU_FLAG_RVV_F64      (1 << 6) ///< Vectors of double's
 
 /**
  * Return the flags which specify extensions supported by the CPU.
diff --git a/libavutil/riscv/cpu.c b/libavutil/riscv/cpu.c
index 6803f035e5..e234201395 100644
--- a/libavutil/riscv/cpu.c
+++ b/libavutil/riscv/cpu.c
@@ -40,6 +40,11 @@  int ff_get_cpu_flags_riscv(void)
         ret |= AV_CPU_FLAG_RVF;
     if (hwcap & HWCAP_RV('D'))
         ret |= AV_CPU_FLAG_RVD;
+
+    /* 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
@@ -50,6 +55,20 @@  int ff_get_cpu_flags_riscv(void)
 #if (__riscv_flen >= 64)
     ret |= AV_CPU_FLAG_RVD;
 #endif
+#endif
+
+    /* If RV-V is enabled statically at compile-time, check the details. */
+#ifdef __riscv_vectors
+    ret |= AV_CPU_FLAG_RVV_I32;
+#if __riscv_v_elen >= 64
+    ret |= AV_CPU_FLAG_RVV_I64;
+#endif
+#if __riscv_v_elen_fp >= 32
+    ret |= AV_CPU_FLAG_RVV_F32;
+#if __riscv_v_elen_fp >= 64
+    ret |= AV_CPU_FLAG_RVV_F64;
+#endif
+#endif
 #endif
 
     return ret;
diff --git a/tests/checkasm/checkasm.c b/tests/checkasm/checkasm.c
index e1135a84ac..90dd7e4634 100644
--- a/tests/checkasm/checkasm.c
+++ b/tests/checkasm/checkasm.c
@@ -236,6 +236,10 @@  static const struct {
     { "RVI",      "rvi",      AV_CPU_FLAG_RVI },
     { "RVF",      "rvf",      AV_CPU_FLAG_RVF },
     { "RVD",      "rvd",      AV_CPU_FLAG_RVD },
+    { "RVVi32",   "rvv_i32",  AV_CPU_FLAG_RVV_I32 },
+    { "RVVf32",   "rvv_f32",  AV_CPU_FLAG_RVV_F32 },
+    { "RVVi64",   "rvv_i64",  AV_CPU_FLAG_RVV_I64 },
+    { "RVVf64",   "rvv_f64",  AV_CPU_FLAG_RVV_F64 },
 #elif ARCH_MIPS
     { "MMI",      "mmi",      AV_CPU_FLAG_MMI },
     { "MSA",      "msa",      AV_CPU_FLAG_MSA },