2 cc --std=c23
"$0" -O3 -o
"$0.out"
21const char *capitalise(
const char *str) {
24 while (i < 64 && i < strlen(str)) {
25 ret[i] = toupper(str[i]);
32#define TABLE_LEN(details) ((details).bits >= 8 ? 256u : 1u << (details).bits)
33#define MASK(details) ((details).bits == 64 ? ~UINT64_C(0) : (UINT64_C(1) << (details).bits) - UINT64_C(1))
34#define HIGH_BIT(details) (UINT64_C(1) << ((details).bits - 1))
35#define HIGH_BYTE_OFFSET(details) ((details).bits - 8)
36#define TYPE_NAME(details) (\
37 (details).bits > 32 ? "uint64_t" :\
38 (details).bits > 16 ? "uint32_t" :\
39 (details).bits > 8 ? "uint16_t" :\
42#define LITERAL_WRAPPER(details) (\
43 (details).bits > 32 ? "UINT64_C" :\
44 (details).bits > 16 ? "UINT32_C" :\
45 (details).bits > 8 ? "UINT16_C" :\
49uint64_t reflect(
const uint64_t n,
const uint8_t bits) {
51 for (uint8_t i = 0; i < bits; i++) {
52 r |= (n >> i & 1) << (bits - i - 1);
56 return r & ((UINT64_C(1) << bits) - 1);
58void table_gen(uint64_t *table,
const struct crc_details details) {
59 const uint64_t polynomial = details.polynomial & MASK(details);
62 for (uint64_t i = 0; i < TABLE_LEN(details); i++) {
64 crc = reflect(i, details.bits);
66 crc = i << HIGH_BYTE_OFFSET(details);
68 for (
int bit = 0; bit < 8; bit++) {
69 if (crc & HIGH_BIT(details))
70 crc = crc << 1 ^ polynomial;
76 table[i] = reflect(crc, details.bits);
78 table[i] = crc & MASK(details);
81void power_table_gen(uint64_t *table, uint8_t bits,
const struct crc_details details) {
82 uint64_t power = (details.bits <= 8) ? details.polynomial : 0x100;
83 for (uint8_t i = 0; i < bits; i++) {
85 uint64_t n = power, res = 0;
86 for (uint64_t j = 0; j < details.bits; j++) {
87 if (power & (UINT64_C(1) << j))
89 if (n & HIGH_BIT(details))
90 n = (n << 1) ^ details.polynomial;
98void inverse_table_gen(uint64_t *table,
const struct crc_details details) {
103void write_details(
const struct crc_details details) {
104 const char *caps = capitalise(details.name);
105 printf(
"#define %s_BITS %d\n", caps, details.bits);
106 printf(
"#define %s_POLYNOMIAL %s(0x%"PRIX64
")\n", caps, LITERAL_WRAPPER(details), details.polynomial);
107 printf(
"#define %s_NORMALISED_POLYNOMIAL %s(0x%"PRIX64
")\n",
108 caps, LITERAL_WRAPPER(details), details.reflect ? reflect(details.polynomial, details.bits) : details.polynomial);
109 printf(
"#define %s_REFLECTED %s\n", caps, details.reflect ?
"true" :
"false");
111void write_table(
const uint64_t *table,
size_t table_len,
const char *suffix,
const struct crc_details details) {
112 printf(
"static constexpr %s %s_%s[%"PRIu64
"] = {\n\t", TYPE_NAME(details), details.name, suffix, (uint64_t)table_len);
113 for (
size_t i = 0; i < table_len; i++) {
114 printf(
"%s(0x%" PRIX64
"),", LITERAL_WRAPPER(details), table[i]);
115 if (i != table_len - 1) {
130 .polynomial = UINT64_C(0x42F0E1EBA9EA3693),
136 .polynomial = UINT64_C(0x1EDC6F41),
142 .polynomial = UINT64_C(0x864CFB),
148 .polynomial = UINT64_C(0x1021),
154 .polynomial = UINT64_C(0x07),
158 constexpr size_t details_len =
sizeof(details)/
sizeof(details[0]);
161 printf(
"// generated by "__FILE__
"\n");
162 printf(
"#ifndef LIBCLOD_CRC_TABLES_H\n");
163 printf(
"#define LIBCLOD_CRC_TABLES_H\n");
164 printf(
"#include <stdint.h>\n\n");
165 for (
unsigned i = 0; i < details_len; i++) {
166 write_details(details[i]);
168 table_gen(table, details[i]);
169 write_table(table, 256,
"table", details[i]);
171 power_table_gen(table, 64, details[i]);
172 write_table(table, 64,
"power_table", details[i]);
174 if (i != details_len - 1) printf(
"\n");