Moved CRC64 LUT table calculation out of runtime

This commit is contained in:
lammertb
2016-12-04 14:52:15 +01:00
parent d948b50516
commit 48d1147178
9 changed files with 324 additions and 45 deletions

5
.gitignore vendored
View File

@@ -8,8 +8,13 @@ test/obj/*.obj
test/obj/*.o
examples/obj/*.obj
examples/obj/*.o
precalc/obj/*.obj
precalc/obj/*.o
tab/*.inc
make.exe
testall.exe
testall
tstcrc.exe
tstcrc
precalc.exe
precalc

View File

@@ -58,10 +58,12 @@
ifeq ($(OS),Windows_NT)
GENDIR = precalc\\
INCDIR = include\\
LIBDIR = lib\\
OBJDIR = obj\\
SRCDIR = src\\
TABDIR = tab\\
TSTDIR = test\\
EXADIR = examples\\
@@ -83,10 +85,12 @@ CFLAGS = -Ox -Ot -MT -GT -volatile:iso -I${INCDIR} -nologo -J -sdl -Wall -WX \
else
GENDIR = precalc/
INCDIR = include/
LIBDIR = lib/
OBJDIR = obj/
SRCDIR = src/
TABDIR = tab/
TSTDIR = test/
EXADIR = examples/
@@ -119,6 +123,9 @@ ${OBJDIR}%${OBJEXT} : ${SRCDIR}%.c
${TSTDIR}${OBJDIR}%${OBJEXT} : ${TSTDIR}%.c
${CC} -c ${CFLAGS} ${OFLAG}$@ $<
${GENDIR}${OBJDIR}%${OBJEXT} : ${GENDIR}%.c
${CC} -c ${CFLAGS} ${OFLAG}$@ $<
${EXADIR}${OBJDIR}%${OBJEXT} : ${EXADIR}%.c
${CC} -c ${CFLAGS} ${OFLAG}$@ $<
@@ -139,9 +146,12 @@ all: \
clean:
${RM} ${OBJDIR}*${OBJEXT}
${RM} ${TABDIR}*.inc
${RM} ${EXADIR}${OBJDIR}*${OBJEXT}
${RM} ${TSTDIR}${OBJDIR}*${OBJEXT}
${RM} ${GENDIR}${OBJDIR}*${OBJEXT}
${RM} ${LIBDIR}libcrc${LIBEXT}
${RM} precalc${EXEEXT}
${RM} testall${EXEEXT}
${RM} tstcrc${EXEEXT}
@@ -163,6 +173,20 @@ testall${EXEEXT} : \
${LIBDIR}libcrc${LIBEXT}
${STRIP} testall${EXEEXT}
#
# The precalc program is used during compilation to generate the lookup tables
# for the CRC calculation routines.
#
precalc${EXEEXT} : \
${GENDIR}${OBJDIR}precalc${OBJEXT} \
${GENDIR}${OBJDIR}crc64_table${OBJEXT} \
Makefile
${LINK} ${XFLAG}precalc${EXEEXT} \
${GENDIR}${OBJDIR}precalc${OBJEXT} \
${GENDIR}${OBJDIR}crc64_table${OBJEXT}
${STRIP} precalc${EXEEXT}
#
# The tstcrc program can be run to calculate the CRC values of manual input or
# of the contents of one or more files.
@@ -205,6 +229,13 @@ ${LIBDIR}libcrc${LIBEXT} : \
${AR} ${ARQ} ${LIBDIR}libcrc${LIBEXT} ${OBJDIR}nmea-chk${OBJEXT}
${RANLIB} ${LIBDIR}libcrc${LIBEXT}
#
# Lookup table include file dependencies
#
${TABDIR}gentab64.inc : precalc${EXEEXT}
precalc --crc64 ${TABDIR}gentab64.inc
#
# Individual source files with their header file dependencies
#
@@ -215,7 +246,7 @@ ${OBJDIR}crc16${OBJEXT} : ${SRCDIR}crc16.c ${INCDIR}checksum.h
${OBJDIR}crc32${OBJEXT} : ${SRCDIR}crc32.c ${INCDIR}checksum.h
${OBJDIR}crc64${OBJEXT} : ${SRCDIR}crc64.c ${INCDIR}checksum.h
${OBJDIR}crc64${OBJEXT} : ${SRCDIR}crc64.c ${INCDIR}checksum.h ${TABDIR}gentab64.inc
${OBJDIR}crcccitt${OBJEXT} : ${SRCDIR}crcccitt.c ${INCDIR}checksum.h

View File

@@ -97,4 +97,10 @@ uint16_t update_crc_dnp( uint16_t crc, unsigned char c
uint16_t update_crc_kermit( uint16_t crc, unsigned char c );
uint16_t update_crc_sick( uint16_t crc, unsigned char c, unsigned char prev_byte );
/*
* Global CRC lookup tables
*/
extern const uint64_t crc64_tab[];
#endif // DEF_LIBCRC_CHECKSUM_H

