CPU/Recompiler: Detect move instructions and forward to PGXP

Fixes holes in polygons in Gran Turismo 1 + 2 with PGXP enabled.
This commit is contained in:
Connor McLaughlin 2020-10-04 22:13:33 +10:00
parent 0b858658ca
commit 8a91395566
3 changed files with 18 additions and 0 deletions

View file

@ -1301,6 +1301,7 @@ bool CodeGenerator::Compile_Add(const CodeBlockInstruction& cbi)
(cbi.instruction.op == InstructionOp::funct && cbi.instruction.r.funct == InstructionFunct::add)); (cbi.instruction.op == InstructionOp::funct && cbi.instruction.r.funct == InstructionFunct::add));
Value lhs, rhs; Value lhs, rhs;
Reg lhs_src;
Reg dest; Reg dest;
switch (cbi.instruction.op) switch (cbi.instruction.op)
{ {
@ -1309,6 +1310,7 @@ bool CodeGenerator::Compile_Add(const CodeBlockInstruction& cbi)
{ {
// rt <- rs + sext(imm) // rt <- rs + sext(imm)
dest = cbi.instruction.i.rt; dest = cbi.instruction.i.rt;
lhs_src = cbi.instruction.i.rs;
lhs = m_register_cache.ReadGuestRegister(cbi.instruction.i.rs); lhs = m_register_cache.ReadGuestRegister(cbi.instruction.i.rs);
rhs = Value::FromConstantU32(cbi.instruction.i.imm_sext32()); 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); Assert(cbi.instruction.r.funct == InstructionFunct::add || cbi.instruction.r.funct == InstructionFunct::addu);
dest = cbi.instruction.r.rd; dest = cbi.instruction.r.rd;
lhs_src = cbi.instruction.r.rs;
lhs = m_register_cache.ReadGuestRegister(cbi.instruction.r.rs); lhs = m_register_cache.ReadGuestRegister(cbi.instruction.r.rs);
rhs = m_register_cache.ReadGuestRegister(cbi.instruction.r.rt); rhs = m_register_cache.ReadGuestRegister(cbi.instruction.r.rt);
} }
@ -1328,6 +1331,13 @@ bool CodeGenerator::Compile_Add(const CodeBlockInstruction& cbi)
return false; 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<u32>(dest) << 8) | (static_cast<u32>(lhs_src))), lhs);
}
Value result = AddValues(lhs, rhs, check_overflow); Value result = AddValues(lhs, rhs, check_overflow);
if (check_overflow) if (check_overflow)
GenerateExceptionExit(cbi, Exception::Ov, Condition::Overflow); GenerateExceptionExit(cbi, Exception::Ov, Condition::Overflow);

View file

@ -870,6 +870,13 @@ void CPU_SW(u32 instr, u32 rtVal, u32 addr)
WriteMem(&CPU_reg[rt(instr)], 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) void CPU_ADDI(u32 instr, u32 rtVal, u32 rsVal)
{ {
// Rt = Rs + Imm (signed) // Rt = Rs + Imm (signed)

View file

@ -52,6 +52,7 @@ void CPU_LBx(u32 instr, u32 rtVal, u32 addr);
void CPU_SB(u32 instr, u8 rtVal, u32 addr); void CPU_SB(u32 instr, u8 rtVal, u32 addr);
void CPU_SH(u32 instr, u16 rtVal, u32 addr); void CPU_SH(u32 instr, u16 rtVal, u32 addr);
void CPU_SW(u32 instr, u32 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 // Arithmetic with immediate value
void CPU_ADDI(u32 instr, u32 rtVal, u32 rsVal); void CPU_ADDI(u32 instr, u32 rtVal, u32 rsVal);