Commit Graph

410 Commits

Author SHA1 Message Date
Chris Young
4ad94b2963 Detect AltiVec support on AmigaOS 4 2016-11-18 13:03:28 -06:00
DRC
108b1cd9ba Merge branch 'master' into dev 2016-10-20 01:37:40 -05:00
DRC
13e6b151b0 Win: Use YASM if it is in the PATH and NASM isn't
Previously, simd/CMakeLists.txt was hard-coded to use NASM, and it was
necessary to override the NASM variable in order to use YASM.  This
commit changes the behavior such that NASM is still preferred, but YASM
will be used if it is in the PATH and NASM isn't available.  This brings
the actual behavior in line with the behavior described in BUILDING.md.

Based on
b0799a1598

Closes #107
2016-10-11 11:58:20 -05:00
DRC
ed21f4bd03 Merge branch 'master' into dev 2016-10-05 14:41:14 -05:00
DRC
f34f2f5bc6 Fix 'make dist' 2016-10-05 13:36:35 -05:00
DRC
7bfb22af12 Fix broken MIPS build
Regression introduced by 9055fb408d

Fixes #104
2016-09-26 18:01:54 -05:00
DRC
6c36568626 Merge branch 'master' into dev 2016-09-20 18:09:15 -05:00
mayeut
cb88e5da80 ARM64 NEON: Fix another ABI conformance issue
Based on
98a5a9dc89
with wordsmithing by DRC.

In the AArch64 ABI, as in many others, it's forbidden to read/store data
below the stack pointer.  Some SIMD functions were doing just that
(stack pointer misuse) when trying to preserve callee-saved registers,
and this resulted in those registers being restored with incorrect
contents under certain circumstances.

This patch fixes that behavior, and callee-saved registers are now
stored above the stack pointer throughout the function call.  The patch
also removes register saving in places where it is unnecessary for this
ABI, or it makes use of unused scratch regiters instead of callee-saved
registers.

Fixes #97.  Closes #101.

Refer also to https://bugzilla.redhat.com/show_bug.cgi?id=1368569
2016-09-20 17:38:39 -05:00
DRC
3924ebceb5 AVX2: Perform additional checks for O/S support
cpuid tells us whether the O/S uses extended state management via
XSAVE/XRSTOR, but we have to call xgetbv to verify that it is using
XSAVE/XRSTOR to manage the state of XMM/YMM registers.
2016-07-13 16:03:36 -05:00
DRC
1120ff29a1 Fix AArch64 ABI conformance issue in SIMD code
In the AArch64 ABI, the high (unused) DWORD of a 32-bit argument's
register is undefined, so it was incorrect to use 64-bit
instructions to transfer a JDIMENSION argument in the 64-bit NEON SIMD
functions.  The code worked thus far only because the existing compiler
optimizers weren't smart enough to do anything else with the register in
question, so the upper 32 bits happened to be all zeroes.

