//! Auxiliary crate for tests that need SIMD types. //! //! Historically the tests just made their own, but projections into simd types //! was banned by , which //! breaks `derive(Clone)`, so this exists to give easily-usable types that can //! be used without copy-pasting the definitions of the helpers everywhere. //! //! This makes no attempt to guard against ICEs. Using it with proper types //! and such is your responsibility in the tests you write. #![allow(unused)] #![allow(non_camel_case_types)] // The field is currently left `pub` for convenience in porting tests, many of // which attempt to just construct it directly. That still works; it's just the // `.0` projection that doesn't. #[repr(simd)] #[derive(Copy, Eq)] pub struct Simd(pub [T; N]); impl Clone for Simd { fn clone(&self) -> Self { *self } } impl PartialEq for Simd { fn eq(&self, other: &Self) -> bool { self.as_array() == other.as_array() } } impl core::fmt::Debug for Simd { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> { <[T; N] as core::fmt::Debug>::fmt(self.as_array(), f) } } impl core::ops::Index for Simd { type Output = T; fn index(&self, i: usize) -> &T { &self.as_array()[i] } } impl Simd { pub const fn from_array(a: [T; N]) -> Self { Simd(a) } pub fn as_array(&self) -> &[T; N] { let p: *const Self = self; unsafe { &*p.cast::<[T; N]>() } } pub fn into_array(self) -> [T; N] where T: Copy, { *self.as_array() } } pub type u8x2 = Simd; pub type u8x4 = Simd; pub type u8x8 = Simd; pub type u8x16 = Simd; pub type u8x32 = Simd; pub type u8x64 = Simd; pub type u16x2 = Simd; pub type u16x4 = Simd; pub type u16x8 = Simd; pub type u16x16 = Simd; pub type u16x32 = Simd; pub type u32x2 = Simd; pub type u32x4 = Simd; pub type u32x8 = Simd; pub type u32x16 = Simd; pub type u64x2 = Simd; pub type u64x4 = Simd; pub type u64x8 = Simd; pub type u128x2 = Simd; pub type u128x4 = Simd; pub type i8x2 = Simd; pub type i8x4 = Simd; pub type i8x8 = Simd; pub type i8x16 = Simd; pub type i8x32 = Simd; pub type i8x64 = Simd; pub type i16x2 = Simd; pub type i16x4 = Simd; pub type i16x8 = Simd; pub type i16x16 = Simd; pub type i16x32 = Simd; pub type i32x2 = Simd; pub type i32x4 = Simd; pub type i32x8 = Simd; pub type i32x16 = Simd; pub type i64x2 = Simd; pub type i64x4 = Simd; pub type i64x8 = Simd; pub type i128x2 = Simd; pub type i128x4 = Simd; pub type f32x2 = Simd; pub type f32x4 = Simd; pub type f32x8 = Simd; pub type f32x16 = Simd; pub type f64x2 = Simd; pub type f64x4 = Simd; pub type f64x8 = Simd; // The field is currently left `pub` for convenience in porting tests, many of // which attempt to just construct it directly. That still works; it's just the // `.0` projection that doesn't. #[repr(simd, packed)] #[derive(Copy)] pub struct PackedSimd(pub [T; N]); impl Clone for PackedSimd { fn clone(&self) -> Self { *self } } impl PartialEq for PackedSimd { fn eq(&self, other: &Self) -> bool { self.as_array() == other.as_array() } } impl core::fmt::Debug for PackedSimd { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> { <[T; N] as core::fmt::Debug>::fmt(self.as_array(), f) } } impl PackedSimd { pub const fn from_array(a: [T; N]) -> Self { PackedSimd(a) } pub fn as_array(&self) -> &[T; N] { let p: *const Self = self; unsafe { &*p.cast::<[T; N]>() } } pub fn into_array(self) -> [T; N] where T: Copy, { *self.as_array() } }