diff --git a/rpcs3/Emu/Cell/SPULLVMRecompiler.cpp b/rpcs3/Emu/Cell/SPULLVMRecompiler.cpp index cfa047f2ed..f1bb474e6f 100644 --- a/rpcs3/Emu/Cell/SPULLVMRecompiler.cpp +++ b/rpcs3/Emu/Cell/SPULLVMRecompiler.cpp @@ -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(), m_ir->CreateIntToPtr(m_ir->getInt64(reinterpret_cast(&g_timebase_offs)), get_type())); const auto timestamp = m_ir->CreateLoad(get_type(), spu_ptr(&spu_thread::ch_dec_start_timestamp)); const auto dec_value = m_ir->CreateLoad(get_type(), spu_ptr(&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(), spu_ptr(&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(), m_ir->CreateIntToPtr(m_ir->getInt64(reinterpret_cast(&g_timebase_offs)), get_type())); 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(&spu_thread::ch_dec_start_timestamp)); } else diff --git a/rpcs3/Emu/Cell/lv2/sys_time.cpp b/rpcs3/Emu/Cell/lv2/sys_time.cpp index 1413304a8b..539bb9dedf 100644 --- a/rpcs3/Emu/Cell/lv2/sys_time.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_time.cpp @@ -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(ts.tv_sec) * g_timebase_freq + static_cast(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); } diff --git a/rpcs3/Emu/Cell/lv2/sys_time.h b/rpcs3/Emu/Cell/lv2/sys_time.h index 63a0d1b4b6..fd8c729ab3 100644 --- a/rpcs3/Emu/Cell/lv2/sys_time.h +++ b/rpcs3/Emu/Cell/lv2/sys_time.h @@ -11,3 +11,5 @@ error_code sys_time_get_current_time(vm::ptr sec, vm::ptr 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 rtc); + +extern u64 g_timebase_offs;