From cf24eaf9d2bcb739aaec5b4c75d6bb09b4b902ae Mon Sep 17 00:00:00 2001 From: Yang Liu Date: Thu, 26 Dec 2024 21:40:04 +0800 Subject: [LA64_DYNAREC] Added hardware wall-clock support (#2216) * [LA64_DYNAREC] Added hardware wall-clock support * Refined multi-language support --- src/emu/x64emu.c | 35 +++++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) (limited to 'src/emu') diff --git a/src/emu/x64emu.c b/src/emu/x64emu.c index e63f46dd..e35f2608 100644 --- a/src/emu/x64emu.c +++ b/src/emu/x64emu.c @@ -702,6 +702,37 @@ static inline uint64_t readFreq() : "=r"(val)); return val; } +#elif defined(LA64) +static inline uint64_t readCycleCounter() +{ + uint64_t val; + asm volatile("rdtime.d %0, %1" + : "=r"(val) : "r"(0)); + return val; +} + +static inline uint64_t readFreq() +{ + static size_t val = -1; + + FILE* f = popen("cat /proc/cpuinfo | grep -i \"CPU MHz\" | head -n 1 | sed -r 's/CPU MHz.+:\\s{1,}//g'", "r"); + if(f) { + char tmp[200] = ""; + ssize_t s = fread(tmp, 1, 200, f); + pclose(f); + if (s > 0) return (uint64_t)atof(tmp) * 1e6; + } + + // fallback to rdtime + sleep + struct timespec ts; + ts.tv_sec = 0; + ts.tv_nsec = 50000000; // 50 milliseconds + uint64_t cycles = readCycleCounter(); + nanosleep(&ts, NULL); + // round to MHz + val = (size_t)round(((double)(readCycleCounter() - cycles) * 20) / 1e6) * 1e6; + return (uint64_t)val; +} #endif uint64_t ReadTSC(x64emu_t* emu) @@ -709,7 +740,7 @@ uint64_t ReadTSC(x64emu_t* emu) (void)emu; // Hardware counter, per architecture -#if defined(ARM64) || defined(RV64) +#if defined(ARM64) || defined(RV64) || defined(LA64) if (!box64_rdtsc) return readCycleCounter(); #endif // fall back to gettime... @@ -728,7 +759,7 @@ uint64_t ReadTSCFrequency(x64emu_t* emu) { (void)emu; // Hardware counter, per architecture -#if defined(ARM64) || defined(RV64) +#if defined(ARM64) || defined(RV64) || defined(LA64) if (!box64_rdtsc) return readFreq(); #endif // fall back to get time -- cgit 1.4.1