#[cfg(target_arch = "x86_64")]
mod avx;
#[cfg(target_arch = "x86_64")]
mod avx512;
#[cfg(target_arch = "aarch64")]
mod neon;
mod scalar;
#[cfg(target_arch = "x86_64")]
mod sse;
#[cfg(target_arch = "x86_64")]
pub use avx::{BackendAVX, BackendAVXU8};
#[cfg(target_arch = "x86_64")]
pub use avx512::{BackendAVX512, BackendAVX512U8};
#[cfg(target_arch = "aarch64")]
pub use neon::{BackendNEON, BackendNEONU8};
pub use scalar::{BackendScalar8, BackendScalar16U8};
#[cfg(target_arch = "x86_64")]
pub use sse::{BackendSSE, BackendSSEU8};
pub trait Backend: Sized + core::fmt::Debug + Clone + 'static {
const LANES: usize;
const LANE_BYTES: usize;
type Bytes: BytesVec<Mask = Self::Mask>;
type Mask: MaskVec;
type Score: ScoreVec;
fn is_available() -> bool;
unsafe fn widen_mask(m: Self::Mask) -> Self::Score;
unsafe fn propagate_horizontal_gaps(
row: Self::Score,
adjacent_row: Self::Score,
match_mask: Self::Score,
adjacent_match_mask: Self::Score,
gap_open_penalty: Self::Score,
gap_extend_penalty: Self::Score,
) -> Self::Score;
#[allow(clippy::too_many_arguments)]
unsafe fn propagate_horizontal_unicode_gaps(
row: Self::Score,
adjacent_row: Self::Score,
pending_gap_open_mask: Self::Score,
adjacent_pending_gap_open_mask: Self::Score,
continuation_gap_extend_penalty: Self::Score,
adjacent_continuation_gap_extend_penalty: Self::Score,
scalar_end_mask: Self::Score,
adjacent_scalar_end_mask: Self::Score,
gap_open_penalty: Self::Score,
gap_extend_penalty: Self::Score,
) -> (Self::Score, Self::Score);
}
pub trait BytesVec: Copy + core::fmt::Debug {
type Mask: MaskVec;
unsafe fn splat(value: u8) -> Self;
unsafe fn eq(self, other: Self) -> Self::Mask;
unsafe fn gt(self, other: Self) -> Self::Mask;
unsafe fn lt(self, other: Self) -> Self::Mask;
unsafe fn load_partial(data: *const u8, start: usize, len: usize) -> Self;
#[cfg(test)]
fn from_lanes(values: &[u8]) -> Self;
#[cfg(test)]
fn to_lanes(self) -> Vec<u8>;
}
pub trait MaskVec: Copy + core::fmt::Debug {
unsafe fn zero() -> Self;
unsafe fn and(self, other: Self) -> Self;
unsafe fn or(self, other: Self) -> Self;
unsafe fn not(self) -> Self;
unsafe fn is_zero(self) -> bool;
unsafe fn shift_right_padded_1(self, prev: Self) -> Self;
#[cfg(test)]
fn from_lanes(values: &[bool]) -> Self;
#[cfg(test)]
fn to_lanes(self) -> Vec<bool>;
}
pub trait ScoreVec: Copy + core::fmt::Debug {
unsafe fn zero() -> Self;
unsafe fn splat(value: u16) -> Self;
unsafe fn first_lane(value: u16) -> Self;
unsafe fn max(self, other: Self) -> Self;
unsafe fn horizontal_max(self) -> u16;
unsafe fn add(self, other: Self) -> Self;
unsafe fn subs(self, other: Self) -> Self;
unsafe fn and(self, other: Self) -> Self;
unsafe fn shift_right_padded<const L: i32>(self, prev: Self) -> Self;
unsafe fn find_lane(self, search: u16) -> usize;
#[cfg(test)]
fn from_lanes(values: &[u16]) -> Self;
#[cfg(test)]
fn to_lanes(self) -> Vec<u16>;
}
#[cfg(test)]
mod tests;