|
1 | 1 | use rustc_apfloat::{
|
2 | 2 | ieee::{Double, Single},
|
3 |
| - Float as _, FloatConvert as _, |
| 3 | + Float as _, |
4 | 4 | };
|
5 | 5 | use rustc_middle::ty::layout::LayoutOf as _;
|
6 | 6 | use rustc_middle::ty::Ty;
|
@@ -637,51 +637,30 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
637 | 637 | };
|
638 | 638 | this.write_scalar(Scalar::from_i32(i32::from(res)), dest)?;
|
639 | 639 | }
|
640 |
| - // Used to implement the _mm_cvtpd_ps function. |
641 |
| - // Converts packed f32 to packed f64. |
642 |
| - "cvtpd2ps" => { |
| 640 | + // Used to implement the _mm_cvtpd_ps and _mm_cvtps_pd functions. |
| 641 | + // Converts packed f32/f64 to packed f64/f32. |
| 642 | + "cvtpd2ps" | "cvtps2pd" => { |
643 | 643 | let [op] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
644 | 644 |
|
645 | 645 | let (op, op_len) = this.operand_to_simd(op)?;
|
646 | 646 | let (dest, dest_len) = this.place_to_simd(dest)?;
|
647 | 647 |
|
648 |
| - // op is f64x2, dest is f32x4 |
649 |
| - assert_eq!(op_len, 2); |
650 |
| - assert_eq!(dest_len, 4); |
651 |
| - |
652 |
| - for i in 0..op_len { |
653 |
| - let op = this.read_scalar(&this.project_index(&op, i)?)?.to_f64()?; |
| 648 | + // For cvtpd2ps: op is f64x2, dest is f32x4 |
| 649 | + // For cvtps2pd: op is f32x4, dest is f64x2 |
| 650 | + // In either case, the two first values are converted |
| 651 | + for i in 0..op_len.min(dest_len) { |
| 652 | + let op = this.read_immediate(&this.project_index(&op, i)?)?; |
654 | 653 | let dest = this.project_index(&dest, i)?;
|
655 | 654 |
|
656 |
| - let res = op.convert(/*loses_info*/ &mut false).value; |
657 |
| - this.write_scalar(Scalar::from_f32(res), &dest)?; |
| 655 | + let res = this.float_to_float_or_int(&op, dest.layout.ty)?; |
| 656 | + this.write_immediate(res, &dest)?; |
658 | 657 | }
|
659 |
| - // Fill the remaining with zeros |
| 658 | + // For f32 -> f64, ignore the remaining |
| 659 | + // For f64 -> f32, fill the remaining with zeros |
660 | 660 | for i in op_len..dest_len {
|
661 | 661 | let dest = this.project_index(&dest, i)?;
|
662 |
| - this.write_scalar(Scalar::from_u32(0), &dest)?; |
663 |
| - } |
664 |
| - } |
665 |
| - // Used to implement the _mm_cvtps_pd function. |
666 |
| - // Converts packed f64 to packed f32. |
667 |
| - "cvtps2pd" => { |
668 |
| - let [op] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; |
669 |
| - |
670 |
| - let (op, op_len) = this.operand_to_simd(op)?; |
671 |
| - let (dest, dest_len) = this.place_to_simd(dest)?; |
672 |
| - |
673 |
| - // op is f32x4, dest is f64x2 |
674 |
| - assert_eq!(op_len, 4); |
675 |
| - assert_eq!(dest_len, 2); |
676 |
| - |
677 |
| - for i in 0..dest_len { |
678 |
| - let op = this.read_scalar(&this.project_index(&op, i)?)?.to_f32()?; |
679 |
| - let dest = this.project_index(&dest, i)?; |
680 |
| - |
681 |
| - let res = op.convert(/*loses_info*/ &mut false).value; |
682 |
| - this.write_scalar(Scalar::from_f64(res), &dest)?; |
| 662 | + this.write_scalar(Scalar::from_int(0, dest.layout.size), &dest)?; |
683 | 663 | }
|
684 |
| - // the two remaining f32 are ignored |
685 | 664 | }
|
686 | 665 | // Used to implement the _mm_cvtpd_epi32 and _mm_cvttpd_epi32 functions.
|
687 | 666 | // Converts packed f64 to packed i32.
|
|
0 commit comments