1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
use super::sealed::Sealed;
use crate::simd::{intrinsics, LaneCount, Mask, Simd, SimdPartialEq, SupportedLaneCount};
/// 对常量指针的 SIMD vectors 的操作。
pub trait SimdConstPtr: Copy + Sealed {
/// `usize` 的 Vector 与 lanes 的数量相同。
type Usize;
/// `isize` 的 Vector 与 lanes 的数量相同。
type Isize;
/// Vector 的可变指针指向同一类型。
type MutPtr;
/// 用于操作此 SIMD vector 类型的掩码类型。
type Mask;
/// 为每个为空的 lane 返回 `true`。
fn is_null(self) -> Self::Mask;
/// 更改常量而不更改类型。
///
/// 相当于在每个 lane 上调用 [`pointer::cast_mut`]。
fn cast_mut(self) -> Self::MutPtr;
/// 获取指针的 "address" 部分。
///
/// 该方法丢弃了指针语义元数据,因此不能将结果直接转换为有效指针。
///
///
/// 此方法在语义上丢弃了*provenance* 和*address-space* 信息。
/// 要正确恢复该信息,请使用 [`Self::with_addr`]。
///
/// 相当于在每个 lane 上调用 [`pointer::addr`]。
fn addr(self) -> Self::Usize;
/// 使用给定地址创建一个新指针。
///
/// 这执行与强制转换相同的操作,但将 `self` 的*address-space* 和*provenance* 复制到新指针。
///
///
/// 相当于在每个 lane 上调用 [`pointer::with_addr`]。
fn with_addr(self, addr: Self::Usize) -> Self;
/// 获取指针的 "address" 部分,"exposes" 是 future 在 [`Self::from_exposed_addr`] 中使用的出处部分。
///
fn expose_addr(self) -> Self::Usize;
/// 将地址转换回指针,获取以前的 "exposed" 出处。
///
/// 相当于在每个 lane 上调用 [`core::ptr::from_exposed_addr`]。
fn from_exposed_addr(addr: Self::Usize) -> Self;
/// 使用换行算法计算与指针的偏移量。
///
/// 相当于在每个 lane 上调用 [`pointer::wrapping_offset`]。
fn wrapping_offset(self, offset: Self::Isize) -> Self;
/// 使用换行算法计算与指针的偏移量。
///
/// 相当于在每个 lane 上调用 [`pointer::wrapping_add`]。
fn wrapping_add(self, count: Self::Usize) -> Self;
/// 使用换行算法计算与指针的偏移量。
///
/// 相当于在每个 lane 上调用 [`pointer::wrapping_sub`]。
fn wrapping_sub(self, count: Self::Usize) -> Self;
}
impl<T, const LANES: usize> Sealed for Simd<*const T, LANES> where
LaneCount<LANES>: SupportedLaneCount
{
}
impl<T, const LANES: usize> SimdConstPtr for Simd<*const T, LANES>
where
LaneCount<LANES>: SupportedLaneCount,
{
type Usize = Simd<usize, LANES>;
type Isize = Simd<isize, LANES>;
type MutPtr = Simd<*mut T, LANES>;
type Mask = Mask<isize, LANES>;
#[inline]
fn is_null(self) -> Self::Mask {
Simd::splat(core::ptr::null()).simd_eq(self)
}
#[inline]
fn cast_mut(self) -> Self::MutPtr {
self.cast_ptr()
}
#[inline]
fn addr(self) -> Self::Usize {
// FIXME(strict_provenance_magic): 我是魔法,应该是编译器内部函数。
// SAFETY: 指针到整数的转换是有效的 (如果您同意丢失出处的话)。
//
unsafe { core::mem::transmute_copy(&self) }
}
#[inline]
fn with_addr(self, addr: Self::Usize) -> Self {
// FIXME(strict_provenance_magic): 我是魔法,应该是编译器内部函数。
//
// 同时,这个操作被定义为 "as if",它是一个 wrapping_offset,所以我们可以模拟它。
// 即使在今天的编译器下,这也应该正确地恢复指针 Provenance。
//
self.cast_ptr::<*const u8>()
.wrapping_offset(addr.cast::<isize>() - self.addr().cast::<isize>())
.cast_ptr()
}
#[inline]
fn expose_addr(self) -> Self::Usize {
// 安全性: `self` 是指针 vector
unsafe { intrinsics::simd_expose_addr(self) }
}
#[inline]
fn from_exposed_addr(addr: Self::Usize) -> Self {
// 安全性: `self` 是指针 vector
unsafe { intrinsics::simd_from_exposed_addr(addr) }
}
#[inline]
fn wrapping_offset(self, count: Self::Isize) -> Self {
// 安全性: simd_arith_offset 采用 vector 指针和 vector 偏移量
unsafe { intrinsics::simd_arith_offset(self, count) }
}
#[inline]
fn wrapping_add(self, count: Self::Usize) -> Self {
self.wrapping_offset(count.cast())
}
#[inline]
fn wrapping_sub(self, count: Self::Usize) -> Self {
self.wrapping_offset(-count.cast::<isize>())
}
}