151d12cebb61ca00f5455fe6e25938cd79fea15abTheodore Ts'o/*
251d12cebb61ca00f5455fe6e25938cd79fea15abTheodore Ts'o * gen_crc32table.c --- Generate CRC32 tables.
351d12cebb61ca00f5455fe6e25938cd79fea15abTheodore Ts'o *
451d12cebb61ca00f5455fe6e25938cd79fea15abTheodore Ts'o * Copyright (C) 2008 Theodore Ts'o.
551d12cebb61ca00f5455fe6e25938cd79fea15abTheodore Ts'o *
651d12cebb61ca00f5455fe6e25938cd79fea15abTheodore Ts'o * %Begin-Header%
751d12cebb61ca00f5455fe6e25938cd79fea15abTheodore Ts'o * This file may be redistributed under the terms of the GNU Public
851d12cebb61ca00f5455fe6e25938cd79fea15abTheodore Ts'o * License.
951d12cebb61ca00f5455fe6e25938cd79fea15abTheodore Ts'o * %End-Header%
1051d12cebb61ca00f5455fe6e25938cd79fea15abTheodore Ts'o */
1151d12cebb61ca00f5455fe6e25938cd79fea15abTheodore Ts'o
1251d12cebb61ca00f5455fe6e25938cd79fea15abTheodore Ts'o#include <stdio.h>
1351d12cebb61ca00f5455fe6e25938cd79fea15abTheodore Ts'o#include "crc32defs.h"
1451d12cebb61ca00f5455fe6e25938cd79fea15abTheodore Ts'o#include <inttypes.h>
1551d12cebb61ca00f5455fe6e25938cd79fea15abTheodore Ts'o
1651d12cebb61ca00f5455fe6e25938cd79fea15abTheodore Ts'o#define ENTRIES_PER_LINE 4
1751d12cebb61ca00f5455fe6e25938cd79fea15abTheodore Ts'o
1851d12cebb61ca00f5455fe6e25938cd79fea15abTheodore Ts'o#define LE_TABLE_SIZE (1 << CRC_LE_BITS)
1951d12cebb61ca00f5455fe6e25938cd79fea15abTheodore Ts'o#define BE_TABLE_SIZE (1 << CRC_BE_BITS)
2051d12cebb61ca00f5455fe6e25938cd79fea15abTheodore Ts'o
2151d12cebb61ca00f5455fe6e25938cd79fea15abTheodore Ts'ostatic uint32_t crc32table_le[LE_TABLE_SIZE];
2251d12cebb61ca00f5455fe6e25938cd79fea15abTheodore Ts'ostatic uint32_t crc32table_be[BE_TABLE_SIZE];
2351d12cebb61ca00f5455fe6e25938cd79fea15abTheodore Ts'o
2451d12cebb61ca00f5455fe6e25938cd79fea15abTheodore Ts'o/**
2551d12cebb61ca00f5455fe6e25938cd79fea15abTheodore Ts'o * crc32init_le() - allocate and initialize LE table data
2651d12cebb61ca00f5455fe6e25938cd79fea15abTheodore Ts'o *
2751d12cebb61ca00f5455fe6e25938cd79fea15abTheodore Ts'o * crc is the crc of the byte i; other entries are filled in based on the
2851d12cebb61ca00f5455fe6e25938cd79fea15abTheodore Ts'o * fact that crctable[i^j] = crctable[i] ^ crctable[j].
2951d12cebb61ca00f5455fe6e25938cd79fea15abTheodore Ts'o *
3051d12cebb61ca00f5455fe6e25938cd79fea15abTheodore Ts'o */
3151d12cebb61ca00f5455fe6e25938cd79fea15abTheodore Ts'ostatic void crc32init_le(void)
3251d12cebb61ca00f5455fe6e25938cd79fea15abTheodore Ts'o{
3351d12cebb61ca00f5455fe6e25938cd79fea15abTheodore Ts'o	unsigned i, j;
3451d12cebb61ca00f5455fe6e25938cd79fea15abTheodore Ts'o	uint32_t crc = 1;
3551d12cebb61ca00f5455fe6e25938cd79fea15abTheodore Ts'o
3651d12cebb61ca00f5455fe6e25938cd79fea15abTheodore Ts'o	crc32table_le[0] = 0;
3751d12cebb61ca00f5455fe6e25938cd79fea15abTheodore Ts'o
3851d12cebb61ca00f5455fe6e25938cd79fea15abTheodore Ts'o	for (i = 1 << (CRC_LE_BITS - 1); i; i >>= 1) {
3951d12cebb61ca00f5455fe6e25938cd79fea15abTheodore Ts'o		crc = (crc >> 1) ^ ((crc & 1) ? CRCPOLY_LE : 0);
4051d12cebb61ca00f5455fe6e25938cd79fea15abTheodore Ts'o		for (j = 0; j < LE_TABLE_SIZE; j += 2 * i)
4151d12cebb61ca00f5455fe6e25938cd79fea15abTheodore Ts'o			crc32table_le[i + j] = crc ^ crc32table_le[j];
4251d12cebb61ca00f5455fe6e25938cd79fea15abTheodore Ts'o	}
4351d12cebb61ca00f5455fe6e25938cd79fea15abTheodore Ts'o}
4451d12cebb61ca00f5455fe6e25938cd79fea15abTheodore Ts'o
4551d12cebb61ca00f5455fe6e25938cd79fea15abTheodore Ts'o/**
4651d12cebb61ca00f5455fe6e25938cd79fea15abTheodore Ts'o * crc32init_be() - allocate and initialize BE table data
4751d12cebb61ca00f5455fe6e25938cd79fea15abTheodore Ts'o */
4851d12cebb61ca00f5455fe6e25938cd79fea15abTheodore Ts'ostatic void crc32init_be(void)
4951d12cebb61ca00f5455fe6e25938cd79fea15abTheodore Ts'o{
5051d12cebb61ca00f5455fe6e25938cd79fea15abTheodore Ts'o	unsigned i, j;
5151d12cebb61ca00f5455fe6e25938cd79fea15abTheodore Ts'o	uint32_t crc = 0x80000000;
5251d12cebb61ca00f5455fe6e25938cd79fea15abTheodore Ts'o
5351d12cebb61ca00f5455fe6e25938cd79fea15abTheodore Ts'o	crc32table_be[0] = 0;
5451d12cebb61ca00f5455fe6e25938cd79fea15abTheodore Ts'o
5551d12cebb61ca00f5455fe6e25938cd79fea15abTheodore Ts'o	for (i = 1; i < BE_TABLE_SIZE; i <<= 1) {
5651d12cebb61ca00f5455fe6e25938cd79fea15abTheodore Ts'o		crc = (crc << 1) ^ ((crc & 0x80000000) ? CRCPOLY_BE : 0);
5751d12cebb61ca00f5455fe6e25938cd79fea15abTheodore Ts'o		for (j = 0; j < i; j++)
5851d12cebb61ca00f5455fe6e25938cd79fea15abTheodore Ts'o			crc32table_be[i + j] = crc ^ crc32table_be[j];
5951d12cebb61ca00f5455fe6e25938cd79fea15abTheodore Ts'o	}
6051d12cebb61ca00f5455fe6e25938cd79fea15abTheodore Ts'o}
6151d12cebb61ca00f5455fe6e25938cd79fea15abTheodore Ts'o
6251d12cebb61ca00f5455fe6e25938cd79fea15abTheodore Ts'ostatic void output_table(uint32_t table[], int len, const char *trans)
6351d12cebb61ca00f5455fe6e25938cd79fea15abTheodore Ts'o{
6451d12cebb61ca00f5455fe6e25938cd79fea15abTheodore Ts'o	int i;
6551d12cebb61ca00f5455fe6e25938cd79fea15abTheodore Ts'o
6651d12cebb61ca00f5455fe6e25938cd79fea15abTheodore Ts'o	for (i = 0; i < len - 1; i++) {
6751d12cebb61ca00f5455fe6e25938cd79fea15abTheodore Ts'o		if (i % ENTRIES_PER_LINE == 0)
6851d12cebb61ca00f5455fe6e25938cd79fea15abTheodore Ts'o			printf("\n");
6951d12cebb61ca00f5455fe6e25938cd79fea15abTheodore Ts'o		printf("%s(0x%8.8xL), ", trans, table[i]);
7051d12cebb61ca00f5455fe6e25938cd79fea15abTheodore Ts'o	}
7151d12cebb61ca00f5455fe6e25938cd79fea15abTheodore Ts'o	printf("%s(0x%8.8xL)\n", trans, table[len - 1]);
7251d12cebb61ca00f5455fe6e25938cd79fea15abTheodore Ts'o}
7351d12cebb61ca00f5455fe6e25938cd79fea15abTheodore Ts'o
742acad6b4895a0e218f9d9eece1ade23c2cf4ffc7Theodore Ts'o#ifdef __GNUC__
752acad6b4895a0e218f9d9eece1ade23c2cf4ffc7Theodore Ts'o#define ATTR(x) __attribute__(x)
762acad6b4895a0e218f9d9eece1ade23c2cf4ffc7Theodore Ts'o#else
772acad6b4895a0e218f9d9eece1ade23c2cf4ffc7Theodore Ts'o#define ATTR(x)
782acad6b4895a0e218f9d9eece1ade23c2cf4ffc7Theodore Ts'o#endif
792acad6b4895a0e218f9d9eece1ade23c2cf4ffc7Theodore Ts'o
802acad6b4895a0e218f9d9eece1ade23c2cf4ffc7Theodore Ts'oint main(int argc ATTR((unused)), char** argv ATTR((unused)))
8151d12cebb61ca00f5455fe6e25938cd79fea15abTheodore Ts'o{
8251d12cebb61ca00f5455fe6e25938cd79fea15abTheodore Ts'o	printf("/* this file is generated - do not edit */\n\n");
8351d12cebb61ca00f5455fe6e25938cd79fea15abTheodore Ts'o
8451d12cebb61ca00f5455fe6e25938cd79fea15abTheodore Ts'o	printf("#ifdef UNITTEST\n");
8551d12cebb61ca00f5455fe6e25938cd79fea15abTheodore Ts'o	if (CRC_LE_BITS > 1) {
8651d12cebb61ca00f5455fe6e25938cd79fea15abTheodore Ts'o		crc32init_le();
8751d12cebb61ca00f5455fe6e25938cd79fea15abTheodore Ts'o		printf("static const __u32 crc32table_le[] = {");
8851d12cebb61ca00f5455fe6e25938cd79fea15abTheodore Ts'o		output_table(crc32table_le, LE_TABLE_SIZE, "tole");
8951d12cebb61ca00f5455fe6e25938cd79fea15abTheodore Ts'o		printf("};\n");
9051d12cebb61ca00f5455fe6e25938cd79fea15abTheodore Ts'o	}
9151d12cebb61ca00f5455fe6e25938cd79fea15abTheodore Ts'o	printf("#endif /* UNITTEST */\n");
9251d12cebb61ca00f5455fe6e25938cd79fea15abTheodore Ts'o
9351d12cebb61ca00f5455fe6e25938cd79fea15abTheodore Ts'o	if (CRC_BE_BITS > 1) {
9451d12cebb61ca00f5455fe6e25938cd79fea15abTheodore Ts'o		crc32init_be();
9551d12cebb61ca00f5455fe6e25938cd79fea15abTheodore Ts'o		printf("static const __u32 crc32table_be[] = {");
9651d12cebb61ca00f5455fe6e25938cd79fea15abTheodore Ts'o		output_table(crc32table_be, BE_TABLE_SIZE, "tobe");
9751d12cebb61ca00f5455fe6e25938cd79fea15abTheodore Ts'o		printf("};\n");
9851d12cebb61ca00f5455fe6e25938cd79fea15abTheodore Ts'o	}
9951d12cebb61ca00f5455fe6e25938cd79fea15abTheodore Ts'o
10051d12cebb61ca00f5455fe6e25938cd79fea15abTheodore Ts'o	return 0;
10151d12cebb61ca00f5455fe6e25938cd79fea15abTheodore Ts'o}
102