From a6193abcd71eeacf033562436339522c97f2f0ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 14 Oct 2026 20:49:31 +0200 Subject: [PATCH] IR: Fix vmmov between transposed matrices whose rows wrap around For a matrix like E020, the register layout checks pass, but transposing the register names and taking their columns gives unaligned Vec4s. The IR interpreter crashed on x86 on the aligned store (vmscl.p M000, M702, S301 then vmmov.q E020, E100). Take the Vec4s from the checked layout instead. Co-Authored-By: Claude Opus 5.5 (1M context) --- Core/MIPS/IR/IRCompVFPU.cpp | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/Core/MIPS/IR/IRCompVFPU.cpp b/Core/MIPS/IR/IRCompVFPU.cpp index 25e59e933c..a34cc8a3f1 100644 --- a/Core/MIPS/IR/IRCompVFPU.cpp +++ b/Core/MIPS/IR/IRCompVFPU.cpp @@ -1827,20 +1827,11 @@ namespace MIPSComp { const bool bothVec4 = IsMatrixVec4(sz, sregs) && IsMatrixVec4(sz, dregs); const bool bothTransposedVec4 = IsMatrixTransposedVec4(sz, sregs) && IsMatrixTransposedVec4(sz, dregs); if (bothVec4 || bothTransposedVec4) { - // Untranspose both matrices - if (IsMatrixTransposed(vd)) { - vd = TransposeMatrixReg(vd); - vs = TransposeMatrixReg(vs); - } - // Get the columns - u8 scols[4], dcols[4]; - GetMatrixColumns(vs, sz, scols); - GetMatrixColumns(vd, sz, dcols); + // The Vec4s start at every fourth reg, or for the transposed layout at the first four. + // (Transposing the register names instead goes wrong when the rows wrap around, like E020.) for (int i = 0; i < 4; i++) { - u8 svec[4], dvec[4]; - GetVectorRegs(svec, GetVectorSize(sz), scols[i]); - GetVectorRegs(dvec, GetVectorSize(sz), dcols[i]); - ir.Write(IROp::Vec4Mov, dvec[0], svec[0]); + int start = bothVec4 ? i * 4 : i; + ir.Write(IROp::Vec4Mov, dregs[start], sregs[start]); } return; }