mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 11:28:12 +00:00
UserspaceEmulator: Add helpers for making loop instructions generic
Use them to implement CMPSB/CMPSW/CMPSD.
This commit is contained in:
parent
28b6ba56aa
commit
485d1faf09
2 changed files with 138 additions and 22 deletions
|
@ -195,23 +195,9 @@ void SoftCPU::do_once_or_repeat(const X86::Instruction& insn, Callback callback)
|
|||
if (!insn.has_rep_prefix())
|
||||
return callback();
|
||||
|
||||
if (insn.has_address_size_override_prefix()) {
|
||||
while (cx()) {
|
||||
callback();
|
||||
set_cx(cx() - 1);
|
||||
if constexpr (check_zf) {
|
||||
if (insn.rep_prefix() == X86::Prefix::REPZ && !zf())
|
||||
break;
|
||||
if (insn.rep_prefix() == X86::Prefix::REPNZ && zf())
|
||||
break;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
while (ecx()) {
|
||||
while (loop_index(insn.a32())) {
|
||||
callback();
|
||||
set_ecx(ecx() - 1);
|
||||
decrement_loop_index(insn.a32());
|
||||
if constexpr (check_zf) {
|
||||
if (insn.rep_prefix() == X86::Prefix::REPZ && !zf())
|
||||
break;
|
||||
|
@ -1057,9 +1043,33 @@ void SoftCPU::CMOVcc_reg32_RM32(const X86::Instruction& insn)
|
|||
gpr32(insn.reg32()) = insn.modrm().read32(*this, insn);
|
||||
}
|
||||
|
||||
void SoftCPU::CMPSB(const X86::Instruction&) { TODO(); }
|
||||
void SoftCPU::CMPSD(const X86::Instruction&) { TODO(); }
|
||||
void SoftCPU::CMPSW(const X86::Instruction&) { TODO(); }
|
||||
template<typename T>
|
||||
ALWAYS_INLINE static void do_cmps(SoftCPU& cpu, const X86::Instruction& insn)
|
||||
{
|
||||
auto src_segment = cpu.segment(insn.segment_prefix().value_or(X86::SegmentRegister::DS));
|
||||
cpu.do_once_or_repeat<true>(insn, [&] {
|
||||
auto src = cpu.read_memory<T>({ src_segment, cpu.source_index(insn.a32()) });
|
||||
auto dest = cpu.read_memory<T>({ cpu.es(), cpu.destination_index(insn.a32()) });
|
||||
op_sub(cpu, dest, src);
|
||||
cpu.step_source_index(insn.a32(), sizeof(T));
|
||||
cpu.step_destination_index(insn.a32(), sizeof(T));
|
||||
});
|
||||
}
|
||||
|
||||
void SoftCPU::CMPSB(const X86::Instruction& insn)
|
||||
{
|
||||
do_cmps<u8>(*this, insn);
|
||||
}
|
||||
|
||||
void SoftCPU::CMPSD(const X86::Instruction& insn)
|
||||
{
|
||||
do_cmps<u32>(*this, insn);
|
||||
}
|
||||
|
||||
void SoftCPU::CMPSW(const X86::Instruction& insn)
|
||||
{
|
||||
do_cmps<u16>(*this, insn);
|
||||
}
|
||||
|
||||
void SoftCPU::CMPXCHG_RM16_reg16(const X86::Instruction& insn)
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue