|
1 |
| -use rustc_apfloat::{ |
2 |
| - ieee::{Double, Single}, |
3 |
| - Float as _, |
4 |
| -}; |
5 |
| -use rustc_middle::mir; |
| 1 | +use rustc_apfloat::ieee::Double; |
6 | 2 | use rustc_middle::ty::layout::LayoutOf as _;
|
7 | 3 | use rustc_middle::ty::Ty;
|
8 | 4 | use rustc_span::Symbol;
|
@@ -39,49 +35,6 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
|
39 | 35 | // Intrinsincs sufixed with "epiX" or "epuX" operate with X-bit signed or unsigned
|
40 | 36 | // vectors.
|
41 | 37 | match unprefixed_name {
|
42 |
| - // Used to implement the _mm_avg_epu8 and _mm_avg_epu16 functions. |
43 |
| - // Averages packed unsigned 8/16-bit integers in `left` and `right`. |
44 |
| - "pavg.b" | "pavg.w" => { |
45 |
| - let [left, right] = |
46 |
| - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; |
47 |
| - |
48 |
| - let (left, left_len) = this.operand_to_simd(left)?; |
49 |
| - let (right, right_len) = this.operand_to_simd(right)?; |
50 |
| - let (dest, dest_len) = this.place_to_simd(dest)?; |
51 |
| - |
52 |
| - assert_eq!(dest_len, left_len); |
53 |
| - assert_eq!(dest_len, right_len); |
54 |
| - |
55 |
| - for i in 0..dest_len { |
56 |
| - let left = this.read_immediate(&this.project_index(&left, i)?)?; |
57 |
| - let right = this.read_immediate(&this.project_index(&right, i)?)?; |
58 |
| - let dest = this.project_index(&dest, i)?; |
59 |
| - |
60 |
| - // Widen the operands to avoid overflow |
61 |
| - let twice_wide = this.layout_of(this.get_twice_wide_int_ty(left.layout.ty))?; |
62 |
| - let left = this.int_to_int_or_float(&left, twice_wide)?; |
63 |
| - let right = this.int_to_int_or_float(&right, twice_wide)?; |
64 |
| - |
65 |
| - // Calculate left + right + 1 |
66 |
| - let added = this.wrapping_binary_op(mir::BinOp::Add, &left, &right)?; |
67 |
| - let added = this.wrapping_binary_op( |
68 |
| - mir::BinOp::Add, |
69 |
| - &added, |
70 |
| - &ImmTy::from_uint(1u32, twice_wide), |
71 |
| - )?; |
72 |
| - |
73 |
| - // Calculate (left + right + 1) / 2 |
74 |
| - let divided = this.wrapping_binary_op( |
75 |
| - mir::BinOp::Div, |
76 |
| - &added, |
77 |
| - &ImmTy::from_uint(2u32, twice_wide), |
78 |
| - )?; |
79 |
| - |
80 |
| - // Narrow back to the original type |
81 |
| - let res = this.int_to_int_or_float(÷d, dest.layout)?; |
82 |
| - this.write_immediate(*res, &dest)?; |
83 |
| - } |
84 |
| - } |
85 | 38 | // Used to implement the _mm_madd_epi16 function.
|
86 | 39 | // Multiplies packed signed 16-bit integers in `left` and `right`, producing
|
87 | 40 | // intermediate signed 32-bit integers. Horizontally add adjacent pairs of
|
@@ -118,70 +71,6 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
|
118 | 71 | this.write_scalar(Scalar::from_i32(res), &dest)?;
|
119 | 72 | }
|
120 | 73 | }
|
121 |
| - // Used to implement the _mm_mulhi_epi16 and _mm_mulhi_epu16 functions. |
122 |
| - "pmulh.w" | "pmulhu.w" => { |
123 |
| - let [left, right] = |
124 |
| - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; |
125 |
| - |
126 |
| - let (left, left_len) = this.operand_to_simd(left)?; |
127 |
| - let (right, right_len) = this.operand_to_simd(right)?; |
128 |
| - let (dest, dest_len) = this.place_to_simd(dest)?; |
129 |
| - |
130 |
| - assert_eq!(dest_len, left_len); |
131 |
| - assert_eq!(dest_len, right_len); |
132 |
| - |
133 |
| - for i in 0..dest_len { |
134 |
| - let left = this.read_immediate(&this.project_index(&left, i)?)?; |
135 |
| - let right = this.read_immediate(&this.project_index(&right, i)?)?; |
136 |
| - let dest = this.project_index(&dest, i)?; |
137 |
| - |
138 |
| - // Widen the operands to avoid overflow |
139 |
| - let twice_wide = this.layout_of(this.get_twice_wide_int_ty(left.layout.ty))?; |
140 |
| - let left = this.int_to_int_or_float(&left, twice_wide)?; |
141 |
| - let right = this.int_to_int_or_float(&right, twice_wide)?; |
142 |
| - |
143 |
| - // Multiply |
144 |
| - let multiplied = this.wrapping_binary_op(mir::BinOp::Mul, &left, &right)?; |
145 |
| - // Keep the high half |
146 |
| - let high = this.wrapping_binary_op( |
147 |
| - mir::BinOp::Shr, |
148 |
| - &multiplied, |
149 |
| - &ImmTy::from_uint(dest.layout.size.bits(), twice_wide), |
150 |
| - )?; |
151 |
| - |
152 |
| - // Narrow back to the original type |
153 |
| - let res = this.int_to_int_or_float(&high, dest.layout)?; |
154 |
| - this.write_immediate(*res, &dest)?; |
155 |
| - } |
156 |
| - } |
157 |
| - // Used to implement the _mm_mul_epu32 function. |
158 |
| - // Multiplies the the low unsigned 32-bit integers from each packed |
159 |
| - // 64-bit element and stores the result as 64-bit unsigned integers. |
160 |
| - "pmulu.dq" => { |
161 |
| - let [left, right] = |
162 |
| - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; |
163 |
| - |
164 |
| - let (left, left_len) = this.operand_to_simd(left)?; |
165 |
| - let (right, right_len) = this.operand_to_simd(right)?; |
166 |
| - let (dest, dest_len) = this.place_to_simd(dest)?; |
167 |
| - |
168 |
| - // left and right are u32x4, dest is u64x2 |
169 |
| - assert_eq!(left_len, 4); |
170 |
| - assert_eq!(right_len, 4); |
171 |
| - assert_eq!(dest_len, 2); |
172 |
| - |
173 |
| - for i in 0..dest_len { |
174 |
| - let op_i = i.checked_mul(2).unwrap(); |
175 |
| - let left = this.read_scalar(&this.project_index(&left, op_i)?)?.to_u32()?; |
176 |
| - let right = this.read_scalar(&this.project_index(&right, op_i)?)?.to_u32()?; |
177 |
| - let dest = this.project_index(&dest, i)?; |
178 |
| - |
179 |
| - // The multiplication will not overflow because stripping the |
180 |
| - // operands are expanded from 32-bit to 64-bit. |
181 |
| - let res = u64::from(left).checked_mul(u64::from(right)).unwrap(); |
182 |
| - this.write_scalar(Scalar::from_u64(res), &dest)?; |
183 |
| - } |
184 |
| - } |
185 | 74 | // Used to implement the _mm_sad_epu8 function.
|
186 | 75 | // Computes the absolute differences of packed unsigned 8-bit integers in `a`
|
187 | 76 | // and `b`, then horizontally sum each consecutive 8 differences to produce
|
@@ -370,25 +259,6 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
|
370 | 259 | this.write_scalar(Scalar::from_u64(res), &dest)?;
|
371 | 260 | }
|
372 | 261 | }
|
373 |
| - // Used to implement the _mm_cvtepi32_ps function. |
374 |
| - // Converts packed i32 to packed f32. |
375 |
| - // FIXME: Can we get rid of this intrinsic and just use simd_as? |
376 |
| - "cvtdq2ps" => { |
377 |
| - let [op] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; |
378 |
| - |
379 |
| - let (op, op_len) = this.operand_to_simd(op)?; |
380 |
| - let (dest, dest_len) = this.place_to_simd(dest)?; |
381 |
| - |
382 |
| - assert_eq!(dest_len, op_len); |
383 |
| - |
384 |
| - for i in 0..dest_len { |
385 |
| - let op = this.read_scalar(&this.project_index(&op, i)?)?.to_i32()?; |
386 |
| - let dest = this.project_index(&dest, i)?; |
387 |
| - |
388 |
| - let res = Scalar::from_f32(Single::from_i128(op.into()).value); |
389 |
| - this.write_scalar(res, &dest)?; |
390 |
| - } |
391 |
| - } |
392 | 262 | // Used to implement the _mm_cvtps_epi32 and _mm_cvttps_epi32 functions.
|
393 | 263 | // Converts packed f32 to packed i32.
|
394 | 264 | "cvtps2dq" | "cvttps2dq" => {
|
@@ -652,31 +522,6 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
|
652 | 522 | };
|
653 | 523 | this.write_scalar(Scalar::from_i32(i32::from(res)), dest)?;
|
654 | 524 | }
|
655 |
| - // Used to implement the _mm_cvtpd_ps and _mm_cvtps_pd functions. |
656 |
| - // Converts packed f32/f64 to packed f64/f32. |
657 |
| - "cvtpd2ps" | "cvtps2pd" => { |
658 |
| - let [op] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; |
659 |
| - |
660 |
| - let (op, op_len) = this.operand_to_simd(op)?; |
661 |
| - let (dest, dest_len) = this.place_to_simd(dest)?; |
662 |
| - |
663 |
| - // For cvtpd2ps: op is f64x2, dest is f32x4 |
664 |
| - // For cvtps2pd: op is f32x4, dest is f64x2 |
665 |
| - // In either case, the two first values are converted |
666 |
| - for i in 0..op_len.min(dest_len) { |
667 |
| - let op = this.read_immediate(&this.project_index(&op, i)?)?; |
668 |
| - let dest = this.project_index(&dest, i)?; |
669 |
| - |
670 |
| - let res = this.float_to_float_or_int(&op, dest.layout)?; |
671 |
| - this.write_immediate(*res, &dest)?; |
672 |
| - } |
673 |
| - // For f32 -> f64, ignore the remaining |
674 |
| - // For f64 -> f32, fill the remaining with zeros |
675 |
| - for i in op_len..dest_len { |
676 |
| - let dest = this.project_index(&dest, i)?; |
677 |
| - this.write_scalar(Scalar::from_int(0, dest.layout.size), &dest)?; |
678 |
| - } |
679 |
| - } |
680 | 525 | // Used to implement the _mm_cvtpd_epi32 and _mm_cvttpd_epi32 functions.
|
681 | 526 | // Converts packed f64 to packed i32.
|
682 | 527 | "cvtpd2dq" | "cvttpd2dq" => {
|
@@ -772,25 +617,6 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
|
772 | 617 | )?;
|
773 | 618 | }
|
774 | 619 | }
|
775 |
| - // Used to implement the _mm_movemask_pd function. |
776 |
| - // Returns a scalar integer where the i-th bit is the highest |
777 |
| - // bit of the i-th component of `op`. |
778 |
| - // https://www.felixcloutier.com/x86/movmskpd |
779 |
| - "movmsk.pd" => { |
780 |
| - let [op] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; |
781 |
| - let (op, op_len) = this.operand_to_simd(op)?; |
782 |
| - |
783 |
| - let mut res = 0; |
784 |
| - for i in 0..op_len { |
785 |
| - let op = this.read_scalar(&this.project_index(&op, i)?)?; |
786 |
| - let op = op.to_u64()?; |
787 |
| - |
788 |
| - // Extract the highest bit of `op` and place it in the `i`-th bit of `res` |
789 |
| - res |= (op >> 63) << i; |
790 |
| - } |
791 |
| - |
792 |
| - this.write_scalar(Scalar::from_u32(res.try_into().unwrap()), dest)?; |
793 |
| - } |
794 | 620 | // Used to implement the `_mm_pause` function.
|
795 | 621 | // The intrinsic is used to hint the processor that the code is in a spin-loop.
|
796 | 622 | "pause" => {
|
|
0 commit comments