From 73f1b9465ab31a5cc0e5030fcb40792f4df255ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 15 Oct 2026 01:55:40 +0200 Subject: [PATCH] Interpreter: Vector loads ignore the D prefix's write mask As on hardware (cpu/vfpu/prefix_load), lv.q, lvl.q and lvr.q write every lane whatever mask a pending D prefix has, and leave the prefix pending, like lv.s and mtv already did. The IR cores fall back to the interpreter for lvl.q and lvr.q, so they get this too. Co-Authored-By: Claude Opus 5.5 (1M context) --- Core/MIPS/InterpreterVFPU.cpp | 17 +++++++++++++---- pspautotests | 2 +- test.py | 1 + 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/Core/MIPS/InterpreterVFPU.cpp b/Core/MIPS/InterpreterVFPU.cpp index 838025d1be..716d7838f6 100644 --- a/Core/MIPS/InterpreterVFPU.cpp +++ b/Core/MIPS/InterpreterVFPU.cpp @@ -236,6 +236,15 @@ namespace MIPSInt PC += 4; } + // The loads write every lane, whatever mask a pending D prefix has, and leave the prefix pending + // (cpu/vfpu/prefix_load). + static void WriteLoadedVector(MIPSState *mips, const float *d, int vt) { + const u32 dprefix = mips->vfpuCtrl[VFPU_CTRL_DPREFIX]; + mips->vfpuCtrl[VFPU_CTRL_DPREFIX] = dprefix & ~0xF00; + WriteVector(mips, d, V_Quad, vt); + mips->vfpuCtrl[VFPU_CTRL_DPREFIX] = dprefix; + } + void Int_SVQ(MIPSState *mips, MIPSOpcode op) { int imm = SignExtend16ToS32(op & 0xFFFC); int rs = _RS; @@ -269,7 +278,7 @@ namespace MIPSInt d[i] = valid ? Memory::ReadUnchecked_Float(addr + 4 * i) : 0.0f; } } - WriteVector(mips, d, V_Quad, vt); + WriteLoadedVector(mips, d, vt); } break; @@ -279,13 +288,13 @@ namespace MIPSInt if ((addr & 0xF) || !Memory::IsValid4AlignedAddress(addr)) { Core_MemoryException(addr, 16, PC, MemoryExceptionType::READ_WORD, "lv.q"); const float zero[4]{}; - WriteVector(mips, zero, V_Quad, vt); + WriteLoadedVector(mips, zero, vt); break; } #ifndef COMMON_BIG_ENDIAN cf = reinterpret_cast(Memory::GetPointerUnchecked(addr)); - WriteVector(mips, cf, V_Quad, vt); + WriteLoadedVector(mips, cf, vt); #else float lvqd[4]; @@ -294,7 +303,7 @@ namespace MIPSInt lvqd[2] = Memory::ReadUnchecked_Float(addr + 8); lvqd[3] = Memory::ReadUnchecked_Float(addr + 12); - WriteVector(mips, lvqd, V_Quad, vt); + WriteLoadedVector(mips, lvqd, vt); #endif break; diff --git a/pspautotests b/pspautotests index 011a777e66..3e011268b6 160000 --- a/pspautotests +++ b/pspautotests @@ -1 +1 @@ -Subproject commit 011a777e6623632ce7dca581782fb0f78cca94f8 +Subproject commit 3e011268b66418d9febf989a6e8467ba3d0042df diff --git a/test.py b/test.py index cbf913ff8d..2affad5e24 100755 --- a/test.py +++ b/test.py @@ -101,6 +101,7 @@ tests_good = [ "cpu/vfpu/prefix_branch", "cpu/vfpu/prefix_ctrl", "cpu/vfpu/prefix_lanes", + "cpu/vfpu/prefix_load", "cpu/vfpu/vbranch", "cpu/vfpu/vrnd", "cpu/vfpu/overlap",