Skip to content

Commit 1afce7c

Browse files
committed
Implement simd_insert_dyn and simd_extract_dyn intrinsics
1 parent f99bdfe commit 1afce7c

File tree

2 files changed

+56
-0
lines changed

2 files changed

+56
-0
lines changed

src/intrinsics/simd.rs

+28
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,20 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
283283
ret_lane.write_cvalue(fx, val);
284284
}
285285

286+
sym::simd_insert_dyn => {
287+
intrinsic_args!(fx, args => (base, idx, val); intrinsic);
288+
289+
if !base.layout().ty.is_simd() {
290+
report_simd_type_validation_error(fx, intrinsic, span, base.layout().ty);
291+
return;
292+
}
293+
294+
let idx = idx.load_scalar(fx);
295+
296+
ret.write_cvalue(fx, base);
297+
ret.write_lane_dyn(fx, idx, val);
298+
}
299+
286300
sym::simd_extract => {
287301
let (v, idx) = match args {
288302
[v, idx] => (v, idx),
@@ -318,6 +332,20 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
318332
ret.write_cvalue(fx, ret_lane);
319333
}
320334

335+
sym::simd_extract_dyn => {
336+
intrinsic_args!(fx, args => (v, idx); intrinsic);
337+
338+
if !v.layout().ty.is_simd() {
339+
report_simd_type_validation_error(fx, intrinsic, span, v.layout().ty);
340+
return;
341+
}
342+
343+
let idx = idx.load_scalar(fx);
344+
345+
let ret_lane = v.value_lane_dyn(fx, idx);
346+
ret.write_cvalue(fx, ret_lane);
347+
}
348+
321349
sym::simd_neg
322350
| sym::simd_bswap
323351
| sym::simd_bitreverse

src/value_and_place.rs

+28
Original file line numberDiff line numberDiff line change
@@ -806,6 +806,34 @@ impl<'tcx> CPlace<'tcx> {
806806
}
807807
}
808808

809+
/// Write a value to an individual lane in a SIMD vector.
810+
pub(crate) fn write_lane_dyn(
811+
self,
812+
fx: &mut FunctionCx<'_, '_, 'tcx>,
813+
lane_idx: Value,
814+
value: CValue<'tcx>,
815+
) {
816+
let layout = self.layout();
817+
assert!(layout.ty.is_simd());
818+
let (_lane_count, lane_ty) = layout.ty.simd_size_and_type(fx.tcx);
819+
let lane_layout = fx.layout_of(lane_ty);
820+
assert_eq!(lane_layout, value.layout());
821+
822+
match self.inner {
823+
CPlaceInner::Var(_, _) => unreachable!(),
824+
CPlaceInner::VarPair(_, _, _) => unreachable!(),
825+
CPlaceInner::Addr(ptr, None) => {
826+
let field_offset = fx
827+
.bcx
828+
.ins()
829+
.imul_imm(lane_idx, i64::try_from(lane_layout.size.bytes()).unwrap());
830+
let field_ptr = ptr.offset_value(fx, field_offset);
831+
CPlace::for_ptr(field_ptr, lane_layout).write_cvalue(fx, value);
832+
}
833+
CPlaceInner::Addr(_, Some(_)) => unreachable!(),
834+
}
835+
}
836+
809837
pub(crate) fn place_index(
810838
self,
811839
fx: &mut FunctionCx<'_, '_, 'tcx>,

0 commit comments

Comments
 (0)