mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-21 10:19:04 +02:00
VFPU: Generate the VFPU's NaN in vbfy, vocp and vsocp on all cores
These are sums, so a NaN result is 0x7F800001 like vadd's (cpu/vfpu/specials). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
d5de19a120
commit
e0a31e7fbc
5 files changed
+31
-10
No files matched your search
@@ -2421,6 +2421,8 @@ namespace MIPSComp
|
||||
for (int i = 0; i < n; ++i) {
|
||||
fpr.MapDirtyInInV(tempregs[i], sregs[i], tregs[i]);
|
||||
VADD(fpr.V(tempregs[i]), fpr.V(tregs[i]), fpr.V(sregs[i]));
|
||||
// A NaN comes out as the VFPU's (cpu/vfpu/specials).
|
||||
EmitVfpuSumNaN(fpr.V(tempregs[i]));
|
||||
}
|
||||
|
||||
for (int i = 0; i < n; ++i) {
|
||||
|
||||
@@ -2422,6 +2422,8 @@ namespace MIPSComp {
|
||||
for (int i = 0; i < n; ++i) {
|
||||
fpr.MapDirtyInInV(tempregs[i], sregs[i], tregs[i]);
|
||||
fp.FADD(fpr.V(tempregs[i]), fpr.V(tregs[i]), fpr.V(sregs[i]));
|
||||
// A NaN comes out as the VFPU's (cpu/vfpu/specials).
|
||||
EmitVfpuSumNaN(fpr.V(tempregs[i]));
|
||||
}
|
||||
|
||||
for (int i = 0; i < n; ++i) {
|
||||
@@ -2542,6 +2544,10 @@ namespace MIPSComp {
|
||||
fp.FSUB(S3, fpr.V(sregs[2]), fpr.V(sregs[3]));
|
||||
}
|
||||
}
|
||||
// A NaN comes out as the VFPU's (cpu/vfpu/specials).
|
||||
for (int i = 0; i < n; i++) {
|
||||
EmitVfpuSumNaN((ARM64Reg)(S0 + i));
|
||||
}
|
||||
|
||||
fpr.MapRegsAndSpillLockV(dregs, sz, MAP_NOINIT);
|
||||
for (int i = 0; i < n; i++) {
|
||||
|
||||
@@ -2503,10 +2503,13 @@ namespace MIPSComp {
|
||||
GetVectorRegsPrefixT(tregs, sz, _VS);
|
||||
GetVectorRegsPrefixD(dregs, sz, _VD);
|
||||
|
||||
// A NaN comes out as the VFPU's (cpu/vfpu/specials).
|
||||
if (IsVec4(sz, dregs) && IsVec4(sz, sregs) && IsVec4(sz, tregs)) {
|
||||
ir.Write(IROp::Vec4Add, dregs[0], tregs[0], sregs[0]);
|
||||
ir.Write(IROp::Vec4VfpuNaN, dregs[0], dregs[0]);
|
||||
} else if (IsVec3of4(sz, dregs) && IsVec3of4(sz, sregs) && IsVec3of4(sz, tregs) && opts.preferVec4) {
|
||||
ir.Write(IROp::Vec4Add, IRVTEMP_0, tregs[0], sregs[0]);
|
||||
ir.Write(IROp::Vec4VfpuNaN, IRVTEMP_0, IRVTEMP_0);
|
||||
ir.Write(IROp::Vec4Blend, dregs[0], dregs[0], IRVTEMP_0, 0x7);
|
||||
} else {
|
||||
u8 tempregs[4];
|
||||
@@ -2520,6 +2523,7 @@ namespace MIPSComp {
|
||||
|
||||
for (int i = 0; i < n; ++i) {
|
||||
ir.Write(IROp::FAdd, tempregs[i], tregs[i], sregs[i]);
|
||||
ir.Write(IROp::FVfpuNaN, tempregs[i], tempregs[i]);
|
||||
}
|
||||
for (int i = 0; i < n; ++i) {
|
||||
if (dregs[i] != tempregs[i]) {
|
||||
@@ -2642,6 +2646,10 @@ namespace MIPSComp {
|
||||
INVALIDOP;
|
||||
}
|
||||
|
||||
// A NaN comes out as the VFPU's (cpu/vfpu/specials).
|
||||
for (int i = 0; i < n; ++i) {
|
||||
ir.Write(IROp::FVfpuNaN, tempregs[i], tempregs[i]);
|
||||
}
|
||||
for (int i = 0; i < n; ++i) {
|
||||
if (tempregs[i] != dregs[i])
|
||||
ir.Write(IROp::FMov, dregs[i], tempregs[i]);
|
||||
|
||||
@@ -753,8 +753,8 @@ namespace MIPSInt
|
||||
ApplyPrefixST(mips, t, VFPURewritePrefix(mips, VFPU_CTRL_TPREFIX, tprefixRemove, tprefixAdd), sz);
|
||||
|
||||
for (int i = 0; i < GetNumVectorElements(sz); i++) {
|
||||
// Always positive NaN. Note that s is always negated from the registers.
|
||||
d[i] = my_isnan(s[i]) ? fabsf(s[i]) : t[i] + s[i];
|
||||
// Note that s is always negated from the registers.
|
||||
d[i] = VfpuSumNaN(t[i] + s[i]);
|
||||
}
|
||||
RetainInvalidSwizzleST(mips, d, sz);
|
||||
ApplyPrefixD(mips, d, sz);
|
||||
@@ -786,11 +786,11 @@ namespace MIPSInt
|
||||
ApplyPrefixST(mips, t, VFPURewritePrefix(mips, VFPU_CTRL_TPREFIX, tprefixRemove, tprefixAdd), outSize);
|
||||
|
||||
// Essentially D prefix saturation is forced.
|
||||
d[0] = nanclamp(t[0] + s[0], 0.0f, 1.0f);
|
||||
d[1] = nanclamp(t[1] + s[1], 0.0f, 1.0f);
|
||||
d[0] = nanclamp(VfpuSumNaN(t[0] + s[0]), 0.0f, 1.0f);
|
||||
d[1] = nanclamp(VfpuSumNaN(t[1] + s[1]), 0.0f, 1.0f);
|
||||
if (outSize == V_Quad) {
|
||||
d[2] = nanclamp(t[2] + s[2], 0.0f, 1.0f);
|
||||
d[3] = nanclamp(t[3] + s[3], 0.0f, 1.0f);
|
||||
d[2] = nanclamp(VfpuSumNaN(t[2] + s[2]), 0.0f, 1.0f);
|
||||
d[3] = nanclamp(VfpuSumNaN(t[3] + s[3]), 0.0f, 1.0f);
|
||||
}
|
||||
ApplyPrefixD(mips, d, sz, true);
|
||||
WriteVector(mips, d, outSize, vd);
|
||||
@@ -1335,10 +1335,9 @@ namespace MIPSInt
|
||||
}
|
||||
}
|
||||
|
||||
d[0] = s[0] + t[0];
|
||||
d[1] = s[1] + t[1];
|
||||
d[2] = s[2] + t[2];
|
||||
d[3] = s[3] + t[3];
|
||||
for (int i = 0; i < 4; i++) {
|
||||
d[i] = VfpuSumNaN(s[i] + t[i]);
|
||||
}
|
||||
|
||||
ApplyPrefixD(mips, d, sz);
|
||||
WriteVector(mips, d, sz, vd);
|
||||
|
||||
@@ -2247,6 +2247,8 @@ void Jit::Comp_Vocp(MIPSOpcode op) {
|
||||
}
|
||||
ADDSS(XMM0, fpr.V(sregs[i]));
|
||||
MOVSS(tempxregs[i], R(XMM0));
|
||||
// A NaN comes out as the VFPU's (cpu/vfpu/specials).
|
||||
EmitVfpuSumNaN1(tempxregs[i]);
|
||||
}
|
||||
|
||||
for (int i = 0; i < n; ++i) {
|
||||
@@ -2318,6 +2320,10 @@ void Jit::Comp_Vbfy(MIPSOpcode op) {
|
||||
DISABLE;
|
||||
}
|
||||
|
||||
// A NaN comes out as the VFPU's (cpu/vfpu/specials).
|
||||
for (int i = 0; i < n; ++i)
|
||||
EmitVfpuSumNaN1(tempxregs[i]);
|
||||
|
||||
for (int i = 0; i < n; ++i) {
|
||||
if (!fpr.V(dregs[i]).IsSimpleReg(tempxregs[i]))
|
||||
MOVSS(fpr.V(dregs[i]), tempxregs[i]);
|
||||
|
||||
Reference in new issue
Block a user