1use super::AlignmentMode;
5use super::Emulator;
6use super::Error;
7use super::InternalError;
8use crate::Cpu;
9use crate::Segment;
10use iced_x86::Instruction;
11use iced_x86::OpKind;
12
13impl<T: Cpu> Emulator<'_, T> {
14 pub(super) async fn mov(&mut self, instr: &Instruction) -> Result<(), InternalError<T::Error>> {
15 let value = self.op_value(instr, 1).await?;
16 self.write_op_0(instr, value).await?;
17 Ok(())
18 }
19
20 pub(super) async fn movsx(
21 &mut self,
22 instr: &Instruction,
23 ) -> Result<(), InternalError<T::Error>> {
24 let value = self.op_value_sign_extend(instr, 1).await?;
25 self.write_op_0(instr, value as u64).await?;
26 Ok(())
27 }
28
29 pub(super) async fn mov_sse(
30 &mut self,
31 instr: &Instruction,
32 alignment: AlignmentMode,
33 ) -> Result<(), InternalError<T::Error>> {
34 let value = match instr.op1_kind() {
35 OpKind::Memory => self.read_memory_op(instr, 1, alignment).await?,
36 OpKind::Register => {
37 let reg = instr.op1_register();
38 assert!(reg.is_xmm());
39 self.cpu.xmm(reg.number())
40 }
41 _ => Err(self.unsupported_instruction(instr))?,
42 };
43
44 match instr.op0_kind() {
45 OpKind::Memory => self.write_memory_op(instr, 0, alignment, value).await?,
46 OpKind::Register => {
47 let reg = instr.op0_register();
48 assert!(reg.is_xmm());
49 let xmm_index = reg.number();
50 self.cpu.set_xmm(xmm_index, value).map_err(|err| {
51 Error::XmmRegister(xmm_index, super::OperationKind::Write, err)
52 })?
53 }
54 _ => Err(self.unsupported_instruction(instr))?,
55 };
56
57 Ok(())
58 }
59
60 pub(super) async fn movdir64b(
61 &mut self,
62 instr: &Instruction,
63 ) -> Result<(), InternalError<T::Error>> {
64 let mut buffer = [0; 64];
65 let src = self.memory_op_offset(instr, 1);
66 let dst = self.cpu.gp(instr.op0_register().into());
67
68 self.read_memory(
69 instr.memory_segment().into(),
70 src,
71 AlignmentMode::Unaligned,
72 &mut buffer,
73 )
74 .await?;
75
76 self.write_memory(Segment::ES, dst, AlignmentMode::Aligned(64), &buffer)
77 .await?;
78
79 Ok(())
80 }
81}