diff options
author | Andreas Kling <kling@serenityos.org> | 2020-07-18 00:16:00 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-07-18 00:25:02 +0200 |
commit | 79290696cf56d43bb8b88deb94d012b0236264e0 (patch) | |
tree | fa14b6890bf5b3781fdebd6de1bb153b62d5f205 /DevTools/UserspaceEmulator | |
parent | f70f5307220d80526bd3f12d86966156f4ec6752 (diff) | |
download | serenity-79290696cf56d43bb8b88deb94d012b0236264e0.zip |
UserspaceEmulator: Simplify MOVSB/MOVSW/MOVSD instructions
Use the new loop instruction helpers.
Diffstat (limited to 'DevTools/UserspaceEmulator')
-rw-r--r-- | DevTools/UserspaceEmulator/SoftCPU.cpp | 63 |
1 files changed, 15 insertions, 48 deletions
diff --git a/DevTools/UserspaceEmulator/SoftCPU.cpp b/DevTools/UserspaceEmulator/SoftCPU.cpp index 7d6f8dfcd6..013441f764 100644 --- a/DevTools/UserspaceEmulator/SoftCPU.cpp +++ b/DevTools/UserspaceEmulator/SoftCPU.cpp @@ -1440,64 +1440,31 @@ 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(); } +template<typename T> +ALWAYS_INLINE static void do_movs(SoftCPU& cpu, const X86::Instruction& insn) +{ + auto src_segment = cpu.segment(insn.segment_prefix().value_or(X86::SegmentRegister::DS)); + cpu.do_once_or_repeat<false>(insn, [&] { + auto src = cpu.read_memory<T>({ src_segment, cpu.source_index(insn.a32()) }); + cpu.write_memory<T>({ cpu.es(), cpu.destination_index(insn.a32()) }, src); + cpu.step_source_index(insn.a32(), sizeof(T)); + cpu.step_destination_index(insn.a32(), sizeof(T)); + }); +} + 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)); - }); - } + do_movs<u8>(*this, insn); } 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() ? -4 : 4)); - set_si(si() + (df() ? -4 : 4)); - }); - } else { - do_once_or_repeat<false>(insn, [&] { - auto src = read_memory32({ src_segment, esi() }); - write_memory32({ es(), edi() }, src); - set_edi(edi() + (df() ? -4 : 4)); - set_esi(esi() + (df() ? -4 : 4)); - }); - } + do_movs<u32>(*this, insn); } 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() ? -2 : 2)); - set_si(si() + (df() ? -2 : 2)); - }); - } else { - do_once_or_repeat<false>(insn, [&] { - auto src = read_memory16({ src_segment, esi() }); - write_memory16({ es(), edi() }, src); - set_edi(edi() + (df() ? -2 : 2)); - set_esi(esi() + (df() ? -2 : 2)); - }); - } + do_movs<u16>(*this, insn); } void SoftCPU::MOVSX_reg16_RM8(const X86::Instruction& insn) { |