summaryrefslogtreecommitdiff
path: root/src/common/x64/native_clock.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/common/x64/native_clock.cpp')
-rw-r--r--src/common/x64/native_clock.cpp47
1 files changed, 7 insertions, 40 deletions
diff --git a/src/common/x64/native_clock.cpp b/src/common/x64/native_clock.cpp
index c799111fd..26d4d0ba6 100644
--- a/src/common/x64/native_clock.cpp
+++ b/src/common/x64/native_clock.cpp
@@ -11,44 +11,11 @@
11#include <x86intrin.h> 11#include <x86intrin.h>
12#endif 12#endif
13 13
14#include "common/uint128.h"
14#include "common/x64/native_clock.h" 15#include "common/x64/native_clock.h"
15 16
16namespace Common { 17namespace Common {
17 18
18#ifdef _MSC_VER
19
20namespace {
21
22struct uint128 {
23 u64 low;
24 u64 high;
25};
26
27u64 umuldiv64(u64 a, u64 b, u64 d) {
28 uint128 r{};
29 r.low = _umul128(a, b, &r.high);
30 u64 remainder;
31 return _udiv128(r.high, r.low, d, &remainder);
32}
33
34} // namespace
35
36#else
37
38namespace {
39
40u64 umuldiv64(u64 a, u64 b, u64 d) {
41 const u64 diva = a / d;
42 const u64 moda = a % d;
43 const u64 divb = b / d;
44 const u64 modb = b % d;
45 return diva * b + moda * divb + moda * modb / d;
46}
47
48} // namespace
49
50#endif
51
52u64 EstimateRDTSCFrequency() { 19u64 EstimateRDTSCFrequency() {
53 const auto milli_10 = std::chrono::milliseconds{10}; 20 const auto milli_10 = std::chrono::milliseconds{10};
54 // get current time 21 // get current time
@@ -70,7 +37,7 @@ u64 EstimateRDTSCFrequency() {
70 const u64 timer_diff = 37 const u64 timer_diff =
71 std::chrono::duration_cast<std::chrono::nanoseconds>(endTime - startTime).count(); 38 std::chrono::duration_cast<std::chrono::nanoseconds>(endTime - startTime).count();
72 const u64 tsc_diff = tscEnd - tscStart; 39 const u64 tsc_diff = tscEnd - tscStart;
73 const u64 tsc_freq = umuldiv64(tsc_diff, 1000000000ULL, timer_diff); 40 const u64 tsc_freq = MultiplyAndDivide64(tsc_diff, 1000000000ULL, timer_diff);
74 return tsc_freq; 41 return tsc_freq;
75} 42}
76 43
@@ -100,27 +67,27 @@ u64 NativeClock::GetRTSC() {
100 67
101std::chrono::nanoseconds NativeClock::GetTimeNS() { 68std::chrono::nanoseconds NativeClock::GetTimeNS() {
102 const u64 rtsc_value = GetRTSC(); 69 const u64 rtsc_value = GetRTSC();
103 return std::chrono::nanoseconds{umuldiv64(rtsc_value, 1000000000, rtsc_frequency)}; 70 return std::chrono::nanoseconds{MultiplyAndDivide64(rtsc_value, 1000000000, rtsc_frequency)};
104} 71}
105 72
106std::chrono::microseconds NativeClock::GetTimeUS() { 73std::chrono::microseconds NativeClock::GetTimeUS() {
107 const u64 rtsc_value = GetRTSC(); 74 const u64 rtsc_value = GetRTSC();
108 return std::chrono::microseconds{umuldiv64(rtsc_value, 1000000, rtsc_frequency)}; 75 return std::chrono::microseconds{MultiplyAndDivide64(rtsc_value, 1000000, rtsc_frequency)};
109} 76}
110 77
111std::chrono::milliseconds NativeClock::GetTimeMS() { 78std::chrono::milliseconds NativeClock::GetTimeMS() {
112 const u64 rtsc_value = GetRTSC(); 79 const u64 rtsc_value = GetRTSC();
113 return std::chrono::milliseconds{umuldiv64(rtsc_value, 1000, rtsc_frequency)}; 80 return std::chrono::milliseconds{MultiplyAndDivide64(rtsc_value, 1000, rtsc_frequency)};
114} 81}
115 82
116u64 NativeClock::GetClockCycles() { 83u64 NativeClock::GetClockCycles() {
117 const u64 rtsc_value = GetRTSC(); 84 const u64 rtsc_value = GetRTSC();
118 return umuldiv64(rtsc_value, emulated_clock_frequency, rtsc_frequency); 85 return MultiplyAndDivide64(rtsc_value, emulated_clock_frequency, rtsc_frequency);
119} 86}
120 87
121u64 NativeClock::GetCPUCycles() { 88u64 NativeClock::GetCPUCycles() {
122 const u64 rtsc_value = GetRTSC(); 89 const u64 rtsc_value = GetRTSC();
123 return umuldiv64(rtsc_value, emulated_cpu_frequency, rtsc_frequency); 90 return MultiplyAndDivide64(rtsc_value, emulated_cpu_frequency, rtsc_frequency);
124} 91}
125 92
126} // namespace X64 93} // namespace X64