mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-01-30 12:32:43 +00:00
SPU LLVM: Inline timer reads for WrDec and RdDec
- Uses RDTSC to emulate the spu decrementer
This commit is contained in:
parent
f199ad7a42
commit
f2e782f5dd
@ -6521,6 +6521,24 @@ public:
|
||||
}
|
||||
case SPU_RdDec:
|
||||
{
|
||||
if (utils::get_tsc_freq() && !(g_cfg.core.spu_loop_detection) && (g_cfg.core.clocks_scale == 100))
|
||||
{
|
||||
const auto timestamp = m_ir->CreateLoad(get_type<u64>(), spu_ptr<u64>(&spu_thread::ch_dec_start_timestamp));
|
||||
const auto dec_value = m_ir->CreateLoad(get_type<u32>(), spu_ptr<u32>(&spu_thread::ch_dec_value));
|
||||
const auto tsc = m_ir->CreateCall(get_intrinsic(llvm::Intrinsic::x86_rdtsc));
|
||||
const auto tscx = m_ir->CreateMul(m_ir->CreateUDiv(tsc, m_ir->getInt64(utils::get_tsc_freq())), m_ir->getInt64(80000000));
|
||||
const auto tscm = m_ir->CreateUDiv(m_ir->CreateMul(m_ir->CreateURem(tsc, m_ir->getInt64(utils::get_tsc_freq())), m_ir->getInt64(80000000)), m_ir->getInt64(utils::get_tsc_freq()));
|
||||
const auto tsctb = m_ir->CreateAdd(tscx, tscm);
|
||||
|
||||
const auto frz = m_ir->CreateLoad(get_type<u8>(), spu_ptr<u8>(&spu_thread::is_dec_frozen));
|
||||
const auto frzev = m_ir->CreateICmpEQ(frz, m_ir->getInt8(0));
|
||||
|
||||
const auto delta = m_ir->CreateTrunc(m_ir->CreateSub(tsctb, timestamp), get_type<u32>());
|
||||
const auto deltax = m_ir->CreateSelect(frzev, delta, m_ir->getInt32(0));
|
||||
res.value = m_ir->CreateSub(dec_value, deltax);
|
||||
break;
|
||||
}
|
||||
|
||||
res.value = call("spu_read_decrementer", &exec_read_dec, m_thread);
|
||||
break;
|
||||
}
|
||||
@ -7188,7 +7206,20 @@ public:
|
||||
case SPU_WrDec:
|
||||
{
|
||||
call("spu_get_events", &exec_get_events, m_thread, m_ir->getInt32(SPU_EVENT_TM));
|
||||
m_ir->CreateStore(call("get_timebased_time", &get_timebased_time), spu_ptr<u64>(&spu_thread::ch_dec_start_timestamp));
|
||||
|
||||
if (utils::get_tsc_freq() && !(g_cfg.core.spu_loop_detection) && (g_cfg.core.clocks_scale == 100))
|
||||
{
|
||||
const auto tsc = m_ir->CreateCall(get_intrinsic(llvm::Intrinsic::x86_rdtsc));
|
||||
const auto tscx = m_ir->CreateMul(m_ir->CreateUDiv(tsc, m_ir->getInt64(utils::get_tsc_freq())), m_ir->getInt64(80000000));
|
||||
const auto tscm = m_ir->CreateUDiv(m_ir->CreateMul(m_ir->CreateURem(tsc, m_ir->getInt64(utils::get_tsc_freq())), m_ir->getInt64(80000000)), m_ir->getInt64(utils::get_tsc_freq()));
|
||||
const auto tsctb = m_ir->CreateAdd(tscx, tscm);
|
||||
m_ir->CreateStore(tsctb, spu_ptr<u64>(&spu_thread::ch_dec_start_timestamp));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ir->CreateStore(call("get_timebased_time", &get_timebased_time), spu_ptr<u64>(&spu_thread::ch_dec_start_timestamp));
|
||||
}
|
||||
|
||||
m_ir->CreateStore(val.value, spu_ptr<u32>(&spu_thread::ch_dec_value));
|
||||
m_ir->CreateStore(m_ir->getInt8(0), spu_ptr<u8>(&spu_thread::is_dec_frozen));
|
||||
return;
|
||||
|
@ -38,7 +38,7 @@ struct cfg_root : cfg::node
|
||||
cfg::_bool mfc_debug{ this, "MFC Debug" };
|
||||
cfg::_int<0, 6> preferred_spu_threads{ this, "Preferred SPU Threads", 0, true }; // Number of hardware threads dedicated to heavy simultaneous spu tasks
|
||||
cfg::_int<0, 16> spu_delay_penalty{ this, "SPU delay penalty", 3 }; // Number of milliseconds to block a thread if a virtual 'core' isn't free
|
||||
cfg::_bool spu_loop_detection{ this, "SPU loop detection", false, true }; // Try to detect wait loops and trigger thread yield
|
||||
cfg::_bool spu_loop_detection{ this, "SPU loop detection", false }; // Try to detect wait loops and trigger thread yield
|
||||
cfg::_int<0, 6> max_spurs_threads{ this, "Max SPURS Threads", 6 }; // HACK. If less then 6, max number of running SPURS threads in each thread group.
|
||||
cfg::_enum<spu_block_size_type> spu_block_size{ this, "SPU Block Size", spu_block_size_type::safe };
|
||||
cfg::_bool spu_accurate_getllar{ this, "Accurate GETLLAR", false, true };
|
||||
|
Loading…
x
Reference in New Issue
Block a user