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
use super::sealed::Sealed;
use crate::simd::{intrinsics, LaneCount, Simd, SupportedLaneCount};

/// 对无符号整数的 SIMD vectors 的操作。
pub trait SimdUint: Copy + Sealed {
    /// 此 SIMD vector 类型包含的标量类型。
    type Scalar;

    /// Lanewise 饱和加法。
    ///
    /// # Examples
    /// ```
    /// # #![feature(portable_simd)]
    /// # #[cfg(feature = "as_crate")] use core_simd::simd;
    /// # #[cfg(not(feature = "as_crate"))] use core::simd;
    /// # use simd::{Simd, SimdUint};
    /// use core::u32::MAX;
    /// let x = Simd::from_array([2, 1, 0, MAX]);
    /// let max = Simd::splat(MAX);
    /// let unsat = x + max;
    /// let sat = x.saturating_add(max);
    /// assert_eq!(unsat, Simd::from_array([1, 0, MAX, MAX - 1]));
    /// assert_eq!(sat, max);
    /// ```
    fn saturating_add(self, second: Self) -> Self;

    /// Lanewise 饱和减法。
    ///
    /// # Examples
    /// ```
    /// # #![feature(portable_simd)]
    /// # #[cfg(feature = "as_crate")] use core_simd::simd;
    /// # #[cfg(not(feature = "as_crate"))] use core::simd;
    /// # use simd::{Simd, SimdUint};
    /// use core::u32::MAX;
    /// let x = Simd::from_array([2, 1, 0, MAX]);
    /// let max = Simd::splat(MAX);
    /// let unsat = x - max;
    /// let sat = x.saturating_sub(max);
    /// assert_eq!(unsat, Simd::from_array([3, 2, 1, 0]));
    /// assert_eq!(sat, Simd::splat(0));
    fn saturating_sub(self, second: Self) -> Self;

    /// 返回 vector 的 lane 总和,带包装加法。
    fn reduce_sum(self) -> Self::Scalar;

    /// 返回 vector 的 lane 的乘积,带包装乘法。
    fn reduce_product(self) -> Self::Scalar;

    /// 返回 vector 中的最大 lane。
    fn reduce_max(self) -> Self::Scalar;

    /// 返回 vector 中的最小 lane。
    fn reduce_min(self) -> Self::Scalar;

    /// 返回跨 vector lane 的累积按位与。
    fn reduce_and(self) -> Self::Scalar;

    /// 返回跨 vector lane 的累积按位或。
    fn reduce_or(self) -> Self::Scalar;

    /// 返回跨 vector lane 的累积按位异或。
    fn reduce_xor(self) -> Self::Scalar;
}

macro_rules! impl_trait {
    { $($ty:ty),* } => {
        $(
        impl<const LANES: usize> Sealed for Simd<$ty, LANES>
        where
            LaneCount<LANES>: SupportedLaneCount,
        {
        }

        impl<const LANES: usize> SimdUint for Simd<$ty, LANES>
        where
            LaneCount<LANES>: SupportedLaneCount,
        {
            type Scalar = $ty;

            #[inline]
            fn saturating_add(self, second: Self) -> Self {
                // 安全性: `self` 是 vector
                unsafe { intrinsics::simd_saturating_add(self, second) }
            }

            #[inline]
            fn saturating_sub(self, second: Self) -> Self {
                // 安全性: `self` 是 vector
                unsafe { intrinsics::simd_saturating_sub(self, second) }
            }

            #[inline]
            fn reduce_sum(self) -> Self::Scalar {
                // 安全性: `self` 是整数 vector
                unsafe { intrinsics::simd_reduce_add_ordered(self, 0) }
            }

            #[inline]
            fn reduce_product(self) -> Self::Scalar {
                // 安全性: `self` 是整数 vector
                unsafe { intrinsics::simd_reduce_mul_ordered(self, 1) }
            }

            #[inline]
            fn reduce_max(self) -> Self::Scalar {
                // 安全性: `self` 是整数 vector
                unsafe { intrinsics::simd_reduce_max(self) }
            }

            #[inline]
            fn reduce_min(self) -> Self::Scalar {
                // 安全性: `self` 是整数 vector
                unsafe { intrinsics::simd_reduce_min(self) }
            }

            #[inline]
            fn reduce_and(self) -> Self::Scalar {
                // 安全性: `self` 是整数 vector
                unsafe { intrinsics::simd_reduce_and(self) }
            }

            #[inline]
            fn reduce_or(self) -> Self::Scalar {
                // 安全性: `self` 是整数 vector
                unsafe { intrinsics::simd_reduce_or(self) }
            }

            #[inline]
            fn reduce_xor(self) -> Self::Scalar {
                // 安全性: `self` 是整数 vector
                unsafe { intrinsics::simd_reduce_xor(self) }
            }
        }
        )*
    }
}

impl_trait! { u8, u16, u32, u64, usize }