|
3 | 3 | #![allow(incomplete_features, internal_features)]
|
4 | 4 | use std::simd::{prelude::*, StdFloat};
|
5 | 5 |
|
6 |
| -extern "platform-intrinsic" { |
7 |
| - pub(crate) fn simd_bitmask<T, U>(x: T) -> U; |
8 |
| -} |
9 |
| - |
10 | 6 | fn simd_ops_f32() {
|
11 | 7 | let a = f32x4::splat(10.0);
|
12 | 8 | let b = f32x4::from_array([1.0, 2.0, 3.0, -4.0]);
|
@@ -218,6 +214,11 @@ fn simd_ops_i32() {
|
218 | 214 | }
|
219 | 215 |
|
220 | 216 | fn simd_mask() {
|
| 217 | + extern "platform-intrinsic" { |
| 218 | + pub(crate) fn simd_bitmask<T, U>(x: T) -> U; |
| 219 | + pub(crate) fn simd_select_bitmask<M, T>(m: M, yes: T, no: T) -> T; |
| 220 | + } |
| 221 | + |
221 | 222 | let intmask = Mask::from_int(i32x4::from_array([0, -1, 0, 0]));
|
222 | 223 | assert_eq!(intmask, Mask::from_array([false, true, false, false]));
|
223 | 224 | assert_eq!(intmask.to_array(), [false, true, false, false]);
|
@@ -286,6 +287,40 @@ fn simd_mask() {
|
286 | 287 | true, true, true,
|
287 | 288 | ]),
|
288 | 289 | );
|
| 290 | + |
| 291 | + // Also directly call simd_select_bitmask, to test both kinds of argument types. |
| 292 | + unsafe { |
| 293 | + // These masks are exactly the results we got out above in the `simd_bitmask` tests. |
| 294 | + let selected1 = simd_select_bitmask::<u16, _>( |
| 295 | + if cfg!(target_endian = "little") { 0b1010001101001001 } else { 0b1001001011000101 }, |
| 296 | + i32x16::splat(1), // yes |
| 297 | + i32x16::splat(0), // no |
| 298 | + ); |
| 299 | + let selected2 = simd_select_bitmask::<[u8; 2], _>( |
| 300 | + if cfg!(target_endian = "little") { |
| 301 | + [0b01001001, 0b10100011] |
| 302 | + } else { |
| 303 | + [0b10010010, 0b11000101] |
| 304 | + }, |
| 305 | + i32x16::splat(1), // yes |
| 306 | + i32x16::splat(0), // no |
| 307 | + ); |
| 308 | + assert_eq!(selected1, i32x16::from_array([1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1])); |
| 309 | + assert_eq!(selected2, selected1); |
| 310 | + // Also try masks less than a byte long. |
| 311 | + let selected1 = simd_select_bitmask::<u8, _>( |
| 312 | + if cfg!(target_endian = "little") { 0b1000 } else { 0b0001 }, |
| 313 | + i32x4::splat(1), // yes |
| 314 | + i32x4::splat(0), // no |
| 315 | + ); |
| 316 | + let selected2 = simd_select_bitmask::<[u8; 1], _>( |
| 317 | + if cfg!(target_endian = "little") { [0b1000] } else { [0b0001] }, |
| 318 | + i32x4::splat(1), // yes |
| 319 | + i32x4::splat(0), // no |
| 320 | + ); |
| 321 | + assert_eq!(selected1, i32x4::from_array([0, 0, 0, 1])); |
| 322 | + assert_eq!(selected2, selected1); |
| 323 | + } |
289 | 324 | }
|
290 | 325 |
|
291 | 326 | fn simd_cast() {
|
|
0 commit comments