mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-28 13:28:01 +03: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/system_config.h"
|
||||||
#include "Emu/IdManager.h"
|
#include "Emu/IdManager.h"
|
||||||
#include "Emu/Cell/timers.hpp"
|
#include "Emu/Cell/timers.hpp"
|
||||||
|
#include "Emu/Cell/lv2/sys_time.h"
|
||||||
#include "Emu/Memory/vm_reservation.h"
|
#include "Emu/Memory/vm_reservation.h"
|
||||||
#include "Emu/RSX/Core/RSXReservationLock.hpp"
|
#include "Emu/RSX/Core/RSXReservationLock.hpp"
|
||||||
#include "Crypto/sha1.h"
|
#include "Crypto/sha1.h"
|
||||||
|
@ -3482,13 +3483,13 @@ public:
|
||||||
#if defined(ARCH_X64)
|
#if defined(ARCH_X64)
|
||||||
if (utils::get_tsc_freq() && !(g_cfg.core.spu_loop_detection) && (g_cfg.core.clocks_scale == 100))
|
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 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 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 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 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 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 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 frzev = m_ir->CreateICmpEQ(frz, m_ir->getInt8(0));
|
||||||
|
|
||||||
|
@ -4305,10 +4306,11 @@ public:
|
||||||
#if defined(ARCH_X64)
|
#if defined(ARCH_X64)
|
||||||
if (utils::get_tsc_freq() && !(g_cfg.core.spu_loop_detection) && (g_cfg.core.clocks_scale == 100))
|
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 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 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 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));
|
m_ir->CreateStore(tsctb, spu_ptr<u64>(&spu_thread::ch_dec_start_timestamp));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
#include "util/sysinfo.hpp"
|
#include "util/sysinfo.hpp"
|
||||||
|
|
||||||
static u64 timebase_offset;
|
u64 g_timebase_offs{};
|
||||||
static u64 systemtime_offset;
|
static u64 systemtime_offset;
|
||||||
|
|
||||||
#ifndef __linux__
|
#ifndef __linux__
|
||||||
|
@ -145,8 +145,8 @@ static constexpr u64 g_timebase_freq = /*79800000*/ 80000000ull; // 80 Mhz
|
||||||
u64 convert_to_timebased_time(u64 time)
|
u64 convert_to_timebased_time(u64 time)
|
||||||
{
|
{
|
||||||
const u64 result = time * (g_timebase_freq / 1000000ull) * g_cfg.core.clocks_scale / 100u;
|
const u64 result = time * (g_timebase_freq / 1000000ull) * g_cfg.core.clocks_scale / 100u;
|
||||||
ensure(result >= timebase_offset);
|
ensure(result >= g_timebase_offs);
|
||||||
return result - timebase_offset;
|
return result - g_timebase_offs;
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 get_timebased_time()
|
u64 get_timebased_time()
|
||||||
|
@ -160,7 +160,7 @@ u64 get_timebased_time()
|
||||||
#else
|
#else
|
||||||
const u64 result = (tsc / freq * g_timebase_freq + tsc % freq * g_timebase_freq / freq) * g_cfg.core.clocks_scale / 100u;
|
const u64 result = (tsc / freq * g_timebase_freq + tsc % freq * g_timebase_freq / freq) * g_cfg.core.clocks_scale / 100u;
|
||||||
#endif
|
#endif
|
||||||
return result - timebase_offset;
|
return result - g_timebase_offs;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (true)
|
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;
|
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
|
#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)
|
// If none-zero arg is specified it will become the base time (for savestates)
|
||||||
void initialize_timebased_time(u64 timebased_init, bool reset)
|
void initialize_timebased_time(u64 timebased_init, bool reset)
|
||||||
{
|
{
|
||||||
timebase_offset = 0;
|
g_timebase_offs = 0;
|
||||||
|
|
||||||
if (reset)
|
if (reset)
|
||||||
{
|
{
|
||||||
|
@ -204,7 +204,7 @@ void initialize_timebased_time(u64 timebased_init, bool reset)
|
||||||
const u64 current = get_timebased_time();
|
const u64 current = get_timebased_time();
|
||||||
timebased_init = current - timebased_init;
|
timebased_init = current - timebased_init;
|
||||||
|
|
||||||
timebase_offset = timebased_init;
|
g_timebase_offs = timebased_init;
|
||||||
systemtime_offset = timebased_init / (g_timebase_freq / 1000000);
|
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);
|
error_code sys_time_set_current_time(s64 sec, s64 nsec);
|
||||||
u64 sys_time_get_timebase_frequency();
|
u64 sys_time_get_timebase_frequency();
|
||||||
error_code sys_time_get_rtc(vm::ptr<u64> rtc);
|
error_code sys_time_get_rtc(vm::ptr<u64> rtc);
|
||||||
|
|
||||||
|
extern u64 g_timebase_offs;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue