Add cycle counters for 64-bit ARM
authorErik Lindahl <erik@kth.se>
Tue, 19 Aug 2014 12:29:57 +0000 (14:29 +0200)
committerGerrit Code Review <gerrit@gerrit.gromacs.org>
Wed, 20 Aug 2014 15:54:49 +0000 (17:54 +0200)
The gcc code has been tested on actual ARM64
hardware, but the MSVC one is only implemented
from the MSVC manual.

Change-Id: I13aac4d65345c684b6ddc5812ca9c3fcbe27b81a

src/gromacs/timing/cyclecounter.h

index 87d19b19a1c3865653b314e789343fd9d810af41..7751db43906c65805b076820fd707be7f2d0dad9 100644 (file)
@@ -79,6 +79,11 @@ extern "C"
 typedef unsigned long long
     gmx_cycles_t;
 
+#elif ((defined __aarch64__) && (defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__PATHSCALE__) || defined(__PGIC__)))
+/* 64-bit ARM cycle counters with GCC inline assembly */
+typedef unsigned long long
+    gmx_cycles_t;
+
 #elif defined(_MSC_VER)
 #include <windows.h>
 typedef __int64
@@ -210,6 +215,12 @@ static __inline__ int gmx_cycles_have_counter(void)
     /* x86 or x86-64 with GCC inline assembly - pentium TSC register */
     return 1;
 }
+#elif ((defined __aarch64__) && (defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__PATHSCALE__) || defined(__PGIC__)))
+static __inline int gmx_cycles_have_counter(void)
+{
+    /* 64-bit ARM cycle counters with GCC inline assembly */
+    return 1;
+}
 #elif (defined(_MSC_VER))
 static __inline int gmx_cycles_have_counter(void)
 {
@@ -350,14 +361,30 @@ static __inline__ gmx_cycles_t gmx_cycles_read(void)
 
     return cycle;
 }
+#elif ((defined __aarch64__) && (defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__PATHSCALE__) || defined(__PGIC__)))
+static __inline__ gmx_cycles_t gmx_cycles_read(void)
+{
+    /* 64-bit ARM cycle counters with GCC inline assembly */
+    gmx_cycles_t   cycle;
+    __asm__ __volatile__("mrs %0, cntvct_el0" : "=r" (cycle) );
+
+    return cycle;
+}
+
 #elif defined(_MSC_VER)
 static __inline gmx_cycles_t gmx_cycles_read(void)
 {
-#ifdef HAVE_RDTSCP
+#ifdef _M_ARM
+    /* Windows on 64-bit ARM */
+    return __rdpmccntr64();
+#else
+    /* x86 */
+#    ifdef HAVE_RDTSCP
     unsigned int ui;
     return __rdtscp(&ui);
-#else
+#    else
     return __rdtsc();
+#    endif
 #endif
 }
 #elif (defined(__hpux) || defined(__HP_cc)) && defined(__ia64)