Skip to main content

miri/intrinsics/x86/
sse3.rs

1use rustc_span::Symbol;
2
3use crate::*;
4
5impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
6pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
7    fn emulate_x86_sse3_intrinsic(
8        &mut self,
9        link_name: Symbol,
10        args: &[OpTy<'tcx>],
11        dest: &MPlaceTy<'tcx>,
12    ) -> InterpResult<'tcx, EmulateItemResult> {
13        let this = self.eval_context_mut();
14        this.expect_target_feature_for_intrinsic(link_name, "sse3")?;
15        // Prefix should have already been checked.
16        let unprefixed_name = link_name.as_str().strip_prefix("llvm.x86.sse3.").unwrap();
17
18        match unprefixed_name {
19            // Used to implement the _mm_lddqu_si128 function.
20            // Reads a 128-bit vector from an unaligned pointer. This intrinsic
21            // is expected to perform better than a regular unaligned read when
22            // the data crosses a cache line, but for Miri this is just a regular
23            // unaligned read.
24            "ldu.dq" => {
25                let [src_ptr] = this.check_shim_sig_unadjusted(link_name, args)?;
26                let src_ptr = this.read_pointer(src_ptr)?;
27                let dest = dest.force_mplace(this)?;
28
29                this.mem_copy(src_ptr, dest.ptr(), dest.layout.size, /*nonoverlapping*/ true)?;
30            }
31            _ => return interp_ok(EmulateItemResult::NotSupported),
32        }
33        interp_ok(EmulateItemResult::NeedsReturn)
34    }
35}