1
0
mirror of https://github.com/RPCS3/rpcs3.git synced 2024-11-22 18:53:28 +01:00

SPU: some instructions removed

They can't be used on PS3.
Bitfields for interrupt flags added.
This commit is contained in:
Nekotekina 2014-08-18 04:23:05 +04:00
parent 8a785fefc2
commit 07a5720c17
5 changed files with 128 additions and 202 deletions

View File

@ -223,19 +223,19 @@ private:
{
DisAsm("wrch", spu_ch_name[ra], spu_reg_name[rt]);
}
void BIZ(u32 rt, u32 ra)
void BIZ(u32 intr, u32 rt, u32 ra)
{
DisAsm("biz", spu_reg_name[rt], spu_reg_name[ra]);
}
void BINZ(u32 rt, u32 ra)
void BINZ(u32 intr, u32 rt, u32 ra)
{
DisAsm("binz", spu_reg_name[rt], spu_reg_name[ra]);
}
void BIHZ(u32 rt, u32 ra)
void BIHZ(u32 intr, u32 rt, u32 ra)
{
DisAsm("bihz", spu_reg_name[rt], spu_reg_name[ra]);
}
void BIHNZ(u32 rt, u32 ra)
void BIHNZ(u32 intr, u32 rt, u32 ra)
{
DisAsm("bihnz", spu_reg_name[rt], spu_reg_name[ra]);
}
@ -247,11 +247,11 @@ private:
{
DisAsm("stqx", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]);
}
void BI(u32 ra)
void BI(u32 intr, u32 ra)
{
DisAsm("bi", spu_reg_name[ra]);
}
void BISL(u32 rt, u32 ra)
void BISL(u32 intr, u32 rt, u32 ra)
{
DisAsm("bisl", spu_reg_name[rt], spu_reg_name[ra]);
}
@ -259,7 +259,7 @@ private:
{
DisAsm("iret", spu_reg_name[ra]);
}
void BISLED(u32 rt, u32 ra)
void BISLED(u32 intr, u32 rt, u32 ra)
{
DisAsm("bisled", spu_reg_name[rt], spu_reg_name[ra]);
}

View File

@ -88,16 +88,16 @@ namespace SPU_instr
bind_instr(ri7_list, AVGB, RT, RA, RB);
bind_instr(ri7_list, MTSPR, RT, RA);
bind_instr(ri7_list, WRCH, RA, RT);
bind_instr(ri7_list, BIZ, RT, RA);
bind_instr(ri7_list, BINZ, RT, RA);
bind_instr(ri7_list, BIHZ, RT, RA);
bind_instr(ri7_list, BIHNZ, RT, RA);
bind_instr(ri7_list, BIZ, RB, RT, RA);
bind_instr(ri7_list, BINZ, RB, RT, RA);
bind_instr(ri7_list, BIHZ, RB, RT, RA);
bind_instr(ri7_list, BIHNZ, RB, RT, RA);
bind_instr(ri7_list, STOPD, RT, RA, RB);
bind_instr(ri7_list, STQX, RT, RA, RB);
bind_instr(ri7_list, BI, RA);
bind_instr(ri7_list, BISL, RT, RA);
bind_instr(ri7_list, BI, RB, RA);
bind_instr(ri7_list, BISL, RB, RT, RA);
bind_instr(ri7_list, IRET, RA);
bind_instr(ri7_list, BISLED, RT, RA);
bind_instr(ri7_list, BISLED, RB, RT, RA);
bind_instr(ri7_list, HBR, L_11, RO, RA);
bind_instr(ri7_list, GB, RT, RA);
bind_instr(ri7_list, GBH, RT, RA);

View File

@ -60,7 +60,7 @@ private:
}
void MFSPR(u32 rt, u32 sa)
{
UNIMPLEMENTED();
UNIMPLEMENTED(); // not used
}
void RDCH(u32 rt, u32 ra)
{
@ -256,14 +256,20 @@ private:
}
void MTSPR(u32 rt, u32 sa)
{
UNIMPLEMENTED();
UNIMPLEMENTED(); // not used
}
void WRCH(u32 ra, u32 rt)
{
CPU.WriteChannel(ra, CPU.GPR[rt]);
}
void BIZ(u32 rt, u32 ra)
void BIZ(u32 intr, u32 rt, u32 ra)
{
if (intr)
{
UNIMPLEMENTED();
return;
}
u64 target = branchTarget(CPU.GPR[ra]._u32[3], 0);
if (CPU.GPR[rt]._u32[3] == 0)
{
@ -275,8 +281,14 @@ private:
LOG5_OPCODE("not taken (0x%llx)", target);
}
}
void BINZ(u32 rt, u32 ra)
void BINZ(u32 intr, u32 rt, u32 ra)
{
if (intr)
{
UNIMPLEMENTED();
return;
}
u64 target = branchTarget(CPU.GPR[ra]._u32[3], 0);
if (CPU.GPR[rt]._u32[3] != 0)
{
@ -288,8 +300,14 @@ private:
LOG5_OPCODE("not taken (0x%llx)", target);
}
}
void BIHZ(u32 rt, u32 ra)
void BIHZ(u32 intr, u32 rt, u32 ra)
{
if (intr)
{
UNIMPLEMENTED();
return;
}
u64 target = branchTarget(CPU.GPR[ra]._u32[3], 0);
if (CPU.GPR[rt]._u16[6] == 0)
{
@ -301,8 +319,14 @@ private:
LOG5_OPCODE("not taken (0x%llx)", target);
}
}
void BIHNZ(u32 rt, u32 ra)
void BIHNZ(u32 intr, u32 rt, u32 ra)
{
if (intr)
{
UNIMPLEMENTED();
return;
}
u64 target = branchTarget(CPU.GPR[ra]._u32[3], 0);
if (CPU.GPR[rt]._u16[6] != 0)
{
@ -316,8 +340,7 @@ private:
}
void STOPD(u32 rc, u32 ra, u32 rb)
{
UNIMPLEMENTED();
Emu.Pause();
UNIMPLEMENTED(); // not used
}
void STQX(u32 rt, u32 ra, u32 rb)
{
@ -325,14 +348,26 @@ private:
CPU.WriteLS128(lsa, CPU.GPR[rt]._u128);
}
void BI(u32 ra)
void BI(u32 intr, u32 ra)
{
if (intr)
{
UNIMPLEMENTED();
return;
}
u64 target = branchTarget(CPU.GPR[ra]._u32[3], 0);
LOG5_OPCODE("branch (0x%llx)", target);
CPU.SetBranch(target);
}
void BISL(u32 rt, u32 ra)
void BISL(u32 intr, u32 rt, u32 ra)
{
if (intr)
{
UNIMPLEMENTED();
return;
}
u64 target = branchTarget(CPU.GPR[ra]._u32[3], 0);
CPU.GPR[rt].Reset();
CPU.GPR[rt]._u32[3] = CPU.PC + 4;
@ -341,12 +376,11 @@ private:
}
void IRET(u32 ra)
{
UNIMPLEMENTED();
//SetBranch(SRR0);
UNIMPLEMENTED(); // not used
}
void BISLED(u32 rt, u32 ra)
void BISLED(u32 intr, u32 rt, u32 ra)
{
UNIMPLEMENTED();
UNIMPLEMENTED(); // not used
}
void HBR(u32 p, u32 ro, u32 ra)
{
@ -756,8 +790,7 @@ private:
}
void DFCGT(u32 rt, u32 ra, u32 rb)
{
CPU.GPR[rt]._u64[0] = CPU.GPR[ra]._d[0] > CPU.GPR[rb]._d[0] ? 0xffffffffffffffff : 0;
CPU.GPR[rt]._u64[1] = CPU.GPR[ra]._d[1] > CPU.GPR[rb]._d[1] ? 0xffffffffffffffff : 0;
UNIMPLEMENTED(); // cannot be used
}
void FA(u32 rt, u32 ra, u32 rb)
{
@ -802,8 +835,7 @@ private:
}
void DFCMGT(u32 rt, u32 ra, u32 rb)
{
CPU.GPR[rt]._u64[0] = fabs(CPU.GPR[ra]._d[0]) > fabs(CPU.GPR[rb]._d[0]) ? 0xffffffffffffffff : 0;
CPU.GPR[rt]._u64[1] = fabs(CPU.GPR[ra]._d[1]) > fabs(CPU.GPR[rb]._d[1]) ? 0xffffffffffffffff : 0;
UNIMPLEMENTED(); // cannot be used
}
void DFA(u32 rt, u32 ra, u32 rb)
{
@ -875,11 +907,13 @@ private:
}
void CGX(u32 rt, u32 ra, u32 rb)
{
// rarely used
for (int w = 0; w < 4; w++)
CPU.GPR[rt]._u32[w] = ((u64)CPU.GPR[ra]._u32[w] + (u64)CPU.GPR[rb]._u32[w] + (u64)(CPU.GPR[rt]._u32[w] & 1)) >> 32;
}
void BGX(u32 rt, u32 ra, u32 rb)
{
// rarely used
s64 nResult;
for (int w = 0; w < 4; w++)
@ -902,10 +936,7 @@ private:
void FSCRRD(u32 rt)
{
/*CPU.GPR[rt]._u128.lo =
CPU.FPSCR.Exception0 << 20 &
CPU.FPSCR.*/
UNIMPLEMENTED();
UNIMPLEMENTED(); // TODO (rarely used)
}
void FESD(u32 rt, u32 ra)
{
@ -921,60 +952,11 @@ private:
}
void FSCRWR(u32 rt, u32 ra)
{
UNIMPLEMENTED();
UNIMPLEMENTED(); // TODO (rarely used)
}
void DFTSV(u32 rt, u32 ra, s32 i7)
{
const u64 DoubleExpMask = 0x7ff0000000000000;
const u64 DoubleFracMask = 0x000fffffffffffff;
const u64 DoubleSignMask = 0x8000000000000000;
const SPU_GPR_hdr temp = CPU.GPR[ra];
CPU.GPR[rt].Reset();
if (i7 & 1) //Negative Denorm Check (-, exp is zero, frac is non-zero)
for (int i = 0; i < 2; i++)
{
if (temp._u64[i] & DoubleFracMask)
if ((temp._u64[i] & (DoubleSignMask | DoubleExpMask)) == DoubleSignMask)
CPU.GPR[rt]._u64[i] = 0xffffffffffffffff;
}
if (i7 & 2) //Positive Denorm Check (+, exp is zero, frac is non-zero)
for (int i = 0; i < 2; i++)
{
if (temp._u64[i] & DoubleFracMask)
if ((temp._u64[i] & (DoubleSignMask | DoubleExpMask)) == 0)
CPU.GPR[rt]._u64[i] = 0xffffffffffffffff;
}
if (i7 & 4) //Negative Zero Check (-, exp is zero, frac is zero)
for (int i = 0; i < 2; i++)
{
if (temp._u64[i] == DoubleSignMask)
CPU.GPR[rt]._u64[i] = 0xffffffffffffffff;
}
if (i7 & 8) //Positive Zero Check (+, exp is zero, frac is zero)
for (int i = 0; i < 2; i++)
{
if (temp._u64[i] == 0)
CPU.GPR[rt]._u64[i] = 0xffffffffffffffff;
}
if (i7 & 16) //Negative Infinity Check (-, exp is 0x7ff, frac is zero)
for (int i = 0; i < 2; i++)
{
if (temp._u64[i] == (DoubleSignMask | DoubleExpMask))
CPU.GPR[rt]._u64[i] = 0xffffffffffffffff;
}
if (i7 & 32) //Positive Infinity Check (+, exp is 0x7ff, frac is zero)
for (int i = 0; i < 2; i++)
{
if (temp._u64[i] == DoubleExpMask)
CPU.GPR[rt]._u64[i] = 0xffffffffffffffff;
}
if (i7 & 64) //Not-a-Number Check (any sign, exp is 0x7ff, frac is non-zero)
for (int i = 0; i < 2; i++)
{
if (temp._u64[i] & DoubleFracMask)
if ((temp._u64[i] & DoubleExpMask) == DoubleExpMask)
CPU.GPR[rt]._u64[i] = 0xffffffffffffffff;
}
UNIMPLEMENTED(); // cannot be used
}
void FCEQ(u32 rt, u32 ra, u32 rb)
{
@ -985,8 +967,7 @@ private:
}
void DFCEQ(u32 rt, u32 ra, u32 rb)
{
CPU.GPR[rt]._u64[0] = CPU.GPR[ra]._d[0] == CPU.GPR[rb]._d[0] ? 0xffffffffffffffff : 0;
CPU.GPR[rt]._u64[1] = CPU.GPR[ra]._d[1] == CPU.GPR[rb]._d[1] ? 0xffffffffffffffff : 0;
UNIMPLEMENTED(); // cannot be used
}
void MPY(u32 rt, u32 ra, u32 rb)
{
@ -1022,8 +1003,7 @@ private:
}
void DFCMEQ(u32 rt, u32 ra, u32 rb)
{
CPU.GPR[rt]._u64[0] = fabs(CPU.GPR[ra]._d[0]) == fabs(CPU.GPR[rb]._d[0]) ? 0xffffffffffffffff : 0;
CPU.GPR[rt]._u64[1] = fabs(CPU.GPR[ra]._d[1]) == fabs(CPU.GPR[rb]._d[1]) ? 0xffffffffffffffff : 0;
UNIMPLEMENTED(); // cannot be used
}
void MPYU(u32 rt, u32 ra, u32 rb)
{
@ -1037,8 +1017,8 @@ private:
}
void FI(u32 rt, u32 ra, u32 rb)
{
//Floating Interpolation: ra will be ignored.
//It should work correctly if result of preceding FREST or FRSQEST is sufficiently exact
// TODO: Floating Interpolation: ra will be ignored.
// It should work correctly if result of preceding FREST or FRSQEST is sufficiently exact
CPU.GPR[rt] = CPU.GPR[rb];
}
void HEQ(u32 rt, u32 ra, u32 rb)

View File

@ -272,16 +272,16 @@ public:
virtual void AVGB(u32 rt, u32 ra, u32 rb) = 0;
virtual void MTSPR(u32 rt, u32 sa) = 0;
virtual void WRCH(u32 ra, u32 rt) = 0;
virtual void BIZ(u32 rt, u32 ra) = 0;
virtual void BINZ(u32 rt, u32 ra) = 0;
virtual void BIHZ(u32 rt, u32 ra) = 0;
virtual void BIHNZ(u32 rt, u32 ra) = 0;
virtual void BIZ(u32 intr, u32 rt, u32 ra) = 0;
virtual void BINZ(u32 intr, u32 rt, u32 ra) = 0;
virtual void BIHZ(u32 intr, u32 rt, u32 ra) = 0;
virtual void BIHNZ(u32 intr, u32 rt, u32 ra) = 0;
virtual void STOPD(u32 rc, u32 ra, u32 rb) = 0;
virtual void STQX(u32 rt, u32 ra, u32 rb) = 0;
virtual void BI(u32 ra) = 0;
virtual void BISL(u32 rt, u32 ra) = 0;
virtual void BI(u32 intr, u32 ra) = 0;
virtual void BISL(u32 intr, u32 rt, u32 ra) = 0;
virtual void IRET(u32 ra) = 0;
virtual void BISLED(u32 rt, u32 ra) = 0;
virtual void BISLED(u32 intr, u32 rt, u32 ra) = 0;
virtual void HBR(u32 p, u32 ro, u32 ra) = 0;
virtual void GB(u32 rt, u32 ra) = 0;
virtual void GBH(u32 rt, u32 ra) = 0;

View File

@ -1130,8 +1130,14 @@ private:
}
}*/
}
void BIZ(u32 rt, u32 ra)
void BIZ(u32 intr, u32 rt, u32 ra)
{
if (intr)
{
UNIMPLEMENTED();
return;
}
c.mov(cpu_qword(PC), (u32)CPU.PC);
do_finalize = true;
@ -1142,8 +1148,14 @@ private:
c.shr(*pos_var, 2);
LOG_OPCODE();
}
void BINZ(u32 rt, u32 ra)
void BINZ(u32 intr, u32 rt, u32 ra)
{
if (intr)
{
UNIMPLEMENTED();
return;
}
c.mov(cpu_qword(PC), (u32)CPU.PC);
do_finalize = true;
@ -1154,8 +1166,14 @@ private:
c.shr(*pos_var, 2);
LOG_OPCODE();
}
void BIHZ(u32 rt, u32 ra)
void BIHZ(u32 intr, u32 rt, u32 ra)
{
if (intr)
{
UNIMPLEMENTED();
return;
}
c.mov(cpu_qword(PC), (u32)CPU.PC);
do_finalize = true;
@ -1166,8 +1184,14 @@ private:
c.shr(*pos_var, 2);
LOG_OPCODE();
}
void BIHNZ(u32 rt, u32 ra)
void BIHNZ(u32 intr, u32 rt, u32 ra)
{
if (intr)
{
UNIMPLEMENTED();
return;
}
c.mov(cpu_qword(PC), (u32)CPU.PC);
do_finalize = true;
@ -1181,7 +1205,6 @@ private:
void STOPD(u32 rc, u32 ra, u32 rb)
{
UNIMPLEMENTED();
Emu.Pause();
}
void STQX(u32 rt, u32 ra, u32 rb)
{
@ -1210,8 +1233,14 @@ private:
LOG_OPCODE();
}
void BI(u32 ra)
void BI(u32 intr, u32 ra)
{
if (intr)
{
UNIMPLEMENTED();
return;
}
c.mov(cpu_qword(PC), (u32)CPU.PC);
do_finalize = true;
@ -1219,8 +1248,14 @@ private:
c.shr(*pos_var, 2);
LOG_OPCODE();
}
void BISL(u32 rt, u32 ra)
void BISL(u32 intr, u32 rt, u32 ra)
{
if (intr)
{
UNIMPLEMENTED();
return;
}
XmmInvalidate(rt);
c.mov(cpu_qword(PC), (u32)CPU.PC);
@ -1238,9 +1273,8 @@ private:
void IRET(u32 ra)
{
UNIMPLEMENTED();
//SetBranch(SRR0);
}
void BISLED(u32 rt, u32 ra)
void BISLED(u32 intr, u32 rt, u32 ra)
{
UNIMPLEMENTED();
}
@ -2049,18 +2083,7 @@ private:
}
void DFCGT(u32 rt, u32 ra, u32 rb)
{
// reverted less-than
const XmmLink& vb = XmmGet(rb, rt);
if (const XmmLink* va = XmmRead(ra))
{
c.cmppd(vb.get(), va->read(), 1);
}
else
{
c.cmppd(vb.get(), cpu_xmm(GPR[ra]), 1);
}
XmmFinalize(vb, rt);
LOG_OPCODE();
UNIMPLEMENTED();
}
void FA(u32 rt, u32 ra, u32 rb)
{
@ -2190,15 +2213,7 @@ private:
}
void DFCMGT(u32 rt, u32 ra, u32 rb)
{
// reverted less-than
const XmmLink& vb = XmmGet(rb, rt);
const XmmLink& va = XmmGet(ra);
c.andpd(vb.get(), XmmConst(_mm_set_epi32(0x7fffffff, 0xffffffff, 0x7fffffff, 0xffffffff))); // abs
c.andpd(va.get(), XmmConst(_mm_set_epi32(0x7fffffff, 0xffffffff, 0x7fffffff, 0xffffffff))); // abs
c.cmppd(vb.get(), va.get(), 1);
XmmFinalize(vb, rt);
XmmFinalize(va);
LOG_OPCODE();
UNIMPLEMENTED();
}
void DFA(u32 rt, u32 ra, u32 rb)
{
@ -2484,58 +2499,7 @@ private:
}
void DFTSV(u32 rt, u32 ra, s32 i7) //nf
{
WRAPPER_BEGIN(rt, ra, i7, zz);
const u64 DoubleExpMask = 0x7ff0000000000000;
const u64 DoubleFracMask = 0x000fffffffffffff;
const u64 DoubleSignMask = 0x8000000000000000;
const SPU_GPR_hdr temp = CPU.GPR[ra];
CPU.GPR[rt].Reset();
if (i7 & 1) //Negative Denorm Check (-, exp is zero, frac is non-zero)
for (int i = 0; i < 2; i++)
{
if (temp._u64[i] & DoubleFracMask)
if ((temp._u64[i] & (DoubleSignMask | DoubleExpMask)) == DoubleSignMask)
CPU.GPR[rt]._u64[i] = 0xffffffffffffffff;
}
if (i7 & 2) //Positive Denorm Check (+, exp is zero, frac is non-zero)
for (int i = 0; i < 2; i++)
{
if (temp._u64[i] & DoubleFracMask)
if ((temp._u64[i] & (DoubleSignMask | DoubleExpMask)) == 0)
CPU.GPR[rt]._u64[i] = 0xffffffffffffffff;
}
if (i7 & 4) //Negative Zero Check (-, exp is zero, frac is zero)
for (int i = 0; i < 2; i++)
{
if (temp._u64[i] == DoubleSignMask)
CPU.GPR[rt]._u64[i] = 0xffffffffffffffff;
}
if (i7 & 8) //Positive Zero Check (+, exp is zero, frac is zero)
for (int i = 0; i < 2; i++)
{
if (temp._u64[i] == 0)
CPU.GPR[rt]._u64[i] = 0xffffffffffffffff;
}
if (i7 & 16) //Negative Infinity Check (-, exp is 0x7ff, frac is zero)
for (int i = 0; i < 2; i++)
{
if (temp._u64[i] == (DoubleSignMask | DoubleExpMask))
CPU.GPR[rt]._u64[i] = 0xffffffffffffffff;
}
if (i7 & 32) //Positive Infinity Check (+, exp is 0x7ff, frac is zero)
for (int i = 0; i < 2; i++)
{
if (temp._u64[i] == DoubleExpMask)
CPU.GPR[rt]._u64[i] = 0xffffffffffffffff;
}
if (i7 & 64) //Not-a-Number Check (any sign, exp is 0x7ff, frac is non-zero)
for (int i = 0; i < 2; i++)
{
if (temp._u64[i] & DoubleFracMask)
if ((temp._u64[i] & DoubleExpMask) == DoubleExpMask)
CPU.GPR[rt]._u64[i] = 0xffffffffffffffff;
}
WRAPPER_END(rt, ra, i7, 0);
UNIMPLEMENTED();
}
void FCEQ(u32 rt, u32 ra, u32 rb)
{
@ -2554,18 +2518,7 @@ private:
}
void DFCEQ(u32 rt, u32 ra, u32 rb)
{
// compare equal
const XmmLink& vb = XmmGet(rb, rt);
if (const XmmLink* va = XmmRead(ra))
{
c.cmppd(vb.get(), va->read(), 0);
}
else
{
c.cmppd(vb.get(), cpu_xmm(GPR[ra]), 0);
}
XmmFinalize(vb, rt);
LOG_OPCODE();
UNIMPLEMENTED();
}
void MPY(u32 rt, u32 ra, u32 rb)
{
@ -2649,14 +2602,7 @@ private:
}
void DFCMEQ(u32 rt, u32 ra, u32 rb)
{
const XmmLink& vb = XmmGet(rb, rt);
const XmmLink& va = XmmGet(ra);
c.andpd(vb.get(), XmmConst(_mm_set_epi32(0x7fffffff, 0xffffffff, 0x7fffffff, 0xffffffff))); // abs
c.andpd(va.get(), XmmConst(_mm_set_epi32(0x7fffffff, 0xffffffff, 0x7fffffff, 0xffffffff))); // abs
c.cmppd(vb.get(), va.get(), 0); // ==
XmmFinalize(vb, rt);
XmmFinalize(va);
LOG_OPCODE();
UNIMPLEMENTED();
}
void MPYU(u32 rt, u32 ra, u32 rb)
{