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) <noreply@anthropic.com>
This commit is contained in:
Henrik RydgårdandClaude Opus 5.5 committed 2026-10-15 14:41:51 +02:00
1 parent ff42928673
commit a6193abcd7
1 file changed
+4 -13
+4 -13
View File
@@ -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;
}