summaryrefslogtreecommitdiff
path: root/DevTools
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2020-07-12 14:45:02 +0200
committerAndreas Kling <kling@serenityos.org>2020-07-12 14:45:02 +0200
commit2d44f4526a9830468f875d8e13e488bc022b7881 (patch)
tree2244608fba3c0aa77dbe10b2430b4d2cc838f731 /DevTools
parented57efff4ffdd91647d457f191bb830a192184d1 (diff)
downloadserenity-2d44f4526a9830468f875d8e13e488bc022b7881.zip
UserspaceEmulator: Implement MOVSB/MOVSW/MOVSD
Diffstat (limited to 'DevTools')
-rw-r--r--DevTools/UserspaceEmulator/SoftCPU.cpp63
1 files changed, 60 insertions, 3 deletions
diff --git a/DevTools/UserspaceEmulator/SoftCPU.cpp b/DevTools/UserspaceEmulator/SoftCPU.cpp
index fc1c244759..ad1d4db67f 100644
--- a/DevTools/UserspaceEmulator/SoftCPU.cpp
+++ b/DevTools/UserspaceEmulator/SoftCPU.cpp
@@ -973,9 +973,66 @@ void SoftCPU::LSL_reg32_RM32(const X86::Instruction&) { TODO(); }
void SoftCPU::LSS_reg16_mem16(const X86::Instruction&) { TODO(); }
void SoftCPU::LSS_reg32_mem32(const X86::Instruction&) { TODO(); }
void SoftCPU::LTR_RM16(const X86::Instruction&) { TODO(); }
-void SoftCPU::MOVSB(const X86::Instruction&) { TODO(); }
-void SoftCPU::MOVSD(const X86::Instruction&) { TODO(); }
-void SoftCPU::MOVSW(const X86::Instruction&) { TODO(); }
+
+void SoftCPU::MOVSB(const X86::Instruction& insn)
+{
+ auto src_segment = segment(insn.segment_prefix().value_or(X86::SegmentRegister::DS));
+ if (insn.has_address_size_override_prefix()) {
+ do_once_or_repeat<false>(insn, [&] {
+ auto src = read_memory8({ src_segment, si() });
+ write_memory8({ es(), di() }, src);
+ set_di(di() + (df() ? -1 : 1));
+ set_si(si() + (df() ? -1 : 1));
+ });
+ } else {
+ do_once_or_repeat<false>(insn, [&] {
+ auto src = read_memory8({ src_segment, esi() });
+ write_memory8({ es(), edi() }, src);
+ set_edi(edi() + (df() ? -1 : 1));
+ set_esi(esi() + (df() ? -1 : 1));
+ });
+ }
+}
+
+void SoftCPU::MOVSD(const X86::Instruction& insn)
+{
+ auto src_segment = segment(insn.segment_prefix().value_or(X86::SegmentRegister::DS));
+ if (insn.has_address_size_override_prefix()) {
+ do_once_or_repeat<false>(insn, [&] {
+ auto src = read_memory32({ src_segment, si() });
+ write_memory32({ es(), di() }, src);
+ set_di(di() + (df() ? -1 : 1));
+ set_si(si() + (df() ? -1 : 1));
+ });
+ } else {
+ do_once_or_repeat<false>(insn, [&] {
+ auto src = read_memory32({ src_segment, esi() });
+ write_memory32({ es(), edi() }, src);
+ set_edi(edi() + (df() ? -1 : 1));
+ set_esi(esi() + (df() ? -1 : 1));
+ });
+ }
+}
+
+void SoftCPU::MOVSW(const X86::Instruction& insn)
+{
+ auto src_segment = segment(insn.segment_prefix().value_or(X86::SegmentRegister::DS));
+ if (insn.has_address_size_override_prefix()) {
+ do_once_or_repeat<false>(insn, [&] {
+ auto src = read_memory16({ src_segment, si() });
+ write_memory16({ es(), di() }, src);
+ set_di(di() + (df() ? -1 : 1));
+ set_si(si() + (df() ? -1 : 1));
+ });
+ } else {
+ do_once_or_repeat<false>(insn, [&] {
+ auto src = read_memory16({ src_segment, esi() });
+ write_memory16({ es(), edi() }, src);
+ set_edi(edi() + (df() ? -1 : 1));
+ set_esi(esi() + (df() ? -1 : 1));
+ });
+ }
+}
void SoftCPU::MOVSX_reg16_RM8(const X86::Instruction&) { TODO(); }
void SoftCPU::MOVSX_reg32_RM16(const X86::Instruction&) { TODO(); }
void SoftCPU::MOVSX_reg32_RM8(const X86::Instruction&) { TODO(); }