|
1 | 1 | use crate::simd::{
|
2 |
| - LaneCount, Mask, Select, Simd, SupportedLaneCount, |
| 2 | + LaneCount, Mask, Select, Simd, SimdElement, SupportedLaneCount, |
3 | 3 | cmp::SimdPartialEq,
|
4 | 4 | ptr::{SimdConstPtr, SimdMutPtr},
|
5 | 5 | };
|
@@ -152,94 +152,108 @@ macro_rules! impl_float {
|
152 | 152 |
|
153 | 153 | impl_float! { f32, f64 }
|
154 | 154 |
|
155 |
| -macro_rules! impl_mask { |
156 |
| - { $($integer:ty),* } => { |
157 |
| - $( |
158 |
| - impl<const N: usize> SimdPartialOrd for Mask<$integer, N> |
159 |
| - where |
160 |
| - LaneCount<N>: SupportedLaneCount, |
161 |
| - { |
162 |
| - #[inline] |
163 |
| - fn simd_lt(self, other: Self) -> Self::Mask { |
164 |
| - // Safety: `self` is a vector, and the result of the comparison |
165 |
| - // is always a valid mask. |
166 |
| - unsafe { Self::from_simd_unchecked(core::intrinsics::simd::simd_lt(self.to_simd(), other.to_simd())) } |
167 |
| - } |
| 155 | +impl<T, const N: usize> SimdPartialOrd for Mask<T, N> |
| 156 | +where |
| 157 | + T: SimdElement, |
| 158 | + LaneCount<N>: SupportedLaneCount, |
| 159 | +{ |
| 160 | + #[inline] |
| 161 | + fn simd_lt(self, other: Self) -> Self::Mask { |
| 162 | + // Use intrinsic to avoid extra bounds on T. |
| 163 | + // Safety: `self` is a vector, and the result of the comparison is always a valid mask. |
| 164 | + unsafe { |
| 165 | + Self::from_simd_unchecked(core::intrinsics::simd::simd_lt( |
| 166 | + self.to_simd(), |
| 167 | + other.to_simd(), |
| 168 | + )) |
| 169 | + } |
| 170 | + } |
168 | 171 |
|
169 |
| - #[inline] |
170 |
| - fn simd_le(self, other: Self) -> Self::Mask { |
171 |
| - // Safety: `self` is a vector, and the result of the comparison |
172 |
| - // is always a valid mask. |
173 |
| - unsafe { Self::from_simd_unchecked(core::intrinsics::simd::simd_le(self.to_simd(), other.to_simd())) } |
174 |
| - } |
| 172 | + #[inline] |
| 173 | + fn simd_le(self, other: Self) -> Self::Mask { |
| 174 | + // Use intrinsic to avoid extra bounds on T. |
| 175 | + // Safety: `self` is a vector, and the result of the comparison is always a valid mask. |
| 176 | + unsafe { |
| 177 | + Self::from_simd_unchecked(core::intrinsics::simd::simd_le( |
| 178 | + self.to_simd(), |
| 179 | + other.to_simd(), |
| 180 | + )) |
| 181 | + } |
| 182 | + } |
175 | 183 |
|
176 |
| - #[inline] |
177 |
| - fn simd_gt(self, other: Self) -> Self::Mask { |
178 |
| - // Safety: `self` is a vector, and the result of the comparison |
179 |
| - // is always a valid mask. |
180 |
| - unsafe { Self::from_simd_unchecked(core::intrinsics::simd::simd_gt(self.to_simd(), other.to_simd())) } |
181 |
| - } |
| 184 | + #[inline] |
| 185 | + fn simd_gt(self, other: Self) -> Self::Mask { |
| 186 | + // Use intrinsic to avoid extra bounds on T. |
| 187 | + // Safety: `self` is a vector, and the result of the comparison is always a valid mask. |
| 188 | + unsafe { |
| 189 | + Self::from_simd_unchecked(core::intrinsics::simd::simd_gt( |
| 190 | + self.to_simd(), |
| 191 | + other.to_simd(), |
| 192 | + )) |
| 193 | + } |
| 194 | + } |
182 | 195 |
|
183 |
| - #[inline] |
184 |
| - fn simd_ge(self, other: Self) -> Self::Mask { |
185 |
| - // Safety: `self` is a vector, and the result of the comparison |
186 |
| - // is always a valid mask. |
187 |
| - unsafe { Self::from_simd_unchecked(core::intrinsics::simd::simd_ge(self.to_simd(), other.to_simd())) } |
188 |
| - } |
| 196 | + #[inline] |
| 197 | + fn simd_ge(self, other: Self) -> Self::Mask { |
| 198 | + // Use intrinsic to avoid extra bounds on T. |
| 199 | + // Safety: `self` is a vector, and the result of the comparison is always a valid mask. |
| 200 | + unsafe { |
| 201 | + Self::from_simd_unchecked(core::intrinsics::simd::simd_ge( |
| 202 | + self.to_simd(), |
| 203 | + other.to_simd(), |
| 204 | + )) |
189 | 205 | }
|
| 206 | + } |
| 207 | +} |
190 | 208 |
|
191 |
| - impl<const N: usize> SimdOrd for Mask<$integer, N> |
192 |
| - where |
193 |
| - LaneCount<N>: SupportedLaneCount, |
194 |
| - { |
195 |
| - #[inline] |
196 |
| - fn simd_max(self, other: Self) -> Self { |
197 |
| - self.simd_gt(other).select(other, self) |
198 |
| - } |
| 209 | +impl<T, const N: usize> SimdOrd for Mask<T, N> |
| 210 | +where |
| 211 | + T: SimdElement, |
| 212 | + LaneCount<N>: SupportedLaneCount, |
| 213 | +{ |
| 214 | + #[inline] |
| 215 | + fn simd_max(self, other: Self) -> Self { |
| 216 | + self.simd_gt(other).select(other, self) |
| 217 | + } |
199 | 218 |
|
200 |
| - #[inline] |
201 |
| - fn simd_min(self, other: Self) -> Self { |
202 |
| - self.simd_lt(other).select(other, self) |
203 |
| - } |
| 219 | + #[inline] |
| 220 | + fn simd_min(self, other: Self) -> Self { |
| 221 | + self.simd_lt(other).select(other, self) |
| 222 | + } |
204 | 223 |
|
205 |
| - #[inline] |
206 |
| - #[track_caller] |
207 |
| - fn simd_clamp(self, min: Self, max: Self) -> Self { |
208 |
| - assert!( |
209 |
| - min.simd_le(max).all(), |
210 |
| - "each element in `min` must be less than or equal to the corresponding element in `max`", |
211 |
| - ); |
212 |
| - self.simd_max(min).simd_min(max) |
213 |
| - } |
214 |
| - } |
215 |
| - )* |
| 224 | + #[inline] |
| 225 | + #[track_caller] |
| 226 | + fn simd_clamp(self, min: Self, max: Self) -> Self { |
| 227 | + assert!( |
| 228 | + min.simd_le(max).all(), |
| 229 | + "each element in `min` must be less than or equal to the corresponding element in `max`", |
| 230 | + ); |
| 231 | + self.simd_max(min).simd_min(max) |
216 | 232 | }
|
217 | 233 | }
|
218 | 234 |
|
219 |
| -impl_mask! { i8, i16, i32, i64, isize } |
220 |
| - |
221 | 235 | impl<T, const N: usize> SimdPartialOrd for Simd<*const T, N>
|
222 | 236 | where
|
223 | 237 | LaneCount<N>: SupportedLaneCount,
|
224 | 238 | {
|
225 | 239 | #[inline]
|
226 | 240 | fn simd_lt(self, other: Self) -> Self::Mask {
|
227 |
| - self.addr().simd_lt(other.addr()) |
| 241 | + self.addr().simd_lt(other.addr()).cast::<*const T>() |
228 | 242 | }
|
229 | 243 |
|
230 | 244 | #[inline]
|
231 | 245 | fn simd_le(self, other: Self) -> Self::Mask {
|
232 |
| - self.addr().simd_le(other.addr()) |
| 246 | + self.addr().simd_le(other.addr()).cast::<*const T>() |
233 | 247 | }
|
234 | 248 |
|
235 | 249 | #[inline]
|
236 | 250 | fn simd_gt(self, other: Self) -> Self::Mask {
|
237 |
| - self.addr().simd_gt(other.addr()) |
| 251 | + self.addr().simd_gt(other.addr()).cast::<*const T>() |
238 | 252 | }
|
239 | 253 |
|
240 | 254 | #[inline]
|
241 | 255 | fn simd_ge(self, other: Self) -> Self::Mask {
|
242 |
| - self.addr().simd_ge(other.addr()) |
| 256 | + self.addr().simd_ge(other.addr()).cast::<*const T>() |
243 | 257 | }
|
244 | 258 | }
|
245 | 259 |
|
@@ -274,22 +288,22 @@ where
|
274 | 288 | {
|
275 | 289 | #[inline]
|
276 | 290 | fn simd_lt(self, other: Self) -> Self::Mask {
|
277 |
| - self.addr().simd_lt(other.addr()) |
| 291 | + self.addr().simd_lt(other.addr()).cast::<*mut T>() |
278 | 292 | }
|
279 | 293 |
|
280 | 294 | #[inline]
|
281 | 295 | fn simd_le(self, other: Self) -> Self::Mask {
|
282 |
| - self.addr().simd_le(other.addr()) |
| 296 | + self.addr().simd_le(other.addr()).cast::<*mut T>() |
283 | 297 | }
|
284 | 298 |
|
285 | 299 | #[inline]
|
286 | 300 | fn simd_gt(self, other: Self) -> Self::Mask {
|
287 |
| - self.addr().simd_gt(other.addr()) |
| 301 | + self.addr().simd_gt(other.addr()).cast::<*mut T>() |
288 | 302 | }
|
289 | 303 |
|
290 | 304 | #[inline]
|
291 | 305 | fn simd_ge(self, other: Self) -> Self::Mask {
|
292 |
| - self.addr().simd_ge(other.addr()) |
| 306 | + self.addr().simd_ge(other.addr()).cast::<*mut T>() |
293 | 307 | }
|
294 | 308 | }
|
295 | 309 |
|
|
0 commit comments