use crate::block::Block;
#[inline(always)]
pub(crate) fn combine2<B: Block>(input: &[B; 7]) -> [B; 2] {
let mut output = [input[0], input[1]];
output[0] = output[0].plus(input[2]);
output[1] = output[1].plus(input[2]);
output[0] = output[0].plus(input[3]);
output[1] = output[1].plus(input[3].shl::<1>());
output[0] = output[0].plus(input[4].shl::<1>());
output[1] = output[1].plus(input[4]);
output[0] = output[0].plus(input[5]);
output[1] = output[1].plus(input[5].shl::<2>());
output[0] = output[0].plus(input[6].shl::<2>());
output[1] = output[1].plus(input[6]);
output
}
#[inline(always)]
pub(crate) fn combine3<B: Block>(input: &[B; 9]) -> [B; 3] {
let mut output = [B::zero(); 3];
output[1] = input[0];
output[2] = input[0];
output[1] = output[1].plus(input[1]);
output[2] = output[2].plus(input[1].shl::<2>());
output[0] = input[2];
output[2] = output[2].plus(input[2]);
output[0] = output[0].plus(input[3].shl::<2>());
output[2] = output[2].plus(input[3]);
output[0] = output[0].plus(input[4]);
output[1] = output[1].plus(input[4]);
output[0] = output[0].plus(input[5]);
output[1] = output[1].plus(input[5].shl::<2>());
output[0] = output[0].plus(input[6].shl::<1>());
output[1] = output[1].plus(input[6]);
output[2] = output[2].plus(input[6].shl::<1>());
output[0] = output[0].plus(input[7].shl::<1>());
output[1] = output[1].plus(input[7].shl::<1>());
output[2] = output[2].plus(input[7]);
output[0] = output[0].plus(input[8]);
output[1] = output[1].plus(input[8].shl::<1>());
output[2] = output[2].plus(input[8].shl::<1>());
output
}
#[inline(always)]
pub(crate) fn combine4<B: Block>(input: &[B; 10]) -> [B; 4] {
let mut output = [B::zero(); 4];
output[2] = input[0].shl::<1>();
output[3] = input[0];
output[1] = input[1];
output[3] = output[3].plus(input[1]);
output[1] = output[1].plus(input[2].shl::<1>());
output[2] = output[2].plus(input[2]);
output[0] = input[3];
output[3] = output[3].plus(input[3]);
output[0] = output[0].plus(input[4]);
output[2] = output[2].plus(input[4].shl::<2>());
output[0] = output[0].plus(input[5].shl::<2>());
output[1] = output[1].plus(input[5]);
output[0] = output[0].plus(input[6].shl::<1>());
output[1] = output[1].plus(input[6]);
output[2] = output[2].plus(input[6]);
output[3] = output[3].plus(input[6].shl::<2>());
output[0] = output[0].plus(input[7].shl::<2>());
output[1] = output[1].plus(input[7].shl::<1>());
output[2] = output[2].plus(input[7]);
output[3] = output[3].plus(input[7]);
output[0] = output[0].plus(input[8]);
output[1] = output[1].plus(input[8].shl::<2>());
output[2] = output[2].plus(input[8]);
output[3] = output[3].plus(input[8].shl::<1>());
output[0] = output[0].plus(input[9]);
output[1] = output[1].plus(input[9]);
output[2] = output[2].plus(input[9]);
output[3] = output[3].plus(input[9].shl::<3>());
output
}
#[inline(always)]
pub(crate) fn combine5<B: Block>(input: &[B; 9]) -> [B; 5] {
let mut output = [input[0], input[1], input[2], input[3], input[4]];
output[0] = output[0].plus(input[5]);
output[1] = output[1].plus(input[5]);
output[2] = output[2].plus(input[5]);
output[3] = output[3].plus(input[5]);
output[4] = output[4].plus(input[5]);
output[0] = output[0].plus(input[6]);
output[1] = output[1].plus(input[6].shl::<1>());
output[2] = output[2].plus(input[6].plus(input[6].shl::<1>()));
output[3] = output[3].plus(input[6].shl::<2>());
output[4] = output[4].plus(input[6].plus(input[6].shl::<2>()));
output[0] = output[0].plus(input[7].shl::<1>());
output[1] = output[1].plus(input[7]);
output[2] = output[2].plus(input[7].shl::<3>());
output[3] = output[3].plus(input[7].plus(input[7].shl::<3>()));
output[4] = output[4].plus(input[7].plus(input[7].shl::<1>()));
output[0] = output[0].plus(input[8].shl::<2>());
output[1] = output[1].plus(input[8].shl::<3>().minus(input[8]));
output[2] = output[2].plus(input[8].plus(input[8].shl::<2>()));
output[3] = output[3].plus(input[8].shl::<3>());
output[4] = output[4].plus(input[8].plus(input[8].shl::<3>()));
output
}