Commit Graph
105 Commits
Author SHA1 Message Date
Shreesh Adiga 915bac7bdc avutil/crc: add aarch64 hybrid crc32 NEON PMULL+EOR SIMD implementation
Adding crc32 specialization for aarch64 which uses both PMULL and crc32
instructions to perform 192 bytes fold in one iteration, performing
9x PMULL and 6 crc32 in one loop iteration, obtaining higher performance for
large inputs >8kB. This approach is based on zlib-ng implementation which
is also described at https://github.com/corsix/fast-crc32.

For smaller buffer size, it was observed to be slightly slower, thus only
for input size >8192 this logic is used, for smaller sizes otherwise the
4x PMULL folding method is used along with scalar crc32 instructions for
processing the remainder input size.

On a MediaTek Dimensity 9400 Android device in termux environment,
with normal checkasm seed 0 which picks random buffer size and max buffer size
of 16kB, the data observed on Cortex X925, A720 and X4:
X925 Before:
  crc_32_IEEE_LE_c:                  12762.0
  crc_32_IEEE_LE_crc:                  667.5 (19.11x)
  crc_32_IEEE_LE_pmull_eor3:           346.9 (26.30x)
X925 After:
  crc_32_IEEE_LE_c:                  12707.6
  crc_32_IEEE_LE_crc:                  665.2 (19.10x)
  crc_32_IEEE_LE_pmull_eor3:           292.8 (41.90x)

A720 Before:
  crc_32_IEEE_LE_c:                  23059.1
  crc_32_IEEE_LE_crc:                 1220.7 (18.89x)
  crc_32_IEEE_LE_pmull_eor3:          1198.9 (19.23x)
A720 After:
  crc_32_IEEE_LE_c:                  23293.3
  crc_32_IEEE_LE_crc:                 1209.1 (19.26x)
  crc_32_IEEE_LE_pmull_eor3:          1150.4 (20.24x)

X4 Before:
  crc_32_IEEE_LE_c:                  12405.5
  crc_32_IEEE_LE_crc:                  664.5 (18.67x)
  crc_32_IEEE_LE_pmull_eor3:           498.1 (24.90x)
X4 After:
  crc_32_IEEE_LE_c:                  12457.2
  crc_32_IEEE_LE_crc:                  665.5 (18.72x)
  crc_32_IEEE_LE_pmull_eor3:           468.8 (26.57x)

So it seems to work well on high performance core like X925, and results in about
20% better performance, while having tiny gains on other cores.

Testing for input size of 160 kB after modifying the checkasm crc test to
have buffer size increased to 160kB and always using full capacity instead of
a random size results in below observations:
X925 Before:
  crc_32_IEEE_LE_c:                 210177.1
  crc_32_IEEE_LE_crc:                10313.7 (20.35x)
  crc_32_IEEE_LE_pmull_eor3:          6580.9 (31.83x)
X925 After:
  crc_32_IEEE_LE_c:                 210869.3
  crc_32_IEEE_LE_crc:                10304.8 (20.36x)
  crc_32_IEEE_LE_pmull_eor3:          3098.5 (68.05x)

A720 Before:
  crc_32_IEEE_LE_c:                 387502.5
  crc_32_IEEE_LE_crc:                19196.7 (19.54x)
  crc_32_IEEE_LE_pmull_eor3:         18717.1 (20.63x)
A720 After:
  crc_32_IEEE_LE_c:                 392090.8
  crc_32_IEEE_LE_crc:                19795.1 (18.68x)
  crc_32_IEEE_LE_pmull_eor3:         14971.4 (24.97x)

X4 Before:
  crc_32_IEEE_LE_c:                 196232.0
  crc_32_IEEE_LE_crc:                10378.7 (18.68x)
  crc_32_IEEE_LE_pmull_eor3:          7742.0 (25.29x)
X4 After:
  crc_32_IEEE_LE_c:                 199632.9
  crc_32_IEEE_LE_crc:                10495.8 (18.32x)
  crc_32_IEEE_LE_pmull_eor3:          5448.9 (24.69x)

Seems to result in about 2x gains on X925, 25% on A70 and 40% on X4.
In general the performance gains depends on the CPU Core and input size,
and this optimization benefits large input size especially on high performance
cores like X925 and Apple M series.
2026-07-02 09:03:25 +00:00
Zhao Zhili 1e86a92a1c lavu/aarch64: unroll butterflies_float to 8 floats/iter
butterflies_float_neon:   before           after
  Cortex-A76 (gcc 12.4):  163.1 (3.95x)    147.0 (4.37x)
  Apple M1 (clang 16):      0.7 (0.85x)      0.6 (0.99x)

Signed-off-by: Zhao Zhili <quinkblack@foxmail.com>
2026-06-03 09:36:59 +00:00
Zhao Zhili 1f66f9041b lavu/aarch64: split FMLA chain in scalarproduct_float
Unroll to 16 floats per iteration with four independent accumulators
and reduce them once after the loop.

scalarproduct_float_neon:  before          after
  Apple M1 (clang 16):      0.9 (3.56x)    0.4 (9.18x)
  Cortex-A76 (gcc 12.4):  118.7 (4.43x)   85.3 (6.15x)

Signed-off-by: Zhao Zhili <quinkblack@foxmail.com>
2026-06-03 09:36:59 +00:00
Jeongkeun Kim de18feb0f0 avutil/aarch64: add pixelutils 32x32 SAD NEON implementation
This adds a NEON-optimized function for computing 32x32 Sum of Absolute
Differences (SAD) on AArch64, addressing a gap where x86 had SSE2/AVX2
implementations but AArch64 lacked equivalent coverage.

The implementation mirrors the existing sad8 and sad16 NEON functions,
employing a 4-row unrolled loop with UABAL and UABAL2 instructions for
efficient load-compute interleaving, and four 8x16-bit accumulators to
handle the wider 32-byte rows.

Benchmarks on AWS Graviton3 (Neoverse V1, c7g.xlarge) using checkasm:
  sad_32x32_0: C 146.4 cycles -> NEON  98.1 cycles (1.49x speedup)
  sad_32x32_1: C 141.4 cycles -> NEON  98.9 cycles (1.43x speedup)
  sad_32x32_2: C 140.7 cycles -> NEON  95.0 cycles (1.48x speedup)

Signed-off-by: Jeongkeun Kim <variety0724@gmail.com>
2026-04-19 19:27:55 +00:00
Martin Storsjö 77ff3bcb90 aarch64: Add AARCH64_VALID_JUMP_CALL_TARGET
We currently don't have any cases where this is needed, but include
it for completeness and clarity.

These macros for BTI were added in
08b4716a9e.

A later comment in this file, added in
248986a0db, referenced the macro
AARCH64_VALID_JUMP_CALL_TARGET which never was added here before.
2026-03-31 19:57:46 +00:00
Martin Storsjö 8ed8e221bd aarch64: Fix a URL typo
This was added in 248986a0db.
2026-03-31 19:57:46 +00:00
Ramiro Polla af443abe99 aarch64: Add support for indirect branch targets in the function macro
The function macro emits AARCH64_VALID_CALL_TARGET for exported symbols,
marking them as valid destinations for indirect _calls_. Functions that
are reached by indirect _branches_ (i.e. tail-call dispatch chains
where the link register is not set) require AARCH64_VALID_JUMP_TARGET
instead.

This commit adds a "jumpable" parameter to the function macro that, when
set, emits AARCH64_VALID_JUMP_TARGET instead of AARCH64_VALID_CALL_TARGET.

Sponsored-by: Sovereign Tech Fund
Signed-off-by: Ramiro Polla <ramiro.polla@gmail.com>
2026-03-31 11:48:52 +00:00
Martin Storsjö f72f692afa aarch64: Add PAC sign/validation of the link register
Whenever the link register is stored on the stack, sign it
before storing it and validate at a symmetrical point (with the
stack at the same level as when it was signed).

These macros only have an effect if built with PAC enabled (e.g.
through -mbranch-protection=standard), otherwise they don't
generate any extra instructions.

None of these cases were present when PAC support was added
in 248986a0db in 2022.

