#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct ClassicMqState {
pub qe: u32,
pub nmps: u8,
pub nlps: u8,
pub switch: bool,
}
macro_rules! mq_states {
($($qe:expr, $nmps:expr, $nlps:expr, $switch:expr),+ $(,)?) => {
[$(ClassicMqState { qe: $qe, nmps: $nmps, nlps: $nlps, switch: $switch }),+]
};
}
#[rustfmt::skip]
pub const MQ_STATES: [ClassicMqState; 47] = mq_states!(
0x5601, 1, 1, true,
0x3401, 2, 6, false,
0x1801, 3, 9, false,
0x0AC1, 4, 12, false,
0x0521, 5, 29, false,
0x0221, 38, 33, false,
0x5601, 7, 6, true,
0x5401, 8, 14, false,
0x4801, 9, 14, false,
0x3801, 10, 14, false,
0x3001, 11, 17, false,
0x2401, 12, 18, false,
0x1C01, 13, 20, false,
0x1601, 29, 21, false,
0x5601, 15, 14, true,
0x5401, 16, 14, false,
0x5101, 17, 15, false,
0x4801, 18, 16, false,
0x3801, 19, 17, false,
0x3401, 20, 18, false,
0x3001, 21, 19, false,
0x2801, 22, 19, false,
0x2401, 23, 20, false,
0x2201, 24, 21, false,
0x1C01, 25, 22, false,
0x1801, 26, 23, false,
0x1601, 27, 24, false,
0x1401, 28, 25, false,
0x1201, 29, 26, false,
0x1101, 30, 27, false,
0x0AC1, 31, 28, false,
0x09C1, 32, 29, false,
0x08A1, 33, 30, false,
0x0521, 34, 31, false,
0x0441, 35, 32, false,
0x02A1, 36, 33, false,
0x0221, 37, 34, false,
0x0141, 38, 35, false,
0x0111, 39, 36, false,
0x0085, 40, 37, false,
0x0049, 41, 38, false,
0x0025, 42, 39, false,
0x0015, 43, 40, false,
0x0009, 44, 41, false,
0x0005, 45, 42, false,
0x0001, 45, 43, false,
0x5601, 46, 46, false,
);
const fn mq_qe_values() -> [u32; 47] {
let mut values = [0; 47];
let mut index = 0;
while index < values.len() {
values[index] = MQ_STATES[index].qe;
index += 1;
}
values
}
const fn packed_mq_transitions() -> [u32; 47] {
let mut values = [0; 47];
let mut index = 0;
while index < values.len() {
let state = MQ_STATES[index];
values[index] =
state.nmps as u32 | ((state.nlps as u32) << 8) | ((state.switch as u32) << 16);
index += 1;
}
values
}
pub const MQ_QE_VALUES: [u32; 47] = mq_qe_values();
pub const PACKED_MQ_TRANSITION_VALUES: [u32; 47] = packed_mq_transitions();
#[rustfmt::skip]
pub const SIGN_CONTEXT_LOOKUP: [(u8, u8); 256] = [
(9,0), (10,0), (10,1), (0,0), (12,0), (13,0), (11,0), (0,0), (12,1), (11,1),
(13,1), (0,0), (0,0), (0,0), (0,0), (0,0), (12,0), (13,0), (11,0), (0,0),
(12,0), (13,0), (11,0), (0,0), (9,0), (10,0), (10,1), (0,0), (0,0), (0,0),
(0,0), (0,0), (12,1), (11,1), (13,1), (0,0), (9,0), (10,0), (10,1), (0,0),
(12,1), (11,1), (13,1), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0),
(0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0),
(0,0), (0,0), (0,0), (10,0), (10,0), (9,0), (0,0), (13,0), (13,0), (12,0),
(0,0), (11,1), (11,1), (12,1), (0,0), (0,0), (0,0), (0,0), (0,0), (13,0),
(13,0), (12,0), (0,0), (13,0), (13,0), (12,0), (0,0), (10,0), (10,0), (9,0),
(0,0), (0,0), (0,0), (0,0), (0,0), (11,1), (11,1), (12,1), (0,0), (10,0),
(10,0), (9,0), (0,0), (11,1), (11,1), (12,1), (0,0), (0,0), (0,0), (0,0),
(0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0),
(0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (10,1), (9,0), (10,1), (0,0),
(11,0), (12,0), (11,0), (0,0), (13,1), (12,1), (13,1), (0,0), (0,0), (0,0),
(0,0), (0,0), (11,0), (12,0), (11,0), (0,0), (11,0), (12,0), (11,0), (0,0),
(10,1), (9,0), (10,1), (0,0), (0,0), (0,0), (0,0), (0,0), (13,1), (12,1),
(13,1), (0,0), (10,1), (9,0), (10,1), (0,0), (13,1), (12,1), (13,1), (0,0),
(0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0),
(0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0),
(0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0),
(0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0),
(0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0),
(0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0),
(0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0),
(0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0),
];
const fn packed_sign_contexts() -> [u16; 256] {
let mut values = [0; 256];
let mut index = 0;
while index < values.len() {
let (context, xor) = SIGN_CONTEXT_LOOKUP[index];
values[index] = context as u16 | ((xor as u16) << 8);
index += 1;
}
values
}
pub const PACKED_SIGN_CONTEXT_LOOKUP: [u16; 256] = packed_sign_contexts();
#[rustfmt::skip]
pub const ZERO_CTX_LL_LH_LOOKUP: [u8; 256] = [
0, 3, 1, 3, 5, 7, 6, 7, 1, 3, 2, 3, 6, 7, 6, 7, 5, 7, 6, 7, 8, 8, 8, 8, 6,
7, 6, 7, 8, 8, 8, 8, 1, 3, 2, 3, 6, 7, 6, 7, 2, 3, 2, 3, 6, 7, 6, 7, 6, 7,
6, 7, 8, 8, 8, 8, 6, 7, 6, 7, 8, 8, 8, 8, 3, 4, 3, 4, 7, 7, 7, 7, 3, 4, 3,
4, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 7, 7, 7, 7, 8, 8, 8, 8, 3, 4, 3, 4,
7, 7, 7, 7, 3, 4, 3, 4, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 7, 7, 7, 7, 8,
8, 8, 8, 1, 3, 2, 3, 6, 7, 6, 7, 2, 3, 2, 3, 6, 7, 6, 7, 6, 7, 6, 7, 8, 8,
8, 8, 6, 7, 6, 7, 8, 8, 8, 8, 2, 3, 2, 3, 6, 7, 6, 7, 2, 3, 2, 3, 6, 7, 6,
7, 6, 7, 6, 7, 8, 8, 8, 8, 6, 7, 6, 7, 8, 8, 8, 8, 3, 4, 3, 4, 7, 7, 7, 7,
3, 4, 3, 4, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 7, 7, 7, 7, 8, 8, 8, 8, 3,
4, 3, 4, 7, 7, 7, 7, 3, 4, 3, 4, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 7, 7,
7, 7, 8, 8, 8, 8,
];
#[rustfmt::skip]
pub const ZERO_CTX_HL_LOOKUP: [u8; 256] = [
0, 5, 1, 6, 3, 7, 3, 7, 1, 6, 2, 6, 3, 7, 3, 7, 3, 7, 3, 7, 4, 7, 4, 7, 3,
7, 3, 7, 4, 7, 4, 7, 1, 6, 2, 6, 3, 7, 3, 7, 2, 6, 2, 6, 3, 7, 3, 7, 3, 7,
3, 7, 4, 7, 4, 7, 3, 7, 3, 7, 4, 7, 4, 7, 5, 8, 6, 8, 7, 8, 7, 8, 6, 8, 6,
8, 7, 8, 7, 8, 7, 8, 7, 8, 7, 8, 7, 8, 7, 8, 7, 8, 7, 8, 7, 8, 6, 8, 6, 8,
7, 8, 7, 8, 6, 8, 6, 8, 7, 8, 7, 8, 7, 8, 7, 8, 7, 8, 7, 8, 7, 8, 7, 8, 7,
8, 7, 8, 1, 6, 2, 6, 3, 7, 3, 7, 2, 6, 2, 6, 3, 7, 3, 7, 3, 7, 3, 7, 4, 7,
4, 7, 3, 7, 3, 7, 4, 7, 4, 7, 2, 6, 2, 6, 3, 7, 3, 7, 2, 6, 2, 6, 3, 7, 3,
7, 3, 7, 3, 7, 4, 7, 4, 7, 3, 7, 3, 7, 4, 7, 4, 7, 6, 8, 6, 8, 7, 8, 7, 8,
6, 8, 6, 8, 7, 8, 7, 8, 7, 8, 7, 8, 7, 8, 7, 8, 7, 8, 7, 8, 7, 8, 7, 8, 6,
8, 6, 8, 7, 8, 7, 8, 6, 8, 6, 8, 7, 8, 7, 8, 7, 8, 7, 8, 7, 8, 7, 8, 7, 8,
7, 8, 7, 8, 7, 8,
];
#[rustfmt::skip]
pub const ZERO_CTX_HH_LOOKUP: [u8; 256] = [
0, 1, 3, 4, 1, 2, 4, 5, 3, 4, 6, 7, 4, 5, 7, 7, 1, 2, 4, 5, 2, 2, 5, 5, 4,
5, 7, 7, 5, 5, 7, 7, 3, 4, 6, 7, 4, 5, 7, 7, 6, 7, 8, 8, 7, 7, 8, 8, 4, 5,
7, 7, 5, 5, 7, 7, 7, 7, 8, 8, 7, 7, 8, 8, 1, 2, 4, 5, 2, 2, 5, 5, 4, 5, 7,
7, 5, 5, 7, 7, 2, 2, 5, 5, 2, 2, 5, 5, 5, 5, 7, 7, 5, 5, 7, 7, 4, 5, 7, 7,
5, 5, 7, 7, 7, 7, 8, 8, 7, 7, 8, 8, 5, 5, 7, 7, 5, 5, 7, 7, 7, 7, 8, 8, 7,
7, 8, 8, 3, 4, 6, 7, 4, 5, 7, 7, 6, 7, 8, 8, 7, 7, 8, 8, 4, 5, 7, 7, 5, 5,
7, 7, 7, 7, 8, 8, 7, 7, 8, 8, 6, 7, 8, 8, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 7, 7, 8, 8, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 4, 5, 7, 7, 5, 5, 7, 7,
7, 7, 8, 8, 7, 7, 8, 8, 5, 5, 7, 7, 5, 5, 7, 7, 7, 7, 8, 8, 7, 7, 8, 8, 7,
7, 8, 8, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 8, 8, 7, 7, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8,
];
#[cfg(test)]
mod tests {
use core::hint::black_box;
use super::*;
#[test]
fn device_tables_match_their_structured_sources_at_runtime() {
let build_qe: fn() -> [u32; 47] = mq_qe_values;
let build_transitions: fn() -> [u32; 47] = packed_mq_transitions;
let build_sign_contexts: fn() -> [u16; 256] = packed_sign_contexts;
let qe = black_box(build_qe)();
let transitions = black_box(build_transitions)();
let sign_contexts = black_box(build_sign_contexts)();
for (index, state) in MQ_STATES.iter().copied().enumerate() {
assert_eq!(qe[index], state.qe);
assert_eq!(
transitions[index],
u32::from(state.nmps)
| (u32::from(state.nlps) << 8)
| (u32::from(state.switch) << 16)
);
}
for (index, (context, xor)) in SIGN_CONTEXT_LOOKUP.iter().copied().enumerate() {
assert_eq!(
sign_contexts[index],
u16::from(context) | (u16::from(xor) << 8)
);
}
}
}