Disasm: read instruction contents only once

Memory is volatile and may be changed by guest threads, ensure the decoded instruction matches with the data.
This commit is contained in:
Eladash 2020-12-16 18:50:21 +02:00 committed by Ivan
parent 2c06043617
commit 59ed222205
3 changed files with 13 additions and 12 deletions

View file

@ -17,6 +17,7 @@ class CPUDisAsm
protected: protected:
const CPUDisAsmMode m_mode; const CPUDisAsmMode m_mode;
const std::add_pointer_t<const u8> m_offset; const std::add_pointer_t<const u8> m_offset;
u32 m_op = 0;
virtual void Write(const std::string& value) virtual void Write(const std::string& value)
{ {
@ -25,20 +26,20 @@ protected:
case CPUDisAsm_DumpMode: case CPUDisAsm_DumpMode:
{ {
last_opcode = fmt::format("\t%08x:\t%02x %02x %02x %02x\t%s\n", dump_pc, last_opcode = fmt::format("\t%08x:\t%02x %02x %02x %02x\t%s\n", dump_pc,
m_offset[dump_pc], static_cast<u8>(m_op >> 24),
m_offset[dump_pc + 1], static_cast<u8>(m_op >> 16),
m_offset[dump_pc + 2], static_cast<u8>(m_op >> 8),
m_offset[dump_pc + 3], value); static_cast<u8>(m_op >> 0), value);
break; break;
} }
case CPUDisAsm_InterpreterMode: case CPUDisAsm_InterpreterMode:
{ {
last_opcode = fmt::format("[%08x] %02x %02x %02x %02x: %s", dump_pc, last_opcode = fmt::format("[%08x] %02x %02x %02x %02x: %s", dump_pc,
m_offset[dump_pc], static_cast<u8>(m_op >> 24),
m_offset[dump_pc + 1], static_cast<u8>(m_op >> 16),
m_offset[dump_pc + 2], static_cast<u8>(m_op >> 8),
m_offset[dump_pc + 3], value); static_cast<u8>(m_op >> 0), value);
break; break;
} }

View file

@ -7,8 +7,8 @@ const ppu_decoder<PPUDisAsm> s_ppu_disasm;
u32 PPUDisAsm::disasm(u32 pc) u32 PPUDisAsm::disasm(u32 pc)
{ {
dump_pc = pc; dump_pc = pc;
const u32 op = *reinterpret_cast<const be_t<u32>*>(m_offset + pc); m_op = *reinterpret_cast<const atomic_be_t<u32>*>(m_offset + pc);
(this->*(s_ppu_disasm.decode(op)))({ op }); (this->*(s_ppu_disasm.decode(m_op)))({ m_op });
return 4; return 4;
} }

View file

@ -12,8 +12,8 @@ const spu_decoder<spu_iflag> s_spu_iflag;
u32 SPUDisAsm::disasm(u32 pc) u32 SPUDisAsm::disasm(u32 pc)
{ {
dump_pc = pc; dump_pc = pc;
const u32 op = *reinterpret_cast<const be_t<u32>*>(m_offset + pc); m_op = *reinterpret_cast<const atomic_be_t<u32>*>(m_offset + pc);
(this->*(s_spu_disasm.decode(op)))({ op }); (this->*(s_spu_disasm.decode(m_op)))({ m_op });
return 4; return 4;
} }