rten_simd/
simd.rs

1//! Traits for SIMD vectors and masks.
2
3use std::fmt::Debug;
4
5use crate::elem::Elem;
6use crate::ops::Isa;
7
8/// Masks used or returned by SIMD operations.
9///
10/// Most operations on masks are available via the
11/// [`MaskOps`](crate::ops::MaskOps) trait. Implementations are obtained via
12/// methods of [`Isa`].
13pub trait Mask: Copy + Debug {
14    type Array: AsRef<[bool]>
15        + Copy
16        + Debug
17        + IntoIterator<Item = bool>
18        + PartialEq<Self::Array>
19        + std::ops::Index<usize, Output = bool>;
20
21    /// Convert this mask to a bool array.
22    fn to_array(self) -> Self::Array;
23}
24
25/// SIMD vector type.
26#[allow(clippy::len_without_is_empty)]
27pub trait Simd: Copy + Debug {
28    /// Representation of this vector as a `[Self::Elem; N]` array.
29    type Array: AsRef<[Self::Elem]>
30        + Copy
31        + Debug
32        + IntoIterator<Item = Self::Elem>
33        + PartialEq<Self::Array>
34        + std::ops::Index<usize, Output = Self::Elem>
35        + std::ops::IndexMut<usize, Output = Self::Elem>;
36
37    /// Type of data held in each SIMD lane.
38    type Elem: Elem;
39
40    /// Mask with the same number of elements as this vector.
41    type Mask: Mask;
42
43    /// The ISA associated with this SIMD vector.
44    type Isa: Isa;
45
46    /// Convert this SIMD vector to the common "bits" type used by all vectors
47    /// in this family.
48    fn to_bits(self) -> <Self::Isa as Isa>::Bits;
49
50    /// Convert this SIMD vector from the common "bits" type used by all vectors
51    /// in this family.
52    fn from_bits(bits: <Self::Isa as Isa>::Bits) -> Self;
53
54    /// Reinterpret the bits of this vector as another vector from the same
55    /// family.
56    fn reinterpret_cast<T>(self) -> T
57    where
58        T: Simd<Isa = Self::Isa>,
59    {
60        T::from_bits(self.to_bits())
61    }
62
63    /// Cast this vector to another with the same ISA and element type.
64    ///
65    /// This cast is a no-op which doesn't generate any code. It is needed in
66    /// some cases to downcast a `Simd` type to one of an `Isa`s associated
67    /// types, or vice-versa.
68    fn same_cast<T>(self) -> T
69    where
70        T: Simd<Elem = Self::Elem, Isa = Self::Isa>,
71    {
72        T::from_bits(self.to_bits())
73    }
74
75    /// Convert `self` to a SIMD array.
76    ///
77    /// This is a cheap transmute in most cases, since SIMD vectors usually
78    /// have the same layout as `[S::Elem; N]` but a greater alignment.
79    fn to_array(self) -> Self::Array;
80}