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