about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--Cargo.toml5
-rw-r--r--crates/core_simd/Cargo.toml5
-rw-r--r--crates/core_simd/src/fmt.rs105
-rw-r--r--crates/core_simd/src/lib.rs56
-rw-r--r--crates/core_simd/src/macros.rs320
-rw-r--r--crates/core_simd/src/masks.rs73
-rw-r--r--crates/core_simd/src/vectors_f32.rs23
-rw-r--r--crates/core_simd/src/vectors_f64.rs18
-rw-r--r--crates/core_simd/src/vectors_i128.rs12
-rw-r--r--crates/core_simd/src/vectors_i16.rs23
-rw-r--r--crates/core_simd/src/vectors_i32.rs23
-rw-r--r--crates/core_simd/src/vectors_i64.rs18
-rw-r--r--crates/core_simd/src/vectors_i8.rs23
-rw-r--r--crates/core_simd/src/vectors_isize.rs26
-rw-r--r--crates/core_simd/src/vectors_mask128.rs11
-rw-r--r--crates/core_simd/src/vectors_mask16.rs21
-rw-r--r--crates/core_simd/src/vectors_mask32.rs21
-rw-r--r--crates/core_simd/src/vectors_mask64.rs16
-rw-r--r--crates/core_simd/src/vectors_mask8.rs21
-rw-r--r--crates/core_simd/src/vectors_masksize.rs16
-rw-r--r--crates/core_simd/src/vectors_u128.rs12
-rw-r--r--crates/core_simd/src/vectors_u16.rs23
-rw-r--r--crates/core_simd/src/vectors_u32.rs23
-rw-r--r--crates/core_simd/src/vectors_u64.rs18
-rw-r--r--crates/core_simd/src/vectors_u8.rs23
-rw-r--r--crates/core_simd/src/vectors_usize.rs26
27 files changed, 963 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 00000000000..96ef6c0b944
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+/target
+Cargo.lock
diff --git a/Cargo.toml b/Cargo.toml
new file mode 100644
index 00000000000..f3538db7559
--- /dev/null
+++ b/Cargo.toml
@@ -0,0 +1,5 @@
+[workspace]
+
+members = [
+    "crates/core_simd",
+]
diff --git a/crates/core_simd/Cargo.toml b/crates/core_simd/Cargo.toml
new file mode 100644
index 00000000000..d4aef6f059c
--- /dev/null
+++ b/crates/core_simd/Cargo.toml
@@ -0,0 +1,5 @@
+[package]
+name = "core_simd"
+version = "0.1.0"
+authors = ["Caleb Zulawski <caleb.zulawski@gmail.com>"]
+edition = "2018"
diff --git a/crates/core_simd/src/fmt.rs b/crates/core_simd/src/fmt.rs
new file mode 100644
index 00000000000..c634e0546bc
--- /dev/null
+++ b/crates/core_simd/src/fmt.rs
@@ -0,0 +1,105 @@
+macro_rules! debug_wrapper {
+    { $($trait:ident => $name: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<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:ty => $(($trait:ident, $format:ident)),*;)* } => {
+        $( // repeat type
+            $( // repeat trait
+                impl core::fmt::$trait for $type {
+                    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
+                        $format(self.as_ref(), f)
+                    }
+                }
+            )*
+        )*
+    };
+    { integers: $($type:ty,)* } => {
+        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:ty,)* } => {
+        impl_fmt_trait! {
+            $($type =>
+              (Debug, format),
+              (LowerExp, format_lower_exp),
+              (UpperExp, format_upper_exp);
+            )*
+        }
+    };
+    { masks: $($type:ty,)* } => {
+        impl_fmt_trait! {
+            $($type =>
+              (Debug, format);
+            )*
+        }
+    }
+}
+
+impl_fmt_trait! {
+    integers:
+        crate::u8x8,    crate::u8x16,    crate::u8x32,    crate::u8x64,
+        crate::i8x8,    crate::i8x16,    crate::i8x32,    crate::i8x64,
+        crate::u16x4,   crate::u16x8,   crate::u16x16,   crate::u16x32,
+        crate::i16x4,   crate::i16x8,   crate::i16x16,   crate::i16x32,
+        crate::u32x2,   crate::u32x4,   crate::u32x8,   crate::u32x16,
+        crate::i32x2,   crate::i32x4,   crate::i32x8,   crate::i32x16,
+        crate::u64x2,   crate::u64x4,   crate::u64x8,
+        crate::i64x2,   crate::i64x4,   crate::i64x8,
+        crate::u128x2,  crate::u128x4,
+        crate::i128x2,  crate::i128x4,
+        crate::usizex2, crate::usizex4, crate::usizex8,
+        crate::isizex2, crate::isizex4, crate::isizex8,
+}
+
+impl_fmt_trait! {
+    floats:
+        crate::f32x2, crate::f32x4, crate::f32x8, crate::f32x16,
+        crate::f64x2, crate::f64x4, crate::f64x8,
+}
+
+impl_fmt_trait! {
+    masks:
+        crate::mask8x8,    crate::mask8x16,    crate::mask8x32,    crate::mask8x64,
+        crate::mask16x4,   crate::mask16x8,   crate::mask16x16,   crate::mask16x32,
+        crate::mask32x2,   crate::mask32x4,   crate::mask32x8,   crate::mask32x16,
+        crate::mask64x2,   crate::mask64x4,   crate::mask64x8,
+        crate::mask128x2,  crate::mask128x4,
+        crate::masksizex2, crate::masksizex4, crate::masksizex8,
+}
diff --git a/crates/core_simd/src/lib.rs b/crates/core_simd/src/lib.rs
new file mode 100644
index 00000000000..d88f5b1eac4
--- /dev/null
+++ b/crates/core_simd/src/lib.rs
@@ -0,0 +1,56 @@
+#![no_std]
+#![feature(repr_simd)]
+#![warn(missing_docs)]
+//! Portable SIMD module.
+
+#[macro_use]
+mod macros;
+
+mod fmt;
+
+mod masks;
+pub use masks::*;
+
+mod vectors_u8;
+pub use vectors_u8::*;
+mod vectors_u16;
+pub use vectors_u16::*;
+mod vectors_u32;
+pub use vectors_u32::*;
+mod vectors_u64;
+pub use vectors_u64::*;
+mod vectors_u128;
+pub use vectors_u128::*;
+mod vectors_usize;
+pub use vectors_usize::*;
+
+mod vectors_i8;
+pub use vectors_i8::*;
+mod vectors_i16;
+pub use vectors_i16::*;
+mod vectors_i32;
+pub use vectors_i32::*;
+mod vectors_i64;
+pub use vectors_i64::*;
+mod vectors_i128;
+pub use vectors_i128::*;
+mod vectors_isize;
+pub use vectors_isize::*;
+
+mod vectors_f32;
+pub use vectors_f32::*;
+mod vectors_f64;
+pub use vectors_f64::*;
+
+mod vectors_mask8;
+pub use vectors_mask8::*;
+mod vectors_mask16;
+pub use vectors_mask16::*;
+mod vectors_mask32;
+pub use vectors_mask32::*;
+mod vectors_mask64;
+pub use vectors_mask64::*;
+mod vectors_mask128;
+pub use vectors_mask128::*;
+mod vectors_masksize;
+pub use vectors_masksize::*;
diff --git a/crates/core_simd/src/macros.rs b/crates/core_simd/src/macros.rs
new file mode 100644
index 00000000000..2f93db19035
--- /dev/null
+++ b/crates/core_simd/src/macros.rs
@@ -0,0 +1,320 @@
+/// Provides implementations of `From<$a> for $b` and `From<$b> for $a` that transmutes the value.
+macro_rules! from_transmute {
+    { unsafe $a:ty => $b:ty } => {
+        from_transmute!{ @impl $a => $b }
+        from_transmute!{ @impl $b => $a }
+    };
+    { @impl $from:ty => $to:ty } => {
+        impl core::convert::From<$from> for $to {
+            #[inline]
+            fn from(value: $from) -> $to {
+                unsafe { core::mem::transmute(value) }
+            }
+        }
+    };
+}
+
+/// Provides implementations of `From<$generic> for core::arch::{x86, x86_64}::$intel` and
+/// vice-versa that transmutes the value.
+macro_rules! from_transmute_x86 {
+    { unsafe $generic:ty => $intel:ident } => {
+        #[cfg(target_arch = "x86")]
+        from_transmute! { unsafe $generic => core::arch::x86::$intel }
+
+        #[cfg(target_arch = "x86_64")]
+        from_transmute! { unsafe $generic => core::arch::x86_64::$intel }
+    }
+}
+
+/// Calls a the macro `$mac` with the provided `$args` followed by `$repeat` repeated the specified
+/// number of times.
+macro_rules! call_repeat {
+    { 1 => $mac:path [$($repeat:tt)*] $($args:tt)* } => {
+        $mac! {
+            $($args)*
+            $($repeat)*
+        }
+    };
+    { 2 => $mac:path [$($repeat:tt)*] $($args:tt)* } => {
+        $mac! {
+            $($args)*
+            $($repeat)* $($repeat)*
+        }
+    };
+    { 4 => $mac:path [$($repeat:tt)*] $($args:tt)* } => {
+        $mac! {
+            $($args)*
+            $($repeat)* $($repeat)* $($repeat)* $($repeat)*
+        }
+    };
+    { 8 => $mac:path [$($repeat:tt)*] $($args:tt)* } => {
+        $mac! {
+            $($args)*
+            $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)*
+        }
+    };
+    { 16 => $mac:path [$($repeat:tt)*] $($args:tt)* } => {
+        $mac! {
+            $($args)*
+            $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)*
+            $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)*
+        }
+    };
+    { 32 => $mac:path [$($repeat:tt)*] $($args:tt)* } => {
+        $mac! {
+            $($args)*
+            $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)*
+            $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)*
+            $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)*
+            $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)*
+        }
+    };
+    { 64 => $mac:path [$($repeat:tt)*] $($args:tt)* } => {
+        $mac! {
+            $($args)*
+            $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)*
+            $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)*
+            $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)*
+            $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)*
+            $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)*
+            $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)*
+            $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)*
+            $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)* $($repeat)*
+        }
+    };
+}
+
+/// Calls the macro `$mac` with the specified `$args` followed by the specified number of unique
+/// identifiers.
+macro_rules! call_counting_args {
+    { 1 => $mac:path => $($args:tt)* } => {
+        $mac! {
+            $($args)*
+            value
+        }
+    };
+    { 2 => $mac:path => $($args:tt)* } => {
+        $mac! {
+            $($args)*
+            v0 v1
+        }
+    };
+    { 4 => $mac:path => $($args:tt)* } => {
+        $mac! {
+            $($args)*
+            v0 v1 v2 v3
+        }
+    };
+    { 8 => $mac:path => $($args:tt)* } => {
+        $mac! {
+            $($args)*
+            v0 v1 v2 v3 v4 v5 v6 v7
+        }
+    };
+    { 16 => $mac:path => $($args:tt)* } => {
+        $mac! {
+            $($args)*
+            v0 v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12 v13 v14 v15
+        }
+    };
+    { 32 => $mac:path => $($args:tt)* } => {
+        $mac! {
+            $($args)*
+            v0  v1  v2  v3  v4  v5  v6  v7  v8  v9  v10 v11 v12 v13 v14 v15
+            v16 v17 v18 v19 v20 v21 v22 v23 v24 v25 v26 v27 v28 v29 v30 v31
+        }
+    };
+    { 64 => $mac:path => $($args:tt)* } => {
+        $mac! {
+            $($args)*
+            v0  v1  v2  v3  v4  v5  v6  v7  v8  v9  v10 v11 v12 v13 v14 v15
+            v16 v17 v18 v19 v20 v21 v22 v23 v24 v25 v26 v27 v28 v29 v30 v31
+            v32 v33 v34 v35 v36 v37 v38 v39 v40 v41 v42 v43 v44 v45 v46 v47
+            v48 v49 v50 v51 v52 v53 v54 v55 v56 v57 v58 v59 v60 v61 v62 v63
+        }
+    };
+}
+
+/// Implements common traits on the specified vector `$name`, holding multiple `$lanes` of `$type`.
+macro_rules! base_vector_traits {
+    { $name:path => [$type:ty; $lanes:literal] } => {
+        impl Copy for $name {}
+
+        impl Clone for $name {
+            #[inline]
+            fn clone(&self) -> Self {
+                *self
+            }
+        }
+
+        impl Default for $name {
+            #[inline]
+            fn default() -> Self {
+                Self::splat(<$type>::default())
+            }
+        }
+
+        impl PartialEq for $name {
+            #[inline]
+            fn eq(&self, other: &Self) -> bool {
+                AsRef::<[$type]>::as_ref(self) == AsRef::<[$type]>::as_ref(other)
+            }
+        }
+
+        impl PartialOrd for $name {
+            #[inline]
+            fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
+                AsRef::<[$type]>::as_ref(self).partial_cmp(AsRef::<[$type]>::as_ref(other))
+            }
+        }
+
+        // array references
+        impl AsRef<[$type; $lanes]> for $name {
+            #[inline]
+            fn as_ref(&self) -> &[$type; $lanes] {
+                unsafe { &*(self as *const _ as *const _) }
+            }
+        }
+
+        impl AsMut<[$type; $lanes]> for $name {
+            #[inline]
+            fn as_mut(&mut self) -> &mut [$type; $lanes] {
+                unsafe { &mut *(self as *mut _ as *mut _) }
+            }
+        }
+
+        // slice references
+        impl AsRef<[$type]> for $name {
+            #[inline]
+            fn as_ref(&self) -> &[$type] {
+                AsRef::<[$type; $lanes]>::as_ref(self)
+            }
+        }
+
+        impl AsMut<[$type]> for $name {
+            #[inline]
+            fn as_mut(&mut self) -> &mut [$type] {
+                AsMut::<[$type; $lanes]>::as_mut(self)
+            }
+        }
+
+        // vector/array conversion
+        from_transmute! { unsafe $name => [$type; $lanes] }
+
+        // splat
+        impl From<$type> for $name {
+            #[inline]
+            fn from(value: $type) -> Self {
+                Self::splat(value)
+            }
+        }
+    }
+}
+
+/// Implements additional integer traits (Eq, Ord, Hash) on the specified vector `$name`, holding multiple `$lanes` of `$type`.
+macro_rules! integer_vector_traits {
+    { $name:path => [$type:ty; $lanes:literal] } => {
+        impl Eq for $name {}
+
+        impl Ord for $name {
+            #[inline]
+            fn cmp(&self, other: &Self) -> core::cmp::Ordering {
+                AsRef::<[$type]>::as_ref(self).cmp(AsRef::<[$type]>::as_ref(other))
+            }
+        }
+
+        impl core::hash::Hash for $name {
+            #[inline]
+            fn hash<H>(&self, state: &mut H)
+            where
+                H: core::hash::Hasher
+            {
+                AsRef::<[$type]>::as_ref(self).hash(state)
+            }
+        }
+    }
+}
+
+/// Defines a vector `$name` containing multiple `$lanes` of `$type`.
+macro_rules! define_vector {
+    { $(#[$attr:meta])* struct $name:ident([$type:ty; $lanes:tt]); } => {
+        call_repeat! { $lanes => define_vector [$type] def $(#[$attr])* | $name | }
+
+        impl $name {
+            call_repeat! { $lanes => define_vector [$type] splat $type | }
+            call_counting_args! { $lanes => define_vector => new $type | }
+        }
+
+        base_vector_traits! { $name => [$type; $lanes] }
+    };
+    { def $(#[$attr:meta])* | $name:ident | $($itype:ty)* } => {
+        $(#[$attr])*
+        #[allow(non_camel_case_types)]
+        #[repr(simd)]
+        pub struct $name($($itype),*);
+    };
+    { splat $type:ty | $($itype:ty)* } => {
+        /// Construct a vector by setting all lanes to the given value.
+        #[inline]
+        pub const fn splat(value: $type) -> Self {
+            Self($(value as $itype),*)
+        }
+    };
+    { new $type:ty | $($var:ident)* } => {
+        /// Construct a vector by setting each lane to the given values.
+        #[allow(clippy::too_many_arguments)]
+        #[inline]
+        pub const fn new($($var: $type),*) -> Self {
+            Self($($var),*)
+        }
+    }
+}
+
+/// Defines an integer vector `$name` containing multiple `$lanes` of integer `$type`.
+macro_rules! define_integer_vector {
+    { $(#[$attr:meta])* struct $name:ident([$type:ty; $lanes:tt]); } => {
+        define_vector! {
+            $(#[$attr])*
+            struct $name([$type; $lanes]);
+        }
+
+        integer_vector_traits! { $name => [$type; $lanes] }
+    }
+}
+
+/// Defines a mask vector `$name` containing multiple `$lanes` of `$type`, represented by the
+/// underlying type `$impl_type`.
+macro_rules! define_mask_vector {
+    { $(#[$attr:meta])* struct $name:ident([$impl_type:ty as $type:ty; $lanes:tt]); } => {
+        call_repeat! { $lanes => define_mask_vector [$impl_type] def $(#[$attr])* | $name | }
+
+        impl $name {
+            call_repeat! { $lanes => define_mask_vector [$impl_type] splat $type | }
+            call_counting_args! { $lanes => define_mask_vector => new $type | }
+        }
+
+        base_vector_traits! { $name => [$type; $lanes] }
+        integer_vector_traits! { $name => [$type; $lanes] }
+    };
+    { def $(#[$attr:meta])* | $name:ident | $($itype:ty)* } => {
+        $(#[$attr])*
+        #[allow(non_camel_case_types)]
+        #[repr(simd)]
+        pub struct $name($($itype),*);
+    };
+    { splat $type:ty | $($itype:ty)* } => {
+        /// Construct a vector by setting all lanes to the given value.
+        #[inline]
+        pub const fn splat(value: $type) -> Self {
+            Self($(value.0 as $itype),*)
+        }
+    };
+    { new $type:ty | $($var:ident)* } => {
+        /// Construct a vector by setting each lane to the given values.
+        #[allow(clippy::too_many_arguments)]
+        #[inline]
+        pub const fn new($($var: $type),*) -> Self {
+            Self($($var.0),*)
+        }
+    }
+}
diff --git a/crates/core_simd/src/masks.rs b/crates/core_simd/src/masks.rs
new file mode 100644
index 00000000000..1fc281a310d
--- /dev/null
+++ b/crates/core_simd/src/masks.rs
@@ -0,0 +1,73 @@
+macro_rules! define_mask {
+    { $(#[$attr:meta])* struct $name:ident($type:ty); } => {
+        $(#[$attr])*
+        #[allow(non_camel_case_types)]
+        #[derive(Copy, Clone, Default, PartialEq, PartialOrd, Eq, Ord, Hash)]
+        #[repr(transparent)]
+        pub struct $name(pub(crate) $type);
+
+        impl $name {
+            /// Construct a mask from the given value.
+            pub const fn new(value: bool) -> Self {
+                if value {
+                    Self(!0)
+                } else {
+                    Self(0)
+                }
+            }
+
+            /// Test if the mask is set.
+            pub const fn test(&self) -> bool {
+                self.0 != 0
+            }
+        }
+
+        impl core::convert::From<bool> for $name {
+            fn from(value: bool) -> Self {
+                Self::new(value)
+            }
+        }
+
+        impl core::convert::From<$name> for bool {
+            fn from(mask: $name) -> Self {
+                mask.test()
+            }
+        }
+
+        impl core::fmt::Debug for $name {
+            fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
+                self.test().fmt(f)
+            }
+        }
+    }
+}
+
+define_mask! {
+    /// 8-bit mask
+    struct mask8(i8);
+}
+
+define_mask! {
+    /// 16-bit mask
+    struct mask16(i16);
+}
+
+define_mask! {
+    /// 32-bit mask
+    struct mask32(i32);
+}
+
+define_mask! {
+    /// 64-bit mask
+    struct mask64(i64);
+}
+
+define_mask! {
+    /// 128-bit mask
+    struct mask128(i128);
+}
+
+define_mask! {
+    /// `isize`-wide mask
+    struct masksize(isize);
+}
diff --git a/crates/core_simd/src/vectors_f32.rs b/crates/core_simd/src/vectors_f32.rs
new file mode 100644
index 00000000000..9fcbd9d53f0
--- /dev/null
+++ b/crates/core_simd/src/vectors_f32.rs
@@ -0,0 +1,23 @@
+define_vector! {
+    /// Vector of two `f32` values
+    struct f32x2([f32; 2]);
+}
+
+define_vector! {
+    /// Vector of four `f32` values
+    struct f32x4([f32; 4]);
+}
+
+define_vector! {
+    /// Vector of eight `f32` values
+    struct f32x8([f32; 8]);
+}
+
+define_vector! {
+    /// Vector of 16 `f32` values
+    struct f32x16([f32; 16]);
+}
+
+from_transmute_x86! { unsafe f32x4 => __m128 }
+from_transmute_x86! { unsafe f32x8 => __m256 }
+//from_transmute_x86! { unsafe f32x16 => __m512 }
diff --git a/crates/core_simd/src/vectors_f64.rs b/crates/core_simd/src/vectors_f64.rs
new file mode 100644
index 00000000000..d741aabe88e
--- /dev/null
+++ b/crates/core_simd/src/vectors_f64.rs
@@ -0,0 +1,18 @@
+define_vector! {
+    /// Vector of two `f64` values
+    struct f64x2([f64; 2]);
+}
+
+define_vector! {
+    /// Vector of four `f64` values
+    struct f64x4([f64; 4]);
+}
+
+define_vector! {
+    /// Vector of eight `f64` values
+    struct f64x8([f64; 8]);
+}
+
+from_transmute_x86! { unsafe f64x2 => __m128d }
+from_transmute_x86! { unsafe f64x4 => __m256d }
+//from_transmute_x86! { unsafe f64x8 => __m512d }
diff --git a/crates/core_simd/src/vectors_i128.rs b/crates/core_simd/src/vectors_i128.rs
new file mode 100644
index 00000000000..5c8354070e8
--- /dev/null
+++ b/crates/core_simd/src/vectors_i128.rs
@@ -0,0 +1,12 @@
+define_integer_vector! {
+    /// Vector of two `i128` values
+    struct i128x2([i128; 2]);
+}
+
+define_integer_vector! {
+    /// Vector of four `i128` values
+    struct i128x4([i128; 4]);
+}
+
+from_transmute_x86! { unsafe i128x2 => __m256i }
+//from_transmute_x86! { unsafe i128x4 => __m512i }
diff --git a/crates/core_simd/src/vectors_i16.rs b/crates/core_simd/src/vectors_i16.rs
new file mode 100644
index 00000000000..8aabd136b10
--- /dev/null
+++ b/crates/core_simd/src/vectors_i16.rs
@@ -0,0 +1,23 @@
+define_integer_vector! {
+    /// Vector of four `i16` values
+    struct i16x4([i16; 4]);
+}
+
+define_integer_vector! {
+    /// Vector of eight `i16` values
+    struct i16x8([i16; 8]);
+}
+
+define_integer_vector! {
+    /// Vector of 16 `i16` values
+    struct i16x16([i16; 16]);
+}
+
+define_integer_vector! {
+    /// Vector of 32 `i16` values
+    struct i16x32([i16; 32]);
+}
+
+from_transmute_x86! { unsafe i16x8 => __m128i }
+from_transmute_x86! { unsafe i16x16 => __m256i }
+//from_transmute_x86! { unsafe i16x32 => __m512i }
diff --git a/crates/core_simd/src/vectors_i32.rs b/crates/core_simd/src/vectors_i32.rs
new file mode 100644
index 00000000000..9aa9bc8e9dc
--- /dev/null
+++ b/crates/core_simd/src/vectors_i32.rs
@@ -0,0 +1,23 @@
+define_integer_vector! {
+    /// Vector of two `i32` values
+    struct i32x2([i32; 2]);
+}
+
+define_integer_vector! {
+    /// Vector of four `i32` values
+    struct i32x4([i32; 4]);
+}
+
+define_integer_vector! {
+    /// Vector of eight `i32` values
+    struct i32x8([i32; 8]);
+}
+
+define_integer_vector! {
+    /// Vector of 16 `i32` values
+    struct i32x16([i32; 16]);
+}
+
+from_transmute_x86! { unsafe i32x4 => __m128i }
+from_transmute_x86! { unsafe i32x8 => __m256i }
+//from_transmute_x86! { unsafe i32x16 => __m512i }
diff --git a/crates/core_simd/src/vectors_i64.rs b/crates/core_simd/src/vectors_i64.rs
new file mode 100644
index 00000000000..ba66aba2095
--- /dev/null
+++ b/crates/core_simd/src/vectors_i64.rs
@@ -0,0 +1,18 @@
+define_integer_vector! {
+    /// Vector of two `i64` values
+    struct i64x2([i64; 2]);
+}
+
+define_integer_vector! {
+    /// Vector of four `i64` values
+    struct i64x4([i64; 4]);
+}
+
+define_integer_vector! {
+    /// Vector of eight `i64` values
+    struct i64x8([i64; 8]);
+}
+
+from_transmute_x86! { unsafe i64x2 => __m128i }
+from_transmute_x86! { unsafe i64x4 => __m256i }
+//from_transmute_x86! { unsafe i64x8 => __m512i }
diff --git a/crates/core_simd/src/vectors_i8.rs b/crates/core_simd/src/vectors_i8.rs
new file mode 100644
index 00000000000..3e52d894cc2
--- /dev/null
+++ b/crates/core_simd/src/vectors_i8.rs
@@ -0,0 +1,23 @@
+define_integer_vector! {
+    /// Vector of eight `i8` values
+    struct i8x8([i8; 8]);
+}
+
+define_integer_vector! {
+    /// Vector of 16 `i8` values
+    struct i8x16([i8; 16]);
+}
+
+define_integer_vector! {
+    /// Vector of 32 `i8` values
+    struct i8x32([i8; 32]);
+}
+
+define_integer_vector! {
+    /// Vector of 64 `i8` values
+    struct i8x64([i8; 64]);
+}
+
+from_transmute_x86! { unsafe i8x16 => __m128i }
+from_transmute_x86! { unsafe i8x32 => __m256i }
+//from_transmute_x86! { unsafe i8x64 => __m512i }
diff --git a/crates/core_simd/src/vectors_isize.rs b/crates/core_simd/src/vectors_isize.rs
new file mode 100644
index 00000000000..35dac8bcbd4
--- /dev/null
+++ b/crates/core_simd/src/vectors_isize.rs
@@ -0,0 +1,26 @@
+define_integer_vector! {
+    /// Vector of two `isize` values
+    struct isizex2([isize; 2]);
+}
+
+define_integer_vector! {
+    /// Vector of four `isize` values
+    struct isizex4([isize; 4]);
+}
+
+define_integer_vector! {
+    /// Vector of eight `isize` values
+    struct isizex8([isize; 8]);
+}
+
+#[cfg(target_pointer_width = "32")]
+from_transmute_x86! { unsafe isizex4 => __m128i }
+#[cfg(target_pointer_width = "32")]
+from_transmute_x86! { unsafe isizex8 => __m256i }
+
+#[cfg(target_pointer_width = "64")]
+from_transmute_x86! { unsafe isizex2 => __m128i }
+#[cfg(target_pointer_width = "64")]
+from_transmute_x86! { unsafe isizex4 => __m256i }
+//#[cfg(target_pointer_width = "64")]
+//from_transmute_x86! { unsafe isizex8 => __m512i }
diff --git a/crates/core_simd/src/vectors_mask128.rs b/crates/core_simd/src/vectors_mask128.rs
new file mode 100644
index 00000000000..adf56a3684b
--- /dev/null
+++ b/crates/core_simd/src/vectors_mask128.rs
@@ -0,0 +1,11 @@
+use crate::mask128;
+
+define_mask_vector! {
+    /// Vector of two `mask128` values
+    struct mask128x2([i128 as mask128; 2]);
+}
+
+define_mask_vector! {
+    /// Vector of four `mask128` values
+    struct mask128x4([i128 as mask128; 4]);
+}
diff --git a/crates/core_simd/src/vectors_mask16.rs b/crates/core_simd/src/vectors_mask16.rs
new file mode 100644
index 00000000000..406d7255a11
--- /dev/null
+++ b/crates/core_simd/src/vectors_mask16.rs
@@ -0,0 +1,21 @@
+use crate::mask16;
+
+define_mask_vector! {
+    /// Vector of four `mask16` values
+    struct mask16x4([i16 as mask16; 4]);
+}
+
+define_mask_vector! {
+    /// Vector of eight `mask16` values
+    struct mask16x8([i16 as mask16; 8]);
+}
+
+define_mask_vector! {
+    /// Vector of 16 `mask16` values
+    struct mask16x16([i16 as mask16; 16]);
+}
+
+define_mask_vector! {
+    /// Vector of 32 `mask16` values
+    struct mask16x32([i16 as mask16; 32]);
+}
diff --git a/crates/core_simd/src/vectors_mask32.rs b/crates/core_simd/src/vectors_mask32.rs
new file mode 100644
index 00000000000..fad191421f3
--- /dev/null
+++ b/crates/core_simd/src/vectors_mask32.rs
@@ -0,0 +1,21 @@
+use crate::mask32;
+
+define_mask_vector! {
+    /// Vector of two `mask32` values
+    struct mask32x2([i32 as mask32; 2]);
+}
+
+define_mask_vector! {
+    /// Vector of four `mask32` values
+    struct mask32x4([i32 as mask32; 4]);
+}
+
+define_mask_vector! {
+    /// Vector of eight `mask32` values
+    struct mask32x8([i32 as mask32; 8]);
+}
+
+define_mask_vector! {
+    /// Vector of 16 `mask32` values
+    struct mask32x16([i32 as mask32; 16]);
+}
diff --git a/crates/core_simd/src/vectors_mask64.rs b/crates/core_simd/src/vectors_mask64.rs
new file mode 100644
index 00000000000..554e731ccf2
--- /dev/null
+++ b/crates/core_simd/src/vectors_mask64.rs
@@ -0,0 +1,16 @@
+use crate::mask64;
+
+define_mask_vector! {
+    /// Vector of two `mask64` values
+    struct mask64x2([i64 as mask64; 2]);
+}
+
+define_mask_vector! {
+    /// Vector of four `mask64` values
+    struct mask64x4([i64 as mask64; 4]);
+}
+
+define_mask_vector! {
+    /// Vector of eight `mask64` values
+    struct mask64x8([i64 as mask64; 8]);
+}
diff --git a/crates/core_simd/src/vectors_mask8.rs b/crates/core_simd/src/vectors_mask8.rs
new file mode 100644
index 00000000000..d038b336104
--- /dev/null
+++ b/crates/core_simd/src/vectors_mask8.rs
@@ -0,0 +1,21 @@
+use crate::mask8;
+
+define_mask_vector! {
+    /// Vector of eight `mask8` values
+    struct mask8x8([i8 as mask8; 8]);
+}
+
+define_mask_vector! {
+    /// Vector of 16 `mask8` values
+    struct mask8x16([i8 as mask8; 16]);
+}
+
+define_mask_vector! {
+    /// Vector of 32 `mask8` values
+    struct mask8x32([i8 as mask8; 32]);
+}
+
+define_mask_vector! {
+    /// Vector of 64 `mask8` values
+    struct mask8x64([i8 as mask8; 64]);
+}
diff --git a/crates/core_simd/src/vectors_masksize.rs b/crates/core_simd/src/vectors_masksize.rs
new file mode 100644
index 00000000000..a838aee5198
--- /dev/null
+++ b/crates/core_simd/src/vectors_masksize.rs
@@ -0,0 +1,16 @@
+use crate::masksize;
+
+define_mask_vector! {
+    /// Vector of two `masksize` values
+    struct masksizex2([isize as masksize; 2]);
+}
+
+define_mask_vector! {
+    /// Vector of four `masksize` values
+    struct masksizex4([isize as masksize; 4]);
+}
+
+define_mask_vector! {
+    /// Vector of eight `masksize` values
+    struct masksizex8([isize as masksize; 8]);
+}
diff --git a/crates/core_simd/src/vectors_u128.rs b/crates/core_simd/src/vectors_u128.rs
new file mode 100644
index 00000000000..eec7bde1722
--- /dev/null
+++ b/crates/core_simd/src/vectors_u128.rs
@@ -0,0 +1,12 @@
+define_integer_vector! {
+    /// Vector of two `u128` values
+    struct u128x2([u128; 2]);
+}
+
+define_integer_vector! {
+    /// Vector of four `u128` values
+    struct u128x4([u128; 4]);
+}
+
+from_transmute_x86! { unsafe u128x2 => __m256i }
+//from_transmute_x86! { unsafe u128x4 => __m512i }
diff --git a/crates/core_simd/src/vectors_u16.rs b/crates/core_simd/src/vectors_u16.rs
new file mode 100644
index 00000000000..809ab10383c
--- /dev/null
+++ b/crates/core_simd/src/vectors_u16.rs
@@ -0,0 +1,23 @@
+define_integer_vector! {
+    /// Vector of four `u16` values
+    struct u16x4([u16; 4]);
+}
+
+define_integer_vector! {
+    /// Vector of eight `u16` values
+    struct u16x8([u16; 8]);
+}
+
+define_integer_vector! {
+    /// Vector of 16 `u16` values
+    struct u16x16([u16; 16]);
+}
+
+define_integer_vector! {
+    /// Vector of 32 `u16` values
+    struct u16x32([u16; 32]);
+}
+
+from_transmute_x86! { unsafe u16x8 => __m128i }
+from_transmute_x86! { unsafe u16x16 => __m256i }
+//from_transmute_x86! { unsafe u16x32 => __m512i }
diff --git a/crates/core_simd/src/vectors_u32.rs b/crates/core_simd/src/vectors_u32.rs
new file mode 100644
index 00000000000..b00c63d9058
--- /dev/null
+++ b/crates/core_simd/src/vectors_u32.rs
@@ -0,0 +1,23 @@
+define_integer_vector! {
+    /// Vector of two `u32` values
+    struct u32x2([u32; 2]);
+}
+
+define_integer_vector! {
+    /// Vector of four `u32` values
+    struct u32x4([u32; 4]);
+}
+
+define_integer_vector! {
+    /// Vector of eight `u32` values
+    struct u32x8([u32; 8]);
+}
+
+define_integer_vector! {
+    /// Vector of 16 `u32` values
+    struct u32x16([u32; 16]);
+}
+
+from_transmute_x86! { unsafe u32x4 => __m128i }
+from_transmute_x86! { unsafe u32x8 => __m256i }
+//from_transmute_x86! { unsafe u32x16 => __m512i }
diff --git a/crates/core_simd/src/vectors_u64.rs b/crates/core_simd/src/vectors_u64.rs
new file mode 100644
index 00000000000..0bcf28ebc26
--- /dev/null
+++ b/crates/core_simd/src/vectors_u64.rs
@@ -0,0 +1,18 @@
+define_integer_vector! {
+    /// Vector of two `u64` values
+    struct u64x2([u64; 2]);
+}
+
+define_integer_vector! {
+    /// Vector of four `u64` values
+    struct u64x4([u64; 4]);
+}
+
+define_integer_vector! {
+    /// Vector of eight `u64` values
+    struct u64x8([u64; 8]);
+}
+
+from_transmute_x86! { unsafe u64x2 => __m128i }
+from_transmute_x86! { unsafe u64x4 => __m256i }
+//from_transmute_x86! { unsafe u64x8 => __m512i }
diff --git a/crates/core_simd/src/vectors_u8.rs b/crates/core_simd/src/vectors_u8.rs
new file mode 100644
index 00000000000..a187bc6f7b4
--- /dev/null
+++ b/crates/core_simd/src/vectors_u8.rs
@@ -0,0 +1,23 @@
+define_integer_vector! {
+    /// Vector of eight `u8` values
+    struct u8x8([u8; 8]);
+}
+
+define_integer_vector! {
+    /// Vector of 16 `u8` values
+    struct u8x16([u8; 16]);
+}
+
+define_integer_vector! {
+    /// Vector of 32 `u8` values
+    struct u8x32([u8; 32]);
+}
+
+define_integer_vector! {
+    /// Vector of 64 `u8` values
+    struct u8x64([u8; 64]);
+}
+
+from_transmute_x86! { unsafe u8x16 => __m128i }
+from_transmute_x86! { unsafe u8x32 => __m256i }
+//from_transmute_x86! { unsafe u8x64 => __m512i }
diff --git a/crates/core_simd/src/vectors_usize.rs b/crates/core_simd/src/vectors_usize.rs
new file mode 100644
index 00000000000..84a4b8e509b
--- /dev/null
+++ b/crates/core_simd/src/vectors_usize.rs
@@ -0,0 +1,26 @@
+define_integer_vector! {
+    /// Vector of two `usize` values
+    struct usizex2([usize; 2]);
+}
+
+define_integer_vector! {
+    /// Vector of four `usize` values
+    struct usizex4([usize; 4]);
+}
+
+define_integer_vector! {
+    /// Vector of eight `usize` values
+    struct usizex8([usize; 8]);
+}
+
+#[cfg(target_pointer_width = "32")]
+from_transmute_x86! { unsafe usizex4 => __m128i }
+#[cfg(target_pointer_width = "32")]
+from_transmute_x86! { unsafe usizex8 => __m256i }
+
+#[cfg(target_pointer_width = "64")]
+from_transmute_x86! { unsafe usizex2 => __m128i }
+#[cfg(target_pointer_width = "64")]
+from_transmute_x86! { unsafe usizex4 => __m256i }
+//#[cfg(target_pointer_width = "64")]
+//from_transmute_x86! { unsafe usizex8 => __m512i }