Without these changes, PAC still had an effect in the compiler
generated code and in the existing cases where we these macros were
used - but make it apply to the remaining cases of link register
on the stack.
2026-03-20 13:16:06 +02:00
Martin Storsjö 846746be4b aarch64: Add Armv9.3-A GCS (Guarded Control Stack) support
Signal that our assembly is compliant with the GCS feature, if
the GCS feature is enabled in the compiler (available since Clang
18 and GCC 15) - this is enabled by -mbranch-protection=standard
with a new enough compiler.

GCS doesn't require any specific modifications to the assembly
code, but requires that all functions return to the expected call
address (checked through a shadow stack).
2026-03-17 20:37:53 +00:00
Shreesh Adiga 5085432f8b avutil/crc: add aarch64 NEON PMULL+EOR3 SIMD implementation for av_crc
Implemented clmul algorithm for aarch64 using PMULL and EOR3 instructions.
The logic and structure is same as x86 clmul implementation with
slight rearrangement of constants as per PMULL and PMULL2 instructions.

Benchmarking in Android (Termux) on a MediaTek Dimensity 9400 SoC:

./tests/checkasm/checkasm --test=crc --bench --runs=12
benchmarking with native FFmpeg timers
nop: 0.2
checkasm: SVE 128 bits, using random seed 2502847808
checkasm: bench runs 4096 (1 << 12)
CRC:
 - crc.crc [OK]
PMULL:
 - crc.crc [OK]
checkasm: all 10 tests passed
crc_8_ATM_c:                                            26.0 ( 1.00x)
crc_8_ATM_pmull_eor3:                                    0.7 (37.17x)
crc_8_EBU_c:                                            46.4 ( 1.00x)
crc_8_EBU_pmull_eor3:                                    1.5 (31.47x)
crc_16_ANSI_c:                                          36.3 ( 1.00x)
crc_16_ANSI_pmull_eor3:                                  1.1 (31.70x)
crc_16_ANSI_LE_c:                                       90.9 ( 1.00x)
crc_16_ANSI_LE_pmull_eor3:                               2.8 (32.30x)
crc_16_CCITT_c:                                        118.0 ( 1.00x)
crc_16_CCITT_pmull_eor3:                                 3.7 (32.00x)
crc_24_IEEE_c:                                           1.6 ( 1.00x)
crc_24_IEEE_pmull_eor3:                                  0.1 (12.19x)
crc_32_IEEE_c:                                          45.2 ( 1.00x)
crc_32_IEEE_pmull_eor3:                                  1.4 (31.39x)
crc_32_IEEE_LE_c:                                       49.1 ( 1.00x)
crc_32_IEEE_LE_crc:                                      2.5 (19.51x)
crc_32_IEEE_LE_pmull_eor3:                               1.5 (32.84x)
crc_custom_polynomial_c:                                45.3 ( 1.00x)
crc_custom_polynomial_pmull_eor3:                        1.3 (35.16x)
2026-03-11 14:03:36 +00:00
Shreesh Adiga b19bd0de6c avutil/cpu: add aarch64 CPU feature flag for PMULL and EOR3 2026-03-11 14:03:36 +00:00
Andreas Rheinhardt 022c42649c avutil/aarch64: Add neon optimizations for pixelutils
Adapted from the corresponding me_cmp code.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2026-03-09 10:17:26 +01:00
Georgii Zagoruiko 0edd75e150 aarch64/asm.S: to support SME added macro to save/restore registers d8-d16 2026-03-04 23:52:58 +02:00
Georgii Zagoruiko 905348df9d configure: add detection of SME-I16I64 extension 2026-03-04 23:52:57 +02:00
Georgii Zagoruiko 70691bbb27 configure: add detection of assembler support for SME2 2026-03-04 23:52:36 +02:00
Martin Storsjö a0d23706e8 aarch64: Switch to a more correct Windows flag for detecting I8MM
Newer revisions of WinSDK 10.0.26100.0 have exposed more flags for
IsProcessorFeaturePresent; now there is a separate one for
detecting specifically I8MM and not just SVE-I8MM. Switch to using
this flag instead.
2026-03-04 21:46:18 +00:00
Shreesh Adiga 22d484f498 avutil/cpu: add static CPU feature flag for AArch64 CRC32 2026-03-03 21:38:00 +00:00
Brad Smith c352a9ab02 avutil/cpu: add CPU feature detection for AArch64 CRC32 on OpenBSD
Signed-off-by: Brad Smith <brad@comstyle.com>
2026-02-06 14:24:01 -05:00
Zhao ZhiliandAndreas Rheinhardt 66f7e9db71 avutil/crc: use arm64 crc32 instruction
On rpi5 A76
crc_32_ieee_le_c:                       23146.3 ( 1.00x)
crc_32_ieee_le_crc:                      1060.1 (21.83x)

