FFmpeg
Loading...
Searching...
No Matches
cpu.c
Go to the documentation of this file.
1/*
2 * Copyright © 2022 Rémi Denis-Courmont.
3 *
4 * This file is part of FFmpeg.
5 *
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21#ifndef _GNU_SOURCE
22# define _GNU_SOURCE
23#endif
24#include "libavutil/cpu.h"
25#include "libavutil/riscv/cpu.h"
27#include "libavutil/macros.h"
28#include "libavutil/log.h"
29#include "config.h"
30
31#if HAVE_GETAUXVAL || HAVE_ELF_AUX_INFO
32#include <sys/auxv.h>
33#define HWCAP_RV(letter) (1ul << ((letter) - 'A'))
34#endif
35#if HAVE_SYS_HWPROBE_H
36#include <sys/hwprobe.h>
37#elif HAVE_ASM_HWPROBE_H
38#include <asm/hwprobe.h>
39#include <asm/unistd.h>
40#include <sys/syscall.h>
41#include <unistd.h>
42
43static int __riscv_hwprobe(struct riscv_hwprobe *pairs, size_t pair_count,
44 size_t cpu_count, unsigned long *cpus,
45 unsigned int flags)
46{
47 return syscall(__NR_riscv_hwprobe, pairs, pair_count, cpu_count, cpus,
48 flags);
49}
50#endif
51
53{
54 int ret = 0;
55#if HAVE_SYS_HWPROBE_H || HAVE_ASM_HWPROBE_H
56 struct riscv_hwprobe pairs[] = {
57 { RISCV_HWPROBE_KEY_BASE_BEHAVIOR, 0 },
58 { RISCV_HWPROBE_KEY_IMA_EXT_0, 0 },
59 { RISCV_HWPROBE_KEY_CPUPERF_0, 0 },
60 };
61
62 if (__riscv_hwprobe(pairs, FF_ARRAY_ELEMS(pairs), 0, NULL, 0) == 0) {
63 if (pairs[0].value & RISCV_HWPROBE_BASE_BEHAVIOR_IMA)
64 ret |= AV_CPU_FLAG_RVI;
65#ifdef RISCV_HWPROBE_IMA_V
66 if (pairs[1].value & RISCV_HWPROBE_IMA_V)
69#ifdef RISCV_HWPROBE_EXT_ZVE32X
70 else if ((pairs[1].value & RISCV_HWPROBE_EXT_ZVE32X) &&
71 ff_get_rv_vlenb() >= 16) { // runtime detect assumes 128+ bits
73
74 if (pairs[1].value & RISCV_HWPROBE_EXT_ZVE32F)
76 if (pairs[1].value & RISCV_HWPROBE_EXT_ZVE64X) {
78
79 if (pairs[1].value & RISCV_HWPROBE_EXT_ZVE64D)
81 }
82 }
83#endif
84#endif
85#ifdef RISCV_HWPROBE_EXT_ZBB
86 if (pairs[1].value & RISCV_HWPROBE_EXT_ZBB)
88#if defined (RISCV_HWPROBE_EXT_ZBA) && defined (RISCV_HWPROBE_EXT_ZBS)
89 if ((pairs[1].value & RISCV_HWPROBE_EXT_ZBA) &&
90 (pairs[1].value & RISCV_HWPROBE_EXT_ZBB) &&
91 (pairs[1].value & RISCV_HWPROBE_EXT_ZBS))
92 ret |= AV_CPU_FLAG_RVB;
93#endif
94#endif
95#ifdef RISCV_HWPROBE_EXT_ZVBB
96 if (pairs[1].value & RISCV_HWPROBE_EXT_ZVBB)
98#endif
99 switch (pairs[2].value & RISCV_HWPROBE_MISALIGNED_MASK) {
100 case RISCV_HWPROBE_MISALIGNED_FAST:
102 break;
103 default:
104 ; /* do nothing */
105 }
106 }
107#elif HAVE_GETAUXVAL || HAVE_ELF_AUX_INFO
108 {
109 const unsigned long hwcap = ff_getauxval(AT_HWCAP);
110
111 if (hwcap & HWCAP_RV('I'))
112 ret |= AV_CPU_FLAG_RVI;
113 if (hwcap & HWCAP_RV('B'))
115
116 /* The V extension implies all Zve* functional subsets */
117 if (hwcap & HWCAP_RV('V'))
120 }
121#endif
122
123#ifdef __riscv_i
124 ret |= AV_CPU_FLAG_RVI;
125#endif
126
127#ifdef __riscv_zbb
129#endif
130#if defined (__riscv_b) || \
131 (defined (__riscv_zba) && defined (__riscv_zbb) && defined (__riscv_zbs))
132 ret |= AV_CPU_FLAG_RVB;
133#endif
134
135 /* If RV-V is enabled statically at compile-time, check the details. */
136#ifdef __riscv_vector
137 ret |= AV_CPU_FLAG_RVV_I32;
138#if __riscv_v_elen >= 64
139 ret |= AV_CPU_FLAG_RVV_I64;
140#endif
141#if __riscv_v_elen_fp >= 32
142 ret |= AV_CPU_FLAG_RVV_F32;
143#if __riscv_v_elen_fp >= 64
144 ret |= AV_CPU_FLAG_RVV_F64;
145#endif
146#endif
147#endif
148#ifdef __riscv_zvbb
149 ret |= AV_CPU_FLAG_RV_ZVBB;
150#endif
151
152 return ret;
153}
#define flags(name, subs,...)
Definition cbs_h264.c:74
#define NULL
Definition coverity.c:32
int ff_get_cpu_flags_riscv(void)
Definition cpu.c:52
double value
Definition eval.c:102
unsigned long ff_getauxval(unsigned long type)
Definition cpu.c:309
static atomic_int cpu_count
Definition cpu.c:57
#define AV_CPU_FLAG_RVV_I64
Vectors of 64-bit int's *‍/.
Definition cpu.h:99
#define AV_CPU_FLAG_RVI
I (full GPR bank)
Definition cpu.h:96
#define AV_CPU_FLAG_RVB
B (bit manipulations)
Definition cpu.h:104
#define AV_CPU_FLAG_RVB_BASIC
Basic bit-manipulations.
Definition cpu.h:101
#define AV_CPU_FLAG_RVV_I32
Vectors of 8/16/32-bit int's *‍/.
Definition cpu.h:97
#define AV_CPU_FLAG_RV_ZVBB
Vector basic bit-manipulations.
Definition cpu.h:102
#define AV_CPU_FLAG_RVV_F32
Vectors of float's *‍/.
Definition cpu.h:98
#define AV_CPU_FLAG_RVV_F64
Vectors of double's.
Definition cpu.h:100
#define AV_CPU_FLAG_RV_MISALIGNED
Fast misaligned accesses.
Definition cpu.h:103
#define AT_HWCAP
Definition cpu.c:50
Utility Preprocessor macros.
#define FF_ARRAY_ELEMS(a)