mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-01 14:58:14 +00:00
VFPU: make vmfvc see a pending prefix, and actually write its result
Comp_Vmfvc read vfpuCtrl[] straight from the context in all four backends, while the mfvc path in Comp_Mftv flushes first, with the comment "In case we have a saved prefix" - so "vpfxs X" followed by "vmfvc sN, $128" returned the stale value in memory. The IR frontend flushes only for the three prefix registers, which is the tighter form, so vmfvc does the same there. On ARM and ARM64 the fix alone wouldn't have been observable: those two map the destination with no flags, leaving isDirty false, so the flush dropped the loaded value without storing it. x86 already passes MAP_DIRTY | MAP_NOINIT. That part is a fix of its own, but the two are inseparable in this function - a vmfvc that reads the right value and then throws it away is no better. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
This commit is contained in:
1 parent
6c7fc8df37
commit
315d128141
4 files changed
+16
-2
No files matched your search
@@ -1332,11 +1332,13 @@ namespace MIPSComp
|
||||
int vd = _VD;
|
||||
int imm = (op >> 8) & 0x7F;
|
||||
if (imm < VFPU_CTRL_MAX) {
|
||||
fpr.MapRegV(vd);
|
||||
fpr.MapRegV(vd, MAP_DIRTY | MAP_NOINIT);
|
||||
if (imm == VFPU_CTRL_CC) {
|
||||
gpr.MapReg(MIPS_REG_VFPUCC, 0);
|
||||
VMOV(fpr.V(vd), gpr.R(MIPS_REG_VFPUCC));
|
||||
} else {
|
||||
// In case we have a saved prefix.
|
||||
FlushPrefixV();
|
||||
ADDI2R(SCRATCHREG1, CTXREG, offsetof(MIPSState, vfpuCtrl[0]) + imm * 4, SCRATCHREG2);
|
||||
VLDR(fpr.V(vd), SCRATCHREG1, 0);
|
||||
}
|
||||
|
||||
@@ -1110,11 +1110,13 @@ namespace MIPSComp {
|
||||
int vd = _VD;
|
||||
int imm = (op >> 8) & 0x7F;
|
||||
if (imm < VFPU_CTRL_MAX) {
|
||||
fpr.MapRegV(vd);
|
||||
fpr.MapRegV(vd, MAP_DIRTY | MAP_NOINIT);
|
||||
if (imm == VFPU_CTRL_CC) {
|
||||
gpr.MapReg(MIPS_REG_VFPUCC, 0);
|
||||
fp.FMOV(fpr.V(vd), gpr.R(MIPS_REG_VFPUCC));
|
||||
} else {
|
||||
// In case we have a saved prefix.
|
||||
FlushPrefixV();
|
||||
ADDI2R(SCRATCH1_64, CTXREG, offsetof(MIPSState, vfpuCtrl[0]) + imm * 4, SCRATCH2);
|
||||
fp.LDR(32, INDEX_UNSIGNED, fpr.V(vd), SCRATCH1_64, 0);
|
||||
}
|
||||
|
||||
@@ -1318,6 +1318,14 @@ namespace MIPSComp {
|
||||
int vd = _VD;
|
||||
int imm = (op >> 8) & 0x7F;
|
||||
if (imm < VFPU_CTRL_MAX) {
|
||||
switch (imm) {
|
||||
case VFPU_CTRL_DPREFIX:
|
||||
case VFPU_CTRL_SPREFIX:
|
||||
case VFPU_CTRL_TPREFIX:
|
||||
// In case we have a saved prefix.
|
||||
FlushPrefixV();
|
||||
break;
|
||||
}
|
||||
ir.Write(IROp::VfpuCtrlToReg, IRTEMP_0, imm);
|
||||
ir.Write(IROp::FMovFromGPR, vfpuBase + voffset[vd], IRTEMP_0);
|
||||
} else {
|
||||
|
||||
@@ -2586,6 +2586,8 @@ void Jit::Comp_Vmfvc(MIPSOpcode op) {
|
||||
gpr.MapReg(MIPS_REG_VFPUCC, true, false);
|
||||
MOVD_xmm(fpr.VX(vd), gpr.R(MIPS_REG_VFPUCC));
|
||||
} else {
|
||||
// In case we have a saved prefix.
|
||||
FlushPrefixV();
|
||||
MOVSS(fpr.VX(vd), MIPSSTATE_VAR_ELEM32(vfpuCtrl[0], imm));
|
||||
}
|
||||
fpr.ReleaseSpillLocks();
|
||||
|
||||
Reference in new issue
Block a user