From 6bf1390603574311bb2e9737b8f3f20c71cec6d9 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 15 May 2016 01:32:37 -0700 Subject: [PATCH 1/5] Fix timing drift on CoreTiming::ForceCheck(). Since -1 -(-1) = 0, we'll never think we moved forward this way. --- Core/CoreTiming.cpp | 2 +- Core/MIPS/IR/IRJit.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Core/CoreTiming.cpp b/Core/CoreTiming.cpp index 61956cf1e3..887e420dd1 100644 --- a/Core/CoreTiming.cpp +++ b/Core/CoreTiming.cpp @@ -572,7 +572,7 @@ void ForceCheck() // This will cause us to check for new events immediately. currentMIPS->downcount = -1; // But let's not eat a bunch more time in Advance() because of this. - slicelength = 1; + slicelength = -1; } void Advance() diff --git a/Core/MIPS/IR/IRJit.cpp b/Core/MIPS/IR/IRJit.cpp index c89feb9fd9..13d4209633 100644 --- a/Core/MIPS/IR/IRJit.cpp +++ b/Core/MIPS/IR/IRJit.cpp @@ -149,7 +149,7 @@ bool IRJit::ReplaceJalTo(u32 dest) { } void IRBlockCache::Clear() { - for (size_t i = 0; i < blocks_.size(); ++i) { + for (int i = 0; i < size_; ++i) { blocks_[i].Destroy(i); } blocks_.clear(); From fa61deae3da66e309c49bfb31eeeaed6187e2215 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 15 May 2016 12:43:18 -0700 Subject: [PATCH 2/5] Remove unused value. --- Core/MIPS/MIPSIntVFPU.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/Core/MIPS/MIPSIntVFPU.cpp b/Core/MIPS/MIPSIntVFPU.cpp index be321815db..d6e2294fe6 100644 --- a/Core/MIPS/MIPSIntVFPU.cpp +++ b/Core/MIPS/MIPSIntVFPU.cpp @@ -768,7 +768,6 @@ namespace MIPSInt // conversion between 8-bit and 16-bit values. But then why not do it in vc2i? { u32 value = s[0]; - u32 value2 = value / 2; for (int i = 0; i < 4; i++) { d[i] = (u32)((value & 0xFF) * 0x01010101) >> 1; value >>= 8; From 3f0fc2d8519387b395192d9ea76896c2aa041738 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 15 May 2016 13:10:04 -0700 Subject: [PATCH 3/5] jit-ir: Fix FSat0_1 behavior on -0.0f. --- Core/MIPS/IR/IRInterpreter.cpp | 5 +++-- Core/MIPS/MIPSIntVFPU.cpp | 11 ++--------- Core/MIPS/MIPSVFPUUtils.h | 5 +++++ 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/Core/MIPS/IR/IRInterpreter.cpp b/Core/MIPS/IR/IRInterpreter.cpp index 18500238cb..c4a73a2064 100644 --- a/Core/MIPS/IR/IRInterpreter.cpp +++ b/Core/MIPS/IR/IRInterpreter.cpp @@ -593,10 +593,11 @@ u32 IRInterpret(MIPSState *mips, const IRInst *inst, const u32 *constPool, int c mips->f[inst->dest] = -mips->f[inst->src1]; break; case IROp::FSat0_1: - mips->f[inst->dest] = clamp_value(mips->f[inst->src1], 0.0f, 1.0f); + // We have to do this carefully to handle NAN and -0.0f. + mips->f[inst->dest] = vfpu_clamp(mips->f[inst->src1], 0.0f, 1.0f); break; case IROp::FSatMinus1_1: - mips->f[inst->dest] = clamp_value(mips->f[inst->src1], -1.0f, 1.0f); + mips->f[inst->dest] = vfpu_clamp(mips->f[inst->src1], -1.0f, 1.0f); break; // Bitwise trickery diff --git a/Core/MIPS/MIPSIntVFPU.cpp b/Core/MIPS/MIPSIntVFPU.cpp index d6e2294fe6..a787e1f768 100644 --- a/Core/MIPS/MIPSIntVFPU.cpp +++ b/Core/MIPS/MIPSIntVFPU.cpp @@ -164,16 +164,9 @@ void ApplyPrefixD(float *v, VectorSize size, bool onlyWriteMask = false) { int sat = (data >> (i * 2)) & 3; if (sat == 1) - { - if (v[i] > 1.0f) v[i] = 1.0f; - // This includes -0.0f -> +0.0f. - if (v[i] <= 0.0f) v[i] = 0.0f; - } + v[i] = vfpu_clamp(v[i], 0.0f, 1.0f); else if (sat == 3) - { - if (v[i] > 1.0f) v[i] = 1.0f; - if (v[i] < -1.0f) v[i] = -1.0f; - } + v[i] = vfpu_clamp(v[i], -1.0f, 1.0f); } } diff --git a/Core/MIPS/MIPSVFPUUtils.h b/Core/MIPS/MIPSVFPUUtils.h index 7f6ada0fa2..ad98e7cca7 100644 --- a/Core/MIPS/MIPSVFPUUtils.h +++ b/Core/MIPS/MIPSVFPUUtils.h @@ -60,6 +60,11 @@ inline void vfpu_sincos(float angle, float &sine, float &cosine) { #endif } +inline float vfpu_clamp(float v, float min, float max) { + // Note: NAN is preserved, and -0.0 becomes +0.0 if min=+0.0. + return v >= max ? max : (v <= min ? min : v); +} + #define VFPU_FLOAT16_EXP_MAX 0x1f #define VFPU_SH_FLOAT16_SIGN 15 #define VFPU_MASK_FLOAT16_SIGN 0x1 From ab1461facadf522500f9a7577200d159039f3c2c Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 15 May 2016 13:16:03 -0700 Subject: [PATCH 4/5] Add prefix handling to vfpu color conv per tests. --- Core/MIPS/IR/IRCompVFPU.cpp | 3 ++- Core/MIPS/MIPSIntVFPU.cpp | 2 ++ Core/MIPS/x86/CompVFPU.cpp | 5 +++++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/Core/MIPS/IR/IRCompVFPU.cpp b/Core/MIPS/IR/IRCompVFPU.cpp index 676b1d0988..dab8e97e7a 100644 --- a/Core/MIPS/IR/IRCompVFPU.cpp +++ b/Core/MIPS/IR/IRCompVFPU.cpp @@ -1830,7 +1830,8 @@ namespace MIPSComp { void IRFrontend::Comp_ColorConv(MIPSOpcode op) { CONDITIONAL_DISABLE; - // TODO: Verify if this ignores prefixes? + if (js.HasUnknownPrefix()) + DISABLE; // Vector color conversion // d[N] = ConvertTo16(s[N*2]) | (ConvertTo16(s[N*2+1]) << 16) diff --git a/Core/MIPS/MIPSIntVFPU.cpp b/Core/MIPS/MIPSIntVFPU.cpp index a787e1f768..2d2c8f18f3 100644 --- a/Core/MIPS/MIPSIntVFPU.cpp +++ b/Core/MIPS/MIPSIntVFPU.cpp @@ -928,6 +928,7 @@ namespace MIPSInt u32 s[4]; VectorSize sz = V_Quad; ReadVector(reinterpret_cast(s), sz, vs); + ApplySwizzleS(reinterpret_cast(s), sz); u16 colors[4]; for (int i = 0; i < 4; i++) { @@ -965,6 +966,7 @@ namespace MIPSInt colors[i] = col; } u32 ov[2] = {(u32)colors[0] | (colors[1] << 16), (u32)colors[2] | (colors[3] << 16)}; + ApplyPrefixD(reinterpret_cast(ov), V_Pair); WriteVector((const float *)ov, V_Pair, vd); PC += 4; EatPrefixes(); diff --git a/Core/MIPS/x86/CompVFPU.cpp b/Core/MIPS/x86/CompVFPU.cpp index ec95760d57..50176066f6 100644 --- a/Core/MIPS/x86/CompVFPU.cpp +++ b/Core/MIPS/x86/CompVFPU.cpp @@ -3468,6 +3468,10 @@ void Jit::Comp_VRot(MIPSOpcode op) { } void Jit::Comp_ColorConv(MIPSOpcode op) { + CONDITIONAL_DISABLE; + if (js.HasUnknownPrefix()) + DISABLE; + int vd = _VD; int vs = _VS; @@ -3485,6 +3489,7 @@ void Jit::Comp_ColorConv(MIPSOpcode op) { u8 sregs[4]; u8 dregs[1]; + // WARNING: Prefixes. GetVectorRegs(sregs, sz, vs); GetVectorRegs(dregs, V_Pair, vd); From e9601584907fe238510f0d13de3ecdc263cd4b8d Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 15 May 2016 14:03:45 -0700 Subject: [PATCH 5/5] jit-ir: Add notes and report about vrot prefixes. --- Core/MIPS/IR/IRCompVFPU.cpp | 15 +++++++++++++++ Core/MIPS/MIPSIntVFPU.cpp | 1 + Core/MIPS/x86/CompVFPU.cpp | 8 ++++++++ 3 files changed, 24 insertions(+) diff --git a/Core/MIPS/IR/IRCompVFPU.cpp b/Core/MIPS/IR/IRCompVFPU.cpp index dab8e97e7a..a4c90ba784 100644 --- a/Core/MIPS/IR/IRCompVFPU.cpp +++ b/Core/MIPS/IR/IRCompVFPU.cpp @@ -1716,6 +1716,17 @@ namespace MIPSComp { // calling the math library. void IRFrontend::Comp_VRot(MIPSOpcode op) { CONDITIONAL_DISABLE; + if (!js.HasNoPrefix()) { + // Prefixes work strangely for this: + // * They never apply to cos (whether d or s prefixes.) + // * They mostly apply to sin/0, e.g. 0:1, M, or |x|. + DISABLE; + } + + // Vector rotation matrix (weird prefixes) + // d[N] = SINCOSVAL(s[0], imm[N]) + // The imm selects: cos index, sin index, 0 or sin for others, sin sign flip. + int vd = _VD; int vs = _VS; int imm = (op >> 16) & 0x1f; @@ -1844,6 +1855,10 @@ namespace MIPSComp { if (js.HasUnknownPrefix()) DISABLE; + // Vector butterfly operation + // vbfy2: d[0] = s[0] + s[2], d[1] = s[1] + s[3], d[2] = s[0] - s[2], d[3] = s[1] - s[3] + // vbfy1: d[N*2] = s[N*2] + s[N*2+1], d[N*2+1] = s[N*2] - s[N*2+1] + VectorSize sz = GetVecSize(op); int n = GetNumVectorElements(sz); if (n != 2 && n != 4) { diff --git a/Core/MIPS/MIPSIntVFPU.cpp b/Core/MIPS/MIPSIntVFPU.cpp index 2d2c8f18f3..784cba75ca 100644 --- a/Core/MIPS/MIPSIntVFPU.cpp +++ b/Core/MIPS/MIPSIntVFPU.cpp @@ -1297,6 +1297,7 @@ namespace MIPSInt // Generates one line of a rotation matrix around one of the three axes void Int_Vrot(MIPSOpcode op) { + // Note: prefixes behave strangely for this. int vd = _VD; int vs = _VS; int imm = (op >> 16) & 0x1f; diff --git a/Core/MIPS/x86/CompVFPU.cpp b/Core/MIPS/x86/CompVFPU.cpp index 50176066f6..33a74ccd01 100644 --- a/Core/MIPS/x86/CompVFPU.cpp +++ b/Core/MIPS/x86/CompVFPU.cpp @@ -3410,6 +3410,14 @@ void Jit::CompVrotShuffle(u8 *dregs, int imm, int n, bool negSin) { // Very heavily used by FF:CC void Jit::Comp_VRot(MIPSOpcode op) { CONDITIONAL_DISABLE; + if (js.HasUnknownPrefix()) { + DISABLE; + } + if (!js.HasNoPrefix()) { + // Prefixes work strangely for this, see IRCompVFPU. + WARN_LOG_REPORT(JIT, "vrot instruction using prefixes at %08x", GetCompilerPC()); + DISABLE; + } int vd = _VD; int vs = _VS;