From 782b5fe7ac97554f7bf4b9121e985871e650ca41 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Mon, 5 Sep 2022 16:13:36 +0000 Subject: Implement simd_saturating_{add,sub} --- src/intrinsics/mod.rs | 24 ++++++++++++++++++++++++ src/intrinsics/simd.rs | 17 +++++++++++++++-- 2 files changed, 39 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/intrinsics/mod.rs b/src/intrinsics/mod.rs index e06166d0ab7..1e47ccbd49f 100644 --- a/src/intrinsics/mod.rs +++ b/src/intrinsics/mod.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>( fx: &mut FunctionCx<'_, '_, 'tcx>, x: CValue<'tcx>, diff --git a/src/intrinsics/simd.rs b/src/intrinsics/simd.rs index 4d77370dfc5..a70ced7472f 100644 --- a/src/intrinsics/simd.rs +++ b/src/intrinsics/simd.rs @@ -730,9 +730,22 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( 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_saturating_add - // simd_saturating_sub // simd_scatter // simd_gather // simd_select_bitmask -- cgit 1.4.1-3-g733a5