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.
This commit is contained in:
Andreas Kling 2020-07-10 16:30:37 +02:00
commit f8b38eabeb
Notes: sideshowbarker 2024-07-19 04:59:05 +09:00
2 changed files with 92 additions and 13 deletions

View file

@ -32,6 +32,34 @@
namespace UserspaceEmulator {
template<typename T>
struct TypeDoubler {
};
template<>
struct TypeDoubler<u8> {
typedef u16 type;
};
template<>
struct TypeDoubler<u16> {
typedef u32 type;
};
template<>
struct TypeDoubler<u32> {
typedef u64 type;
};
template<>
struct TypeDoubler<i8> {
typedef i16 type;
};
template<>
struct TypeDoubler<i16> {
typedef i32 type;
};
template<>
struct TypeDoubler<i32> {
typedef i64 type;
};
SoftCPU::SoftCPU(Emulator& emulator)
: m_emulator(emulator)
{
@ -78,6 +106,45 @@ u32 SoftCPU::pop32()
return value;
}
template<typename Destination, typename Source>
static typename TypeDoubler<Destination>::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<typename Op>
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<typename Op>
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<typename Op>
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<u32, u32>, insn);
}
void SoftCPU::XOR_RM32_imm8(const X86::Instruction& insn)
{
generic_RM32_imm8(op_xor<u32, u8>, 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<u32, u32>, insn);
}
void SoftCPU::XOR_RM8_imm8(const X86::Instruction&) { TODO(); }

View file

@ -591,6 +591,13 @@ private:
virtual void wrap_0xD3_16(const X86::Instruction&) override;
virtual void wrap_0xD3_32(const X86::Instruction&) override;
template<typename Op>
void generic_RM32_reg32(Op, const X86::Instruction&);
template<typename Op>
void generic_RM32_imm32(Op, const X86::Instruction&);
template<typename Op>
void generic_RM32_imm8(Op, const X86::Instruction&);
private:
Emulator& m_emulator;