about summary refs log tree commit diff
diff options
context:
space:
mode:
authorCaleb Zulawski <caleb.zulawski@gmail.com>2022-08-04 19:31:50 -0400
committerCaleb Zulawski <caleb.zulawski@gmail.com>2022-10-29 11:55:01 -0400
commit176cc81324d008bd58e28136aa8e60b537caa3ce (patch)
tree49464ab6b5abc249d28c1cf53c31ad2b4236d0b7
parent8a5a5732a1527fbdffbc825ae630d911fc130e2e (diff)
downloadrust-176cc81324d008bd58e28136aa8e60b537caa3ce.tar.gz
rust-176cc81324d008bd58e28136aa8e60b537caa3ce.zip
Update for new intrinsics
-rw-r--r--crates/core_simd/src/cast.rs98
-rw-r--r--crates/core_simd/src/elements/const_ptr.rs31
-rw-r--r--crates/core_simd/src/elements/mut_ptr.rs28
-rw-r--r--crates/core_simd/src/intrinsics.rs23
-rw-r--r--crates/core_simd/src/vector.rs30
5 files changed, 110 insertions, 100 deletions
diff --git a/crates/core_simd/src/cast.rs b/crates/core_simd/src/cast.rs
index ddcc786afa4..d14b0de5d5e 100644
--- a/crates/core_simd/src/cast.rs
+++ b/crates/core_simd/src/cast.rs
@@ -1,79 +1,23 @@
-use crate::simd::{intrinsics, LaneCount, Simd, SimdElement, SupportedLaneCount};
+use crate::simd::SimdElement;
 
 /// Supporting trait for `Simd::cast`.  Typically doesn't need to be used directly.
-pub unsafe trait SimdCast<Target: SimdElement>: SimdElement {
-    #[doc(hidden)]
-    fn cast<const LANES: usize>(x: Simd<Self, LANES>) -> Simd<Target, LANES>
-    where
-        LaneCount<LANES>: SupportedLaneCount,
-    {
-        // Safety: implementing this trait indicates that the types are supported by `simd_as`
-        unsafe { intrinsics::simd_as(x) }
-    }
-
-    #[doc(hidden)]
-    unsafe fn cast_unchecked<const LANES: usize>(x: Simd<Self, LANES>) -> Simd<Target, LANES>
-    where
-        LaneCount<LANES>: SupportedLaneCount,
-    {
-        // Safety: implementing this trait indicates that the types are supported by `simd_cast`
-        // The caller is responsible for the conversion invariants.
-        unsafe { intrinsics::simd_cast(x) }
-    }
-}
-
-macro_rules! into_number {
-    { unsafe $from:ty as $to:ty } => {
-        // Safety: casting between numbers is supported by `simd_cast` and `simd_as`
-        unsafe impl SimdCast<$to> for $from {}
-    };
-    { unsafe $($type:ty),* } => {
-        $(
-        into_number! { unsafe $type as i8 }
-        into_number! { unsafe $type as i16 }
-        into_number! { unsafe $type as i32 }
-        into_number! { unsafe $type as i64 }
-        into_number! { unsafe $type as isize }
-
-        into_number! { unsafe $type as u8 }
-        into_number! { unsafe $type as u16 }
-        into_number! { unsafe $type as u32 }
-        into_number! { unsafe $type as u64 }
-        into_number! { unsafe $type as usize }
-
-        into_number! { unsafe $type as f32 }
-        into_number! { unsafe $type as f64 }
-        )*
-    }
-}
-
-into_number! { unsafe i8, i16, i32, i64, isize, u8, u16, u32, u64, usize, f32, f64 }
-
-// TODO uncomment pending PR to rustc
-/*
-macro_rules! into_pointer {
-    { unsafe $($type:ty),* } => {
-        $(
-        // Safety: casting between numbers and pointers is supported by `simd_cast` and `simd_as`
-        unsafe impl<T> SimdCast<$type> for *const T {}
-        // Safety: casting between numbers and pointers is supported by `simd_cast` and `simd_as`
-        unsafe impl<T> SimdCast<$type> for *mut T {}
-        // Safety: casting between numbers and pointers is supported by `simd_cast` and `simd_as`
-        unsafe impl<T> SimdCast<*const T> for $type {}
-        // Safety: casting between numbers and pointers is supported by `simd_cast` and `simd_as`
-        unsafe impl<T> SimdCast<*mut T> for $type {}
-        )*
-    }
-}
-
-into_pointer! { unsafe i8, i16, i32, i64, isize, u8, u16, u32, u64, usize }
-
-// Safety: casting between pointers is supported by `simd_cast` and `simd_as`
-unsafe impl<T, U> SimdCast<*const T> for *const U {}
-// Safety: casting between pointers is supported by `simd_cast` and `simd_as`
-unsafe impl<T, U> SimdCast<*const T> for *mut U {}
-// Safety: casting between pointers is supported by `simd_cast` and `simd_as`
-unsafe impl<T, U> SimdCast<*mut T> for *const U {}
-// Safety: casting between pointers is supported by `simd_cast` and `simd_as`
-unsafe impl<T, U> SimdCast<*mut T> for *mut U {}
-*/
+pub unsafe trait SimdCast: SimdElement {}
+
+unsafe impl SimdCast for i8 {}
+unsafe impl SimdCast for i16 {}
+unsafe impl SimdCast for i32 {}
+unsafe impl SimdCast for i64 {}
+unsafe impl SimdCast for isize {}
+unsafe impl SimdCast for u8 {}
+unsafe impl SimdCast for u16 {}
+unsafe impl SimdCast for u32 {}
+unsafe impl SimdCast for u64 {}
+unsafe impl SimdCast for usize {}
+unsafe impl SimdCast for f32 {}
+unsafe impl SimdCast for f64 {}
+
+/// Supporting trait for `Simd::cast_ptr`.  Typically doesn't need to be used directly.
+pub unsafe trait SimdCastPtr: SimdElement {}
+
+unsafe impl<T> SimdCastPtr for *const T {}
+unsafe impl<T> SimdCastPtr for *mut T {}
diff --git a/crates/core_simd/src/elements/const_ptr.rs b/crates/core_simd/src/elements/const_ptr.rs
index 3485d31e44d..27b41019dc8 100644
--- a/crates/core_simd/src/elements/const_ptr.rs
+++ b/crates/core_simd/src/elements/const_ptr.rs
@@ -40,6 +40,15 @@ pub trait SimdConstPtr: Copy + Sealed {
     /// Equivalent to calling [`pointer::with_addr`] on each lane.
     fn with_addr(self, addr: Self::Usize) -> Self;
 
+    /// Gets the "address" portion of the pointer, and "exposes" the provenance part for future use
+    /// in [`from_exposed_addr`].
+    fn expose_addr(self) -> Self::Usize;
+
+    /// Convert an address back to a pointer, picking up a previously "exposed" provenance.
+    ///
+    /// Equivalent to calling [`pointer::from_exposed_addr`] on each lane.
+    fn from_exposed_addr(addr: Self::Usize) -> Self;
+
     /// Calculates the offset from a pointer using wrapping arithmetic.
     ///
     /// Equivalent to calling [`pointer::wrapping_offset`] on each lane.
@@ -77,8 +86,7 @@ where
 
     #[inline]
     fn as_mut(self) -> Self::MutPtr {
-        unimplemented!()
-        //self.cast()
+        unsafe { intrinsics::simd_cast_ptr(self) }
     }
 
     #[inline]
@@ -90,18 +98,25 @@ where
     }
 
     #[inline]
-    fn with_addr(self, _addr: Self::Usize) -> Self {
-        unimplemented!()
-        /*
+    fn with_addr(self, addr: Self::Usize) -> Self {
         // FIXME(strict_provenance_magic): I am magic and should be a compiler intrinsic.
         //
         // In the mean-time, this operation is defined to be "as if" it was
         // a wrapping_offset, so we can emulate it as such. This should properly
         // restore pointer provenance even under today's compiler.
-        self.cast::<*const u8>()
+        self.cast_ptr::<*const u8>()
             .wrapping_offset(addr.cast::<isize>() - self.addr().cast::<isize>())
-            .cast()
-        */
+            .cast_ptr()
+    }
+
+    #[inline]
+    fn expose_addr(self) -> Self::Usize {
+        unsafe { intrinsics::simd_expose_addr(self) }
+    }
+
+    #[inline]
+    fn from_exposed_addr(addr: Self::Usize) -> Self {
+        unsafe { intrinsics::simd_from_exposed_addr(addr) }
     }
 
     #[inline]
diff --git a/crates/core_simd/src/elements/mut_ptr.rs b/crates/core_simd/src/elements/mut_ptr.rs
index 39fe9f35621..59a8b6293b5 100644
--- a/crates/core_simd/src/elements/mut_ptr.rs
+++ b/crates/core_simd/src/elements/mut_ptr.rs
@@ -37,6 +37,15 @@ pub trait SimdMutPtr: Copy + Sealed {
     /// Equivalent to calling [`pointer::with_addr`] on each lane.
     fn with_addr(self, addr: Self::Usize) -> Self;
 
+    /// Gets the "address" portion of the pointer, and "exposes" the provenance part for future use
+    /// in [`from_exposed_addr`].
+    fn expose_addr(self) -> Self::Usize;
+
+    /// Convert an address back to a pointer, picking up a previously "exposed" provenance.
+    ///
+    /// Equivalent to calling [`pointer::from_exposed_addr`] on each lane.
+    fn from_exposed_addr(addr: Self::Usize) -> Self;
+
     /// Calculates the offset from a pointer using wrapping arithmetic.
     ///
     /// Equivalent to calling [`pointer::wrapping_offset`] on each lane.
@@ -85,18 +94,25 @@ where
     }
 
     #[inline]
