annotate src/fftw-3.3.8/kernel/cycle.h @ 83:ae30d91d2ffe

Replace these with versions built using an older toolset (so as to avoid ABI compatibilities when linking on Ubuntu 14.04 for packaging purposes)
author Chris Cannam
date Fri, 07 Feb 2020 11:51:13 +0000
parents d0c2a83c1364
children
rev   line source
Chris@82 1 /*
Chris@82 2 * Copyright (c) 2003, 2007-14 Matteo Frigo
Chris@82 3 * Copyright (c) 2003, 2007-14 Massachusetts Institute of Technology
Chris@82 4 *
Chris@82 5 * Permission is hereby granted, free of charge, to any person obtaining
Chris@82 6 * a copy of this software and associated documentation files (the
Chris@82 7 * "Software"), to deal in the Software without restriction, including
Chris@82 8 * without limitation the rights to use, copy, modify, merge, publish,
Chris@82 9 * distribute, sublicense, and/or sell copies of the Software, and to
Chris@82 10 * permit persons to whom the Software is furnished to do so, subject to
Chris@82 11 * the following conditions:
Chris@82 12 *
Chris@82 13 * The above copyright notice and this permission notice shall be
Chris@82 14 * included in all copies or substantial portions of the Software.
Chris@82 15 *
Chris@82 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
Chris@82 17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
Chris@82 18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
Chris@82 19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
Chris@82 20 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
Chris@82 21 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
Chris@82 22 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Chris@82 23 *
Chris@82 24 */
Chris@82 25
Chris@82 26
Chris@82 27 /* machine-dependent cycle counters code. Needs to be inlined. */
Chris@82 28
Chris@82 29 /***************************************************************************/
Chris@82 30 /* To use the cycle counters in your code, simply #include "cycle.h" (this
Chris@82 31 file), and then use the functions/macros:
Chris@82 32
Chris@82 33 ticks getticks(void);
Chris@82 34
Chris@82 35 ticks is an opaque typedef defined below, representing the current time.
Chris@82 36 You extract the elapsed time between two calls to gettick() via:
Chris@82 37
Chris@82 38 double elapsed(ticks t1, ticks t0);
Chris@82 39
Chris@82 40 which returns a double-precision variable in arbitrary units. You
Chris@82 41 are not expected to convert this into human units like seconds; it
Chris@82 42 is intended only for *comparisons* of time intervals.
Chris@82 43
Chris@82 44 (In order to use some of the OS-dependent timer routines like
Chris@82 45 Solaris' gethrtime, you need to paste the autoconf snippet below
Chris@82 46 into your configure.ac file and #include "config.h" before cycle.h,
Chris@82 47 or define the relevant macros manually if you are not using autoconf.)
Chris@82 48 */
Chris@82 49
Chris@82 50 /***************************************************************************/
Chris@82 51 /* This file uses macros like HAVE_GETHRTIME that are assumed to be
Chris@82 52 defined according to whether the corresponding function/type/header
Chris@82 53 is available on your system. The necessary macros are most
Chris@82 54 conveniently defined if you are using GNU autoconf, via the tests:
Chris@82 55
Chris@82 56 dnl ---------------------------------------------------------------------
Chris@82 57
Chris@82 58 AC_C_INLINE
Chris@82 59 AC_HEADER_TIME
Chris@82 60 AC_CHECK_HEADERS([sys/time.h c_asm.h intrinsics.h mach/mach_time.h])
Chris@82 61
Chris@82 62 AC_CHECK_TYPE([hrtime_t],[AC_DEFINE(HAVE_HRTIME_T, 1, [Define to 1 if hrtime_t is defined in <sys/time.h>])],,[#if HAVE_SYS_TIME_H
Chris@82 63 #include <sys/time.h>
Chris@82 64 #endif])
Chris@82 65
Chris@82 66 AC_CHECK_FUNCS([gethrtime read_real_time time_base_to_time clock_gettime mach_absolute_time])
Chris@82 67
Chris@82 68 dnl Cray UNICOS _rtc() (real-time clock) intrinsic
Chris@82 69 AC_MSG_CHECKING([for _rtc intrinsic])
Chris@82 70 rtc_ok=yes
Chris@82 71 AC_TRY_LINK([#ifdef HAVE_INTRINSICS_H
Chris@82 72 #include <intrinsics.h>
Chris@82 73 #endif], [_rtc()], [AC_DEFINE(HAVE__RTC,1,[Define if you have the UNICOS _rtc() intrinsic.])], [rtc_ok=no])
Chris@82 74 AC_MSG_RESULT($rtc_ok)
Chris@82 75
Chris@82 76 dnl ---------------------------------------------------------------------
Chris@82 77 */
Chris@82 78
Chris@82 79 /***************************************************************************/
Chris@82 80
Chris@82 81 #if TIME_WITH_SYS_TIME
Chris@82 82 # include <sys/time.h>
Chris@82 83 # include <time.h>
Chris@82 84 #else
Chris@82 85 # if HAVE_SYS_TIME_H
Chris@82 86 # include <sys/time.h>
Chris@82 87 # else
Chris@82 88 # include <time.h>
Chris@82 89 # endif
Chris@82 90 #endif
Chris@82 91
Chris@82 92 #define INLINE_ELAPSED(INL) static INL double elapsed(ticks t1, ticks t0) \
Chris@82 93 { \
Chris@82 94 return (double)t1 - (double)t0; \
Chris@82 95 }
Chris@82 96
Chris@82 97 /*----------------------------------------------------------------*/
Chris@82 98 /* Solaris */
Chris@82 99 #if defined(HAVE_GETHRTIME) && defined(HAVE_HRTIME_T) && !defined(HAVE_TICK_COUNTER)
Chris@82 100 typedef hrtime_t ticks;
Chris@82 101
Chris@82 102 #define getticks gethrtime
Chris@82 103
Chris@82 104 INLINE_ELAPSED(inline)
Chris@82 105
Chris@82 106 #define HAVE_TICK_COUNTER
Chris@82 107 #endif
Chris@82 108
Chris@82 109 /*----------------------------------------------------------------*/
Chris@82 110 /* AIX v. 4+ routines to read the real-time clock or time-base register */
Chris@82 111 #if defined(HAVE_READ_REAL_TIME) && defined(HAVE_TIME_BASE_TO_TIME) && !defined(HAVE_TICK_COUNTER)
Chris@82 112 typedef timebasestruct_t ticks;
Chris@82 113
Chris@82 114 static __inline ticks getticks(void)
Chris@82 115 {
Chris@82 116 ticks t;
Chris@82 117 read_real_time(&t, TIMEBASE_SZ);
Chris@82 118 return t;
Chris@82 119 }
Chris@82 120
Chris@82 121 static __inline double elapsed(ticks t1, ticks t0) /* time in nanoseconds */
Chris@82 122 {
Chris@82 123 time_base_to_time(&t1, TIMEBASE_SZ);
Chris@82 124 time_base_to_time(&t0, TIMEBASE_SZ);
Chris@82 125 return (((double)t1.tb_high - (double)t0.tb_high) * 1.0e9 +
Chris@82 126 ((double)t1.tb_low - (double)t0.tb_low));
Chris@82 127 }
Chris@82 128
Chris@82 129 #define HAVE_TICK_COUNTER
Chris@82 130 #endif
Chris@82 131
Chris@82 132 /*----------------------------------------------------------------*/
Chris@82 133 /*
Chris@82 134 * PowerPC ``cycle'' counter using the time base register.
Chris@82 135 */
Chris@82 136 #if ((((defined(__GNUC__) && (defined(__powerpc__) || defined(__ppc__))) || (defined(__MWERKS__) && defined(macintosh)))) || (defined(__IBM_GCC_ASM) && (defined(__powerpc__) || defined(__ppc__)))) && !defined(HAVE_TICK_COUNTER)
Chris@82 137 typedef unsigned long long ticks;
Chris@82 138
Chris@82 139 static __inline__ ticks getticks(void)
Chris@82 140 {
Chris@82 141 unsigned int tbl, tbu0, tbu1;
Chris@82 142
Chris@82 143 do {
Chris@82 144 __asm__ __volatile__ ("mftbu %0" : "=r"(tbu0));
Chris@82 145 __asm__ __volatile__ ("mftb %0" : "=r"(tbl));
Chris@82 146 __asm__ __volatile__ ("mftbu %0" : "=r"(tbu1));
Chris@82 147 } while (tbu0 != tbu1);
Chris@82 148
Chris@82 149 return (((unsigned long long)tbu0) << 32) | tbl;
Chris@82 150 }
Chris@82 151
Chris@82 152 INLINE_ELAPSED(__inline__)
Chris@82 153
Chris@82 154 #define HAVE_TICK_COUNTER
Chris@82 155 #endif
Chris@82 156
Chris@82 157 /* MacOS/Mach (Darwin) time-base register interface (unlike UpTime,
Chris@82 158 from Carbon, requires no additional libraries to be linked). */
Chris@82 159 #if defined(HAVE_MACH_ABSOLUTE_TIME) && defined(HAVE_MACH_MACH_TIME_H) && !defined(HAVE_TICK_COUNTER)
Chris@82 160 #include <mach/mach_time.h>
Chris@82 161 typedef uint64_t ticks;
Chris@82 162 #define getticks mach_absolute_time
Chris@82 163 INLINE_ELAPSED(__inline__)
Chris@82 164 #define HAVE_TICK_COUNTER
Chris@82 165 #endif
Chris@82 166
Chris@82 167 /*----------------------------------------------------------------*/
Chris@82 168 /*
Chris@82 169 * Pentium cycle counter
Chris@82 170 */
Chris@82 171 #if (defined(__GNUC__) || defined(__ICC)) && defined(__i386__) && !defined(HAVE_TICK_COUNTER)
Chris@82 172 typedef unsigned long long ticks;
Chris@82 173
Chris@82 174 static __inline__ ticks getticks(void)
Chris@82 175 {
Chris@82 176 ticks ret;
Chris@82 177
Chris@82 178 __asm__ __volatile__("rdtsc": "=A" (ret));
Chris@82 179 /* no input, nothing else clobbered */
Chris@82 180 return ret;
Chris@82 181 }
Chris@82 182
Chris@82 183 INLINE_ELAPSED(__inline__)
Chris@82 184
Chris@82 185 #define HAVE_TICK_COUNTER
Chris@82 186 #define TIME_MIN 5000.0 /* unreliable pentium IV cycle counter */
Chris@82 187 #endif
Chris@82 188
Chris@82 189 /* Visual C++ -- thanks to Morten Nissov for his help with this */
Chris@82 190 #if _MSC_VER >= 1200 && _M_IX86 >= 500 && !defined(HAVE_TICK_COUNTER)
Chris@82 191 #include <windows.h>
Chris@82 192 typedef LARGE_INTEGER ticks;
Chris@82 193 #define RDTSC __asm __emit 0fh __asm __emit 031h /* hack for VC++ 5.0 */
Chris@82 194
Chris@82 195 static __inline ticks getticks(void)
Chris@82 196 {
Chris@82 197 ticks retval;
Chris@82 198
Chris@82 199 __asm {
Chris@82 200 RDTSC
Chris@82 201 mov retval.HighPart, edx
Chris@82 202 mov retval.LowPart, eax
Chris@82 203 }
Chris@82 204 return retval;
Chris@82 205 }
Chris@82 206
Chris@82 207 static __inline double elapsed(ticks t1, ticks t0)
Chris@82 208 {
Chris@82 209 return (double)t1.QuadPart - (double)t0.QuadPart;
Chris@82 210 }
Chris@82 211
Chris@82 212 #define HAVE_TICK_COUNTER
Chris@82 213 #define TIME_MIN 5000.0 /* unreliable pentium IV cycle counter */
Chris@82 214 #endif
Chris@82 215
Chris@82 216 /*----------------------------------------------------------------*/
Chris@82 217 /*
Chris@82 218 * X86-64 cycle counter
Chris@82 219 */
Chris@82 220 #if (defined(__GNUC__) || defined(__ICC) || defined(__SUNPRO_C)) && defined(__x86_64__) && !defined(HAVE_TICK_COUNTER)
Chris@82 221 typedef unsigned long long ticks;
Chris@82 222
Chris@82 223 static __inline__ ticks getticks(void)
Chris@82 224 {
Chris@82 225 unsigned a, d;
Chris@82 226 __asm__ __volatile__ ("rdtsc" : "=a" (a), "=d" (d));
Chris@82 227 return ((ticks)a) | (((ticks)d) << 32);
Chris@82 228 }
Chris@82 229
Chris@82 230 INLINE_ELAPSED(__inline__)
Chris@82 231
Chris@82 232 #define HAVE_TICK_COUNTER
Chris@82 233 #define TIME_MIN 5000.0
Chris@82 234 #endif
Chris@82 235
Chris@82 236 /* PGI compiler, courtesy Cristiano Calonaci, Andrea Tarsi, & Roberto Gori.
Chris@82 237 NOTE: this code will fail to link unless you use the -Masmkeyword compiler
Chris@82 238 option (grrr). */
Chris@82 239 #if defined(__PGI) && defined(__x86_64__) && !defined(HAVE_TICK_COUNTER)
Chris@82 240 typedef unsigned long long ticks;
Chris@82 241 static ticks getticks(void)
Chris@82 242 {
Chris@82 243 asm(" rdtsc; shl $0x20,%rdx; mov %eax,%eax; or %rdx,%rax; ");
Chris@82 244 }
Chris@82 245 INLINE_ELAPSED(__inline__)
Chris@82 246 #define HAVE_TICK_COUNTER
Chris@82 247 #define TIME_MIN 5000.0
Chris@82 248 #endif
Chris@82 249
Chris@82 250 /* Visual C++, courtesy of Dirk Michaelis */
Chris@82 251 #if _MSC_VER >= 1400 && (defined(_M_AMD64) || defined(_M_X64)) && !defined(HAVE_TICK_COUNTER)
Chris@82 252
Chris@82 253 #include <intrin.h>
Chris@82 254 #pragma intrinsic(__rdtsc)
Chris@82 255 typedef unsigned __int64 ticks;
Chris@82 256 #define getticks __rdtsc
Chris@82 257 INLINE_ELAPSED(__inline)
Chris@82 258
Chris@82 259 #define HAVE_TICK_COUNTER
Chris@82 260 #define TIME_MIN 5000.0
Chris@82 261 #endif
Chris@82 262
Chris@82 263 /*----------------------------------------------------------------*/
Chris@82 264 /*
Chris@82 265 * IA64 cycle counter
Chris@82 266 */
Chris@82 267
Chris@82 268 /* intel's icc/ecc compiler */
Chris@82 269 #if (defined(__EDG_VERSION) || defined(__ECC)) && defined(__ia64__) && !defined(HAVE_TICK_COUNTER)
Chris@82 270 typedef unsigned long ticks;
Chris@82 271 #include <ia64intrin.h>
Chris@82 272
Chris@82 273 static __inline__ ticks getticks(void)
Chris@82 274 {
Chris@82 275 return __getReg(_IA64_REG_AR_ITC);
Chris@82 276 }
Chris@82 277
Chris@82 278 INLINE_ELAPSED(__inline__)
Chris@82 279
Chris@82 280 #define HAVE_TICK_COUNTER
Chris@82 281 #endif
Chris@82 282
Chris@82 283 /* gcc */
Chris@82 284 #if defined(__GNUC__) && defined(__ia64__) && !defined(HAVE_TICK_COUNTER)
Chris@82 285 typedef unsigned long ticks;
Chris@82 286
Chris@82 287 static __inline__ ticks getticks(void)
Chris@82 288 {
Chris@82 289 ticks ret;
Chris@82 290
Chris@82 291 __asm__ __volatile__ ("mov %0=ar.itc" : "=r"(ret));
Chris@82 292 return ret;
Chris@82 293 }
Chris@82 294
Chris@82 295 INLINE_ELAPSED(__inline__)
Chris@82 296
Chris@82 297 #define HAVE_TICK_COUNTER
Chris@82 298 #endif
Chris@82 299
Chris@82 300 /* HP/UX IA64 compiler, courtesy Teresa L. Johnson: */
Chris@82 301 #if defined(__hpux) && defined(__ia64) && !defined(HAVE_TICK_COUNTER)
Chris@82 302 #include <machine/sys/inline.h>
Chris@82 303 typedef unsigned long ticks;
Chris@82 304
Chris@82 305 static inline ticks getticks(void)
Chris@82 306 {
Chris@82 307 ticks ret;
Chris@82 308
Chris@82 309 ret = _Asm_mov_from_ar (_AREG_ITC);
Chris@82 310 return ret;
Chris@82 311 }
Chris@82 312
Chris@82 313 INLINE_ELAPSED(inline)
Chris@82 314
Chris@82 315 #define HAVE_TICK_COUNTER
Chris@82 316 #endif
Chris@82 317
Chris@82 318 /* Microsoft Visual C++ */
Chris@82 319 #if defined(_MSC_VER) && defined(_M_IA64) && !defined(HAVE_TICK_COUNTER)
Chris@82 320 typedef unsigned __int64 ticks;
Chris@82 321
Chris@82 322 # ifdef __cplusplus
Chris@82 323 extern "C"
Chris@82 324 # endif
Chris@82 325 ticks __getReg(int whichReg);
Chris@82 326 #pragma intrinsic(__getReg)
Chris@82 327
Chris@82 328 static __inline ticks getticks(void)
Chris@82 329 {
Chris@82 330 volatile ticks temp;
Chris@82 331 temp = __getReg(3116);
Chris@82 332 return temp;
Chris@82 333 }
Chris@82 334
Chris@82 335 INLINE_ELAPSED(inline)
Chris@82 336
Chris@82 337 #define HAVE_TICK_COUNTER
Chris@82 338 #endif
Chris@82 339
Chris@82 340 /*----------------------------------------------------------------*/
Chris@82 341 /*
Chris@82 342 * PA-RISC cycle counter
Chris@82 343 */
Chris@82 344 #if (defined(__hppa__) || defined(__hppa)) && !defined(HAVE_TICK_COUNTER)
Chris@82 345 typedef unsigned long ticks;
Chris@82 346
Chris@82 347 # ifdef __GNUC__
Chris@82 348 static __inline__ ticks getticks(void)
Chris@82 349 {
Chris@82 350 ticks ret;
Chris@82 351
Chris@82 352 __asm__ __volatile__("mfctl 16, %0": "=r" (ret));
Chris@82 353 /* no input, nothing else clobbered */
Chris@82 354 return ret;
Chris@82 355 }
Chris@82 356 # else
Chris@82 357 # include <machine/inline.h>
Chris@82 358 static inline unsigned long getticks(void)
Chris@82 359 {
Chris@82 360 register ticks ret;
Chris@82 361 _MFCTL(16, ret);
Chris@82 362 return ret;
Chris@82 363 }
Chris@82 364 # endif
Chris@82 365
Chris@82 366 INLINE_ELAPSED(inline)
Chris@82 367
Chris@82 368 #define HAVE_TICK_COUNTER
Chris@82 369 #endif
Chris@82 370
Chris@82 371 /*----------------------------------------------------------------*/
Chris@82 372 /* S390, courtesy of James Treacy */
Chris@82 373 #if defined(__GNUC__) && defined(__s390__) && !defined(HAVE_TICK_COUNTER)
Chris@82 374 typedef unsigned long long ticks;
Chris@82 375
Chris@82 376 static __inline__ ticks getticks(void)
Chris@82 377 {
Chris@82 378 ticks cycles;
Chris@82 379 __asm__("stck 0(%0)" : : "a" (&(cycles)) : "memory", "cc");
Chris@82 380 return cycles;
Chris@82 381 }
Chris@82 382
Chris@82 383 INLINE_ELAPSED(__inline__)
Chris@82 384
Chris@82 385 #define HAVE_TICK_COUNTER
Chris@82 386 #endif
Chris@82 387 /*----------------------------------------------------------------*/
Chris@82 388 #if defined(__GNUC__) && defined(__alpha__) && !defined(HAVE_TICK_COUNTER)
Chris@82 389 /*
Chris@82 390 * The 32-bit cycle counter on alpha overflows pretty quickly,
Chris@82 391 * unfortunately. A 1GHz machine overflows in 4 seconds.
Chris@82 392 */
Chris@82 393 typedef unsigned int ticks;
Chris@82 394
Chris@82 395 static __inline__ ticks getticks(void)
Chris@82 396 {
Chris@82 397 unsigned long cc;
Chris@82 398 __asm__ __volatile__ ("rpcc %0" : "=r"(cc));
Chris@82 399 return (cc & 0xFFFFFFFF);
Chris@82 400 }
Chris@82 401
Chris@82 402 INLINE_ELAPSED(__inline__)
Chris@82 403
Chris@82 404 #define HAVE_TICK_COUNTER
Chris@82 405 #endif
Chris@82 406
Chris@82 407 /*----------------------------------------------------------------*/
Chris@82 408 #if defined(__GNUC__) && defined(__sparc_v9__) && !defined(HAVE_TICK_COUNTER)
Chris@82 409 typedef unsigned long ticks;
Chris@82 410
Chris@82 411 static __inline__ ticks getticks(void)
Chris@82 412 {
Chris@82 413 ticks ret;
Chris@82 414 __asm__ __volatile__("rd %%tick, %0" : "=r" (ret));
Chris@82 415 return ret;
Chris@82 416 }
Chris@82 417
Chris@82 418 INLINE_ELAPSED(__inline__)
Chris@82 419
Chris@82 420 #define HAVE_TICK_COUNTER
Chris@82 421 #endif
Chris@82 422
Chris@82 423 /*----------------------------------------------------------------*/
Chris@82 424 #if (defined(__DECC) || defined(__DECCXX)) && defined(__alpha) && defined(HAVE_C_ASM_H) && !defined(HAVE_TICK_COUNTER)
Chris@82 425 # include <c_asm.h>
Chris@82 426 typedef unsigned int ticks;
Chris@82 427
Chris@82 428 static __inline ticks getticks(void)
Chris@82 429 {
Chris@82 430 unsigned long cc;
Chris@82 431 cc = asm("rpcc %v0");
Chris@82 432 return (cc & 0xFFFFFFFF);
Chris@82 433 }
Chris@82 434
Chris@82 435 INLINE_ELAPSED(__inline)
Chris@82 436
Chris@82 437 #define HAVE_TICK_COUNTER
Chris@82 438 #endif
Chris@82 439 /*----------------------------------------------------------------*/
Chris@82 440 /* SGI/Irix */
Chris@82 441 #if defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_SGI_CYCLE) && !defined(HAVE_TICK_COUNTER) && !defined(__ANDROID__)
Chris@82 442 typedef struct timespec ticks;
Chris@82 443
Chris@82 444 static inline ticks getticks(void)
Chris@82 445 {
Chris@82 446 struct timespec t;
Chris@82 447 clock_gettime(CLOCK_SGI_CYCLE, &t);
Chris@82 448 return t;
Chris@82 449 }
Chris@82 450
Chris@82 451 static inline double elapsed(ticks t1, ticks t0)
Chris@82 452 {
Chris@82 453 return ((double)t1.tv_sec - (double)t0.tv_sec) * 1.0E9 +
Chris@82 454 ((double)t1.tv_nsec - (double)t0.tv_nsec);
Chris@82 455 }
Chris@82 456 #define HAVE_TICK_COUNTER
Chris@82 457 #endif
Chris@82 458
Chris@82 459 /*----------------------------------------------------------------*/
Chris@82 460 /* Cray UNICOS _rtc() intrinsic function */
Chris@82 461 #if defined(HAVE__RTC) && !defined(HAVE_TICK_COUNTER)
Chris@82 462 #ifdef HAVE_INTRINSICS_H
Chris@82 463 # include <intrinsics.h>
Chris@82 464 #endif
Chris@82 465
Chris@82 466 typedef long long ticks;
Chris@82 467
Chris@82 468 #define getticks _rtc
Chris@82 469
Chris@82 470 INLINE_ELAPSED(inline)
Chris@82 471
Chris@82 472 #define HAVE_TICK_COUNTER
Chris@82 473 #endif
Chris@82 474
Chris@82 475 /*----------------------------------------------------------------*/
Chris@82 476 /* MIPS ZBus */
Chris@82 477 #if HAVE_MIPS_ZBUS_TIMER
Chris@82 478 #if defined(__mips__) && !defined(HAVE_TICK_COUNTER)
Chris@82 479 #include <sys/mman.h>
Chris@82 480 #include <unistd.h>
Chris@82 481 #include <fcntl.h>
Chris@82 482
Chris@82 483 typedef uint64_t ticks;
Chris@82 484
Chris@82 485 static inline ticks getticks(void)
Chris@82 486 {
Chris@82 487 static uint64_t* addr = 0;
Chris@82 488
Chris@82 489 if (addr == 0)
Chris@82 490 {
Chris@82 491 uint32_t rq_addr = 0x10030000;
Chris@82 492 int fd;
Chris@82 493 int pgsize;
Chris@82 494
Chris@82 495 pgsize = getpagesize();
Chris@82 496 fd = open ("/dev/mem", O_RDONLY | O_SYNC, 0);
Chris@82 497 if (fd < 0) {
Chris@82 498 perror("open");
Chris@82 499 return NULL;
Chris@82 500 }
Chris@82 501 addr = mmap(0, pgsize, PROT_READ, MAP_SHARED, fd, rq_addr);
Chris@82 502 close(fd);
Chris@82 503 if (addr == (uint64_t *)-1) {
Chris@82 504 perror("mmap");
Chris@82 505 return NULL;
Chris@82 506 }
Chris@82 507 }
Chris@82 508
Chris@82 509 return *addr;
Chris@82 510 }
Chris@82 511
Chris@82 512 INLINE_ELAPSED(inline)
Chris@82 513
Chris@82 514 #define HAVE_TICK_COUNTER
Chris@82 515 #endif
Chris@82 516 #endif /* HAVE_MIPS_ZBUS_TIMER */
Chris@82 517
Chris@82 518 #if defined(HAVE_ARMV7A_CNTVCT)
Chris@82 519 typedef uint64_t ticks;
Chris@82 520 static inline ticks getticks(void)
Chris@82 521 {
Chris@82 522 uint32_t Rt, Rt2 = 0;
Chris@82 523 asm volatile("mrrc p15, 1, %0, %1, c14" : "=r"(Rt), "=r"(Rt2));
Chris@82 524 return ((uint64_t)Rt) | (((uint64_t)Rt2) << 32);
Chris@82 525 }
Chris@82 526 INLINE_ELAPSED(inline)
Chris@82 527 #define HAVE_TICK_COUNTER
Chris@82 528 #endif
Chris@82 529
Chris@82 530 #if defined(HAVE_ARMV7A_PMCCNTR)
Chris@82 531 typedef uint64_t ticks;
Chris@82 532 static inline ticks getticks(void)
Chris@82 533 {
Chris@82 534 uint32_t r;
Chris@82 535 asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r"(r) );
Chris@82 536 return r;
Chris@82 537 }
Chris@82 538 INLINE_ELAPSED(inline)
Chris@82 539 #define HAVE_TICK_COUNTER
Chris@82 540 #endif
Chris@82 541
Chris@82 542 #if defined(__aarch64__) && defined(HAVE_ARMV8_CNTVCT_EL0) && !defined(HAVE_ARMV8_PMCCNTR_EL0)
Chris@82 543 typedef uint64_t ticks;
Chris@82 544 static inline ticks getticks(void)
Chris@82 545 {
Chris@82 546 uint64_t Rt;
Chris@82 547 asm volatile("mrs %0, CNTVCT_EL0" : "=r" (Rt));
Chris@82 548 return Rt;
Chris@82 549 }
Chris@82 550 INLINE_ELAPSED(inline)
Chris@82 551 #define HAVE_TICK_COUNTER
Chris@82 552 #endif
Chris@82 553
Chris@82 554 #if defined(__aarch64__) && defined(HAVE_ARMV8_PMCCNTR_EL0)
Chris@82 555 typedef uint64_t ticks;
Chris@82 556 static inline ticks getticks(void)
Chris@82 557 {
Chris@82 558 uint64_t cc = 0;
Chris@82 559 asm volatile("mrs %0, PMCCNTR_EL0" : "=r"(cc));
Chris@82 560 return cc;
Chris@82 561 }
Chris@82 562 INLINE_ELAPSED(inline)
Chris@82 563 #define HAVE_TICK_COUNTER
Chris@82 564 #endif