CPU/Recompiler: Implement mfhi/mthi/mflo/mtlo
This commit is contained in:
parent
51a873e58d
commit
e5c0d28fdc
|
@ -74,10 +74,6 @@ bool Core::DoState(StateWrapper& sw)
|
||||||
sw.Do(&m_pending_ticks);
|
sw.Do(&m_pending_ticks);
|
||||||
sw.Do(&m_downcount);
|
sw.Do(&m_downcount);
|
||||||
sw.DoArray(m_regs.r, countof(m_regs.r));
|
sw.DoArray(m_regs.r, countof(m_regs.r));
|
||||||
sw.Do(&m_regs.pc);
|
|
||||||
sw.Do(&m_regs.hi);
|
|
||||||
sw.Do(&m_regs.lo);
|
|
||||||
sw.Do(&m_regs.npc);
|
|
||||||
sw.Do(&m_cop0_regs.BPC);
|
sw.Do(&m_cop0_regs.BPC);
|
||||||
sw.Do(&m_cop0_regs.BDA);
|
sw.Do(&m_cop0_regs.BDA);
|
||||||
sw.Do(&m_cop0_regs.TAR);
|
sw.Do(&m_cop0_regs.TAR);
|
||||||
|
|
|
@ -114,6 +114,13 @@ bool CodeGenerator::CompileInstruction(const CodeBlockInstruction& cbi)
|
||||||
result = Compile_ShiftVariable(cbi);
|
result = Compile_ShiftVariable(cbi);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case InstructionFunct::mfhi:
|
||||||
|
case InstructionFunct::mflo:
|
||||||
|
case InstructionFunct::mthi:
|
||||||
|
case InstructionFunct::mtlo:
|
||||||
|
result = Compile_MoveHiLo(cbi);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
result = Compile_Fallback(cbi);
|
result = Compile_Fallback(cbi);
|
||||||
break;
|
break;
|
||||||
|
@ -873,6 +880,37 @@ bool CodeGenerator::Compile_Store(const CodeBlockInstruction& cbi)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CodeGenerator::Compile_MoveHiLo(const CodeBlockInstruction& cbi)
|
||||||
|
{
|
||||||
|
InstructionPrologue(cbi, 1);
|
||||||
|
|
||||||
|
switch (cbi.instruction.r.funct)
|
||||||
|
{
|
||||||
|
case InstructionFunct::mfhi:
|
||||||
|
m_register_cache.WriteGuestRegister(cbi.instruction.r.rd, m_register_cache.ReadGuestRegister(Reg::hi));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case InstructionFunct::mthi:
|
||||||
|
m_register_cache.WriteGuestRegister(Reg::hi, m_register_cache.ReadGuestRegister(cbi.instruction.r.rs));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case InstructionFunct::mflo:
|
||||||
|
m_register_cache.WriteGuestRegister(cbi.instruction.r.rd, m_register_cache.ReadGuestRegister(Reg::lo));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case InstructionFunct::mtlo:
|
||||||
|
m_register_cache.WriteGuestRegister(Reg::lo, m_register_cache.ReadGuestRegister(cbi.instruction.r.rs));
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
UnreachableCode();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
InstructionEpilogue(cbi);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool CodeGenerator::Compile_lui(const CodeBlockInstruction& cbi)
|
bool CodeGenerator::Compile_lui(const CodeBlockInstruction& cbi)
|
||||||
{
|
{
|
||||||
InstructionPrologue(cbi, 1);
|
InstructionPrologue(cbi, 1);
|
||||||
|
@ -897,4 +935,5 @@ bool CodeGenerator::Compile_addiu(const CodeBlockInstruction& cbi)
|
||||||
InstructionEpilogue(cbi);
|
InstructionEpilogue(cbi);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace CPU::Recompiler
|
} // namespace CPU::Recompiler
|
||||||
|
|
|
@ -169,6 +169,7 @@ private:
|
||||||
bool Compile_ShiftVariable(const CodeBlockInstruction& cbi);
|
bool Compile_ShiftVariable(const CodeBlockInstruction& cbi);
|
||||||
bool Compile_Load(const CodeBlockInstruction& cbi);
|
bool Compile_Load(const CodeBlockInstruction& cbi);
|
||||||
bool Compile_Store(const CodeBlockInstruction& cbi);
|
bool Compile_Store(const CodeBlockInstruction& cbi);
|
||||||
|
bool Compile_MoveHiLo(const CodeBlockInstruction& cbi);
|
||||||
bool Compile_lui(const CodeBlockInstruction& cbi);
|
bool Compile_lui(const CodeBlockInstruction& cbi);
|
||||||
bool Compile_addiu(const CodeBlockInstruction& cbi);
|
bool Compile_addiu(const CodeBlockInstruction& cbi);
|
||||||
|
|
||||||
|
|
|
@ -3,9 +3,9 @@
|
||||||
#include <array>
|
#include <array>
|
||||||
|
|
||||||
namespace CPU {
|
namespace CPU {
|
||||||
static const std::array<const char*, 32> s_reg_names = {
|
static const std::array<const char*, 36> s_reg_names = {
|
||||||
{"$zero", "at", "v0", "v1", "a0", "a1", "a2", "a3", "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
|
{"$zero", "at", "v0", "v1", "a0", "a1", "a2", "a3", "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", "s0", "s1",
|
||||||
"s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", "t8", "t9", "k0", "k1", "gp", "sp", "fp", "ra"}};
|
"s2", "s3", "s4", "s5", "s6", "s7", "t8", "t9", "k0", "k1", "gp", "sp", "fp", "ra", "hi", "lo", "pc", "npc"}};
|
||||||
|
|
||||||
const char* GetRegName(Reg reg)
|
const char* GetRegName(Reg reg)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue