mirror of
https://github.com/lammertb/libcrc.git
synced 2025-10-14 01:59:00 +08:00
Moved CRC64 LUT table calculation out of runtime
This commit is contained in:
5
.gitignore
vendored
5
.gitignore
vendored
@@ -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
|
||||
|
33
Makefile
33
Makefile
@@ -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
|
||||
|
||||
|
@@ -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
72
precalc/crc64_table.c
Normal 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
3
precalc/obj/README
Normal file
@@ -0,0 +1,3 @@
|
||||
#
|
||||
# Directory for object files
|
||||
#
|
150
precalc/precalc.c
Normal file
150
precalc/precalc.c
Normal 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
49
precalc/precalc.h
Normal 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];
|
48
src/crc64.c
48
src/crc64.c
@@ -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
3
tab/README
Normal file
@@ -0,0 +1,3 @@
|
||||
#
|
||||
# Directory for lookup table include files
|
||||
#
|
Reference in New Issue
Block a user