Implement simd_saturating_{add,sub}
This commit is contained in:
parent
0980596271
commit
782b5fe7ac
@ -11,110 +11,6 @@ Subject: [PATCH] Disable unsupported tests
|
|||||||
crates/core_simd/tests/masks.rs | 3 ---
|
crates/core_simd/tests/masks.rs | 3 ---
|
||||||
5 files changed, 20 insertions(+), 3 deletions(-)
|
5 files changed, 20 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
diff --git a/crates/core_simd/src/elements/int.rs b/crates/core_simd/src/elements/int.rs
|
|
||||||
index 9b8c37e..ea95f08 100644
|
|
||||||
--- a/crates/core_simd/src/elements/int.rs
|
|
||||||
+++ b/crates/core_simd/src/elements/int.rs
|
|
||||||
@@ -11,6 +11,7 @@ pub trait SimdInt: Copy + Sealed {
|
|
||||||
/// Scalar type contained by this SIMD vector type.
|
|
||||||
type Scalar;
|
|
||||||
|
|
||||||
+ /*
|
|
||||||
/// Lanewise saturating add.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
@@ -45,6 +46,7 @@ pub trait SimdInt: Copy + Sealed {
|
|
||||||
/// assert_eq!(unsat, Simd::from_array([1, MAX, MIN, 0]));
|
|
||||||
/// assert_eq!(sat, Simd::from_array([MIN, MIN, MIN, 0]));
|
|
||||||
fn saturating_sub(self, second: Self) -> Self;
|
|
||||||
+ */
|
|
||||||
|
|
||||||
/// Lanewise absolute value, implemented in Rust.
|
|
||||||
/// Every lane becomes its absolute value.
|
|
||||||
@@ -61,6 +63,7 @@ pub trait SimdInt: Copy + Sealed {
|
|
||||||
/// ```
|
|
||||||
fn abs(self) -> Self;
|
|
||||||
|
|
||||||
+ /*
|
|
||||||
/// Lanewise saturating absolute value, implemented in Rust.
|
|
||||||
/// As abs(), except the MIN value becomes MAX instead of itself.
|
|
||||||
///
|
|
||||||
@@ -96,6 +99,7 @@ pub trait SimdInt: Copy + Sealed {
|
|
||||||
/// assert_eq!(sat, Simd::from_array([MAX, 2, -3, MIN + 1]));
|
|
||||||
/// ```
|
|
||||||
fn saturating_neg(self) -> Self;
|
|
||||||
+ */
|
|
||||||
|
|
||||||
/// Returns true for each positive lane and false if it is zero or negative.
|
|
||||||
fn is_positive(self) -> Self::Mask;
|
|
||||||
@@ -199,6 +203,7 @@ macro_rules! impl_trait {
|
|
||||||
type Mask = Mask<<$ty as SimdElement>::Mask, LANES>;
|
|
||||||
type Scalar = $ty;
|
|
||||||
|
|
||||||
+ /*
|
|
||||||
#[inline]
|
|
||||||
fn saturating_add(self, second: Self) -> Self {
|
|
||||||
// Safety: `self` is a vector
|
|
||||||
@@ -210,6 +215,7 @@ macro_rules! impl_trait {
|
|
||||||
// Safety: `self` is a vector
|
|
||||||
unsafe { intrinsics::simd_saturating_sub(self, second) }
|
|
||||||
}
|
|
||||||
+ */
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn abs(self) -> Self {
|
|
||||||
@@ -218,6 +224,7 @@ macro_rules! impl_trait {
|
|
||||||
(self^m) - m
|
|
||||||
}
|
|
||||||
|
|
||||||
+ /*
|
|
||||||
#[inline]
|
|
||||||
fn saturating_abs(self) -> Self {
|
|
||||||
// arith shift for -1 or 0 mask based on sign bit, giving 2s complement
|
|
||||||
@@ -230,6 +237,7 @@ macro_rules! impl_trait {
|
|
||||||
fn saturating_neg(self) -> Self {
|
|
||||||
Self::splat(0).saturating_sub(self)
|
|
||||||
}
|
|
||||||
+ */
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn is_positive(self) -> Self::Mask {
|
|
||||||
diff --git a/crates/core_simd/src/elements/uint.rs b/crates/core_simd/src/elements/uint.rs
|
|
||||||
index 21e7e76..0d6dee2 100644
|
|
||||||
--- a/crates/core_simd/src/elements/uint.rs
|
|
||||||
+++ b/crates/core_simd/src/elements/uint.rs
|
|
||||||
@@ -6,6 +6,7 @@ pub trait SimdUint: Copy + Sealed {
|
|
||||||
/// Scalar type contained by this SIMD vector type.
|
|
||||||
type Scalar;
|
|
||||||
|
|
||||||
+ /*
|
|
||||||
/// Lanewise saturating add.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
@@ -40,6 +41,7 @@ pub trait SimdUint: Copy + Sealed {
|
|
||||||
/// assert_eq!(unsat, Simd::from_array([3, 2, 1, 0]));
|
|
||||||
/// assert_eq!(sat, Simd::splat(0));
|
|
||||||
fn saturating_sub(self, second: Self) -> Self;
|
|
||||||
+ */
|
|
||||||
|
|
||||||
/// Returns the sum of the lanes of the vector, with wrapping addition.
|
|
||||||
fn reduce_sum(self) -> Self::Scalar;
|
|
||||||
@@ -78,6 +80,7 @@ macro_rules! impl_trait {
|
|
||||||
{
|
|
||||||
type Scalar = $ty;
|
|
||||||
|
|
||||||
+ /*
|
|
||||||
#[inline]
|
|
||||||
fn saturating_add(self, second: Self) -> Self {
|
|
||||||
// Safety: `self` is a vector
|
|
||||||
@@ -89,6 +92,7 @@ macro_rules! impl_trait {
|
|
||||||
// Safety: `self` is a vector
|
|
||||||
unsafe { intrinsics::simd_saturating_sub(self, second) }
|
|
||||||
}
|
|
||||||
+ */
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn reduce_sum(self) -> Self::Scalar {
|
|
||||||
diff --git a/crates/core_simd/src/masks/full_masks.rs b/crates/core_simd/src/masks/full_masks.rs
|
diff --git a/crates/core_simd/src/masks/full_masks.rs b/crates/core_simd/src/masks/full_masks.rs
|
||||||
index adf0fcb..e7e657e 100644
|
index adf0fcb..e7e657e 100644
|
||||||
--- a/crates/core_simd/src/masks/full_masks.rs
|
--- a/crates/core_simd/src/masks/full_masks.rs
|
||||||
|
@ -84,6 +84,30 @@ fn simd_for_each_lane<'tcx>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn simd_pair_for_each_lane_typed<'tcx>(
|
||||||
|
fx: &mut FunctionCx<'_, '_, 'tcx>,
|
||||||
|
x: CValue<'tcx>,
|
||||||
|
y: CValue<'tcx>,
|
||||||
|
ret: CPlace<'tcx>,
|
||||||
|
f: &dyn Fn(&mut FunctionCx<'_, '_, 'tcx>, CValue<'tcx>, CValue<'tcx>) -> CValue<'tcx>,
|
||||||
|
) {
|
||||||
|
assert_eq!(x.layout(), y.layout());
|
||||||
|
let layout = x.layout();
|
||||||
|
|
||||||
|
let (lane_count, _lane_ty) = layout.ty.simd_size_and_type(fx.tcx);
|
||||||
|
let (ret_lane_count, _ret_lane_ty) = ret.layout().ty.simd_size_and_type(fx.tcx);
|
||||||
|
assert_eq!(lane_count, ret_lane_count);
|
||||||
|
|
||||||
|
for lane_idx in 0..lane_count {
|
||||||
|
let x_lane = x.value_lane(fx, lane_idx);
|
||||||
|
let y_lane = y.value_lane(fx, lane_idx);
|
||||||
|
|
||||||
|
let res_lane = f(fx, x_lane, y_lane);
|
||||||
|
|
||||||
|
ret.place_lane(fx, lane_idx).write_cvalue(fx, res_lane);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn simd_pair_for_each_lane<'tcx>(
|
fn simd_pair_for_each_lane<'tcx>(
|
||||||
fx: &mut FunctionCx<'_, '_, 'tcx>,
|
fx: &mut FunctionCx<'_, '_, 'tcx>,
|
||||||
x: CValue<'tcx>,
|
x: CValue<'tcx>,
|
||||||
|
@ -730,9 +730,22 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
|
|||||||
ret.write_cvalue(fx, res);
|
ret.write_cvalue(fx, res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sym::simd_saturating_add | sym::simd_saturating_sub => {
|
||||||
|
intrinsic_args!(fx, args => (x, y); intrinsic);
|
||||||
|
|
||||||
|
let bin_op = match intrinsic {
|
||||||
|
sym::simd_saturating_add => BinOp::Add,
|
||||||
|
sym::simd_saturating_sub => BinOp::Sub,
|
||||||
|
_ => unreachable!(),
|
||||||
|
};
|
||||||
|
|
||||||
|
// FIXME use vector instructions when possible
|
||||||
|
simd_pair_for_each_lane_typed(fx, x, y, ret, &|fx, x_lane, y_lane| {
|
||||||
|
crate::num::codegen_saturating_int_binop(fx, bin_op, x_lane, y_lane)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// simd_arith_offset
|
// simd_arith_offset
|
||||||
// simd_saturating_add
|
|
||||||
// simd_saturating_sub
|
|
||||||
// simd_scatter
|
// simd_scatter
|
||||||
// simd_gather
|
// simd_gather
|
||||||
// simd_select_bitmask
|
// simd_select_bitmask
|
||||||
|
Loading…
Reference in New Issue
Block a user