mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-08 07:51:28 +12:00
SPU ASMJIT: internal jumptable
Allow indirect calls within current function using a jumptable This restores some functionality removed in SPU ASMJIT 2.0 Change SPUThread::get_ch_value prototype
This commit is contained in:
parent
df453d6d4f
commit
767dfa271e
7 changed files with 302 additions and 229 deletions
|
@ -119,6 +119,22 @@ void fmt_class_string<spu_decoder_type>::format(std::string& out, u64 arg)
|
|||
});
|
||||
}
|
||||
|
||||
template <>
|
||||
void fmt_class_string<spu_block_size_type>::format(std::string& out, u64 arg)
|
||||
{
|
||||
format_enum(out, arg, [](spu_block_size_type type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case spu_block_size_type::safe: return "Safe";
|
||||
case spu_block_size_type::mega: return "Mega";
|
||||
case spu_block_size_type::giga: return "Giga";
|
||||
}
|
||||
|
||||
return unknown;
|
||||
});
|
||||
}
|
||||
|
||||
namespace spu
|
||||
{
|
||||
namespace scheduler
|
||||
|
@ -1497,11 +1513,11 @@ u32 SPUThread::get_ch_count(u32 ch)
|
|||
fmt::throw_exception("Unknown/illegal channel (ch=%d [%s])" HERE, ch, ch < 128 ? spu_ch_name[ch] : "???");
|
||||
}
|
||||
|
||||
bool SPUThread::get_ch_value(u32 ch, u32& out)
|
||||
s64 SPUThread::get_ch_value(u32 ch)
|
||||
{
|
||||
LOG_TRACE(SPU, "get_ch_value(ch=%d [%s])", ch, ch < 128 ? spu_ch_name[ch] : "???");
|
||||
|
||||
auto read_channel = [&](spu_channel& channel)
|
||||
auto read_channel = [&](spu_channel& channel) -> s64
|
||||
{
|
||||
for (int i = 0; i < 10 && channel.get_count() == 0; i++)
|
||||
{
|
||||
|
@ -1515,25 +1531,26 @@ bool SPUThread::get_ch_value(u32 ch, u32& out)
|
|||
}
|
||||
}
|
||||
|
||||
u32 out;
|
||||
|
||||
while (!channel.try_pop(out))
|
||||
{
|
||||
if (test(state, cpu_flag::stop))
|
||||
{
|
||||
return false;
|
||||
return -1;
|
||||
}
|
||||
|
||||
thread_ctrl::wait();
|
||||
}
|
||||
|
||||
return true;
|
||||
return out;
|
||||
};
|
||||
|
||||
switch (ch)
|
||||
{
|
||||
case SPU_RdSRR0:
|
||||
{
|
||||
out = srr0;
|
||||
return true;
|
||||
return srr0;
|
||||
}
|
||||
case SPU_RdInMbox:
|
||||
{
|
||||
|
@ -1551,6 +1568,8 @@ bool SPUThread::get_ch_value(u32 ch, u32& out)
|
|||
}
|
||||
}
|
||||
|
||||
u32 out;
|
||||
|
||||
if (const uint old_count = ch_in_mbox.try_pop(out))
|
||||
{
|
||||
if (old_count == 4 /* SPU_IN_MBOX_THRESHOLD */) // TODO: check this
|
||||
|
@ -1558,12 +1577,12 @@ bool SPUThread::get_ch_value(u32 ch, u32& out)
|
|||
int_ctrl[2].set(SPU_INT2_STAT_SPU_MAILBOX_THRESHOLD_INT);
|
||||
}
|
||||
|
||||
return true;
|
||||
return out;
|
||||
}
|
||||
|
||||
if (test(state & cpu_flag::stop))
|
||||
{
|
||||
return false;
|
||||
return -1;
|
||||
}
|
||||
|
||||
thread_ctrl::wait();
|
||||
|
@ -1579,9 +1598,9 @@ bool SPUThread::get_ch_value(u32 ch, u32& out)
|
|||
|
||||
if (ch_tag_stat.get_count())
|
||||
{
|
||||
out = ch_tag_stat.get_value();
|
||||
u32 out = ch_tag_stat.get_value();
|
||||
ch_tag_stat.set_value(0, false);
|
||||
return true;
|
||||
return out;
|
||||
}
|
||||
|
||||
// Will stall infinitely
|
||||
|
@ -1590,8 +1609,7 @@ bool SPUThread::get_ch_value(u32 ch, u32& out)
|
|||
|
||||
case MFC_RdTagMask:
|
||||
{
|
||||
out = ch_tag_mask;
|
||||
return true;
|
||||
return ch_tag_mask;
|
||||
}
|
||||
|
||||
case SPU_RdSigNotify1:
|
||||
|
@ -1608,9 +1626,9 @@ bool SPUThread::get_ch_value(u32 ch, u32& out)
|
|||
{
|
||||
if (ch_atomic_stat.get_count())
|
||||
{
|
||||
out = ch_atomic_stat.get_value();
|
||||
u32 out = ch_atomic_stat.get_value();
|
||||
ch_atomic_stat.set_value(0, false);
|
||||
return true;
|
||||
return out;
|
||||
}
|
||||
|
||||
// Will stall infinitely
|
||||
|
@ -1621,9 +1639,9 @@ bool SPUThread::get_ch_value(u32 ch, u32& out)
|
|||
{
|
||||
if (ch_stall_stat.get_count())
|
||||
{
|
||||
out = ch_stall_stat.get_value();
|
||||
u32 out = ch_stall_stat.get_value();
|
||||
ch_stall_stat.set_value(0, false);
|
||||
return true;
|
||||
return out;
|
||||
}
|
||||
|
||||
// Will stall infinitely
|
||||
|
@ -1632,19 +1650,18 @@ bool SPUThread::get_ch_value(u32 ch, u32& out)
|
|||
|
||||
case SPU_RdDec:
|
||||
{
|
||||
out = ch_dec_value - (u32)(get_timebased_time() - ch_dec_start_timestamp);
|
||||
u32 out = ch_dec_value - (u32)(get_timebased_time() - ch_dec_start_timestamp);
|
||||
|
||||
//Polling: We might as well hint to the scheduler to slot in another thread since this one is counting down
|
||||
if (g_cfg.core.spu_loop_detection && out > spu::scheduler::native_jiffy_duration_us)
|
||||
std::this_thread::yield();
|
||||
|
||||
return true;
|
||||
return out;
|
||||
}
|
||||
|
||||
case SPU_RdEventMask:
|
||||
{
|
||||
out = ch_event_mask;
|
||||
return true;
|
||||
return ch_event_mask;
|
||||
}
|
||||
|
||||
case SPU_RdEventStat:
|
||||
|
@ -1658,8 +1675,7 @@ bool SPUThread::get_ch_value(u32 ch, u32& out)
|
|||
|
||||
if (res)
|
||||
{
|
||||
out = res;
|
||||
return true;
|
||||
return res;
|
||||
}
|
||||
|
||||
vm::waiter waiter;
|
||||
|
@ -1678,22 +1694,20 @@ bool SPUThread::get_ch_value(u32 ch, u32& out)
|
|||
{
|
||||
if (test(state & cpu_flag::stop))
|
||||
{
|
||||
return false;
|
||||
return -1;
|
||||
}
|
||||
|
||||
thread_ctrl::wait_for(100);
|
||||
}
|
||||
|
||||
out = res;
|
||||
return true;
|
||||
return res;
|
||||
}
|
||||
|
||||
case SPU_RdMachStat:
|
||||
{
|
||||
// HACK: "Not isolated" status
|
||||
// Return SPU Interrupt status in LSB
|
||||
out = interrupts_enabled == true;
|
||||
return true;
|
||||
return interrupts_enabled == true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue