FFmpeg
Loading...
Searching...
No Matches
intmath.h
Go to the documentation of this file.
1/*
2 * Copyright © 2022-2024 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 AVUTIL_RISCV_INTMATH_H
22#define AVUTIL_RISCV_INTMATH_H
23
24#include <stdint.h>
25#include <math.h>
26
27#include "config.h"
29#include "libavutil/riscv/cpu.h"
30
31/*
32 * The compiler is forced to sign-extend the result anyhow, so it is faster to
33 * compute it explicitly and use it.
34 */
35#define av_clip_int8 av_clip_int8_rvi
37{
38 union { uint8_t u; int8_t s; } u = { .u = a };
39
40 if (a != u.s)
41 a = ((a >> 31) ^ 0x7F);
42 return a;
43}
44
45#define av_clip_int16 av_clip_int16_rvi
47{
48 union { uint16_t u; int16_t s; } u = { .u = a };
49
50 if (a != u.s)
51 a = ((a >> 31) ^ 0x7FFF);
52 return a;
53}
54
55#define av_clipl_int32 av_clipl_int32_rvi
57{
58 union { uint32_t u; int32_t s; } u = { .u = a };
59
60 if (a != u.s)
61 a = ((a >> 63) ^ 0x7FFFFFFF);
62 return a;
63}
64
65#define av_clip_intp2 av_clip_intp2_rvi
67{
68 const int shift = 31 - p;
69 int b = ((int)(((unsigned)a) << shift)) >> shift;
70
71 if (a != b)
72 b = (a >> 31) ^ ((1 << p) - 1);
73 return b;
74}
75
76#if defined (__riscv_f) || defined (__riscv_zfinx)
77#define av_clipf av_clipf_rvf
78static av_always_inline av_const float av_clipf_rvf(float a, float min,
79 float max)
80{
81 return fminf(fmaxf(a, min), max);
82}
83#endif
84
85#if defined (__riscv_d) || defined (__riscv_zdinx)
86#define av_clipd av_clipd_rvd
87static av_always_inline av_const double av_clipd_rvd(double a, double min,
88 double max)
89{
90 return fmin(fmax(a, min), max);
91}
92#endif
93
94#if defined (__GNUC__) || defined (__clang__)
95static inline av_const int ff_ctz_rv(int x)
96{
97#if HAVE_RV && !defined(__riscv_zbb)
98 if (!__builtin_constant_p(x) &&
99 __builtin_expect(ff_rv_zbb_support(), true)) {
100 int y;
101
102 __asm__ (
103 ".option push\n"
104 ".option arch, +zbb\n"
105#if __riscv_xlen >= 64
106 "ctzw %0, %1\n"
107#else
108 "ctz %0, %1\n"
109#endif
110 ".option pop" : "=r" (y) : "r" (x));
111 if (y > 32)
112 __builtin_unreachable();
113 return y;
114 }
115#endif
116 return __builtin_ctz(x);
117}
118#define ff_ctz ff_ctz_rv
119
120static inline av_const int ff_ctzll_rv(long long x)
121{
122#if HAVE_RV && !defined(__riscv_zbb) && __riscv_xlen == 64
123 if (!__builtin_constant_p(x) &&
124 __builtin_expect(ff_rv_zbb_support(), true)) {
125 int y;
126
127 __asm__ (
128 ".option push\n"
129 ".option arch, +zbb\n"
130 "ctz %0, %1\n"
131 ".option pop" : "=r" (y) : "r" (x));
132 if (y > 64)
133 __builtin_unreachable();
134 return y;
135 }
136#endif
137 return __builtin_ctzll(x);
138}
139#define ff_ctzll ff_ctzll_rv
140
141static inline av_const int ff_clz_rv(int x)
142{
143#if HAVE_RV && !defined(__riscv_zbb)
144 if (!__builtin_constant_p(x) &&
145 __builtin_expect(ff_rv_zbb_support(), true)) {
146 int y;
147
148 __asm__ (
149 ".option push\n"
150 ".option arch, +zbb\n"
151#if __riscv_xlen >= 64
152 "clzw %0, %1\n"
153#else
154 "clz %0, %1\n"
155#endif
156 ".option pop" : "=r" (y) : "r" (x));
157 if (y > 32)
158 __builtin_unreachable();
159 return y;
160 }
161#endif
162 return __builtin_clz(x);
163}
164#define ff_clz ff_clz_rv
165
166#if __riscv_xlen == 64
167static inline av_const int ff_clzll_rv(long long x)
168{
169#if HAVE_RV && !defined(__riscv_zbb)
170 if (!__builtin_constant_p(x) &&
171 __builtin_expect(ff_rv_zbb_support(), true)) {
172 int y;
173
174 __asm__ (
175 ".option push\n"
176 ".option arch, +zbb\n"
177 "clz %0, %1\n"
178 ".option pop" : "=r" (y) : "r" (x));
179 if (y > 64)
180 __builtin_unreachable();
181 return y;
182 }
183#endif
184 return __builtin_clzll(x);
185}
186#define ff_clz ff_clz_rv
187#endif
188
189static inline av_const int ff_log2_rv(unsigned int x)
190{
191 return 31 - ff_clz_rv(x | 1);
192}
193#define ff_log2 ff_log2_rv
194#define ff_log2_16bit ff_log2_rv
195
196static inline av_const int av_popcount_rv(unsigned int x)
197{
198#if HAVE_RV && !defined(__riscv_zbb)
199 if (!__builtin_constant_p(x) &&
200 __builtin_expect(ff_rv_zbb_support(), true)) {
201 int y;
202
203 __asm__ (
204 ".option push\n"
205 ".option arch, +zbb\n"
206#if __riscv_xlen >= 64
207 "cpopw %0, %1\n"
208#else
209 "cpop %0, %1\n"
210#endif
211 ".option pop" : "=r" (y) : "r" (x));
212 if (y > 32)
213 __builtin_unreachable();
214 return y;
215 }
216#endif
217 return __builtin_popcount(x);
218}
219#define av_popcount av_popcount_rv
220
221static inline av_const int av_popcount64_rv(uint64_t x)
222{
223#if HAVE_RV && !defined(__riscv_zbb) && __riscv_xlen >= 64
224 if (!__builtin_constant_p(x) &&
225 __builtin_expect(ff_rv_zbb_support(), true)) {
226 int y;
227
228 __asm__ (
229 ".option push\n"
230 ".option arch, +zbb\n"
231 "cpop %0, %1\n"
232 ".option pop" : "=r" (y) : "r" (x));
233 if (y > 64)
234 __builtin_unreachable();
235 return y;
236 }
237#endif
238 return __builtin_popcountl(x);
239}
240#define av_popcount64 av_popcount64_rv
241
242static inline av_const int av_parity_rv(unsigned int x)
243{
244#if HAVE_RV && !defined(__riscv_zbb)
245 if (!__builtin_constant_p(x) &&
246 __builtin_expect(ff_rv_zbb_support(), true)) {
247 int y;
248
249 __asm__ (
250 ".option push\n"
251 ".option arch, +zbb\n"
252#if __riscv_xlen >= 64
253 "cpopw %0, %1\n"
254#else
255 "cpop %0, %1\n"
256#endif
257 ".option pop" : "=r" (y) : "r" (x));
258 return y & 1;
259 }
260#endif
261 return __builtin_parity(x);
262}
263#define av_parity av_parity_rv
264#endif
265
266#endif /* AVUTIL_RISCV_INTMATH_H */
__asm__(".macro parse_r var r\n\t" "\\var = -1\n\t" _IFC_REG(0) _IFC_REG(1) _IFC_REG(2) _IFC_REG(3) _IFC_REG(4) _IFC_REG(5) _IFC_REG(6) _IFC_REG(7) _IFC_REG(8) _IFC_REG(9) _IFC_REG(10) _IFC_REG(11) _IFC_REG(12) _IFC_REG(13) _IFC_REG(14) _IFC_REG(15) _IFC_REG(16) _IFC_REG(17) _IFC_REG(18) _IFC_REG(19) _IFC_REG(20) _IFC_REG(21) _IFC_REG(22) _IFC_REG(23) _IFC_REG(24) _IFC_REG(25) _IFC_REG(26) _IFC_REG(27) _IFC_REG(28) _IFC_REG(29) _IFC_REG(30) _IFC_REG(31) ".iflt \\var\n\t" ".error \"Unable to parse register name \\r\"\n\t" ".endif\n\t" ".endm")
int32_t
#define s(width, name)
Definition cbs_vp9.c:198
long long int64_t
Definition coverity.c:34
#define min(a, b)
#define max(a, b)
double fmin(double, double)
float fminf(float, float)
double fmax(double, double)
float fmaxf(float, float)
int a
#define b
Definition input.c:43
static int shift(int a, int b)
Definition bonk.c:261
#define u(width, name, range_min, range_max)
Definition cbs_apv.c:68
Macro definitions for various function/variable attributes.
#define av_always_inline
Definition attributes.h:72
#define av_const
Definition attributes.h:111
static av_const bool ff_rv_zbb_support(void)
Definition cpu.h:34
static av_const int ff_ctzll_rv(long long x)
Definition intmath.h:120
static av_always_inline av_const int16_t av_clip_int16_rvi(int a)
Definition intmath.h:46
static av_const int av_popcount64_rv(uint64_t x)
Definition intmath.h:221
static av_const int ff_clz_rv(int x)
Definition intmath.h:141
static av_always_inline av_const int8_t av_clip_int8_rvi(int a)
Definition intmath.h:36
static av_always_inline av_const int av_clip_intp2_rvi(int a, int p)
Definition intmath.h:66
static av_const int ff_log2_rv(unsigned int x)
Definition intmath.h:189
static av_always_inline av_const int32_t av_clipl_int32_rvi(int64_t a)
Definition intmath.h:56
static av_const int av_parity_rv(unsigned int x)
Definition intmath.h:242
static av_const int av_popcount_rv(unsigned int x)
Definition intmath.h:196
static av_const int ff_ctz_rv(int x)
Definition intmath.h:95