libdeflate 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
}
|