4 changed files with 134 additions and 1 deletions
-
8src/common/CMakeLists.txt
-
72src/common/arm64/native_clock.cpp
-
47src/common/arm64/native_clock.h
-
8src/common/wall_clock.cpp
@ -0,0 +1,72 @@ |
|||||
|
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
|
||||
|
#include "common/arm64/native_clock.h"
|
||||
|
|
||||
|
namespace Common::Arm64 { |
||||
|
|
||||
|
namespace { |
||||
|
|
||||
|
NativeClock::FactorType GetFixedPointFactor(u64 num, u64 den) { |
||||
|
return (static_cast<NativeClock::FactorType>(num) << 64) / den; |
||||
|
} |
||||
|
|
||||
|
u64 MultiplyHigh(u64 m, NativeClock::FactorType factor) { |
||||
|
return static_cast<u64>((m * factor) >> 64); |
||||
|
} |
||||
|
|
||||
|
} // namespace
|
||||
|
|
||||
|
NativeClock::NativeClock() { |
||||
|
const u64 host_cntfrq = GetHostCNTFRQ(); |
||||
|
ns_cntfrq_factor = GetFixedPointFactor(NsRatio::den, host_cntfrq); |
||||
|
us_cntfrq_factor = GetFixedPointFactor(UsRatio::den, host_cntfrq); |
||||
|
ms_cntfrq_factor = GetFixedPointFactor(MsRatio::den, host_cntfrq); |
||||
|
guest_cntfrq_factor = GetFixedPointFactor(CNTFRQ, host_cntfrq); |
||||
|
gputick_cntfrq_factor = GetFixedPointFactor(GPUTickFreq, host_cntfrq); |
||||
|
} |
||||
|
|
||||
|
std::chrono::nanoseconds NativeClock::GetTimeNS() const { |
||||
|
return std::chrono::nanoseconds{MultiplyHigh(GetHostTicksElapsed(), ns_cntfrq_factor)}; |
||||
|
} |
||||
|
|
||||
|
std::chrono::microseconds NativeClock::GetTimeUS() const { |
||||
|
return std::chrono::microseconds{MultiplyHigh(GetHostTicksElapsed(), us_cntfrq_factor)}; |
||||
|
} |
||||
|
|
||||
|
std::chrono::milliseconds NativeClock::GetTimeMS() const { |
||||
|
return std::chrono::milliseconds{MultiplyHigh(GetHostTicksElapsed(), ms_cntfrq_factor)}; |
||||
|
} |
||||
|
|
||||
|
u64 NativeClock::GetCNTPCT() const { |
||||
|
return MultiplyHigh(GetHostTicksElapsed(), guest_cntfrq_factor); |
||||
|
} |
||||
|
|
||||
|
u64 NativeClock::GetGPUTick() const { |
||||
|
return MultiplyHigh(GetHostTicksElapsed(), gputick_cntfrq_factor); |
||||
|
} |
||||
|
|
||||
|
u64 NativeClock::GetHostTicksNow() const { |
||||
|
u64 cntvct_el0 = 0; |
||||
|
asm volatile("dsb ish\n\t" |
||||
|
"mrs %[cntvct_el0], cntvct_el0\n\t" |
||||
|
"dsb ish\n\t" |
||||
|
: [cntvct_el0] "=r"(cntvct_el0)); |
||||
|
return cntvct_el0; |
||||
|
} |
||||
|
|
||||
|
u64 NativeClock::GetHostTicksElapsed() const { |
||||
|
return GetHostTicksNow(); |
||||
|
} |
||||
|
|
||||
|
bool NativeClock::IsNative() const { |
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
u64 NativeClock::GetHostCNTFRQ() { |
||||
|
u64 cntfrq_el0 = 0; |
||||
|
asm("mrs %[cntfrq_el0], cntfrq_el0" : [cntfrq_el0] "=r"(cntfrq_el0)); |
||||
|
return cntfrq_el0; |
||||
|
} |
||||
|
|
||||
|
} // namespace Common::Arm64
|
||||
@ -0,0 +1,47 @@ |
|||||
|
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project |
||||
|
// SPDX-License-Identifier: GPL-2.0-or-later |
||||
|
|
||||
|
#pragma once |
||||
|
|
||||
|
#include "common/wall_clock.h" |
||||
|
|
||||
|
namespace Common::Arm64 { |
||||
|
|
||||
|
class NativeClock final : public WallClock { |
||||
|
public: |
||||
|
explicit NativeClock(); |
||||
|
|
||||
|
std::chrono::nanoseconds GetTimeNS() const override; |
||||
|
|
||||
|
std::chrono::microseconds GetTimeUS() const override; |
||||
|
|
||||
|
std::chrono::milliseconds GetTimeMS() const override; |
||||
|
|
||||
|
u64 GetCNTPCT() const override; |
||||
|
|
||||
|
u64 GetGPUTick() const override; |
||||
|
|
||||
|
u64 GetHostTicksNow() const override; |
||||
|
|
||||
|
u64 GetHostTicksElapsed() const override; |
||||
|
|
||||
|
bool IsNative() const override; |
||||
|
|
||||
|
static u64 GetHostCNTFRQ(); |
||||
|
|
||||
|
public: |
||||
|
using FactorType = unsigned __int128; |
||||
|
|
||||
|
FactorType GetGuestCNTFRQFactor() const { |
||||
|
return guest_cntfrq_factor; |
||||
|
} |
||||
|
|
||||
|
private: |
||||
|
FactorType ns_cntfrq_factor; |
||||
|
FactorType us_cntfrq_factor; |
||||
|
FactorType ms_cntfrq_factor; |
||||
|
FactorType guest_cntfrq_factor; |
||||
|
FactorType gputick_cntfrq_factor; |
||||
|
}; |
||||
|
|
||||
|
} // namespace Common::Arm64 |
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue