|
1 | 1 | //! Codegen `extern "platform-intrinsic"` intrinsics.
|
2 | 2 |
|
| 3 | +use cranelift_codegen::ir::immediates::Offset32; |
3 | 4 | use rustc_middle::ty::GenericArgsRef;
|
4 | 5 | use rustc_span::Symbol;
|
5 | 6 | use rustc_target::abi::Endian;
|
@@ -1008,8 +1009,57 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
|
1008 | 1009 | }
|
1009 | 1010 | }
|
1010 | 1011 |
|
| 1012 | + sym::simd_masked_load => { |
| 1013 | + intrinsic_args!(fx, args => (mask, ptr, val); intrinsic); |
| 1014 | + |
| 1015 | + let (val_lane_count, val_lane_ty) = val.layout().ty.simd_size_and_type(fx.tcx); |
| 1016 | + let (mask_lane_count, _mask_lane_ty) = mask.layout().ty.simd_size_and_type(fx.tcx); |
| 1017 | + let (ret_lane_count, ret_lane_ty) = ret.layout().ty.simd_size_and_type(fx.tcx); |
| 1018 | + assert_eq!(val_lane_count, mask_lane_count); |
| 1019 | + assert_eq!(val_lane_count, ret_lane_count); |
| 1020 | + |
| 1021 | + let lane_clif_ty = fx.clif_type(val_lane_ty).unwrap(); |
| 1022 | + let ret_lane_layout = fx.layout_of(ret_lane_ty); |
| 1023 | + let ptr_val = ptr.load_scalar(fx); |
| 1024 | + |
| 1025 | + for lane_idx in 0..ret_lane_count { |
| 1026 | + let val_lane = val.value_lane(fx, lane_idx).load_scalar(fx); |
| 1027 | + let mask_lane = mask.value_lane(fx, lane_idx).load_scalar(fx); |
| 1028 | + |
| 1029 | + let if_enabled = fx.bcx.create_block(); |
| 1030 | + let if_disabled = fx.bcx.create_block(); |
| 1031 | + let next = fx.bcx.create_block(); |
| 1032 | + let res_lane = fx.bcx.append_block_param(next, lane_clif_ty); |
| 1033 | + |
| 1034 | + fx.bcx.ins().brif(mask_lane, if_enabled, &[], if_disabled, &[]); |
| 1035 | + fx.bcx.seal_block(if_enabled); |
| 1036 | + fx.bcx.seal_block(if_disabled); |
| 1037 | + |
| 1038 | + fx.bcx.switch_to_block(if_enabled); |
| 1039 | + let offset = lane_idx as i32 * lane_clif_ty.bytes() as i32; |
| 1040 | + let res = fx.bcx.ins().load( |
| 1041 | + lane_clif_ty, |
| 1042 | + MemFlags::trusted(), |
| 1043 | + ptr_val, |
| 1044 | + Offset32::new(offset), |
| 1045 | + ); |
| 1046 | + fx.bcx.ins().jump(next, &[res]); |
| 1047 | + |
| 1048 | + fx.bcx.switch_to_block(if_disabled); |
| 1049 | + fx.bcx.ins().jump(next, &[val_lane]); |
| 1050 | + |
| 1051 | + fx.bcx.seal_block(next); |
| 1052 | + fx.bcx.switch_to_block(next); |
| 1053 | + |
| 1054 | + fx.bcx.ins().nop(); |
| 1055 | + |
| 1056 | + ret.place_lane(fx, lane_idx) |
| 1057 | + .write_cvalue(fx, CValue::by_val(res_lane, ret_lane_layout)); |
| 1058 | + } |
| 1059 | + } |
| 1060 | + |
1011 | 1061 | sym::simd_scatter => {
|
1012 |
| - intrinsic_args!(fx, args => (val, ptr, mask); intrinsic); |
| 1062 | + intrinsic_args!(fx, args => (mask, ptr, val); intrinsic); |
1013 | 1063 |
|
1014 | 1064 | let (val_lane_count, _val_lane_ty) = val.layout().ty.simd_size_and_type(fx.tcx);
|
1015 | 1065 | let (ptr_lane_count, _ptr_lane_ty) = ptr.layout().ty.simd_size_and_type(fx.tcx);
|
|
0 commit comments