@@ -82,6 +82,42 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
82
82
this. write_immediate ( * res, & dest) ?;
83
83
}
84
84
}
85
+ // Used to implement the _mm_madd_epi16 function.
86
+ // Multiplies packed signed 16-bit integers in `left` and `right`, producing
87
+ // intermediate signed 32-bit integers. Horizontally add adjacent pairs of
88
+ // intermediate 32-bit integers, and pack the results in `dest`.
89
+ "pmadd.wd" => {
90
+ let [ left, right] =
91
+ this. check_shim ( abi, Abi :: C { unwind : false } , link_name, args) ?;
92
+
93
+ let ( left, left_len) = this. operand_to_simd ( left) ?;
94
+ let ( right, right_len) = this. operand_to_simd ( right) ?;
95
+ let ( dest, dest_len) = this. place_to_simd ( dest) ?;
96
+
97
+ assert_eq ! ( left_len, right_len) ;
98
+ assert_eq ! ( dest_len. checked_mul( 2 ) . unwrap( ) , left_len) ;
99
+
100
+ for i in 0 ..dest_len {
101
+ let j1 = i. checked_mul ( 2 ) . unwrap ( ) ;
102
+ let left1 = this. read_scalar ( & this. project_index ( & left, j1) ?) ?. to_i16 ( ) ?;
103
+ let right1 = this. read_scalar ( & this. project_index ( & right, j1) ?) ?. to_i16 ( ) ?;
104
+
105
+ let j2 = j1. checked_add ( 1 ) . unwrap ( ) ;
106
+ let left2 = this. read_scalar ( & this. project_index ( & left, j2) ?) ?. to_i16 ( ) ?;
107
+ let right2 = this. read_scalar ( & this. project_index ( & right, j2) ?) ?. to_i16 ( ) ?;
108
+
109
+ let dest = this. project_index ( & dest, i) ?;
110
+
111
+ // Multiplications are i16*i16->i32, which will not overflow.
112
+ let mul1 = i32:: from ( left1) . checked_mul ( right1. into ( ) ) . unwrap ( ) ;
113
+ let mul2 = i32:: from ( left2) . checked_mul ( right2. into ( ) ) . unwrap ( ) ;
114
+ // However, this addition can overflow in the most extreme case
115
+ // (-0x8000)*(-0x8000)+(-0x8000)*(-0x8000) = 0x80000000
116
+ let res = mul1. wrapping_add ( mul2) ;
117
+
118
+ this. write_scalar ( Scalar :: from_i32 ( res) , & dest) ?;
119
+ }
120
+ }
85
121
// Used to implement the _mm_mulhi_epi16 and _mm_mulhi_epu16 functions.
86
122
"pmulh.w" | "pmulhu.w" => {
87
123
let [ left, right] =
0 commit comments