From b2e024025f0038abdf943377fa1059a59bf612dd Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Mon, 11 Mar 2019 22:44:06 -0700 Subject: [PATCH] interp: Handle wrong sizes of vf2h/vh2f. Probably not ever used, but they have consistent behavior. --- Core/MIPS/IR/IRCompVFPU.cpp | 3 +++ Core/MIPS/MIPSIntVFPU.cpp | 25 ++++++++++--------------- 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/Core/MIPS/IR/IRCompVFPU.cpp b/Core/MIPS/IR/IRCompVFPU.cpp index f9081133f1..16ba587bfb 100644 --- a/Core/MIPS/IR/IRCompVFPU.cpp +++ b/Core/MIPS/IR/IRCompVFPU.cpp @@ -930,6 +930,9 @@ namespace MIPSComp { void IRFrontend::Comp_Vh2f(MIPSOpcode op) { CONDITIONAL_DISABLE(VFPU_VEC); + if (js.HasUnknownPrefix() || !IsPrefixWithinSize(js.prefixS, op)) { + DISABLE; + } // Vector expand half to float // d[N*2] = float(lowerhalf(s[N])), d[N*2+1] = float(upperhalf(s[N])) diff --git a/Core/MIPS/MIPSIntVFPU.cpp b/Core/MIPS/MIPSIntVFPU.cpp index be4628d5bd..ab30fcb8e9 100644 --- a/Core/MIPS/MIPSIntVFPU.cpp +++ b/Core/MIPS/MIPSIntVFPU.cpp @@ -717,8 +717,7 @@ namespace MIPSInt EatPrefixes(); } - void Int_Vh2f(MIPSOpcode op) - { + void Int_Vh2f(MIPSOpcode op) { u32 s[4]; float d[4]; int vd = _VD; @@ -735,16 +734,14 @@ namespace MIPSInt d[1] = ExpandHalf(s[0] >> 16); break; case V_Pair: + default: + // All other sizes are treated the same. outsize = V_Quad; d[0] = ExpandHalf(s[0] & 0xFFFF); d[1] = ExpandHalf(s[0] >> 16); d[2] = ExpandHalf(s[1] & 0xFFFF); d[3] = ExpandHalf(s[1] >> 16); break; - default: - _dbg_assert_msg_(CPU, 0, "Trying to interpret Int_Vh2f instruction that can't be interpreted"); - memset(d, 0, sizeof(d)); - break; } ApplyPrefixD(d, outsize); WriteVector(d, outsize, vd); @@ -752,32 +749,30 @@ namespace MIPSInt EatPrefixes(); } - void Int_Vf2h(MIPSOpcode op) - { - float s[4]; + void Int_Vf2h(MIPSOpcode op) { + float s[4]{}; u32 d[4]; int vd = _VD; int vs = _VS; VectorSize sz = GetVecSize(op); ReadVector(s, sz, vs); - ApplySwizzleS(s, sz); + // Swizzle can cause V_Single to properly write both components. + // TODO: Minor, but negate shouldn't apply to invalid here. Maybe always? + ApplySwizzleS(s, V_Quad); VectorSize outsize = V_Single; switch (sz) { + case V_Single: case V_Pair: outsize = V_Single; d[0] = ShrinkToHalf(s[0]) | ((u32)ShrinkToHalf(s[1]) << 16); break; + case V_Triple: case V_Quad: outsize = V_Pair; d[0] = ShrinkToHalf(s[0]) | ((u32)ShrinkToHalf(s[1]) << 16); d[1] = ShrinkToHalf(s[2]) | ((u32)ShrinkToHalf(s[3]) << 16); break; - default: - _dbg_assert_msg_(CPU, 0, "Trying to interpret Int_Vf2h instruction that can't be interpreted"); - d[0] = 0; - d[1] = 0; - break; } ApplyPrefixD(reinterpret_cast(d), outsize); WriteVector(reinterpret_cast(d), outsize, vd);