mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-22 18:53:28 +01:00
Merge pull request #879 from gopalsr83/master
PPU: Implemented some instructions and fixed some bugs in the recompiler. Also fixed some issues in the interpreter.
This commit is contained in:
commit
b942da3f68
@ -155,7 +155,8 @@ private:
|
|||||||
case 0x106:
|
case 0x106:
|
||||||
case 0x107: return CPU.USPRG[n - 0x100];
|
case 0x107: return CPU.USPRG[n - 0x100];
|
||||||
|
|
||||||
case 0x10C: return get_time();
|
case 0x10C: CPU.TB = get_time(); return CPU.TB;
|
||||||
|
case 0x10D: CPU.TB = get_time(); return CPU.TBH;
|
||||||
|
|
||||||
case 0x110:
|
case 0x110:
|
||||||
case 0x111:
|
case 0x111:
|
||||||
@ -190,6 +191,7 @@ private:
|
|||||||
case 0x107: CPU.USPRG[n - 0x100] = value; return;
|
case 0x107: CPU.USPRG[n - 0x100] = value; return;
|
||||||
|
|
||||||
case 0x10C: UNK("WriteSPR: Write to time-based SPR. Report this to a developer!"); return;
|
case 0x10C: UNK("WriteSPR: Write to time-based SPR. Report this to a developer!"); return;
|
||||||
|
case 0x10D: UNK("WriteSPR: Write to time-based SPR upper. Report this to a developer!"); return;
|
||||||
|
|
||||||
case 0x110:
|
case 0x110:
|
||||||
case 0x111:
|
case 0x111:
|
||||||
@ -832,45 +834,57 @@ private:
|
|||||||
}
|
}
|
||||||
void VCTSXS(u32 vd, u32 uimm5, u32 vb)
|
void VCTSXS(u32 vd, u32 uimm5, u32 vb)
|
||||||
{
|
{
|
||||||
int nScale = 1 << uimm5;
|
u32 nScale = 1 << uimm5;
|
||||||
|
|
||||||
for (uint w = 0; w < 4; w++)
|
for (uint w = 0; w < 4; w++)
|
||||||
{
|
{
|
||||||
float result = CPU.VPR[vb]._f[w] * nScale;
|
double result = (double)CPU.VPR[vb]._f[w] * nScale;
|
||||||
|
|
||||||
if (result > 0x7fffffff)
|
if (result > 0x7fffffff)
|
||||||
|
{
|
||||||
CPU.VPR[vd]._s32[w] = (int)0x7fffffff;
|
CPU.VPR[vd]._s32[w] = (int)0x7fffffff;
|
||||||
|
CPU.VSCR.SAT = 1;
|
||||||
|
}
|
||||||
else if (result < -pow(2, 31))
|
else if (result < -pow(2, 31))
|
||||||
|
{
|
||||||
CPU.VPR[vd]._s32[w] = (int)0x80000000;
|
CPU.VPR[vd]._s32[w] = (int)0x80000000;
|
||||||
|
CPU.VSCR.SAT = 1;
|
||||||
|
}
|
||||||
else // C rounding = Round towards 0
|
else // C rounding = Round towards 0
|
||||||
CPU.VPR[vd]._s32[w] = (int)result;
|
CPU.VPR[vd]._s32[w] = (int)result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void VCTUXS(u32 vd, u32 uimm5, u32 vb)
|
void VCTUXS(u32 vd, u32 uimm5, u32 vb)
|
||||||
{
|
{
|
||||||
int nScale = 1 << uimm5;
|
u32 nScale = 1 << uimm5;
|
||||||
|
|
||||||
for (uint w = 0; w < 4; w++)
|
for (uint w = 0; w < 4; w++)
|
||||||
{
|
{
|
||||||
// C rounding = Round towards 0
|
// C rounding = Round towards 0
|
||||||
s64 result = (s64)(CPU.VPR[vb]._f[w] * nScale);
|
double result = (double)CPU.VPR[vb]._f[w] * nScale;
|
||||||
|
|
||||||
if (result > 0xffffffffu)
|
if (result > 0xffffffffu)
|
||||||
|
{
|
||||||
CPU.VPR[vd]._u32[w] = 0xffffffffu;
|
CPU.VPR[vd]._u32[w] = 0xffffffffu;
|
||||||
|
CPU.VSCR.SAT = 1;
|
||||||
|
}
|
||||||
else if (result < 0)
|
else if (result < 0)
|
||||||
|
{
|
||||||
CPU.VPR[vd]._u32[w] = 0;
|
CPU.VPR[vd]._u32[w] = 0;
|
||||||
|
CPU.VSCR.SAT = 1;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
CPU.VPR[vd]._u32[w] = (u32)result;
|
CPU.VPR[vd]._u32[w] = (u32)result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void VEXPTEFP(u32 vd, u32 vb)
|
void VEXPTEFP(u32 vd, u32 vb)
|
||||||
{
|
{
|
||||||
// vd = exp(vb * log(2))
|
// vd = 2^x
|
||||||
// ISA : Note that the value placed into the element of vD may vary between implementations
|
// ISA : Note that the value placed into the element of vD may vary between implementations
|
||||||
// and between different executions on the same implementation.
|
// and between different executions on the same implementation.
|
||||||
for (uint w = 0; w < 4; w++)
|
for (uint w = 0; w < 4; w++)
|
||||||
{
|
{
|
||||||
CPU.VPR[vd]._f[w] = exp(CPU.VPR[vb]._f[w] * log(2.0f));
|
CPU.VPR[vd]._f[w] = powf(2.0f, CPU.VPR[vb]._f[w]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void VLOGEFP(u32 vd, u32 vb)
|
void VLOGEFP(u32 vd, u32 vb)
|
||||||
@ -879,7 +893,7 @@ private:
|
|||||||
// and between different executions on the same implementation.
|
// and between different executions on the same implementation.
|
||||||
for (uint w = 0; w < 4; w++)
|
for (uint w = 0; w < 4; w++)
|
||||||
{
|
{
|
||||||
CPU.VPR[vd]._f[w] = log(CPU.VPR[vb]._f[w]) / log(2.0f);
|
CPU.VPR[vd]._f[w] = log2f(CPU.VPR[vb]._f[w]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void VMADDFP(u32 vd, u32 va, u32 vc, u32 vb)
|
void VMADDFP(u32 vd, u32 va, u32 vc, u32 vb)
|
||||||
@ -938,7 +952,8 @@ private:
|
|||||||
{
|
{
|
||||||
for (uint h = 0; h < 8; h++)
|
for (uint h = 0; h < 8; h++)
|
||||||
{
|
{
|
||||||
s32 result = (s32)CPU.VPR[va]._s16[h] * (s32)CPU.VPR[vb]._s16[h] + (s32)CPU.VPR[vc]._s16[h];
|
s32 result = (s32)CPU.VPR[va]._s16[h] * (s32)CPU.VPR[vb]._s16[h];
|
||||||
|
result = (result >> 15) + (s32)CPU.VPR[vc]._s16[h];
|
||||||
|
|
||||||
if (result > INT16_MAX)
|
if (result > INT16_MAX)
|
||||||
{
|
{
|
||||||
@ -958,7 +973,8 @@ private:
|
|||||||
{
|
{
|
||||||
for (uint h = 0; h < 8; h++)
|
for (uint h = 0; h < 8; h++)
|
||||||
{
|
{
|
||||||
s32 result = (s32)CPU.VPR[va]._s16[h] * (s32)CPU.VPR[vb]._s16[h] + (s32)CPU.VPR[vc]._s16[h] + 0x4000;
|
s32 result = ((s32)CPU.VPR[va]._s16[h] * (s32)CPU.VPR[vb]._s16[h]) + 0x4000;
|
||||||
|
result = (result >> 15) + (s32)CPU.VPR[vc]._s16[h];
|
||||||
|
|
||||||
if (result > INT16_MAX)
|
if (result > INT16_MAX)
|
||||||
{
|
{
|
||||||
@ -1062,26 +1078,32 @@ private:
|
|||||||
}
|
}
|
||||||
void VMRGLB(u32 vd, u32 va, u32 vb)
|
void VMRGLB(u32 vd, u32 va, u32 vb)
|
||||||
{
|
{
|
||||||
|
u128 VA = CPU.VPR[va];
|
||||||
|
u128 VB = CPU.VPR[vb];
|
||||||
for (uint h = 0; h < 8; h++)
|
for (uint h = 0; h < 8; h++)
|
||||||
{
|
{
|
||||||
CPU.VPR[vd]._u8[15 - h*2] = CPU.VPR[va]._u8[7 - h];
|
CPU.VPR[vd]._u8[15 - h*2] = VA._u8[7 - h];
|
||||||
CPU.VPR[vd]._u8[15 - h*2 - 1] = CPU.VPR[vb]._u8[7 - h];
|
CPU.VPR[vd]._u8[15 - h*2 - 1] = VB._u8[7 - h];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void VMRGLH(u32 vd, u32 va, u32 vb)
|
void VMRGLH(u32 vd, u32 va, u32 vb)
|
||||||
{
|
{
|
||||||
|
u128 VA = CPU.VPR[va];
|
||||||
|
u128 VB = CPU.VPR[vb];
|
||||||
for (uint w = 0; w < 4; w++)
|
for (uint w = 0; w < 4; w++)
|
||||||
{
|
{
|
||||||
CPU.VPR[vd]._u16[7 - w*2] = CPU.VPR[va]._u16[3 - w];
|
CPU.VPR[vd]._u16[7 - w*2] = VA._u16[3 - w];
|
||||||
CPU.VPR[vd]._u16[7 - w*2 - 1] = CPU.VPR[vb]._u16[3 - w];
|
CPU.VPR[vd]._u16[7 - w*2 - 1] = VB._u16[3 - w];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void VMRGLW(u32 vd, u32 va, u32 vb)
|
void VMRGLW(u32 vd, u32 va, u32 vb)
|
||||||
{
|
{
|
||||||
|
u128 VA = CPU.VPR[va];
|
||||||
|
u128 VB = CPU.VPR[vb];
|
||||||
for (uint d = 0; d < 2; d++)
|
for (uint d = 0; d < 2; d++)
|
||||||
{
|
{
|
||||||
CPU.VPR[vd]._u32[3 - d*2] = CPU.VPR[va]._u32[1 - d];
|
CPU.VPR[vd]._u32[3 - d*2] = VA._u32[1 - d];
|
||||||
CPU.VPR[vd]._u32[3 - d*2 - 1] = CPU.VPR[vb]._u32[1 - d];
|
CPU.VPR[vd]._u32[3 - d*2 - 1] = VB._u32[1 - d];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void VMSUMMBM(u32 vd, u32 va, u32 vb, u32 vc) //nf
|
void VMSUMMBM(u32 vd, u32 va, u32 vb, u32 vc) //nf
|
||||||
@ -1152,7 +1174,7 @@ private:
|
|||||||
|
|
||||||
for (uint b = 0; b < 4; b++)
|
for (uint b = 0; b < 4; b++)
|
||||||
{
|
{
|
||||||
result += CPU.VPR[va]._u8[w*4 + b] * CPU.VPR[vb]._u8[w*4 + b];
|
result += (u32)CPU.VPR[va]._u8[w*4 + b] * (u32)CPU.VPR[vb]._u8[w*4 + b];
|
||||||
}
|
}
|
||||||
|
|
||||||
result += CPU.VPR[vc]._u32[w];
|
result += CPU.VPR[vc]._u32[w];
|
||||||
@ -1167,7 +1189,7 @@ private:
|
|||||||
|
|
||||||
for (uint h = 0; h < 2; h++)
|
for (uint h = 0; h < 2; h++)
|
||||||
{
|
{
|
||||||
result += CPU.VPR[va]._u16[w*2 + h] * CPU.VPR[vb]._u16[w*2 + h];
|
result += (u32)CPU.VPR[va]._u16[w*2 + h] * (u32)CPU.VPR[vb]._u16[w*2 + h];
|
||||||
}
|
}
|
||||||
|
|
||||||
result += CPU.VPR[vc]._u32[w];
|
result += CPU.VPR[vc]._u32[w];
|
||||||
@ -1183,7 +1205,7 @@ private:
|
|||||||
|
|
||||||
for (uint h = 0; h < 2; h++)
|
for (uint h = 0; h < 2; h++)
|
||||||
{
|
{
|
||||||
result += CPU.VPR[va]._u16[w*2 + h] * CPU.VPR[vb]._u16[w*2 + h];
|
result += (u64)CPU.VPR[va]._u16[w*2 + h] * (u64)CPU.VPR[vb]._u16[w*2 + h];
|
||||||
}
|
}
|
||||||
|
|
||||||
result += CPU.VPR[vc]._u32[w];
|
result += CPU.VPR[vc]._u32[w];
|
||||||
@ -1291,16 +1313,18 @@ private:
|
|||||||
}
|
}
|
||||||
void VPKPX(u32 vd, u32 va, u32 vb)
|
void VPKPX(u32 vd, u32 va, u32 vb)
|
||||||
{
|
{
|
||||||
|
u128 VA = CPU.VPR[va];
|
||||||
|
u128 VB = CPU.VPR[vb];
|
||||||
for (uint h = 0; h < 4; h++)
|
for (uint h = 0; h < 4; h++)
|
||||||
{
|
{
|
||||||
u16 bb7 = CPU.VPR[vb]._u8[15 - (h*4 + 0)] & 0x1;
|
u16 bb7 = VB._u8[15 - (h*4 + 0)] & 0x1;
|
||||||
u16 bb8 = CPU.VPR[vb]._u8[15 - (h*4 + 1)] >> 3;
|
u16 bb8 = VB._u8[15 - (h*4 + 1)] >> 3;
|
||||||
u16 bb16 = CPU.VPR[vb]._u8[15 - (h*4 + 2)] >> 3;
|
u16 bb16 = VB._u8[15 - (h*4 + 2)] >> 3;
|
||||||
u16 bb24 = CPU.VPR[vb]._u8[15 - (h*4 + 3)] >> 3;
|
u16 bb24 = VB._u8[15 - (h*4 + 3)] >> 3;
|
||||||
u16 ab7 = CPU.VPR[va]._u8[15 - (h*4 + 0)] & 0x1;
|
u16 ab7 = VA._u8[15 - (h*4 + 0)] & 0x1;
|
||||||
u16 ab8 = CPU.VPR[va]._u8[15 - (h*4 + 1)] >> 3;
|
u16 ab8 = VA._u8[15 - (h*4 + 1)] >> 3;
|
||||||
u16 ab16 = CPU.VPR[va]._u8[15 - (h*4 + 2)] >> 3;
|
u16 ab16 = VA._u8[15 - (h*4 + 2)] >> 3;
|
||||||
u16 ab24 = CPU.VPR[va]._u8[15 - (h*4 + 3)] >> 3;
|
u16 ab24 = VA._u8[15 - (h*4 + 3)] >> 3;
|
||||||
|
|
||||||
CPU.VPR[vd]._u16[3 - h] = (bb7 << 15) | (bb8 << 10) | (bb16 << 5) | bb24;
|
CPU.VPR[vd]._u16[3 - h] = (bb7 << 15) | (bb8 << 10) | (bb16 << 5) | bb24;
|
||||||
CPU.VPR[vd]._u16[4 + (3 - h)] = (ab7 << 15) | (ab8 << 10) | (ab16 << 5) | ab24;
|
CPU.VPR[vd]._u16[4 + (3 - h)] = (ab7 << 15) | (ab8 << 10) | (ab16 << 5) | ab24;
|
||||||
@ -1308,9 +1332,11 @@ private:
|
|||||||
}
|
}
|
||||||
void VPKSHSS(u32 vd, u32 va, u32 vb) //nf
|
void VPKSHSS(u32 vd, u32 va, u32 vb) //nf
|
||||||
{
|
{
|
||||||
|
u128 VA = CPU.VPR[va];
|
||||||
|
u128 VB = CPU.VPR[vb];
|
||||||
for (uint b = 0; b < 8; b++)
|
for (uint b = 0; b < 8; b++)
|
||||||
{
|
{
|
||||||
s16 result = CPU.VPR[va]._s16[b];
|
s16 result = VA._s16[b];
|
||||||
|
|
||||||
if (result > INT8_MAX)
|
if (result > INT8_MAX)
|
||||||
{
|
{
|
||||||
@ -1325,7 +1351,7 @@ private:
|
|||||||
|
|
||||||
CPU.VPR[vd]._s8[b+8] = (s8)result;
|
CPU.VPR[vd]._s8[b+8] = (s8)result;
|
||||||
|
|
||||||
result = CPU.VPR[vb]._s16[b];
|
result = VB._s16[b];
|
||||||
|
|
||||||
if (result > INT8_MAX)
|
if (result > INT8_MAX)
|
||||||
{
|
{
|
||||||
@ -1343,9 +1369,11 @@ private:
|
|||||||
}
|
}
|
||||||
void VPKSHUS(u32 vd, u32 va, u32 vb)
|
void VPKSHUS(u32 vd, u32 va, u32 vb)
|
||||||
{
|
{
|
||||||
|
u128 VA = CPU.VPR[va];
|
||||||
|
u128 VB = CPU.VPR[vb];
|
||||||
for (uint b = 0; b < 8; b++)
|
for (uint b = 0; b < 8; b++)
|
||||||
{
|
{
|
||||||
s16 result = CPU.VPR[va]._s16[b];
|
s16 result = VA._s16[b];
|
||||||
|
|
||||||
if (result > UINT8_MAX)
|
if (result > UINT8_MAX)
|
||||||
{
|
{
|
||||||
@ -1360,7 +1388,7 @@ private:
|
|||||||
|
|
||||||
CPU.VPR[vd]._u8[b+8] = (u8)result;
|
CPU.VPR[vd]._u8[b+8] = (u8)result;
|
||||||
|
|
||||||
result = CPU.VPR[vb]._s16[b];
|
result = VB._s16[b];
|
||||||
|
|
||||||
if (result > UINT8_MAX)
|
if (result > UINT8_MAX)
|
||||||
{
|
{
|
||||||
@ -1378,9 +1406,11 @@ private:
|
|||||||
}
|
}
|
||||||
void VPKSWSS(u32 vd, u32 va, u32 vb)
|
void VPKSWSS(u32 vd, u32 va, u32 vb)
|
||||||
{
|
{
|
||||||
|
u128 VA = CPU.VPR[va];
|
||||||
|
u128 VB = CPU.VPR[vb];
|
||||||
for (uint h = 0; h < 4; h++)
|
for (uint h = 0; h < 4; h++)
|
||||||
{
|
{
|
||||||
s32 result = CPU.VPR[va]._s32[h];
|
s32 result = VA._s32[h];
|
||||||
|
|
||||||
if (result > INT16_MAX)
|
if (result > INT16_MAX)
|
||||||
{
|
{
|
||||||
@ -1395,7 +1425,7 @@ private:
|
|||||||
|
|
||||||
CPU.VPR[vd]._s16[h+4] = result;
|
CPU.VPR[vd]._s16[h+4] = result;
|
||||||
|
|
||||||
result = CPU.VPR[vb]._s32[h];
|
result = VB._s32[h];
|
||||||
|
|
||||||
if (result > INT16_MAX)
|
if (result > INT16_MAX)
|
||||||
{
|
{
|
||||||
@ -1413,9 +1443,11 @@ private:
|
|||||||
}
|
}
|
||||||
void VPKSWUS(u32 vd, u32 va, u32 vb) //nf
|
void VPKSWUS(u32 vd, u32 va, u32 vb) //nf
|
||||||
{
|
{
|
||||||
|
u128 VA = CPU.VPR[va];
|
||||||
|
u128 VB = CPU.VPR[vb];
|
||||||
for (uint h = 0; h < 4; h++)
|
for (uint h = 0; h < 4; h++)
|
||||||
{
|
{
|
||||||
s32 result = CPU.VPR[va]._s32[h];
|
s32 result = VA._s32[h];
|
||||||
|
|
||||||
if (result > UINT16_MAX)
|
if (result > UINT16_MAX)
|
||||||
{
|
{
|
||||||
@ -1430,7 +1462,7 @@ private:
|
|||||||
|
|
||||||
CPU.VPR[vd]._u16[h+4] = result;
|
CPU.VPR[vd]._u16[h+4] = result;
|
||||||
|
|
||||||
result = CPU.VPR[vb]._s32[h];
|
result = VB._s32[h];
|
||||||
|
|
||||||
if (result > UINT16_MAX)
|
if (result > UINT16_MAX)
|
||||||
{
|
{
|
||||||
@ -1448,17 +1480,21 @@ private:
|
|||||||
}
|
}
|
||||||
void VPKUHUM(u32 vd, u32 va, u32 vb) //nf
|
void VPKUHUM(u32 vd, u32 va, u32 vb) //nf
|
||||||
{
|
{
|
||||||
|
u128 VA = CPU.VPR[va];
|
||||||
|
u128 VB = CPU.VPR[vb];
|
||||||
for (uint b = 0; b < 8; b++)
|
for (uint b = 0; b < 8; b++)
|
||||||
{
|
{
|
||||||
CPU.VPR[vd]._u8[b+8] = CPU.VPR[va]._u8[b*2];
|
CPU.VPR[vd]._u8[b+8] = VA._u8[b*2];
|
||||||
CPU.VPR[vd]._u8[b ] = CPU.VPR[vb]._u8[b*2];
|
CPU.VPR[vd]._u8[b ] = VB._u8[b*2];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void VPKUHUS(u32 vd, u32 va, u32 vb)
|
void VPKUHUS(u32 vd, u32 va, u32 vb)
|
||||||
{
|
{
|
||||||
|
u128 VA = CPU.VPR[va];
|
||||||
|
u128 VB = CPU.VPR[vb];
|
||||||
for (uint b = 0; b < 8; b++)
|
for (uint b = 0; b < 8; b++)
|
||||||
{
|
{
|
||||||
u16 result = CPU.VPR[va]._u16[b];
|
u16 result = VA._u16[b];
|
||||||
|
|
||||||
if (result > UINT8_MAX)
|
if (result > UINT8_MAX)
|
||||||
{
|
{
|
||||||
@ -1468,7 +1504,7 @@ private:
|
|||||||
|
|
||||||
CPU.VPR[vd]._u8[b+8] = (u8)result;
|
CPU.VPR[vd]._u8[b+8] = (u8)result;
|
||||||
|
|
||||||
result = CPU.VPR[vb]._u16[b];
|
result = VB._u16[b];
|
||||||
|
|
||||||
if (result > UINT8_MAX)
|
if (result > UINT8_MAX)
|
||||||
{
|
{
|
||||||
@ -1481,17 +1517,21 @@ private:
|
|||||||
}
|
}
|
||||||
void VPKUWUM(u32 vd, u32 va, u32 vb)
|
void VPKUWUM(u32 vd, u32 va, u32 vb)
|
||||||
{
|
{
|
||||||
|
u128 VA = CPU.VPR[va];
|
||||||
|
u128 VB = CPU.VPR[vb];
|
||||||
for (uint h = 0; h < 4; h++)
|
for (uint h = 0; h < 4; h++)
|
||||||
{
|
{
|
||||||
CPU.VPR[vd]._u16[h+4] = CPU.VPR[va]._u16[h*2];
|
CPU.VPR[vd]._u16[h+4] = VA._u16[h*2];
|
||||||
CPU.VPR[vd]._u16[h ] = CPU.VPR[vb]._u16[h*2];
|
CPU.VPR[vd]._u16[h ] = VB._u16[h*2];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void VPKUWUS(u32 vd, u32 va, u32 vb) //nf
|
void VPKUWUS(u32 vd, u32 va, u32 vb) //nf
|
||||||
{
|
{
|
||||||
|
u128 VA = CPU.VPR[va];
|
||||||
|
u128 VB = CPU.VPR[vb];
|
||||||
for (uint h = 0; h < 4; h++)
|
for (uint h = 0; h < 4; h++)
|
||||||
{
|
{
|
||||||
u32 result = CPU.VPR[va]._u32[h];
|
u32 result = VA._u32[h];
|
||||||
|
|
||||||
if (result > UINT16_MAX)
|
if (result > UINT16_MAX)
|
||||||
{
|
{
|
||||||
@ -1501,7 +1541,7 @@ private:
|
|||||||
|
|
||||||
CPU.VPR[vd]._u16[h+4] = result;
|
CPU.VPR[vd]._u16[h+4] = result;
|
||||||
|
|
||||||
result = CPU.VPR[vb]._u32[h];
|
result = VB._u32[h];
|
||||||
|
|
||||||
if (result > UINT16_MAX)
|
if (result > UINT16_MAX)
|
||||||
{
|
{
|
||||||
@ -1523,30 +1563,28 @@ private:
|
|||||||
{
|
{
|
||||||
for (uint w = 0; w < 4; w++)
|
for (uint w = 0; w < 4; w++)
|
||||||
{
|
{
|
||||||
CPU.VPR[vd]._f[w] = floor(CPU.VPR[vb]._f[w]);
|
CPU.VPR[vd]._f[w] = floorf(CPU.VPR[vb]._f[w]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void VRFIN(u32 vd, u32 vb)
|
void VRFIN(u32 vd, u32 vb)
|
||||||
{
|
{
|
||||||
for (uint w = 0; w < 4; w++)
|
for (uint w = 0; w < 4; w++)
|
||||||
{
|
{
|
||||||
CPU.VPR[vd]._f[w] = floor(CPU.VPR[vb]._f[w] + 0.5f);
|
CPU.VPR[vd]._f[w] = nearbyintf(CPU.VPR[vb]._f[w]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void VRFIP(u32 vd, u32 vb)
|
void VRFIP(u32 vd, u32 vb)
|
||||||
{
|
{
|
||||||
for (uint w = 0; w < 4; w++)
|
for (uint w = 0; w < 4; w++)
|
||||||
{
|
{
|
||||||
CPU.VPR[vd]._f[w] = ceil(CPU.VPR[vb]._f[w]);
|
CPU.VPR[vd]._f[w] = ceilf(CPU.VPR[vb]._f[w]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void VRFIZ(u32 vd, u32 vb)
|
void VRFIZ(u32 vd, u32 vb)
|
||||||
{
|
{
|
||||||
for (uint w = 0; w < 4; w++)
|
for (uint w = 0; w < 4; w++)
|
||||||
{
|
{
|
||||||
float f;
|
CPU.VPR[vd]._f[w] = truncf(CPU.VPR[vb]._f[w]);
|
||||||
modff(CPU.VPR[vb]._f[w], &f);
|
|
||||||
CPU.VPR[vd]._f[w] = f;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void VRLB(u32 vd, u32 va, u32 vb) //nf
|
void VRLB(u32 vd, u32 va, u32 vb) //nf
|
||||||
@ -1589,12 +1627,13 @@ private:
|
|||||||
}
|
}
|
||||||
void VSL(u32 vd, u32 va, u32 vb) //nf
|
void VSL(u32 vd, u32 va, u32 vb) //nf
|
||||||
{
|
{
|
||||||
|
u128 VA = CPU.VPR[va];
|
||||||
u8 sh = CPU.VPR[vb]._u8[0] & 0x7;
|
u8 sh = CPU.VPR[vb]._u8[0] & 0x7;
|
||||||
|
|
||||||
CPU.VPR[vd]._u8[0] = CPU.VPR[va]._u8[0] << sh;
|
CPU.VPR[vd]._u8[0] = VA._u8[0] << sh;
|
||||||
for (uint b = 1; b < 16; b++)
|
for (uint b = 1; b < 16; b++)
|
||||||
{
|
{
|
||||||
CPU.VPR[vd]._u8[b] = (CPU.VPR[va]._u8[b] << sh) | (CPU.VPR[va]._u8[b-1] >> (8 - sh));
|
CPU.VPR[vd]._u8[b] = (VA._u8[b] << sh) | (VA._u8[b-1] >> (8 - sh));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void VSLB(u32 vd, u32 va, u32 vb)
|
void VSLB(u32 vd, u32 va, u32 vb)
|
||||||
@ -1619,18 +1658,19 @@ private:
|
|||||||
{
|
{
|
||||||
for (uint h = 0; h < 8; h++)
|
for (uint h = 0; h < 8; h++)
|
||||||
{
|
{
|
||||||
CPU.VPR[vd]._u16[h] = CPU.VPR[va]._u16[h] << (CPU.VPR[vb]._u8[h*2] & 0xf);
|
CPU.VPR[vd]._u16[h] = CPU.VPR[va]._u16[h] << (CPU.VPR[vb]._u16[h] & 0xf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void VSLO(u32 vd, u32 va, u32 vb)
|
void VSLO(u32 vd, u32 va, u32 vb)
|
||||||
{
|
{
|
||||||
|
u128 VA = CPU.VPR[va];
|
||||||
u8 nShift = (CPU.VPR[vb]._u8[0] >> 3) & 0xf;
|
u8 nShift = (CPU.VPR[vb]._u8[0] >> 3) & 0xf;
|
||||||
|
|
||||||
CPU.VPR[vd].clear();
|
CPU.VPR[vd].clear();
|
||||||
|
|
||||||
for (u8 b = 0; b < 16 - nShift; b++)
|
for (u8 b = 0; b < 16 - nShift; b++)
|
||||||
{
|
{
|
||||||
CPU.VPR[vd]._u8[15 - b] = CPU.VPR[va]._u8[15 - (b + nShift)];
|
CPU.VPR[vd]._u8[15 - b] = VA._u8[15 - (b + nShift)];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void VSLW(u32 vd, u32 va, u32 vb)
|
void VSLW(u32 vd, u32 va, u32 vb)
|
||||||
@ -1694,12 +1734,13 @@ private:
|
|||||||
}
|
}
|
||||||
void VSR(u32 vd, u32 va, u32 vb) //nf
|
void VSR(u32 vd, u32 va, u32 vb) //nf
|
||||||
{
|
{
|
||||||
|
u128 VA = CPU.VPR[va];
|
||||||
u8 sh = CPU.VPR[vb]._u8[0] & 0x7;
|
u8 sh = CPU.VPR[vb]._u8[0] & 0x7;
|
||||||
|
|
||||||
CPU.VPR[vd]._u8[15] = CPU.VPR[va]._u8[15] >> sh;
|
CPU.VPR[vd]._u8[15] = VA._u8[15] >> sh;
|
||||||
for (uint b = 14; ~b; b--)
|
for (uint b = 14; ~b; b--)
|
||||||
{
|
{
|
||||||
CPU.VPR[vd]._u8[b] = (CPU.VPR[va]._u8[b] >> sh) | (CPU.VPR[va]._u8[b+1] << (8 - sh));
|
CPU.VPR[vd]._u8[b] = (VA._u8[b] >> sh) | (VA._u8[b+1] << (8 - sh));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void VSRAB(u32 vd, u32 va, u32 vb) //nf
|
void VSRAB(u32 vd, u32 va, u32 vb) //nf
|
||||||
@ -1713,14 +1754,14 @@ private:
|
|||||||
{
|
{
|
||||||
for (uint h = 0; h < 8; h++)
|
for (uint h = 0; h < 8; h++)
|
||||||
{
|
{
|
||||||
CPU.VPR[vd]._s16[h] = CPU.VPR[va]._s16[h] >> (CPU.VPR[vb]._u8[h*2] & 0xf);
|
CPU.VPR[vd]._s16[h] = CPU.VPR[va]._s16[h] >> (CPU.VPR[vb]._u16[h] & 0xf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void VSRAW(u32 vd, u32 va, u32 vb)
|
void VSRAW(u32 vd, u32 va, u32 vb)
|
||||||
{
|
{
|
||||||
for (uint w = 0; w < 4; w++)
|
for (uint w = 0; w < 4; w++)
|
||||||
{
|
{
|
||||||
CPU.VPR[vd]._s32[w] = CPU.VPR[va]._s32[w] >> (CPU.VPR[vb]._u8[w*4] & 0x1f);
|
CPU.VPR[vd]._s32[w] = CPU.VPR[va]._s32[w] >> (CPU.VPR[vb]._u32[w] & 0x1f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void VSRB(u32 vd, u32 va, u32 vb)
|
void VSRB(u32 vd, u32 va, u32 vb)
|
||||||
@ -1734,25 +1775,26 @@ private:
|
|||||||
{
|
{
|
||||||
for (uint h = 0; h < 8; h++)
|
for (uint h = 0; h < 8; h++)
|
||||||
{
|
{
|
||||||
CPU.VPR[vd]._u16[h] = CPU.VPR[va]._u16[h] >> (CPU.VPR[vb]._u8[h*2] & 0xf);
|
CPU.VPR[vd]._u16[h] = CPU.VPR[va]._u16[h] >> (CPU.VPR[vb]._u16[h] & 0xf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void VSRO(u32 vd, u32 va, u32 vb)
|
void VSRO(u32 vd, u32 va, u32 vb)
|
||||||
{
|
{
|
||||||
|
u128 VA = CPU.VPR[va];
|
||||||
u8 nShift = (CPU.VPR[vb]._u8[0] >> 3) & 0xf;
|
u8 nShift = (CPU.VPR[vb]._u8[0] >> 3) & 0xf;
|
||||||
|
|
||||||
CPU.VPR[vd].clear();
|
CPU.VPR[vd].clear();
|
||||||
|
|
||||||
for (u8 b = 0; b < 16 - nShift; b++)
|
for (u8 b = 0; b < 16 - nShift; b++)
|
||||||
{
|
{
|
||||||
CPU.VPR[vd]._u8[b] = CPU.VPR[va]._u8[b + nShift];
|
CPU.VPR[vd]._u8[b] = VA._u8[b + nShift];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void VSRW(u32 vd, u32 va, u32 vb)
|
void VSRW(u32 vd, u32 va, u32 vb)
|
||||||
{
|
{
|
||||||
for (uint w = 0; w < 4; w++)
|
for (uint w = 0; w < 4; w++)
|
||||||
{
|
{
|
||||||
CPU.VPR[vd]._u32[w] = CPU.VPR[va]._u32[w] >> (CPU.VPR[vb]._u8[w*4] & 0x1f);
|
CPU.VPR[vd]._u32[w] = CPU.VPR[va]._u32[w] >> (CPU.VPR[vb]._u32[w] & 0x1f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void VSUBCUW(u32 vd, u32 va, u32 vb) //nf
|
void VSUBCUW(u32 vd, u32 va, u32 vb) //nf
|
||||||
@ -2013,50 +2055,56 @@ private:
|
|||||||
}
|
}
|
||||||
void VUPKHPX(u32 vd, u32 vb)
|
void VUPKHPX(u32 vd, u32 vb)
|
||||||
{
|
{
|
||||||
|
u128 VB = CPU.VPR[vb];
|
||||||
for (uint w = 0; w < 4; w++)
|
for (uint w = 0; w < 4; w++)
|
||||||
{
|
{
|
||||||
CPU.VPR[vd]._s8[(3 - w)*4 + 3] = CPU.VPR[vb]._s8[w*2 + 0] >> 7; // signed shift sign extends
|
CPU.VPR[vd]._s8[w*4 + 3] = VB._s8[8 + w*2 + 1] >> 7; // signed shift sign extends
|
||||||
CPU.VPR[vd]._u8[(3 - w)*4 + 2] = (CPU.VPR[vb]._u8[w*2 + 0] >> 2) & 0x1f;
|
CPU.VPR[vd]._u8[w*4 + 2] = (VB._u8[8 + w*2 + 1] >> 2) & 0x1f;
|
||||||
CPU.VPR[vd]._u8[(3 - w)*4 + 1] = ((CPU.VPR[vb]._u8[w*2 + 0] & 0x3) << 3) | ((CPU.VPR[vb]._u8[w*2 + 1] >> 5) & 0x7);
|
CPU.VPR[vd]._u8[w*4 + 1] = ((VB._u8[8 + w*2 + 1] & 0x3) << 3) | ((VB._u8[8 + w*2 + 0] >> 5) & 0x7);
|
||||||
CPU.VPR[vd]._u8[(3 - w)*4 + 0] = CPU.VPR[vb]._u8[w*2 + 1] & 0x1f;
|
CPU.VPR[vd]._u8[w*4 + 0] = VB._u8[8 + w*2 + 0] & 0x1f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void VUPKHSB(u32 vd, u32 vb)
|
void VUPKHSB(u32 vd, u32 vb)
|
||||||
{
|
{
|
||||||
|
u128 VB = CPU.VPR[vb];
|
||||||
for (uint h = 0; h < 8; h++)
|
for (uint h = 0; h < 8; h++)
|
||||||
{
|
{
|
||||||
CPU.VPR[vd]._s16[h] = CPU.VPR[vb]._s8[h];
|
CPU.VPR[vd]._s16[h] = VB._s8[8 + h];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void VUPKHSH(u32 vd, u32 vb)
|
void VUPKHSH(u32 vd, u32 vb)
|
||||||
{
|
{
|
||||||
|
u128 VB = CPU.VPR[vb];
|
||||||
for (uint w = 0; w < 4; w++)
|
for (uint w = 0; w < 4; w++)
|
||||||
{
|
{
|
||||||
CPU.VPR[vd]._s32[w] = CPU.VPR[vb]._s16[w];
|
CPU.VPR[vd]._s32[w] = VB._s16[4 + w];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void VUPKLPX(u32 vd, u32 vb)
|
void VUPKLPX(u32 vd, u32 vb)
|
||||||
{
|
{
|
||||||
|
u128 VB = CPU.VPR[vb];
|
||||||
for (uint w = 0; w < 4; w++)
|
for (uint w = 0; w < 4; w++)
|
||||||
{
|
{
|
||||||
CPU.VPR[vd]._s8[(3 - w)*4 + 3] = CPU.VPR[vb]._s8[8 + w*2 + 0] >> 7; // signed shift sign extends
|
CPU.VPR[vd]._s8[w*4 + 3] = VB._s8[w*2 + 1] >> 7; // signed shift sign extends
|
||||||
CPU.VPR[vd]._u8[(3 - w)*4 + 2] = (CPU.VPR[vb]._u8[8 + w*2 + 0] >> 2) & 0x1f;
|
CPU.VPR[vd]._u8[w*4 + 2] = (VB._u8[w*2 + 1] >> 2) & 0x1f;
|
||||||
CPU.VPR[vd]._u8[(3 - w)*4 + 1] = ((CPU.VPR[vb]._u8[8 + w*2 + 0] & 0x3) << 3) | ((CPU.VPR[vb]._u8[8 + w*2 + 1] >> 5) & 0x7);
|
CPU.VPR[vd]._u8[w*4 + 1] = ((VB._u8[w*2 + 1] & 0x3) << 3) | ((VB._u8[w*2 + 0] >> 5) & 0x7);
|
||||||
CPU.VPR[vd]._u8[(3 - w)*4 + 0] = CPU.VPR[vb]._u8[8 + w*2 + 1] & 0x1f;
|
CPU.VPR[vd]._u8[w*4 + 0] = VB._u8[w*2 + 0] & 0x1f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void VUPKLSB(u32 vd, u32 vb) //nf
|
void VUPKLSB(u32 vd, u32 vb) //nf
|
||||||
{
|
{
|
||||||
|
u128 VB = CPU.VPR[vb];
|
||||||
for (uint h = 0; h < 8; h++)
|
for (uint h = 0; h < 8; h++)
|
||||||
{
|
{
|
||||||
CPU.VPR[vd]._s16[h] = CPU.VPR[vb]._s8[8 + h];
|
CPU.VPR[vd]._s16[h] = VB._s8[h];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void VUPKLSH(u32 vd, u32 vb)
|
void VUPKLSH(u32 vd, u32 vb)
|
||||||
{
|
{
|
||||||
|
u128 VB = CPU.VPR[vb];
|
||||||
for (uint w = 0; w < 4; w++)
|
for (uint w = 0; w < 4; w++)
|
||||||
{
|
{
|
||||||
CPU.VPR[vd]._s32[w] = CPU.VPR[vb]._s16[4 + w];
|
CPU.VPR[vd]._s32[w] = VB._s16[w];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void VXOR(u32 vd, u32 va, u32 vb)
|
void VXOR(u32 vd, u32 va, u32 vb)
|
||||||
@ -4064,7 +4112,7 @@ private:
|
|||||||
}
|
}
|
||||||
void MTFSB1(u32 crbd, bool rc)
|
void MTFSB1(u32 crbd, bool rc)
|
||||||
{
|
{
|
||||||
u64 mask = (1ULL << crbd);
|
u64 mask = (1ULL << (31 - crbd));
|
||||||
if ((crbd == 29) && !CPU.FPSCR.NI) LOG_WARNING(PPU, "Non-IEEE mode enabled");
|
if ((crbd == 29) && !CPU.FPSCR.NI) LOG_WARNING(PPU, "Non-IEEE mode enabled");
|
||||||
CPU.FPSCR.FPSCR |= mask;
|
CPU.FPSCR.FPSCR |= mask;
|
||||||
|
|
||||||
@ -4072,13 +4120,32 @@ private:
|
|||||||
}
|
}
|
||||||
void MCRFS(u32 crbd, u32 crbs)
|
void MCRFS(u32 crbd, u32 crbs)
|
||||||
{
|
{
|
||||||
u64 mask = (1ULL << crbd);
|
CPU.SetCR(crbd, (CPU.FPSCR.FPSCR >> ((7 - crbs) * 4)) & 0xf);
|
||||||
CPU.CR.CR &= ~mask;
|
|
||||||
CPU.CR.CR |= CPU.FPSCR.FPSCR & mask;
|
switch (crbs)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
CPU.FPSCR.FX = CPU.FPSCR.OX = 0;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
CPU.FPSCR.UX = CPU.FPSCR.ZX = CPU.FPSCR.XX = CPU.FPSCR.VXSNAN = 0;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
CPU.FPSCR.VXISI = CPU.FPSCR.VXIDI = CPU.FPSCR.VXZDZ = CPU.FPSCR.VXIMZ = 0;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
CPU.FPSCR.VXVC = 0;
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
CPU.FPSCR.VXSOFT = CPU.FPSCR.VXSQRT = CPU.FPSCR.VXCVI = 0;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
void MTFSB0(u32 crbd, bool rc)
|
void MTFSB0(u32 crbd, bool rc)
|
||||||
{
|
{
|
||||||
u64 mask = (1ULL << crbd);
|
u64 mask = (1ULL << (31 - crbd));
|
||||||
if ((crbd == 29) && !CPU.FPSCR.NI) LOG_WARNING(PPU, "Non-IEEE mode disabled");
|
if ((crbd == 29) && !CPU.FPSCR.NI) LOG_WARNING(PPU, "Non-IEEE mode disabled");
|
||||||
CPU.FPSCR.FPSCR &= ~mask;
|
CPU.FPSCR.FPSCR &= ~mask;
|
||||||
|
|
||||||
@ -4086,17 +4153,18 @@ private:
|
|||||||
}
|
}
|
||||||
void MTFSFI(u32 crfd, u32 i, bool rc)
|
void MTFSFI(u32 crfd, u32 i, bool rc)
|
||||||
{
|
{
|
||||||
u64 mask = (0x1ULL << crfd);
|
u32 mask = 0xF0000000 >> (crfd * 4);
|
||||||
|
u32 val = (i & 0xF) << ((7 - crfd) * 4);
|
||||||
|
|
||||||
if(i)
|
const u32 oldNI = CPU.FPSCR.NI;
|
||||||
|
CPU.FPSCR.FPSCR &= ~mask;
|
||||||
|
CPU.FPSCR.FPSCR |= val;
|
||||||
|
if (CPU.FPSCR.NI != oldNI)
|
||||||
{
|
{
|
||||||
if ((crfd == 29) && !CPU.FPSCR.NI) LOG_WARNING(PPU, "Non-IEEE mode enabled");
|
if (oldNI)
|
||||||
CPU.FPSCR.FPSCR |= mask;
|
LOG_WARNING(PPU, "Non-IEEE mode disabled");
|
||||||
}
|
else
|
||||||
else
|
LOG_WARNING(PPU, "Non-IEEE mode enabled");
|
||||||
{
|
|
||||||
if ((crfd == 29) && CPU.FPSCR.NI) LOG_WARNING(PPU, "Non-IEEE mode disabled");
|
|
||||||
CPU.FPSCR.FPSCR &= ~mask;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(rc) UNIMPLEMENTED();
|
if(rc) UNIMPLEMENTED();
|
||||||
@ -4210,9 +4278,7 @@ private:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
(u64&)CPU.FPR[frd] = 0xfff8000000000000ull | r;
|
(u64&)CPU.FPR[frd] = r;
|
||||||
if(r == 0 && ( (u64&)b & DOUBLE_SIGN )) (u64&)CPU.FPR[frd] |= 0x100000000ull;
|
|
||||||
|
|
||||||
if(rc) UNK("fctiw.");
|
if(rc) UNK("fctiw.");
|
||||||
}
|
}
|
||||||
void FCTIWZ(u32 frd, u32 frb, bool rc)
|
void FCTIWZ(u32 frd, u32 frb, bool rc)
|
||||||
@ -4250,10 +4316,7 @@ private:
|
|||||||
value = (u32)i;
|
value = (u32)i;
|
||||||
}
|
}
|
||||||
|
|
||||||
(u64&)CPU.FPR[frd] = 0xfff8000000000000ull | value;
|
(u64&)CPU.FPR[frd] = (u64)value;
|
||||||
if (value == 0 && ( (u64&)b & DOUBLE_SIGN ))
|
|
||||||
(u64&)CPU.FPR[frd] |= 0x100000000ull;
|
|
||||||
|
|
||||||
if(rc) UNK("fctiwz.");
|
if(rc) UNK("fctiwz.");
|
||||||
}
|
}
|
||||||
void FDIV(u32 frd, u32 fra, u32 frb, bool rc)
|
void FDIV(u32 frd, u32 fra, u32 frb, bool rc)
|
||||||
@ -4351,7 +4414,7 @@ private:
|
|||||||
{
|
{
|
||||||
CPU.SetFPSCRException(FPSCR_ZX);
|
CPU.SetFPSCRException(FPSCR_ZX);
|
||||||
}
|
}
|
||||||
CPU.FPR[frd] = static_cast<float>(1.0 / sqrt(CPU.FPR[frb]));
|
CPU.FPR[frd] = 1.0 / sqrt(CPU.FPR[frb]);
|
||||||
if(rc) UNK("frsqrte.");//CPU.UpdateCR1(CPU.FPR[frd]);
|
if(rc) UNK("frsqrte.");//CPU.UpdateCR1(CPU.FPR[frd]);
|
||||||
}
|
}
|
||||||
void FMSUB(u32 frd, u32 fra, u32 frc, u32 frb, bool rc)
|
void FMSUB(u32 frd, u32 fra, u32 frc, u32 frb, bool rc)
|
||||||
@ -4476,9 +4539,7 @@ private:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
(u64&)CPU.FPR[frd] = 0xfff8000000000000ull | r;
|
(u64&)CPU.FPR[frd] = r;
|
||||||
if(r == 0 && ( (u64&)b & DOUBLE_SIGN )) (u64&)CPU.FPR[frd] |= 0x100000000ull;
|
|
||||||
|
|
||||||
if(rc) UNK("fctid.");
|
if(rc) UNK("fctid.");
|
||||||
}
|
}
|
||||||
void FCTIDZ(u32 frd, u32 frb, bool rc)
|
void FCTIDZ(u32 frd, u32 frb, bool rc)
|
||||||
@ -4516,9 +4577,7 @@ private:
|
|||||||
r = (u64)i;
|
r = (u64)i;
|
||||||
}
|
}
|
||||||
|
|
||||||
(u64&)CPU.FPR[frd] = 0xfff8000000000000ull | r;
|
(u64&)CPU.FPR[frd] = r;
|
||||||
if(r == 0 && ( (u64&)b & DOUBLE_SIGN )) (u64&)CPU.FPR[frd] |= 0x100000000ull;
|
|
||||||
|
|
||||||
if(rc) UNK("fctidz.");
|
if(rc) UNK("fctidz.");
|
||||||
}
|
}
|
||||||
void FCFID(u32 frd, u32 frb, bool rc)
|
void FCFID(u32 frd, u32 frb, bool rc)
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -214,7 +214,7 @@ namespace ppu_recompiler_llvm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string ToString() const {
|
std::string ToString() const {
|
||||||
auto s = fmt::Format("0x%08X (0x%08X):", start_address, function_address);
|
auto s = fmt::Format("0x%08X (0x%08X): Size=%u ->", start_address, function_address, GetSize());
|
||||||
for (auto i = instruction_addresses.begin(); i != instruction_addresses.end(); i++) {
|
for (auto i = instruction_addresses.begin(); i != instruction_addresses.end(); i++) {
|
||||||
s += fmt::Format(" 0x%08X", *i);
|
s += fmt::Format(" 0x%08X", *i);
|
||||||
}
|
}
|
||||||
@ -237,6 +237,12 @@ namespace ppu_recompiler_llvm {
|
|||||||
|
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the size of the CFG. The size is a score of how large the CFG is and increases everytime
|
||||||
|
/// a node or an edge is added to the CFG.
|
||||||
|
size_t GetSize() const {
|
||||||
|
return instruction_addresses.size() + branches.size() + calls.size();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class BranchType {
|
enum class BranchType {
|
||||||
@ -247,7 +253,7 @@ namespace ppu_recompiler_llvm {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/// Pointer to an executable
|
/// Pointer to an executable
|
||||||
typedef u32(*Executable)(PPUThread * ppu_state, PPUInterpreter * interpreter, u64 context);
|
typedef u32(*Executable)(PPUThread * ppu_state, u64 context);
|
||||||
|
|
||||||
/// PPU compiler that uses LLVM for code generation and optimization
|
/// PPU compiler that uses LLVM for code generation and optimization
|
||||||
class Compiler : protected PPUOpcodes, protected PPCDecoder {
|
class Compiler : protected PPUOpcodes, protected PPCDecoder {
|
||||||
@ -264,9 +270,6 @@ namespace ppu_recompiler_llvm {
|
|||||||
|
|
||||||
/// Total time
|
/// Total time
|
||||||
std::chrono::nanoseconds total_time;
|
std::chrono::nanoseconds total_time;
|
||||||
|
|
||||||
/// Contains the number of times interpreter fallback was used
|
|
||||||
std::map<std::string, u64> interpreter_fallback_stats;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Compiler(RecompilationEngine & recompilation_engine, const Executable execute_unknown_function, const Executable execute_unknown_block);
|
Compiler(RecompilationEngine & recompilation_engine, const Executable execute_unknown_function, const Executable execute_unknown_block);
|
||||||
@ -289,7 +292,7 @@ namespace ppu_recompiler_llvm {
|
|||||||
Stats GetStats();
|
Stats GetStats();
|
||||||
|
|
||||||
/// Execute all tests
|
/// Execute all tests
|
||||||
void RunAllTests(PPUThread * ppu_state, PPUInterpreter * interpreter);
|
void RunAllTests();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void Decode(const u32 code) override;
|
void Decode(const u32 code) override;
|
||||||
@ -699,7 +702,6 @@ namespace ppu_recompiler_llvm {
|
|||||||
struct CompileTaskState {
|
struct CompileTaskState {
|
||||||
enum Args {
|
enum Args {
|
||||||
State,
|
State,
|
||||||
Interpreter,
|
|
||||||
Context,
|
Context,
|
||||||
MaxArgs,
|
MaxArgs,
|
||||||
};
|
};
|
||||||
@ -863,6 +865,12 @@ namespace ppu_recompiler_llvm {
|
|||||||
/// Set USPRG0
|
/// Set USPRG0
|
||||||
void SetUsprg0(llvm::Value * val_x64);
|
void SetUsprg0(llvm::Value * val_x64);
|
||||||
|
|
||||||
|
/// Load FPSCR
|
||||||
|
llvm::Value * GetFpscr();
|
||||||
|
|
||||||
|
/// Set FPSCR
|
||||||
|
void SetFpscr(llvm::Value * val_x32);
|
||||||
|
|
||||||
/// Get FPR
|
/// Get FPR
|
||||||
llvm::Value * GetFpr(u32 r, u32 bits = 64, bool as_int = false);
|
llvm::Value * GetFpr(u32 r, u32 bits = 64, bool as_int = false);
|
||||||
|
|
||||||
@ -902,10 +910,6 @@ namespace ppu_recompiler_llvm {
|
|||||||
/// Write to memory
|
/// Write to memory
|
||||||
void WriteMemory(llvm::Value * addr_i64, llvm::Value * val_ix, u32 alignment = 0, bool bswap = true, bool could_be_mmio = true);
|
void WriteMemory(llvm::Value * addr_i64, llvm::Value * val_ix, u32 alignment = 0, bool bswap = true, bool could_be_mmio = true);
|
||||||
|
|
||||||
/// Call an interpreter function
|
|
||||||
template<class Func, class... Args>
|
|
||||||
llvm::Value * InterpreterCall(const char * name, Func function, Args... args);
|
|
||||||
|
|
||||||
/// Convert a C++ type to an LLVM type
|
/// Convert a C++ type to an LLVM type
|
||||||
template<class T>
|
template<class T>
|
||||||
llvm::Type * CppToLlvmType();
|
llvm::Type * CppToLlvmType();
|
||||||
@ -924,6 +928,9 @@ namespace ppu_recompiler_llvm {
|
|||||||
/// Excute a test
|
/// Excute a test
|
||||||
void RunTest(const char * name, std::function<void()> test_case, std::function<void()> input, std::function<bool(std::string & msg)> check_result);
|
void RunTest(const char * name, std::function<void()> test_case, std::function<void()> input, std::function<bool(std::string & msg)> check_result);
|
||||||
|
|
||||||
|
/// Handle compilation errors
|
||||||
|
void CompilationError(const std::string & error);
|
||||||
|
|
||||||
/// A mask used in rotate instructions
|
/// A mask used in rotate instructions
|
||||||
static u64 s_rotate_mask[64][64];
|
static u64 s_rotate_mask[64][64];
|
||||||
|
|
||||||
@ -970,6 +977,9 @@ namespace ppu_recompiler_llvm {
|
|||||||
/// The current revision number of this function
|
/// The current revision number of this function
|
||||||
u32 revision;
|
u32 revision;
|
||||||
|
|
||||||
|
/// Size of the CFG when it was last compiled
|
||||||
|
size_t last_compiled_cfg_size;
|
||||||
|
|
||||||
/// The CFG for this block
|
/// The CFG for this block
|
||||||
ControlFlowGraph cfg;
|
ControlFlowGraph cfg;
|
||||||
|
|
||||||
@ -979,13 +989,14 @@ namespace ppu_recompiler_llvm {
|
|||||||
BlockEntry(u32 start_address, u32 function_address)
|
BlockEntry(u32 start_address, u32 function_address)
|
||||||
: num_hits(0)
|
: num_hits(0)
|
||||||
, revision(0)
|
, revision(0)
|
||||||
|
, last_compiled_cfg_size(0)
|
||||||
, is_compiled(false)
|
, is_compiled(false)
|
||||||
, cfg(start_address, function_address) {
|
, cfg(start_address, function_address) {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string ToString() const {
|
std::string ToString() const {
|
||||||
return fmt::Format("0x%08X (0x%08X): NumHits=%u, Revision=%u, IsCompiled=%c",
|
return fmt::Format("0x%08X (0x%08X): NumHits=%u, Revision=%u, LastCompiledCfgSize=%u, IsCompiled=%c",
|
||||||
cfg.start_address, cfg.function_address, num_hits, revision, is_compiled ? 'Y' : 'N');
|
cfg.start_address, cfg.function_address, num_hits, revision, last_compiled_cfg_size, is_compiled ? 'Y' : 'N');
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator == (const BlockEntry & other) const {
|
bool operator == (const BlockEntry & other) const {
|
||||||
@ -1009,54 +1020,8 @@ namespace ppu_recompiler_llvm {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
/// An entry in the function table
|
/// Log
|
||||||
struct FunctionEntry {
|
llvm::raw_fd_ostream * m_log;
|
||||||
/// Address of the function
|
|
||||||
u32 address;
|
|
||||||
|
|
||||||
/// Number of compiled fragments
|
|
||||||
u32 num_compiled_fragments;
|
|
||||||
|
|
||||||
/// Blocks in the function
|
|
||||||
std::list<BlockEntry *> blocks;
|
|
||||||
|
|
||||||
FunctionEntry(u32 address)
|
|
||||||
: address(address)
|
|
||||||
, num_compiled_fragments(0) {
|
|
||||||
}
|
|
||||||
|
|
||||||
void AddBlock(BlockEntry * block_entry) {
|
|
||||||
auto i = std::find(blocks.begin(), blocks.end(), block_entry);
|
|
||||||
if (i == blocks.end()) {
|
|
||||||
if (block_entry->IsFunction()) {
|
|
||||||
// The first block must be the starting block of the function
|
|
||||||
blocks.push_front(block_entry);
|
|
||||||
} else {
|
|
||||||
blocks.push_back(block_entry);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string ToString() const {
|
|
||||||
return fmt::Format("0x%08X: NumCompiledFragments=%u, NumBlocks=%u", address, num_compiled_fragments, blocks.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator == (const FunctionEntry & other) const {
|
|
||||||
return address == other.address;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct hash {
|
|
||||||
size_t operator()(const FunctionEntry * f) const {
|
|
||||||
return f->address;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct equal_to {
|
|
||||||
bool operator()(const FunctionEntry * lhs, const FunctionEntry * rhs) const {
|
|
||||||
return *lhs == *rhs;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Lock for accessing m_pending_execution_traces. TODO: Eliminate this and use a lock-free queue.
|
/// Lock for accessing m_pending_execution_traces. TODO: Eliminate this and use a lock-free queue.
|
||||||
std::mutex m_pending_execution_traces_lock;
|
std::mutex m_pending_execution_traces_lock;
|
||||||
@ -1067,9 +1032,6 @@ namespace ppu_recompiler_llvm {
|
|||||||
/// Block table
|
/// Block table
|
||||||
std::unordered_set<BlockEntry *, BlockEntry::hash, BlockEntry::equal_to> m_block_table;
|
std::unordered_set<BlockEntry *, BlockEntry::hash, BlockEntry::equal_to> m_block_table;
|
||||||
|
|
||||||
/// Function table
|
|
||||||
std::unordered_set<FunctionEntry *, FunctionEntry::hash, FunctionEntry::equal_to> m_function_table;
|
|
||||||
|
|
||||||
/// Execution traces that have been already encountered. Data is the list of all blocks that this trace includes.
|
/// Execution traces that have been already encountered. Data is the list of all blocks that this trace includes.
|
||||||
std::unordered_map<ExecutionTrace::Id, std::vector<BlockEntry *>> m_processed_execution_traces;
|
std::unordered_map<ExecutionTrace::Id, std::vector<BlockEntry *>> m_processed_execution_traces;
|
||||||
|
|
||||||
@ -1086,9 +1048,6 @@ namespace ppu_recompiler_llvm {
|
|||||||
/// PPU Compiler
|
/// PPU Compiler
|
||||||
Compiler m_compiler;
|
Compiler m_compiler;
|
||||||
|
|
||||||
/// Log
|
|
||||||
llvm::raw_fd_ostream * m_log;
|
|
||||||
|
|
||||||
/// Executable lookup table
|
/// Executable lookup table
|
||||||
Executable m_executable_lookup[10000]; // TODO: Adjust size
|
Executable m_executable_lookup[10000]; // TODO: Adjust size
|
||||||
|
|
||||||
@ -1107,7 +1066,7 @@ namespace ppu_recompiler_llvm {
|
|||||||
void UpdateControlFlowGraph(ControlFlowGraph & cfg, const ExecutionTraceEntry & this_entry, const ExecutionTraceEntry * next_entry);
|
void UpdateControlFlowGraph(ControlFlowGraph & cfg, const ExecutionTraceEntry & this_entry, const ExecutionTraceEntry * next_entry);
|
||||||
|
|
||||||
/// Compile a block
|
/// Compile a block
|
||||||
void CompileBlock(FunctionEntry & function_entry, BlockEntry & block_entry);
|
void CompileBlock(BlockEntry & block_entry);
|
||||||
|
|
||||||
/// Mutex used to prevent multiple creation
|
/// Mutex used to prevent multiple creation
|
||||||
static std::mutex s_mutex;
|
static std::mutex s_mutex;
|
||||||
@ -1199,10 +1158,10 @@ namespace ppu_recompiler_llvm {
|
|||||||
Executable GetExecutable(u32 address, Executable default_executable) const;
|
Executable GetExecutable(u32 address, Executable default_executable) const;
|
||||||
|
|
||||||
/// Execute a function
|
/// Execute a function
|
||||||
static u32 ExecuteFunction(PPUThread * ppu_state, PPUInterpreter * interpreter, u64 context);
|
static u32 ExecuteFunction(PPUThread * ppu_state, u64 context);
|
||||||
|
|
||||||
/// Execute till the current function returns
|
/// Execute till the current function returns
|
||||||
static u32 ExecuteTillReturn(PPUThread * ppu_state, PPUInterpreter * interpreter, u64 context);
|
static u32 ExecuteTillReturn(PPUThread * ppu_state, u64 context);
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Get the branch type from a branch instruction
|
/// Get the branch type from a branch instruction
|
||||||
|
@ -63,7 +63,7 @@ VerifyInstructionAgainstInterpreter(fmt::Format("%s.%d", #fn, tc).c_str(), &Comp
|
|||||||
u64 R_ADDR;
|
u64 R_ADDR;
|
||||||
u64 R_VALUE;
|
u64 R_VALUE;
|
||||||
|
|
||||||
/// Mmeory block
|
/// Memory block
|
||||||
u32 address;
|
u32 address;
|
||||||
u64 mem_block[64];
|
u64 mem_block[64];
|
||||||
|
|
||||||
@ -130,9 +130,9 @@ VerifyInstructionAgainstInterpreter(fmt::Format("%s.%d", #fn, tc).c_str(), &Comp
|
|||||||
FPR[i] = (double)rng();
|
FPR[i] = (double)rng();
|
||||||
GPR[i] = rng();
|
GPR[i] = rng();
|
||||||
VPR[i]._f[0] = (float)rng();
|
VPR[i]._f[0] = (float)rng();
|
||||||
VPR[i]._f[1] = (float)rng();
|
VPR[i]._f[1] = (float)(rng() & 0x7FFFFFFF);
|
||||||
VPR[i]._f[2] = (float)rng();
|
VPR[i]._f[2] = -(float)(rng() & 0x7FFFFFFF);
|
||||||
VPR[i]._f[3] = (float)rng();
|
VPR[i]._f[3] = -(float)rng();
|
||||||
|
|
||||||
if (i < 8) {
|
if (i < 8) {
|
||||||
SPRG[i] = rng();
|
SPRG[i] = rng();
|
||||||
@ -164,7 +164,7 @@ VerifyInstructionAgainstInterpreter(fmt::Format("%s.%d", #fn, tc).c_str(), &Comp
|
|||||||
std::string ret;
|
std::string ret;
|
||||||
|
|
||||||
for (int i = 0; i < 32; i++) {
|
for (int i = 0; i < 32; i++) {
|
||||||
ret += fmt::Format("GPR[%02d] = 0x%016llx FPR[%02d] = %16g VPR[%02d] = 0x%s [%s]\n", i, GPR[i], i, FPR[i]._double, i, VPR[i].to_hex().c_str(), VPR[i].to_xyzw().c_str());
|
ret += fmt::Format("GPR[%02d] = 0x%016llx FPR[%02d] = %16g (0x%016llx) VPR[%02d] = 0x%s [%s]\n", i, GPR[i], i, FPR[i]._double, FPR[i]._u64, i, VPR[i].to_hex().c_str(), VPR[i].to_xyzw().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 8; i++) {
|
for (int i = 0; i < 8; i++) {
|
||||||
@ -222,8 +222,8 @@ void Compiler::VerifyInstructionAgainstInterpreter(const char * name, CompilerFn
|
|||||||
|
|
||||||
if (interp_output_state.ToString() != recomp_output_state.ToString()) {
|
if (interp_output_state.ToString() != recomp_output_state.ToString()) {
|
||||||
msg = std::string("Input state:\n") + input_state.ToString() +
|
msg = std::string("Input state:\n") + input_state.ToString() +
|
||||||
std::string("\nOutput state:\n") + recomp_output_state.ToString() +
|
std::string("\nOutput state:\n") + recomp_output_state.ToString() +
|
||||||
std::string("\nInterpreter output state:\n") + interp_output_state.ToString();
|
std::string("\nInterpreter output state:\n") + interp_output_state.ToString();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -235,58 +235,59 @@ void Compiler::VerifyInstructionAgainstInterpreter(const char * name, CompilerFn
|
|||||||
|
|
||||||
void Compiler::RunTest(const char * name, std::function<void()> test_case, std::function<void()> input, std::function<bool(std::string & msg)> check_result) {
|
void Compiler::RunTest(const char * name, std::function<void()> test_case, std::function<void()> input, std::function<bool(std::string & msg)> check_result) {
|
||||||
#ifdef PPU_LLVM_RECOMPILER_UNIT_TESTS
|
#ifdef PPU_LLVM_RECOMPILER_UNIT_TESTS
|
||||||
// Create the unit test function
|
m_recompilation_engine.Log() << "Running test " << name << '\n';
|
||||||
m_current_function = (Function *)m_module->getOrInsertFunction(name, m_ir_builder->getVoidTy(),
|
|
||||||
m_ir_builder->getInt8PtrTy() /*ppu_state*/,
|
|
||||||
m_ir_builder->getInt64Ty() /*base_addres*/,
|
|
||||||
m_ir_builder->getInt8PtrTy() /*interpreter*/, nullptr);
|
|
||||||
m_current_function->setCallingConv(CallingConv::X86_64_Win64);
|
|
||||||
auto arg_i = m_current_function->arg_begin();
|
|
||||||
arg_i->setName("ppu_state");
|
|
||||||
(++arg_i)->setName("base_address");
|
|
||||||
(++arg_i)->setName("interpreter");
|
|
||||||
|
|
||||||
auto block = BasicBlock::Create(*m_llvm_context, "start", m_current_function);
|
// Create the function
|
||||||
|
m_state.function = (Function *)m_module->getOrInsertFunction(name, m_compiled_function_type);
|
||||||
|
m_state.function->setCallingConv(CallingConv::X86_64_Win64);
|
||||||
|
auto arg_i = m_state.function->arg_begin();
|
||||||
|
arg_i->setName("ppu_state");
|
||||||
|
m_state.args[CompileTaskState::Args::State] = arg_i;
|
||||||
|
(++arg_i)->setName("context");
|
||||||
|
m_state.args[CompileTaskState::Args::Context] = arg_i;
|
||||||
|
m_state.current_instruction_address = s_ppu_state->PC;
|
||||||
|
|
||||||
|
auto block = BasicBlock::Create(*m_llvm_context, "start", m_state.function);
|
||||||
m_ir_builder->SetInsertPoint(block);
|
m_ir_builder->SetInsertPoint(block);
|
||||||
|
|
||||||
test_case();
|
test_case();
|
||||||
|
|
||||||
m_ir_builder->CreateRetVoid();
|
m_ir_builder->CreateRet(m_ir_builder->getInt32(0));
|
||||||
|
|
||||||
// Print the IR
|
// Print the IR
|
||||||
std::string ir;
|
std::string ir;
|
||||||
raw_string_ostream ir_ostream(ir);
|
raw_string_ostream ir_ostream(ir);
|
||||||
m_current_function->print(ir_ostream);
|
m_state.function->print(ir_ostream);
|
||||||
LOG_NOTICE(PPU, "[UT %s] LLVM IR:%s", name, ir.c_str());
|
m_recompilation_engine.Log() << "LLVM IR:" << ir;
|
||||||
|
|
||||||
std::string verify;
|
std::string verify_results;
|
||||||
raw_string_ostream verify_ostream(verify);
|
raw_string_ostream verify_results_ostream(verify_results);
|
||||||
if (verifyFunction(*m_current_function, &verify_ostream)) {
|
if (verifyFunction(*m_state.function, &verify_results_ostream)) {
|
||||||
LOG_ERROR(PPU, "[UT %s] Verification Failed:%s", name, verify.c_str());
|
m_recompilation_engine.Log() << "Verification Failed:\n" << verify_results << '\n';
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Optimize
|
// Optimize
|
||||||
m_fpm->run(*m_current_function);
|
m_fpm->run(*m_state.function);
|
||||||
|
|
||||||
// Print the optimized IR
|
// Print the optimized IR
|
||||||
ir = "";
|
ir = "";
|
||||||
m_current_function->print(ir_ostream);
|
m_state.function->print(ir_ostream);
|
||||||
LOG_NOTICE(PPU, "[UT %s] Optimized LLVM IR:%s", name, ir.c_str());
|
m_recompilation_engine.Log() << "Optimized LLVM IR:" << ir;
|
||||||
|
|
||||||
// Generate the function
|
// Generate the function
|
||||||
MachineCodeInfo mci;
|
MachineCodeInfo mci;
|
||||||
m_execution_engine->runJITOnFunction(m_current_function, &mci);
|
m_execution_engine->runJITOnFunction(m_state.function, &mci);
|
||||||
|
|
||||||
// Disassemble the generated function
|
// Disassemble the generated function
|
||||||
auto disassembler = LLVMCreateDisasm(sys::getProcessTriple().c_str(), nullptr, 0, nullptr, nullptr);
|
auto disassembler = LLVMCreateDisasm(sys::getProcessTriple().c_str(), nullptr, 0, nullptr, nullptr);
|
||||||
|
|
||||||
LOG_NOTICE(PPU, "[UT %s] Disassembly:", name);
|
m_recompilation_engine.Log() << "Disassembly:\n";
|
||||||
for (uint64_t pc = 0; pc < mci.size();) {
|
for (uint64_t pc = 0; pc < mci.size();) {
|
||||||
char str[1024];
|
char str[1024];
|
||||||
|
|
||||||
auto size = LLVMDisasmInstruction(disassembler, (uint8_t *)mci.address() + pc, mci.size() - pc, (uint64_t)((uint8_t *)mci.address() + pc), str, sizeof(str));
|
auto size = LLVMDisasmInstruction(disassembler, (uint8_t *)mci.address() + pc, mci.size() - pc, (uint64_t)((uint8_t *)mci.address() + pc), str, sizeof(str));
|
||||||
LOG_NOTICE(PPU, "[UT %s] %p: %s.", name, (uint8_t *)mci.address() + pc, str);
|
m_recompilation_engine.Log() << ((uint8_t *)mci.address() + pc) << ':' << str << '\n';
|
||||||
pc += size;
|
pc += size;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -294,33 +295,31 @@ void Compiler::RunTest(const char * name, std::function<void()> test_case, std::
|
|||||||
|
|
||||||
// Run the test
|
// Run the test
|
||||||
input();
|
input();
|
||||||
std::vector<GenericValue> args;
|
auto executable = (Executable)m_execution_engine->getPointerToFunction(m_state.function);
|
||||||
args.push_back(GenericValue(s_ppu_state));
|
executable(s_ppu_state, 0);
|
||||||
args.push_back(GenericValue(s_interpreter));
|
|
||||||
m_execution_engine->runFunction(m_current_function, args);
|
|
||||||
|
|
||||||
// Verify results
|
// Verify results
|
||||||
std::string msg;
|
std::string msg;
|
||||||
bool pass = check_result(msg);
|
bool pass = check_result(msg);
|
||||||
if (pass) {
|
if (pass) {
|
||||||
LOG_NOTICE(PPU, "[UT %s] Test passed. %s", name, msg.c_str());
|
m_recompilation_engine.Log() << "Test " << name << " passed\n" << msg << "\n";
|
||||||
} else {
|
} else {
|
||||||
LOG_ERROR(PPU, "[UT %s] Test failed. %s", name, msg.c_str());
|
m_recompilation_engine.Log() << "Test " << name << " failed\n" << msg << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
m_execution_engine->freeMachineCodeForFunction(m_current_function);
|
m_execution_engine->freeMachineCodeForFunction(m_state.function);
|
||||||
#endif // PPU_LLVM_RECOMPILER_UNIT_TESTS
|
#endif // PPU_LLVM_RECOMPILER_UNIT_TESTS
|
||||||
}
|
}
|
||||||
|
|
||||||
void Compiler::RunAllTests(PPUThread * ppu_state, PPUInterpreter * interpreter) {
|
void Compiler::RunAllTests() {
|
||||||
#ifdef PPU_LLVM_RECOMPILER_UNIT_TESTS
|
#ifdef PPU_LLVM_RECOMPILER_UNIT_TESTS
|
||||||
s_ppu_state = ppu_state;
|
PPUThread ppu_state;
|
||||||
s_interpreter = interpreter;
|
PPUInterpreter interpreter(ppu_state);
|
||||||
|
|
||||||
PPUState initial_state;
|
s_ppu_state = &ppu_state;
|
||||||
initial_state.Load(*ppu_state, 0x10000);
|
s_interpreter = &interpreter;
|
||||||
|
|
||||||
LOG_NOTICE(PPU, "Running Unit Tests");
|
m_recompilation_engine.Log() << "Starting Unit Tests\n";
|
||||||
|
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MFVSCR, 0, 5, 1);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MFVSCR, 0, 5, 1);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MTVSCR, 0, 5, 1);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MTVSCR, 0, 5, 1);
|
||||||
@ -399,6 +398,12 @@ void Compiler::RunAllTests(PPUThread * ppu_state, PPUInterpreter * interpreter)
|
|||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPGTUW, 5, 5, 0, 1, 1);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPGTUW, 5, 5, 0, 1, 1);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPGTUW_, 0, 5, 0, 1, 2);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPGTUW_, 0, 5, 0, 1, 2);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPGTUW_, 5, 5, 0, 1, 1);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPGTUW_, 5, 5, 0, 1, 1);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCTSXS, 0, 5, 0, 0, 1);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCTSXS, 5, 5, 0, 3, 1);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCTUXS, 0, 5, 0, 0, 1);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCTUXS, 5, 5, 0, 3, 1);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VEXPTEFP, 0, 5, 0, 1);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VLOGEFP, 0, 5, 0, 1);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMADDFP, 0, 5, 0, 1, 2, 3);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMADDFP, 0, 5, 0, 1, 2, 3);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMAXFP, 0, 5, 0, 1, 2);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMAXFP, 0, 5, 0, 1, 2);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMAXSB, 0, 5, 0, 1, 2);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMAXSB, 0, 5, 0, 1, 2);
|
||||||
@ -407,6 +412,8 @@ void Compiler::RunAllTests(PPUThread * ppu_state, PPUInterpreter * interpreter)
|
|||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMAXUB, 0, 5, 0, 1, 2);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMAXUB, 0, 5, 0, 1, 2);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMAXUH, 0, 5, 0, 1, 2);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMAXUH, 0, 5, 0, 1, 2);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMAXUW, 0, 5, 0, 1, 2);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMAXUW, 0, 5, 0, 1, 2);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMHADDSHS, 0, 5, 0, 1, 2, 3);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMHRADDSHS, 0, 5, 0, 1, 2, 3);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMINFP, 0, 5, 0, 1, 2);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMINFP, 0, 5, 0, 1, 2);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMINSB, 0, 5, 0, 1, 2);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMINSB, 0, 5, 0, 1, 2);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMINSH, 0, 5, 0, 1, 2);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMINSH, 0, 5, 0, 1, 2);
|
||||||
@ -414,6 +421,7 @@ void Compiler::RunAllTests(PPUThread * ppu_state, PPUInterpreter * interpreter)
|
|||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMINUB, 0, 5, 0, 1, 2);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMINUB, 0, 5, 0, 1, 2);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMINUH, 0, 5, 0, 1, 2);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMINUH, 0, 5, 0, 1, 2);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMINUW, 0, 5, 0, 1, 2);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMINUW, 0, 5, 0, 1, 2);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMLADDUHM, 0, 5, 0, 1, 2, 3);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMRGHB, 0, 5, 0, 1, 2);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMRGHB, 0, 5, 0, 1, 2);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMRGHH, 0, 5, 0, 1, 2);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMRGHH, 0, 5, 0, 1, 2);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMRGHW, 0, 5, 0, 1, 2);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMRGHW, 0, 5, 0, 1, 2);
|
||||||
@ -422,13 +430,40 @@ void Compiler::RunAllTests(PPUThread * ppu_state, PPUInterpreter * interpreter)
|
|||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMRGLW, 0, 5, 0, 1, 2);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMRGLW, 0, 5, 0, 1, 2);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMSUMMBM, 0, 5, 0, 1, 2, 3);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMSUMMBM, 0, 5, 0, 1, 2, 3);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMSUMSHM, 0, 5, 0, 1, 2, 3);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMSUMSHM, 0, 5, 0, 1, 2, 3);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMSUMSHS, 0, 5, 0, 1, 2, 3);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMSUMUBM, 0, 5, 0, 1, 2, 3);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMSUMUBM, 0, 5, 0, 1, 2, 3);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMSUMUHM, 0, 5, 0, 1, 2, 3);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMSUMUHM, 0, 5, 0, 1, 2, 3);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMSUMUHS, 0, 5, 0, 1, 2, 3);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMULESB, 0, 5, 0, 1, 2);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMULESH, 0, 5, 0, 1, 2);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMULEUB, 0, 5, 0, 1, 2);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMULEUH, 0, 5, 0, 1, 2);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMULOSB, 0, 5, 0, 1, 2);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMULOSH, 0, 5, 0, 1, 2);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMULOUB, 0, 5, 0, 1, 2);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMULOUH, 0, 5, 0, 1, 2);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VNMSUBFP, 0, 5, 0, 1, 2, 3);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VNMSUBFP, 0, 5, 0, 1, 2, 3);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VNOR, 0, 5, 0, 1, 2);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VNOR, 0, 5, 0, 1, 2);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VOR, 0, 5, 0, 1, 2);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VOR, 0, 5, 0, 1, 2);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VPERM, 0, 5, 0, 1, 2, 3);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VPERM, 0, 5, 0, 1, 2, 3);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VPKPX, 0, 5, 0, 1, 2);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VPKSHSS, 0, 5, 0, 1, 2);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VPKSHUS, 0, 5, 0, 1, 2);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VPKSWSS, 0, 5, 0, 1, 2);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VPKSWUS, 0, 5, 0, 1, 2);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VPKUHUM, 0, 5, 0, 1, 2);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VPKUHUS, 0, 5, 0, 1, 2);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VPKUWUM, 0, 5, 0, 1, 2);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VPKUWUS, 0, 5, 0, 1, 2);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VREFP, 0, 5, 0, 1);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VREFP, 0, 5, 0, 1);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VRFIM, 0, 5, 0, 1);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VRFIN, 0, 5, 0, 1);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VRFIP, 0, 5, 0, 1);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VRFIZ, 0, 5, 0, 1);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VRLB, 0, 5, 0, 1, 2);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VRLH, 0, 5, 0, 1, 2);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VRLW, 0, 5, 0, 1, 2);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VRSQRTEFP, 0, 5, 0, 1);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VSEL, 0, 5, 0, 1, 2, 3);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VSEL, 0, 5, 0, 1, 2, 3);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VSL, 0, 5, 0, 1, 2);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VSL, 0, 5, 0, 1, 2);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VSLB, 0, 5, 0, 1, 2);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VSLB, 0, 5, 0, 1, 2);
|
||||||
@ -460,6 +495,17 @@ void Compiler::RunAllTests(PPUThread * ppu_state, PPUInterpreter * interpreter)
|
|||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VSUBUHS, 0, 5, 0, 1, 2);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VSUBUHS, 0, 5, 0, 1, 2);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VSUBUWM, 0, 5, 0, 1, 2);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VSUBUWM, 0, 5, 0, 1, 2);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VSUBUWS, 0, 5, 0, 1, 2);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VSUBUWS, 0, 5, 0, 1, 2);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VSUMSWS, 0, 5, 0, 1, 2);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VSUM2SWS, 0, 5, 0, 1, 2);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VSUM4SBS, 0, 5, 0, 1, 2);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VSUM4SHS, 0, 5, 0, 1, 2);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VSUM4UBS, 0, 5, 0, 1, 2);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VUPKHPX, 0, 5, 0, 1);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VUPKHSB, 0, 5, 0, 1);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VUPKHSH, 0, 5, 0, 1);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VUPKLPX, 0, 5, 0, 1);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VUPKLSB, 0, 5, 0, 1);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VUPKLSH, 0, 5, 0, 1);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VXOR, 0, 5, 0, 1, 2);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VXOR, 0, 5, 0, 1, 2);
|
||||||
// TODO: Rest of the vector instructions
|
// TODO: Rest of the vector instructions
|
||||||
|
|
||||||
@ -483,7 +529,7 @@ void Compiler::RunAllTests(PPUThread * ppu_state, PPUInterpreter * interpreter)
|
|||||||
// TODO: BCLR
|
// TODO: BCLR
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(CRNOR, 0, 5, 0, 7, 3);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(CRNOR, 0, 5, 0, 7, 3);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(CRANDC, 0, 5, 5, 6, 7);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(CRANDC, 0, 5, 5, 6, 7);
|
||||||
// TODO: ISYNC
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(ISYNC, 0, 5);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(CRXOR, 0, 5, 7, 7, 7);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(CRXOR, 0, 5, 7, 7, 7);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(CRNAND, 0, 5, 3, 4, 5);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(CRNAND, 0, 5, 3, 4, 5);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(CRAND, 0, 5, 1, 2, 3);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(CRAND, 0, 5, 1, 2, 3);
|
||||||
@ -513,115 +559,174 @@ void Compiler::RunAllTests(PPUThread * ppu_state, PPUInterpreter * interpreter)
|
|||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(RLDIMI, 5, 5, 21, 22, 23, 43, 1);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(RLDIMI, 5, 5, 21, 22, 23, 43, 1);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(RLDC_LR, 0, 5, 7, 8, 9, 12, 0, 0);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(RLDC_LR, 0, 5, 7, 8, 9, 12, 0, 0);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(RLDC_LR, 5, 5, 21, 22, 23, 43, 1, 1);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(RLDC_LR, 5, 5, 21, 22, 23, 43, 1, 1);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(CMP, 0, 5, 3, 0, 9, 31);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(ADD, 0, 5, 7, 8, 9, 0, 0);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(CMP, 5, 5, 6, 1, 23, 14);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(ADD, 5, 5, 21, 22, 23, 0, 1);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SUBFC, 0, 5, 0, 1, 2, 0, false);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SUBF, 0, 5, 7, 8, 9, 0, 0);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SUBFC, 5, 5, 0, 1, 2, 0, true);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SUBF, 5, 5, 21, 22, 23, 0, 1);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(ADDC, 0, 5, 0, 1, 2, 0, false);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(NEG, 0, 5, 7, 8, 0, 0);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(ADDC, 5, 5, 0, 1, 2, 0, true);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(NEG, 5, 5, 21, 22, 0, 1);
|
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MULHDU, 0, 5, 7, 8, 9, 0);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MULHDU, 0, 5, 7, 8, 9, 0);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MULHDU, 5, 5, 21, 22, 23, 1);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MULHDU, 5, 5, 21, 22, 23, 1);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MULHWU, 0, 5, 7, 8, 9, 0);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MULHWU, 0, 5, 7, 8, 9, 0);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MULHWU, 5, 5, 21, 22, 23, 1);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MULHWU, 5, 5, 21, 22, 23, 1);
|
||||||
|
// TODO: MFOCRF
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SLW, 0, 5, 5, 6, 7, 0);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SLW, 5, 5, 5, 6, 7, 1);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(CNTLZW, 0, 5, 5, 6, 0);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(CNTLZW, 5, 5, 5, 6, 1);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SLD, 0, 5, 5, 6, 7, 0);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SLD, 5, 5, 5, 6, 7, 1);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(AND, 0, 5, 7, 8, 9, 0);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(AND, 5, 5, 21, 22, 23, 1);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(CMPL, 0, 5, 3, 0, 9, 31);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(CMPL, 5, 5, 6, 1, 23, 14);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SUBF, 0, 5, 7, 8, 9, 0, 0);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SUBF, 5, 5, 21, 22, 23, 0, 1);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(CNTLZD, 0, 5, 5, 6, 0);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(CNTLZD, 5, 5, 5, 6, 1);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(ANDC, 0, 5, 5, 6, 7, 0);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(ANDC, 5, 5, 5, 6, 7, 1);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MULHD, 0, 5, 7, 8, 9, 0);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MULHD, 0, 5, 7, 8, 9, 0);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MULHD, 5, 5, 21, 22, 23, 1);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MULHD, 5, 5, 21, 22, 23, 1);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MULHW, 0, 5, 7, 8, 9, 0);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MULHW, 0, 5, 7, 8, 9, 0);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MULHW, 5, 5, 21, 22, 23, 1);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MULHW, 5, 5, 21, 22, 23, 1);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MULLD, 0, 5, 7, 8, 9, 0, 0);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(NEG, 0, 5, 7, 8, 0, 0);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MULLD, 5, 5, 21, 22, 23, 0, 1);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(NEG, 5, 5, 21, 22, 0, 1);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MULLW, 0, 5, 7, 8, 9, 0, 0);
|
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MULLW, 5, 5, 21, 22, 23, 0, 1);
|
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(DIVD, 0, 5, 7, 8, 9, 0, 0);
|
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(DIVD, 5, 5, 21, 22, 23, 0, 1);
|
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(DIVDU, 0, 5, 7, 8, 9, 0, 0);
|
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(DIVDU, 5, 5, 21, 22, 23, 0, 1);
|
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(DIVW, 0, 5, 7, 8, 9, 0, 0);
|
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(DIVW, 5, 5, 21, 22, 23, 0, 1);
|
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(DIVWU, 0, 5, 7, 8, 9, 0, 0);
|
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(DIVWU, 5, 5, 21, 22, 23, 0, 1);
|
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(AND, 0, 5, 7, 8, 9, 0);
|
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(AND, 5, 5, 21, 22, 23, 1);
|
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(OR, 0, 5, 7, 8, 9, 0);
|
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(OR, 5, 5, 21, 22, 23, 1);
|
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(XOR, 0, 5, 7, 8, 9, 0);
|
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(XOR, 5, 5, 21, 22, 23, 1);
|
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(NOR, 0, 5, 7, 8, 9, 0);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(NOR, 0, 5, 7, 8, 9, 0);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(NOR, 5, 5, 21, 22, 23, 1);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(NOR, 5, 5, 21, 22, 23, 1);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(CMP, 0, 5, 3, 0, 9, 31);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SUBFE, 0, 5, 7, 8, 9, 0, 0);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(CMP, 5, 5, 6, 1, 23, 14);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SUBFE, 5, 5, 21, 22, 23, 0, 1);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(CMPL, 0, 5, 3, 0, 9, 31);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(ADDE, 0, 5, 7, 8, 9, 0, 0);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(CMPL, 5, 5, 6, 1, 23, 14);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(ADDE, 5, 5, 21, 22, 23, 0, 1);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(ADDC, 0, 5, 0, 1, 2, 0, false);
|
// TODO: MTOCRF
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(ADDC, 5, 5, 0, 1, 2, 0, true);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(ADDZE, 0, 5, 7, 8, 0, 0);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SUBFC, 0, 5, 0, 1, 2, 0, false);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(ADDZE, 5, 5, 21, 22, 0, 1);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SUBFC, 5, 5, 0, 1, 2, 0, true);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SUBFZE, 0, 5, 7, 8, 0, 0);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(EXTSB, 0, 5, 3, 5, 0);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SUBFZE, 5, 5, 21, 22, 0, 1);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(EXTSB, 5, 5, 3, 5, 1);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SUBFME, 0, 5, 7, 8, 0, 0);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(EXTSH, 0, 5, 6, 9, 0);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SUBFME, 5, 5, 21, 22, 0, 1);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(EXTSH, 5, 5, 6, 9, 1);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MULLD, 0, 5, 7, 8, 9, 0, 0);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(EXTSW, 0, 5, 25, 29, 0);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MULLD, 5, 5, 21, 22, 23, 0, 1);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(EXTSW, 5, 5, 25, 29, 1);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(ADDME, 0, 5, 7, 8, 0, 0);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MTSPR, 0, 5, 0x20, 5);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(ADDME, 5, 5, 21, 22, 0, 1);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MTSPR, 5, 5, 0x100, 5);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MULLW, 0, 5, 7, 8, 9, 0, 0);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MTSPR, 10, 5, 0x120, 5);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MULLW, 5, 5, 21, 22, 23, 0, 1);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MTSPR, 15, 5, 0x8, 5);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(ADD, 0, 5, 7, 8, 9, 0, 0);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(ADD, 5, 5, 21, 22, 23, 0, 1);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(EQV, 0, 5, 7, 8, 9, 0);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(EQV, 5, 5, 21, 22, 23, 1);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(XOR, 0, 5, 7, 8, 9, 0);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(XOR, 5, 5, 21, 22, 23, 1);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MFSPR, 0, 5, 5, 0x20);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MFSPR, 0, 5, 5, 0x20);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MFSPR, 5, 5, 5, 0x100);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MFSPR, 5, 5, 5, 0x100);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MFSPR, 10, 5, 5, 0x120);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MFSPR, 10, 5, 5, 0x120);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MFSPR, 15, 5, 5, 0x8);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MFSPR, 15, 5, 5, 0x8);
|
||||||
|
// TODO: MFTB
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(ORC, 0, 5, 7, 8, 9, 0);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(ORC, 5, 5, 21, 22, 23, 1);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(OR, 0, 5, 7, 8, 9, 0);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(OR, 5, 5, 21, 22, 23, 1);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(DIVDU, 0, 5, 7, 8, 9, 0, 0);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(DIVDU, 5, 5, 21, 22, 23, 0, 1);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(DIVWU, 0, 5, 7, 8, 9, 0, 0);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(DIVWU, 5, 5, 21, 22, 23, 0, 1);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MTSPR, 0, 5, 0x20, 5);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MTSPR, 5, 5, 0x100, 5);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MTSPR, 10, 5, 0x120, 5);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MTSPR, 15, 5, 0x8, 5);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(NAND, 0, 5, 7, 8, 9, 0);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(NAND, 5, 5, 21, 22, 23, 1);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(DIVD, 0, 5, 7, 8, 9, 0, 0);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(DIVD, 5, 5, 21, 22, 23, 0, 1);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(DIVW, 0, 5, 7, 8, 9, 0, 0);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(DIVW, 5, 5, 21, 22, 23, 0, 1);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SRW, 0, 5, 5, 6, 7, 0);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SRW, 5, 5, 5, 6, 7, 1);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SRD, 0, 5, 5, 6, 7, 0);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SRD, 5, 5, 5, 6, 7, 1);
|
||||||
|
// TODO: SYNC
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SRAW, 0, 5, 5, 6, 7, 0);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SRAW, 5, 5, 5, 6, 7, 1);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SRAD, 0, 5, 5, 6, 7, 0);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SRAD, 5, 5, 5, 6, 7, 1);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SRAWI, 0, 5, 5, 6, 0, 0);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SRAWI, 0, 5, 5, 6, 0, 0);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SRAWI, 5, 5, 5, 6, 12, 0);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SRAWI, 5, 5, 5, 6, 12, 0);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SRAWI, 10, 5, 5, 6, 22, 1);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SRAWI, 10, 5, 5, 6, 22, 1);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SRAWI, 15, 5, 5, 6, 31, 1);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SRAWI, 15, 5, 5, 6, 31, 1);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SRAW, 0, 5, 5, 6, 7, 0);
|
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SRAW, 5, 5, 5, 6, 7, 1);
|
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SRADI1, 0, 5, 5, 6, 0, 0);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SRADI1, 0, 5, 5, 6, 0, 0);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SRADI1, 5, 5, 5, 6, 12, 0);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SRADI1, 5, 5, 5, 6, 12, 0);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SRADI1, 10, 5, 5, 6, 48, 1);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SRADI1, 10, 5, 5, 6, 48, 1);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SRADI1, 15, 5, 5, 6, 63, 1);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SRADI1, 15, 5, 5, 6, 63, 1);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SRAD, 0, 5, 5, 6, 7, 0);
|
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SRAD, 5, 5, 5, 6, 7, 1);
|
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SLW, 0, 5, 5, 6, 7, 0);
|
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SLW, 5, 5, 5, 6, 7, 1);
|
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SRW, 0, 5, 5, 6, 7, 0);
|
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SRW, 5, 5, 5, 6, 7, 1);
|
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SLD, 0, 5, 5, 6, 7, 0);
|
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SLD, 5, 5, 5, 6, 7, 1);
|
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SRD, 0, 5, 5, 6, 7, 0);
|
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SRD, 5, 5, 5, 6, 7, 1);
|
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(CNTLZW, 0, 5, 5, 6, 0);
|
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(CNTLZW, 5, 5, 5, 6, 1);
|
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(CNTLZD, 0, 5, 5, 6, 0);
|
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(CNTLZD, 5, 5, 5, 6, 1);
|
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(ISYNC, 0, 5);
|
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(EIEIO, 0, 5);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(EIEIO, 0, 5);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(EXTSH, 0, 5, 6, 9, 0);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(EXTSH, 5, 5, 6, 9, 1);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(EXTSB, 0, 5, 3, 5, 0);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(EXTSB, 5, 5, 3, 5, 1);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(EXTSW, 0, 5, 25, 29, 0);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(EXTSW, 5, 5, 25, 29, 1);
|
||||||
|
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FSQRT, 0, 5, 0, 1, false);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FDIVS, 0, 5, 0, 1, 2, false);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FSUBS, 0, 5, 0, 1, 2, false);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FADDS, 0, 5, 0, 1, 2, false);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FSQRTS, 0, 5, 0, 1, false);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FSQRTS, 0, 5, 0, 1, false);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FRES, 0, 5, 0, 1, false);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FMULS, 0, 5, 0, 1, 2, false);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FMADDS, 0, 5, 0, 1, 2, 3, false);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FMSUBS, 0, 5, 0, 1, 2, 3, false);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FNMSUBS, 0, 5, 0, 1, 2, 3, false);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FNMADDS, 0, 5, 0, 1, 2, 3, false);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MTFSB1, 0, 5, 0, false);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MTFSB1, 5, 5, 3, false);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MTFSB1, 10, 5, 25, false);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MTFSB1, 15, 5, 31, false);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MCRFS, 0, 5, 0, 7);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MCRFS, 5, 5, 7, 0);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MCRFS, 10, 5, 5, 2);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MCRFS, 15, 5, 5, 3);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MTFSB0, 0, 5, 0, false);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MTFSB0, 5, 5, 3, false);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MTFSB0, 10, 5, 25, false);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MTFSB0, 15, 5, 31, false);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MTFSFI, 0, 5, 0, 1, false);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MTFSFI, 5, 5, 2, 6, false);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MTFSFI, 10, 5, 5, 11, false);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MTFSFI, 15, 5, 7, 14, false);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MFFS, 0, 5, 0, false);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MTFSF, 0, 5, 0, 0, false);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MTFSF, 5, 5, 2, 0, false);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MTFSF, 10, 5, 5, 0, false);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MTFSF, 15, 5, 7, 0, false);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FCMPU, 0, 5, 5, 0, 1);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FRSP, 0, 5, 0, 1, false);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FCTIW, 0, 5, 0, 1, false);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FCTIWZ, 0, 5, 0, 1, false);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FDIV, 0, 5, 0, 1, 2, false);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FDIV, 0, 5, 0, 1, 2, false);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FSUB, 0, 5, 0, 1, 2, false);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FSUB, 0, 5, 0, 1, 2, false);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FADD, 0, 5, 0, 1, 2, false);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FADD, 0, 5, 0, 1, 2, false);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FSQRT, 0, 5, 0, 1, false);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FSEL, 0, 5, 0, 1, 2, 3, false);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FMUL, 0, 5, 0, 1, 2, false);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FMUL, 0, 5, 0, 1, 2, false);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FRSQRTE, 0, 5, 0, 1, false);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FMSUB, 0, 5, 0, 1, 2, 3, false);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FMSUB, 0, 5, 0, 1, 2, 3, false);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FMADD, 0, 5, 0, 1, 2, 3, false);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FMADD, 0, 5, 0, 1, 2, 3, false);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FNMSUB, 0, 5, 0, 1, 2, 3, false);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FNMSUB, 0, 5, 0, 1, 2, 3, false);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FNMADD, 0, 5, 0, 1, 2, 3, false);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FNMADD, 0, 5, 0, 1, 2, 3, false);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FCMPO, 0, 5, 3, 0, 1);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FNEG, 0, 5, 0, 1, false);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FNEG, 0, 5, 0, 1, false);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FMR, 0, 5, 0, 1, false);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FMR, 0, 5, 0, 1, false);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FNABS, 0, 5, 0, 1, false);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FNABS, 0, 5, 0, 1, false);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FABS, 0, 5, 0, 1, false);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FABS, 0, 5, 0, 1, false);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FCFID, 0, 5, 0, 1, false);
|
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FCTID, 0, 5, 0, 1, false);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FCTID, 0, 5, 0, 1, false);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FCTIW, 0, 5, 0, 1, false);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FCFID, 0, 5, 0, 1, false);
|
||||||
|
|
||||||
PPUState input;
|
PPUState input;
|
||||||
input.SetRandom(0x10000);
|
input.SetRandom(0x10000);
|
||||||
input.GPR[14] = 10;
|
input.GPR[14] = 10;
|
||||||
input.GPR[21] = 15;
|
input.GPR[21] = 15;
|
||||||
input.GPR[23] = 0x10000;
|
input.GPR[23] = 0x10000;
|
||||||
|
input.R_ADDR = 0x10000;
|
||||||
|
input.R_VALUE = 0x1122334455667788;
|
||||||
|
input.mem_block[0] = 0x8877665544332211;
|
||||||
|
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LBZ, 0, input, 5, 0, 0x10000);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LBZ, 0, input, 5, 0, 0x10000);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LBZ, 1, input, 5, 14, 0x10000);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LBZ, 1, input, 5, 14, 0x10000);
|
||||||
@ -634,6 +739,8 @@ void Compiler::RunAllTests(PPUThread * ppu_state, PPUInterpreter * interpreter)
|
|||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LHZU, 0, input, 5, 14, 0x10000);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LHZU, 0, input, 5, 14, 0x10000);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LHZX, 0, input, 5, 0, 23);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LHZX, 0, input, 5, 0, 23);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LHZX, 1, input, 5, 14, 23);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LHZX, 1, input, 5, 14, 23);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(ECIWX, 0, input, 5, 0, 23);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(ECIWX, 1, input, 5, 14, 23);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LHZUX, 0, input, 5, 14, 23);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LHZUX, 0, input, 5, 14, 23);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LHA, 0, input, 5, 0, 0x100F0);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LHA, 0, input, 5, 0, 0x100F0);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LHA, 1, input, 5, 14, 0x100F0);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LHA, 1, input, 5, 14, 0x100F0);
|
||||||
@ -712,6 +819,8 @@ void Compiler::RunAllTests(PPUThread * ppu_state, PPUInterpreter * interpreter)
|
|||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STB, 0, input, 3, 0, 0x10000);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STB, 0, input, 3, 0, 0x10000);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STB, 1, input, 3, 14, 0x10000);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STB, 1, input, 3, 14, 0x10000);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STBU, 0, input, 3, 14, 0x10000);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STBU, 0, input, 3, 14, 0x10000);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STDCX_, 0, input, 3, 0, 23);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STDCX_, 1, input, 3, 14, 23);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STBX, 0, input, 3, 0, 23);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STBX, 0, input, 3, 0, 23);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STBX, 1, input, 3, 14, 23);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STBX, 1, input, 3, 14, 23);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STBUX, 0, input, 3, 14, 23);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STBUX, 0, input, 3, 14, 23);
|
||||||
@ -720,6 +829,8 @@ void Compiler::RunAllTests(PPUThread * ppu_state, PPUInterpreter * interpreter)
|
|||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STHU, 0, input, 3, 14, 0x10000);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STHU, 0, input, 3, 14, 0x10000);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STHX, 0, input, 3, 0, 23);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STHX, 0, input, 3, 0, 23);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STHX, 1, input, 3, 14, 23);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STHX, 1, input, 3, 14, 23);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(ECOWX, 0, input, 3, 0, 23);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(ECOWX, 1, input, 3, 14, 23);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STHUX, 0, input, 3, 14, 23);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STHUX, 0, input, 3, 14, 23);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STHBRX, 0, input, 3, 14, 23);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STHBRX, 0, input, 3, 14, 23);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STW, 0, input, 3, 0, 0x10000);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STW, 0, input, 3, 0, 0x10000);
|
||||||
@ -728,18 +839,26 @@ void Compiler::RunAllTests(PPUThread * ppu_state, PPUInterpreter * interpreter)
|
|||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STWX, 0, input, 3, 0, 23);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STWX, 0, input, 3, 0, 23);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STWX, 1, input, 3, 14, 23);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STWX, 1, input, 3, 14, 23);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STWUX, 0, input, 3, 14, 23);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STWUX, 0, input, 3, 14, 23);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STVLX, 0, input, 0, 0, 23);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STVLX, 1, input, 0, 14, 23);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STVLX, 2, input, 0, 21, 23);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STWBRX, 0, input, 3, 14, 23);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STWBRX, 0, input, 3, 14, 23);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STD, 0, input, 3, 0, 0x10000);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STD, 0, input, 3, 0, 0x10000);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STD, 1, input, 3, 14, 0x10000);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STD, 1, input, 3, 14, 0x10000);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STDU, 0, input, 3, 14, 0x10000);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STDU, 0, input, 3, 14, 0x10000);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STDX, 0, input, 3, 0, 23);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STDX, 0, input, 3, 0, 23);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STDX, 1, input, 3, 14, 23);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STDX, 1, input, 3, 14, 23);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STWCX_, 0, input, 3, 0, 23);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STWCX_, 1, input, 3, 14, 23);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STDUX, 0, input, 3, 14, 23);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STDUX, 0, input, 3, 14, 23);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STFS, 0, input, 3, 0, 0x10000);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STFS, 0, input, 3, 0, 0x10000);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STFS, 1, input, 3, 14, 0x10000);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STFS, 1, input, 3, 14, 0x10000);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STFSU, 0, input, 3, 14, 0x10000);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STFSU, 0, input, 3, 14, 0x10000);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STFSX, 0, input, 3, 0, 23);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STFSX, 0, input, 3, 0, 23);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STFSX, 1, input, 3, 14, 23);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STFSX, 1, input, 3, 14, 23);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STVRX, 0, input, 0, 0, 23);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STVRX, 1, input, 0, 14, 23);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STVRX, 2, input, 0, 21, 23);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STFSUX, 0, input, 3, 14, 23);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STFSUX, 0, input, 3, 14, 23);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STFD, 0, input, 3, 0, 0x10000);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STFD, 0, input, 3, 0, 0x10000);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STFD, 1, input, 3, 14, 0x10000);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STFD, 1, input, 3, 14, 0x10000);
|
||||||
@ -767,6 +886,6 @@ void Compiler::RunAllTests(PPUThread * ppu_state, PPUInterpreter * interpreter)
|
|||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(DCBZ, 0, input, 0, 23);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(DCBZ, 0, input, 0, 23);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(DCBZ, 1, input, 14, 23);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(DCBZ, 1, input, 14, 23);
|
||||||
|
|
||||||
initial_state.Store(*ppu_state);
|
m_recompilation_engine.Log() << "Finished Unit Tests\n";
|
||||||
#endif // PPU_LLVM_RECOMPILER_UNIT_TESTS
|
#endif // PPU_LLVM_RECOMPILER_UNIT_TESTS
|
||||||
}
|
}
|
||||||
|
@ -767,7 +767,7 @@
|
|||||||
</Link>
|
</Link>
|
||||||
<Lib>
|
<Lib>
|
||||||
<AdditionalLibraryDirectories>..\llvm_build\Release\lib</AdditionalLibraryDirectories>
|
<AdditionalLibraryDirectories>..\llvm_build\Release\lib</AdditionalLibraryDirectories>
|
||||||
<AdditionalDependencies>LLVMJIT.lib;LLVMVectorize.lib;LLVMX86CodeGen.lib;LLVMX86Disassembler.lib;LLVMExecutionEngine.lib;LLVMAsmPrinter.lib;LLVMSelectionDAG.lib;LLVMCodeGen.lib;LLVMScalarOpts.lib;LLVMInstCombine.lib;LLVMTransformUtils.lib;LLVMipa.lib;LLVMAnalysis.lib;LLVMTarget.lib;LLVMX86Desc.lib;LLVMX86AsmPrinter.lib;LLVMObject.lib;LLVMMCParser.lib;LLVMBitReader.lib;LLVMCore.lib;LLVMX86Utils.lib;LLVMMC.lib;LLVMX86Info.lib;LLVMSupport.lib</AdditionalDependencies>
|
<AdditionalDependencies>LLVMJIT.lib;LLVMVectorize.lib;LLVMX86CodeGen.lib;LLVMX86Disassembler.lib;LLVMExecutionEngine.lib;LLVMAsmPrinter.lib;LLVMSelectionDAG.lib;LLVMCodeGen.lib;LLVMScalarOpts.lib;LLVMInstCombine.lib;LLVMTransformUtils.lib;LLVMipa.lib;LLVMAnalysis.lib;LLVMTarget.lib;LLVMX86Desc.lib;LLVMX86AsmPrinter.lib;LLVMObject.lib;LLVMMCParser.lib;LLVMBitReader.lib;LLVMCore.lib;LLVMX86Utils.lib;LLVMMC.lib;LLVMX86Info.lib;LLVMSupport.lib;LLVMMCDisassembler.lib</AdditionalDependencies>
|
||||||
</Lib>
|
</Lib>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
Loading…
Reference in New Issue
Block a user