Commit Graph

394 Commits

Author SHA1 Message Date
Jonathan Wright
e4ec23d7ae Neon: Use byte-swap builtins instead of inline asm
Define compiler-independent byte-swap macros and use them instead of
executing 'rev' via inline assembly code with GCC-compatible compilers
or a slow shift-store sequence with Visual C++.

* This produces identical assembly code with:

  - 64-bit GCC 8.4.0 (Linux)
  - 64-bit GCC 9.3.0 (Linux)
  - 64-bit Clang 10.0.0 (Linux)
  - 64-bit Clang 10.0.0 (MinGW)
  - 64-bit Clang 12.0.0 (Xcode 12.2, macOS)
  - 64-bit Clang 12.0.0 (Xcode 12.2, iOS)

* This produces different assembly code with:

  - 64-bit GCC 4.9.1 (Linux)
  - 32-bit GCC 4.8.2 (Linux)
  - 32-bit GCC 8.4.0 (Linux)
  - 32-bit GCC 9.3.0 (Linux)
    Since the intrinsics implementation of Huffman encoding is not used
    by default with these compilers, this is not a concern.

  - 32-bit Clang 10.0.0 (Linux)
    Verified performance neutrality

Closes #507
2021-03-26 14:09:10 -05:00
DRC
e795afc330 SSE2: Fix prog Huff enc err if Sl%32==0 && Al!=0
(regression introduced by 16bd984557)

This implements the same fix for
jsimd_encode_mcu_AC_refine_prepare_sse2() that
a81a8c137b implemented for
jsimd_encode_mcu_AC_first_prepare_sse2().

Based on:
1a59587397
eb176a91d8

Fixes #509
Closes #510
2021-03-25 22:46:14 -05:00
Adrian Bunk
2c01200c5d Build: Fix incorrect regexes w/ if(...MATCHES...)
"arm*" as a regex means 'ar' followed by zero or more 'm' characters,
which matches 'parisc' and 'sparc64' as well.
2021-03-15 12:56:53 -05:00
Richard Townsend
74e6ea45e3 Neon: Fix Huffman enc. error w/Visual Studio+Clang
The GNU builtin function __builtin_clzl() accepts an unsigned long
argument, which is 8 bytes wide on LP64 systems (most Un*x systems,
including Mac) but 4 bytes wide on LLP64 systems (Windows.)  This caused
the Neon intrinsics implementation of Huffman encoding to produce
mathematically incorrect results when compiled using Visual Studio with
Clang.

This commit changes all invocations of __builtin_clzl() in the Neon SIMD
extensions to __builtin_clzll(), which accepts an unsigned long long
argument that is guaranteed to be 8 bytes wide on all systems.

Fixes #480
Closes #490
2021-01-11 22:29:11 -06:00
Jonathan Wright
eb14189caa Fix Neon SIMD build issues with Visual Studio
- Use the _M_ARM and _M_ARM64 macros provided by Visual Studio for
  compile-time detection of Arm builds, since __arm__ and __aarch64__
  are only present in GNU-compatible compilers.
- Neon/intrinsics: Use the _CountLeadingZeros() and
  _CountLeadingZeros64() intrinsics provided by Visual Studio, since
  __builtin_clz() and __builtin_clzl() are only present in
  GNU-compatible compilers.
- Neon/intrinsics: Since Visual Studio does not support static vector
  initialization, replace static initialization of Neon vectors with the
  appropriate intrinsics.  Compared to the static initialization
  approach, this produces identical assembly code with both GCC and
  Clang.
- Neon/intrinsics: Since Visual Studio does not support inline assembly
  code, provide alternative code paths for Visual Studio whenever inline
  assembly is used.
- Build: Set FLOATTEST appropriately for AArch64 Visual Studio builds
  (Visual Studio does not emit fused multiply-add [FMA] instructions by
  default for such builds.)
- Neon/intrinsics: Move temporary buffer allocation outside of nested
  loops.  Since Visual Studio configures Arm builds with a relatively
  small amount of stack memory, attempting to allocate those buffers
  within the inner loops caused a stack overflow.

