mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-14 15:00:30 +02:00
VFPU: Fix vrot with the angle in a destination lane
The cosine is then taken of what vrot wrote to that lane: the sine, or zero. The IR looked at the sine lane instead of the lane holding the angle, and the legacy JITs ignored the overlap. The assembler refuses such a vrot, so those now leave it to the interpreter, and don't pair one with the vrot before it. Covered by the new cpu/vfpu/vrot test. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
4ebf9ed037
commit
6fc4eb19df
6 files changed
+45
-6
No files matched your search
@@ -2250,6 +2250,16 @@ namespace MIPSComp
|
||||
if (vd2 >= 0)
|
||||
GetVectorRegs(dregs2, sz, vd2);
|
||||
GetVectorRegs(&sreg, V_Single, vs);
|
||||
// With the angle in a destination lane, the cosine is taken of what was written there.
|
||||
// The assembler refuses that, so leave it to the interpreter, and don't pair such a vrot.
|
||||
for (int i = 0; i < n; i++) {
|
||||
if (dregs[i] == sreg) {
|
||||
DISABLE;
|
||||
}
|
||||
if (vd2 >= 0 && dregs2[i] == sreg) {
|
||||
vd2 = -1;
|
||||
}
|
||||
}
|
||||
|
||||
int imm = (op >> 16) & 0x1f;
|
||||
|
||||
|
||||
@@ -2231,6 +2231,16 @@ namespace MIPSComp {
|
||||
if (vd2 >= 0)
|
||||
GetVectorRegs(dregs2, sz, vd2);
|
||||
GetVectorRegs(&sreg, V_Single, vs);
|
||||
// With the angle in a destination lane, the cosine is taken of what was written there.
|
||||
// The assembler refuses that, so leave it to the interpreter, and don't pair such a vrot.
|
||||
for (int i = 0; i < n; i++) {
|
||||
if (dregs[i] == sreg) {
|
||||
DISABLE;
|
||||
}
|
||||
if (vd2 >= 0 && dregs2[i] == sreg) {
|
||||
vd2 = -1;
|
||||
}
|
||||
}
|
||||
|
||||
int imm = (op >> 16) & 0x1f;
|
||||
|
||||
|
||||
@@ -2335,12 +2335,20 @@ namespace MIPSComp {
|
||||
}
|
||||
break;
|
||||
case 'c':
|
||||
if (IsOverlapSafe(n, dregs, 1, sreg))
|
||||
if (IsOverlapSafe(n, dregs, 1, sreg)) {
|
||||
ir.Write(IROp::FCos, dregs[i], sreg[0]);
|
||||
else if (dregs[sineLane] == sreg[0])
|
||||
ir.Write(IROp::FCos, dregs[i], IRVTEMP_0);
|
||||
else
|
||||
ir.WriteFC(IROp::SetConstF, dregs[i], 0, 0, 1.0f);
|
||||
} else {
|
||||
// The cosine is taken of what the source lane got: the sine, or zero.
|
||||
int srcLane = 0;
|
||||
while (dregs[srcLane] != sreg[0]) {
|
||||
srcLane++;
|
||||
}
|
||||
if (broadcastSine || srcLane == sineLane) {
|
||||
ir.Write(IROp::FCos, dregs[i], IRVTEMP_0);
|
||||
} else {
|
||||
ir.WriteFC(IROp::SetConstF, dregs[i], 0, 0, 1.0f);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3759,6 +3759,16 @@ void Jit::Comp_VRot(MIPSOpcode op) {
|
||||
if (vd2 >= 0)
|
||||
GetVectorRegs(dregs2, sz, vd2);
|
||||
GetVectorRegs(&sreg, V_Single, vs);
|
||||
// With the angle in a destination lane, the cosine is taken of what was written there.
|
||||
// The assembler refuses that, so leave it to the interpreter, and don't pair such a vrot.
|
||||
for (int i = 0; i < n; i++) {
|
||||
if (dregs[i] == sreg) {
|
||||
DISABLE;
|
||||
}
|
||||
if (vd2 >= 0 && dregs2[i] == sreg) {
|
||||
vd2 = -1;
|
||||
}
|
||||
}
|
||||
|
||||
// Flush SIMD.
|
||||
fpr.SimpleRegsV(&sreg, V_Single, 0);
|
||||
|
||||
+1
-1
Submodule pspautotests updated: 80eb3ae038...6f03ee6457.
Reference in new issue
Block a user