|
|
@@ -11,44 +11,11 @@
|
|
|
#include <x86intrin.h>
|
|
|
#endif
|
|
|
|
|
|
+#include "common/uint128.h"
|
|
|
#include "common/x64/native_clock.h"
|
|
|
|
|
|
namespace Common {
|
|
|
|
|
|
-#ifdef _MSC_VER
|
|
|
-
|
|
|
-namespace {
|
|
|
-
|
|
|
-struct uint128 {
|
|
|
- u64 low;
|
|
|
- u64 high;
|
|
|
-};
|
|
|
-
|
|
|
-u64 umuldiv64(u64 a, u64 b, u64 d) {
|
|
|
- uint128 r{};
|
|
|
- r.low = _umul128(a, b, &r.high);
|
|
|
- u64 remainder;
|
|
|
- return _udiv128(r.high, r.low, d, &remainder);
|
|
|
-}
|
|
|
-
|
|
|
-} // namespace
|
|
|
-
|
|
|
-#else
|
|
|
-
|
|
|
-namespace {
|
|
|
-
|
|
|
-u64 umuldiv64(u64 a, u64 b, u64 d) {
|
|
|
- const u64 diva = a / d;
|
|
|
- const u64 moda = a % d;
|
|
|
- const u64 divb = b / d;
|
|
|
- const u64 modb = b % d;
|
|
|
- return diva * b + moda * divb + moda * modb / d;
|
|
|
-}
|
|
|
-
|
|
|
-} // namespace
|
|
|
-
|
|
|
-#endif
|
|
|
-
|
|
|
u64 EstimateRDTSCFrequency() {
|
|
|
const auto milli_10 = std::chrono::milliseconds{10};
|
|
|
// get current time
|
|
|
@@ -70,7 +37,7 @@ u64 EstimateRDTSCFrequency() {
|
|
|
const u64 timer_diff =
|
|
|
std::chrono::duration_cast<std::chrono::nanoseconds>(endTime - startTime).count();
|
|
|
const u64 tsc_diff = tscEnd - tscStart;
|
|
|
- const u64 tsc_freq = umuldiv64(tsc_diff, 1000000000ULL, timer_diff);
|
|
|
+ const u64 tsc_freq = MultiplyAndDivide64(tsc_diff, 1000000000ULL, timer_diff);
|
|
|
return tsc_freq;
|
|
|
}
|
|
|
|
|
|
@@ -100,27 +67,27 @@ u64 NativeClock::GetRTSC() {
|
|
|
|
|
|
std::chrono::nanoseconds NativeClock::GetTimeNS() {
|
|
|
const u64 rtsc_value = GetRTSC();
|
|
|
- return std::chrono::nanoseconds{umuldiv64(rtsc_value, 1000000000, rtsc_frequency)};
|
|
|
+ return std::chrono::nanoseconds{MultiplyAndDivide64(rtsc_value, 1000000000, rtsc_frequency)};
|
|
|
}
|
|
|
|
|
|
std::chrono::microseconds NativeClock::GetTimeUS() {
|
|
|
const u64 rtsc_value = GetRTSC();
|
|
|
- return std::chrono::microseconds{umuldiv64(rtsc_value, 1000000, rtsc_frequency)};
|
|
|
+ return std::chrono::microseconds{MultiplyAndDivide64(rtsc_value, 1000000, rtsc_frequency)};
|
|
|
}
|
|
|
|
|
|
std::chrono::milliseconds NativeClock::GetTimeMS() {
|
|
|
const u64 rtsc_value = GetRTSC();
|
|
|
- return std::chrono::milliseconds{umuldiv64(rtsc_value, 1000, rtsc_frequency)};
|
|
|
+ return std::chrono::milliseconds{MultiplyAndDivide64(rtsc_value, 1000, rtsc_frequency)};
|
|
|
}
|
|
|
|
|
|
u64 NativeClock::GetClockCycles() {
|
|
|
const u64 rtsc_value = GetRTSC();
|
|
|
- return umuldiv64(rtsc_value, emulated_clock_frequency, rtsc_frequency);
|
|
|
+ return MultiplyAndDivide64(rtsc_value, emulated_clock_frequency, rtsc_frequency);
|
|
|
}
|
|
|
|
|
|
u64 NativeClock::GetCPUCycles() {
|
|
|
const u64 rtsc_value = GetRTSC();
|
|
|
- return umuldiv64(rtsc_value, emulated_cpu_frequency, rtsc_frequency);
|
|
|
+ return MultiplyAndDivide64(rtsc_value, emulated_cpu_frequency, rtsc_frequency);
|
|
|
}
|
|
|
|
|
|
} // namespace X64
|