From f8b38eabeb9e922309c27bbe9fea230e859a94e5 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Fri, 10 Jul 2020 16:30:37 +0200 Subject: [PATCH] UserspaceEmulator: First cut of generic instruction implementations Let's use C++ templates to implement the generic parts of instructions. There are tons of them with the same set of inputs, just different behavior. Templates are perfect for this. --- DevTools/UserspaceEmulator/SoftCPU.cpp | 98 ++++++++++++++++++++++---- DevTools/UserspaceEmulator/SoftCPU.h | 7 ++ 2 files changed, 92 insertions(+), 13 deletions(-) diff --git a/DevTools/UserspaceEmulator/SoftCPU.cpp b/DevTools/UserspaceEmulator/SoftCPU.cpp index ebf2658676..2fd5d946fa 100644 --- a/DevTools/UserspaceEmulator/SoftCPU.cpp +++ b/DevTools/UserspaceEmulator/SoftCPU.cpp @@ -32,6 +32,34 @@ namespace UserspaceEmulator { +template +struct TypeDoubler { +}; +template<> +struct TypeDoubler { + typedef u16 type; +}; +template<> +struct TypeDoubler { + typedef u32 type; +}; +template<> +struct TypeDoubler { + typedef u64 type; +}; +template<> +struct TypeDoubler { + typedef i16 type; +}; +template<> +struct TypeDoubler { + typedef i32 type; +}; +template<> +struct TypeDoubler { + typedef i64 type; +}; + SoftCPU::SoftCPU(Emulator& emulator) : m_emulator(emulator) { @@ -78,6 +106,45 @@ u32 SoftCPU::pop32() return value; } +template +static typename TypeDoubler::type op_xor(SoftCPU& cpu, Destination& dest, const Source& src) +{ + auto result = dest ^ src; + cpu.set_zf(dest == 0); + cpu.set_sf(dest & 0x80000000); + // FIXME: set_pf + cpu.set_of(false); + cpu.set_cf(false); + return result; +} + +template +void SoftCPU::generic_RM32_reg32(Op op, const X86::Instruction& insn) +{ + auto dest = insn.modrm().read32(*this, insn); + auto src = gpr32(insn.reg32()); + auto result = op(*this, dest, src); + insn.modrm().write32(*this, insn, result); +} + +template +void SoftCPU::generic_RM32_imm32(Op op, const X86::Instruction& insn) +{ + auto dest = insn.modrm().read32(*this, insn); + auto src = insn.imm32(); + auto result = op(*this, dest, src); + insn.modrm().write32(*this, insn, result); +} + +template +void SoftCPU::generic_RM32_imm8(Op op, const X86::Instruction& insn) +{ + auto dest = insn.modrm().read32(*this, insn); + auto src = insn.imm8(); + auto result = op(*this, dest, src); + insn.modrm().write32(*this, insn, result); +} + void SoftCPU::AAA(const X86::Instruction&) { TODO(); } void SoftCPU::AAD(const X86::Instruction&) { TODO(); } void SoftCPU::AAM(const X86::Instruction&) { TODO(); } @@ -548,27 +615,32 @@ void SoftCPU::XCHG_reg16_RM16(const X86::Instruction&) { TODO(); } void SoftCPU::XCHG_reg32_RM32(const X86::Instruction&) { TODO(); } void SoftCPU::XCHG_reg8_RM8(const X86::Instruction&) { TODO(); } void SoftCPU::XLAT(const X86::Instruction&) { TODO(); } -void SoftCPU::XOR_AL_imm8(const X86::Instruction&) { TODO(); } + +void SoftCPU::XOR_AL_imm8(const X86::Instruction&) +{ + + TODO(); +} + void SoftCPU::XOR_AX_imm16(const X86::Instruction&) { TODO(); } void SoftCPU::XOR_EAX_imm32(const X86::Instruction&) { TODO(); } void SoftCPU::XOR_RM16_imm16(const X86::Instruction&) { TODO(); } void SoftCPU::XOR_RM16_imm8(const X86::Instruction&) { TODO(); } void SoftCPU::XOR_RM16_reg16(const X86::Instruction&) { TODO(); } -void SoftCPU::XOR_RM32_imm32(const X86::Instruction&) { TODO(); } -void SoftCPU::XOR_RM32_imm8(const X86::Instruction&) { TODO(); } + +void SoftCPU::XOR_RM32_imm32(const X86::Instruction& insn) +{ + generic_RM32_imm32(op_xor, insn); +} + +void SoftCPU::XOR_RM32_imm8(const X86::Instruction& insn) +{ + generic_RM32_imm8(op_xor, insn); +} void SoftCPU::XOR_RM32_reg32(const X86::Instruction& insn) { - ASSERT(insn.modrm().is_register()); - auto& dest = gpr32(insn.modrm().reg32()); - auto src = gpr32(insn.reg32()); - dest ^= src; - - set_cf(false); - set_of(false); - set_zf(dest == 0); - set_sf(dest & 0x80000000); - // FIXME: set_pf + generic_RM32_reg32(op_xor, insn); } void SoftCPU::XOR_RM8_imm8(const X86::Instruction&) { TODO(); } diff --git a/DevTools/UserspaceEmulator/SoftCPU.h b/DevTools/UserspaceEmulator/SoftCPU.h index 9b05bb52c3..e41e397977 100644 --- a/DevTools/UserspaceEmulator/SoftCPU.h +++ b/DevTools/UserspaceEmulator/SoftCPU.h @@ -591,6 +591,13 @@ private: virtual void wrap_0xD3_16(const X86::Instruction&) override; virtual void wrap_0xD3_32(const X86::Instruction&) override; + template + void generic_RM32_reg32(Op, const X86::Instruction&); + template + void generic_RM32_imm32(Op, const X86::Instruction&); + template + void generic_RM32_imm8(Op, const X86::Instruction&); + private: Emulator& m_emulator;