Message ID | 20240608113717.1677043-4-remi@remlab.net |
---|---|
State | New |
Headers | show |
Series | [FFmpeg-devel,1/4] riscv: probe for Zbb extension at load time | expand |
Context | Check | Description |
---|---|---|
andriy/make_x86 | success | Make finished |
andriy/make_fate_x86 | success | Make fate finished |
On 08/06/2024 13:37, Rémi Denis-Courmont wrote: > 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) > --- > libavutil/riscv/intmath.h | 101 ++++++++++++++++++++++++++++++++++++++ > 1 file changed, 101 insertions(+) > > 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) Could you add a ./configure flag or a check for enabling non-dynamic Zbb?
Le lauantaina 8. kesäkuuta 2024, 21.01.08 EEST Lynne via ffmpeg-devel a écrit : > > #if HAVE_RV && !defined(__riscv_zbb) > > Could you add a ./configure flag or a check for enabling non-dynamic Zbb? That's defined by the compiler target architecture and/or CPU. Adding a configure flag wouldn't work since the compiler wouldn't know that it can use emit Zbb instructions for the corresponding built-ins. And before you ask, to my knowledge, GCC exposes no ad-hoc `-m` flags. This has to be included in -march or -mcpu instead, e.g.: CFLAGS="-march=rv64gc_zba_zbb"
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)