Closes #461
Closes #475
2020-11-24 21:13:16 -06:00
DRC
33859880e9 Neon: Auto-detect compiler intrinsics completeness
This allows the Neon intrinsics code to be built successfully (albeit
likely with reduced run-time performance) with Xcode 5.0-6.2
(iOS/AArch64) and Android NDK < r19 (AArch32).  Note that Xcode 5.0-6.2
will not build the Armv8 GAS code without gas-preprocessor.pl, and no
version of Xcode will build the Armv7 GAS code without
gas-preprocessor.pl, so we always use the full Neon intrinsics
implementation by default with macOS and iOS builds.

Auto-detecting the completeness of the compiler's set of Neon intrinsics
also allows us to more intelligently set the default value of
NEON_INTRINSICS, based on the values of HAVE_VLD1*.  This is a
reasonable, albeit imperfect, proxy for whether a compiler has a full
and optimal set of Neon intrinsics.  Specific notes:

  - 64-bit RGB-to-YCbCr color conversion
    does not use any of the intrinsics in question, regresses with GCC
  - 64-bit accurate integer forward DCT
    uses vld1_s16_x3(), regresses with GCC
  - 64-bit Huffman encoding
    uses vld1q_u8_x4(), regresses with GCC
  - 64-bit YCbCr-to-RGB color conversion
    does not use any of the intrinsics in question, regresses with GCC
  - 64-bit accurate integer inverse DCT
    uses vld1_s16_x3(), regresses with GCC
  - 64-bit 4x4 inverse DCT
    uses vld1_s16_x3().  I did not test this algorithm in isolation, so
    it may in fact regress with GCC, but the regression may be hidden by
    the speedup from the new SIMD-accelerated upsampling algorithms.

  - 32-bit RGB-to-YCbCr color conversion:
    uses vld1_u16_x2(), regresses with GCC
  - 32-bit accurate integer forward DCT
    uses vld1_s16_x3(), regression irrelevant because there was no
    previous implementation
  - 32-bit accurate integer inverse DCT
    uses vld1_s16_x3(), regresses with GCC
  - 32-bit fast integer inverse DCT
    does not use any of the intrinsics in question, regresses with GCC
  - 32-bit 4x4 inverse DCT
    uses vld1_s16_x3().  I did not test this algorithm in isolation, so
    it may in fact regress with GCC, but the regression may be hidden by
    the speedup from the new SIMD-accelerated upsampling algorithms.

Presumably when GCC includes a full and optimal set of Neon intrinsics,
the HAVE_VLD1* tests will pass, and the full Neon intrinsics
implementation will be enabled automatically.
2020-11-13 15:16:34 -06:00
DRC
bbd8089297 Neon: Finalize intrinsics implementation
- Remove gas-preprocessor.pl.  None of the compilers that can build the
  new intrinsics implementation require gas-preprocessor.pl (tested
  with Xcode and with Clang 3.9+ for Linux.)
- Document that Xcode 6.3.x or later is now required for iOS builds
  (older versions of Xcode do not have a full set of Neon intrinsics.)
- Add a change log entry.
- Do not enable the ASM CMake language unless NEON_INTRINSICS is false.
- Add a Clang/Arm64 test to .travis.yml in order to test the new
  intrinsics implementation.

Closes #455
2020-11-10 19:58:28 -06:00
Martyn Jacques
141f26ff6d Neon: Intrinsics impl. of 2x2 and 4x4 scaled IDCTs
The previous AArch32 and AArch64 GAS implementations have been removed,
since the intrinsics implementations provide the same or better
performance.
2020-11-10 19:09:09 -06:00
Jonathan Wright
4574f01f43 Neon: Intrinsics impl. of h2v1 & h2v2 plain upsamp
There was no previous GAS implementation.

NOTE: This doesn't produce much of a speedup when using -O3, because -O3
already enables Neon autovectorization, which works well for the scalar
C implementation of plain upsampling.  However, the Neon SIMD
implementation will benefit other optimization levels.
2020-11-10 19:09:09 -06:00
Jonathan Wright
ba52a3de32 Neon: Intrinsics impl of h2v1 & h2v2 merged upsamp
There was no previous GAS implementation.

