diff options
author | Andreas Kling <kling@serenityos.org> | 2020-07-10 17:18:49 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-07-10 20:20:27 +0200 |
commit | 0cf7fd5268582eca705158f71541013ef340738d (patch) | |
tree | 3541d1fd69c521e8912d9d322611c75ebd6173a4 /Libraries/LibX86/Instruction.h | |
parent | 9955819d92438a06465927b3b4eadb8fc1c383e1 (diff) | |
download | serenity-0cf7fd5268582eca705158f71541013ef340738d.zip |
UserspaceEmulator+LibX86: Implement all the forms of XOR
And they're all generic, which will make it easy to support more ops.
Diffstat (limited to 'Libraries/LibX86/Instruction.h')
-rw-r--r-- | Libraries/LibX86/Instruction.h | 64 |
1 files changed, 62 insertions, 2 deletions
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 @@ -205,9 +205,17 @@ public: RegisterIndex8 reg8() const { return static_cast<RegisterIndex8>(register_index()); } template<typename CPU> + void write8(CPU&, const Instruction&, u8); + template<typename CPU> + void write16(CPU&, const Instruction&, u16); + template<typename CPU> void write32(CPU&, const Instruction&, u32); template<typename CPU> + u8 read8(CPU&, const Instruction&); + template<typename CPU> + u16 read16(CPU&, const Instruction&); + template<typename CPU> u32 read32(CPU&, const Instruction&); private: @@ -227,6 +235,14 @@ private: LogicalAddress resolve32(const CPU&, Optional<SegmentRegister>); template<typename CPU> + LogicalAddress resolve(const CPU& cpu, Optional<SegmentRegister> segment_prefix) + { + if (m_a32) + return resolve32(cpu, segment_prefix); + return resolve16(cpu, segment_prefix); + } + + template<typename CPU> u32 evaluate_sib(const CPU&, SegmentRegister& default_segment) const; unsigned m_register_index { 0xffffffff }; @@ -560,6 +576,30 @@ inline u32 MemoryOrRegisterReference::evaluate_sib(const CPU& cpu, SegmentRegist } template<typename CPU> +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<typename CPU> +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<typename CPU> inline void MemoryOrRegisterReference::write32(CPU& cpu, const Instruction& insn, u32 value) { if (is_register()) { @@ -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<typename CPU> +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<typename CPU> +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<typename CPU> 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); } |