libdeflate 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/.gitmodules +3 -0
- data/.rspec +2 -0
- data/.rubocop.yml +1 -0
- data/.rubocop_todo.yml +9 -0
- data/.travis.yml +5 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +52 -0
- data/Rakefile +15 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/ext/libdeflate/extconf.rb +14 -0
- data/ext/libdeflate/libdeflate/.gitignore +19 -0
- data/ext/libdeflate/libdeflate/COPYING +21 -0
- data/ext/libdeflate/libdeflate/Makefile +231 -0
- data/ext/libdeflate/libdeflate/Makefile.msc +64 -0
- data/ext/libdeflate/libdeflate/NEWS +57 -0
- data/ext/libdeflate/libdeflate/README.md +170 -0
- data/ext/libdeflate/libdeflate/common/common_defs.h +351 -0
- data/ext/libdeflate/libdeflate/common/compiler_gcc.h +134 -0
- data/ext/libdeflate/libdeflate/common/compiler_msc.h +95 -0
- data/ext/libdeflate/libdeflate/lib/adler32.c +213 -0
- data/ext/libdeflate/libdeflate/lib/adler32_impl.h +281 -0
- data/ext/libdeflate/libdeflate/lib/aligned_malloc.c +57 -0
- data/ext/libdeflate/libdeflate/lib/aligned_malloc.h +13 -0
- data/ext/libdeflate/libdeflate/lib/bt_matchfinder.h +357 -0
- data/ext/libdeflate/libdeflate/lib/crc32.c +368 -0
- data/ext/libdeflate/libdeflate/lib/crc32_impl.h +286 -0
- data/ext/libdeflate/libdeflate/lib/crc32_table.h +526 -0
- data/ext/libdeflate/libdeflate/lib/decompress_impl.h +404 -0
- data/ext/libdeflate/libdeflate/lib/deflate_compress.c +2817 -0
- data/ext/libdeflate/libdeflate/lib/deflate_compress.h +14 -0
- data/ext/libdeflate/libdeflate/lib/deflate_constants.h +66 -0
- data/ext/libdeflate/libdeflate/lib/deflate_decompress.c +889 -0
- data/ext/libdeflate/libdeflate/lib/gzip_compress.c +95 -0
- data/ext/libdeflate/libdeflate/lib/gzip_constants.h +45 -0
- data/ext/libdeflate/libdeflate/lib/gzip_decompress.c +130 -0
- data/ext/libdeflate/libdeflate/lib/hc_matchfinder.h +405 -0
- data/ext/libdeflate/libdeflate/lib/lib_common.h +35 -0
- data/ext/libdeflate/libdeflate/lib/matchfinder_avx2.h +53 -0
- data/ext/libdeflate/libdeflate/lib/matchfinder_common.h +205 -0
- data/ext/libdeflate/libdeflate/lib/matchfinder_neon.h +61 -0
- data/ext/libdeflate/libdeflate/lib/matchfinder_sse2.h +53 -0
- data/ext/libdeflate/libdeflate/lib/unaligned.h +202 -0
- data/ext/libdeflate/libdeflate/lib/x86_cpu_features.c +169 -0
- data/ext/libdeflate/libdeflate/lib/x86_cpu_features.h +48 -0
- data/ext/libdeflate/libdeflate/lib/zlib_compress.c +87 -0
- data/ext/libdeflate/libdeflate/lib/zlib_constants.h +21 -0
- data/ext/libdeflate/libdeflate/lib/zlib_decompress.c +91 -0
- data/ext/libdeflate/libdeflate/libdeflate.h +274 -0
- data/ext/libdeflate/libdeflate/programs/benchmark.c +558 -0
- data/ext/libdeflate/libdeflate/programs/checksum.c +197 -0
- data/ext/libdeflate/libdeflate/programs/detect.sh +62 -0
- data/ext/libdeflate/libdeflate/programs/gzip.c +603 -0
- data/ext/libdeflate/libdeflate/programs/prog_util.c +530 -0
- data/ext/libdeflate/libdeflate/programs/prog_util.h +162 -0
- data/ext/libdeflate/libdeflate/programs/test_checksums.c +135 -0
- data/ext/libdeflate/libdeflate/programs/tgetopt.c +118 -0
- data/ext/libdeflate/libdeflate/tools/afl-fuzz/Makefile +12 -0
- data/ext/libdeflate/libdeflate/tools/afl-fuzz/deflate_compress/fuzz.c +40 -0
- data/ext/libdeflate/libdeflate/tools/afl-fuzz/deflate_compress/inputs/0 +0 -0
- data/ext/libdeflate/libdeflate/tools/afl-fuzz/deflate_decompress/fuzz.c +28 -0
- data/ext/libdeflate/libdeflate/tools/afl-fuzz/deflate_decompress/inputs/0 +3 -0
- data/ext/libdeflate/libdeflate/tools/afl-fuzz/gzip_decompress/fuzz.c +28 -0
- data/ext/libdeflate/libdeflate/tools/afl-fuzz/gzip_decompress/inputs/0 +0 -0
- data/ext/libdeflate/libdeflate/tools/afl-fuzz/prepare_for_fuzz.sh +14 -0
- data/ext/libdeflate/libdeflate/tools/afl-fuzz/zlib_decompress/fuzz.c +28 -0
- data/ext/libdeflate/libdeflate/tools/afl-fuzz/zlib_decompress/inputs/0 +3 -0
- data/ext/libdeflate/libdeflate/tools/android_build.sh +104 -0
- data/ext/libdeflate/libdeflate/tools/checksum_benchmarks.sh +76 -0
- data/ext/libdeflate/libdeflate/tools/exec_tests.sh +30 -0
- data/ext/libdeflate/libdeflate/tools/gen_crc32_multipliers.c +108 -0
- data/ext/libdeflate/libdeflate/tools/gen_crc32_table.c +100 -0
- data/ext/libdeflate/libdeflate/tools/gzip_tests.sh +412 -0
- data/ext/libdeflate/libdeflate/tools/make-windows-releases +21 -0
- data/ext/libdeflate/libdeflate/tools/mips_build.sh +9 -0
- data/ext/libdeflate/libdeflate/tools/msc_test.bat +3 -0
- data/ext/libdeflate/libdeflate/tools/pgo_build.sh +23 -0
- data/ext/libdeflate/libdeflate/tools/produce_gzip_benchmark_table.sh +37 -0
- data/ext/libdeflate/libdeflate/tools/run_tests.sh +305 -0
- data/ext/libdeflate/libdeflate/tools/windows_build.sh +10 -0
- data/ext/libdeflate/libdeflate_ext.c +389 -0
- data/ext/libdeflate/libdeflate_ext.h +8 -0
- data/lib/libdeflate.rb +2 -0
- data/lib/libdeflate/version.rb +3 -0
- data/libdeflate.gemspec +33 -0
- metadata +230 -0
|
Binary file
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
#include <assert.h>
|
|
2
|
+
#include <libdeflate.h>
|
|
3
|
+
#include <fcntl.h>
|
|
4
|
+
#include <unistd.h>
|
|
5
|
+
#include <sys/stat.h>
|
|
6
|
+
|
|
7
|
+
int main(int argc, char **argv)
|
|
8
|
+
{
|
|
9
|
+
struct libdeflate_decompressor *d;
|
|
10
|
+
int ret;
|
|
11
|
+
int fd = open(argv[1], O_RDONLY);
|
|
12
|
+
struct stat stbuf;
|
|
13
|
+
assert(fd >= 0);
|
|
14
|
+
ret = fstat(fd, &stbuf);
|
|
15
|
+
assert(!ret);
|
|
16
|
+
|
|
17
|
+
char in[stbuf.st_size];
|
|
18
|
+
ret = read(fd, in, sizeof in);
|
|
19
|
+
assert(ret == sizeof in);
|
|
20
|
+
|
|
21
|
+
char out[sizeof(in) * 3];
|
|
22
|
+
|
|
23
|
+
d = libdeflate_alloc_decompressor();
|
|
24
|
+
|
|
25
|
+
libdeflate_deflate_decompress(d, in, sizeof in, out, sizeof out, NULL);
|
|
26
|
+
libdeflate_free_decompressor(d);
|
|
27
|
+
return 0;
|
|
28
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
#include <assert.h>
|
|
2
|
+
#include <libdeflate.h>
|
|
3
|
+
#include <fcntl.h>
|
|
4
|
+
#include <unistd.h>
|
|
5
|
+
#include <sys/stat.h>
|
|
6
|
+
|
|
7
|
+
int main(int argc, char **argv)
|
|
8
|
+
{
|
|
9
|
+
struct libdeflate_decompressor *d;
|
|
10
|
+
int ret;
|
|
11
|
+
int fd = open(argv[1], O_RDONLY);
|
|
12
|
+
struct stat stbuf;
|
|
13
|
+
assert(fd >= 0);
|
|
14
|
+
ret = fstat(fd, &stbuf);
|
|
15
|
+
assert(!ret);
|
|
16
|
+
|
|
17
|
+
char in[stbuf.st_size];
|
|
18
|
+
ret = read(fd, in, sizeof in);
|
|
19
|
+
assert(ret == sizeof in);
|
|
20
|
+
|
|
21
|
+
char out[sizeof(in) * 3];
|
|
22
|
+
|
|
23
|
+
d = libdeflate_alloc_decompressor();
|
|
24
|
+
|
|
25
|
+
libdeflate_gzip_decompress(d, in, sizeof in, out, sizeof out, NULL);
|
|
26
|
+
libdeflate_free_decompressor(d);
|
|
27
|
+
return 0;
|
|
28
|
+
}
|
|
Binary file
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
|
|
3
|
+
set -e
|
|
4
|
+
|
|
5
|
+
make -C ../../ clean
|
|
6
|
+
make clean
|
|
7
|
+
AFL_HARDEN=1 make CC=afl-gcc -C ../../
|
|
8
|
+
AFL_HARDEN=1 make CC=afl-gcc
|
|
9
|
+
|
|
10
|
+
for dir in $(find . -mindepth 1 -maxdepth 1 -type d); do
|
|
11
|
+
rm -rf /tmp/$dir
|
|
12
|
+
cp -va $dir /tmp/$dir
|
|
13
|
+
mkdir -p /tmp/$dir/outputs
|
|
14
|
+
done
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
#include <assert.h>
|
|
2
|
+
#include <libdeflate.h>
|
|
3
|
+
#include <fcntl.h>
|
|
4
|
+
#include <unistd.h>
|
|
5
|
+
#include <sys/stat.h>
|
|
6
|
+
|
|
7
|
+
int main(int argc, char **argv)
|
|
8
|
+
{
|
|
9
|
+
struct libdeflate_decompressor *d;
|
|
10
|
+
int ret;
|
|
11
|
+
int fd = open(argv[1], O_RDONLY);
|
|
12
|
+
struct stat stbuf;
|
|
13
|
+
assert(fd >= 0);
|
|
14
|
+
ret = fstat(fd, &stbuf);
|
|
15
|
+
assert(!ret);
|
|
16
|
+
|
|
17
|
+
char in[stbuf.st_size];
|
|
18
|
+
ret = read(fd, in, sizeof in);
|
|
19
|
+
assert(ret == sizeof in);
|
|
20
|
+
|
|
21
|
+
char out[sizeof(in) * 3];
|
|
22
|
+
|
|
23
|
+
d = libdeflate_alloc_decompressor();
|
|
24
|
+
|
|
25
|
+
libdeflate_zlib_decompress(d, in, sizeof in, out, sizeof out, NULL);
|
|
26
|
+
libdeflate_free_decompressor(d);
|
|
27
|
+
return 0;
|
|
28
|
+
}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
set -eu
|
|
4
|
+
|
|
5
|
+
ARCH="arm32"
|
|
6
|
+
COMPILER="gcc"
|
|
7
|
+
NDKDIR="/opt/android-ndk"
|
|
8
|
+
DISABLE_NEON=
|
|
9
|
+
|
|
10
|
+
usage() {
|
|
11
|
+
cat << EOF
|
|
12
|
+
Usage: $0 [OPTION]... -- [BENCHMARK_PROGRAM_ARG]...
|
|
13
|
+
Build the libdeflate test programs for Android
|
|
14
|
+
|
|
15
|
+
--arch=ARCH Architecture: arm32|arm64 (default: $ARCH)
|
|
16
|
+
--compiler=COMPILER Compiler: gcc|clang (default: $COMPILER)
|
|
17
|
+
--ndkdir=NDKDIR Android NDK directory (default: $NDKDIR)
|
|
18
|
+
--disable-neon Disable NEON instructions
|
|
19
|
+
EOF
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
if ! options=$(getopt -o '' \
|
|
23
|
+
-l 'arch:,compiler:,ndkdir:,disable-neon,help' -- "$@"); then
|
|
24
|
+
usage
|
|
25
|
+
exit 1
|
|
26
|
+
fi
|
|
27
|
+
|
|
28
|
+
eval set -- "$options"
|
|
29
|
+
|
|
30
|
+
while [ $# -gt 0 ]; do
|
|
31
|
+
case "$1" in
|
|
32
|
+
--arch)
|
|
33
|
+
ARCH="$2"
|
|
34
|
+
shift
|
|
35
|
+
;;
|
|
36
|
+
--compiler)
|
|
37
|
+
COMPILER="$2"
|
|
38
|
+
shift
|
|
39
|
+
;;
|
|
40
|
+
--ndkdir)
|
|
41
|
+
NDKDIR="$2"
|
|
42
|
+
shift
|
|
43
|
+
;;
|
|
44
|
+
--disable-neon)
|
|
45
|
+
DISABLE_NEON=1
|
|
46
|
+
;;
|
|
47
|
+
--help)
|
|
48
|
+
usage
|
|
49
|
+
exit 0
|
|
50
|
+
;;
|
|
51
|
+
--)
|
|
52
|
+
shift
|
|
53
|
+
break
|
|
54
|
+
;;
|
|
55
|
+
*)
|
|
56
|
+
echo 1>&2 "Unknown option \"$1\""
|
|
57
|
+
usage
|
|
58
|
+
exit 1
|
|
59
|
+
esac
|
|
60
|
+
shift
|
|
61
|
+
done
|
|
62
|
+
|
|
63
|
+
CFLAGS="-fPIC -pie"
|
|
64
|
+
|
|
65
|
+
case "$ARCH" in
|
|
66
|
+
arm|arm32|aarch32)
|
|
67
|
+
GCC_TOOLCHAIN="arm-linux-androideabi-4.9"
|
|
68
|
+
CLANG_TARGET="armv7-none-linux-androideabi"
|
|
69
|
+
if [ -n "$DISABLE_NEON" ]; then
|
|
70
|
+
CFLAGS+=" -march=armv6"
|
|
71
|
+
else
|
|
72
|
+
CFLAGS+=" -march=armv7-a -mfpu=neon -mfloat-abi=softfp"
|
|
73
|
+
fi
|
|
74
|
+
CFLAGS+=" --sysroot=\"$NDKDIR/platforms/android-12/arch-arm\""
|
|
75
|
+
;;
|
|
76
|
+
arm64|aarch64)
|
|
77
|
+
GCC_TOOLCHAIN="aarch64-linux-android-4.9"
|
|
78
|
+
CLANG_TARGET="aarch64-none-linux-android"
|
|
79
|
+
CFLAGS+=" --sysroot=\"$NDKDIR/platforms/android-21/arch-arm64\""
|
|
80
|
+
;;
|
|
81
|
+
*)
|
|
82
|
+
echo 1>&2 "Unknown architecture: \"$ARCH\""
|
|
83
|
+
usage
|
|
84
|
+
exit 1
|
|
85
|
+
esac
|
|
86
|
+
|
|
87
|
+
case "$COMPILER" in
|
|
88
|
+
gcc)
|
|
89
|
+
CC="\"$NDKDIR/toolchains/$GCC_TOOLCHAIN/prebuilt/linux-x86_64/bin/${GCC_TOOLCHAIN%-*}-gcc\""
|
|
90
|
+
CFLAGS+=" -pie"
|
|
91
|
+
;;
|
|
92
|
+
clang)
|
|
93
|
+
CC="\"$NDKDIR/toolchains/llvm/prebuilt/linux-x86_64/bin/clang\""
|
|
94
|
+
CFLAGS+=" -target \"$CLANG_TARGET\""
|
|
95
|
+
CFLAGS+=" -gcc-toolchain \"$NDKDIR/toolchains/$GCC_TOOLCHAIN/prebuilt/linux-x86_64\""
|
|
96
|
+
;;
|
|
97
|
+
*)
|
|
98
|
+
echo 1>&2 "Unknown compiler: \"$COMPILER\""
|
|
99
|
+
usage
|
|
100
|
+
exit 1
|
|
101
|
+
esac
|
|
102
|
+
|
|
103
|
+
make -j$(grep -c processor /proc/cpuinfo) test_programs \
|
|
104
|
+
CC="$CC" CFLAGS="$CFLAGS"
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
set -eu
|
|
4
|
+
|
|
5
|
+
if [ $# -eq 0 ]; then
|
|
6
|
+
FILE="$HOME/data/silesia"
|
|
7
|
+
echo "Using default FILE: $FILE"
|
|
8
|
+
echo
|
|
9
|
+
elif [ $# -eq 1 ]; then
|
|
10
|
+
FILE="$1"
|
|
11
|
+
else
|
|
12
|
+
echo "Usage: $0 [FILE]" 1>&2
|
|
13
|
+
exit 1
|
|
14
|
+
fi
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
if ! grep -q '\<sse2\>' /proc/cpuinfo; then
|
|
18
|
+
echo "This script must be run on an x86 CPU" 1>&2
|
|
19
|
+
exit 1
|
|
20
|
+
fi
|
|
21
|
+
|
|
22
|
+
if [ -n "$(git status -s | egrep 'adler32.c|crc32.c')" ]; then
|
|
23
|
+
echo "This script will overwrite adler32.c and crc32.c, which" \
|
|
24
|
+
"have uncommitted changes. Refusing to run." 1>&2
|
|
25
|
+
exit 1
|
|
26
|
+
fi
|
|
27
|
+
|
|
28
|
+
do_benchmark() {
|
|
29
|
+
method="$1"
|
|
30
|
+
shift
|
|
31
|
+
speed=$(./checksum "$@" -t "$FILE" | \
|
|
32
|
+
grep -o '[0-9]\+ MB/s' | grep -o '[0-9]\+')
|
|
33
|
+
printf "%-36s%-10s\n" "$method" "$speed"
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
sort_by_speed() {
|
|
37
|
+
awk '{print $NF, $0}' | sort -nr | cut -f2- -d' '
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
cat << EOF
|
|
41
|
+
Method Speed (MB/s)
|
|
42
|
+
------ ------------
|
|
43
|
+
EOF
|
|
44
|
+
|
|
45
|
+
# CRC-32
|
|
46
|
+
(
|
|
47
|
+
if grep -q '\<pclmulqdq\>' /proc/cpuinfo; then
|
|
48
|
+
make checksum > /dev/null
|
|
49
|
+
do_benchmark "CRC-32 (libdeflate, PCLMUL/AVX)"
|
|
50
|
+
sed -i '/^\#if NEED_PCLMUL_IMPL && !defined(__AVX__)/,/^\#endif$/d' lib/crc32.c
|
|
51
|
+
make checksum > /dev/null
|
|
52
|
+
do_benchmark "CRC-32 (libdeflate, PCLMUL)"
|
|
53
|
+
fi
|
|
54
|
+
sed -i '/^#if defined(__PCLMUL__)/,/^\#endif$/d' lib/crc32.c
|
|
55
|
+
make checksum > /dev/null
|
|
56
|
+
do_benchmark "CRC-32 (libdeflate, generic)"
|
|
57
|
+
git checkout -f lib/crc32.c > /dev/null
|
|
58
|
+
do_benchmark "CRC-32 (zlib)" -Z
|
|
59
|
+
) | sort_by_speed
|
|
60
|
+
|
|
61
|
+
# Adler-32
|
|
62
|
+
echo
|
|
63
|
+
(
|
|
64
|
+
if grep -q '\<avx2\>' /proc/cpuinfo; then
|
|
65
|
+
make checksum > /dev/null
|
|
66
|
+
do_benchmark "Adler-32 (libdeflate, AVX2)" -A
|
|
67
|
+
fi
|
|
68
|
+
sed -i '/^#if defined(__AVX2__)/,/^\#endif$/d' lib/adler32.c
|
|
69
|
+
make checksum > /dev/null
|
|
70
|
+
do_benchmark "Adler-32 (libdeflate, SSE2)" -A
|
|
71
|
+
sed -i '/^#ifdef __SSE2__/,/^\#endif$/d' lib/adler32.c
|
|
72
|
+
make checksum > /dev/null
|
|
73
|
+
do_benchmark "Adler-32 (libdeflate, generic)" -A
|
|
74
|
+
git checkout -f lib/adler32.c > /dev/null
|
|
75
|
+
do_benchmark "Adler-32 (zlib)" -A -Z
|
|
76
|
+
) | sort_by_speed
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Helper script used by run_tests.sh, not intended to be run directly
|
|
3
|
+
#
|
|
4
|
+
|
|
5
|
+
set -eu
|
|
6
|
+
|
|
7
|
+
run_cmd() {
|
|
8
|
+
echo "$WRAPPER $@"
|
|
9
|
+
$WRAPPER "$@" > /dev/null
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
run_cmd ./test_checksums
|
|
13
|
+
|
|
14
|
+
for format in '' '-g' '-z'; do
|
|
15
|
+
for ref_impl in '' '-Y' '-Z'; do
|
|
16
|
+
run_cmd ./benchmark $format $ref_impl $SMOKEDATA
|
|
17
|
+
done
|
|
18
|
+
done
|
|
19
|
+
for level in 1 3 7 9; do
|
|
20
|
+
for ref_impl in '' '-Y'; do
|
|
21
|
+
run_cmd ./benchmark -$level $ref_impl $SMOKEDATA
|
|
22
|
+
done
|
|
23
|
+
done
|
|
24
|
+
for level in 1 3 7 9 12; do
|
|
25
|
+
for ref_impl in '' '-Z'; do
|
|
26
|
+
run_cmd ./benchmark -$level $ref_impl $SMOKEDATA
|
|
27
|
+
done
|
|
28
|
+
done
|
|
29
|
+
|
|
30
|
+
echo "exec_tests finished successfully" # Needed for 'adb shell'
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* gen_crc32_multipliers.c
|
|
3
|
+
*
|
|
4
|
+
* Copyright 2016 Eric Biggers
|
|
5
|
+
*
|
|
6
|
+
* Permission is hereby granted, free of charge, to any person
|
|
7
|
+
* obtaining a copy of this software and associated documentation
|
|
8
|
+
* files (the "Software"), to deal in the Software without
|
|
9
|
+
* restriction, including without limitation the rights to use,
|
|
10
|
+
* copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
11
|
+
* copies of the Software, and to permit persons to whom the
|
|
12
|
+
* Software is furnished to do so, subject to the following
|
|
13
|
+
* conditions:
|
|
14
|
+
*
|
|
15
|
+
* The above copyright notice and this permission notice shall be
|
|
16
|
+
* included in all copies or substantial portions of the Software.
|
|
17
|
+
*
|
|
18
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
19
|
+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
|
20
|
+
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
21
|
+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|
22
|
+
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
23
|
+
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
24
|
+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
25
|
+
* OTHER DEALINGS IN THE SOFTWARE.
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
#include <inttypes.h>
|
|
29
|
+
#include <stdio.h>
|
|
30
|
+
|
|
31
|
+
/* generator polynomial G(x) */
|
|
32
|
+
#define CRCPOLY 0xEDB88320 /* G(x) without x^32 term */
|
|
33
|
+
#define CRCPOLY_FULL (((uint64_t)CRCPOLY << 1) | 1) /* G(x) */
|
|
34
|
+
|
|
35
|
+
/* Compute x^D mod G(x) */
|
|
36
|
+
static uint32_t
|
|
37
|
+
compute_multiplier(int D)
|
|
38
|
+
{
|
|
39
|
+
/* Start with x^0 mod G(x) */
|
|
40
|
+
uint32_t remainder = 0x80000000;
|
|
41
|
+
|
|
42
|
+
/* Each iteration, 'remainder' becomes x^i mod G(x) */
|
|
43
|
+
for (int i = 1; i <= D; i++)
|
|
44
|
+
remainder = (remainder >> 1) ^ ((remainder & 1) ? CRCPOLY : 0);
|
|
45
|
+
|
|
46
|
+
/* Now 'remainder' is x^D mod G(x) */
|
|
47
|
+
return remainder;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/* Compute floor(x^64 / G(x)) */
|
|
51
|
+
static uint64_t
|
|
52
|
+
compute_barrett_reduction_constant(void)
|
|
53
|
+
{
|
|
54
|
+
uint64_t quotient = 0;
|
|
55
|
+
uint64_t dividend = 0x1;
|
|
56
|
+
|
|
57
|
+
for (int i = 0; i < 64 - 32 + 1; i++) {
|
|
58
|
+
if ((dividend >> i) & 1) {
|
|
59
|
+
quotient |= (uint64_t)1 << i;
|
|
60
|
+
dividend ^= CRCPOLY_FULL << i;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return quotient;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/*
|
|
68
|
+
* This program computes the constant multipliers needed for carryless
|
|
69
|
+
* multiplication accelerated CRC-32. It assumes 128-bit vectors divided into
|
|
70
|
+
* two 64-bit halves which are multiplied separately with different 32-bit
|
|
71
|
+
* multipliers, producing two 95-bit products. For a given number of 128-bit
|
|
72
|
+
* vectors per iteration, the program outputs a pair of multipliers, one for
|
|
73
|
+
* each 64-bit half.
|
|
74
|
+
*
|
|
75
|
+
* Careful: all polynomials are "bit-reversed", meaning that the low-order bits
|
|
76
|
+
* have the highest degree and the high-order bits have the lowest degree!
|
|
77
|
+
*/
|
|
78
|
+
int
|
|
79
|
+
main(void)
|
|
80
|
+
{
|
|
81
|
+
printf("\t/* Constants precomputed by gen_crc32_multipliers.c. "
|
|
82
|
+
"Do not edit! */\n");
|
|
83
|
+
|
|
84
|
+
/* High and low multipliers for each needed vector count */
|
|
85
|
+
for (int order = 2; order >= 0; order--) {
|
|
86
|
+
int vecs_per_iteration = 1 << order;
|
|
87
|
+
int right = (128 * vecs_per_iteration) + 95;
|
|
88
|
+
printf("\tconst __v2di multipliers_%d = (__v2di)"
|
|
89
|
+
"{ 0x%08"PRIX32", 0x%08"PRIX32" };\n",
|
|
90
|
+
vecs_per_iteration,
|
|
91
|
+
compute_multiplier(right - 64) /* higher degree half */,
|
|
92
|
+
compute_multiplier(right - 128) /* lower degree half */);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/* Multiplier for final 96 => 64 bit fold */
|
|
96
|
+
printf("\tconst __v2di final_multiplier = (__v2di){ 0x%08"PRIX32" };\n",
|
|
97
|
+
compute_multiplier(63));
|
|
98
|
+
|
|
99
|
+
/* 32-bit mask */
|
|
100
|
+
printf("\tconst __m128i mask32 = (__m128i)(__v4si){ 0xFFFFFFFF };\n");
|
|
101
|
+
|
|
102
|
+
/* Constants for final 64 => 32 bit reduction */
|
|
103
|
+
printf("\tconst __v2di barrett_reduction_constants =\n"
|
|
104
|
+
"\t\t\t(__v2di){ 0x%016"PRIX64", 0x%016"PRIX64" };\n",
|
|
105
|
+
compute_barrett_reduction_constant(), CRCPOLY_FULL);
|
|
106
|
+
|
|
107
|
+
return 0;
|
|
108
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* gen_crc32_table.c - a program for CRC-32 table generation
|
|
3
|
+
*
|
|
4
|
+
* Originally public domain; changes after 2016-09-07 are copyrighted.
|
|
5
|
+
*
|
|
6
|
+
* Copyright 2016 Eric Biggers
|
|
7
|
+
*
|
|
8
|
+
* Permission is hereby granted, free of charge, to any person
|
|
9
|
+
* obtaining a copy of this software and associated documentation
|
|
10
|
+
* files (the "Software"), to deal in the Software without
|
|
11
|
+
* restriction, including without limitation the rights to use,
|
|
12
|
+
* copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
13
|
+
* copies of the Software, and to permit persons to whom the
|
|
14
|
+
* Software is furnished to do so, subject to the following
|
|
15
|
+
* conditions:
|
|
16
|
+
*
|
|
17
|
+
* The above copyright notice and this permission notice shall be
|
|
18
|
+
* included in all copies or substantial portions of the Software.
|
|
19
|
+
*
|
|
20
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
21
|
+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
|
22
|
+
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
23
|
+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|
24
|
+
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
25
|
+
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
26
|
+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
27
|
+
* OTHER DEALINGS IN THE SOFTWARE.
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
#include <stdint.h>
|
|
31
|
+
#include <stdio.h>
|
|
32
|
+
|
|
33
|
+
static uint32_t crc32_table[0x800];
|
|
34
|
+
|
|
35
|
+
static uint32_t
|
|
36
|
+
crc32_update_bit(uint32_t remainder, uint8_t next_bit)
|
|
37
|
+
{
|
|
38
|
+
return (remainder >> 1) ^
|
|
39
|
+
(((remainder ^ next_bit) & 1) ? 0xEDB88320 : 0);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
static uint32_t
|
|
43
|
+
crc32_update_byte(uint32_t remainder, uint8_t next_byte)
|
|
44
|
+
{
|
|
45
|
+
for (int j = 0; j < 8; j++, next_byte >>= 1)
|
|
46
|
+
remainder = crc32_update_bit(remainder, next_byte & 1);
|
|
47
|
+
return remainder;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
static void
|
|
51
|
+
print_256_entries(const uint32_t *entries)
|
|
52
|
+
{
|
|
53
|
+
for (size_t i = 0; i < 256 / 4; i++) {
|
|
54
|
+
printf("\t");
|
|
55
|
+
for (size_t j = 0; j < 4; j++) {
|
|
56
|
+
printf("0x%08x,", entries[i * 4 + j]);
|
|
57
|
+
if (j != 3)
|
|
58
|
+
printf(" ");
|
|
59
|
+
}
|
|
60
|
+
printf("\n");
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
int
|
|
65
|
+
main(void)
|
|
66
|
+
{
|
|
67
|
+
/* crc32_table[i] for 0 <= i < 0x100 is the CRC-32 of byte i. */
|
|
68
|
+
for (int i = 0; i < 0x100; i++)
|
|
69
|
+
crc32_table[i] = crc32_update_byte(0, i);
|
|
70
|
+
|
|
71
|
+
/* crc32_table[i] for 0x100 <= i < 0x800 is the CRC-32 of byte i % 0x100
|
|
72
|
+
* followed by i / 0x100 zero bytes. */
|
|
73
|
+
for (int i = 0x100; i < 0x800; i++)
|
|
74
|
+
crc32_table[i] = crc32_update_byte(crc32_table[i - 0x100], 0);
|
|
75
|
+
|
|
76
|
+
printf("/*\n");
|
|
77
|
+
printf(" * crc32_table.h - data table to accelerate CRC-32 computation\n");
|
|
78
|
+
printf(" *\n");
|
|
79
|
+
printf(" * THIS FILE WAS AUTOMATICALLY GENERATED "
|
|
80
|
+
"BY gen_crc32_table.c. DO NOT EDIT.\n");
|
|
81
|
+
printf(" */\n");
|
|
82
|
+
printf("\n");
|
|
83
|
+
printf("#include <stdint.h>\n");
|
|
84
|
+
printf("\n");
|
|
85
|
+
printf("static const uint32_t crc32_table[] = {\n");
|
|
86
|
+
print_256_entries(&crc32_table[0x000]);
|
|
87
|
+
printf("#if defined(CRC32_SLICE4) || defined(CRC32_SLICE8)\n");
|
|
88
|
+
print_256_entries(&crc32_table[0x100]);
|
|
89
|
+
print_256_entries(&crc32_table[0x200]);
|
|
90
|
+
print_256_entries(&crc32_table[0x300]);
|
|
91
|
+
printf("#endif /* CRC32_SLICE4 || CRC32_SLICE8 */\n");
|
|
92
|
+
printf("#if defined(CRC32_SLICE8)\n");
|
|
93
|
+
print_256_entries(&crc32_table[0x400]);
|
|
94
|
+
print_256_entries(&crc32_table[0x500]);
|
|
95
|
+
print_256_entries(&crc32_table[0x600]);
|
|
96
|
+
print_256_entries(&crc32_table[0x700]);
|
|
97
|
+
printf("#endif /* CRC32_SLICE8 */\n");
|
|
98
|
+
printf("};\n");
|
|
99
|
+
return 0;
|
|
100
|
+
}
|