use crate::Schedule;
use crate::ubc_check::*;
#[inline(always)]
pub(super) fn check(w: &Schedule) -> u32 {
let mask = prefix(w);
if mask == 0 {
return 0;
}
tail(w, mask)
}
#[inline(always)]
fn prefix(w: &Schedule) -> u32 {
let mut mask: u32 = !0;
mask &= (((w[44] >> 29) ^ (w[45] >> 29)) & 1).wrapping_sub(1)
| !(DV_I_48_0_BIT
| DV_I_51_0_BIT
| DV_I_52_0_BIT
| DV_II_45_0_BIT
| DV_II_46_0_BIT
| DV_II_50_0_BIT
| DV_II_51_0_BIT);
mask &= (((w[46] >> 29) ^ (w[47] >> 29)) & 1).wrapping_sub(1)
| !(DV_I_43_0_BIT
| DV_I_50_0_BIT
| DV_II_47_0_BIT
| DV_II_48_0_BIT
| DV_II_52_0_BIT
| DV_II_53_0_BIT);
mask &= (((w[45] >> 4) ^ (w[48] >> 29)) & 1).wrapping_sub(1)
| !(DV_I_45_0_BIT
| DV_I_47_0_BIT
| DV_I_49_0_BIT
| DV_I_51_0_BIT
| DV_II_49_0_BIT
| DV_II_54_0_BIT);
mask &= (((w[49] >> 29) ^ (w[50] >> 29)) & 1).wrapping_sub(1)
| !(DV_I_46_0_BIT
| DV_II_45_0_BIT
| DV_II_50_0_BIT
| DV_II_51_0_BIT
| DV_II_55_0_BIT
| DV_II_56_0_BIT);
mask &= (((w[40] >> 29) ^ (w[41] >> 29)) & 1).wrapping_sub(1)
| !(DV_I_44_0_BIT
| DV_I_47_0_BIT
| DV_I_48_0_BIT
| DV_II_46_0_BIT
| DV_II_47_0_BIT
| DV_II_56_0_BIT);
mask &= (0u32).wrapping_sub(((w[36] >> 1) ^ (w[37] >> 6)) & 1)
| !(DV_I_47_2_BIT | DV_I_50_2_BIT | DV_II_46_2_BIT);
mask &= (((w[47] >> 29) ^ (w[48] >> 29)) & 1).wrapping_sub(1)
| !(DV_I_44_0_BIT
| DV_I_51_0_BIT
| DV_II_48_0_BIT
| DV_II_49_0_BIT
| DV_II_53_0_BIT
| DV_II_54_0_BIT);
mask &= (0u32).wrapping_sub(((w[39] >> 1) ^ (w[40] >> 6)) & 1)
| !(DV_I_46_2_BIT | DV_I_50_2_BIT | DV_II_49_2_BIT);
mask &= (0u32).wrapping_sub(((w[40] >> 1) ^ (w[41] >> 6)) & 1)
| !(DV_I_47_2_BIT | DV_I_51_2_BIT | DV_II_50_2_BIT);
mask &= (0u32).wrapping_sub(((w[41] >> 1) ^ (w[42] >> 6)) & 1)
| !(DV_I_48_2_BIT | DV_II_46_2_BIT | DV_II_51_2_BIT);
mask &= (((w[43] >> 4) ^ (w[46] >> 29)) & 1).wrapping_sub(1)
| !(DV_I_43_0_BIT
| DV_I_45_0_BIT
| DV_I_47_0_BIT
| DV_I_49_0_BIT
| DV_II_47_0_BIT
| DV_II_52_0_BIT);
mask &= (((w[46] >> 4) ^ (w[49] >> 29)) & 1).wrapping_sub(1)
| !(DV_I_46_0_BIT
| DV_I_48_0_BIT
| DV_I_50_0_BIT
| DV_I_52_0_BIT
| DV_II_50_0_BIT
| DV_II_55_0_BIT);
mask &= (((w[45] >> 6) ^ (w[47] >> 6)) & 1).wrapping_sub(1)
| !(DV_I_47_2_BIT | DV_I_49_2_BIT | DV_I_51_2_BIT);
mask &= (((w[45] >> 29) ^ (w[46] >> 29)) & 1).wrapping_sub(1)
| !(DV_I_49_0_BIT
| DV_I_52_0_BIT
| DV_II_46_0_BIT
| DV_II_47_0_BIT
| DV_II_51_0_BIT
| DV_II_52_0_BIT);
mask &= (((w[44] >> 4) ^ (w[47] >> 29)) & 1).wrapping_sub(1)
| !(DV_I_44_0_BIT
| DV_I_46_0_BIT
| DV_I_48_0_BIT
| DV_I_50_0_BIT
| DV_II_48_0_BIT
| DV_II_53_0_BIT);
mask &= (((w[48] >> 29) ^ (w[49] >> 29)) & 1).wrapping_sub(1)
| !(DV_I_45_0_BIT
| DV_I_52_0_BIT
| DV_II_49_0_BIT
| DV_II_50_0_BIT
| DV_II_54_0_BIT
| DV_II_55_0_BIT);
mask &= (((w[44] >> 6) ^ (w[46] >> 6)) & 1).wrapping_sub(1)
| !(DV_I_46_2_BIT | DV_I_48_2_BIT | DV_I_50_2_BIT);
mask &= (((w[47] >> 4) ^ (w[50] >> 29)) & 1).wrapping_sub(1)
| !(DV_I_47_0_BIT
| DV_I_49_0_BIT
| DV_I_51_0_BIT
| DV_II_45_0_BIT
| DV_II_51_0_BIT
| DV_II_56_0_BIT);
mask &=
(0u32).wrapping_sub(((w[35] >> 1) ^ (w[36] >> 6)) & 1) | !(DV_I_46_2_BIT | DV_I_49_2_BIT);
mask &=
(0u32).wrapping_sub(((w[44] >> 1) ^ (w[45] >> 6)) & 1) | !(DV_I_51_2_BIT | DV_II_49_2_BIT);
mask &=
(((w[42] >> 6) ^ (w[43] >> 1)) & 1).wrapping_sub(1) | !(DV_II_46_2_BIT | DV_II_51_2_BIT);
mask &= (((w[37] >> 4) ^ (w[40] >> 29)) & 1).wrapping_sub(1)
| !(DV_I_43_0_BIT | DV_I_47_0_BIT | DV_II_46_0_BIT | DV_II_53_0_BIT | DV_II_55_0_BIT);
mask &= (((w[41] >> 6) ^ (w[42] >> 1)) & 1).wrapping_sub(1) | !(DV_I_51_2_BIT | DV_II_50_2_BIT);
mask &= (((w[40] >> 4) ^ (w[43] >> 29)) & 1).wrapping_sub(1)
| !(DV_I_44_0_BIT | DV_I_46_0_BIT | DV_I_50_0_BIT | DV_II_49_0_BIT | DV_II_56_0_BIT);
mask &= (((w[41] >> 4) ^ (w[44] >> 29)) & 1).wrapping_sub(1)
| !(DV_I_43_0_BIT
| DV_I_45_0_BIT
| DV_I_47_0_BIT
| DV_I_51_0_BIT
| DV_II_45_0_BIT
| DV_II_50_0_BIT);
mask &= (((w[52] >> 29) ^ (w[53] >> 29)) & 1).wrapping_sub(1)
| !(DV_I_49_0_BIT | DV_II_45_0_BIT | DV_II_48_0_BIT | DV_II_53_0_BIT | DV_II_54_0_BIT);
mask &= (((w[40] >> 6) ^ (w[41] >> 1)) & 1).wrapping_sub(1) | !(DV_I_50_2_BIT | DV_II_49_2_BIT);
mask &= (((w[46] >> 6) ^ (w[47] >> 1)) & 1).wrapping_sub(1) | !(DV_I_46_2_BIT | DV_II_50_2_BIT);
mask &= (((w[47] >> 6) ^ (w[48] >> 1)) & 1).wrapping_sub(1) | !(DV_I_47_2_BIT | DV_II_51_2_BIT);
mask &= (((w[42] >> 4) ^ (w[45] >> 29)) & 1).wrapping_sub(1)
| !(DV_I_44_0_BIT
| DV_I_46_0_BIT
| DV_I_48_0_BIT
| DV_I_52_0_BIT
| DV_II_46_0_BIT
| DV_II_51_0_BIT);
mask &=
(0u32).wrapping_sub(((w[37] >> 1) ^ (w[38] >> 6)) & 1) | !(DV_I_48_2_BIT | DV_I_51_2_BIT);
mask &= (((w[43] >> 6) ^ (w[45] >> 6)) & 1).wrapping_sub(1) | !(DV_I_47_2_BIT | DV_I_49_2_BIT);
mask &= (((w[53] >> 29) ^ (w[54] >> 29)) & 1).wrapping_sub(1)
| !(DV_I_50_0_BIT | DV_II_46_0_BIT | DV_II_49_0_BIT | DV_II_54_0_BIT | DV_II_55_0_BIT);
mask &= (((w[41] >> 29) ^ (w[42] >> 29)) & 1).wrapping_sub(1)
| !(DV_I_45_0_BIT | DV_I_48_0_BIT | DV_I_49_0_BIT | DV_II_47_0_BIT | DV_II_48_0_BIT);
mask &= (((w[50] >> 29) ^ (w[51] >> 29)) & 1).wrapping_sub(1)
| !(DV_I_47_0_BIT | DV_II_46_0_BIT | DV_II_51_0_BIT | DV_II_52_0_BIT | DV_II_56_0_BIT);
mask &=
(0u32).wrapping_sub(((w[61] >> 2) ^ (w[62] >> 7)) & 1) | !(DV_I_46_2_BIT | DV_II_46_2_BIT);
mask &= (((w[46] >> 6) ^ (w[48] >> 6)) & 1).wrapping_sub(1) | !(DV_I_48_2_BIT | DV_I_50_2_BIT);
mask &= (((w[39] >> 4) ^ (w[42] >> 29)) & 1).wrapping_sub(1)
| !(DV_I_43_0_BIT | DV_I_45_0_BIT | DV_I_49_0_BIT | DV_II_48_0_BIT | DV_II_55_0_BIT);
mask &= (((w[43] >> 29) ^ (w[44] >> 29)) & 1).wrapping_sub(1)
| !(DV_I_47_0_BIT
| DV_I_50_0_BIT
| DV_I_51_0_BIT
| DV_II_45_0_BIT
| DV_II_49_0_BIT
| DV_II_50_0_BIT);
mask &= (((w[47] >> 6) ^ (w[49] >> 6)) & 1).wrapping_sub(1) | !(DV_I_49_2_BIT | DV_I_51_2_BIT);
mask &= (((w[51] >> 29) ^ (w[52] >> 29)) & 1).wrapping_sub(1)
| !(DV_I_48_0_BIT | DV_II_47_0_BIT | DV_II_52_0_BIT | DV_II_53_0_BIT);
mask &= (0u32).wrapping_sub((w[36] ^ (w[37] >> 5)) & 1) | !(DV_II_49_2_BIT);
mask &= (0u32).wrapping_sub((w[37] ^ (w[38] >> 5)) & 1) | !(DV_II_50_2_BIT);
mask &= (0u32).wrapping_sub((w[38] ^ (w[39] >> 5)) & 1) | !(DV_II_51_2_BIT);
mask &= (((w[38] >> 4) ^ (w[41] >> 29)) & 1).wrapping_sub(1)
| !(DV_I_44_0_BIT | DV_I_48_0_BIT | DV_II_47_0_BIT | DV_II_54_0_BIT | DV_II_56_0_BIT);
mask
}
static TAIL_CHECKS: [(u8, u8, u8, u8, u8); 214] = [
(37, 4, 39, 4, 1),
(39, 4, 41, 4, 1),
(41, 4, 43, 4, 1),
(43, 4, 47, 29, 0),
(58, 0, 59, 5, 1),
(58, 0, 63, 30, 1),
(61, 1, 62, 6, 1),
(38, 4, 40, 4, 1),
(40, 4, 42, 4, 1),
(42, 4, 44, 4, 1),
(44, 4, 48, 29, 0),
(59, 0, 60, 5, 1),
(59, 0, 64, 30, 1),
(62, 1, 63, 6, 1),
(35, 4, 39, 29, 0),
(39, 4, 41, 4, 1),
(41, 4, 43, 4, 1),
(43, 4, 45, 4, 1),
(60, 0, 61, 5, 1),
(63, 1, 64, 6, 1),
(36, 4, 40, 29, 0),
(40, 4, 42, 4, 1),
(42, 4, 44, 4, 1),
(42, 29, 43, 29, 0),
(44, 4, 46, 4, 1),
(61, 0, 62, 5, 1),
(39, 1, 42, 6, 1),
(42, 6, 44, 6, 0),
(37, 4, 41, 29, 0),
(41, 4, 43, 4, 1),
(43, 4, 45, 4, 1),
(45, 4, 47, 4, 1),
(62, 0, 63, 5, 1),
(40, 1, 43, 6, 1),
(62, 2, 63, 7, 1),
(35, 4, 39, 29, 0),
(38, 4, 42, 29, 0),
(42, 4, 44, 4, 1),
(44, 4, 46, 4, 1),
(46, 4, 48, 4, 1),
(48, 4, 51, 29, 0),
(63, 0, 64, 5, 1),
(41, 1, 49, 1, 1),
(42, 6, 44, 6, 0),
(63, 2, 64, 7, 1),
(36, 4, 40, 29, 0),
(39, 4, 43, 29, 0),
(42, 29, 43, 29, 0),
(43, 4, 45, 4, 1),
(45, 4, 47, 4, 1),
(47, 4, 49, 4, 1),
(49, 4, 52, 29, 0),
(38, 1, 39, 6, 1),
(38, 1, 40, 1, 1),
(42, 1, 43, 6, 1),
(42, 1, 50, 1, 1),
(36, 4, 37, 4, 1),
(37, 4, 41, 29, 0),
(40, 4, 44, 29, 0),
(42, 29, 43, 29, 0),
(44, 4, 46, 4, 1),
(46, 4, 48, 4, 1),
(48, 4, 51, 29, 0),
(48, 4, 50, 4, 1),
(50, 4, 53, 29, 0),
(43, 1, 44, 6, 1),
(48, 6, 50, 6, 0),
(48, 6, 51, 1, 0),
(35, 3, 39, 28, 0),
(37, 4, 38, 4, 1),
(38, 4, 42, 29, 0),
(41, 4, 45, 29, 0),
(45, 4, 47, 4, 1),
(47, 4, 49, 4, 1),
(49, 4, 52, 29, 0),
(51, 4, 54, 29, 0),
(52, 29, 55, 29, 1),
(54, 29, 55, 29, 0),
(35, 5, 39, 30, 0),
(37, 1, 37, 6, 0),
(44, 1, 51, 6, 1),
(44, 1, 52, 1, 1),
(38, 4, 39, 4, 1),
(39, 4, 43, 29, 0),
(42, 4, 46, 29, 0),
(46, 4, 48, 4, 1),
(48, 4, 51, 29, 0),
(48, 4, 50, 4, 1),
(50, 4, 53, 29, 0),
(52, 4, 55, 29, 0),
(53, 29, 56, 29, 1),
(55, 29, 56, 29, 0),
(36, 4, 40, 29, 0),
(41, 4, 45, 29, 0),
(47, 4, 49, 4, 1),
(49, 4, 52, 29, 0),
(60, 0, 61, 5, 1),
(63, 1, 64, 6, 1),
(37, 4, 41, 29, 0),
(42, 4, 46, 29, 0),
(48, 4, 51, 29, 0),
(48, 4, 50, 4, 1),
(50, 4, 53, 29, 0),
(61, 0, 62, 5, 1),
(47, 1, 48, 6, 1),
(48, 6, 50, 6, 0),
(48, 6, 51, 1, 0),
(35, 3, 39, 28, 0),
(35, 4, 39, 29, 0),
(38, 4, 42, 29, 0),
(43, 4, 47, 29, 0),
(49, 4, 52, 29, 0),
(51, 4, 54, 29, 0),
(52, 29, 55, 29, 1),
(54, 29, 55, 29, 0),
(62, 0, 63, 5, 1),
(35, 30, 36, 3, 1),
(35, 30, 40, 28, 1),
(36, 4, 40, 29, 0),
(39, 4, 43, 29, 0),
(42, 29, 43, 29, 0),
(44, 4, 48, 29, 0),
(50, 4, 53, 29, 0),
(52, 4, 55, 29, 0),
(52, 29, 55, 29, 1),
(53, 29, 56, 29, 1),
(55, 29, 56, 29, 0),
(63, 0, 64, 5, 1),
(36, 30, 37, 3, 1),
(36, 30, 41, 28, 1),
(37, 4, 41, 29, 0),
(40, 4, 44, 29, 0),
(42, 29, 43, 29, 0),
(51, 4, 54, 29, 0),
(53, 4, 56, 29, 0),
(53, 29, 56, 29, 1),
(54, 29, 57, 29, 1),
(36, 0, 41, 30, 1),
(44, 1, 46, 1, 1),
(50, 1, 51, 6, 1),
(50, 1, 53, 6, 1),
(50, 1, 54, 1, 1),
(37, 30, 38, 3, 1),
(37, 30, 42, 28, 1),
(38, 4, 42, 29, 0),
(41, 4, 45, 29, 0),
(52, 4, 55, 29, 0),
(54, 4, 57, 29, 0),
(54, 29, 55, 29, 0),
(54, 29, 57, 29, 1),
(55, 29, 58, 29, 1),
(37, 0, 42, 30, 1),
(45, 1, 46, 6, 1),
(51, 1, 52, 6, 1),
(51, 1, 54, 6, 1),
(51, 1, 55, 1, 1),
(38, 30, 39, 3, 1),
(38, 30, 43, 28, 1),
(39, 4, 43, 29, 0),
(42, 4, 46, 29, 0),
(53, 4, 56, 29, 0),
(55, 4, 58, 29, 0),
(55, 29, 56, 29, 0),
(55, 29, 58, 29, 1),
(56, 29, 59, 29, 1),
(38, 0, 43, 30, 1),
(46, 1, 47, 6, 1),
(52, 1, 53, 6, 1),
(52, 1, 55, 6, 1),
(52, 1, 56, 1, 1),
(36, 4, 38, 4, 1),
(39, 30, 40, 3, 1),
(39, 30, 44, 28, 1),
(40, 4, 44, 29, 0),
(43, 4, 47, 29, 0),
(48, 4, 51, 29, 0),
(54, 4, 57, 29, 0),
(54, 4, 56, 4, 1),
(54, 4, 60, 29, 1),
(56, 4, 59, 29, 0),
(56, 29, 59, 29, 1),
(37, 4, 39, 4, 1),
(41, 3, 45, 28, 0),
(41, 4, 45, 29, 0),
(44, 4, 48, 29, 0),
(49, 4, 52, 29, 0),
(55, 4, 58, 29, 0),
(55, 4, 57, 4, 1),
(55, 4, 57, 29, 0),
(55, 4, 61, 29, 1),
(36, 4, 38, 4, 1),
(38, 4, 40, 4, 1),
(42, 3, 46, 28, 0),
(42, 4, 46, 29, 0),
(50, 4, 53, 29, 0),
(56, 4, 59, 29, 0),
(56, 4, 58, 29, 0),
(58, 4, 62, 29, 0),
(37, 4, 39, 4, 1),
(39, 4, 41, 4, 1),
(43, 3, 47, 28, 0),
(43, 4, 47, 29, 0),
(51, 4, 54, 29, 0),
(54, 29, 55, 29, 0),
(57, 4, 59, 29, 0),
(59, 4, 63, 29, 0),
(38, 4, 40, 4, 1),
(40, 4, 42, 4, 1),
(44, 3, 48, 28, 0),
(44, 4, 48, 29, 0),
(52, 4, 55, 29, 0),
(54, 29, 55, 29, 0),
(55, 29, 56, 29, 0),
(60, 4, 64, 29, 0),
];
static TAIL_SPANS: [(u16, u8); 32] = [
(0, 7),
(7, 7),
(14, 6),
(20, 6),
(26, 2),
(28, 5),
(33, 2),
(35, 7),
(42, 3),
(45, 7),
(52, 4),
(56, 9),
(65, 3),
(68, 10),
(78, 4),
(82, 10),
(92, 6),
(98, 6),
(104, 3),
(107, 9),
(116, 12),
(128, 9),
(137, 5),
(142, 9),
(151, 5),
(156, 9),
(165, 5),
(170, 11),
(181, 9),
(190, 8),
(198, 8),
(206, 8),
];
fn tail(w: &Schedule, mask: u32) -> u32 {
let mut out = mask;
let mut rest = mask;
while rest != 0 {
let d = rest.trailing_zeros();
rest &= rest - 1;
let (start, len) = TAIL_SPANS[d as usize];
let start = start as usize;
let dead = TAIL_CHECKS[start..start + len as usize]
.iter()
.any(|&(i, a, j, b, c)| {
((w[i as usize] >> a) ^ (w[j as usize] >> b)) & 1 != u32::from(c)
});
if dead {
out &= !(1 << d);
}
}
out
}