diff --git a/src/core/cpu_recompiler_code_generator.cpp b/src/core/cpu_recompiler_code_generator.cpp index c46b08c30..778f638a2 100644 --- a/src/core/cpu_recompiler_code_generator.cpp +++ b/src/core/cpu_recompiler_code_generator.cpp @@ -1301,6 +1301,7 @@ bool CodeGenerator::Compile_Add(const CodeBlockInstruction& cbi) (cbi.instruction.op == InstructionOp::funct && cbi.instruction.r.funct == InstructionFunct::add)); Value lhs, rhs; + Reg lhs_src; Reg dest; switch (cbi.instruction.op) { @@ -1309,6 +1310,7 @@ bool CodeGenerator::Compile_Add(const CodeBlockInstruction& cbi) { // rt <- rs + sext(imm) dest = cbi.instruction.i.rt; + lhs_src = cbi.instruction.i.rs; lhs = m_register_cache.ReadGuestRegister(cbi.instruction.i.rs); rhs = Value::FromConstantU32(cbi.instruction.i.imm_sext32()); } @@ -1318,6 +1320,7 @@ bool CodeGenerator::Compile_Add(const CodeBlockInstruction& cbi) { Assert(cbi.instruction.r.funct == InstructionFunct::add || cbi.instruction.r.funct == InstructionFunct::addu); dest = cbi.instruction.r.rd; + lhs_src = cbi.instruction.r.rs; lhs = m_register_cache.ReadGuestRegister(cbi.instruction.r.rs); rhs = m_register_cache.ReadGuestRegister(cbi.instruction.r.rt); } @@ -1328,6 +1331,13 @@ bool CodeGenerator::Compile_Add(const CodeBlockInstruction& cbi) return false; } + // detect register moves and handle them for pgxp + if (g_settings.gpu_pgxp_enable && rhs.HasConstantValue(0)) + { + EmitFunctionCall(nullptr, &PGXP::CPU_MOVE, + Value::FromConstantU32((static_cast(dest) << 8) | (static_cast(lhs_src))), lhs); + } + Value result = AddValues(lhs, rhs, check_overflow); if (check_overflow) GenerateExceptionExit(cbi, Exception::Ov, Condition::Overflow); diff --git a/src/core/pgxp.cpp b/src/core/pgxp.cpp index 029f6057e..e332bb428 100644 --- a/src/core/pgxp.cpp +++ b/src/core/pgxp.cpp @@ -870,6 +870,13 @@ void CPU_SW(u32 instr, u32 rtVal, u32 addr) WriteMem(&CPU_reg[rt(instr)], addr); } +void CPU_MOVE(u32 rd_and_rs, u32 rsVal) +{ + const u32 Rs = (rd_and_rs & 0xFFu); + Validate(&CPU_reg[Rs], rsVal); + CPU_reg[(rd_and_rs >> 8)] = CPU_reg[Rs]; +} + void CPU_ADDI(u32 instr, u32 rtVal, u32 rsVal) { // Rt = Rs + Imm (signed) diff --git a/src/core/pgxp.h b/src/core/pgxp.h index e5c664941..5bee366d6 100644 --- a/src/core/pgxp.h +++ b/src/core/pgxp.h @@ -52,6 +52,7 @@ void CPU_LBx(u32 instr, u32 rtVal, u32 addr); void CPU_SB(u32 instr, u8 rtVal, u32 addr); void CPU_SH(u32 instr, u16 rtVal, u32 addr); void CPU_SW(u32 instr, u32 rtVal, u32 addr); +void CPU_MOVE(u32 rd_and_rs, u32 rsVal); // Arithmetic with immediate value void CPU_ADDI(u32 instr, u32 rtVal, u32 rsVal);