about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJubilee Young <workingjubilee@gmail.com>2021-06-15 10:32:53 -0700
committerJubilee Young <workingjubilee@gmail.com>2021-06-21 16:15:15 -0700
commit16765a10218bbdfc06375961d70477460a53fc01 (patch)
tree687c15cef322fbc38cad81afe1c132299087ba99
parent57e67c905fe9fb3d45a1714d25baa5dfc143299c (diff)
downloadrust-16765a10218bbdfc06375961d70477460a53fc01.tar.gz
rust-16765a10218bbdfc06375961d70477460a53fc01.zip
Introduce SimdArray trait
This provides a general framework for describing relationships
between vector types and scalar types.
-rw-r--r--crates/core_simd/src/array.rs120
-rw-r--r--crates/core_simd/src/lib.rs3
2 files changed, 123 insertions, 0 deletions
diff --git a/crates/core_simd/src/array.rs b/crates/core_simd/src/array.rs
new file mode 100644
index 00000000000..d2f944d1e53
--- /dev/null
+++ b/crates/core_simd/src/array.rs
@@ -0,0 +1,120 @@
+use crate::masks::*;
+use crate::vector::*;
+
+/// A representation of a vector as an "array" with indices, implementing
+/// operations applicable to any vector type based solely on "having lanes",
+/// and describing relationships between vector and scalar types.
+pub trait SimdArray<const LANES: usize>: crate::LanesAtMost32
+where
+    SimdUsize<LANES>: crate::LanesAtMost32,
+    SimdIsize<LANES>: crate::LanesAtMost32,
+    MaskSize<LANES>: crate::Mask,
+    Self: Sized,
+{
+    /// The scalar type in every lane of this vector type.
+    type Scalar: Copy + Sized;
+
+    /// Generates a SIMD vector with the same value in every lane.
+    #[must_use]
+    fn splat(val: Self::Scalar) -> Self;
+}
+
+macro_rules! impl_simdarray_for {
+    ($simd:ident {type Scalar = $scalar:ident;}) => {
+        impl<const LANES: usize> SimdArray<LANES> for $simd<LANES>
+            where SimdUsize<LANES>: crate::LanesAtMost32,
+            SimdIsize<LANES>: crate::LanesAtMost32,
+            MaskSize<LANES>: crate::Mask,
+            Self: crate::LanesAtMost32,
+        {
+            type Scalar = $scalar;
+
+            #[must_use]
+            #[inline]
+            fn splat(val: Self::Scalar) -> Self {
+                [val; LANES].into()
+            }
+        }
+    };
+
+    ($simd:ident $impl:tt) => {
+        impl<const LANES: usize> SimdArray<LANES> for $simd<LANES>
+            where SimdUsize<LANES>: crate::LanesAtMost32,
+            SimdIsize<LANES>: crate::LanesAtMost32,
+            MaskSize<LANES>: crate::Mask,
+            Self: crate::LanesAtMost32,
+        $impl
+    }
+}
+
+impl_simdarray_for! {
+    SimdUsize {
+        type Scalar = usize;
+    }
+}
+
+impl_simdarray_for! {
+    SimdIsize {
+        type Scalar = isize;
+    }
+}
+
+impl_simdarray_for! {
+    SimdI8 {
+        type Scalar = i8;
+    }
+}
+
+impl_simdarray_for! {
+    SimdI16 {
+        type Scalar = i16;
+    }
+}
+
+impl_simdarray_for! {
+    SimdI32 {
+        type Scalar = i32;
+    }
+}
+
+impl_simdarray_for! {
+    SimdI64 {
+        type Scalar = i64;
+    }
+}
+
+impl_simdarray_for! {
+    SimdU8 {
+        type Scalar = u8;
+    }
+}
+
+impl_simdarray_for! {
+    SimdU16 {
+        type Scalar = u16;
+    }
+}
+
+impl_simdarray_for! {
+    SimdU32 {
+        type Scalar = u32;
+    }
+}
+
+impl_simdarray_for! {
+    SimdU64 {
+        type Scalar = u64;
+    }
+}
+
+impl_simdarray_for! {
+    SimdF32 {
+        type Scalar = f32;
+    }
+}
+
+impl_simdarray_for! {
+    SimdF64 {
+        type Scalar = f64;
+    }
+}
diff --git a/crates/core_simd/src/lib.rs b/crates/core_simd/src/lib.rs
index 7fe7d666e8d..1e68cf5d428 100644
--- a/crates/core_simd/src/lib.rs
+++ b/crates/core_simd/src/lib.rs
@@ -35,3 +35,6 @@ pub use masks::*;
 
 mod vector;
 pub use vector::*;
+
+mod array;
+pub use array::SimdArray;