diff --git a/DevTools/UserspaceEmulator/SoftCPU.cpp b/DevTools/UserspaceEmulator/SoftCPU.cpp index 08f4009c5f..92701147dc 100644 --- a/DevTools/UserspaceEmulator/SoftCPU.cpp +++ b/DevTools/UserspaceEmulator/SoftCPU.cpp @@ -1026,12 +1026,12 @@ void SoftCPU::LEAVE32(const X86::Instruction&) void SoftCPU::LEA_reg16_mem16(const X86::Instruction& insn) { - gpr16(insn.reg16()) = insn.modrm().resolve(*this, insn.segment_prefix()).offset(); + gpr16(insn.reg16()) = insn.modrm().resolve(*this, insn).offset(); } void SoftCPU::LEA_reg32_mem32(const X86::Instruction& insn) { - gpr32(insn.reg32()) = insn.modrm().resolve(*this, insn.segment_prefix()).offset(); + gpr32(insn.reg32()) = insn.modrm().resolve(*this, insn).offset(); } void SoftCPU::LES_reg16_mem16(const X86::Instruction&) { TODO(); } diff --git a/Libraries/LibX86/Instruction.cpp b/Libraries/LibX86/Instruction.cpp index 71d06815e6..adfa3b086d 100644 --- a/Libraries/LibX86/Instruction.cpp +++ b/Libraries/LibX86/Instruction.cpp @@ -725,37 +725,37 @@ const char* Instruction::reg32_name() const return register_name(static_cast(register_index())); } -String MemoryOrRegisterReference::to_string_o8() const +String MemoryOrRegisterReference::to_string_o8(const Instruction& insn) const { if (is_register()) return register_name(static_cast(m_register_index)); - return String::format("[%s]", to_string().characters()); + return String::format("[%s]", to_string(insn).characters()); } -String MemoryOrRegisterReference::to_string_o16() const +String MemoryOrRegisterReference::to_string_o16(const Instruction& insn) const { if (is_register()) return register_name(static_cast(m_register_index)); - return String::format("[%s]", to_string().characters()); + return String::format("[%s]", to_string(insn).characters()); } -String MemoryOrRegisterReference::to_string_o32() const +String MemoryOrRegisterReference::to_string_o32(const Instruction& insn) const { if (is_register()) return register_name(static_cast(m_register_index)); - return String::format("[%s]", to_string().characters()); + return String::format("[%s]", to_string(insn).characters()); } -String MemoryOrRegisterReference::to_string_mm() const +String MemoryOrRegisterReference::to_string_mm(const Instruction& insn) const { if (is_register()) return register_name(static_cast(m_register_index)); - return String::format("[%s]", to_string().characters()); + return String::format("[%s]", to_string(insn).characters()); } -String MemoryOrRegisterReference::to_string() const +String MemoryOrRegisterReference::to_string(const Instruction& insn) const { - if (m_a32) + if (insn.a32()) return to_string_a32(); return to_string_a16(); } @@ -1032,9 +1032,9 @@ String Instruction::to_string_internal(u32 origin, const SymbolProvider* symbol_ return builder.to_string(); }; - auto append_rm8 = [&] { builder.append(m_modrm.to_string_o8()); }; - auto append_rm16 = [&] { builder.append(m_modrm.to_string_o16()); }; - auto append_rm32 = [&] { builder.append(m_modrm.to_string_o32()); }; + auto append_rm8 = [&] { builder.append(m_modrm.to_string_o8(*this)); }; + auto append_rm16 = [&] { builder.append(m_modrm.to_string_o16(*this)); }; + auto append_rm32 = [&] { builder.append(m_modrm.to_string_o32(*this)); }; auto append_imm8 = [&] { builder.appendf("%#02x", imm8()); }; auto append_imm8_2 = [&] { builder.appendf("%#02x", imm8_2()); }; auto append_imm16 = [&] { builder.appendf("%#04x", imm16()); }; @@ -1054,7 +1054,7 @@ String Instruction::to_string_internal(u32 origin, const SymbolProvider* symbol_ auto append_relative_imm32 = [&] { builder.append(formatted_address(origin + 5, x32, i32(imm32()))); }; auto append_mm = [&] { builder.appendf("mm%u", register_index()); }; - auto append_mmrm64 = [&] { builder.append(m_modrm.to_string_mm()); }; + auto append_mmrm64 = [&] { builder.append(m_modrm.to_string_mm(*this)); }; auto append = [&](auto& content) { builder.append(content); }; auto append_moff = [&] { diff --git a/Libraries/LibX86/Instruction.h b/Libraries/LibX86/Instruction.h index b5d8f52694..dba1baed22 100644 --- a/Libraries/LibX86/Instruction.h +++ b/Libraries/LibX86/Instruction.h @@ -336,10 +336,10 @@ class MemoryOrRegisterReference { friend class Instruction; public: - String to_string_o8() const; - String to_string_o16() const; - String to_string_o32() const; - String to_string_mm() const; + String to_string_o8(const Instruction&) const; + String to_string_o16(const Instruction&) const; + String to_string_o32(const Instruction&) const; + String to_string_mm(const Instruction&) const; bool is_register() const { return m_register_index != 0xffffffff; } @@ -363,17 +363,12 @@ public: u32 read32(CPU&, const Instruction&); template - ALWAYS_INLINE LogicalAddress resolve(const CPU& cpu, Optional segment_prefix) - { - if (m_a32) - return resolve32(cpu, segment_prefix); - return resolve16(cpu, segment_prefix); - } + LogicalAddress resolve(const CPU&, const Instruction&); private: MemoryOrRegisterReference() { } - String to_string() const; + String to_string(const Instruction&) const; String to_string_a16() const; String to_string_a32() const; @@ -399,8 +394,6 @@ private: u16 m_offset16; }; - u8 m_a32 { false }; - u8 m_rm { 0 }; u8 m_sib { 0 }; u8 m_displacement_bytes { 0 }; @@ -477,6 +470,8 @@ public: u8 cc() const { return m_has_sub_op ? m_sub_op & 0xf : m_op & 0xf; } + bool a32() const { return m_a32; } + String to_string(u32 origin, const SymbolProvider* = nullptr, bool x32 = true) const; private: @@ -517,8 +512,6 @@ private: template ALWAYS_INLINE LogicalAddress MemoryOrRegisterReference::resolve16(const CPU& cpu, Optional segment_prefix) { - ASSERT(!m_a32); - auto default_segment = SegmentRegister::DS; u16 offset = 0; @@ -563,8 +556,6 @@ ALWAYS_INLINE LogicalAddress MemoryOrRegisterReference::resolve16(const CPU& cpu template ALWAYS_INLINE LogicalAddress MemoryOrRegisterReference::resolve32(const CPU& cpu, Optional segment_prefix) { - ASSERT(m_a32); - auto default_segment = SegmentRegister::DS; u32 offset = 0; @@ -702,7 +693,7 @@ ALWAYS_INLINE void MemoryOrRegisterReference::write8(CPU& cpu, const Instruction return; } - auto address = resolve(cpu, insn.segment_prefix()); + auto address = resolve(cpu, insn); cpu.write_memory8(address, value); } @@ -714,7 +705,7 @@ ALWAYS_INLINE void MemoryOrRegisterReference::write16(CPU& cpu, const Instructio return; } - auto address = resolve(cpu, insn.segment_prefix()); + auto address = resolve(cpu, insn); cpu.write_memory16(address, value); } @@ -726,7 +717,7 @@ ALWAYS_INLINE void MemoryOrRegisterReference::write32(CPU& cpu, const Instructio return; } - auto address = resolve(cpu, insn.segment_prefix()); + auto address = resolve(cpu, insn); cpu.write_memory32(address, value); } @@ -736,7 +727,7 @@ ALWAYS_INLINE u8 MemoryOrRegisterReference::read8(CPU& cpu, const Instruction& i if (is_register()) return cpu.gpr8(reg8()); - auto address = resolve(cpu, insn.segment_prefix()); + auto address = resolve(cpu, insn); return cpu.read_memory8(address); } @@ -746,7 +737,7 @@ ALWAYS_INLINE u16 MemoryOrRegisterReference::read16(CPU& cpu, const Instruction& if (is_register()) return cpu.gpr16(reg16()); - auto address = resolve(cpu, insn.segment_prefix()); + auto address = resolve(cpu, insn); return cpu.read_memory16(address); } @@ -756,7 +747,7 @@ ALWAYS_INLINE u32 MemoryOrRegisterReference::read32(CPU& cpu, const Instruction& if (is_register()) return cpu.gpr32(reg32()); - auto address = resolve(cpu, insn.segment_prefix()); + auto address = resolve(cpu, insn); return cpu.read_memory32(address); } @@ -919,10 +910,9 @@ ALWAYS_INLINE Instruction::Instruction(InstructionStreamType& stream, bool o32, template ALWAYS_INLINE void MemoryOrRegisterReference::decode(InstructionStreamType& stream, bool a32) { - m_a32 = a32; m_rm = stream.read8(); - if (m_a32) { + if (a32) { decode32(stream); switch (m_displacement_bytes) { case 0: @@ -958,8 +948,6 @@ ALWAYS_INLINE void MemoryOrRegisterReference::decode(InstructionStreamType& stre template ALWAYS_INLINE void MemoryOrRegisterReference::decode16(InstructionStreamType&) { - ASSERT(!m_a32); - switch (m_rm & 0xc0) { case 0: if ((m_rm & 0x07) == 6) @@ -982,8 +970,6 @@ ALWAYS_INLINE void MemoryOrRegisterReference::decode16(InstructionStreamType&) template ALWAYS_INLINE void MemoryOrRegisterReference::decode32(InstructionStreamType& stream) { - ASSERT(m_a32); - switch (m_rm & 0xc0) { case 0: if ((m_rm & 0x07) == 5) @@ -1025,5 +1011,12 @@ ALWAYS_INLINE void MemoryOrRegisterReference::decode32(InstructionStreamType& st } } +template +ALWAYS_INLINE LogicalAddress MemoryOrRegisterReference::resolve(const CPU& cpu, const Instruction& insn) +{ + if (insn.a32()) + return resolve32(cpu, insn.segment_prefix()); + return resolve16(cpu, insn.segment_prefix()); +} }