Skip to content

Commit e634c18

Browse files
committed
miri: reduce code duplication in SSE2 cvtpd2ps/cvtps2pd
1 parent 9bd648b commit e634c18

File tree

1 file changed

+14
-35
lines changed
  • src/tools/miri/src/shims/x86

1 file changed

+14
-35
lines changed

src/tools/miri/src/shims/x86/sse2.rs

+14-35
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use rustc_apfloat::{
22
ieee::{Double, Single},
3-
Float as _, FloatConvert as _,
3+
Float as _,
44
};
55
use rustc_middle::ty::layout::LayoutOf as _;
66
use rustc_middle::ty::Ty;
@@ -637,51 +637,30 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
637637
};
638638
this.write_scalar(Scalar::from_i32(i32::from(res)), dest)?;
639639
}
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" => {
643643
let [op] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
644644

645645
let (op, op_len) = this.operand_to_simd(op)?;
646646
let (dest, dest_len) = this.place_to_simd(dest)?;
647647

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)?)?;
654653
let dest = this.project_index(&dest, i)?;
655654

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)?;
658657
}
659-
// Fill the remaining with zeros
658+
// For f32 -> f64, ignore the remaining
659+
// For f64 -> f32, fill the remaining with zeros
660660
for i in op_len..dest_len {
661661
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)?;
683663
}
684-
// the two remaining f32 are ignored
685664
}
686665
// Used to implement the _mm_cvtpd_epi32 and _mm_cvttpd_epi32 functions.
687666
// Converts packed f64 to packed i32.

0 commit comments

Comments
 (0)