Auto merge of #2007 - RalfJung:simd_saturating, r=RalfJung
implement simd_saturating intrinsics
This commit is contained in:
commit
ccaf7206e1
@ -1 +1 @@
|
|||||||
297273c45b205820a4c055082c71677197a40b55
|
d137c3a7bd3b180317044f8ccb9a8b4b3bb07db3
|
||||||
|
@ -372,7 +372,9 @@ enum Op {
|
|||||||
| "simd_gt"
|
| "simd_gt"
|
||||||
| "simd_ge"
|
| "simd_ge"
|
||||||
| "simd_fmax"
|
| "simd_fmax"
|
||||||
| "simd_fmin" => {
|
| "simd_fmin"
|
||||||
|
| "simd_saturating_add"
|
||||||
|
| "simd_saturating_sub" => {
|
||||||
use mir::BinOp;
|
use mir::BinOp;
|
||||||
|
|
||||||
let &[ref left, ref right] = check_arg_count(args)?;
|
let &[ref left, ref right] = check_arg_count(args)?;
|
||||||
@ -385,6 +387,7 @@ enum Op {
|
|||||||
|
|
||||||
enum Op {
|
enum Op {
|
||||||
MirOp(BinOp),
|
MirOp(BinOp),
|
||||||
|
SaturatingOp(BinOp),
|
||||||
FMax,
|
FMax,
|
||||||
FMin,
|
FMin,
|
||||||
}
|
}
|
||||||
@ -407,6 +410,8 @@ enum Op {
|
|||||||
"simd_ge" => Op::MirOp(BinOp::Ge),
|
"simd_ge" => Op::MirOp(BinOp::Ge),
|
||||||
"simd_fmax" => Op::FMax,
|
"simd_fmax" => Op::FMax,
|
||||||
"simd_fmin" => Op::FMin,
|
"simd_fmin" => Op::FMin,
|
||||||
|
"simd_saturating_add" => Op::SaturatingOp(BinOp::Add),
|
||||||
|
"simd_saturating_sub" => Op::SaturatingOp(BinOp::Sub),
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -442,6 +447,9 @@ enum Op {
|
|||||||
Op::FMin => {
|
Op::FMin => {
|
||||||
fmin_op(&left, &right)?
|
fmin_op(&left, &right)?
|
||||||
}
|
}
|
||||||
|
Op::SaturatingOp(mir_op) => {
|
||||||
|
this.saturating_arith(mir_op, &left, &right)?
|
||||||
|
}
|
||||||
};
|
};
|
||||||
this.write_scalar(val, &dest.into())?;
|
this.write_scalar(val, &dest.into())?;
|
||||||
}
|
}
|
||||||
|
@ -102,10 +102,27 @@ fn simd_ops_i32() {
|
|||||||
assert_eq!(a % b, i32x4::from_array([0, 0, 1, 2]));
|
assert_eq!(a % b, i32x4::from_array([0, 0, 1, 2]));
|
||||||
assert_eq!(i32x2::splat(i32::MIN) % i32x2::splat(-1), i32x2::splat(0));
|
assert_eq!(i32x2::splat(i32::MIN) % i32x2::splat(-1), i32x2::splat(0));
|
||||||
assert_eq!(b.abs(), i32x4::from_array([1, 2, 3, 4]));
|
assert_eq!(b.abs(), i32x4::from_array([1, 2, 3, 4]));
|
||||||
// FIXME not a per-lane method (https://github.com/rust-lang/rust/issues/94682)
|
// FIXME not a per-lane method (https://github.com/rust-lang/portable-simd/issues/247)
|
||||||
// assert_eq!(a.max(b * i32x4::splat(4)), i32x4::from_array([10, 10, 12, 10]));
|
// assert_eq!(a.max(b * i32x4::splat(4)), i32x4::from_array([10, 10, 12, 10]));
|
||||||
// assert_eq!(a.min(b * i32x4::splat(4)), i32x4::from_array([4, 8, 10, -16]));
|
// assert_eq!(a.min(b * i32x4::splat(4)), i32x4::from_array([4, 8, 10, -16]));
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
i8x4::from_array([i8::MAX, -23, 23, i8::MIN]).saturating_add(i8x4::from_array([1, i8::MIN, i8::MAX, 28])),
|
||||||
|
i8x4::from_array([i8::MAX, i8::MIN, i8::MAX, -100])
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
i8x4::from_array([i8::MAX, -28, 27, 42]).saturating_sub(i8x4::from_array([1, i8::MAX, i8::MAX, -80])),
|
||||||
|
i8x4::from_array([126, i8::MIN, -100, 122])
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
u8x4::from_array([u8::MAX, 0, 23, 42]).saturating_add(u8x4::from_array([1, 1, u8::MAX, 200])),
|
||||||
|
u8x4::from_array([u8::MAX, 1, u8::MAX, 242])
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
u8x4::from_array([u8::MAX, 0, 23, 42]).saturating_sub(u8x4::from_array([1, 1, u8::MAX, 200])),
|
||||||
|
u8x4::from_array([254, 0, 0, 0])
|
||||||
|
);
|
||||||
|
|
||||||
assert_eq!(!b, i32x4::from_array([!1, !2, !3, !-4]));
|
assert_eq!(!b, i32x4::from_array([!1, !2, !3, !-4]));
|
||||||
assert_eq!(b << i32x4::splat(2), i32x4::from_array([4, 8, 12, -16]));
|
assert_eq!(b << i32x4::splat(2), i32x4::from_array([4, 8, 12, -16]));
|
||||||
assert_eq!(b >> i32x4::splat(1), i32x4::from_array([0, 1, 1, -2]));
|
assert_eq!(b >> i32x4::splat(1), i32x4::from_array([0, 1, 1, -2]));
|
||||||
|
Loading…
Reference in New Issue
Block a user