mirror of
https://github.com/stenzek/duckstation.git
synced 2026-11-12 01:00:48 +01:00
CPU/PGXP: Fix recompiled mtc0 validating its source with a garbage value
The recompiler only passes the source register, so take that alone.
This commit is contained in:
4 files changed
+28
-4
No files matched your search
@@ -205,6 +205,30 @@ TEST_P(CPUExecution, PGXPIgnoresWritesToZero)
|
||||
CPU::CodeCache::Reset();
|
||||
}
|
||||
|
||||
TEST_P(CPUExecution, PGXPMTC0KeepsSourceValid)
|
||||
{
|
||||
// mtc0 validates its source register, which must not lose its flags.
|
||||
g_settings.gpu_pgxp_enable = true;
|
||||
g_settings.gpu_pgxp_cpu = true;
|
||||
CPU::PGXP::Initialize();
|
||||
CPU::CodeCache::Reset();
|
||||
const CPU::PGXPValue zero = CPU::g_state.pgxp_gpr[0];
|
||||
|
||||
Program prog;
|
||||
prog.LoadImmediate(Reg::T0, 0x12345678u);
|
||||
prog.Emit(mtc0(Reg::T0, 3));
|
||||
prog.Emit(mtc0(Reg::R0, 3));
|
||||
prog.Run();
|
||||
|
||||
EXPECT_EQ(CPU::g_state.pgxp_gpr[static_cast<u32>(Reg::T0)].flags & CPU::PGXP::VALID_XY, CPU::PGXP::VALID_XY);
|
||||
EXPECT_EQ(std::memcmp(&CPU::g_state.pgxp_gpr[0], &zero, sizeof(zero)), 0);
|
||||
|
||||
CPU::PGXP::Shutdown();
|
||||
g_settings.gpu_pgxp_enable = false;
|
||||
g_settings.gpu_pgxp_cpu = false;
|
||||
CPU::CodeCache::Reset();
|
||||
}
|
||||
|
||||
TEST_P(CPUExecution, PGXPMemoryModeMovesWithZeroImmediate)
|
||||
{
|
||||
// addiu/ori/xori with a zero immediate are moves, which memory mode PGXP keeps the value through.
|
||||
|
||||
@@ -1987,7 +1987,7 @@ restart_instruction:
|
||||
}
|
||||
|
||||
if constexpr (pgxp_mode == PGXPMode::CPU)
|
||||
PGXP::CPU_MTC0(inst, value, orig_value);
|
||||
PGXP::CPU_MTC0(inst, orig_value);
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
@@ -1923,7 +1923,7 @@ void CPU::PGXP::CPU_MFC0(Instruction instr, u32 rdVal)
|
||||
prtVal.value = rdVal;
|
||||
}
|
||||
|
||||
void CPU::PGXP::CPU_MTC0(Instruction instr, u32 rdVal, u32 rtVal)
|
||||
void CPU::PGXP::CPU_MTC0(Instruction instr, u32 rtVal)
|
||||
{
|
||||
LOG_VALUES_C1(instr.r.rt.GetValue(), rtVal);
|
||||
|
||||
@@ -1931,5 +1931,5 @@ void CPU::PGXP::CPU_MTC0(Instruction instr, u32 rdVal, u32 rtVal)
|
||||
PGXPValue& prtVal = ValidateAndGetRtValue(instr, rtVal);
|
||||
PGXPValue& prdVal = g_state.pgxp_cop0[static_cast<u8>(instr.r.rd.GetValue())];
|
||||
prdVal = prtVal;
|
||||
prdVal.value = rdVal;
|
||||
prdVal.value = rtVal;
|
||||
}
|
||||
+1
-1
@@ -89,7 +89,7 @@ void CPU_SLLV(Instruction instr, u32 rsVal, u32 rtVal);
|
||||
void CPU_SRLV(Instruction instr, u32 rsVal, u32 rtVal);
|
||||
void CPU_SRAV(Instruction instr, u32 rsVal, u32 rtVal);
|
||||
void CPU_MFC0(Instruction instr, u32 rdVal);
|
||||
void CPU_MTC0(Instruction instr, u32 rdVal, u32 rtVal);
|
||||
void CPU_MTC0(Instruction instr, u32 rtVal);
|
||||
|
||||
// Utility functions.
|
||||
|
||||
|
||||
Reference in new issue
Block a user