mirror of
https://git.proxmox.com/git/rustc
synced 2025-08-19 00:34:23 +00:00
125 lines
3.0 KiB
Rust
125 lines
3.0 KiB
Rust
use std::env;
|
|
use std::fs::File;
|
|
use std::io::{self, Write};
|
|
use std::path::{Path, PathBuf};
|
|
|
|
const CASTAGNOLI_POLY: u32 = 0x82f63b78;
|
|
|
|
type Result<T> = std::result::Result<T, Box<dyn std::error::Error>>;
|
|
|
|
fn main() {
|
|
if let Err(err) = try_main() {
|
|
panic!("{}", err);
|
|
}
|
|
}
|
|
|
|
fn try_main() -> Result<()> {
|
|
let out_dir = match env::var_os("OUT_DIR") {
|
|
None => {
|
|
return Err(From::from("OUT_DIR environment variable not defined"))
|
|
}
|
|
Some(out_dir) => PathBuf::from(out_dir),
|
|
};
|
|
write_tag_lookup_table(&out_dir)?;
|
|
write_crc_tables(&out_dir)?;
|
|
Ok(())
|
|
}
|
|
|
|
fn write_tag_lookup_table(out_dir: &Path) -> Result<()> {
|
|
let out_path = out_dir.join("tag.rs");
|
|
let mut out = io::BufWriter::new(File::create(out_path)?);
|
|
|
|
writeln!(out, "pub const TAG_LOOKUP_TABLE: [u16; 256] = [")?;
|
|
for b in 0u8..=255 {
|
|
writeln!(out, " {},", tag_entry(b))?;
|
|
}
|
|
writeln!(out, "];")?;
|
|
Ok(())
|
|
}
|
|
|
|
fn tag_entry(b: u8) -> u16 {
|
|
let b = b as u16;
|
|
match b & 0b00000011 {
|
|
0b00 => {
|
|
let lit_len = (b >> 2) + 1;
|
|
if lit_len <= 60 {
|
|
lit_len
|
|
} else {
|
|
assert!(lit_len <= 64);
|
|
(lit_len - 60) << 11
|
|
}
|
|
}
|
|
0b01 => {
|
|
let len = 4 + ((b >> 2) & 0b111);
|
|
let offset = (b >> 5) & 0b111;
|
|
(1 << 11) | (offset << 8) | len
|
|
}
|
|
0b10 => {
|
|
let len = 1 + (b >> 2);
|
|
(2 << 11) | len
|
|
}
|
|
0b11 => {
|
|
let len = 1 + (b >> 2);
|
|
(4 << 11) | len
|
|
}
|
|
_ => unreachable!(),
|
|
}
|
|
}
|
|
|
|
fn write_crc_tables(out_dir: &Path) -> Result<()> {
|
|
let out_path = out_dir.join("crc32_table.rs");
|
|
let mut out = io::BufWriter::new(File::create(out_path)?);
|
|
|
|
let table = make_table(CASTAGNOLI_POLY);
|
|
let table16 = make_table16(CASTAGNOLI_POLY);
|
|
|
|
writeln!(out, "pub const TABLE: [u32; 256] = [")?;
|
|
for &x in table.iter() {
|
|
writeln!(out, " {},", x)?;
|
|
}
|
|
writeln!(out, "];\n")?;
|
|
|
|
writeln!(out, "pub const TABLE16: [[u32; 256]; 16] = [")?;
|
|
for table in table16.iter() {
|
|
writeln!(out, " [")?;
|
|
for &x in table.iter() {
|
|
writeln!(out, " {},", x)?;
|
|
}
|
|
writeln!(out, " ],")?;
|
|
}
|
|
writeln!(out, "];")?;
|
|
|
|
out.flush()?;
|
|
|
|
Ok(())
|
|
}
|
|
|
|
fn make_table16(poly: u32) -> [[u32; 256]; 16] {
|
|
let mut tab = [[0; 256]; 16];
|
|
tab[0] = make_table(poly);
|
|
for i in 0..256 {
|
|
let mut crc = tab[0][i];
|
|
for j in 1..16 {
|
|
crc = (crc >> 8) ^ tab[0][crc as u8 as usize];
|
|
tab[j][i] = crc;
|
|
}
|
|
}
|
|
tab
|
|
}
|
|
|
|
fn make_table(poly: u32) -> [u32; 256] {
|
|
let mut tab = [0; 256];
|
|
for i in 0u32..256u32 {
|
|
let mut crc = i;
|
|
for _ in 0..8 {
|
|
if crc & 1 == 1 {
|
|
crc = (crc >> 1) ^ poly;
|
|
} else {
|
|
crc >>= 1;
|
|
}
|
|
}
|
|
tab[i as usize] = crc;
|
|
}
|
|
tab
|
|
}
|