1#[derive(Debug, Clone, Copy, PartialEq, Eq)]
7pub struct ClassicMqState {
8 pub qe: u32,
10 pub nmps: u8,
12 pub nlps: u8,
14 pub switch: bool,
16}
17
18macro_rules! mq_states {
19 ($($qe:expr, $nmps:expr, $nlps:expr, $switch:expr),+ $(,)?) => {
20 [$(ClassicMqState { qe: $qe, nmps: $nmps, nlps: $nlps, switch: $switch }),+]
21 };
22}
23
24#[rustfmt::skip]
26pub const MQ_STATES: [ClassicMqState; 47] = mq_states!(
27 0x5601, 1, 1, true,
28 0x3401, 2, 6, false,
29 0x1801, 3, 9, false,
30 0x0AC1, 4, 12, false,
31 0x0521, 5, 29, false,
32 0x0221, 38, 33, false,
33 0x5601, 7, 6, true,
34 0x5401, 8, 14, false,
35 0x4801, 9, 14, false,
36 0x3801, 10, 14, false,
37 0x3001, 11, 17, false,
38 0x2401, 12, 18, false,
39 0x1C01, 13, 20, false,
40 0x1601, 29, 21, false,
41 0x5601, 15, 14, true,
42 0x5401, 16, 14, false,
43 0x5101, 17, 15, false,
44 0x4801, 18, 16, false,
45 0x3801, 19, 17, false,
46 0x3401, 20, 18, false,
47 0x3001, 21, 19, false,
48 0x2801, 22, 19, false,
49 0x2401, 23, 20, false,
50 0x2201, 24, 21, false,
51 0x1C01, 25, 22, false,
52 0x1801, 26, 23, false,
53 0x1601, 27, 24, false,
54 0x1401, 28, 25, false,
55 0x1201, 29, 26, false,
56 0x1101, 30, 27, false,
57 0x0AC1, 31, 28, false,
58 0x09C1, 32, 29, false,
59 0x08A1, 33, 30, false,
60 0x0521, 34, 31, false,
61 0x0441, 35, 32, false,
62 0x02A1, 36, 33, false,
63 0x0221, 37, 34, false,
64 0x0141, 38, 35, false,
65 0x0111, 39, 36, false,
66 0x0085, 40, 37, false,
67 0x0049, 41, 38, false,
68 0x0025, 42, 39, false,
69 0x0015, 43, 40, false,
70 0x0009, 44, 41, false,
71 0x0005, 45, 42, false,
72 0x0001, 45, 43, false,
73 0x5601, 46, 46, false,
74);
75
76const fn mq_qe_values() -> [u32; 47] {
77 let mut values = [0; 47];
78 let mut index = 0;
79 while index < values.len() {
80 values[index] = MQ_STATES[index].qe;
81 index += 1;
82 }
83 values
84}
85
86const fn packed_mq_transitions() -> [u32; 47] {
87 let mut values = [0; 47];
88 let mut index = 0;
89 while index < values.len() {
90 let state = MQ_STATES[index];
91 values[index] =
92 state.nmps as u32 | ((state.nlps as u32) << 8) | ((state.switch as u32) << 16);
93 index += 1;
94 }
95 values
96}
97
98pub const MQ_QE_VALUES: [u32; 47] = mq_qe_values();
100pub const PACKED_MQ_TRANSITION_VALUES: [u32; 47] = packed_mq_transitions();
102
103#[rustfmt::skip]
105pub const SIGN_CONTEXT_LOOKUP: [(u8, u8); 256] = [
106 (9,0), (10,0), (10,1), (0,0), (12,0), (13,0), (11,0), (0,0), (12,1), (11,1),
107 (13,1), (0,0), (0,0), (0,0), (0,0), (0,0), (12,0), (13,0), (11,0), (0,0),
108 (12,0), (13,0), (11,0), (0,0), (9,0), (10,0), (10,1), (0,0), (0,0), (0,0),
109 (0,0), (0,0), (12,1), (11,1), (13,1), (0,0), (9,0), (10,0), (10,1), (0,0),
110 (12,1), (11,1), (13,1), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0),
111 (0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0),
112 (0,0), (0,0), (0,0), (10,0), (10,0), (9,0), (0,0), (13,0), (13,0), (12,0),
113 (0,0), (11,1), (11,1), (12,1), (0,0), (0,0), (0,0), (0,0), (0,0), (13,0),
114 (13,0), (12,0), (0,0), (13,0), (13,0), (12,0), (0,0), (10,0), (10,0), (9,0),
115 (0,0), (0,0), (0,0), (0,0), (0,0), (11,1), (11,1), (12,1), (0,0), (10,0),
116 (10,0), (9,0), (0,0), (11,1), (11,1), (12,1), (0,0), (0,0), (0,0), (0,0),
117 (0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0),
118 (0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (10,1), (9,0), (10,1), (0,0),
119 (11,0), (12,0), (11,0), (0,0), (13,1), (12,1), (13,1), (0,0), (0,0), (0,0),
120 (0,0), (0,0), (11,0), (12,0), (11,0), (0,0), (11,0), (12,0), (11,0), (0,0),
121 (10,1), (9,0), (10,1), (0,0), (0,0), (0,0), (0,0), (0,0), (13,1), (12,1),
122 (13,1), (0,0), (10,1), (9,0), (10,1), (0,0), (13,1), (12,1), (13,1), (0,0),
123 (0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0),
124 (0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0),
125 (0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0),
126 (0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0),
127 (0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0),
128 (0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0),
129 (0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0),
130 (0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0),
131];
132
133const fn packed_sign_contexts() -> [u16; 256] {
134 let mut values = [0; 256];
135 let mut index = 0;
136 while index < values.len() {
137 let (context, xor) = SIGN_CONTEXT_LOOKUP[index];
138 values[index] = context as u16 | ((xor as u16) << 8);
139 index += 1;
140 }
141 values
142}
143
144pub const PACKED_SIGN_CONTEXT_LOOKUP: [u16; 256] = packed_sign_contexts();
146
147#[rustfmt::skip]
149pub const ZERO_CTX_LL_LH_LOOKUP: [u8; 256] = [
150 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,
151 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,
152 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,
153 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,
154 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,
155 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,
156 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,
157 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,
158 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,
159 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,
160 7, 7, 8, 8, 8, 8,
161];
162
163#[rustfmt::skip]
165pub const ZERO_CTX_HL_LOOKUP: [u8; 256] = [
166 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,
167 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,
168 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,
169 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,
170 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,
171 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,
172 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,
173 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,
174 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,
175 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,
176 7, 8, 7, 8, 7, 8,
177];
178
179#[rustfmt::skip]
181pub const ZERO_CTX_HH_LOOKUP: [u8; 256] = [
182 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,
183 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,
184 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,
185 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,
186 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,
187 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,
188 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,
189 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,
190 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,
191 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,
192 8, 8, 8, 8, 8, 8,
193];
194
195#[cfg(test)]
196mod tests {
197 use core::hint::black_box;
198
199 use super::*;
200
201 #[test]
202 fn device_tables_match_their_structured_sources_at_runtime() {
203 let build_qe: fn() -> [u32; 47] = mq_qe_values;
204 let build_transitions: fn() -> [u32; 47] = packed_mq_transitions;
205 let build_sign_contexts: fn() -> [u16; 256] = packed_sign_contexts;
206
207 let qe = black_box(build_qe)();
208 let transitions = black_box(build_transitions)();
209 let sign_contexts = black_box(build_sign_contexts)();
210
211 for (index, state) in MQ_STATES.iter().copied().enumerate() {
212 assert_eq!(qe[index], state.qe);
213 assert_eq!(
214 transitions[index],
215 u32::from(state.nmps)
216 | (u32::from(state.nlps) << 8)
217 | (u32::from(state.switch) << 16)
218 );
219 }
220 for (index, (context, xor)) in SIGN_CONTEXT_LOOKUP.iter().copied().enumerate() {
221 assert_eq!(
222 sign_contexts[index],
223 u16::from(context) | (u16::from(xor) << 8)
224 );
225 }
226 }
227}