From eeb67bcec38257469af60c97f9ce8725a2beb5e0 Mon Sep 17 00:00:00 2001 From: Marisa Kirisame Date: Fri, 25 Mar 2022 17:01:39 +0100 Subject: [PATCH] Use RDTSC equivalent on AARCH64. --- src/common/engine/stats.h | 12 +++++++----- src/common/platform/posix/sdl/i_system.cpp | 10 +++++++++- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/common/engine/stats.h b/src/common/engine/stats.h index 7e3e05d8c..d6e976ea5 100644 --- a/src/common/engine/stats.h +++ b/src/common/engine/stats.h @@ -76,8 +76,9 @@ inline uint64_t rdtsc() while (upper != temp); return (static_cast(upper) << 32) | lower; #elif defined __aarch64__ - // TODO: Implement and test on ARM64 - return 0; + uint64_t vct; + asm volatile("mrs %0, cntvct_el0":"=r"(vct)); + return vct; #elif defined __i386__ if (CPU.bRDTSC) { @@ -186,14 +187,15 @@ inline uint64_t rdtsc() unsigned int lower, upper, temp; do { - asm volatile ("mftbu %0 \n mftb %1 \n mftbu %2 \n" + asm volatile ("mftbu %0 \n mftb %1 \n mftbu %2 \n" : "=r"(upper), "=r"(lower), "=r"(temp)); } while (upper != temp); return (static_cast(upper) << 32) | lower; #elif defined __aarch64__ - // TODO: Implement and test on ARM64 - return 0; + uint64_t vct; + asm volatile("mrs %0, cntvct_el0":"=r"(vct)); + return vct; #elif defined __i386__ // i386 if (CPU.bRDTSC) { diff --git a/src/common/platform/posix/sdl/i_system.cpp b/src/common/platform/posix/sdl/i_system.cpp index 783d65efa..51da146d3 100644 --- a/src/common/platform/posix/sdl/i_system.cpp +++ b/src/common/platform/posix/sdl/i_system.cpp @@ -144,7 +144,15 @@ void CalculateCPUSpeed() { PerfAvailable = false; PerfToMillisec = PerfToSec = 0.; -#ifdef __linux__ +#ifdef __aarch64__ + // [MK] on aarch64 rather than having to calculate cpu speed, there is + // already an independent frequency for the perf timer + uint64_t frq; + asm volatile("mrs %0, cntfrq_el0":"=r"(frq)); + PerfAvailable = true; + PerfToSec = 1./frq; + PerfToMillisec = PerfToSec*1000.; +#elif defined(__linux__) // [MK] read from perf values if we can struct perf_event_attr pe; memset(&pe,0,sizeof(struct perf_event_attr));