about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--crates/core_simd/src/fmt.rs102
-rw-r--r--crates/core_simd/src/lib.rs1
-rw-r--r--crates/core_simd/src/permute.rs21
-rw-r--r--crates/core_simd/src/vector.rs338
-rw-r--r--crates/core_simd/src/vector/float.rs1
-rw-r--r--crates/core_simd/src/vector/int.rs24
-rw-r--r--crates/core_simd/src/vector/uint.rs26
-rw-r--r--crates/core_simd/src/vector/vector_impl.rs257
8 files changed, 370 insertions, 400 deletions
diff --git a/crates/core_simd/src/fmt.rs b/crates/core_simd/src/fmt.rs
index 78ae5ce3fce..9ad3a6c100e 100644
--- a/crates/core_simd/src/fmt.rs
+++ b/crates/core_simd/src/fmt.rs
@@ -1,88 +1,36 @@
-macro_rules! debug_wrapper {
-    { $($trait:ident => $name:ident,)* } => {
+macro_rules! impl_fmt_trait {
+    { $($trait:ident,)* } => {
         $(
-            pub(crate) fn $name<T: core::fmt::$trait>(slice: &[T], f: &mut core::fmt::Formatter) -> core::fmt::Result {
-                #[repr(transparent)]
-                struct Wrapper<'a, T: core::fmt::$trait>(&'a T);
+            impl<Element, const LANES: usize> core::fmt::$trait for crate::Simd<Element, LANES>
+            where
+                crate::LaneCount<LANES>: crate::SupportedLaneCount,
+                Element: crate::SimdElement + core::fmt::$trait,
+            {
+                fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
+                    #[repr(transparent)]
+                    struct Wrapper<'a, T: core::fmt::$trait>(&'a T);
 
-                impl<T: core::fmt::$trait> core::fmt::Debug for Wrapper<'_, T> {
-                    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
-                        self.0.fmt(f)
+                    impl<T: core::fmt::$trait> core::fmt::Debug for Wrapper<'_, T> {
+                        fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
+                            self.0.fmt(f)
+                        }
                     }
-                }
-
-                f.debug_list()
-                    .entries(slice.iter().map(|x| Wrapper(x)))
-                    .finish()
-            }
-        )*
-    }
-}
 
-debug_wrapper! {
-    Debug => format,
-    Binary => format_binary,
-    LowerExp => format_lower_exp,
-    UpperExp => format_upper_exp,
-    Octal => format_octal,
-    LowerHex => format_lower_hex,
-    UpperHex => format_upper_hex,
-}
-
-macro_rules! impl_fmt_trait {
-    { $($type:ident => $(($trait:ident, $format:ident)),*;)* } => {
-        $( // repeat type
-            $( // repeat trait
-                impl<const LANES: usize> core::fmt::$trait for crate::$type<LANES>
-                where
-                    crate::LaneCount<LANES>: crate::SupportedLaneCount,
-                {
-                    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
-                        $format(self.as_ref(), f)
-                    }
+                    f.debug_list()
+                        .entries(self.as_array().iter().map(|x| Wrapper(x)))
+                        .finish()
                 }
-            )*
+            }
         )*
-    };
-    { integers: $($type:ident,)* } => {
-        impl_fmt_trait! {
-            $($type =>
-              (Debug, format),
-              (Binary, format_binary),
-              (LowerExp, format_lower_exp),
-              (UpperExp, format_upper_exp),
-              (Octal, format_octal),
-              (LowerHex, format_lower_hex),
-              (UpperHex, format_upper_hex);
-            )*
-        }
-    };
-    { floats: $($type:ident,)* } => {
-        impl_fmt_trait! {
-            $($type =>
-              (Debug, format),
-              (LowerExp, format_lower_exp),
-              (UpperExp, format_upper_exp);
-            )*
-        }
-    };
-    { masks: $($type:ident,)* } => {
-        impl_fmt_trait! {
-            $($type =>
-              (Debug, format);
-            )*
-        }
     }
 }
 
 impl_fmt_trait! {
-    integers:
-        SimdU8, SimdU16, SimdU32, SimdU64,
-        SimdI8, SimdI16, SimdI32, SimdI64,
-        SimdUsize, SimdIsize,
-}
-
-impl_fmt_trait! {
-    floats:
-        SimdF32, SimdF64,
+    Debug,
+    Binary,
+    LowerExp,
+    UpperExp,
+    Octal,
+    LowerHex,
+    UpperHex,
 }
diff --git a/crates/core_simd/src/lib.rs b/crates/core_simd/src/lib.rs
index 5f88e3c63b5..fc0df1813b9 100644
--- a/crates/core_simd/src/lib.rs
+++ b/crates/core_simd/src/lib.rs
@@ -2,6 +2,7 @@
 #![allow(incomplete_features)]
 #![feature(
     const_evaluatable_checked,
