use crate::simd::Vector256;
#[inline(always)]
pub unsafe fn propagate_horizontal_gaps<Simd256: Vector256>(
row: Simd256,
adjacent_row: Simd256,
match_mask: Simd256,
adjacent_match_mask: Simd256,
gap_open_penalty: Simd256,
gap_extend_penalty: Simd256,
) -> Simd256 {
unsafe {
let shifted_row = row.shift_right_padded_u16::<1>(adjacent_row);
let shifted_match_mask = match_mask.shift_right_padded_u16::<1>(adjacent_match_mask);
let gap_penalty = gap_extend_penalty.add_u16(gap_open_penalty.and(shifted_match_mask));
let decayed = shifted_row.subs_u16(gap_penalty);
let row = row.max_u16(decayed);
let shifted_row = row.shift_right_padded_u16::<2>(adjacent_row);
let shifted_match_mask = match_mask.shift_right_padded_u16::<2>(adjacent_match_mask);
let gap_extend_penalty = gap_extend_penalty.add_u16(gap_extend_penalty);
let gap_penalty = gap_extend_penalty.add_u16(gap_open_penalty.and(shifted_match_mask));
let decayed = shifted_row.subs_u16(gap_penalty);
let row = row.max_u16(decayed);
let shifted_row = row.shift_right_padded_u16::<4>(adjacent_row);
let shifted_match_mask = match_mask.shift_right_padded_u16::<4>(adjacent_match_mask);
let gap_extend_penalty = gap_extend_penalty.add_u16(gap_extend_penalty);
let gap_penalty = gap_extend_penalty.add_u16(gap_open_penalty.and(shifted_match_mask));
let decayed = shifted_row.subs_u16(gap_penalty);
let row = row.max_u16(decayed);
let shifted_row = row.shift_right_padded_u16::<8>(adjacent_row);
let shifted_match_mask = match_mask.shift_right_padded_u16::<8>(adjacent_match_mask);
let gap_extend_penalty = gap_extend_penalty.add_u16(gap_extend_penalty);
let gap_penalty = gap_extend_penalty.add_u16(gap_open_penalty.and(shifted_match_mask));
let decayed = shifted_row.subs_u16(gap_penalty);
row.max_u16(decayed)
}
}