On RK3566 A55
crc_32_ieee_le_c:                       28773.8 ( 1.00x)
crc_32_ieee_le_crc:                      2602.4 (11.06x)

Co-authored-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2026-01-04 15:49:30 +01:00
Zhao ZhiliandMartin Storsjö 0645c48453 avutil/cpu: add CPU feature flag for arm crc32
Co-Authored-by: Martin Storsjö <martin@martin.st>
2026-01-04 15:49:30 +01:00
Martin Storsjö 3dcbcce80c configure: Check for the AArch64 CRC extension
Name the feature "arm_crc" rather than plain "crc", to make it
clear that this is about a CPU feature extension, not CRC
implementations in general.

This requires dealing with the extension slightly differently
than other extensions, as the name of the feature and the
".arch_extension" extension name differ.

Naming it with an "arm" prefix rather than "aarch64", as the
CPU extension also is available in 32 bit ARM form, even though
we don't intend to use it there.
2026-01-04 15:49:30 +01:00
James Almer 44862a9d68 avutil/aarch64/cpu: fix check for SME on Linux
SME is a AT_HWCAP2 entry, not AT_HWCAP.

Signed-off-by: James Almer <jamrial@gmail.com>
2025-12-10 21:51:11 -03:00
Georgii Zagoruiko cdb14bc74d configure: add detection of assembler support for SME
All changes are made during development/testing of SVE/SME for ffmpeg (vvc). Tested on Apple M4
2025-12-09 21:38:38 +00:00
Ramiro Polla b6803bf104 aarch64: increase default alignment for functions and constants
Use 16-byte alignment (align=4) instead of 4-byte (align=2) in the function and
const macros. This improves instruction fetch and NEON load performance on
modern AArch64 CPUs.
2025-05-19 13:20:51 +02:00
Krzysztof Pyrkosz via ffmpeg-devel 9993a64d7b avutil/aarch64/tx_float_neon.S: clean up FFT4_X2 2025-02-28 13:42:54 +01:00
Martin Storsjö b1ee2af843 aarch64: Print the SVE vector length in libavutil/tests/cpu.c
This makes this aspect more visible in test logs.

Signed-off-by: Martin Storsjö <martin@martin.st>
2024-09-27 00:06:30 +03:00
Martin Storsjö e6eabb7ce7 aarch64: Add CPU feature flags for SVE and SVE2
Add code for detecting the feature on Linux and Windows.

Signed-off-by: Martin Storsjö <martin@martin.st>
2024-09-27 00:04:30 +03:00
Martin Storsjö e6e56fd7a7 configure: Add detection of assembler support for SVE/SVE2
Signed-off-by: Martin Storsjö <martin@martin.st>
2024-09-27 00:03:04 +03:00
Martin Storsjö 067abbfe9d aarch64: Detect I8MM on Windows via SVE-I8MM
There's no direct processor feature constant for I8MM alone, but
there is a flag for SVE-I8MM (added in WinSDK 10.0.26100 and
recent versions of mingw-w64). If SVE-I8MM is available, we can
assume that I8MM is available.

While HW supporting these features isn't yet commonly running
Windows, this at least allows detecting and running the I8MM codepaths
in Windows builds in Wine (possibly running in QEMU).

Signed-off-by: Martin Storsjö <martin@martin.st>
2024-09-27 00:02:48 +03:00
Brad Smith a3f79fd22a aarch64: Implement support for elf_aux_info(3) on FreeBSD and OpenBSD
FreeBSD 12.0+, OpenBSD -current and what will be OpenBSD 7.6 support
elf_aux_info(3).