72
precalc/crc64_table.c Normal file
View File

@@ -0,0 +1,72 @@
/*
* Library: libcrc
* File: precalc/crc64_table.c
* Author: Lammert Bies
*
* This file is licensed under the MIT License as stated below
*
* Copyright (c) 2016 Lammert Bies
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Description
* -----------
* The source file precalc/crc64_table.c contains the routines which are needed
* to generate the lookup table for 64 bit CRC calculations.
*/
#include <stdbool.h>
#include <stdlib.h>
#include "checksum.h"
uint64_t crc_tab64_precalc[256];
/*
* void init_crc64_tab( void );
*
* For optimal speed, the CRC64 calculation uses a table with pre-calculated
* bit patterns which are used in the XOR operations in the program. This table
* is generated during compilation of the library and added to the library as a
* table with constant values.
*/
void init_crc64_tab( void ) {
uint64_t i;
uint64_t j;
uint64_t c;
uint64_t crc;
for (i=0; i<256; i++) {
crc = 0;
c = i << 56;
for (j=0; j<8; j++) {
if ( ( crc ^ c ) & 0x8000000000000000ull ) crc = ( crc << 1 ) ^ CRC_POLY_64;
else crc = crc << 1;
c = c << 1;
}
crc_tab64_precalc[i] = crc;
}
} /* init_crc64_tab */

3
precalc/obj/README Normal file
View File

@@ -0,0 +1,3 @@
#
# Directory for object files
#

150
precalc/precalc.c Normal file
View File

@@ -0,0 +1,150 @@
/*
* Library: libcrc
* File: precalc/precalc.c
* Author: Lammert Bies
*
* This file is licensed under the MIT License as stated below
*
* Copyright (c) 2008-2016 Lammert Bies
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Description
* -----------
* The source file precalc/precalc.c contains routines to generate the lookup
* tables for the CRC values at compile time. The tables are stored in include
* files which are then included by the CRC routine source files
*/
#include <inttypes.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "precalc.h"
#define TYPE_CRC64 1
static int generate_table( const char *typename, const char *filename );
/*
* int main( int argc, char *argv[] );
*
* Precalc is a commandline utility that is called from the Makefile to
* generate the lookup tables for the CRC routines. Generating these tables at
* compile time is much more efficient than doing it at runtime. Most compilers
* will be able to optimize the routines more when the tables are guaranteerd
* to be constant than when they have been generated on the fly as variable
* tables.
*/
int main( int argc, char *argv[] ) {
int retval;
if ( argc != 3 ) {
fprintf( stderr, "\nusage: precalc --type file\n" );
fprintf( stderr, " where --type is any of --crc64\n\n" );
exit( 1 );
}
retval = generate_table( argv[1], argv[2] );
exit( retval );
} /* main (libcrc precalc) */
/*
* static int generate_table( const char *typename, const char *filename );
*
* The function generate_table() generates a CRC lookup table of a specified
* type and stores the generated output in a file. If the function succeeds the
* value 0 is returned. Another value is an indication of failure and that
* value is used as the exit value of the program.
*/
static int generate_table( const char *typename, const char *filename ) {
int a;
int type;
FILE *fp;
const char *tabname;
if ( typename == NULL || filename == NULL ) {
fprintf( stderr, "\nprecalc: Internal pointer error\n\n" );
return 2;
}
if ( ! strcmp( typename, "--crc64" ) ) type = TYPE_CRC64;
else {
fprintf( stderr, "\nprecalc: Unknown table type \"%s\" passed\n\n", typename );
return 3;
}
tabname = NULL;
switch ( type ) {
case TYPE_CRC64 : init_crc64_tab(); tabname = "crc_tab64"; break;
}
#if defined(_MSC_VER)
fp = NULL;
fopen_s( &fp, filename, "w" );
#else
fp = fopen( filename, "w" );
#endif
if ( fp == NULL ) {
fprintf( stderr, "\nprecalc: cannot open \"%s\" for writing\n\n", filename );
return 0;
}
fprintf( fp, "/*\n" );
fprintf( fp, " * Library: libcrc\n" );
fprintf( fp, " * File: %s\n", filename );
fprintf( fp, " * Author: Auto generated by the precalc program\n" );
fprintf( fp, " *\n" );
fprintf( fp, " * PLEASE DO NOT CHANGE THIS FILE!\n" );
fprintf( fp, " * ===============================\n" );
fprintf( fp, " * This file was automatically generated and will be overwritten whenever the\n" );
fprintf( fp, " * library is recompiled. All manually added changes will be lost in that case.\n" );
fprintf( fp, " */\n\n" );
fprintf( fp, "const uint64_t %s[256] = {\n", tabname );
for (a=0; a<256; a++) {
fprintf( fp, "\t0x%016" PRIX64, crc_tab64_precalc[a] );
if ( a < 255 ) fprintf( fp, ",\n" );
else fprintf( fp, "\n" );
}
fprintf( fp, "};\n\n" );
fclose( fp );
return 0;
} /* generate_table */

