Browse Source

UserspaceEmulator+LibX86: Implement all the forms of XOR

And they're all generic, which will make it easy to support more ops.
Andreas Kling 5 years ago
parent
commit
0cf7fd5268

+ 120 - 36
DevTools/UserspaceEmulator/SoftCPU.cpp

@@ -149,12 +149,57 @@ static typename TypeDoubler<Destination>::type op_xor(SoftCPU& cpu, Destination&
 }
 }
 
 
 template<typename Op>
 template<typename Op>
-void SoftCPU::generic_RM32_reg32(Op op, const X86::Instruction& insn)
+void SoftCPU::generic_AL_imm8(Op op, const X86::Instruction& insn)
 {
 {
-    auto dest = insn.modrm().read32(*this, insn);
-    auto src = gpr32(insn.reg32());
+    auto dest = al();
+    auto src = insn.imm8();
     auto result = op(*this, dest, src);
     auto result = op(*this, dest, src);
-    insn.modrm().write32(*this, insn, result);
+    set_al(result);
+}
+
+template<typename Op>
+void SoftCPU::generic_AX_imm16(Op op, const X86::Instruction& insn)
+{
+    auto dest = ax();
+    auto src = insn.imm16();
+    auto result = op(*this, dest, src);
+    set_ax(result);
+}
+
+template<typename Op>
+void SoftCPU::generic_EAX_imm32(Op op, const X86::Instruction& insn)
+{
+    auto dest = eax();
+    auto src = insn.imm32();
+    auto result = op(*this, dest, src);
+    set_eax(result);
+}
+
+template<typename Op>
+void SoftCPU::generic_RM16_imm16(Op op, const X86::Instruction& insn)
+{
+    auto dest = insn.modrm().read16(*this, insn);
+    auto src = insn.imm16();
+    auto result = op(*this, dest, src);
+    insn.modrm().write16(*this, insn, result);
+}
+
+template<typename Op>
+void SoftCPU::generic_RM16_imm8(Op op, const X86::Instruction& insn)
+{
+    auto dest = insn.modrm().read16(*this, insn);
+    auto src = insn.imm8();
+    auto result = op(*this, dest, src);
+    insn.modrm().write16(*this, insn, result);
+}
+
+template<typename Op>
+void SoftCPU::generic_RM16_reg16(Op op, const X86::Instruction& insn)
+{
+    auto dest = insn.modrm().read16(*this, insn);
+    auto src = gpr16(insn.reg16());
+    auto result = op(*this, dest, src);
+    insn.modrm().write16(*this, insn, result);
 }
 }
 
 
 template<typename Op>
 template<typename Op>
@@ -175,6 +220,60 @@ void SoftCPU::generic_RM32_imm8(Op op, const X86::Instruction& insn)
     insn.modrm().write32(*this, insn, result);
     insn.modrm().write32(*this, insn, 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_RM8_imm8(Op op, const X86::Instruction& insn)
+{
+    auto dest = insn.modrm().read8(*this, insn);
+    auto src = insn.imm8();
+    auto result = op(*this, dest, src);
+    insn.modrm().write8(*this, insn, result);
+}
+
+template<typename Op>
+void SoftCPU::generic_RM8_reg8(Op op, const X86::Instruction& insn)
+{
+    auto dest = insn.modrm().read8(*this, insn);
+    auto src = gpr8(insn.reg8());
+    auto result = op(*this, dest, src);
+    insn.modrm().write8(*this, insn, result);
+}
+
+template<typename Op>
+void SoftCPU::generic_reg16_RM16(Op op, const X86::Instruction& insn)
+{
+    auto dest = gpr16(insn.reg16());
+    auto src = insn.modrm().read16(*this, insn);
+    auto result = op(*this, dest, src);
+    gpr16(insn.reg16()) = result;
+}
+
+template<typename Op>
+void SoftCPU::generic_reg32_RM32(Op op, const X86::Instruction& insn)
+{
+    auto dest = gpr32(insn.reg32());
+    auto src = insn.modrm().read32(*this, insn);
+    auto result = op(*this, dest, src);
+    gpr32(insn.reg32()) = result;
+}
+
+template<typename Op>
+void SoftCPU::generic_reg8_RM8(Op op, const X86::Instruction& insn)
+{
+    auto dest = gpr8(insn.reg8());
+    auto src = insn.modrm().read8(*this, insn);
+    auto result = op(*this, dest, src);
+    gpr8(insn.reg8()) = result;
+}
+
 void SoftCPU::AAA(const X86::Instruction&) { TODO(); }
 void SoftCPU::AAA(const X86::Instruction&) { TODO(); }
 void SoftCPU::AAD(const X86::Instruction&) { TODO(); }
 void SoftCPU::AAD(const X86::Instruction&) { TODO(); }
 void SoftCPU::AAM(const X86::Instruction&) { TODO(); }
 void SoftCPU::AAM(const X86::Instruction&) { TODO(); }
@@ -646,38 +745,24 @@ void SoftCPU::XCHG_reg32_RM32(const X86::Instruction&) { TODO(); }
 void SoftCPU::XCHG_reg8_RM8(const X86::Instruction&) { TODO(); }
 void SoftCPU::XCHG_reg8_RM8(const X86::Instruction&) { TODO(); }
 void SoftCPU::XLAT(const X86::Instruction&) { TODO(); }
 void SoftCPU::XLAT(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(); }
+#define DEFINE_GENERIC_INSN_HANDLERS(mnemonic, op)                                                                \
+    void SoftCPU::mnemonic##_AL_imm8(const X86::Instruction& insn) { generic_AL_imm8(op<u8, u8>, insn); }         \
+    void SoftCPU::mnemonic##_AX_imm16(const X86::Instruction& insn) { generic_AX_imm16(op<u16, u16>, insn); }     \
+    void SoftCPU::mnemonic##_EAX_imm32(const X86::Instruction& insn) { generic_EAX_imm32(op<u32, u32>, insn); }   \
+    void SoftCPU::mnemonic##_RM16_imm16(const X86::Instruction& insn) { generic_RM16_imm16(op<u16, u16>, insn); } \
+    void SoftCPU::mnemonic##_RM16_imm8(const X86::Instruction& insn) { generic_RM16_imm8(op<u16, u8>, insn); }    \
+    void SoftCPU::mnemonic##_RM16_reg16(const X86::Instruction& insn) { generic_RM16_reg16(op<u16, u16>, insn); } \
+    void SoftCPU::mnemonic##_RM32_imm32(const X86::Instruction& insn) { generic_RM32_imm32(op<u32, u32>, insn); } \
+    void SoftCPU::mnemonic##_RM32_imm8(const X86::Instruction& insn) { generic_RM32_imm8(op<u32, u8>, insn); }    \
+    void SoftCPU::mnemonic##_RM32_reg32(const X86::Instruction& insn) { generic_RM32_reg32(op<u32, u32>, insn); } \
+    void SoftCPU::mnemonic##_RM8_imm8(const X86::Instruction& insn) { generic_RM8_imm8(op<u8, u8>, insn); }       \
+    void SoftCPU::mnemonic##_RM8_reg8(const X86::Instruction& insn) { generic_RM8_reg8(op<u8, u8>, insn); }       \
+    void SoftCPU::mnemonic##_reg16_RM16(const X86::Instruction& insn) { generic_reg16_RM16(op<u16, u16>, insn); } \
+    void SoftCPU::mnemonic##_reg32_RM32(const X86::Instruction& insn) { generic_reg32_RM32(op<u32, u32>, insn); } \
+    void SoftCPU::mnemonic##_reg8_RM8(const X86::Instruction& insn) { generic_reg8_RM8(op<u8, u8>, insn); }
+
+DEFINE_GENERIC_INSN_HANDLERS(XOR, op_xor)
 
 
-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)
-{
-    generic_RM32_reg32(op_xor<u32, u32>, insn);
-}
-
-void SoftCPU::XOR_RM8_imm8(const X86::Instruction&) { TODO(); }
-void SoftCPU::XOR_RM8_reg8(const X86::Instruction&) { TODO(); }
-void SoftCPU::XOR_reg16_RM16(const X86::Instruction&) { TODO(); }
-void SoftCPU::XOR_reg32_RM32(const X86::Instruction&) { TODO(); }
-void SoftCPU::XOR_reg8_RM8(const X86::Instruction&) { TODO(); }
 void SoftCPU::MOVQ_mm1_mm2m64(const X86::Instruction&) { TODO(); }
 void SoftCPU::MOVQ_mm1_mm2m64(const X86::Instruction&) { TODO(); }
 void SoftCPU::EMMS(const X86::Instruction&) { TODO(); }
 void SoftCPU::EMMS(const X86::Instruction&) { TODO(); }
 void SoftCPU::MOVQ_mm1_m64_mm2(const X86::Instruction&) { TODO(); }
 void SoftCPU::MOVQ_mm1_m64_mm2(const X86::Instruction&) { TODO(); }
@@ -690,5 +775,4 @@ void SoftCPU::wrap_0xD1_32(const X86::Instruction&) { TODO(); }
 void SoftCPU::wrap_0xD2(const X86::Instruction&) { TODO(); }
 void SoftCPU::wrap_0xD2(const X86::Instruction&) { TODO(); }
 void SoftCPU::wrap_0xD3_16(const X86::Instruction&) { TODO(); }
 void SoftCPU::wrap_0xD3_16(const X86::Instruction&) { TODO(); }
 void SoftCPU::wrap_0xD3_32(const X86::Instruction&) { TODO(); }
 void SoftCPU::wrap_0xD3_32(const X86::Instruction&) { TODO(); }
-
 }
 }

+ 23 - 1
DevTools/UserspaceEmulator/SoftCPU.h

@@ -664,11 +664,33 @@ private:
     virtual void wrap_0xD3_32(const X86::Instruction&) override;
     virtual void wrap_0xD3_32(const X86::Instruction&) override;
 
 
     template<typename Op>
     template<typename Op>
-    void generic_RM32_reg32(Op, const X86::Instruction&);
+    void generic_AL_imm8(Op, const X86::Instruction&);
+    template<typename Op>
+    void generic_AX_imm16(Op, const X86::Instruction&);
+    template<typename Op>
+    void generic_EAX_imm32(Op, const X86::Instruction&);
+    template<typename Op>
+    void generic_RM16_imm16(Op, const X86::Instruction&);
+    template<typename Op>
+    void generic_RM16_imm8(Op, const X86::Instruction&);
+    template<typename Op>
+    void generic_RM16_reg16(Op, const X86::Instruction&);
     template<typename Op>
     template<typename Op>
     void generic_RM32_imm32(Op, const X86::Instruction&);
     void generic_RM32_imm32(Op, const X86::Instruction&);
     template<typename Op>
     template<typename Op>
     void generic_RM32_imm8(Op, const X86::Instruction&);
     void generic_RM32_imm8(Op, const X86::Instruction&);
+    template<typename Op>
+    void generic_RM32_reg32(Op, const X86::Instruction&);
+    template<typename Op>
+    void generic_RM8_imm8(Op, const X86::Instruction&);
+    template<typename Op>
+    void generic_RM8_reg8(Op, const X86::Instruction&);
+    template<typename Op>
+    void generic_reg16_RM16(Op, const X86::Instruction&);
+    template<typename Op>
+    void generic_reg32_RM32(Op, const X86::Instruction&);
+    template<typename Op>
+    void generic_reg8_RM8(Op, const X86::Instruction&);
 
 
 private:
 private:
     Emulator& m_emulator;
     Emulator& m_emulator;

+ 62 - 2
Libraries/LibX86/Instruction.h

@@ -204,9 +204,17 @@ public:
     RegisterIndex16 reg16() const { return static_cast<RegisterIndex16>(register_index()); }
     RegisterIndex16 reg16() const { return static_cast<RegisterIndex16>(register_index()); }
     RegisterIndex8 reg8() const { return static_cast<RegisterIndex8>(register_index()); }
     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>
     template<typename CPU>
     void write32(CPU&, const Instruction&, u32);
     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>
     template<typename CPU>
     u32 read32(CPU&, const Instruction&);
     u32 read32(CPU&, const Instruction&);
 
 
@@ -226,6 +234,14 @@ private:
     template<typename CPU>
     template<typename CPU>
     LogicalAddress resolve32(const CPU&, Optional<SegmentRegister>);
     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>
     template<typename CPU>
     u32 evaluate_sib(const CPU&, SegmentRegister& default_segment) const;
     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;
     return (scale * index) + base;
 }
 }
 
 
+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>
 template<typename CPU>
 inline void MemoryOrRegisterReference::write32(CPU& cpu, const Instruction& insn, u32 value)
 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;
         return;
     }
     }
 
 
-    auto address = resolve32(cpu, insn.segment_prefix());
+    auto address = resolve(cpu, insn.segment_prefix());
     cpu.write_memory32(address, value);
     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>
 template<typename CPU>
 inline u32 MemoryOrRegisterReference::read32(CPU& cpu, const Instruction& insn)
 inline u32 MemoryOrRegisterReference::read32(CPU& cpu, const Instruction& insn)
 {
 {
     if (is_register())
     if (is_register())
         return cpu.gpr32(reg32());
         return cpu.gpr32(reg32());
 
 
-    auto address = resolve32(cpu, insn.segment_prefix());
+    auto address = resolve(cpu, insn.segment_prefix());
     return cpu.read_memory32(address);
     return cpu.read_memory32(address);
 }
 }