@@ -224,6 +224,42 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
224224
225225 shift_simd_by_scalar ( this, left, right, which, dest) ?;
226226 }
227+ // Used to implement the _mm256_madd_epi16 function.
228+ // Multiplies packed signed 16-bit integers in `left` and `right`, producing
229+ // intermediate signed 32-bit integers. Horizontally add adjacent pairs of
230+ // intermediate 32-bit integers, and pack the results in `dest`.
231+ "pmadd.wd" => {
232+ let [ left, right] =
233+ this. check_shim_sig_lenient ( abi, CanonAbi :: C , link_name, args) ?;
234+
235+ let ( left, left_len) = this. project_to_simd ( left) ?;
236+ let ( right, right_len) = this. project_to_simd ( right) ?;
237+ let ( dest, dest_len) = this. project_to_simd ( dest) ?;
238+
239+ assert_eq ! ( left_len, right_len) ;
240+ assert_eq ! ( dest_len. strict_mul( 2 ) , left_len) ;
241+
242+ for i in 0 ..dest_len {
243+ let j1 = i. strict_mul ( 2 ) ;
244+ let left1 = this. read_scalar ( & this. project_index ( & left, j1) ?) ?. to_i16 ( ) ?;
245+ let right1 = this. read_scalar ( & this. project_index ( & right, j1) ?) ?. to_i16 ( ) ?;
246+
247+ let j2 = j1. strict_add ( 1 ) ;
248+ let left2 = this. read_scalar ( & this. project_index ( & left, j2) ?) ?. to_i16 ( ) ?;
249+ let right2 = this. read_scalar ( & this. project_index ( & right, j2) ?) ?. to_i16 ( ) ?;
250+
251+ let dest = this. project_index ( & dest, i) ?;
252+
253+ // Multiplications are i16*i16->i32, which will not overflow.
254+ let mul1 = i32:: from ( left1) . strict_mul ( right1. into ( ) ) ;
255+ let mul2 = i32:: from ( left2) . strict_mul ( right2. into ( ) ) ;
256+ // However, this addition can overflow in the most extreme case
257+ // (-0x8000)*(-0x8000)+(-0x8000)*(-0x8000) = 0x80000000
258+ let res = mul1. wrapping_add ( mul2) ;
259+
260+ this. write_scalar ( Scalar :: from_i32 ( res) , & dest) ?;
261+ }
262+ }
227263 _ => return interp_ok ( EmulateItemResult :: NotSupported ) ,
228264 }
229265 interp_ok ( EmulateItemResult :: NeedsReturn )
0 commit comments