This commit also reverts 40557b2301 and
7723d7f7d0.
7723d7f7d0 was only necessary because
there was no Neon implementation of merged upsampling/color conversion,
and 40557b2301 was only necessary because
of 7723d7f7d0.
2020-11-10 19:09:09 -06:00
Jonathan Wright
240ba417aa Neon: Intrinsics impl. of prog. Huffman encoding
The previous AArch64 GAS implementation has been removed, since the
intrinsics implementation provides the same or better performance.
There was no previous AArch32 GAS implementation.
2020-11-10 19:09:09 -06:00
Jonathan Wright
ed581cd935 Neon: Intrinsics impl. of accurate int inverse DCT
The previous AArch32 and AArch64 GAS implementations are retained by
default when using GCC, in order to avoid a performance regression.  The
intrinsics implementation can be forced on or off using the new
NEON_INTRINSICS CMake variable.
2020-11-10 19:09:09 -06:00
Jonathan Wright
2c6b68e283 Neon: Intrinsics impl. of fast integer Inverse DCT
The previous AArch32 GAS implementation is retained by default when
using GCC, in order to avoid a performance regression.  The intrinsics
implementation can be forced on or off using the new NEON_INTRINSICS
CMake variable.  The previous AArch64 GAS implementation has been
removed, since the intrinsics implementation provides the same or better
performance.
2020-11-10 19:09:09 -06:00
Jonathan Wright
2acfb93c94 Neon: Intrinsics impl. of h1v2 fancy upsamling
There was no previous GAS implementation.
2020-11-10 19:09:09 -06:00
Jonathan Wright
975307775c Neon: Intrinsics impl. of h2v1 & h2v2 fancy upsamp
The previous AArch32 GAS implementation of h2v1 fancy upsampling has
been removed, since the intrinsics implementation provides the same or
better performance.  There was no previous GAS implementation of h2v2
fancy upsampling, and there was no previous AArch64 GAS implementation
of h2v1 fancy upsampling.
2020-11-10 19:09:09 -06:00
Jonathan Wright
5dbd39323c Neon: Intrinsics implementation of YCbCr->RGB565
The previous AArch64 GAS implementation is retained by default when
using GCC, in order to avoid a performance regression.  The intrinsics
implementation can be forced on or off using the new NEON_INTRINSICS
CMake variable.  The previous AArch32 GAS implementation has been
removed, since the intrinsics implementation provides the same or better
performance.
2020-11-10 19:09:09 -06:00
Jonathan Wright
0f35cd68f2 Neon: Intrinsics implementation of YCbCr->RGB
The previous AArch64 GAS implementation is retained by default when
using GCC, in order to avoid a performance regression.  The intrinsics
implementation can be forced on or off using the new NEON_INTRINSICS
CMake variable.  The previous AArch32 GAS implementation has been
removed, since the intrinsics implementation provides the same or better
performance.
2020-11-10 19:09:09 -06:00
Jonathan Wright
f3c3f01d23 Neon: Intrinsics impl. of Huffman encoding
The previous AArch64 GAS implementation is retained by default when
using GCC, in order to avoid a performance regression.  The intrinsics
implementation can be forced on or off using the new NEON_INTRINSICS
CMake variable.  The previous AArch32 GAS implementation has been
removed, since the intrinsics implementation provides the same or better
performance.
2020-11-10 19:09:09 -06:00
Jonathan Wright
d0004de5dd Neon: Intrinsics impl. of accurate int forward DCT
The previous AArch64 GAS implementation is retained by default when
using GCC, in order to avoid a performance regression.  The intrinsics
implementation can be forced on or off using the new NEON_INTRINSICS
CMake variable.  There was no previous AArch32 GAS implementation.
2020-11-10 19:09:09 -06:00
Jonathan Wright
3d84668d42 Neon: Intrinsics impl. of fast integer forward DCT
The previous AArch32 and AArch64 GAS implementations have been removed,
since the intrinsics implementation provides the same or better
performance.
2020-11-10 19:09:09 -06:00
Jonathan Wright
951d3677eb Neon: Intrinsics impl. of int sample conv./quant.
The previous AArch32 and AArch64 GAS implementations have been removed,
since the intrinsics implementation provides the same or better
performance.
2020-11-10 19:09:09 -06:00
Jonathan Wright
366168aa7d Neon: Intrinsics impl. of h2v1 & h2v2 downsampling
The previous AArch64 GAS implementation has been removed, since the
intrinsics implementation provides the same or better performance.
There was no previous AArch32 GAS implementation.
2020-11-10 19:09:09 -06:00
Jonathan Wright
f73b1dbc60 Neon: Intrinsics implementation of RGB->Grayscale
There was no previous GAS implementation.
2020-11-10 19:09:09 -06:00
Jonathan Wright
4f2216b435 Neon: Intrinsics implementation of RGB->YCbCr
The previous AArch32 and AArch64 GAS implementations are retained by
default when using GCC, in order to avoid a performance regression.  The
intrinsics implementation can be forced on or off using a new
NEON_INTRINSICS CMake variable.
2020-11-10 19:09:05 -06:00
DRC
7c1a1789d2 Merge branch 'master' into dev 2020-11-05 16:04:55 -06:00
DRC
6e632af9f6 Demote "fast" [I]DCT algorithms to legacy status
- Refer to the "slow" [I]DCT algorithms as "accurate" instead, since
  they are not slow under libjpeg-turbo.
- Adjust documentation claims to reflect the fact that the "slow" and
  "fast" algorithms produce about the same performance on AVX2-equipped
  CPUs (because of the dual-lane nature of AVX2, it was not possible to
  accelerate the "fast" algorithm beyond what was achievable with SSE2.)
  Also adjust the claims to reflect the fact that the "fast" algorithm
  tends to be ~5-15% faster than the "slow" algorithm on
  non-AVX2-equipped CPUs, regardless of the use of the libjpeg-turbo
  SIMD extensions.
- Indicate the legacy status of the "fast" and float algorithms in the
  documentation and cjpeg/djpeg usage info.
- Remove obsolete paragraph in the djpeg man page that suggested that
  the float algorithm could be faster than the "fast" algorithm on some
  CPUs.
2020-11-05 15:59:31 -06:00
DRC
cd342acf7f Merge branch 'master' into dev 2020-10-27 16:45:23 -05:00
DRC
d27b935a88 Consistify formatting to simplify checkstyle
The checkstyle script was hastily developed prior to libjpeg-turbo 2.0
beta1, so it has a lot of exceptions and is thus prone to false
negatives.  This commit eliminates some of those exceptions.
2020-10-27 15:45:09 -05:00
DRC
59352195b2 Merge branch 'master' into dev 2020-10-19 21:17:46 -05:00
DRC
1ed312eab6 "ARM"="Arm", "NEON"="Neon"
Refer to:
https://www.arm.com/company/policies/trademarks/arm-trademark-list/arm-trademark
https://www.arm.com/company/policies/trademarks/arm-trademark-list/neon-trademark

NOTE: These changes are only applied to change log entries for 2.0.x and
later, since the change log is a historical record and Arm's new
trademark policy did not go into effect until late 2017.
2020-10-15 17:47:31 -05:00
DRC
ae08115d4d Merge branch 'master' into dev 2020-10-15 10:25:46 -05:00
DRC
b5a1472781 Build: Fix permissions 2020-10-15 10:22:51 -05:00
DRC
6ab61fa1d1 Merge branch 'master' into dev 2020-09-13 17:02:27 -05:00
DRC
6ee5d5f568 ARMv8 NEON: Support Windows builds w/AArch64 MinGW
Based on:
c5ef665928

Closes #438
2020-07-28 18:24:41 -05:00
DRC
00d48d7e8c Merge branch 'master' into dev 2020-02-17 18:14:10 -06:00
DRC
035262a18d MIPS DSPr2: Work around various 'make test' errors
Referring to #408, this commit #ifdefs DSPr2 SIMD functions that only
work on little endian processors, and it completely excludes
jsimd_h2v1_downsample_dspr2() and jsimd_h2v2_downsample_dspr2().  The
latter two functions fail with the TJBench tiling regression tests, most
likely because the implementation of the functions predates those tests.
2020-02-17 18:13:31 -06:00
DRC
ed7cab47d9 MIPS DSPr2: Fix compiler warning with -mdspr2
If -mdspr2 is passed to the compiler, __mips_dsp will be defined, and
__mips_dsp_rev will be >= 2, so parse_proc_cpuinfo() will not be used.
2020-02-17 16:35:00 -06:00
DRC
42d679b9fc MIPS SIMD: Always honor JSIMD_FORCE* env vars
Previously, these environment variables were not honored unless a 74K
CPU was detected, but this detection doesn't work properly with QEMU's
user mode emulation.  With all other CPU types, libjpeg-turbo honors
JSIMD_FORCE* regardless of CPU detection.
2020-02-17 15:19:32 -06:00
DRC
b34c85ea4a Merge branch 'master' into dev 2019-12-31 01:20:12 -06:00
DRC
166e34213e simd/arm64/jsimd_neon.S: Fix checkstyle issue 2019-12-31 01:10:30 -06:00
DRC
c4675d62e8 Merge branch 'master' into dev 2019-12-31 00:58:42 -06:00
DRC
b542e4c8e9 ARMv8 SIMD: Support execute-only memory (XOM)
Move constants out of the .text section in simd/arm64/jsimd_neon.S and
into a .rodata section.  This ensures that the ARMv8 NEON SIMD
extensions are compatible with memory layouts that are marked
execute-only (and thus unreadable.)