Signed-off-by: Brad Smith <brad@comstyle.com>
2024-09-09 07:17:49 -04:00
Brad Smith fe4b9ef69f avutil/cpu_internal: Provide ff_getauxval() wrapper for getauxvaul()
Initially used for getauxval() but will be used to add support for
other API, such as elf_aux_info().

Signed-off-by: Brad Smith <brad@comstyle.com>
2024-09-09 06:20:11 -04:00
Ramiro Polla abb4e13a0a avutil/aarch64: add AV_COPY128 and AV_ZERO128 macros 2024-08-26 10:26:59 +02:00
Brad Smith 41190da9e1 aarch64: Add OpenBSD runtime detection of dotprod and i8mm using sysctl
Signed-off-by: Brad Smith <brad@comstyle.com>
2024-06-26 02:06:53 -04:00
Martin Storsjö ab8f7030bc aarch64: Use cntvct_el0 as timer register on Android and macOS
The default timer register pmccntr_el0 usually requires enabling
access with e.g. a kernel module (while it is accessible by
default on Windows). On Linux, the default for checkasm benchmarks
is to use perf (if suitable headers are available) though.

On macOS, using cntvct_el0 gives measurements with the same
magnitude as mach_absolute_time (which is used currently), but
possibly with a little less overhead/noise.

Signed-off-by: Martin Storsjö <martin@martin.st>
2024-06-17 14:00:34 +03:00
Rémi Denis-Courmont c5f69719bc lavu/bswap: remove some inline assembler
C code or compiler built-ins are preferable over inline assembler for
byte-swaps as it allows for better optimisations (e.g. instruction
scheduling) which would otherwise be impossible.

As with f64c2e710f for x86 and Arm,
this removes the inline assembler on GCC (and Clang) since we now
require recent enough compiler versions. This indeed seems to work on
AArch64, SuperH and, if Zbb is enabled, RISC-V. (AVR32 was not tested
since it has no known working compilers at this time.)
2024-06-13 21:16:16 +03:00
Zhao Zhili 6a18c0bc87 avutil/aarch64: Skip define AV_READ_TIME for apple
It will fallback to mach_absolute_time inside libavutil/timer.h

Reviewed-by: Martin Storsjö <martin@martin.st>
Signed-off-by: Zhao Zhili <zhilizhao@tencent.com>
2024-06-11 01:10:42 +08:00
Martin Storsjö 8339a45400 aarch64: Factorize code for CPU feature detection on Apple platforms
Signed-off-by: Martin Storsjö <martin@martin.st>
2024-04-10 10:39:08 +03:00
Martin Storsjö e30369bc1c aarch64: Use regular hwcaps flags instead of HWCAP_CPUID for CPU feature detection on Linux
This makes the code much simpler (especially for adding support
for other instruction set extensions), avoids needing inline
assembly for this feature, and generally is more of the canonical
way to do this.

The CPU feature detection was added in
493fcde50a, using HWCAP_CPUID.

The argument for using that, was that HWCAP_CPUID was added much
earlier in the kernel (in Linux v4.11), while the HWCAP flags for
individual features always come later. This allows detecting support
for new CPU extensions before the kernel exposes information about
them via hwcap flags.

However in practice, there's probably quite little advantage in this.
E.g. HWCAP2_I8MM was added in Linux v5.10 - long after HWCAP_CPUID,
but there's probably very little practical cases where one would
run a kernel older than that on a CPU that supports those instructions.

Additionally, we provide our own definitions of the flag values to
check (as they are fixed constants anyway), with names not conflicting
with the ones from system headers. This reduces the number of ifdefs
needed, and allows detecting those features even if building with
userland headers that are lacking the definitions of those flags.

Also, slightly older versions of QEMU, e.g. 6.2 in Ubuntu 22.04,
do expose support for these features via HWCAP flags, but the
emulated cpuid registers are missing the bits for exposing e.g. I8MM.
(This issue is fixed in later versions of QEMU though.)

