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) <noreply@anthropic.com>
This commit is contained in:
Henrik RydgårdandClaude Opus 5.5 committed 2026-10-15 09:55:35 +02:00
1 parent c308ab1b99
commit 73f1b9465a
3 files changed
+15 -5

No files matched your search

+13 -4
View File
@@ -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<const float *>(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;
+1
View File
@@ -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",