Based on:
88f3ca7664

Closes #318
2019-12-20 14:24:10 -06:00
DRC
81b8c0eed5 Loongson MMI: Merge with MIPS64/add auto-detection
Modern Loongson processors are MIPS64-compatible, and MMI instructions
are now supported in the mainline of GCC.  Thus, this commit adds
compile-time and run-time auto-detection of MMI instructions and moves
the MMI SIMD extensions for libjpeg-turbo from simd/loongson/ to
simd/mips64/.  That will allow MMI and MSA instructions to co-exist
in the same build once #377 has been integrated.

Based on:
82953ddd61

Closes #383
2019-12-17 14:35:49 -06:00
mayeut
e821464f79 ARM64 NEON SIMD impl. of prog. Huffman encoding
This commit adds ARM64 NEON optimizations for the
encode_mcu_AC_first() and encode_mcu_AC_refine() functions used in
progressive Huffman encoding.

Compression speedups for the typical set of five libjpeg-turbo test
images (https://libjpeg-turbo.org/About/Performance):
Cortex-A53: 23.8-39.2% (avg. 32.2%)
Cortex-A72: 26.8-41.1% (avg. 33.5%)
Apple A7:  29.7-45.9% (avg. 39.6%)

Closes #229
2019-12-10 00:21:57 -06:00
DRC
9c6f79e919 Fix formatting issues detected by checkstyle 2019-11-14 12:16:38 -06:00
DRC
f60b6dd36f Remove vestigial jpeg_nbits_table.inc
Not needed since 087c29e07f
2019-11-12 17:42:39 -06:00
DRC
713c451f58 Enable SSE2 progressive Huffman encoder for x32
Referring to #289, I'm not sure where I arrived at the conclusion that
the SSE2 progressive Huffman encoder doesn't provide any speedup for
x32.  Upon re-testing, I discovered it to be about 50% faster than the
C encoder.

This commit also re-purposes one of the CI tests (specifically, the
jpeg-7 API/ABI test) so that it tests x32 as well.
2019-11-08 16:03:38 -06:00
DRC
cbf0fcc8b7 i386 SSE2 Huffman: Fix pointer arithmetic issue
Splitting the pointer arithmetic in GET_SYM() into a separate add and
sub instruction was an attempt to work around an error ("invalid operand
type") that occurred when assembling the file with NASM.  However, this
created a link error on macOS ("ld: illegal text-relocation to
'_jconst_huff_encode_one_block' in
simd/CMakeFiles/simd.dir/i386/jchuff-sse2.asm.o from
'_jsimd_huff_encode_one_block_sse2' in
simd/CMakeFiles/simd.dir/i386/jchuff-sse2.asm.o for architecture i386")
and also changed the alignment of the code in ways that might have
affected the previous benchmark results (which took a great deal of time
to obtain.)  Ultimately, the path of least resistance is just to
require NASM 2.13 or later.
2019-11-05 15:56:28 -06:00
DRC
bbedb4b564 Merge branch 'master' into dev 2019-11-05 15:43:21 -06:00
DRC
cf54623b08 Mac: Support hiding SIMD fct symbols w/ NASM 2.14+
(NASM 2.14+ now supports the private_extern section directive, which was
previously only available with YASM.)
2019-11-05 15:41:59 -06:00