Skip to content

Commit a0ce060

Browse files
committed
Move implementation of SSE4.1 ptest* into a helper function
1 parent 8c5882e commit a0ce060

File tree

2 files changed

+41
-21
lines changed

2 files changed

+41
-21
lines changed

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

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -615,3 +615,31 @@ fn horizontal_bin_op<'tcx>(
615615

616616
Ok(())
617617
}
618+
619+
/// Folds SIMD vectors `lhs` and `rhs` into a value of type `T` using `f`.
620+
fn bin_op_folded<'tcx, T>(
621+
this: &crate::MiriInterpCx<'_, 'tcx>,
622+
lhs: &OpTy<'tcx, Provenance>,
623+
rhs: &OpTy<'tcx, Provenance>,
624+
init: T,
625+
mut f: impl FnMut(T, ImmTy<'tcx, Provenance>, ImmTy<'tcx, Provenance>) -> InterpResult<'tcx, T>,
626+
) -> InterpResult<'tcx, T> {
627+
assert_eq!(lhs.layout, rhs.layout);
628+
629+
let (lhs, lhs_len) = this.operand_to_simd(lhs)?;
630+
let (rhs, rhs_len) = this.operand_to_simd(rhs)?;
631+
632+
assert_eq!(lhs_len, rhs_len);
633+
634+
let mut acc = init;
635+
for i in 0..lhs_len {
636+
let lhs = this.project_index(&lhs, i)?;
637+
let rhs = this.project_index(&rhs, i)?;
638+
639+
let lhs = this.read_immediate(&lhs)?;
640+
let rhs = this.read_immediate(&rhs)?;
641+
acc = f(acc, lhs, rhs)?;
642+
}
643+
644+
Ok(acc)
645+
}

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

Lines changed: 13 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use rustc_middle::mir;
22
use rustc_span::Symbol;
33
use rustc_target::spec::abi::Abi;
44

5-
use super::{round_all, round_first};
5+
use super::{bin_op_folded, round_all, round_first};
66
use crate::*;
77
use shims::foreign_items::EmulateForeignItemResult;
88

@@ -257,26 +257,18 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
257257
"ptestz" | "ptestc" | "ptestnzc" => {
258258
let [op, mask] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
259259

260-
let (op, op_len) = this.operand_to_simd(op)?;
261-
let (mask, mask_len) = this.operand_to_simd(mask)?;
262-
263-
assert_eq!(op_len, mask_len);
264-
265-
let f = match unprefixed_name {
266-
"ptestz" => |op, mask| op & mask == 0,
267-
"ptestc" => |op, mask| op & mask == mask,
268-
"ptestnzc" => |op, mask| op & mask != 0 && op & mask != mask,
269-
_ => unreachable!(),
270-
};
271-
272-
let mut all_zero = true;
273-
for i in 0..op_len {
274-
let op = this.read_scalar(&this.project_index(&op, i)?)?.to_u64()?;
275-
let mask = this.read_scalar(&this.project_index(&mask, i)?)?.to_u64()?;
276-
all_zero &= f(op, mask);
277-
}
278-
279-
this.write_scalar(Scalar::from_i32(all_zero.into()), dest)?;
260+
let res = bin_op_folded(this, op, mask, true, |acc, op, mask| {
261+
let op = op.to_scalar().to_uint(op.layout.size)?;
262+
let mask = mask.to_scalar().to_uint(mask.layout.size)?;
263+
Ok(match unprefixed_name {
264+
"ptestz" => acc && (op & mask) == 0,
265+
"ptestc" => acc && (op & mask) == mask,
266+
"ptestnzc" => acc && (op & mask) != 0 && (op & mask) != mask,
267+
_ => unreachable!(),
268+
})
269+
})?;
270+
271+
this.write_scalar(Scalar::from_i32(res.into()), dest)?;
280272
}
281273
_ => return Ok(EmulateForeignItemResult::NotSupported),
282274
}

0 commit comments

Comments
 (0)