Skip to content

Commit 37059ee

Browse files
committed
Add crc32 combination code from pigz
1 parent 65cb692 commit 37059ee

File tree

1 file changed

+87
-0
lines changed

1 file changed

+87
-0
lines changed

src/isal/crc32_combine.h

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
/* pigz.c -- parallel implementation of gzip
2+
* Copyright (C) 2007-2023 Mark Adler
3+
* Version 2.8 19 Aug 2023 Mark Adler
4+
*/
5+
6+
/*
7+
This software is provided 'as-is', without any express or implied
8+
warranty. In no event will the author be held liable for any damages
9+
arising from the use of this software.
10+
11+
Permission is granted to anyone to use this software for any purpose,
12+
including commercial applications, and to alter it and redistribute it
13+
freely, subject to the following restrictions:
14+
15+
1. The origin of this software must not be misrepresented; you must not
16+
claim that you wrote the original software. If you use this software
17+
in a product, an acknowledgment in the product documentation would be
18+
appreciated but is not required.
19+
2. Altered source versions must be plainly marked as such, and must not be
20+
misrepresented as being the original software.
21+
3. This notice may not be removed or altered from any source distribution.
22+
23+
Mark Adler
24+
25+
26+
*/
27+
28+
/*
29+
Alterations from original:
30+
- typedef for crc_t
31+
- local declarations replaced with static inline
32+
- g.block selector in crc32_comb removed
33+
*/
34+
35+
#include <stdint.h>
36+
#include <stddef.h>
37+
38+
typedef uint32_t crc_t;
39+
40+
// CRC-32 polynomial, reflected.
41+
#define POLY 0xedb88320
42+
43+
// Return a(x) multiplied by b(x) modulo p(x), where p(x) is the CRC
44+
// polynomial, reflected. For speed, this requires that a not be zero.
45+
static inline crc_t multmodp(crc_t a, crc_t b) {
46+
crc_t m = (crc_t)1 << 31;
47+
crc_t p = 0;
48+
for (;;) {
49+
if (a & m) {
50+
p ^= b;
51+
if ((a & (m - 1)) == 0)
52+
break;
53+
}
54+
m >>= 1;
55+
b = b & 1 ? (b >> 1) ^ POLY : b >> 1;
56+
}
57+
return p;
58+
}
59+
60+
// Table of x^2^n modulo p(x).
61+
static inline const crc_t x2n_table[] = {
62+
0x40000000, 0x20000000, 0x08000000, 0x00800000, 0x00008000,
63+
0xedb88320, 0xb1e6b092, 0xa06a2517, 0xed627dae, 0x88d14467,
64+
0xd7bbfe6a, 0xec447f11, 0x8e7ea170, 0x6427800e, 0x4d47bae0,
65+
0x09fe548f, 0x83852d0f, 0x30362f1a, 0x7b5a9cc3, 0x31fec169,
66+
0x9fec022a, 0x6c8dedc4, 0x15d6874d, 0x5fde7a4e, 0xbad90e37,
67+
0x2e4e5eef, 0x4eaba214, 0xa8a472c0, 0x429a969e, 0x148d302a,
68+
0xc40ba6d0, 0xc4e22c3c};
69+
70+
// Return x^(n*2^k) modulo p(x).
71+
static inline crc_t x2nmodp(size_t n, unsigned k) {
72+
crc_t p = (crc_t)1 << 31; // x^0 == 1
73+
while (n) {
74+
if (n & 1)
75+
p = multmodp(x2n_table[k & 31], p);
76+
n >>= 1;
77+
k++;
78+
}
79+
return p;
80+
}
81+
82+
// This uses the pre-computed g.shift value most of the time. Only the last
83+
// combination requires a new x2nmodp() calculation.
84+
static inline unsigned long crc32_comb(unsigned long crc1, unsigned long crc2,
85+
size_t len2) {
86+
return multmodp(x2nmodp(len2, 3), crc1) ^ crc2;
87+
}

0 commit comments

Comments
 (0)