diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000000..96ef6c0b944e --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/target +Cargo.lock diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 000000000000..f3538db75590 --- /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 000000000000..d4aef6f059c5 --- /dev/null +++ b/crates/core_simd/Cargo.toml @@ -0,0 +1,5 @@ +[package] +name = "core_simd" +version = "0.1.0" +authors = ["Caleb Zulawski "] +edition = "2018" diff --git a/crates/core_simd/src/fmt.rs b/crates/core_simd/src/fmt.rs new file mode 100644 index 000000000000..c634e0546bc1 --- /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(slice: &[T], f: &mut core::fmt::Formatter) -> core::fmt::Result { + #[repr(transparent)] + struct Wrapper<'a, T: core::fmt::$trait>(&'a T); + + impl 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 000000000000..d88f5b1eac45 --- /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 000000000000..2f93db190352 --- /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 { + 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(&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 000000000000..1fc281a310d3 --- /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 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 000000000000..9fcbd9d53f0f --- /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 000000000000..d741aabe88e0 --- /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 000000000000..5c8354070e81 --- /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 000000000000..8aabd136b104 --- /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 000000000000..9aa9bc8e9dc8 --- /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 000000000000..ba66aba2095d --- /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 000000000000..3e52d894cc22 --- /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 000000000000..35dac8bcbd45 --- /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 000000000000..adf56a3684b3 --- /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 000000000000..406d7255a11e --- /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 000000000000..fad191421f38 --- /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 000000000000..554e731ccf24 --- /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 000000000000..d038b3361044 --- /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 000000000000..a838aee51985 --- /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 000000000000..eec7bde1722f --- /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 000000000000..809ab10383cd --- /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 000000000000..b00c63d9058f --- /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 000000000000..0bcf28ebc265 --- /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 000000000000..a187bc6f7b42 --- /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 000000000000..84a4b8e509b3 --- /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 }