mirror of
https://github.com/libretro/ppsspp.git
synced 2025-02-21 17:30:46 +00:00
Fix VFPU bugs thanks to new tests.
This commit is contained in:
parent
7fd96a0c27
commit
8aa072161c
@ -468,7 +468,9 @@ namespace MIPSInt
|
||||
case 21: d[i] = logf(s[i])/log(2.0f); break;
|
||||
case 22: d[i] = sqrtf(s[i]); break; //vsqrt
|
||||
case 23: d[i] = asinf(s[i] * (float)M_2_PI); break; //vasin
|
||||
|
||||
// case 24: vnrcp
|
||||
// case 26: vnsin
|
||||
case 28: d[i] = 1.0f / expf(s[i] * (float)M_LOG2E); break; // vrexp2
|
||||
default:
|
||||
_dbg_assert_msg_(CPU,0,"Trying to interpret VV2Op instruction that can't be interpreted");
|
||||
break;
|
||||
@ -516,24 +518,6 @@ namespace MIPSInt
|
||||
EatPrefixes();
|
||||
}
|
||||
|
||||
void Int_VRexp2(u32 op)
|
||||
{
|
||||
float s[4], d[4];
|
||||
int vd = _VD;
|
||||
int vs = _VS;
|
||||
VectorSize sz = GetVecSize(op);
|
||||
ReadVector(s, sz, vs);
|
||||
ApplySwizzleS(s, sz);
|
||||
for (int i = 0; i < GetNumVectorElements(sz); i++)
|
||||
{
|
||||
d[i] = 1.0f / expf(s[i] * (float)M_LOG2E);
|
||||
}
|
||||
ApplyPrefixD(d, sz);
|
||||
WriteVector(d, sz, vd);
|
||||
PC += 4;
|
||||
EatPrefixes();
|
||||
}
|
||||
|
||||
void Int_Vf2i(u32 op)
|
||||
{
|
||||
float s[4];
|
||||
@ -609,6 +593,70 @@ namespace MIPSInt
|
||||
EatPrefixes();
|
||||
}
|
||||
|
||||
u32 replicate3(u32 low) {
|
||||
low &= 0xFF;
|
||||
return low | (low << 8) | (low << 16);
|
||||
}
|
||||
|
||||
void Int_Vx2i(u32 op)
|
||||
{
|
||||
int s[4];
|
||||
u32 d[4] = {0};
|
||||
int vd = _VD;
|
||||
int vs = _VS;
|
||||
VectorSize sz = GetVecSize(op);
|
||||
VectorSize oz = sz;
|
||||
ReadVector((float*)s, sz, vs);
|
||||
// ForbidVPFXS
|
||||
|
||||
switch ((op >> 16) & 3) {
|
||||
case 0: // vuc2i
|
||||
// Quad is the only option
|
||||
{
|
||||
_dbg_assert_msg_(CPU,0,"Trying to interpret instruction that can't be interpreted");
|
||||
// this op appears to be bugged and most likely useless, and this stuff is wrong. I've disabled this op in the vfpu_convert test
|
||||
u32 value = s[0];
|
||||
u32 value2 = value / 2;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
d[i] = ((value & 0xFF) << 24) | replicate3(value2);
|
||||
value >>= 8;
|
||||
value2 >>= 8;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 1: // vc2i
|
||||
// Quad is the only option
|
||||
{
|
||||
u32 value = s[0];
|
||||
d[0] = (value & 0xFF) << 24;
|
||||
d[1] = (value & 0xFF00) << 16;
|
||||
d[2] = (value & 0xFF0000) << 8;
|
||||
d[3] = (value & 0xFF000000);
|
||||
}
|
||||
break;
|
||||
|
||||
case 2: // vus2i
|
||||
// Actually identical to vs2i, the sign doesn't matter I think.
|
||||
case 3: // vs2i
|
||||
for (int i = 0; i < GetNumVectorElements(sz); i++) {
|
||||
u32 value = s[i];
|
||||
d[i * 2] = (value & 0xFFFF) << 16;
|
||||
d[i * 2 + 1] = value & 0xFFFF0000;
|
||||
}
|
||||
oz = V_Pair;
|
||||
if (sz == V_Pair) oz = V_Quad;
|
||||
break;
|
||||
default:
|
||||
_dbg_assert_msg_(CPU,0,"Trying to interpret instruction that can't be interpreted");
|
||||
break;
|
||||
}
|
||||
|
||||
ApplyPrefixD((float*)d,oz); // Only write mask should be valid
|
||||
WriteVector((float*)d,oz,vd);
|
||||
PC += 4;
|
||||
EatPrefixes();
|
||||
}
|
||||
|
||||
void Int_Vi2x(u32 op)
|
||||
{
|
||||
int s[4];
|
||||
@ -694,7 +742,7 @@ namespace MIPSInt
|
||||
u16 colors[4];
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
u32 in = colors[i];
|
||||
u32 in = s[i];
|
||||
u16 col = 0;
|
||||
switch ((op >> 16) & 3)
|
||||
{
|
||||
@ -709,10 +757,10 @@ namespace MIPSInt
|
||||
}
|
||||
case 2: // 5551
|
||||
{
|
||||
int a = ((in >> 24) & 0xFF) >> 4;
|
||||
int b = ((in >> 16) & 0xFF) >> 4;
|
||||
int g = ((in >> 8) & 0xFF) >> 4;
|
||||
int r = ((in) & 0xFF) >> 4;
|
||||
int a = ((in >> 24) & 0xFF) >> 7;
|
||||
int b = ((in >> 16) & 0xFF) >> 3;
|
||||
int g = ((in >> 8) & 0xFF) >> 3;
|
||||
int r = ((in) & 0xFF) >> 3;
|
||||
col = (a << 15) | (b << 10) | (g << 5) | (r);
|
||||
break;
|
||||
}
|
||||
|
@ -57,11 +57,11 @@ namespace MIPSInt
|
||||
void Int_Vf2i(u32 op);
|
||||
void Int_Vi2f(u32 op);
|
||||
void Int_Vi2x(u32 op);
|
||||
void Int_Vx2i(u32 op);
|
||||
void Int_VBranch(u32 op);
|
||||
void Int_Vrnds(u32 op);
|
||||
void Int_VrndX(u32 op);
|
||||
void Int_ColorConv(u32 op);
|
||||
void Int_Vh2f2h(u32 op);
|
||||
void Int_VRexp2(u32 op);
|
||||
}
|
||||
|
||||
|
@ -241,7 +241,11 @@ const MIPSInstruction tableSpecial[64] = /// 000000 ...... ...... .......... xxx
|
||||
{-2},
|
||||
|
||||
//56
|
||||
{-2}, {-2}, {-2}, {-2}, {-2}, {-2}, {-2}, {-2},
|
||||
{-2}, {-2}, {-2}, {-2}, {-2},
|
||||
|
||||
{-2},
|
||||
{-2},
|
||||
{-2},
|
||||
};
|
||||
|
||||
const MIPSInstruction tableSpecial2[64] =
|
||||
@ -566,10 +570,10 @@ MIPSInstruction tableVFPU7[32] =
|
||||
{-2},
|
||||
INSTR("vlgb", &Jit::Comp_Generic, Dis_Generic, 0, IS_VFPU),
|
||||
//24
|
||||
INSTR("vrexp2", &Jit::Comp_Generic, Dis_Generic, Int_VRexp2, IS_VFPU), // vrexp2 Seen in BraveStory, initialization 110100 00001110000 000 0001 0000 0000
|
||||
{-2},
|
||||
INSTR("vus2i", &Jit::Comp_Generic, Dis_Generic, 0, IS_VFPU),
|
||||
INSTR("vs2i", &Jit::Comp_Generic, Dis_Generic, 0, IS_VFPU),
|
||||
INSTR("vuc2i", &Jit::Comp_Generic, Dis_Generic, Int_Vx2i, IS_VFPU), // Seen in BraveStory, initialization 110100 00001110000 000 0001 0000 0000
|
||||
INSTR("vc2i", &Jit::Comp_Generic, Dis_Generic, Int_Vx2i, IS_VFPU),
|
||||
INSTR("vus2i", &Jit::Comp_Generic, Dis_Generic, Int_Vx2i, IS_VFPU),
|
||||
INSTR("vs2i", &Jit::Comp_Generic, Dis_Generic, Int_Vx2i, IS_VFPU),
|
||||
|
||||
INSTR("vi2uc", &Jit::Comp_Generic, Dis_Vi2x, Int_Vi2x, IS_VFPU),
|
||||
INSTR("vi2c", &Jit::Comp_Generic, Dis_Vi2x, Int_Vi2x, IS_VFPU),
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 696aad4df5ff0e4cd26dd46b705ca1c2fe57ccfd
|
||||
Subproject commit 1a817700d4ae2b2c1fd20e68b4351d3a9014ee96
|
14
test.py
14
test.py
@ -14,6 +14,10 @@ TEST_ROOT = "pspautotests/tests/"
|
||||
# These have worked and should keep working always - regression tests.
|
||||
tests_good = [
|
||||
"cpu/cpu/cpu",
|
||||
"cpu/vfpu/vfpu",
|
||||
"cpu/vfpu/convert/vfpu_convert",
|
||||
"cpu/vfpu/prefixes/vfpu_prefixes",
|
||||
"cpu/vfpu/colors/vfpu_colors",
|
||||
"cpu/icache/icache",
|
||||
"cpu/lsu/lsu",
|
||||
"cpu/fpu/fpu",
|
||||
@ -31,7 +35,6 @@ tests_good = [
|
||||
|
||||
# These are the next tests up for fixing.
|
||||
tests_next = [
|
||||
"cpu/vfpu/vfpu",
|
||||
"ctrl/ctrl",
|
||||
"gpu/simple/simple",
|
||||
"gpu/triangle/triangle",
|
||||
@ -42,10 +45,8 @@ tests_next = [
|
||||
"io/io/io",
|
||||
"io/iodrv/iodrv",
|
||||
"malloc/malloc",
|
||||
"mstick/mstick",
|
||||
"modules/loadexec/loader",
|
||||
"power/power",
|
||||
"sysmem/sysmem",
|
||||
"threads/events/events",
|
||||
"threads/fpl/fpl",
|
||||
"threads/msgpipe/msgpipe",
|
||||
@ -64,6 +65,13 @@ tests_next = [
|
||||
"video/pmf_simple",
|
||||
]
|
||||
|
||||
# These don't even run (or run correctly) on the real PSP
|
||||
test_broken = [
|
||||
"sysmem/sysmem",
|
||||
"mstick/mstick",
|
||||
]
|
||||
|
||||
|
||||
# These are the tests we ignore (not important, or impossible to run)
|
||||
tests_ignored = [
|
||||
"kirk/kirk",
|
||||
|
Loading…
x
Reference in New Issue
Block a user