From 0cf7fd5268582eca705158f71541013ef340738d Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Fri, 10 Jul 2020 17:18:49 +0200 Subject: UserspaceEmulator+LibX86: Implement all the forms of XOR And they're all generic, which will make it easy to support more ops. --- Libraries/LibX86/Instruction.h | 64 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 62 insertions(+), 2 deletions(-) (limited to 'Libraries') diff --git a/Libraries/LibX86/Instruction.h b/Libraries/LibX86/Instruction.h index ea928ee3eb..17208a829b 100644 --- a/Libraries/LibX86/Instruction.h +++ b/Libraries/LibX86/Instruction.h @@ -204,9 +204,17 @@ public: RegisterIndex16 reg16() const { return static_cast(register_index()); } RegisterIndex8 reg8() const { return static_cast(register_index()); } + template + void write8(CPU&, const Instruction&, u8); + template + void write16(CPU&, const Instruction&, u16); template void write32(CPU&, const Instruction&, u32); + template + u8 read8(CPU&, const Instruction&); + template + u16 read16(CPU&, const Instruction&); template u32 read32(CPU&, const Instruction&); @@ -226,6 +234,14 @@ private: template LogicalAddress resolve32(const CPU&, Optional); + template + LogicalAddress resolve(const CPU& cpu, Optional segment_prefix) + { + if (m_a32) + return resolve32(cpu, segment_prefix); + return resolve16(cpu, segment_prefix); + } + template u32 evaluate_sib(const CPU&, SegmentRegister& default_segment) const; @@ -559,6 +575,30 @@ inline u32 MemoryOrRegisterReference::evaluate_sib(const CPU& cpu, SegmentRegist return (scale * index) + base; } +template +inline void MemoryOrRegisterReference::write8(CPU& cpu, const Instruction& insn, u8 value) +{ + if (is_register()) { + cpu.gpr8(reg8()) = value; + return; + } + + auto address = resolve(cpu, insn.segment_prefix()); + cpu.write_memory8(address, value); +} + +template +inline void MemoryOrRegisterReference::write16(CPU& cpu, const Instruction& insn, u16 value) +{ + if (is_register()) { + cpu.gpr16(reg16()) = value; + return; + } + + auto address = resolve(cpu, insn.segment_prefix()); + cpu.write_memory16(address, value); +} + template inline void MemoryOrRegisterReference::write32(CPU& cpu, const Instruction& insn, u32 value) { @@ -567,17 +607,37 @@ inline void MemoryOrRegisterReference::write32(CPU& cpu, const Instruction& insn return; } - auto address = resolve32(cpu, insn.segment_prefix()); + auto address = resolve(cpu, insn.segment_prefix()); cpu.write_memory32(address, value); } +template +inline u8 MemoryOrRegisterReference::read8(CPU& cpu, const Instruction& insn) +{ + if (is_register()) + return cpu.gpr8(reg8()); + + auto address = resolve(cpu, insn.segment_prefix()); + return cpu.read_memory8(address); +} + +template +inline u16 MemoryOrRegisterReference::read16(CPU& cpu, const Instruction& insn) +{ + if (is_register()) + return cpu.gpr16(reg16()); + + auto address = resolve(cpu, insn.segment_prefix()); + return cpu.read_memory16(address); +} + template inline u32 MemoryOrRegisterReference::read32(CPU& cpu, const Instruction& insn) { if (is_register()) return cpu.gpr32(reg32()); - auto address = resolve32(cpu, insn.segment_prefix()); + auto address = resolve(cpu, insn.segment_prefix()); return cpu.read_memory32(address); } -- cgit v1.2.3