mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-20 11:36:13 +00:00
SPU LLVM: Subtract Timebase from decrementer
This commit is contained in:
parent
a3d2e93b14
commit
5e4637e15c
3 changed files with 14 additions and 10 deletions
|
@ -5,6 +5,7 @@
|
|||
#include "Emu/system_config.h"
|
||||
#include "Emu/IdManager.h"
|
||||
#include "Emu/Cell/timers.hpp"
|
||||
#include "Emu/Cell/lv2/sys_time.h"
|
||||
#include "Emu/Memory/vm_reservation.h"
|
||||
#include "Emu/RSX/Core/RSXReservationLock.hpp"
|
||||
#include "Crypto/sha1.h"
|
||||
|
@ -3482,13 +3483,13 @@ public:
|
|||
#if defined(ARCH_X64)
|
||||
if (utils::get_tsc_freq() && !(g_cfg.core.spu_loop_detection) && (g_cfg.core.clocks_scale == 100))
|
||||
{
|
||||
const auto timebase_offs = m_ir->CreateLoad(get_type<u64>(), m_ir->CreateIntToPtr(m_ir->getInt64(reinterpret_cast<u64>(&g_timebase_offs)), get_type<u64*>()));
|
||||
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 tsctb = m_ir->CreateSub(m_ir->CreateAdd(tscx, tscm), timebase_offs);
|
||||
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));
|
||||
|
||||
|
@ -4305,10 +4306,11 @@ public:
|
|||
#if defined(ARCH_X64)
|
||||
if (utils::get_tsc_freq() && !(g_cfg.core.spu_loop_detection) && (g_cfg.core.clocks_scale == 100))
|
||||
{
|
||||
const auto timebase_offs = m_ir->CreateLoad(get_type<u64>(), m_ir->CreateIntToPtr(m_ir->getInt64(reinterpret_cast<u64>(&g_timebase_offs)), get_type<u64*>()));
|
||||
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 tsctb = m_ir->CreateSub(m_ir->CreateAdd(tscx, tscm), timebase_offs);
|
||||
m_ir->CreateStore(tsctb, spu_ptr<u64>(&spu_thread::ch_dec_start_timestamp));
|
||||
}
|
||||
else
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
#include "util/sysinfo.hpp"
|
||||
|
||||
static u64 timebase_offset;
|
||||
u64 g_timebase_offs{};
|
||||
static u64 systemtime_offset;
|
||||
|
||||
#ifndef __linux__
|
||||
|
@ -145,8 +145,8 @@ static constexpr u64 g_timebase_freq = /*79800000*/ 80000000ull; // 80 Mhz
|
|||
u64 convert_to_timebased_time(u64 time)
|
||||
{
|
||||
const u64 result = time * (g_timebase_freq / 1000000ull) * g_cfg.core.clocks_scale / 100u;
|
||||
ensure(result >= timebase_offset);
|
||||
return result - timebase_offset;
|
||||
ensure(result >= g_timebase_offs);
|
||||
return result - g_timebase_offs;
|
||||
}
|
||||
|
||||
u64 get_timebased_time()
|
||||
|
@ -160,7 +160,7 @@ u64 get_timebased_time()
|
|||
#else
|
||||
const u64 result = (tsc / freq * g_timebase_freq + tsc % freq * g_timebase_freq / freq) * g_cfg.core.clocks_scale / 100u;
|
||||
#endif
|
||||
return result - timebase_offset;
|
||||
return result - g_timebase_offs;
|
||||
}
|
||||
|
||||
while (true)
|
||||
|
@ -183,7 +183,7 @@ u64 get_timebased_time()
|
|||
|
||||
const u64 result = (static_cast<u64>(ts.tv_sec) * g_timebase_freq + static_cast<u64>(ts.tv_nsec) * g_timebase_freq / 1000000000ull) * g_cfg.core.clocks_scale / 100u;
|
||||
#endif
|
||||
if (result) return result - timebase_offset;
|
||||
if (result) return result - g_timebase_offs;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -192,7 +192,7 @@ u64 get_timebased_time()
|
|||
// If none-zero arg is specified it will become the base time (for savestates)
|
||||
void initialize_timebased_time(u64 timebased_init, bool reset)
|
||||
{
|
||||
timebase_offset = 0;
|
||||
g_timebase_offs = 0;
|
||||
|
||||
if (reset)
|
||||
{
|
||||
|
@ -204,7 +204,7 @@ void initialize_timebased_time(u64 timebased_init, bool reset)
|
|||
const u64 current = get_timebased_time();
|
||||
timebased_init = current - timebased_init;
|
||||
|
||||
timebase_offset = timebased_init;
|
||||
g_timebase_offs = timebased_init;
|
||||
systemtime_offset = timebased_init / (g_timebase_freq / 1000000);
|
||||
}
|
||||
|
||||
|
|
|
@ -11,3 +11,5 @@ error_code sys_time_get_current_time(vm::ptr<s64> sec, vm::ptr<s64> nsec);
|
|||
error_code sys_time_set_current_time(s64 sec, s64 nsec);
|
||||
u64 sys_time_get_timebase_frequency();
|
||||
error_code sys_time_get_rtc(vm::ptr<u64> rtc);
|
||||
|
||||
extern u64 g_timebase_offs;
|
||||
|
|
Loading…
Add table
Reference in a new issue