The latest builds of Clang/LLVM have a smarter optimizer, and under
certain circumstances, it will attempt to load-combine adjacent 32-bit
integers from one of the libjpeg structures into a single 64-bit integer
and pass that 64-bit integer as a 32-bit argument to one of the SIMD
functions (which is allowed by the ABI, since the upper 32 bits of the
32-bit argument's register are undefined.)  This caused the
libjpeg-turbo regression tests to crash.

This patch tries to use the Wn registers whenever possible.  Otherwise,
it uses a zero-extend instruction to avoid using the upper 32 bits of
the 64-bit registers, which are not guaranteed to be valid for 32-bit
arguments.

Based on 1fbae13021

Closes #91.  Refer also to android-ndk/ndk#110 and
https://llvm.org/bugs/show_bug.cgi?id=28393
2016-07-13 14:36:19 -05:00
DRC
3dcb85ee9a AVX2: Verify O/S support for AVX2 before enabling
This fixes crashes that would occur when attempting to use
libjpeg-turbo's AVX2 extensions on older O/S's (such as Windows XP or
RHEL 5.)  Even if the CPU supports AVX2, the O/S has to also support
saving/restoring YMM registers when switching contexts.
2016-07-11 20:26:34 -05:00
DRC
1be87b6273 Reformat jsimdcpu[-64].asm to improve readability 2016-07-11 19:42:37 -05:00
DRC
b331385e8a Merge branch 'master' into dev 2016-07-11 13:11:25 -05:00
DRC
b2921f1bcc 32-bit AVX2 implementation of integer quantization 2016-07-08 21:28:48 -05:00
DRC
eaae2cdb16 64-bit AVX2 implementation of integer quantization 2016-07-08 21:15:27 -05:00
DRC
a7c2f97939 AVX2: Avoid expensive AVX-SSE transitions
Refer to
https://software.intel.com/sites/default/files/m/d/4/1/d/8/11MC12_Avoiding_2BAVX-SSE_2BTransition_2BPenalties_2Brh_2Bfinal.pdf
for more information.  This eliminates all AVX-SSE transitions detected
with the Intel SDE tool.
2016-07-08 20:10:24 -05:00
DRC
e06ccbe3f7 64-bit AVX2: Fix bug in IS_ALIGNED_AVX() macro
32 = 1 << 5, not 1 << 8
2016-07-08 13:02:30 -05:00
DRC
67de29b503 32-bit AVX2 impl. of h2v2 & h2v1 merged upsampling 2016-07-08 13:02:30 -05:00
DRC
c22e42e9a2 Optimize 64-bit AVX2 h2v2 fancy upsampler
Reduce register usage and eliminate unnecessary mov instructions
2016-07-08 13:02:30 -05:00
DRC
6d765524bc 32-bit AVX2 impl. of h2v2 & h2v1 upsampling
(Fancy & Plain)
2016-07-08 13:02:30 -05:00
DRC
421d34fd2f 32-bit AVX2 impl. of YCC->RGB color conversion 2016-07-08 13:02:30 -05:00
DRC
c6300ffe4e 32-bit AVX2 impl. of h2v2 & h2v1 downsampling 2016-07-08 13:02:30 -05:00
DRC
6448a5e584 32-bit AVX2 impl. of RGB->YCC/RGB->Gray color conv 2016-07-08 13:02:24 -05:00
DRC
6e9d43e085 Linux/PPC: Only enable AltiVec if CPU supports it
This eliminates "illegal instruction" errors when running libjpeg-turbo
under Linux on PowerPC chips that lack AltiVec support (e.g. the old
7XX/G3 models but also the newer e5500 series.)
2016-07-07 19:02:44 +00:00
DRC
9055fb408d ARM/MIPS: Change the behavior of JSIMD_FORCE*
The JSIMD_FORCE* environment variables previously meant "force the use
of this instruction set if it is available but others are available as
well", but that did nothing on ARM platforms, since there is only ever
one instruction set available.  Since the ARM and MIPS CPU feature
detection code is less than bulletproof, and since there is only one
SIMD instruction set (currently) supported on those platforms, it makes
sense for the JSIMD_FORCE* environment variables on those platforms to
actually force the use of the SIMD instruction set, thus bypassing the
CPU feature detection code.

This addresses a concern raised in #88 whereby parsing /proc/cpuinfo
didn't work within a QEMU environment.  This at least provides a
workaround, allowing users to force-enable or force-disable SIMD
instructions for ARM and MIPS builds of libjpeg-turbo.
2016-07-07 13:38:48 -05:00
DRC
7ee3ce9ada Lay the groundwork for 32-bit AVX2 SIMD support 2016-07-05 16:23:06 -05:00
DRC
b5426c52c0 64-bit AVX2 SIMD: Restore instructive comments
This commit adds back instructive comments in the image-space
algorithms, similar to those in the SSE2 code.  These comments make it
easier to follow the flow of data through the algorithms.
2016-06-29 13:56:50 -05:00
DRC
621b29f5b1 64-bit AVX2 impl. of h2v2 & h2v1 merged upsampling 2016-05-31 22:56:11 -05:00
DRC
f1cbc32876 64-bit AVX2 impl. of h2v2 & h2v1 upsampling
(Fancy & Plain)
2016-05-31 22:56:11 -05:00
DRC
72c837da24 64-bit AVX2 impl. of YCC->RGB color conversion 2016-05-31 22:56:11 -05:00
DRC
1c8a475cd4 64-bit AVX2 impl. of h2v2 & h2v1 downsampling 2016-05-31 22:56:11 -05:00
DRC
8880e08771 64-bit AVX2 impl. of RGB->Gray color conversion 2016-05-31 22:56:11 -05:00
DRC
426d787c4c 64-bit AVX2 impl. of RGB->YCC color conversion 2016-05-31 22:56:11 -05:00
DRC
2cf199cbbd Lay the groundwork for 64-bit AVX2 SIMD support 2016-05-31 22:54:38 -05:00
DRC
16b121890c x86-64 SIMD: Optimize argument collection
Expand collect_args/uncollect_args macros so that the number of
arguments can be specified.  This prevents unnecessary push and mov
instructions.

NOTE: On Windows, the push/pop of xmm6 and xmm7 had to be moved to the
other end of the macro to ensure that rsp is aligned on a 16-byte
boundary.
2016-05-31 22:54:37 -05:00
DRC
ff5685d534 Reformat SSE/SSE2 SIMD code to improve readability 2016-05-31 22:53:40 -05:00
DRC
123f7258a8 Format copyright headers more consistently
The IJG convention is to format copyright notices as:

Copyright (C) YYYY, Owner.

We try to maintain this convention for any code that is part of the
libjpeg API library (with the exception of preserving the copyright
notices from Cendio's code verbatim, since those predate
libjpeg-turbo.)

Note that the phrase "All Rights Reserved" is no longer necessary, since
all Buenos Aires Convention signatories signed onto the Berne Convention
in 2000.  However, our convention is to retain this phrase for any files
that have a self-contained copyright header but to leave it off of any
files that refer to another file for conditions of distribution and use.
For instance, all of the non-SIMD files in the libjpeg API library refer
to README.ijg, and the copyright message in that file contains "All
Rights Reserved", so it is unnecessary to add it to the individual
files.

The TurboJPEG code retains my preferred formatting convention for
copyright notices, which is based on that of VirtualGL (where the
TurboJPEG API originated.)
2016-05-28 19:16:58 -05:00
mattsarett
2e480fa2a3 ARMv7 SIMD: Fix clang compatibility (Part 2)
GCC does support UAL syntax (strbeq) if the ".syntax unified" directive
is supplied.  This directive is supported by all versions of GCC and
clang going back to 2003, so it should not create any backward
compatibility issues.

Based on 1264349e2f

Closes #76
2016-05-03 13:08:58 -05:00
mattsarett
5e576386b5 ARMv7 SIMD: Fix clang compatibility
By design, clang only supports Unified Assembler Language (and not
pre-UAL syntax):
https://llvm.org/bugs/show_bug.cgi?id=23507
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0473c/BABJIHGJ.html

Thus, clang only supports the strbeq instruction and not streqb, but
unfortunately some versions of GCC only support streqb.  Go, go
Gadget #ifdef...

Based on https://github.com/mattsarett/libjpeg-turbo/commit/a82e63aac63f8fa3
95fa4caad4de6859623ee2e2

Closes #75
2016-05-02 12:20:10 -05:00
DRC
056536f660 Win/x64: Fix improper callee save of xmm8-xmm11
The x86-64 SIMD accelerations for Huffman encoding used incorrect
stack math to save xmm8-xmm11 on Windows.  This caused TJBench to
always report 1 Mpixel/sec for the compression performance, and it
likely would have caused other application issues as well.
2016-02-29 17:46:34 -06:00
DRC
bd49803f92 Use consistent/modern code formatting for pointers
The convention used by libjpeg:

    type * variable;

is not very common anymore, because it looks too much like
multiplication.  Some (particularly C++ programmers) prefer to tuck the
pointer symbol against the type:

    type* variable;

to emphasize that a pointer to a type is effectively a new type.
However, this can also be confusing, since defining multiple variables
on the same line would not work properly:

    type* variable1, variable2;  /* Only variable1 is actually a
                                    pointer. */

This commit reformats the entirety of the libjpeg-turbo code base so
that it uses the same code formatting convention for pointers that the
TurboJPEG API code uses:

    type *variable1, *variable2;

This seems to be the most common convention among C programmers, and
it is the convention used by other codec libraries, such as libpng and
libtiff.
2016-02-19 09:10:07 -06:00
DRC
8632f1b262 ARM64: Avoid tbl instruction on Cortex-A53/A57
Full-color compression speedups relative to previous commits:
Cortex-A53 (Nexus 5X), Android, 64-bit: 0.91-3.0% (avg. 1.8%)
Cortex-A57 (Nexus 5X), Android, 64-bit: -0.35-1.5% (avg. 0.65%)
2016-02-09 00:38:58 -06:00
DRC
28f00bf235 Fix iOS/ARMv8 build
Broken by 46ecffa324.

gas-preprocessor.pl and/or the clang assembler apparently don't like
default values in macro arguments, and we need to use a separate const
section for each function (because of our use of adr, also necessitated
by the broken clang assembler.)
2016-02-08 15:15:11 -06:00
DRC
53c635b8e8 Fix 'make dist'; Include LICENSE.md in packages 2016-02-08 14:03:13 -06:00
DRC
46ecffa324 ARM64: Avoid LD3/ST3 at run time, not compile time
... and only if ThunderX is detected.  This can be easily expanded later
on to include other CPUs that are known to suffer from slow LD3/ST3, but
it doesn't make sense to disable LD3/ST3 for all non-Android Linux
platforms just because ThunderX is slow.
2016-02-07 22:05:56 -06:00
DRC
219470d6ac ARM64 NEON SIMD implementation of Huffman encoding
Full-color compression speedups relative to previous commits:
Cortex-A53 (Nexus 5X), Android, 64-bit: 1.1-13% (avg. 6.0%)
Cortex-A57 (Nexus 5X), Android, 64-bit: 0.0-22% (avg. 6.3%)

Refer to #47 and #50 for discussion

Closes #50

Note that this commit introduces a similar /proc/cpuinfo parser to that
of the ARM32 implementation.  It is used to specifically check whether
the code is running on Cavium ThunderX and, if so, disable the ARM64
SIMD Huffman routines (which slow performance by an average of 8% on
that CPU.)

Based on:
a8c282e5e5
2016-02-07 21:51:11 -06:00
DRC
15aaa7f7e2 ARM SIMD: Comment tweaks 2016-02-07 17:39:33 -06:00
DRC
cf888486d1 Use consistent formatting in ARM NEON SIMD code
There aren't really any best practices to follow here.  I tried as best
as I could to adopt a standard that would ease any future maintenance
burdens.  The basic tenets of that standard are:

* Assembly instructions always start on Column 5, and operands always
  start on Column 21, except:
  - The instruction and operand can be indented (usually by 2 spaces)
    to indicate a separate instruction stream.
  - If the instruction is within an enclosing .if block in a macro,
    it should always be indented relative to the .if block.
* Comments are placed with an eye toward readability.  There are always
  at least 2 spaces between the end of a line of code and the associated
  in-line comment.  Where it made sense, I tried to line up the comments
  in blocks, and some were shifted right to avoid overlap with
  neighboring instruction lines.  Not an exact science.
* Assembler directives and macros use 2-space indenting rules.  .if
  blocks are indented relative to the macro, and code within the .if
  blocks is indented relative to the .if directive.
* No extraneous spaces between operands.  Lining up the operands
  vertically did not really improve readability-- personally, I think it
  made it worse, since my eye would tend to lose its place in the
  uniform columns of characters.  Also, code with a lot of vertical
  alignment is really hard to maintain, since changing one line could
  necessitate changing a bunch of other lines to avoid spoiling the
  alignment.
* No extraneous spaces in #defines or other directives.  In general, the
  only extraneous spaces (other than indenting spaces) are between:
  - Instructions and operands
  - Operands and in-line comments
This standard should be more or less in keeping with other formatting
standards used within the project.
2016-02-02 23:39:03 -06:00
DRC
cb49bb00d9 Opt. ARM64 SIMD decompr. for in-order pipelines
Decompression speedup relative to libjpeg-turbo 1.4.2 (ISLOW IDCT):
48-core ThunderX (RunAbove ARM Cloud), Linux, 64-bit: 60-113% (avg. 86%)
Cortex-A53 (Nexus 5X), Android, 64-bit: 6.8-27% (avg. 14%)
Cortex-A57 (Nexus 5X), Android, 64-bit: 2.0-14% (avg. 6.8%)

Decompression speedup relative to libjpeg-turbo 1.4.2 (IFAST IDCT):
48-core ThunderX (RunAbove ARM Cloud), Linux, 64-bit: 51-98% (avg. 75%)

Minimal speedup (1-5%) observed on iPhone 5S (Cortex-A7)

NOTE: This commit avoids the st3 instruction for non-Android and
non-Apple builds, which may cause a performance regression against
libjpeg-turbo 1.4.x on ARM64 systems that are running plain Linux.
Since ThunderX is the only platform known to suffer from slow ld3 and
st3 instructions, it is probably better to check for the CPU type
at run time and disable ld3/st3 only if ThunderX is detected.

This commit also enables the use of ld3 on Android platforms, which
should be a safe bet, at least for now.  This speeds up compression on
the afore-mentioned Nexus Cortex-A53 by 5.5-19% (avg. 12%) and on the
Nexus Cortex-A57 by 1.2-14% (avg. 6.3%), relative to the previous
commits.

This commit also removes unnecessary macros.

Refer to #52 for discussion.

Closes #52.

Based on:
6bad905034
488dd7bf17
4f4d057c1f
d3198afc43
2016-02-02 23:14:27 -06:00
DRC
d38b4f21ec Optimize ARM64 SIMD code for Cavium ThunderX
Per @ssvb:
ThunderX is an ARM64 chip that dedicates most of its transistor real
estate to providing 48 cores, so each core is not as fast as a result.
Each core is dual-issue & in-order for scalar instructions and has only
a single-issue half-width NEON unit, so the peak throughput is one
128-bit instruction per 2 cycles.  So careful instruction scheduling is
important.  Furthermore, ThunderX has an extremely slow implementation
of ld2 and ld3, so this commit implements the equivalent of those
instructions using ld1.

Compression speedup relative to libjpeg-turbo 1.4.2:
48-core ThunderX (RunAbove ARM Cloud), Linux, 64-bit: 58-85% (avg. 74%)
relative to jpeg-6b: 1.75-2.14x (avg. 1.95x)

Refer to #49 and #51 for discussion.

Closes #51.

This commit also wordsmiths the ChangeLog entry (the ARMv8 SIMD
implementation is "complete" only for compression-- it still lacks some
decompression algorithms, as does the ARMv7 implementation.)

Based on:
9405b5fd03

which is based on:
f561944ff7
962c8ab21f
2016-01-16 02:39:02 -06:00