|
|
|
/*
|
|
|
|
* Copyright © 2022 Rémi Denis-Courmont.
|
|
|
|
*
|
|
|
|
* This file is part of FFmpeg.
|
|
|
|
*
|
|
|
|
* FFmpeg is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* FFmpeg is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
* License along with FFmpeg; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "libavutil/cpu.h"
|
|
|
|
#include "libavutil/cpu_internal.h"
|
|
|
|
#include "libavutil/log.h"
|
|
|
|
#include "config.h"
|
|
|
|
|
|
|
|
#if HAVE_GETAUXVAL
|
|
|
|
#include <sys/auxv.h>
|
|
|
|
#define HWCAP_RV(letter) (1ul << ((letter) - 'A'))
|
|
|
|
#endif
|
|
|
|
|
|
|
|
int ff_get_cpu_flags_riscv(void)
|
|
|
|
{
|
|
|
|
int ret = 0;
|
|
|
|
#if HAVE_GETAUXVAL
|
|
|
|
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;
|
lavu/riscv: CPU flag for the Zbb extension
Unfortunately, it is common, and will remain so, that the Bit
manipulations are not enabled at compilation time. This is an official
policy for Debian ports in general (though they do not support RISC-V
officially as of yet) to stick to the minimal target baseline, which
does not include the B extension or even its Zbb subset.
For inline helpers (CPOP, REV8), compiler builtins (CTZ, CLZ) or
even plain C code (MIN, MAX, MINU, MAXU), run-time detection seems
impractical. But at least it can work for the byte-swap DSP functions.
2 years ago
|
|
|
if (hwcap & HWCAP_RV('B'))
|
|
|
|
ret |= AV_CPU_FLAG_RVB_ADDR | AV_CPU_FLAG_RVB_BASIC;
|
lavu/cpu: CPU flags for the RISC-V Vector extension
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.
2 years ago
|
|
|
|
|
|
|
/* 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
|
|
|
|
ret |= AV_CPU_FLAG_RVI;
|
|
|
|
#endif
|
|
|
|
#if defined (__riscv_flen) && (__riscv_flen >= 32)
|
|
|
|
ret |= AV_CPU_FLAG_RVF;
|
|
|
|
#if (__riscv_flen >= 64)
|
|
|
|
ret |= AV_CPU_FLAG_RVD;
|
|
|
|
#endif
|
lavu/cpu: CPU flags for the RISC-V Vector extension
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.
2 years ago
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef __riscv_zba
|
|
|
|
ret |= AV_CPU_FLAG_RVB_ADDR;
|
|
|
|
#endif
|
lavu/riscv: CPU flag for the Zbb extension
Unfortunately, it is common, and will remain so, that the Bit
manipulations are not enabled at compilation time. This is an official
policy for Debian ports in general (though they do not support RISC-V
officially as of yet) to stick to the minimal target baseline, which
does not include the B extension or even its Zbb subset.
For inline helpers (CPOP, REV8), compiler builtins (CTZ, CLZ) or
even plain C code (MIN, MAX, MINU, MAXU), run-time detection seems
impractical. But at least it can work for the byte-swap DSP functions.
2 years ago
|
|
|
#ifdef __riscv_zbb
|
|
|
|
ret |= AV_CPU_FLAG_RVB_BASIC;
|
|
|
|
#endif
|
|
|
|
|
lavu/cpu: CPU flags for the RISC-V Vector extension
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.
2 years ago
|
|
|
/* If RV-V is enabled statically at compile-time, check the details. */
|
|
|
|
#ifdef __riscv_vector
|
lavu/cpu: CPU flags for the RISC-V Vector extension
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.
2 years ago
|
|
|
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;
|
|
|
|
}
|