Implement llvm.fma.v* intrinsics · rust-lang/rust@48ca2d9 (original) (raw)

Original file line number Diff line number Diff line change
@@ -132,6 +132,35 @@ fn simd_pair_for_each_lane<'tcx>(
132 132 }
133 133 }
134 134
135 +fn simd_trio_for_each_lane<'tcx>(
136 +fx: &mut FunctionCx<'_, '_, 'tcx>,
137 +x: CValue<'tcx>,
138 +y: CValue<'tcx>,
139 +z: CValue<'tcx>,
140 +ret: CPlace<'tcx>,
141 +f: &dyn Fn(&mut FunctionCx<'_, '_, 'tcx>, Ty<'tcx>, Ty<'tcx>, Value, Value, Value) -> Value,
142 +) {
143 +assert_eq!(x.layout(), y.layout());
144 +let layout = x.layout();
145 +
146 +let (lane_count, lane_ty) = layout.ty.simd_size_and_type(fx.tcx);
147 +let lane_layout = fx.layout_of(lane_ty);
148 +let (ret_lane_count, ret_lane_ty) = ret.layout().ty.simd_size_and_type(fx.tcx);
149 +let ret_lane_layout = fx.layout_of(ret_lane_ty);
150 +assert_eq!(lane_count, ret_lane_count);
151 +
152 +for lane_idx in 0..lane_count {
153 +let x_lane = x.value_lane(fx, lane_idx).load_scalar(fx);
154 +let y_lane = y.value_lane(fx, lane_idx).load_scalar(fx);
155 +let z_lane = z.value_lane(fx, lane_idx).load_scalar(fx);
156 +
157 +let res_lane = f(fx, lane_layout.ty, ret_lane_layout.ty, x_lane, y_lane, z_lane);
158 +let res_lane = CValue::by_val(res_lane, ret_lane_layout);
159 +
160 + ret.place_lane(fx, lane_idx).write_cvalue(fx, res_lane);
161 +}
162 +}
163 +
135 164 fn simd_reduce<'tcx>(
136 165 fx: &mut FunctionCx<'_, '_, 'tcx>,
137 166 val: CValue<'tcx>,