-    fn with_addr(self, _addr: Self::Usize) -> Self {
-        unimplemented!()
-        /*
+    fn with_addr(self, addr: Self::Usize) -> Self {
         // FIXME(strict_provenance_magic): I am magic and should be a compiler intrinsic.
         //
         // In the mean-time, this operation is defined to be "as if" it was
         // a wrapping_offset, so we can emulate it as such. This should properly
         // restore pointer provenance even under today's compiler.
-        self.cast::<*mut u8>()
+        self.cast_ptr::<*mut u8>()
             .wrapping_offset(addr.cast::<isize>() - self.addr().cast::<isize>())
-            .cast()
-        */
+            .cast_ptr()
+    }
+
+    #[inline]
+    fn expose_addr(self) -> Self::Usize {
+        unsafe { intrinsics::simd_expose_addr(self) }
+    }
+
+    #[inline]
+    fn from_exposed_addr(addr: Self::Usize) -> Self {
+        unsafe { intrinsics::simd_from_exposed_addr(addr) }
     }
 
     #[inline]
diff --git a/crates/core_simd/src/intrinsics.rs b/crates/core_simd/src/intrinsics.rs
index 41128cd1481..c0fbae2db08 100644
--- a/crates/core_simd/src/intrinsics.rs
+++ b/crates/core_simd/src/intrinsics.rs
@@ -154,4 +154,27 @@ extern "platform-intrinsic" {
 
     // equivalent to wrapping_offset
     pub(crate) fn simd_arith_offset<T, U>(ptr: T, offset: U) -> T;
+
+    /*
+    /// equivalent to `T as U` semantics, specifically for pointers
+    pub(crate) fn simd_cast_ptr<T, U>(ptr: T) -> U;
+
+    /// expose a pointer as an address
+    pub(crate) fn simd_expose_addr<T, U>(ptr: T) -> U;
+
+    /// convert an exposed address back to a pointer
+    pub(crate) fn simd_from_exposed_addr<T, U>(addr: T) -> U;
+    */
+}
+
+pub(crate) unsafe fn simd_cast_ptr<T, U>(_ptr: T) -> U {
+    unimplemented!()
+}
+
+pub(crate) unsafe fn simd_expose_addr<T, U>(_ptr: T) -> U {
+    unimplemented!()
+}
+
+pub(crate) unsafe fn simd_from_exposed_addr<T, U>(_addr: T) -> U {
+    unimplemented!()
 }
diff --git a/crates/core_simd/src/vector.rs b/crates/core_simd/src/vector.rs
index 3987b7a747b..3c435c4c805 100644
--- a/crates/core_simd/src/vector.rs
+++ b/crates/core_simd/src/vector.rs
@@ -1,6 +1,6 @@
 use crate::simd::{
-    intrinsics, LaneCount, Mask, MaskElement, SimdCast, SimdConstPtr, SimdMutPtr, SimdPartialOrd,
-    SupportedLaneCount, Swizzle,
+    intrinsics, LaneCount, Mask, MaskElement, SimdCast, SimdCastPtr, SimdConstPtr, SimdMutPtr,
+    SimdPartialOrd, SupportedLaneCount, Swizzle,
 };
 
 /// A SIMD vector of `LANES` elements of type `T`. `Simd<T, N>` has the same shape as [`[T; N]`](array), but operates like `T`.
@@ -209,11 +209,23 @@ where
     #[must_use]
     #[inline]
     #[cfg(not(bootstrap))]
-    pub fn cast<U: SimdElement>(self) -> Simd<U, LANES>
+    pub fn cast<U: SimdCast>(self) -> Simd<U, LANES>
     where
-        T: SimdCast<U>,
+        T: SimdCast,
     {
-        SimdCast::cast(self)
+        // Safety: supported types are guaranteed by SimdCast
+        unsafe { intrinsics::simd_as(self) }
+    }
+
+    /// Lanewise casts pointers to another pointer type.
+    #[must_use]
+    #[inline]
+    pub fn cast_ptr<U: SimdCastPtr>(self) -> Simd<U, LANES>
+    where
+        T: SimdCastPtr,
+    {
+        // Safety: supported types are guaranteed by SimdCastPtr
+        unsafe { intrinsics::simd_cast_ptr(self) }
     }
 
     /// Rounds toward zero and converts to the same-width integer type, assuming that
@@ -234,11 +246,11 @@ where
     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
     pub unsafe fn to_int_unchecked<I>(self) -> Simd<I, LANES>
     where
-        T: core::convert::FloatToInt<I> + SimdCast<I>,
-        I: SimdElement,
+        T: core::convert::FloatToInt<I> + SimdCast,
+        I: SimdCast,
     {
-        // Safety: the caller is responsible for the invariants
-        unsafe { SimdCast::cast_unchecked(self) }
+        // Safety: supported types are guaranteed by SimdCast, the caller is responsible for the extra invariants
+        unsafe { intrinsics::simd_cast(self) }
     }
 
     /// Reads from potentially discontiguous indices in `slice` to construct a SIMD vector.