diff options
| author | Caleb Zulawski <caleb.zulawski@gmail.com> | 2023-10-01 21:28:03 -0400 |
|---|---|---|
| committer | Caleb Zulawski <caleb.zulawski@gmail.com> | 2023-10-01 22:40:19 -0400 |
| commit | a93ded542652cdff67e8b222c91a401d8e905777 (patch) | |
| tree | 261eddda3598cea25ea5266b30da570b9ae453cc | |
| parent | 4825b2a64d765317066948867e8714674419359b (diff) | |
| download | rust-a93ded542652cdff67e8b222c91a401d8e905777.tar.gz rust-a93ded542652cdff67e8b222c91a401d8e905777.zip | |
Remove generic_const_exprs
| -rw-r--r-- | crates/core_simd/Cargo.toml | 1 | ||||
| -rw-r--r-- | crates/core_simd/src/lib.rs | 2 | ||||
| -rw-r--r-- | crates/core_simd/src/masks.rs | 5 | ||||
| -rw-r--r-- | crates/core_simd/src/masks/bitmask.rs | 2 | ||||
| -rw-r--r-- | crates/core_simd/src/masks/full_masks.rs | 25 | ||||
| -rw-r--r-- | crates/core_simd/src/masks/to_bitmask.rs | 64 | ||||
| -rw-r--r-- | crates/core_simd/src/mod.rs | 5 | ||||
| -rw-r--r-- | crates/core_simd/src/to_bytes.rs | 147 | ||||
| -rw-r--r-- | crates/core_simd/tests/masks.rs | 1 | ||||
| -rw-r--r-- | crates/core_simd/tests/to_bytes.rs | 6 |
10 files changed, 148 insertions, 110 deletions
diff --git a/crates/core_simd/Cargo.toml b/crates/core_simd/Cargo.toml index d1a3a515a7e..b4a8fd70f4c 100644 --- a/crates/core_simd/Cargo.toml +++ b/crates/core_simd/Cargo.toml @@ -12,7 +12,6 @@ license = "MIT OR Apache-2.0" default = ["as_crate"] as_crate = [] std = [] -generic_const_exprs = [] all_lane_counts = [] [target.'cfg(target_arch = "wasm32")'.dev-dependencies] diff --git a/crates/core_simd/src/lib.rs b/crates/core_simd/src/lib.rs index 2d68e4cce85..dd3c546e014 100644 --- a/crates/core_simd/src/lib.rs +++ b/crates/core_simd/src/lib.rs @@ -14,8 +14,6 @@ strict_provenance, ptr_metadata )] -#![cfg_attr(feature = "generic_const_exprs", feature(generic_const_exprs))] -#![cfg_attr(feature = "generic_const_exprs", allow(incomplete_features))] #![warn(missing_docs, clippy::missing_inline_in_public_items)] // basically all items, really #![deny(unsafe_op_in_unsafe_fn, clippy::undocumented_unsafe_blocks)] #![allow(internal_features)] diff --git a/crates/core_simd/src/masks.rs b/crates/core_simd/src/masks.rs index fea687bdc1a..b6af9f83581 100644 --- a/crates/core_simd/src/masks.rs +++ b/crates/core_simd/src/masks.rs @@ -13,10 +13,7 @@ mod mask_impl; mod to_bitmask; -pub use to_bitmask::ToBitMask; - -#[cfg(feature = "generic_const_exprs")] -pub use to_bitmask::{bitmask_len, ToBitMaskArray}; +pub use to_bitmask::{ToBitMask, ToBitMaskArray}; use crate::simd::{intrinsics, LaneCount, Simd, SimdElement, SimdPartialEq, SupportedLaneCount}; use core::cmp::Ordering; diff --git a/crates/core_simd/src/masks/bitmask.rs b/crates/core_simd/src/masks/bitmask.rs index 20465ba9b07..a7df6304bc7 100644 --- a/crates/core_simd/src/masks/bitmask.rs +++ b/crates/core_simd/src/masks/bitmask.rs @@ -119,7 +119,6 @@ where unsafe { Self(intrinsics::simd_bitmask(value), PhantomData) } } - #[cfg(feature = "generic_const_exprs")] #[inline] #[must_use = "method returns a new array and does not mutate the original value"] pub fn to_bitmask_array<const N: usize>(self) -> [u8; N] { @@ -129,7 +128,6 @@ where unsafe { core::mem::transmute_copy(&self.0) } } - #[cfg(feature = "generic_const_exprs")] #[inline] #[must_use = "method returns a new mask and does not mutate the original value"] pub fn from_bitmask_array<const N: usize>(bitmask: [u8; N]) -> Self { diff --git a/crates/core_simd/src/masks/full_masks.rs b/crates/core_simd/src/masks/full_masks.rs index 1d13c45b8e7..4b36adece71 100644 --- a/crates/core_simd/src/masks/full_masks.rs +++ b/crates/core_simd/src/masks/full_masks.rs @@ -1,12 +1,9 @@ //! Masks that take up full SIMD vector registers. -use super::MaskElement; +use super::{to_bitmask::ToBitMaskArray, MaskElement}; use crate::simd::intrinsics; use crate::simd::{LaneCount, Simd, SupportedLaneCount, ToBitMask}; -#[cfg(feature = "generic_const_exprs")] -use crate::simd::ToBitMaskArray; - #[repr(transparent)] pub struct Mask<T, const LANES: usize>(Simd<T, LANES>) where @@ -145,23 +142,19 @@ where unsafe { Mask(intrinsics::simd_cast(self.0)) } } - #[cfg(feature = "generic_const_exprs")] #[inline] #[must_use = "method returns a new array and does not mutate the original value"] pub fn to_bitmask_array<const N: usize>(self) -> [u8; N] where super::Mask<T, LANES>: ToBitMaskArray, - [(); <super::Mask<T, LANES> as ToBitMaskArray>::BYTES]: Sized, { - assert_eq!(<super::Mask<T, LANES> as ToBitMaskArray>::BYTES, N); - - // Safety: N is the correct bitmask size + // Safety: Bytes is the right size array unsafe { // Compute the bitmask - let bitmask: [u8; <super::Mask<T, LANES> as ToBitMaskArray>::BYTES] = + let bitmask: <super::Mask<T, LANES> as ToBitMaskArray>::BitMaskArray = intrinsics::simd_bitmask(self.0); - // Transmute to the return type, previously asserted to be the same size + // Transmute to the return type let mut bitmask: [u8; N] = core::mem::transmute_copy(&bitmask); // LLVM assumes bit order should match endianness @@ -175,17 +168,13 @@ where } } - #[cfg(feature = "generic_const_exprs")] #[inline] #[must_use = "method returns a new mask and does not mutate the original value"] pub fn from_bitmask_array<const N: usize>(mut bitmask: [u8; N]) -> Self where super::Mask<T, LANES>: ToBitMaskArray, - [(); <super::Mask<T, LANES> as ToBitMaskArray>::BYTES]: Sized, { - assert_eq!(<super::Mask<T, LANES> as ToBitMaskArray>::BYTES, N); - - // Safety: N is the correct bitmask size + // Safety: Bytes is the right size array unsafe { // LLVM assumes bit order should match endianness if cfg!(target_endian = "big") { @@ -194,8 +183,8 @@ where } } - // Transmute to the bitmask type, previously asserted to be the same size - let bitmask: [u8; <super::Mask<T, LANES> as ToBitMaskArray>::BYTES] = + // Transmute to the bitmask + let bitmask: <super::Mask<T, LANES> as ToBitMaskArray>::BitMaskArray = core::mem::transmute_copy(&bitmask); // Compute the regular mask diff --git a/crates/core_simd/src/masks/to_bitmask.rs b/crates/core_simd/src/masks/to_bitmask.rs index 8e724c9de8c..7041d15164d 100644 --- a/crates/core_simd/src/masks/to_bitmask.rs +++ b/crates/core_simd/src/masks/to_bitmask.rs @@ -30,19 +30,18 @@ pub trait ToBitMask: Sealed { /// Converts masks to and from byte array bitmasks. /// /// Each bit of the bitmask corresponds to a mask lane, starting with the LSB of the first byte. -#[cfg(feature = "generic_const_exprs")] pub trait ToBitMaskArray: Sealed { - /// The length of the bitmask array. - const BYTES: usize; + /// The bitmask array. + type BitMaskArray; /// Converts a mask to a bitmask. - fn to_bitmask_array(self) -> [u8; Self::BYTES]; + fn to_bitmask_array(self) -> Self::BitMaskArray; /// Converts a bitmask to a mask. - fn from_bitmask_array(bitmask: [u8; Self::BYTES]) -> Self; + fn from_bitmask_array(bitmask: Self::BitMaskArray) -> Self; } -macro_rules! impl_integer_intrinsic { +macro_rules! impl_integer { { $(impl ToBitMask<BitMask=$int:ty> for Mask<_, $lanes:literal>)* } => { $( impl<T: MaskElement> ToBitMask for Mask<T, $lanes> { @@ -62,7 +61,27 @@ macro_rules! impl_integer_intrinsic { } } -impl_integer_intrinsic! { +macro_rules! impl_array { + { $(impl ToBitMaskArray<Bytes=$int:literal> for Mask<_, $lanes:literal>)* } => { + $( + impl<T: MaskElement> ToBitMaskArray for Mask<T, $lanes> { + type BitMaskArray = [u8; $int]; + + #[inline] + fn to_bitmask_array(self) -> Self::BitMaskArray { + self.0.to_bitmask_array() + } + + #[inline] + fn from_bitmask_array(bitmask: Self::BitMaskArray) -> Self { + Self(mask_impl::Mask::from_bitmask_array(bitmask)) + } + } + )* + } +} + +impl_integer! { impl ToBitMask<BitMask=u8> for Mask<_, 1> impl ToBitMask<BitMask=u8> for Mask<_, 2> impl ToBitMask<BitMask=u8> for Mask<_, 4> @@ -72,27 +91,12 @@ impl_integer_intrinsic! { impl ToBitMask<BitMask=u64> for Mask<_, 64> } -/// Returns the minimum number of bytes in a bitmask with `lanes` lanes. -#[cfg(feature = "generic_const_exprs")] -#[allow(clippy::missing_inline_in_public_items)] -pub const fn bitmask_len(lanes: usize) -> usize { - (lanes + 7) / 8 -} - -#[cfg(feature = "generic_const_exprs")] -impl<T: MaskElement, const LANES: usize> ToBitMaskArray for Mask<T, LANES> -where - LaneCount<LANES>: SupportedLaneCount, -{ - const BYTES: usize = bitmask_len(LANES); - - #[inline] - fn to_bitmask_array(self) -> [u8; Self::BYTES] { - self.0.to_bitmask_array() - } - - #[inline] - fn from_bitmask_array(bitmask: [u8; Self::BYTES]) -> Self { - Mask(mask_impl::Mask::from_bitmask_array(bitmask)) - } +impl_array! { + impl ToBitMaskArray<Bytes=1> for Mask<_, 1> + impl ToBitMaskArray<Bytes=1> for Mask<_, 2> + impl ToBitMaskArray<Bytes=1> for Mask<_, 4> + impl ToBitMaskArray<Bytes=1> for Mask<_, 8> + impl ToBitMaskArray<Bytes=2> for Mask<_, 16> + impl ToBitMaskArray<Bytes=4> for Mask<_, 32> + impl ToBitMaskArray<Bytes=8> for Mask<_, 64> } diff --git a/crates/core_simd/src/mod.rs b/crates/core_simd/src/mod.rs index dd954b7cc48..f489ae36de4 100644 --- a/crates/core_simd/src/mod.rs +++ b/crates/core_simd/src/mod.rs @@ -3,9 +3,6 @@ mod swizzle; pub(crate) mod intrinsics; -#[cfg(feature = "generic_const_exprs")] -mod to_bytes; - mod alias; mod cast; mod elements; @@ -18,6 +15,7 @@ mod ops; mod ord; mod select; mod swizzle_dyn; +mod to_bytes; mod vector; mod vendor; @@ -37,5 +35,6 @@ pub mod simd { pub use crate::core_simd::ord::*; pub use crate::core_simd::swizzle::*; pub use crate::core_simd::swizzle_dyn::*; + pub use crate::core_simd::to_bytes::ToBytes; pub use crate::core_simd::vector::*; } diff --git a/crates/core_simd/src/to_bytes.rs b/crates/core_simd/src/to_bytes.rs index 5f1374fd5a5..5fe4a77d50d 100644 --- a/crates/core_simd/src/to_bytes.rs +++ b/crates/core_simd/src/to_bytes.rs @@ -1,72 +1,126 @@ -use crate::simd::SimdUint; +use crate::simd::{LaneCount, Simd, SimdElement, SimdFloat, SimdInt, SimdUint, SupportedLaneCount}; + +mod sealed { + use super::*; + pub trait Sealed {} + impl<T: SimdElement, const N: usize> Sealed for Simd<T, N> where LaneCount<N>: SupportedLaneCount {} +} +use sealed::Sealed; + +/// Convert SIMD vectors to vectors of bytes +pub trait ToBytes: Sealed { + /// This type, reinterpreted as bytes. + type Bytes; + + /// Return the memory representation of this integer as a byte array in native byte + /// order. + fn to_ne_bytes(self) -> Self::Bytes; + + /// Return the memory representation of this integer as a byte array in big-endian + /// (network) byte order. + fn to_be_bytes(self) -> Self::Bytes; + + /// Return the memory representation of this integer as a byte array in little-endian + /// byte order. + fn to_le_bytes(self) -> Self::Bytes; + + /// Create a native endian integer value from its memory representation as a byte array + /// in native endianness. + fn from_ne_bytes(bytes: Self::Bytes) -> Self; + + /// Create an integer value from its representation as a byte array in big endian. + fn from_be_bytes(bytes: Self::Bytes) -> Self; + + /// Create an integer value from its representation as a byte array in little endian. + fn from_le_bytes(bytes: Self::Bytes) -> Self; +} + +macro_rules! swap_bytes { + { f32, $x:expr } => { Simd::from_bits($x.to_bits().swap_bytes()) }; + { f64, $x:expr } => { Simd::from_bits($x.to_bits().swap_bytes()) }; + { $ty:ty, $x:expr } => { $x.swap_bytes() } +} macro_rules! impl_to_bytes { - { $ty:ty, $size:literal } => { - impl<const LANES: usize> crate::simd::Simd<$ty, LANES> - where - crate::simd::LaneCount<LANES>: crate::simd::SupportedLaneCount, - crate::simd::LaneCount<{{ $size * LANES }}>: crate::simd::SupportedLaneCount, - { - /// Return the memory representation of this integer as a byte array in native byte - /// order. + { $ty:tt, $size:tt } => { + impl_to_bytes! { $ty, $size * 1 } + impl_to_bytes! { $ty, $size * 2 } + impl_to_bytes! { $ty, $size * 4 } + impl_to_bytes! { $ty, $size * 8 } + impl_to_bytes! { $ty, $size * 16 } + impl_to_bytes! { $ty, $size * 32 } + impl_to_bytes! { $ty, $size * 64 } + }; + + // multiply element size by number of elements + { $ty:tt, 1 * $elems:literal } => { impl_to_bytes! { @impl [$ty; $elems], $elems } }; + { $ty:tt, $size:literal * 1 } => { impl_to_bytes! { @impl [$ty; 1], $size } }; + { $ty:tt, 2 * 2 } => { impl_to_bytes! { @impl [$ty; 2], 4 } }; + { $ty:tt, 2 * 4 } => { impl_to_bytes! { @impl [$ty; 4], 8 } }; + { $ty:tt, 2 * 8 } => { impl_to_bytes! { @impl [$ty; 8], 16 } }; + { $ty:tt, 2 * 16 } => { impl_to_bytes! { @impl [$ty; 16], 32 } }; + { $ty:tt, 2 * 32 } => { impl_to_bytes! { @impl [$ty; 32], 64 } }; + { $ty:tt, 4 * 2 } => { impl_to_bytes! { @impl [$ty; 2], 8 } }; + { $ty:tt, 4 * 4 } => { impl_to_bytes! { @impl [$ty; 4], 16 } }; + { $ty:tt, 4 * 8 } => { impl_to_bytes! { @impl [$ty; 8], 32 } }; + { $ty:tt, 4 * 16 } => { impl_to_bytes! { @impl [$ty; 16], 64 } }; + { $ty:tt, 8 * 2 } => { impl_to_bytes! { @impl [$ty; 2], 16 } }; + { $ty:tt, 8 * 4 } => { impl_to_bytes! { @impl [$ty; 4], 32 } }; + { $ty:tt, 8 * 8 } => { impl_to_bytes! { @impl [$ty; 8], 64 } }; + + // unsupported number of lanes + { $ty:ty, $a:literal * $b:literal } => { }; + + { @impl [$ty:tt; $elem:literal], $bytes:literal } => { + impl ToBytes for Simd<$ty, $elem> { + type Bytes = Simd<u8, $bytes>; + #[inline] - pub fn to_ne_bytes(self) -> crate::simd::Simd<u8, {{ $size * LANES }}> { + fn to_ne_bytes(self) -> Self::Bytes { // Safety: transmuting between vectors is safe - unsafe { core::mem::transmute_copy(&self) } + unsafe { core::mem::transmute(self) } } - /// Return the memory representation of this integer as a byte array in big-endian - /// (network) byte order. #[inline] - pub fn to_be_bytes(self) -> crate::simd::Simd<u8, {{ $size * LANES }}> { - let bytes = self.to_ne_bytes(); - if cfg!(target_endian = "big") { - bytes - } else { - bytes.swap_bytes() + fn to_be_bytes(mut self) -> Self::Bytes { + if !cfg!(target_endian = "big") { + self = swap_bytes!($ty, self); } + self.to_ne_bytes() } - /// Return the memory representation of this integer as a byte array in little-endian - /// byte order. #[inline] - pub fn to_le_bytes(self) -> crate::simd::Simd<u8, {{ $size * LANES }}> { - let bytes = self.to_ne_bytes(); - if cfg!(target_endian = "little") { - bytes - } else { - bytes.swap_bytes() + fn to_le_bytes(mut self) -> Self::Bytes { + if !cfg!(target_endian = "little") { + self = swap_bytes!($ty, self); } + self.to_ne_bytes() } - /// Create a native endian integer value from its memory representation as a byte array - /// in native endianness. #[inline] - pub fn from_ne_bytes(bytes: crate::simd::Simd<u8, {{ $size * LANES }}>) -> Self { + fn from_ne_bytes(bytes: Self::Bytes) -> Self { // Safety: transmuting between vectors is safe - unsafe { core::mem::transmute_copy(&bytes) } + unsafe { core::mem::transmute(bytes) } } - /// Create an integer value from its representation as a byte array in big endian. #[inline] - pub fn from_be_bytes(bytes: crate::simd::Simd<u8, {{ $size * LANES }}>) -> Self { - let bytes = if cfg!(target_endian = "big") { - bytes + fn from_be_bytes(bytes: Self::Bytes) -> Self { + let ret = Self::from_ne_bytes(bytes); + if cfg!(target_endian = "big") { + ret } else { - bytes.swap_bytes() - }; - Self::from_ne_bytes(bytes) + swap_bytes!($ty, ret) + } } - /// Create an integer value from its representation as a byte array in little endian. #[inline] - pub fn from_le_bytes(bytes: crate::simd::Simd<u8, {{ $size * LANES }}>) -> Self { - let bytes = if cfg!(target_endian = "little") { - bytes + fn from_le_bytes(bytes: Self::Bytes) -> Self { + let ret = Self::from_ne_bytes(bytes); + if cfg!(target_endian = "little") { + ret } else { - bytes.swap_bytes() - }; - Self::from_ne_bytes(bytes) + swap_bytes!($ty, ret) + } } } } @@ -89,3 +143,6 @@ impl_to_bytes! { i64, 8 } impl_to_bytes! { isize, 4 } #[cfg(target_pointer_width = "64")] impl_to_bytes! { isize, 8 } + +impl_to_bytes! { f32, 4 } +impl_to_bytes! { f64, 8 } diff --git a/crates/core_simd/tests/masks.rs b/crates/core_simd/tests/masks.rs index 9f8bad1c36c..7c1d4c7dd3f 100644 --- a/crates/core_simd/tests/masks.rs +++ b/crates/core_simd/tests/masks.rs @@ -125,7 +125,6 @@ macro_rules! test_mask_api { cast_impl::<isize>(); } - #[cfg(feature = "generic_const_exprs")] #[test] fn roundtrip_bitmask_array_conversion() { use core_simd::simd::ToBitMaskArray; diff --git a/crates/core_simd/tests/to_bytes.rs b/crates/core_simd/tests/to_bytes.rs index 7dd740d65dd..66a7981cdc3 100644 --- a/crates/core_simd/tests/to_bytes.rs +++ b/crates/core_simd/tests/to_bytes.rs @@ -1,8 +1,6 @@ -#![feature(portable_simd, generic_const_exprs, adt_const_params)] -#![allow(incomplete_features)] -#![cfg(feature = "generic_const_exprs")] +#![feature(portable_simd)] -use core_simd::simd::Simd; +use core_simd::simd::{Simd, ToBytes}; #[test] fn byte_convert() { |
