/*
Copyright (C) 2001 Paul Davis
Code derived from various headers from the Linux kernel
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
* We only use the low 32 bits, and we'd simply better make sure
* that we reschedule before that wraps. Scheduling at least every
* four billion cycles just basically sounds like a good idea,
- * regardless of how fast the machine is.
+ * regardless of how fast the machine is.
*/
typedef uint64_t cycles_t;
extern cycles_t cacheflush_time;
-#define rdtscll(val) \
- __asm__ __volatile__("rdtsc" : "=A" (val))
+#if defined(__x86_64__)
+
+#define rdtscll(lo, hi) \
+ __asm__ __volatile__("rdtsc" : "=a" (lo), "=d" (hi))
+
+static inline cycles_t get_cycles (void)
+{
+ cycles_t lo, hi;
+
+ rdtscll(lo, hi);
+ return lo;
+}
+
+#else
+
+#define rdtscll(val) \
+__asm__ __volatile__("rdtsc" : "=A" (val))
static inline cycles_t get_cycles (void)
{
- uint32_t long ret;
+ cycles_t ret;
rdtscll(ret);
- return ret;
+ return ret & 0xffffffff;
}
+#endif
#elif defined(__powerpc__)
* Standard way to access the cycle counter.
* Currently only used on SMP for scheduling.
*
- * Only the low 32 bits are available as a continuously counting entity.
+ * Only the low 32 bits are available as a continuously counting entity.
* But this only means we'll force a reschedule every 8 seconds or so,
* which isn't an evil thing.
*/
typedef uint32_t long cycles_t;
static inline cycles_t get_cycles(void)
{
- cycles_t cycles;
- __asm__("stck 0(%0)" : : "a" (&(cycles)) : "memory", "cc");
- return cycles >> 2;
+ cycles_t cycles;
+ __asm__("stck 0(%0)" : : "a" (&(cycles)) : "memory", "cc");
+ return cycles >> 2;
}
#elif defined(__hppa__)
/* hppa/parisc */
#define mfctl(reg) ({ \
- uint32_t cr; \
- __asm__ __volatile__( \
- "mfctl " #reg ",%0" : \
- "=r" (cr) \
- ); \
- cr; \
+ uint32_t cr; \
+ __asm__ __volatile__( \
+ "mfctl " #reg ",%0" : \
+ "=r" (cr) \
+ ); \
+ cr; \
})
typedef uint32_t cycles_t;
static inline cycles_t get_cycles (void)
{
- return mfctl(16);
+ return mfctl(16);
}
#elif defined(__mips__)
* We know that all SMP capable CPUs have cycle counters.
*/
-#define __read_32bit_c0_register(source, sel) \
-({ int __res; \
- if (sel == 0) \
- __asm__ __volatile__( \
- "mfc0\t%0, " #source "\n\t" \
- : "=r" (__res)); \
- else \
- __asm__ __volatile__( \
- ".set\tmips32\n\t" \
- "mfc0\t%0, " #source ", " #sel "\n\t" \
- ".set\tmips0\n\t" \
- : "=r" (__res)); \
- __res; \
+#define __read_32bit_c0_register(source, sel) \
+({ int __res; \
+ if (sel == 0) \
+ __asm__ __volatile__( \
+ "mfc0\t%0, " #source "\n\t" \
+ : "=r" (__res)); \
+ else \
+ __asm__ __volatile__( \
+ ".set\tmips32\n\t" \
+ "mfc0\t%0, " #source ", " #sel "\n\t" \
+ ".set\tmips0\n\t" \
+ : "=r" (__res)); \
+ __res; \
})
/* #define CP0_COUNT $9 */
typedef uint32_t cycles_t;
static inline cycles_t get_cycles (void)
{
- return read_c0_count();
+ return read_c0_count();
}
/* begin mach */
typedef UInt64 cycles_t;
static inline cycles_t get_cycles (void)
{
- UInt64 time = AudioGetCurrentHostTime();
- return AudioConvertHostTimeToNanos(time);
+ UInt64 time = AudioGetCurrentHostTime();
+ return AudioConvertHostTimeToNanos(time);
}
/* end mach */
static inline cycles_t get_cycles(void)
{
- struct timeval tv;
- gettimeofday (&tv, NULL);
+ struct timeval tv;
+ gettimeofday (&tv, NULL);
- return tv.tv_usec;
+ return tv.tv_usec;
}
#endif