Skip to content

Commit

Permalink
Fix profile timing measurements on AArch64. (dlang#150)
Browse files Browse the repository at this point in the history
We cannot use ldc.intrinsics.llvm_readcyclecounter because that is not an accurate time counter (it is a counter of CPU cycles, where here we want a time clock).
Also, priviledged execution rights are needed to enable correct counting with ldc.intrinsics.llvm_readcyclecounter on AArch64.
So instead, we use the general virtual counter register, and also read out the frequency of that counter.
  • Loading branch information
JohanEngelen committed Dec 23, 2018
1 parent 98321e0 commit 4e74576
Showing 1 changed file with 48 additions and 23 deletions.
71 changes: 48 additions & 23 deletions src/rt/trace.d
Expand Up @@ -841,39 +841,64 @@ version (Windows)
}
else
{
extern (D) void QueryPerformanceCounter(timer_t* ctr)
version (LDC)
{
version (LDC)
version (AArch64)
{
import ldc.intrinsics: llvm_readcyclecounter;
*ctr = llvm_readcyclecounter();
}
else version (D_InlineAsm_X86)
{
asm
import ldc.llvmasm: __asm;
// We cannot use ldc.intrinsics.llvm_readcyclecounter because that is not an accurate
// time counter (it is a counter of CPU cycles, where here we want a time clock).
// Also, priviledged execution rights are needed to enable correct counting with
// ldc.intrinsics.llvm_readcyclecounter on AArch64.
extern (D) void QueryPerformanceCounter(timer_t* ctr)
{
naked ;
mov ECX,EAX ;
rdtsc ;
mov [ECX],EAX ;
mov 4[ECX],EDX ;
ret ;
*ctr = __asm!ulong("mrs $0, cntvct_el0", "=r");
}
extern (D) void QueryPerformanceFrequency(timer_t* freq)
{
*freq = __asm!ulong("mrs $0, cntfrq_el0", "=r");
}
}
else version (D_InlineAsm_X86_64)
else
{
asm
extern (D) void QueryPerformanceCounter(timer_t* ctr)
{
naked ;
rdtsc ;
mov [RDI],EAX ;
mov 4[RDI],EDX ;
ret ;
import ldc.intrinsics: llvm_readcyclecounter;
*ctr = llvm_readcyclecounter();
}
}
else
}
else
{
extern (D) void QueryPerformanceCounter(timer_t* ctr)
{
static assert(0);
version (D_InlineAsm_X86)
{
asm
{
naked ;
mov ECX,EAX ;
rdtsc ;
mov [ECX],EAX ;
mov 4[ECX],EDX ;
ret ;
}
}
else version (D_InlineAsm_X86_64)
{
asm
{
naked ;
rdtsc ;
mov [RDI],EAX ;
mov 4[RDI],EDX ;
ret ;
}
}
else
{
static assert(0);
}
}
}
}

0 comments on commit 4e74576

Please sign in to comment.