49
precalc/precalc.h Normal file
View File

@@ -0,0 +1,49 @@
/*
* Library: libcrc
* File: precalc/precalc.h
* Author: Lammert Bies
*
* This file is licensed under the MIT License as stated below
*
* Copyright (c) 2008-2016 Lammert Bies
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Description
* -----------
* The source file precalc/precalc.h contains definitions and prototypes that
* are used by the precalc program which calculates the static lookup tables
* for the several CRC algorithms in the library.
*/
#include <stdbool.h>
#include <stdint.h>
/*
* Global functions used in the precalc program
*/
void init_crc64_tab( void );
int main( int argc, char *argv[] );
/*
* Global variables used in the precalc program
*/
extern uint64_t crc_tab64_precalc[256];

View File

@@ -35,10 +35,11 @@
#include <stdlib.h>
#include "checksum.h"
static void init_crc64_tab( void );
/*
* Include the lookup table for the CRC 64 calculation
*/
static bool crc_tab64_init = false;
static uint64_t crc_tab64[256];
#include "../tab/gentab64.inc"
/*
* uint64_t crc_64_ecma( const unsigned char *input_str, size_t num_bytes );
@@ -54,8 +55,6 @@ uint64_t crc_64_ecma( const unsigned char *input_str, size_t num_bytes ) {
const unsigned char *ptr;
size_t a;
if ( ! crc_tab64_init ) init_crc64_tab();
crc = CRC_START_64_ECMA;
ptr = input_str;
@@ -82,8 +81,6 @@ uint64_t crc_64_we( const unsigned char *input_str, size_t num_bytes ) {
const unsigned char *ptr;
size_t a;
if ( ! crc_tab64_init ) init_crc64_tab();
crc = CRC_START_64_WE;
ptr = input_str;
@@ -105,43 +102,6 @@ uint64_t crc_64_we( const unsigned char *input_str, size_t num_bytes ) {
uint64_t update_crc_64( uint64_t crc, unsigned char c ) {
if ( ! crc_tab64_init ) init_crc64_tab();
return (crc << 8) ^ crc_tab64[ ((crc >> 56) ^ (uint64_t) c) & 0x00000000000000FFull ];
} /* update_crc_64 */
/*
* static void init_crc64_tab( void );
*
* For optimal speed, the CRC64 calculation uses a table with pre-calculated
* bit patterns which are used in the XOR operations in the program. This table
* is generated once, the first time the CRC update routine is called.
*/
static void init_crc64_tab( void ) {
uint64_t i;
uint64_t j;
uint64_t c;
uint64_t crc;
for (i=0; i<256; i++) {
crc = 0;
c = i << 56;
for (j=0; j<8; j++) {
if ( ( crc ^ c ) & 0x8000000000000000ull ) crc = ( crc << 1 ) ^ CRC_POLY_64;
else crc = crc << 1;
c = c << 1;
}
crc_tab64[i] = crc;
}
crc_tab64_init = true;
} /* init_crc64_tab */

3
tab/README Normal file
View File

@@ -0,0 +1,3 @@
#
# Directory for lookup table include files
#