implement simd_select
This commit is contained in:
parent
f672282bf2
commit
aa4f82ea48
3 changed files with 35 additions and 10 deletions
|
|
@ -1 +1 @@
|
|||
6a705566166debf5eff88c57140df607fa409aaa
|
||||
f0c4da49983aa699f715caf681e3154b445fb60b
|
||||
|
|
|
|||
|
|
@ -386,6 +386,28 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
|
|||
|
||||
this.write_scalar(Scalar::from_bool(res), dest)?;
|
||||
}
|
||||
"simd_select" => {
|
||||
let &[ref mask, ref yes, ref no] = check_arg_count(args)?;
|
||||
let (mask, mask_len) = this.operand_to_simd(mask)?;
|
||||
let (yes, yes_len) = this.operand_to_simd(yes)?;
|
||||
let (no, no_len) = this.operand_to_simd(no)?;
|
||||
let (dest, dest_len) = this.place_to_simd(dest)?;
|
||||
|
||||
assert_eq!(dest_len, mask_len);
|
||||
assert_eq!(dest_len, yes_len);
|
||||
assert_eq!(dest_len, no_len);
|
||||
|
||||
for i in 0..dest_len {
|
||||
let mask = this.read_immediate(&this.mplace_index(&mask, i)?.into())?;
|
||||
let yes = this.read_immediate(&this.mplace_index(&yes, i)?.into())?;
|
||||
let no = this.read_immediate(&this.mplace_index(&no, i)?.into())?;
|
||||
let dest = this.mplace_index(&dest, i)?;
|
||||
|
||||
let mask = simd_element_to_bool(mask)?;
|
||||
let val = if mask { yes } else { no };
|
||||
this.write_immediate(*val, &dest.into())?;
|
||||
}
|
||||
}
|
||||
|
||||
// Atomic operations
|
||||
"atomic_load" => this.atomic_load(args, dest, AtomicReadOp::SeqCst)?,
|
||||
|
|
|
|||
|
|
@ -29,19 +29,22 @@ fn simd_ops_i32() {
|
|||
|
||||
fn simd_intrinsics() {
|
||||
extern "platform-intrinsic" {
|
||||
pub(crate) fn simd_eq<T, U>(x: T, y: T) -> U;
|
||||
pub(crate) fn simd_reduce_any<T>(x: T) -> bool;
|
||||
fn simd_eq<T, U>(x: T, y: T) -> U;
|
||||
fn simd_reduce_any<T>(x: T) -> bool;
|
||||
fn simd_select<M, T>(m: M, yes: T, no: T) -> T;
|
||||
}
|
||||
|
||||
// Make sure simd_eq returns all-1 for `true`
|
||||
let a = i32x4::splat(10);
|
||||
let b = i32x4::from_array([1, 2, 10, 4]);
|
||||
let c: i32x4 = unsafe { simd_eq(a, b) };
|
||||
assert_eq!(c, i32x4::from_array([0, 0, -1, 0]));
|
||||
|
||||
unsafe {
|
||||
// Make sure simd_eq returns all-1 for `true`
|
||||
let a = i32x4::splat(10);
|
||||
let b = i32x4::from_array([1, 2, 10, 4]);
|
||||
let c: i32x4 = simd_eq(a, b);
|
||||
assert_eq!(c, i32x4::from_array([0, 0, -1, 0]));
|
||||
|
||||
assert!(!simd_reduce_any(i32x4::splat(0)));
|
||||
assert!(simd_reduce_any(i32x4::splat(-1)));
|
||||
|
||||
assert_eq!(simd_select(i8x4::from_array([0, -1, -1, 0]), a, b), i32x4::from_array([1, 10, 10, 4]));
|
||||
assert_eq!(simd_select(i8x4::from_array([0, -1, -1, 0]), b, a), i32x4::from_array([10, 2, 10, 10]));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue