diff --git a/DevTools/UserspaceEmulator/SoftCPU.cpp b/DevTools/UserspaceEmulator/SoftCPU.cpp index 228808ecf8..9323c96434 100644 --- a/DevTools/UserspaceEmulator/SoftCPU.cpp +++ b/DevTools/UserspaceEmulator/SoftCPU.cpp @@ -34,21 +34,13 @@ namespace UserspaceEmulator { SoftCPU::SoftCPU(Emulator& emulator) : m_emulator(emulator) { - m_reg32_table[X86::RegisterEAX] = &m_eax; - m_reg32_table[X86::RegisterEBX] = &m_ebx; - m_reg32_table[X86::RegisterECX] = &m_ecx; - m_reg32_table[X86::RegisterEDX] = &m_edx; - m_reg32_table[X86::RegisterEBP] = &m_ebp; - m_reg32_table[X86::RegisterESP] = &m_esp; - m_reg32_table[X86::RegisterESI] = &m_esi; - m_reg32_table[X86::RegisterEDI] = &m_edi; } void SoftCPU::dump() const { - printf("eax=%08x ebx=%08x ecx=%08x edx=%08x ", m_eax, m_ebx, m_ecx, m_edx); - printf("ebp=%08x esp=%08x esi=%08x edi=%08x ", m_ebp, m_esp, m_esi, m_edi); - printf("o=%u s=%u z=%u a=%u p=%u c=%u\n", m_of, m_sf, m_zf, m_af, m_pf, m_cf); + printf("eax=%08x ebx=%08x ecx=%08x edx=%08x ", eax(), ebx(), ecx(), edx()); + printf("ebp=%08x esp=%08x esi=%08x edi=%08x ", ebp(), esp(), esi(), edi()); + printf("o=%u s=%u z=%u a=%u p=%u c=%u\n", of(), sf(), zf(), af(), pf(), cf()); } u32 SoftCPU::read_memory32(X86::LogicalAddress address) @@ -68,14 +60,14 @@ void SoftCPU::write_memory32(X86::LogicalAddress address, u32 value) void SoftCPU::push32(u32 value) { - m_esp -= sizeof(value); - write_memory32({ get_ss(), get_esp() }, value); + set_esp(esp() - sizeof(value)); + write_memory32({ ss(), esp() }, value); } u32 SoftCPU::pop32() { - auto value = read_memory32({ get_ss(), get_esp() }); - m_esp += sizeof(value); + auto value = read_memory32({ ss(), esp() }); + set_esp(esp() + sizeof(value)); return value; } @@ -228,7 +220,7 @@ void SoftCPU::INTO(const X86::Instruction&) { TODO(); } void SoftCPU::INT_imm8(const X86::Instruction& insn) { ASSERT(insn.imm8() == 0x82); - m_eax = m_emulator.virt_syscall(m_eax, m_edx, m_ecx, m_ebx); + set_eax(m_emulator.virt_syscall(eax(), edx(), ecx(), ebx())); } void SoftCPU::INVLPG(const X86::Instruction&) { TODO(); } @@ -303,7 +295,7 @@ void SoftCPU::MOV_RM32_imm32(const X86::Instruction&) { TODO(); } void SoftCPU::MOV_RM32_reg32(const X86::Instruction& insn) { ASSERT(insn.modrm().is_register()); - *m_reg32_table[insn.modrm().register_index()] = *m_reg32_table[insn.register_index()]; + gpr32(insn.modrm().reg32()) = gpr32(insn.reg32()); } void SoftCPU::MOV_RM8_imm8(const X86::Instruction&) { TODO(); } @@ -319,7 +311,7 @@ void SoftCPU::MOV_reg32_RM32(const X86::Instruction&) { TODO(); } void SoftCPU::MOV_reg32_imm32(const X86::Instruction& insn) { - *m_reg32_table[insn.register_index()] = insn.imm32(); + gpr32(insn.reg32()) = insn.imm32(); } void SoftCPU::MOV_reg8_RM8(const X86::Instruction&) { TODO(); } @@ -377,7 +369,7 @@ void SoftCPU::POP_reg16(const X86::Instruction&) { TODO(); } void SoftCPU::POP_reg32(const X86::Instruction& insn) { - *m_reg32_table[insn.register_index()] = pop32(); + gpr32(insn.reg32()) = pop32(); } void SoftCPU::PUSHA(const X86::Instruction&) { TODO(); } @@ -400,7 +392,7 @@ void SoftCPU::PUSH_reg16(const X86::Instruction&) { TODO(); } void SoftCPU::PUSH_reg32(const X86::Instruction& insn) { - push32(*m_reg32_table[insn.register_index()]); + push32(gpr32(insn.reg32())); } void SoftCPU::RCL_RM16_1(const X86::Instruction&) { TODO(); } @@ -561,8 +553,8 @@ void SoftCPU::XOR_RM32_imm8(const X86::Instruction&) { TODO(); } void SoftCPU::XOR_RM32_reg32(const X86::Instruction& insn) { ASSERT(insn.modrm().is_register()); - auto& dest = *m_reg32_table[insn.modrm().register_index()]; - auto src = *m_reg32_table[insn.register_index()]; + auto& dest = gpr32(insn.modrm().reg32()); + auto src = gpr32(insn.reg32()); dest ^= src; set_cf(false); diff --git a/DevTools/UserspaceEmulator/SoftCPU.h b/DevTools/UserspaceEmulator/SoftCPU.h index 24ab02c693..fe25b6f6b7 100644 --- a/DevTools/UserspaceEmulator/SoftCPU.h +++ b/DevTools/UserspaceEmulator/SoftCPU.h @@ -33,6 +33,21 @@ namespace UserspaceEmulator { class Emulator; +union PartAddressableRegister { + struct { + u32 full_u32 { 0 }; + }; + struct { + u16 low_u16; + u16 high_u16; + }; + struct { + u8 low_u8; + u8 high_u8; + u16 also_high_u16; + }; +}; + class SoftCPU final : public X86::Interpreter { public: explicit SoftCPU(Emulator&); @@ -41,13 +56,45 @@ public: void push32(u32); u32 pop32(); - u32 get_esp() const { return m_esp; } - void set_esp(u32 value) { m_esp = value; } + u32 gpr32(X86::RegisterIndex32 reg) const { return m_gpr[reg].full_u32; } + u32& gpr32(X86::RegisterIndex32 reg) { return m_gpr[reg].full_u32; } - u16 get_cs() const { return 0x18; } - u16 get_ds() const { return 0x20; } - u16 get_es() const { return 0x20; } - u16 get_ss() const { return 0x20; } + u32 eax() const { return gpr32(X86::RegisterEAX); } + u32 ebx() const { return gpr32(X86::RegisterEBX); } + u32 ecx() const { return gpr32(X86::RegisterECX); } + u32 edx() const { return gpr32(X86::RegisterEDX); } + u32 esp() const { return gpr32(X86::RegisterESP); } + u32 ebp() const { return gpr32(X86::RegisterEBP); } + u32 esi() const { return gpr32(X86::RegisterESI); } + u32 edi() const { return gpr32(X86::RegisterEDI); } + + void set_eax(u32 value) { gpr32(X86::RegisterEAX) = value; } + void set_ebx(u32 value) { gpr32(X86::RegisterEBX) = value; } + void set_ecx(u32 value) { gpr32(X86::RegisterECX) = value; } + void set_edx(u32 value) { gpr32(X86::RegisterEDX) = value; } + void set_ebp(u32 value) { gpr32(X86::RegisterEBP) = value; } + void set_esp(u32 value) { gpr32(X86::RegisterESP) = value; } + void set_esi(u32 value) { gpr32(X86::RegisterESI) = value; } + void set_edi(u32 value) { gpr32(X86::RegisterEDI) = value; } + + bool of() const { return m_of; } + bool sf() const { return m_sf; } + bool zf() const { return m_zf; } + bool af() const { return m_af; } + bool pf() const { return m_pf; } + bool cf() const { return m_cf; } + + void set_of(bool value) { m_of = value; } + void set_sf(bool value) { m_sf = value; } + void set_zf(bool value) { m_zf = value; } + void set_af(bool value) { m_af = value; } + void set_pf(bool value) { m_pf = value; } + void set_cf(bool value) { m_cf = value; } + + u16 cs() const { return 0x18; } + u16 ds() const { return 0x20; } + u16 es() const { return 0x20; } + u16 ss() const { return 0x20; } u32 read_memory32(X86::LogicalAddress); void write_memory32(X86::LogicalAddress, u32); @@ -526,30 +573,7 @@ private: private: Emulator& m_emulator; - bool get_of() const { return m_of; } - bool get_sf() const { return m_sf; } - bool get_zf() const { return m_zf; } - bool get_af() const { return m_af; } - bool get_pf() const { return m_pf; } - bool get_cf() const { return m_cf; } - - void set_of(bool value) { m_of = value; } - void set_sf(bool value) { m_sf = value; } - void set_zf(bool value) { m_zf = value; } - void set_af(bool value) { m_af = value; } - void set_pf(bool value) { m_pf = value; } - void set_cf(bool value) { m_cf = value; } - - u32* m_reg32_table[8]; - - u32 m_eax { 0 }; - u32 m_ebx { 0 }; - u32 m_ecx { 0 }; - u32 m_edx { 0 }; - u32 m_esp { 0 }; - u32 m_ebp { 0 }; - u32 m_esi { 0 }; - u32 m_edi { 0 }; + PartAddressableRegister m_gpr[8]; bool m_of { false }; bool m_sf { false }; diff --git a/Libraries/LibX86/Instruction.h b/Libraries/LibX86/Instruction.h index 676dbb29f9..fa312466e5 100644 --- a/Libraries/LibX86/Instruction.h +++ b/Libraries/LibX86/Instruction.h @@ -124,7 +124,7 @@ enum MMXRegisterIndex { class LogicalAddress { public: - LogicalAddress() {} + LogicalAddress() { } LogicalAddress(u16 selector, u32 offset) : m_selector(selector) , m_offset(offset) @@ -200,6 +200,10 @@ public: bool is_register() const { return m_register_index != 0xffffffff; } unsigned register_index() const { return m_register_index; } + RegisterIndex32 reg32() const { return static_cast(register_index()); } + RegisterIndex16 reg16() const { return static_cast(register_index()); } + RegisterIndex8 reg8() const { return static_cast(register_index()); } + SegmentRegister segment() const { ASSERT(!is_register()); @@ -208,7 +212,7 @@ public: u32 offset(); private: - MemoryOrRegisterReference() {} + MemoryOrRegisterReference() { } String to_string() const; String to_string_a16() const; @@ -245,7 +249,7 @@ typedef void (Interpreter::*InstructionHandler)(const Instruction&); class Instruction { public: static Instruction from_stream(InstructionStream&, bool o32, bool a32); - ~Instruction() {} + ~Instruction() { } MemoryOrRegisterReference& modrm() const { @@ -321,6 +325,10 @@ public: bool has_sub_op() const { return m_has_sub_op; } unsigned register_index() const { return m_register_index; } + RegisterIndex32 reg32() const { return static_cast(register_index()); } + RegisterIndex16 reg16() const { return static_cast(register_index()); } + RegisterIndex8 reg8() const { return static_cast(register_index()); } + SegmentRegister segment_register() const { return static_cast(register_index()); } u8 cc() const { return m_has_sub_op ? m_sub_op & 0xf : m_op & 0xf; }