summaryrefslogtreecommitdiff
path: root/DevTools
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2020-07-12 14:42:48 +0200
committerAndreas Kling <kling@serenityos.org>2020-07-12 14:43:30 +0200
commited57efff4ffdd91647d457f191bb830a192184d1 (patch)
tree2160b67d388dd85db988bd384d40dacb960a4df2 /DevTools
parent6ec0a63af136cbbca06441e92257b2d355441096 (diff)
downloadserenity-ed57efff4ffdd91647d457f191bb830a192184d1.zip
UserspaceEmulator: Implement the CMPXCHG instruction
Diffstat (limited to 'DevTools')
-rw-r--r--DevTools/UserspaceEmulator/SoftCPU.cpp40
1 files changed, 37 insertions, 3 deletions
diff --git a/DevTools/UserspaceEmulator/SoftCPU.cpp b/DevTools/UserspaceEmulator/SoftCPU.cpp
index e3b352eba2..fc1c244759 100644
--- a/DevTools/UserspaceEmulator/SoftCPU.cpp
+++ b/DevTools/UserspaceEmulator/SoftCPU.cpp
@@ -735,9 +735,43 @@ void SoftCPU::CMOVcc_reg32_RM32(const X86::Instruction& insn)
void SoftCPU::CMPSB(const X86::Instruction&) { TODO(); }
void SoftCPU::CMPSD(const X86::Instruction&) { TODO(); }
void SoftCPU::CMPSW(const X86::Instruction&) { TODO(); }
-void SoftCPU::CMPXCHG_RM16_reg16(const X86::Instruction&) { TODO(); }
-void SoftCPU::CMPXCHG_RM32_reg32(const X86::Instruction&) { TODO(); }
-void SoftCPU::CMPXCHG_RM8_reg8(const X86::Instruction&) { TODO(); }
+
+void SoftCPU::CMPXCHG_RM16_reg16(const X86::Instruction& insn)
+{
+ auto current = insn.modrm().read16(*this, insn);
+ if (current == eax()) {
+ set_zf(true);
+ insn.modrm().write16(*this, insn, gpr16(insn.reg16()));
+ } else {
+ set_zf(false);
+ set_eax(current);
+ }
+}
+
+void SoftCPU::CMPXCHG_RM32_reg32(const X86::Instruction& insn)
+{
+ auto current = insn.modrm().read32(*this, insn);
+ if (current == eax()) {
+ set_zf(true);
+ insn.modrm().write32(*this, insn, gpr32(insn.reg32()));
+ } else {
+ set_zf(false);
+ set_eax(current);
+ }
+}
+
+void SoftCPU::CMPXCHG_RM8_reg8(const X86::Instruction& insn)
+{
+ auto current = insn.modrm().read8(*this, insn);
+ if (current == eax()) {
+ set_zf(true);
+ insn.modrm().write8(*this, insn, gpr8(insn.reg8()));
+ } else {
+ set_zf(false);
+ set_eax(current);
+ }
+}
+
void SoftCPU::CPUID(const X86::Instruction&) { TODO(); }
void SoftCPU::CWD(const X86::Instruction&) { TODO(); }
void SoftCPU::CWDE(const X86::Instruction&) { TODO(); }