mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-11-15 02:29:51 +01:00
interp: Correct size handling for vi2x ops.
This commit is contained in:
1 parent
8a888bad96
commit
fa5315de5e
2 files changed
+57
-62
No files matched your search
@@ -1443,8 +1443,7 @@ namespace MIPSComp {
|
||||
|
||||
void IRFrontend::Comp_Vi2x(MIPSOpcode op) {
|
||||
CONDITIONAL_DISABLE(VFPU_VEC);
|
||||
|
||||
if (js.HasUnknownPrefix())
|
||||
if (js.HasUnknownPrefix() || js.HasSPrefix())
|
||||
DISABLE;
|
||||
|
||||
int bits = ((op >> 16) & 2) == 0 ? 8 : 16; // vi2uc/vi2c (0/1), vi2us/vi2s (2/3)
|
||||
|
||||
+56
-60
@@ -960,89 +960,85 @@ namespace MIPSInt
|
||||
EatPrefixes();
|
||||
}
|
||||
|
||||
void Int_Vi2x(MIPSOpcode op)
|
||||
{
|
||||
int s[4];
|
||||
u32 d[2] = {0};
|
||||
void Int_Vi2x(MIPSOpcode op) {
|
||||
int s[4]{};
|
||||
u32 d[2]{};
|
||||
int vd = _VD;
|
||||
int vs = _VS;
|
||||
VectorSize sz = GetVecSize(op);
|
||||
VectorSize oz;
|
||||
ReadVector(reinterpret_cast<float *>(s), sz, vs);
|
||||
ApplySwizzleS(reinterpret_cast<float *>(s), sz); //TODO: and the mask to kill everything but swizzle
|
||||
switch ((op >> 16)&3)
|
||||
{
|
||||
// Negate, const, etc. apply as expected.
|
||||
ApplySwizzleS(reinterpret_cast<float *>(s), V_Quad);
|
||||
|
||||
// TODO: Similar to colorconv, invalid swizzle seems to reuse last output.
|
||||
switch ((op >> 16) & 3) {
|
||||
case 0: //vi2uc
|
||||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
int v = s[i];
|
||||
if (v < 0) v = 0;
|
||||
v >>= 23;
|
||||
d[0] |= ((u32)v & 0xFF) << (i * 8);
|
||||
}
|
||||
oz = V_Single;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
int v = s[i];
|
||||
if (v < 0) v = 0;
|
||||
v >>= 23;
|
||||
d[0] |= ((u32)v & 0xFF) << (i * 8);
|
||||
}
|
||||
oz = V_Single;
|
||||
break;
|
||||
|
||||
case 1: //vi2c
|
||||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
u32 v = s[i];
|
||||
d[0] |= (v >> 24) << (i * 8);
|
||||
}
|
||||
oz = V_Single;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
u32 v = s[i];
|
||||
d[0] |= (v >> 24) << (i * 8);
|
||||
}
|
||||
oz = V_Single;
|
||||
break;
|
||||
|
||||
case 2: //vi2us
|
||||
{
|
||||
for (int i = 0; i < GetNumVectorElements(sz) / 2; i++) {
|
||||
int low = s[i * 2];
|
||||
int high = s[i * 2 + 1];
|
||||
if (low < 0) low = 0;
|
||||
if (high < 0) high = 0;
|
||||
low >>= 15;
|
||||
high >>= 15;
|
||||
d[i] = low | (high << 16);
|
||||
}
|
||||
switch (sz) {
|
||||
case V_Quad: oz = V_Pair; break;
|
||||
case V_Pair: oz = V_Single; break;
|
||||
default:
|
||||
_dbg_assert_msg_(CPU,0,"Trying to interpret instruction that can't be interpreted");
|
||||
oz = V_Single;
|
||||
break;
|
||||
}
|
||||
for (int i = 0; i < (GetNumVectorElements(sz) + 1) / 2; i++) {
|
||||
int low = s[i * 2];
|
||||
int high = s[i * 2 + 1];
|
||||
if (low < 0) low = 0;
|
||||
if (high < 0) high = 0;
|
||||
low >>= 15;
|
||||
high >>= 15;
|
||||
d[i] = low | (high << 16);
|
||||
}
|
||||
switch (sz) {
|
||||
case V_Quad: oz = V_Pair; break;
|
||||
case V_Triple: oz = V_Pair; break;
|
||||
case V_Pair: oz = V_Single; break;
|
||||
case V_Single: oz = V_Single; break;
|
||||
default:
|
||||
_dbg_assert_msg_(CPU, 0, "Trying to interpret instruction that can't be interpreted");
|
||||
oz = V_Single;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 3: //vi2s
|
||||
{
|
||||
for (int i = 0; i < GetNumVectorElements(sz) / 2; i++) {
|
||||
u32 low = s[i * 2];
|
||||
u32 high = s[i * 2 + 1];
|
||||
low >>= 16;
|
||||
high >>= 16;
|
||||
d[i] = low | (high << 16);
|
||||
}
|
||||
switch (sz) {
|
||||
case V_Quad: oz = V_Pair; break;
|
||||
case V_Pair: oz = V_Single; break;
|
||||
default:
|
||||
_dbg_assert_msg_(CPU,0,"Trying to interpret instruction that can't be interpreted");
|
||||
oz = V_Single;
|
||||
break;
|
||||
}
|
||||
for (int i = 0; i < (GetNumVectorElements(sz) + 1) / 2; i++) {
|
||||
u32 low = s[i * 2];
|
||||
u32 high = s[i * 2 + 1];
|
||||
low >>= 16;
|
||||
high >>= 16;
|
||||
d[i] = low | (high << 16);
|
||||
}
|
||||
switch (sz) {
|
||||
case V_Quad: oz = V_Pair; break;
|
||||
case V_Triple: oz = V_Pair; break;
|
||||
case V_Pair: oz = V_Single; break;
|
||||
case V_Single: oz = V_Single; break;
|
||||
default:
|
||||
_dbg_assert_msg_(CPU, 0, "Trying to interpret instruction that can't be interpreted");
|
||||
oz = V_Single;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
_dbg_assert_msg_(CPU,0,"Trying to interpret instruction that can't be interpreted");
|
||||
_dbg_assert_msg_(CPU, 0, "Trying to interpret instruction that can't be interpreted");
|
||||
oz = V_Single;
|
||||
break;
|
||||
}
|
||||
ApplyPrefixD(reinterpret_cast<float *>(d),oz);
|
||||
WriteVector(reinterpret_cast<float *>(d),oz,vd);
|
||||
// D prefix applies as expected.
|
||||
ApplyPrefixD(reinterpret_cast<float *>(d), oz);
|
||||
WriteVector(reinterpret_cast<float *>(d), oz, vd);
|
||||
PC += 4;
|
||||
EatPrefixes();
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user