SPU: simplify unimplemented event check

Move checks closer to the actual use
This commit is contained in:
Nekotekina 2018-07-02 01:02:34 +03:00
parent afd5af04f6
commit a0c0d8b993
2 changed files with 38 additions and 60 deletions

View file

@ -1442,6 +1442,13 @@ bool SPUThread::process_mfc_cmd(spu_mfc_cmd args)
u32 SPUThread::get_events(bool waiting)
{
const u32 mask1 = ch_event_mask;
if (mask1 & ~SPU_EVENT_IMPLEMENTED)
{
fmt::throw_exception("SPU Events not implemented (mask=0x%x)" HERE, mask1);
}
// Check reservation status and set SPU_EVENT_LR if lost
if (raddr && (vm::reservation_acquire(raddr, sizeof(rdata)) != rtime || rdata != vm::_ref<decltype(rdata)>(raddr)))
{
@ -1459,9 +1466,9 @@ u32 SPUThread::get_events(bool waiting)
}
// Simple polling or polling with atomically set/removed SPU_EVENT_WAITING flag
return !waiting ? ch_event_stat & ch_event_mask : ch_event_stat.atomic_op([&](u32& stat) -> u32
return !waiting ? ch_event_stat & mask1 : ch_event_stat.atomic_op([&](u32& stat) -> u32
{
if (u32 res = stat & ch_event_mask)
if (u32 res = stat & mask1)
{
stat &= ~SPU_EVENT_WAITING;
return res;
@ -1474,9 +1481,9 @@ u32 SPUThread::get_events(bool waiting)
void SPUThread::set_events(u32 mask)
{
if (u32 unimpl = mask & ~SPU_EVENT_IMPLEMENTED)
if (mask & ~SPU_EVENT_IMPLEMENTED)
{
fmt::throw_exception("Unimplemented events (0x%x)" HERE, unimpl);
fmt::throw_exception("SPU Events not implemented (mask=0x%x)" HERE, mask);
}
// Set new events, get old event mask
@ -1493,11 +1500,12 @@ void SPUThread::set_interrupt_status(bool enable)
{
if (enable)
{
// detect enabling interrupts with events masked
if (u32 mask = ch_event_mask & ~SPU_EVENT_INTR_IMPLEMENTED)
// Detect enabling interrupts with events masked
if (ch_event_mask & ~SPU_EVENT_INTR_IMPLEMENTED)
{
fmt::throw_exception("SPU Interrupts not implemented (mask=0x%x)" HERE, mask);
fmt::throw_exception("SPU Interrupts not implemented (mask=0x%x)" HERE, +ch_event_mask);
}
interrupts_enabled = true;
}
else
@ -2007,29 +2015,12 @@ bool SPUThread::set_ch_value(u32 ch, u32 value)
case SPU_WrEventMask:
{
// detect masking events with enabled interrupt status
if (value & ~SPU_EVENT_INTR_IMPLEMENTED && interrupts_enabled)
{
fmt::throw_exception("SPU Interrupts not implemented (mask=0x%x)" HERE, value);
}
// detect masking unimplemented events
if (value & ~SPU_EVENT_IMPLEMENTED)
{
break;
}
ch_event_mask = value;
return true;
}
case SPU_WrEventAck:
{
if (value & ~SPU_EVENT_IMPLEMENTED)
{
break;
}
ch_event_stat &= ~value;
return true;
}