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}