Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[LA64_DYNAREC] Added hardware wall-clock support #2216

Merged
merged 2 commits into from
Dec 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -593,7 +593,7 @@ void computeRDTSC()
{
int hardware = 0;
box64_rdtsc_shift = 0;
#if defined(ARM64) || defined(RV64)
#if defined(ARM64) || defined(RV64) || defined(LA64)
hardware = 1;
box64_rdtsc = 0; // allow hardware counter
#else
Expand Down
7 changes: 5 additions & 2 deletions src/dynarec/la64/dynarec_la64_0f.c
Original file line number Diff line number Diff line change
Expand Up @@ -338,8 +338,11 @@ uintptr_t dynarec64_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
case 0x31:
INST_NAME("RDTSC");
NOTEST(x1);
// TODO: how to read the wall-clock real time on LoongArch?
CALL(ReadTSC, x3); // will return the u64 in x3
if (box64_rdtsc) {
CALL(ReadTSC, x3); // will return the u64 in x3
} else {
RDTIME_D(x3, xZR);
}
if (box64_rdtsc_shift) {
SRLI_D(x3, x3, box64_rdtsc_shift);
}
Expand Down
2 changes: 2 additions & 0 deletions src/dynarec/la64/la64_emitter.h
Original file line number Diff line number Diff line change
Expand Up @@ -950,6 +950,8 @@ f24-f31 fs0-fs7 Static registers Callee
#define FCMP_D(cd, fj, fk, cond) EMIT(type_4R(0b000011000010, cond, fk, fj, cd & 0b111))
#define FSEL(fd, fj, fk, ca) EMIT(type_4R(0b000011010000, ca & 0b111, fk, fj, fd))

#define RDTIME_D(rd, rj) EMIT(type_2R(0b11010, rj, rd))

////////////////////////////////////////////////////////////////////////////////
// (undocumented) LSX/LASX extension instructions

Expand Down
35 changes: 33 additions & 2 deletions src/emu/x64emu.c
Original file line number Diff line number Diff line change
Expand Up @@ -702,14 +702,45 @@ 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)
{
(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...
Expand All @@ -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
Expand Down
10 changes: 2 additions & 8 deletions src/tools/my_cpuid.c
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ const char* getCpuName()
}
setenv("BOX64_CPUNAME", name, 1); // temporary set
#ifndef STATICBUILD
FILE* f = popen("lscpu | grep \"Model name:\" | sed -r 's/Model name:\\s{1,}//g'", "r");
FILE* f = popen("LC_ALL=C lscpu | grep -i \"model name:\" | head -n 1 | sed -r 's/(model name:)\\s{1,}//gi'", "r");
if(f) {
char tmp[200] = "";
ssize_t s = fread(tmp, 1, 200, f);
Expand All @@ -145,17 +145,14 @@ const char* getCpuName()
// trim ending
while(strlen(tmp) && tmp[strlen(tmp)-1]=='\n')
tmp[strlen(tmp)-1] = 0;
// incase multiple cpu type are present, there will be multiple lines
while(strchr(tmp, '\n'))
*strchr(tmp,'\n') = ' ';
strncpy(name, tmp, 199);
}
setenv("BOX64_CPUNAME", name, 1);
return name;
}
}
// failled, try to get architecture at least
f = popen("lscpu | grep \"Architecture:\" | sed -r 's/Architecture:\\s{1,}//g'", "r");
f = popen("LC_ALL=C lscpu | grep -i \"architecture:\" | head -n 1 | sed -r 's/(architecture:)\\s{1,}//gi'", "r");
if(f) {
char tmp[200] = "";
ssize_t s = fread(tmp, 1, 200, f);
Expand All @@ -165,9 +162,6 @@ const char* getCpuName()
// trim ending
while(strlen(tmp) && tmp[strlen(tmp)-1]=='\n')
tmp[strlen(tmp)-1] = 0;
// incase multiple cpu type are present, there will be multiple lines
while(strchr(tmp, '\n'))
*strchr(tmp,'\n') = ' ';
snprintf(name, 199, "unknown %s cpu", tmp);
setenv("BOX64_CPUNAME", name, 1);
return name;
Expand Down
Loading