Signed-off-by: Martin Storsjö <martin@martin.st>
2024-03-04 10:13:31 +02:00
Reimar Döffinger 0ea184fc39 libavutil/aarch64/cpu.c: HWCAPS requires inline asm support.
Fixes compilation with tcc, which does not have aarch64
inline asm support.
2023-11-02 21:03:43 +01:00
Martin Storsjö f05948ada4 aarch64: Simplify the linux runtime cpu detection code
Skip doing the whole getauxval(AT_HWCAP) if HWCAP_CPUID isn't
defined.

Signed-off-by: Martin Storsjö <martin@martin.st>
2023-10-31 12:23:27 +02:00
Martin Storsjö a4877f1ec1 aarch64: Only enable extensions in the intended files/regions
This eases actual development of the assembly functions, by only
allowing extension instructions within the sections that explicitly
enable them, instead of having all extensions enabled everywhere.

Signed-off-by: Martin Storsjö <martin@martin.st>
2023-10-24 14:46:20 +03:00
Martin Storsjö 0679e85331 aarch64: Stop using asm/hwcap.h for the HWCAP_* detection
Including sys/auxv.h should be enough (it pulls in bits/hwcap.h,
which provides the same defines).

Signed-off-by: Martin Storsjö <martin@martin.st>
2023-10-24 14:46:14 +03:00
Martin Storsjö cada4597ca aarch64: Manually tweak vertical alignment/indentation in tx_float_neon.S
Favour left aligned columns over right aligned columns.

In principle either style should be ok, but some of the cases
easily lead to incorrect indentation in the surrounding code (see
a couple of cases fixed up in the preceding patch), and show up in
automatic indentation correction attempts.

Signed-off-by: Martin Storsjö <martin@martin.st>
2023-10-21 23:25:39 +03:00
Martin Storsjö 7f905f3672 aarch64: Make the indentation more consistent
Some functions have slightly different indentation styles; try
to match the surrounding code.

libavcodec/aarch64/vc1dsp_neon.S is skipped here, as it intentionally
uses a layered indentation style to visually show how different
unrolled/interleaved phases fit together.

Signed-off-by: Martin Storsjö <martin@martin.st>
2023-10-21 23:25:29 +03:00
Martin Storsjö 184103b310 aarch64: Consistently use lowercase for vector element specifiers
Signed-off-by: Martin Storsjö <martin@martin.st>
2023-10-21 23:25:18 +03:00
Rémi Denis-Courmont f032234953 aarch64: remove VFP feature check
This is not actually used for anything. The configure check causes the
CPU feature flag to be set, but nothing consumes it at all.

While AArch64 does have VFP, it is only used for the scalar C code.
Conversely, it is still possible to disable VFP, by changing the
C compiler flags as before (though that only makes sense for an
hypothetical non-standard Armv8 platform without VFP).

Note that this retains the "vfp" option flag, for backward
compatibility and on the very remote but theoretically possible chance
that FFmpeg actually makes use of it in the future.

AV_CPU_FLAG_VFP is retained as it is actually used by AArch32.
2023-07-15 22:56:30 +03:00
Martin Storsjö c76643021e aarch64: Add Windows runtime detection of the dotprod instructions
For Windows, there's no publicly defined constant for checking for
the i8mm extension yet.

Signed-off-by: Martin Storsjö <martin@martin.st>
2023-06-06 12:50:15 +03:00
Martin Storsjö 9b0052200a aarch64: Add Apple runtime detection of dotprod and i8mm using sysctl
For now, there's not much value in this since Clang don't support
enabling the dotprod or i8mm features with either .arch_extension
or .arch (it has to be enabled by the base arch flags passed to
the compiler). But it may be supported in the future.

Signed-off-by: Martin Storsjö <martin@martin.st>
2023-06-06 12:41:20 +03:00
Martin Storsjö 493fcde50a aarch64: Add Linux runtime cpu feature detection using HWCAP_CPUID
Based partially on code by Janne Grunau.

Signed-off-by: Martin Storsjö <martin@martin.st>
2023-06-06 12:40:57 +03:00
Martin Storsjö 397cb623c8 aarch64: Add cpu flags for the dotprod and i8mm extensions
Set these available if they are available unconditionally for
the compiler.

Signed-off-by: Martin Storsjö <martin@martin.st>
2023-06-06 12:40:42 +03:00