diff options
author | Rémi Denis-Courmont <remi@remlab.net> | 2024-06-08 13:27:10 +0300 |
---|---|---|
committer | Rémi Denis-Courmont <remi@remlab.net> | 2024-06-11 20:12:37 +0300 |
commit | f6d0a41c8ca67672f8e4b3c6e16cb3abd9f379bf (patch) | |
tree | e40944cff468cdf5ad70d7321ab4fd34ba0e5427 | |
parent | 98db1409102c5443491c2738aa601531f7f9b938 (diff) | |
download | ffmpeg-f6d0a41c8ca67672f8e4b3c6e16cb3abd9f379bf.tar.gz |
lavu/riscv: use Zbb CLZ/CTZ/CLZW/CTZW at run-time
Zbb static Zbb dynamic I baseline
clz 0.668032642 1.336072283 19.552376803
clzl 0.668092643 1.336181786 26.110855571
ctz 1.336208533 3.340209702 26.054869008
ctzl 1.336247784 3.340362457 26.055266290
(seconds for 1 billion iterations on a SiFive-U74 core)
-rw-r--r-- | libavutil/riscv/intmath.h | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/libavutil/riscv/intmath.h b/libavutil/riscv/intmath.h index 1f0afbc81d..3e7ab864c5 100644 --- a/libavutil/riscv/intmath.h +++ b/libavutil/riscv/intmath.h @@ -73,6 +73,107 @@ static av_always_inline av_const int av_clip_intp2_rvi(int a, int p) } #if defined (__GNUC__) || defined (__clang__) +static inline av_const int ff_ctz_rv(int x) +{ +#if HAVE_RV && !defined(__riscv_zbb) + if (!__builtin_constant_p(x) && + __builtin_expect(ff_rv_zbb_support(), true)) { + int y; + + __asm__ ( + ".option push\n" + ".option arch, +zbb\n" +#if __riscv_xlen >= 64 + "ctzw %0, %1\n" +#else + "ctz %0, %1\n" +#endif + ".option pop" : "=r" (y) : "r" (x)); + if (y > 32) + __builtin_unreachable(); + return y; + } +#endif + return __builtin_ctz(x); +} +#define ff_ctz ff_ctz_rv + +static inline av_const int ff_ctzll_rv(long long x) +{ +#if HAVE_RV && !defined(__riscv_zbb) && __riscv_xlen == 64 + if (!__builtin_constant_p(x) && + __builtin_expect(ff_rv_zbb_support(), true)) { + int y; + + __asm__ ( + ".option push\n" + ".option arch, +zbb\n" + "ctz %0, %1\n" + ".option pop" : "=r" (y) : "r" (x)); + if (y > 64) + __builtin_unreachable(); + return y; + } +#endif + return __builtin_ctzll(x); +} +#define ff_ctzll ff_ctzll_rv + +static inline av_const int ff_clz_rv(int x) +{ +#if HAVE_RV && !defined(__riscv_zbb) + if (!__builtin_constant_p(x) && + __builtin_expect(ff_rv_zbb_support(), true)) { + int y; + + __asm__ ( + ".option push\n" + ".option arch, +zbb\n" +#if __riscv_xlen >= 64 + "clzw %0, %1\n" +#else + "clz %0, %1\n" +#endif + ".option pop" : "=r" (y) : "r" (x)); + if (y > 32) + __builtin_unreachable(); + return y; + } +#endif + return __builtin_clz(x); +} +#define ff_clz ff_clz_rv + +#if __riscv_xlen == 64 +static inline av_const int ff_clzll_rv(long long x) +{ +#if HAVE_RV && !defined(__riscv_zbb) + if (!__builtin_constant_p(x) && + __builtin_expect(ff_rv_zbb_support(), true)) { + int y; + + __asm__ ( + ".option push\n" + ".option arch, +zbb\n" + "clz %0, %1\n" + ".option pop" : "=r" (y) : "r" (x)); + if (y > 64) + __builtin_unreachable(); + return y; + } +#endif + return __builtin_clzll(x); +} +#define ff_clz ff_clz_rv +#endif + +static inline av_const int ff_log2_rv(unsigned int x) +{ + return 31 - ff_clz_rv(x | 1); +} +#define ff_log2 ff_log2_rv +#define ff_log2_16bit ff_log2_rv + static inline av_const int av_popcount_rv(unsigned int x) { #if HAVE_RV && !defined(__riscv_zbb) |