// Copyright 2025 Don MacAskill. Licensed under MIT or Apache-2.0. //! Utility to generate pre-computed 16-lane lookup tables for all CRC algorithms. //! //! This generates Rust source code that can be used to create the `src/tables.rs` module. //! Run with: `cargo run --bin generate_tables > src/tables.rs` use crc_fast::arch::software::{generate_table_u16, generate_table_u32, generate_table_u64}; fn main() { println!("// Copyright 2025 Don MacAskill. Licensed under MIT or Apache-2.0."); println!(); println!("//! Pre-generated 16-lane lookup tables for CRC calculations."); println!("//!"); println!("//! This file is auto-generated by `cargo run --bin generate_tables`."); println!("//! Do not edit manually."); println!(); println!("#![allow(dead_code)]"); println!(); generate_crc16_tables(); generate_crc32_tables(); generate_crc64_tables(); } fn generate_crc16_tables() { println!("pub mod crc16 {{"); println!(" //! CRC-16 lookup tables"); println!(); // CRC-16 algorithms with their parameters: (name, poly, reflect) let algorithms: &[(&str, u16, bool)] = &[ ("ARC", 0x8005, true), ("CDMA2000", 0xc867, false), ("CMS", 0x8005, false), ("DDS_110", 0x8005, false), ("DECT_R", 0x0589, false), ("DECT_X", 0x0589, false), ("DNP", 0x3d65, true), ("EN_13757", 0x3d65, false), ("GENIBUS", 0x1021, false), ("GSM", 0x1021, false), ("IBM_3740", 0x1021, false), ("IBM_SDLC", 0x1021, true), ("ISO_IEC_14443_3_A", 0x1021, true), ("KERMIT", 0x1021, true), ("LJ1200", 0x6f63, false), ("M17", 0x5935, false), ("MAXIM_DOW", 0x8005, true), ("MCRF4XX", 0x1021, true), ("MODBUS", 0x8005, true), ("NRSC_5", 0x080b, true), ("OPENSAFETY_A", 0x5935, false), ("OPENSAFETY_B", 0x755b, false), ("PROFIBUS", 0x1dcf, false), ("RIELLO", 0x1021, true), ("SPI_FUJITSU", 0x1021, false), ("T10_DIF", 0x8bb7, false), ("TELEDISK", 0xa097, false), ("TMS37157", 0x1021, true), ("UMTS", 0x8005, false), ("USB", 0x8005, true), ("XMODEM", 0x1021, false), ]; for (name, poly, reflect) in algorithms { print_table_u16(name, 16, *poly, *reflect); } println!("}}"); println!(); } fn generate_crc32_tables() { println!("pub mod crc32 {{"); println!(" //! CRC-32 lookup tables"); println!(); // CRC-32 algorithms with their parameters: (name, poly, reflect) let algorithms: &[(&str, u32, bool)] = &[ ("AIXM", 0x814141ab, false), ("AUTOSAR", 0xf4acfb13, true), ("BASE91_D", 0xa833982b, true), ("BZIP2", 0x04c11db7, false), ("CD_ROM_EDC", 0x8001801b, true), ("CKSUM", 0x04c11db7, false), ("ISCSI", 0x1edc6f41, true), ("ISO_HDLC", 0x04c11db7, true), ("JAMCRC", 0x04c11db7, true), ("MEF", 0x741b8cd7, true), ("MPEG_2", 0x04c11db7, false), ("XFER", 0x000000af, false), ]; for (name, poly, reflect) in algorithms { print_table_u32(name, 32, *poly, *reflect); } println!("}}"); println!(); } fn generate_crc64_tables() { println!("pub mod crc64 {{"); println!(" //! CRC-64 lookup tables"); println!(); // CRC-64 algorithms with their parameters: (name, poly, reflect) let algorithms: &[(&str, u64, bool)] = &[ ("ECMA_182", 0x42f0e1eba9ea3693, false), ("GO_ISO", 0x000000000000001b, true), ("MS", 0x259c84cba6426349, true), ("NVME", 0xad93d23594c93659, true), ("REDIS", 0xad93d23594c935a9, true), ("WE", 0x42f0e1eba9ea3693, false), ("XZ", 0x42f0e1eba9ea3693, true), ]; for (name, poly, reflect) in algorithms { print_table_u64(name, 64, *poly, *reflect); } println!("}}"); } fn print_table_u16(name: &str, width: u8, poly: u16, reflect: bool) { let table = generate_table_u16(width, poly, reflect); println!(" pub static CRC16_{}_TABLE: [[u16; 256]; 16] = [", name); for lane in &table { println!(" ["); for chunk in lane.chunks(8) { print!(" "); for (i, val) in chunk.iter().enumerate() { print!("0x{:04x}", val); if i < chunk.len() - 1 { print!(", "); } } println!(","); } println!(" ],"); } println!(" ];"); println!(); } fn print_table_u32(name: &str, width: u8, poly: u32, reflect: bool) { let table = generate_table_u32(width, poly, reflect); println!(" pub static CRC32_{}_TABLE: [[u32; 256]; 16] = [", name); for lane in &table { println!(" ["); for chunk in lane.chunks(4) { print!(" "); for (i, val) in chunk.iter().enumerate() { print!("0x{:08x}", val); if i < chunk.len() - 1 { print!(", "); } } println!(","); } println!(" ],"); } println!(" ];"); println!(); } fn print_table_u64(name: &str, width: u8, poly: u64, reflect: bool) { let table = generate_table_u64(width, poly, reflect); println!(" pub static CRC64_{}_TABLE: [[u64; 256]; 16] = [", name); for lane in &table { println!(" ["); for chunk in lane.chunks(2) { print!(" "); for (i, val) in chunk.iter().enumerate() { print!("0x{:016x}", val); if i < chunk.len() - 1 { print!(", "); } } println!(","); } println!(" ],"); } println!(" ];"); println!(); }