1 /* makecrct.c -- output crc32 tables
2 * Copyright (C) 1995-2006, 2010, 2011, 2012, 2016, 2018 Mark Adler
3 * For conditions of distribution and use, see copyright notice in zlib.h
4 */
5
6 #include <stdio.h>
7 #include <inttypes.h>
8 #include "zbuild.h"
9 #include "zutil.h"
10
11 /*
12 The crc32 table header file contains tables for both 32-bit and 64-bit
13 z_word_t's, and so requires a 64-bit type be available. In that case,
14 z_word_t must be defined to be 64-bits. This code then also generates
15 and writes out the tables for the case that z_word_t is 32 bits.
16 */
17
18 #define W 8 /* Need a 64-bit integer type in order to generate crc32 tables. */
19
20 #include "crc32_braid_p.h"
21
22 static uint32_t crc_table[256];
23 static z_word_t crc_big_table[256];
24
25 static uint32_t crc_braid_table[W][256];
26 static z_word_t crc_braid_big_table[W][256];
27 static uint32_t x2n_table[32];
28
29 #include "crc32_braid_comb_p.h"
30
31 static void make_crc_table(void);
32 static void print_crc_table(void);
33
34 static void braid(uint32_t ltl[][256], z_word_t big[][256], int n, int w);
35
36 static void write_table(const uint32_t *table, int k);
37 static void write_table32hi(const z_word_t *table, int k);
38 static void write_table64(const z_word_t *table, int k);
39
40 /* ========================================================================= */
41 /*
42 Generate tables for a byte-wise 32-bit CRC calculation on the polynomial:
43 x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1.
44
45 Polynomials over GF(2) are represented in binary, one bit per coefficient,
46 with the lowest powers in the most significant bit. Then adding polynomials
47 is just exclusive-or, and multiplying a polynomial by x is a right shift by
48 one. If we call the above polynomial p, and represent a byte as the
49 polynomial q, also with the lowest power in the most significant bit (so the
50 byte 0xb1 is the polynomial x^7+x^3+x^2+1), then the CRC is (q*x^32) mod p,
51 where a mod b means the remainder after dividing a by b.
52
53 This calculation is done using the shift-register method of multiplying and
54 taking the remainder. The register is initialized to zero, and for each
55 incoming bit, x^32 is added mod p to the register if the bit is a one (where
56 x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by x
57 (which is shifting right by one and adding x^32 mod p if the bit shifted out
58 is a one). We start with the highest power (least significant bit) of q and
59 repeat for all eight bits of q.
60
61 The table is simply the CRC of all possible eight bit values. This is all the
62 information needed to generate CRCs on data a byte at a time for all
63 combinations of CRC register values and incoming bytes.
64 */
make_crc_table()65 static void make_crc_table() {
66 unsigned i, j, n;
67 uint32_t p;
68
69 /* initialize the CRC of bytes tables */
70 for (i = 0; i < 256; i++) {
71 p = i;
72 for (j = 0; j < 8; j++)
73 p = p & 1 ? (p >> 1) ^ POLY : p >> 1;
74 crc_table[i] = p;
75 crc_big_table[i] = ZSWAP64(p);
76 }
77
78 /* initialize the x^2^n mod p(x) table */
79 p = (uint32_t)1 << 30; /* x^1 */
80 x2n_table[0] = p;
81 for (n = 1; n < 32; n++)
82 x2n_table[n] = p = multmodp(p, p);
83
84 /* initialize the braiding tables -- needs x2n_table[] */
85 braid(crc_braid_table, crc_braid_big_table, N, W);
86 }
87
88 /*
89 Generate the little and big-endian braid tables for the given n and z_word_t
90 size w. Each array must have room for w blocks of 256 elements.
91 */
braid(uint32_t ltl[][256],z_word_t big[][256],int n,int w)92 static void braid(uint32_t ltl[][256], z_word_t big[][256], int n, int w) {
93 int k;
94 uint32_t i, p, q;
95 for (k = 0; k < w; k++) {
96 p = x2nmodp((n * w + 3 - k) << 3, 0);
97 ltl[k][0] = 0;
98 big[w - 1 - k][0] = 0;
99 for (i = 1; i < 256; i++) {
100 ltl[k][i] = q = multmodp(i << 24, p);
101 big[w - 1 - k][i] = ZSWAP64(q);
102 }
103 }
104 }
105
106 /*
107 Write the 32-bit values in table[0..k-1] to out, five per line in
108 hexadecimal separated by commas.
109 */
write_table(const uint32_t * table,int k)110 static void write_table(const uint32_t *table, int k) {
111 int n;
112
113 for (n = 0; n < k; n++)
114 printf("%s0x%08" PRIx32 "%s", n == 0 || n % 5 ? "" : " ",
115 (uint32_t)(table[n]),
116 n == k - 1 ? "" : (n % 5 == 4 ? ",\n" : ", "));
117 }
118
119 /*
120 Write the high 32-bits of each value in table[0..k-1] to out, five per line
121 in hexadecimal separated by commas.
122 */
write_table32hi(const z_word_t * table,int k)123 static void write_table32hi(const z_word_t *table, int k) {
124 int n;
125
126 for (n = 0; n < k; n++)
127 printf("%s0x%08" PRIx32 "%s", n == 0 || n % 5 ? "" : " ",
128 (uint32_t)(table[n] >> 32),
129 n == k - 1 ? "" : (n % 5 == 4 ? ",\n" : ", "));
130 }
131
132 /*
133 Write the 64-bit values in table[0..k-1] to out, three per line in
134 hexadecimal separated by commas. This assumes that if there is a 64-bit
135 type, then there is also a long long integer type, and it is at least 64
136 bits. If not, then the type cast and format string can be adjusted
137 accordingly.
138 */
write_table64(const z_word_t * table,int k)139 static void write_table64(const z_word_t *table, int k) {
140 int n;
141
142 for (n = 0; n < k; n++)
143 printf("%s0x%016" PRIx64 "%s", n == 0 || n % 3 ? "" : " ",
144 (uint64_t)(table[n]),
145 n == k - 1 ? "" : (n % 3 == 2 ? ",\n" : ", "));
146 }
147
print_crc_table(void)148 static void print_crc_table(void) {
149 int k, n;
150 uint32_t ltl[8][256];
151 z_word_t big[8][256];
152
153 printf("#ifndef CRC32_BRAID_TBL_H_\n");
154 printf("#define CRC32_BRAID_TBL_H_\n\n");
155 printf("/* crc32_braid_tbl.h -- tables for braided CRC calculation\n");
156 printf(" * Generated automatically by makecrct.c\n */\n\n");
157
158 /* print little-endian CRC table */
159 printf("static const uint32_t crc_table[] = {\n");
160 printf(" ");
161 write_table(crc_table, 256);
162 printf("};\n\n");
163
164 /* print big-endian CRC table for 64-bit z_word_t */
165 printf("#ifdef W\n\n");
166 printf("#if W == 8\n\n");
167 printf("static const z_word_t crc_big_table[] = {\n");
168 printf(" ");
169 write_table64(crc_big_table, 256);
170 printf("};\n\n");
171
172 /* print big-endian CRC table for 32-bit z_word_t */
173 printf("#else /* W == 4 */\n\n");
174 printf("static const z_word_t crc_big_table[] = {\n");
175 printf(" ");
176 write_table32hi(crc_big_table, 256);
177 printf("};\n\n");
178 printf("#endif\n\n");
179 printf("#endif /* W */\n\n");
180
181 /* write out braid tables for each value of N */
182 for (n = 1; n <= 6; n++) {
183 printf("#if N == %d\n", n);
184
185 /* compute braid tables for this N and 64-bit word_t */
186 braid(ltl, big, n, 8);
187
188 /* write out braid tables for 64-bit z_word_t */
189 printf("\n");
190 printf("#if W == 8\n\n");
191 printf("static const uint32_t crc_braid_table[][256] = {\n");
192 for (k = 0; k < 8; k++) {
193 printf(" {");
194 write_table(ltl[k], 256);
195 printf("}%s", k < 7 ? ",\n" : "");
196 }
197 printf("};\n\n");
198 printf("static const z_word_t crc_braid_big_table[][256] = {\n");
199 for (k = 0; k < 8; k++) {
200 printf(" {");
201 write_table64(big[k], 256);
202 printf("}%s", k < 7 ? ",\n" : "");
203 }
204 printf("};\n");
205
206 /* compute braid tables for this N and 32-bit word_t */
207 braid(ltl, big, n, 4);
208
209 /* write out braid tables for 32-bit z_word_t */
210 printf("\n");
211 printf("#else /* W == 4 */\n\n");
212 printf("static const uint32_t crc_braid_table[][256] = {\n");
213 for (k = 0; k < 4; k++) {
214 printf(" {");
215 write_table(ltl[k], 256);
216 printf("}%s", k < 3 ? ",\n" : "");
217 }
218 printf("};\n\n");
219 printf("static const z_word_t crc_braid_big_table[][256] = {\n");
220 for (k = 0; k < 4; k++) {
221 printf(" {");
222 write_table32hi(big[k], 256);
223 printf("}%s", k < 3 ? ",\n" : "");
224 }
225 printf("};\n\n");
226 printf("#endif /* W */\n\n");
227
228 printf("#endif /* N == %d */\n", n);
229 }
230 printf("\n");
231
232 /* write out zeros operator table */
233 printf("static const uint32_t x2n_table[] = {\n");
234 printf(" ");
235 write_table(x2n_table, 32);
236 printf("};\n");
237
238 printf("\n");
239 printf("#endif /* CRC32_BRAID_TBL_H_ */\n");
240 }
241
242 // The output of this application can be piped out to recreate crc32 tables
main(int argc,char * argv[])243 int main(int argc, char *argv[]) {
244 Z_UNUSED(argc);
245 Z_UNUSED(argv);
246
247 make_crc_table();
248 print_crc_table();
249 return 0;
250 }
251