+    const_fn_trait_bound,
     const_generics,
     platform_intrinsics,
     repr_simd,
diff --git a/crates/core_simd/src/permute.rs b/crates/core_simd/src/permute.rs
index 01148a26bad..4e377d68915 100644
--- a/crates/core_simd/src/permute.rs
+++ b/crates/core_simd/src/permute.rs
@@ -1,6 +1,9 @@
 macro_rules! impl_shuffle_lane {
-    { $name:ident, $fn:ident, $n:literal } => {
-        impl $name<$n> {
+    { $fn:ident, $n:literal } => {
+        impl<Element> crate::Simd<Element, $n>
+        where
+            Element: crate::SimdElement,
+        {
             /// A const SIMD shuffle that takes 2 SIMD vectors and produces another vector, using
             /// the indices in the const parameter. The first or "self" vector will have its lanes
             /// indexed from 0, and the second vector will have its first lane indexed at $n.
@@ -138,12 +141,8 @@ macro_rules! impl_shuffle_lane {
     }
 }
 
-macro_rules! impl_shuffle_2pow_lanes {
-    { $name:ident } => {
-        impl_shuffle_lane!{ $name, simd_shuffle2, 2 }
-        impl_shuffle_lane!{ $name, simd_shuffle4, 4 }
-        impl_shuffle_lane!{ $name, simd_shuffle8, 8 }
-        impl_shuffle_lane!{ $name, simd_shuffle16, 16 }
-        impl_shuffle_lane!{ $name, simd_shuffle32, 32 }
-    }
-}
+impl_shuffle_lane! { simd_shuffle2, 2 }
+impl_shuffle_lane! { simd_shuffle4, 4 }
+impl_shuffle_lane! { simd_shuffle8, 8 }
+impl_shuffle_lane! { simd_shuffle16, 16 }
+impl_shuffle_lane! { simd_shuffle32, 32 }
diff --git a/crates/core_simd/src/vector.rs b/crates/core_simd/src/vector.rs
index ea1a732f203..2e3855bff3c 100644
--- a/crates/core_simd/src/vector.rs
+++ b/crates/core_simd/src/vector.rs
@@ -1,6 +1,3 @@
-#[macro_use]
-mod vector_impl;
-
 mod float;
 mod int;
 mod uint;
@@ -21,13 +18,325 @@ where
     Element: SimdElement,
     LaneCount<LANES>: SupportedLaneCount;
 
+impl<Element, const LANES: usize> Simd<Element, LANES>
+where
+    LaneCount<LANES>: SupportedLaneCount,
+    Element: SimdElement,
+{
+    /// Construct a SIMD vector by setting all lanes to the given value.
+    pub const fn splat(value: Element) -> Self {
+        Self([value; LANES])
+    }
+
+    /// Returns an array reference containing the entire SIMD vector.
+    pub const fn as_array(&self) -> &[Element; LANES] {
+        &self.0
+    }
+
+    /// Returns a mutable array reference containing the entire SIMD vector.
+    pub fn as_mut_array(&mut self) -> &mut [Element; LANES] {
+        &mut self.0
+    }
+
+    /// Converts an array to a SIMD vector.
+    pub const fn from_array(array: [Element; LANES]) -> Self {
+        Self(array)
+    }
+
+    /// Converts a SIMD vector to an array.
+    pub const fn to_array(self) -> [Element; LANES] {
+        self.0
+    }
+
+    /// SIMD gather: construct a SIMD vector by reading from a slice, using potentially discontiguous indices.
+    /// If an index is out of bounds, that lane instead selects the value from the "or" vector.
+    /// ```
+    /// # #![feature(portable_simd)]
+    /// # use core_simd::*;
+    /// let vec: Vec<i32> = vec![10, 11, 12, 13, 14, 15, 16, 17, 18];
+    /// let idxs = SimdUsize::<4>::from_array([9, 3, 0, 5]);
+    /// let alt = SimdI32::from_array([-5, -4, -3, -2]);
+    ///
+    /// let result = SimdI32::<4>::gather_or(&vec, idxs, alt); // Note the lane that is out-of-bounds.
+    /// assert_eq!(result, SimdI32::from_array([-5, 13, 10, 15]));
+    /// ```
+    #[must_use]
+    #[inline]
+    pub fn gather_or(slice: &[Element], idxs: crate::SimdUsize<LANES>, or: Self) -> Self {
+        Self::gather_select(slice, crate::MaskSize::splat(true), idxs, or)
+    }
+
+    /// SIMD gather: construct a SIMD vector by reading from a slice, using potentially discontiguous indices.
+    /// Out-of-bounds indices instead use the default value for that lane (0).
+    /// ```
+    /// # #![feature(portable_simd)]
+    /// # use core_simd::*;
+    /// let vec: Vec<i32> = vec![10, 11, 12, 13, 14, 15, 16, 17, 18];
+    /// let idxs = SimdUsize::<4>::from_array([9, 3, 0, 5]);
+    ///
+    /// let result = SimdI32::<4>::gather_or_default(&vec, idxs); // Note the lane that is out-of-bounds.
+    /// assert_eq!(result, SimdI32::from_array([0, 13, 10, 15]));
+    /// ```
+    #[must_use]
+    #[inline]
+    pub fn gather_or_default(slice: &[Element], idxs: crate::SimdUsize<LANES>) -> Self
+    where
+        Element: Default,
+    {
+        Self::gather_or(slice, idxs, Self::splat(Element::default()))
+    }
+
+    /// SIMD gather: construct a SIMD vector by reading from a slice, using potentially discontiguous indices.
+    /// Out-of-bounds or masked indices instead select the value from the "or" vector.
+    /// ```
+    /// # #![feature(portable_simd)]
+    /// # use core_simd::*;
+    /// let vec: Vec<i32> = vec![10, 11, 12, 13, 14, 15, 16, 17, 18];
+    /// let idxs = SimdUsize::<4>::from_array([9, 3, 0, 5]);
+    /// let alt = SimdI32::from_array([-5, -4, -3, -2]);
+    /// let mask = MaskSize::from_array([true, true, true, false]); // Note the mask of the last lane.
+    ///
+    /// let result = SimdI32::<4>::gather_select(&vec, mask, idxs, alt); // Note the lane that is out-of-bounds.
+    /// assert_eq!(result, SimdI32::from_array([-5, 13, 10, -2]));
+    /// ```
+    #[must_use]
+    #[inline]
+    pub fn gather_select(
+        slice: &[Element],
+        mask: crate::MaskSize<LANES>,
+        idxs: crate::SimdUsize<LANES>,
+        or: Self,
+    ) -> Self {
+        let mask = (mask & idxs.lanes_lt(crate::SimdUsize::splat(slice.len()))).to_int();
+        let base_ptr = crate::vector::ptr::SimdConstPtr::splat(slice.as_ptr());
+        // Ferris forgive me, I have done pointer arithmetic here.
+        let ptrs = base_ptr.wrapping_add(idxs);
+        // SAFETY: The ptrs have been bounds-masked to prevent memory-unsafe reads insha'allah
+        unsafe { crate::intrinsics::simd_gather(or, ptrs, mask) }
+    }
+
+    /// SIMD scatter: write a SIMD vector's values into a slice, using potentially discontiguous indices.
+    /// Out-of-bounds indices are not written.
+    /// `scatter` writes "in order", so if an index receives two writes, only the last is guaranteed.
+    /// ```
+    /// # #![feature(portable_simd)]
+    /// # use core_simd::*;
+    /// let mut vec: Vec<i32> = vec![10, 11, 12, 13, 14, 15, 16, 17, 18];
+    /// let idxs = SimdUsize::<4>::from_array([9, 3, 0, 0]);
+    /// let vals = SimdI32::from_array([-27, 82, -41, 124]);
+    ///
+    /// vals.scatter(&mut vec, idxs); // index 0 receives two writes.
+    /// assert_eq!(vec, vec![124, 11, 12, 82, 14, 15, 16, 17, 18]);
+    /// ```
+    #[inline]
+    pub fn scatter(self, slice: &mut [Element], idxs: crate::SimdUsize<LANES>) {
+        self.scatter_select(slice, crate::MaskSize::splat(true), idxs)
+    }
+
+    /// SIMD scatter: write a SIMD vector's values into a slice, using potentially discontiguous indices.
+    /// Out-of-bounds or masked indices are not written.
+    /// `scatter_select` writes "in order", so if an index receives two writes, only the last is guaranteed.
+    /// ```
+    /// # #![feature(portable_simd)]
+    /// # use core_simd::*;
+    /// let mut vec: Vec<i32> = vec![10, 11, 12, 13, 14, 15, 16, 17, 18];
+    /// let idxs = SimdUsize::<4>::from_array([9, 3, 0, 0]);
+    /// let vals = SimdI32::from_array([-27, 82, -41, 124]);
+    /// let mask = MaskSize::from_array([true, true, true, false]); // Note the mask of the last lane.
+    ///
+    /// vals.scatter_select(&mut vec, mask, idxs); // index 0's second write is masked, thus omitted.
+    /// assert_eq!(vec, vec![-41, 11, 12, 82, 14, 15, 16, 17, 18]);
+    /// ```
+    #[inline]
+    pub fn scatter_select(
+        self,
+        slice: &mut [Element],
+        mask: crate::MaskSize<LANES>,
+        idxs: crate::SimdUsize<LANES>,
+    ) {
+        // We must construct our scatter mask before we derive a pointer!
+        let mask = (mask & idxs.lanes_lt(crate::SimdUsize::splat(slice.len()))).to_int();
+        // SAFETY: This block works with *mut T derived from &mut 'a [T],
+        // which means it is delicate in Rust's borrowing model, circa 2021:
+        // &mut 'a [T] asserts uniqueness, so deriving &'a [T] invalidates live *mut Ts!
+        // Even though this block is largely safe methods, it must be almost exactly this way
+        // to prevent invalidating the raw ptrs while they're live.
+        // Thus, entering this block requires all values to use being already ready:
+        // 0. idxs we want to write to, which are used to construct the mask.
+        // 1. mask, which depends on an initial &'a [T] and the idxs.
+        // 2. actual values to scatter (self).
+        // 3. &mut [T] which will become our base ptr.
+        unsafe {
+            // Now Entering ☢️ *mut T Zone
+            let base_ptr = crate::vector::ptr::SimdMutPtr::splat(slice.as_mut_ptr());
+            // Ferris forgive me, I have done pointer arithmetic here.
+            let ptrs = base_ptr.wrapping_add(idxs);
+            // The ptrs have been bounds-masked to prevent memory-unsafe writes insha'allah
+            crate::intrinsics::simd_scatter(self, ptrs, mask)
+            // Cleared ☢️ *mut T Zone
+        }
+    }
+}
+
+impl<Element, const LANES: usize> Copy for Simd<Element, LANES>
+where
+    Element: SimdElement,
+    LaneCount<LANES>: SupportedLaneCount,
+{
+}
+
+impl<Element, const LANES: usize> Clone for Simd<Element, LANES>
+where
+    Element: SimdElement,
+    LaneCount<LANES>: SupportedLaneCount,
+{
+    fn clone(&self) -> Self {
+        *self
+    }
+}
+
+impl<Element, const LANES: usize> Default for Simd<Element, LANES>
+where
+    LaneCount<LANES>: SupportedLaneCount,
+    Element: SimdElement + Default,
+{
+    #[inline]
+    fn default() -> Self {
+        Self::splat(Element::default())
+    }
+}
+
+impl<Element, const LANES: usize> PartialEq for Simd<Element, LANES>
+where
+    LaneCount<LANES>: SupportedLaneCount,
+    Element: SimdElement + PartialEq,
+{
+    #[inline]
+    fn eq(&self, other: &Self) -> bool {
+        // TODO use SIMD equality
+        self.to_array() == other.to_array()
+    }
+}
+
+impl<Element, const LANES: usize> PartialOrd for Simd<Element, LANES>
+where
+    LaneCount<LANES>: SupportedLaneCount,
+    Element: SimdElement + PartialOrd,
+{
+    #[inline]
+    fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
+        // TODO use SIMD equality
+        self.to_array().partial_cmp(other.as_ref())
+    }
+}
+
+impl<Element, const LANES: usize> Eq for Simd<Element, LANES>
+where
+    LaneCount<LANES>: SupportedLaneCount,
+    Element: SimdElement + Eq,
+{
+}
+
+impl<Element, const LANES: usize> Ord for Simd<Element, LANES>
+where
+    LaneCount<LANES>: SupportedLaneCount,
+    Element: SimdElement + Ord,
+{
+    #[inline]
+    fn cmp(&self, other: &Self) -> core::cmp::Ordering {
+        // TODO use SIMD equality
+        self.to_array().cmp(other.as_ref())
+    }
+}
+
+impl<Element, const LANES: usize> core::hash::Hash for Simd<Element, LANES>
+where
+    LaneCount<LANES>: SupportedLaneCount,
+    Element: SimdElement + core::hash::Hash,
+{
+    #[inline]
+    fn hash<H>(&self, state: &mut H)
+    where
+        H: core::hash::Hasher,
+    {
+        self.as_array().hash(state)
+    }
+}
+
+// array references
+impl<Element, const LANES: usize> AsRef<[Element; LANES]> for Simd<Element, LANES>
+where
+    LaneCount<LANES>: SupportedLaneCount,
+    Element: SimdElement,
+{
+    #[inline]
+    fn as_ref(&self) -> &[Element; LANES] {
+        &self.0
+    }
+}
+
+impl<Element, const LANES: usize> AsMut<[Element; LANES]> for Simd<Element, LANES>
+where
+    LaneCount<LANES>: SupportedLaneCount,
+    Element: SimdElement,
+{
+    #[inline]
+    fn as_mut(&mut self) -> &mut [Element; LANES] {
+        &mut self.0
+    }
+}
+
+// slice references
+impl<Element, const LANES: usize> AsRef<[Element]> for Simd<Element, LANES>
+where
+    LaneCount<LANES>: SupportedLaneCount,
+    Element: SimdElement,
+{
+    #[inline]
+    fn as_ref(&self) -> &[Element] {
+        &self.0
+    }
+}
+
+impl<Element, const LANES: usize> AsMut<[Element]> for Simd<Element, LANES>
+where
+    LaneCount<LANES>: SupportedLaneCount,
+    Element: SimdElement,
+{
+    #[inline]
+    fn as_mut(&mut self) -> &mut [Element] {
+        &mut self.0
+    }
+}
+
+// vector/array conversion
+impl<Element, const LANES: usize> From<[Element; LANES]> for Simd<Element, LANES>
+where
+    LaneCount<LANES>: SupportedLaneCount,
+    Element: SimdElement,
+{
+    fn from(array: [Element; LANES]) -> Self {
+        Self(array)
+    }
+}
+
+impl<Element, const LANES: usize> From<Simd<Element, LANES>> for [Element; LANES]
+where
+    LaneCount<LANES>: SupportedLaneCount,
+    Element: SimdElement,
+{
+    fn from(vector: Simd<Element, LANES>) -> Self {
+        vector.to_array()
+    }
+}
+
 mod sealed {
     pub trait Sealed {}
 }
 use sealed::Sealed;
 
 /// Marker trait for types that may be used as SIMD vector elements.
-pub unsafe trait SimdElement: Sealed {
+pub unsafe trait SimdElement: Sealed + Copy {
     /// The mask element type corresponding to this element type.
     type Mask: SimdElement;
 }
@@ -106,3 +415,24 @@ pub trait Vector: sealed::Sealed {
     #[must_use]
     fn splat(val: Self::Scalar) -> Self;
 }
+
+impl<Element, const LANES: usize> Sealed for Simd<Element, LANES>
+where
+    LaneCount<LANES>: SupportedLaneCount,
+    Element: SimdElement,
+{
+}
+
+impl<Element, const LANES: usize> Vector for Simd<Element, LANES>
+where
+    LaneCount<LANES>: SupportedLaneCount,
+    Element: SimdElement,
+{
+    type Scalar = Element;
+    const LANES: usize = LANES;
+
+    #[inline]
+    fn splat(val: Self::Scalar) -> Self {
+        Self::splat(val)
+    }
+}
diff --git a/crates/core_simd/src/vector/float.rs b/crates/core_simd/src/vector/float.rs
index 231fe590ada..40959d66872 100644
--- a/crates/core_simd/src/vector/float.rs
+++ b/crates/core_simd/src/vector/float.rs
@@ -7,7 +7,6 @@ use crate::{LaneCount, SupportedLaneCount};
 /// representation. Called from `define_float_vector!`.
 macro_rules! impl_float_vector {
     { $name:ident, $type:ident, $bits_ty:ident, $mask_ty:ident, $mask_impl_ty:ident } => {
-        impl_vector! { $name, $type }
         impl_float_reductions! { $name, $type }
 
         impl<const LANES: usize> $name<LANES>
diff --git a/crates/core_simd/src/vector/int.rs b/crates/core_simd/src/vector/int.rs
index 88a17daa2f4..74c4a0f2fb6 100644
--- a/crates/core_simd/src/vector/int.rs
+++ b/crates/core_simd/src/vector/int.rs
@@ -5,32 +5,8 @@ use crate::{LaneCount, SupportedLaneCount};
 /// Implements additional integer traits (Eq, Ord, Hash) on the specified vector `$name`, holding multiple `$lanes` of `$type`.
 macro_rules! impl_integer_vector {
     { $name:ident, $type:ty, $mask_ty:ident, $mask_impl_ty:ident } => {
-        impl_vector! { $name, $type }
         impl_integer_reductions! { $name, $type }
 
-        impl<const LANES: usize> Eq for $name<LANES> where LaneCount<LANES>: SupportedLaneCount {}
-
-        impl<const LANES: usize> Ord for $name<LANES> where LaneCount<LANES>: SupportedLaneCount {
-            #[inline]
-            fn cmp(&self, other: &Self) -> core::cmp::Ordering {
-                // TODO use SIMD cmp
-                self.as_array().cmp(other.as_ref())
-            }
-        }
-
-        impl<const LANES: usize> core::hash::Hash for $name<LANES>
-        where
-            LaneCount<LANES>: SupportedLaneCount,
-        {
-            #[inline]
-            fn hash<H>(&self, state: &mut H)
-            where
-                H: core::hash::Hasher
-            {
-                self.as_array().hash(state)
-            }
-        }
-
         impl<const LANES: usize> $name<LANES>
         where
             LaneCount<LANES>: SupportedLaneCount,
diff --git a/crates/core_simd/src/vector/uint.rs b/crates/core_simd/src/vector/uint.rs
index 5bd1a7fd67f..6dfcbe79593 100644
--- a/crates/core_simd/src/vector/uint.rs
+++ b/crates/core_simd/src/vector/uint.rs
@@ -1,35 +1,9 @@
 #![allow(non_camel_case_types)]
 
-use crate::{LaneCount, SupportedLaneCount};
-
 /// Implements additional integer traits (Eq, Ord, Hash) on the specified vector `$name`, holding multiple `$lanes` of `$type`.
 macro_rules! impl_unsigned_vector {
     { $name:ident, $type:ty } => {
-        impl_vector! { $name, $type }
         impl_integer_reductions! { $name, $type }
-
-        impl<const LANES: usize> Eq for $name<LANES> where LaneCount<LANES>: SupportedLaneCount {}
-
-        impl<const LANES: usize> Ord for $name<LANES> where LaneCount<LANES>: SupportedLaneCount {
-            #[inline]
-            fn cmp(&self, other: &Self) -> core::cmp::Ordering {
-                // TODO use SIMD cmp
-                self.as_array().cmp(other.as_ref())
-            }
-        }
-
-        impl<const LANES: usize> core::hash::Hash for $name<LANES>
-        where
-            LaneCount<LANES>: SupportedLaneCount,
-        {
-            #[inline]
-            fn hash<H>(&self, state: &mut H)
-            where
-                H: core::hash::Hasher
-            {
-                self.as_array().hash(state)
-            }
-        }
     }
 }
 
diff --git a/crates/core_simd/src/vector/vector_impl.rs b/crates/core_simd/src/vector/vector_impl.rs
deleted file mode 100644
index 58ea244adfc..00000000000
--- a/crates/core_simd/src/vector/vector_impl.rs
+++ /dev/null
@@ -1,257 +0,0 @@
-/// Implements common traits on the specified vector `$name`, holding multiple `$lanes` of `$type`.
-macro_rules! impl_vector {
-    { $name:ident, $type:ty } => {
-        impl<const LANES: usize> crate::vector::sealed::Sealed for $name<LANES>
-        where
-            crate::LaneCount<LANES>: crate::SupportedLaneCount,
-        {}
-
-        impl<const LANES: usize> crate::vector::Vector for $name<LANES>
-        where
-            crate::LaneCount<LANES>: crate::SupportedLaneCount,
-        {
-            type Scalar = $type;
-            const LANES: usize = LANES;
-
-            #[inline]
-            fn splat(val: Self::Scalar) -> Self {
-                Self::splat(val)
-            }
-        }
-
-        impl<const LANES: usize> $name<LANES>
-        where
-            crate::LaneCount<LANES>: crate::SupportedLaneCount,
-        {
-            /// Construct a SIMD vector by setting all lanes to the given value.
-            pub const fn splat(value: $type) -> Self {
-                Self([value; LANES])
-            }
-
-            /// Returns an array reference containing the entire SIMD vector.
-            pub const fn as_array(&self) -> &[$type; LANES] {
-                &self.0
-            }
-
-            /// Returns a mutable array reference containing the entire SIMD vector.
-            pub fn as_mut_array(&mut self) -> &mut [$type; LANES] {
-                &mut self.0
-            }
-
-            /// Converts an array to a SIMD vector.
-            pub const fn from_array(array: [$type; LANES]) -> Self {
-                Self(array)
-            }
-
-            /// Converts a SIMD vector to an array.
-            pub const fn to_array(self) -> [$type; LANES] {
-                self.0
-            }
-
-            /// SIMD gather: construct a SIMD vector by reading from a slice, using potentially discontiguous indices.
-            /// If an index is out of bounds, that lane instead selects the value from the "or" vector.
-            /// ```
-            /// # #![feature(portable_simd)]
-            /// # use core_simd::*;
-            /// let vec: Vec<i32> = vec![10, 11, 12, 13, 14, 15, 16, 17, 18];
-            /// let idxs = SimdUsize::<4>::from_array([9, 3, 0, 5]);
-            /// let alt = SimdI32::from_array([-5, -4, -3, -2]);
-            ///
-            /// let result = SimdI32::<4>::gather_or(&vec, idxs, alt); // Note the lane that is out-of-bounds.
-            /// assert_eq!(result, SimdI32::from_array([-5, 13, 10, 15]));
-            /// ```
-            #[must_use]
-            #[inline]
-            pub fn gather_or(slice: &[$type], idxs: crate::SimdUsize<LANES>, or: Self) -> Self {
-                Self::gather_select(slice, crate::MaskSize::splat(true), idxs, or)
-            }
-
-            /// SIMD gather: construct a SIMD vector by reading from a slice, using potentially discontiguous indices.
-            /// Out-of-bounds indices instead use the default value for that lane (0).
-            /// ```
-            /// # #![feature(portable_simd)]
-            /// # use core_simd::*;
-            /// let vec: Vec<i32> = vec![10, 11, 12, 13, 14, 15, 16, 17, 18];
-            /// let idxs = SimdUsize::<4>::from_array([9, 3, 0, 5]);
-            ///
-            /// let result = SimdI32::<4>::gather_or_default(&vec, idxs); // Note the lane that is out-of-bounds.
-            /// assert_eq!(result, SimdI32::from_array([0, 13, 10, 15]));
-            /// ```
-            #[must_use]
-            #[inline]
-            pub fn gather_or_default(slice: &[$type], idxs: crate::SimdUsize<LANES>) -> Self {
-                Self::gather_or(slice, idxs, Self::splat(<$type>::default()))
-            }
-
-            /// SIMD gather: construct a SIMD vector by reading from a slice, using potentially discontiguous indices.
-            /// Out-of-bounds or masked indices instead select the value from the "or" vector.
-            /// ```
-            /// # #![feature(portable_simd)]
-            /// # use core_simd::*;
-            /// let vec: Vec<i32> = vec![10, 11, 12, 13, 14, 15, 16, 17, 18];
-            /// let idxs = SimdUsize::<4>::from_array([9, 3, 0, 5]);
-            /// let alt = SimdI32::from_array([-5, -4, -3, -2]);
-            /// let mask = MaskSize::from_array([true, true, true, false]); // Note the mask of the last lane.
-            ///
-            /// let result = SimdI32::<4>::gather_select(&vec, mask, idxs, alt); // Note the lane that is out-of-bounds.
-            /// assert_eq!(result, SimdI32::from_array([-5, 13, 10, -2]));
-            /// ```
-            #[must_use]
-            #[inline]
-            pub fn gather_select(
-                slice: &[$type],
-                mask: crate::MaskSize<LANES>,
-                idxs: crate::SimdUsize<LANES>,
-                or: Self,
-            ) -> Self
-            {
-                let mask = (mask & idxs.lanes_lt(crate::SimdUsize::splat(slice.len()))).to_int();
-                let base_ptr = crate::vector::ptr::SimdConstPtr::splat(slice.as_ptr());
-                // Ferris forgive me, I have done pointer arithmetic here.
-                let ptrs = base_ptr.wrapping_add(idxs);
-                // SAFETY: The ptrs have been bounds-masked to prevent memory-unsafe reads insha'allah
-                unsafe { crate::intrinsics::simd_gather(or, ptrs, mask) }
-            }
-
-            /// SIMD scatter: write a SIMD vector's values into a slice, using potentially discontiguous indices.
-            /// Out-of-bounds indices are not written.
-            /// `scatter` writes "in order", so if an index receives two writes, only the last is guaranteed.
-            /// ```
-            /// # #![feature(portable_simd)]
-            /// # use core_simd::*;
-            /// let mut vec: Vec<i32> = vec![10, 11, 12, 13, 14, 15, 16, 17, 18];
-            /// let idxs = SimdUsize::<4>::from_array([9, 3, 0, 0]);
-            /// let vals = SimdI32::from_array([-27, 82, -41, 124]);
-            ///
-            /// vals.scatter(&mut vec, idxs); // index 0 receives two writes.
-            /// assert_eq!(vec, vec![124, 11, 12, 82, 14, 15, 16, 17, 18]);
-            /// ```
-            #[inline]
-            pub fn scatter(self, slice: &mut [$type], idxs: crate::SimdUsize<LANES>) {
-                self.scatter_select(slice, crate::MaskSize::splat(true), idxs)
-            }
-
-            /// SIMD scatter: write a SIMD vector's values into a slice, using potentially discontiguous indices.
-            /// Out-of-bounds or masked indices are not written.
-            /// `scatter_select` writes "in order", so if an index receives two writes, only the last is guaranteed.
-            /// ```
-            /// # #![feature(portable_simd)]
-            /// # use core_simd::*;
-            /// let mut vec: Vec<i32> = vec![10, 11, 12, 13, 14, 15, 16, 17, 18];
-            /// let idxs = SimdUsize::<4>::from_array([9, 3, 0, 0]);
-            /// let vals = SimdI32::from_array([-27, 82, -41, 124]);
-            /// let mask = MaskSize::from_array([true, true, true, false]); // Note the mask of the last lane.
-            ///
-            /// vals.scatter_select(&mut vec, mask, idxs); // index 0's second write is masked, thus omitted.
-            /// assert_eq!(vec, vec![-41, 11, 12, 82, 14, 15, 16, 17, 18]);
-            /// ```
-            #[inline]
-            pub fn scatter_select(
-                self,
-                slice: &mut [$type],
-                mask: crate::MaskSize<LANES>,
-                idxs: crate::SimdUsize<LANES>,
-            )
-            {
-                // We must construct our scatter mask before we derive a pointer!
-                let mask = (mask & idxs.lanes_lt(crate::SimdUsize::splat(slice.len()))).to_int();
-                // SAFETY: This block works with *mut T derived from &mut 'a [T],
-                // which means it is delicate in Rust's borrowing model, circa 2021:
-                // &mut 'a [T] asserts uniqueness, so deriving &'a [T] invalidates live *mut Ts!
-                // Even though this block is largely safe methods, it must be almost exactly this way
-                // to prevent invalidating the raw ptrs while they're live.
-                // Thus, entering this block requires all values to use being already ready:
-                // 0. idxs we want to write to, which are used to construct the mask.
-                // 1. mask, which depends on an initial &'a [T] and the idxs.
-                // 2. actual values to scatter (self).
-                // 3. &mut [T] which will become our base ptr.
-                unsafe {
-                    // Now Entering ☢️ *mut T Zone
-                    let base_ptr = crate::vector::ptr::SimdMutPtr::splat(slice.as_mut_ptr());
-                    // Ferris forgive me, I have done pointer arithmetic here.
-                    let ptrs = base_ptr.wrapping_add(idxs);
-                    // The ptrs have been bounds-masked to prevent memory-unsafe writes insha'allah
-                    crate::intrinsics::simd_scatter(self, ptrs, mask)
-                    // Cleared ☢️ *mut T Zone
-                }
-            }
-        }
-
-        impl<const LANES: usize> Copy for $name<LANES> where crate::LaneCount<LANES>: crate::SupportedLaneCount {}
-
-        impl<const LANES: usize> Clone for $name<LANES> where crate::LaneCount<LANES>: crate::SupportedLaneCount {
-            #[inline]
-            fn clone(&self) -> Self {
-                *self
-            }
-        }
-
-        impl<const LANES: usize> Default for $name<LANES> where crate::LaneCount<LANES>: crate::SupportedLaneCount {
-            #[inline]
-            fn default() -> Self {
-                Self::splat(<$type>::default())
-            }
-        }
-
-        impl<const LANES: usize> PartialEq for $name<LANES> where crate::LaneCount<LANES>: crate::SupportedLaneCount {
-            #[inline]
-            fn eq(&self, other: &Self) -> bool {
-                // TODO use SIMD equality
-                self.to_array() == other.to_array()
-            }
-        }
-
-        impl<const LANES: usize> PartialOrd for $name<LANES> where crate::LaneCount<LANES>: crate::SupportedLaneCount {
-            #[inline]
-            fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
-                // TODO use SIMD equalitya
-                self.to_array().partial_cmp(other.as_ref())
-            }
-        }
-
-        // array references
-        impl<const LANES: usize> AsRef<[$type; LANES]> for $name<LANES> where crate::LaneCount<LANES>: crate::SupportedLaneCount {
-            #[inline]
-            fn as_ref(&self) -> &[$type; LANES] {
-                &self.0
-            }
-        }
-
-        impl<const LANES: usize> AsMut<[$type; LANES]> for $name<LANES> where crate::LaneCount<LANES>: crate::SupportedLaneCount {
-            #[inline]
-            fn as_mut(&mut self) -> &mut [$type; LANES] {
-                &mut self.0
-            }
-        }
-
-        // slice references
-        impl<const LANES: usize> AsRef<[$type]> for $name<LANES> where crate::LaneCount<LANES>: crate::SupportedLaneCount {
-            #[inline]
-            fn as_ref(&self) -> &[$type] {
-                &self.0
-            }
-        }
-
-        impl<const LANES: usize> AsMut<[$type]> for $name<LANES> where crate::LaneCount<LANES>: crate::SupportedLaneCount {
-            #[inline]
-            fn as_mut(&mut self) -> &mut [$type] {
-                &mut self.0
-            }
-        }
-
-        // vector/array conversion
-        impl<const LANES: usize> From<[$type; LANES]> for $name<LANES> where crate::LaneCount<LANES>: crate::SupportedLaneCount {
-            fn from(array: [$type; LANES]) -> Self {
-                Self(array)
-            }
-        }
-
-        impl <const LANES: usize> From<$name<LANES>> for [$type; LANES] where crate::LaneCount<LANES>: crate::SupportedLaneCount {
-            fn from(vector: $name<LANES>) -> Self {
-                vector.to_array()
-            }
-        }
-
-        impl_shuffle_2pow_lanes!{ $name }
-    }
-}