Implement simd_insert_dyn and simd_extract_dyn intrinsics
This commit is contained in:
parent
f99bdfef83
commit
1afce7c354
2 changed files with 56 additions and 0 deletions
|
|
@ -283,6 +283,20 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
|
|||
ret_lane.write_cvalue(fx, val);
|
||||
}
|
||||
|
||||
sym::simd_insert_dyn => {
|
||||
intrinsic_args!(fx, args => (base, idx, val); intrinsic);
|
||||
|
||||
if !base.layout().ty.is_simd() {
|
||||
report_simd_type_validation_error(fx, intrinsic, span, base.layout().ty);
|
||||
return;
|
||||
}
|
||||
|
||||
let idx = idx.load_scalar(fx);
|
||||
|
||||
ret.write_cvalue(fx, base);
|
||||
ret.write_lane_dyn(fx, idx, val);
|
||||
}
|
||||
|
||||
sym::simd_extract => {
|
||||
let (v, idx) = match args {
|
||||
[v, idx] => (v, idx),
|
||||
|
|
@ -318,6 +332,20 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
|
|||
ret.write_cvalue(fx, ret_lane);
|
||||
}
|
||||
|
||||
sym::simd_extract_dyn => {
|
||||
intrinsic_args!(fx, args => (v, idx); intrinsic);
|
||||
|
||||
if !v.layout().ty.is_simd() {
|
||||
report_simd_type_validation_error(fx, intrinsic, span, v.layout().ty);
|
||||
return;
|
||||
}
|
||||
|
||||
let idx = idx.load_scalar(fx);
|
||||
|
||||
let ret_lane = v.value_lane_dyn(fx, idx);
|
||||
ret.write_cvalue(fx, ret_lane);
|
||||
}
|
||||
|
||||
sym::simd_neg
|
||||
| sym::simd_bswap
|
||||
| sym::simd_bitreverse
|
||||
|
|
|
|||
|
|
@ -806,6 +806,34 @@ impl<'tcx> CPlace<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Write a value to an individual lane in a SIMD vector.
|
||||
pub(crate) fn write_lane_dyn(
|
||||
self,
|
||||
fx: &mut FunctionCx<'_, '_, 'tcx>,
|
||||
lane_idx: Value,
|
||||
value: CValue<'tcx>,
|
||||
) {
|
||||
let layout = self.layout();
|
||||
assert!(layout.ty.is_simd());
|
||||
let (_lane_count, lane_ty) = layout.ty.simd_size_and_type(fx.tcx);
|
||||
let lane_layout = fx.layout_of(lane_ty);
|
||||
assert_eq!(lane_layout, value.layout());
|
||||
|
||||
match self.inner {
|
||||
CPlaceInner::Var(_, _) => unreachable!(),
|
||||
CPlaceInner::VarPair(_, _, _) => unreachable!(),
|
||||
CPlaceInner::Addr(ptr, None) => {
|
||||
let field_offset = fx
|
||||
.bcx
|
||||
.ins()
|
||||
.imul_imm(lane_idx, i64::try_from(lane_layout.size.bytes()).unwrap());
|
||||
let field_ptr = ptr.offset_value(fx, field_offset);
|
||||
CPlace::for_ptr(field_ptr, lane_layout).write_cvalue(fx, value);
|
||||
}
|
||||
CPlaceInner::Addr(_, Some(_)) => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn place_index(
|
||||
self,
|
||||
fx: &mut FunctionCx<'_, '_, 'tcx>,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue