SPU: Implement events channel count, minor interrupts fixes

This commit is contained in:
eladash 2018-08-06 10:19:47 +03:00 committed by kd-11
parent cdc3ee6c1c
commit 36ac68b436
7 changed files with 160 additions and 267 deletions

View file

@ -5387,11 +5387,6 @@ public:
static u32 exec_read_events(spu_thread* _spu)
{
if (const u32 events = _spu->get_events(_spu->ch_event_mask))
{
return events;
}
// TODO
return exec_rdch(_spu, SPU_RdEventStat);
}
@ -5490,7 +5485,7 @@ public:
}
case SPU_RdEventMask:
{
res.value = m_ir->CreateLoad(spu_ptr<u32>(&spu_thread::ch_event_mask));
res.value = m_ir->CreateTrunc(m_ir->CreateLShr(m_ir->CreateLoad(spu_ptr<u64>(&spu_thread::ch_events), true), 32), get_type<u32>());
break;
}
case SPU_RdEventStat:
@ -5524,7 +5519,7 @@ public:
static u32 exec_get_events(spu_thread* _spu, u32 mask)
{
return _spu->get_events(mask);
return _spu->get_events(mask).count;
}
llvm::Value* get_rchcnt(u32 off, u64 inv = 0)
@ -5602,9 +5597,8 @@ public:
}
case SPU_RdEventStat:
{
res.value = call("spu_get_events", &exec_get_events, m_thread, m_ir->CreateLoad(spu_ptr<u32>(&spu_thread::ch_event_mask)));
res.value = m_ir->CreateICmpNE(res.value, m_ir->getInt32(0));
res.value = m_ir->CreateZExt(res.value, get_type<u32>());
const auto mask = m_ir->CreateTrunc(m_ir->CreateLShr(m_ir->CreateLoad(spu_ptr<u64>(&spu_thread::ch_events), true), 32), get_type<u32>());
res.value = call("spu_get_events", &exec_get_events, m_thread, mask);
break;
}
@ -6097,18 +6091,6 @@ public:
m_ir->CreateStore(val.value, spu_ptr<u32>(&spu_thread::ch_dec_value));
return;
}
case SPU_WrEventMask:
{
m_ir->CreateStore(val.value, spu_ptr<u32>(&spu_thread::ch_event_mask))->setVolatile(true);
return;
}
case SPU_WrEventAck:
{
// "Collect" events before final acknowledgment
call("spu_get_events", &exec_get_events, m_thread, val.value);
m_ir->CreateAtomicRMW(llvm::AtomicRMWInst::And, spu_ptr<u32>(&spu_thread::ch_event_stat), eval(~val).value, llvm::AtomicOrdering::Release);
return;
}
case 69:
{
return;
@ -8280,7 +8262,7 @@ public:
{
_spu->set_interrupt_status(true);
if ((_spu->ch_event_mask & _spu->ch_event_stat & SPU_EVENT_INTR_IMPLEMENTED) > 0)
if (_spu->ch_events.load().count)
{
_spu->interrupts_enabled = false;
_spu->srr0 = addr;
@ -8586,7 +8568,8 @@ public:
if (m_block) m_block->block_end = m_ir->GetInsertBlock();
const auto addr = eval(extract(get_vr(op.ra), 3) & 0x3fffc);
set_link(op);
const auto res = call("spu_get_events", &exec_get_events, m_thread, m_ir->CreateLoad(spu_ptr<u32>(&spu_thread::ch_event_mask)));
const auto mask = m_ir->CreateTrunc(m_ir->CreateLShr(m_ir->CreateLoad(spu_ptr<u64>(&spu_thread::ch_events), true), 32), get_type<u32>());
const auto res = call("spu_get_events", &exec_get_events, m_thread, mask);
const auto target = add_block_indirect(op, addr);
m_ir->CreateCondBr(m_ir->CreateICmpNE(res, m_ir->getInt32(0)), target, add_block_next());
}