SPU: Implement many missing channel counts

This commit is contained in:
Eladash 2020-09-19 19:40:47 +03:00 committed by Ivan
parent 418968d974
commit ad37259ccc
3 changed files with 78 additions and 2 deletions

View file

@ -1559,7 +1559,6 @@ void spu_recompiler::RCHCNT(spu_opcode_t op)
case MFC_WrTagUpdate:
{
const XmmLink& vr = XmmAlloc();
const XmmLink& v1 = XmmAlloc();
c->mov(addr->r32(), 1);
c->movd(vr, addr->r32());
c->pslldq(vr, 12);
@ -1588,6 +1587,34 @@ void spu_recompiler::RCHCNT(spu_opcode_t op)
c->movdqa(SPU_OFF_128(gpr, op.rt), vr);
return;
}
// Channels with a constant count of 1:
case SPU_WrEventMask:
case SPU_WrEventAck:
case SPU_WrDec:
case SPU_RdDec:
case SPU_RdEventMask:
case SPU_RdMachStat:
case SPU_WrSRR0:
case SPU_RdSRR0:
case SPU_Set_Bkmk_Tag:
case SPU_PM_Start_Ev:
case SPU_PM_Stop_Ev:
case MFC_RdTagMask:
case MFC_LSA:
case MFC_EAH:
case MFC_EAL:
case MFC_Size:
case MFC_TagID:
case MFC_WrTagMask:
case MFC_WrListStallAck:
{
const XmmLink& vr = XmmAlloc();
c->mov(addr->r32(), 1);
c->movd(vr, addr->r32());
c->pslldq(vr, 12);
c->movdqa(SPU_OFF_128(gpr, op.rt), vr);
return;
}
case SPU_RdEventStat:
{
spu_log.warning("[0x%x] RCHCNT: RdEventStat", m_pos);

View file

@ -5602,6 +5602,31 @@ public:
break;
}
// Channels with a constant count of 1:
case SPU_WrEventMask:
case SPU_WrEventAck:
case SPU_WrDec:
case SPU_RdDec:
case SPU_RdEventMask:
case SPU_RdMachStat:
case SPU_WrSRR0:
case SPU_RdSRR0:
case SPU_Set_Bkmk_Tag:
case SPU_PM_Start_Ev:
case SPU_PM_Stop_Ev:
case MFC_RdTagMask:
case MFC_LSA:
case MFC_EAH:
case MFC_EAL:
case MFC_Size:
case MFC_TagID:
case MFC_WrTagMask:
case MFC_WrListStallAck:
{
res.value = m_ir->getInt32(1);
break;
}
default:
{
res.value = call("spu_read_channel_count", &exec_rchcnt, m_thread, m_ir->getInt32(op.ra));
@ -6091,7 +6116,9 @@ public:
m_ir->CreateStore(val.value, spu_ptr<u32>(&spu_thread::ch_dec_value));
return;
}
case 69:
case SPU_Set_Bkmk_Tag:
case SPU_PM_Start_Ev:
case SPU_PM_Stop_Ev:
{
return;
}

View file

@ -2512,6 +2512,28 @@ u32 spu_thread::get_ch_count(u32 ch)
case MFC_RdAtomicStat: return ch_atomic_stat.get_count();
case SPU_RdEventStat: return get_events().count;
case MFC_Cmd: return 16 - mfc_size;
// Channels with a constant count of 1:
case SPU_WrEventMask:
case SPU_WrEventAck:
case SPU_WrDec:
case SPU_RdDec:
case SPU_RdEventMask:
case SPU_RdMachStat:
case SPU_WrSRR0:
case SPU_RdSRR0:
case SPU_Set_Bkmk_Tag:
case SPU_PM_Start_Ev:
case SPU_PM_Stop_Ev:
case MFC_RdTagMask:
case MFC_LSA:
case MFC_EAH:
case MFC_EAL:
case MFC_Size:
case MFC_TagID:
case MFC_WrTagMask:
case MFC_WrListStallAck:
return 1;
}
fmt::throw_exception("Unknown/illegal channel in RCHCNT (ch=%d [%s])" HERE, ch, ch < 128 ? spu_ch_name[ch] : "???");