/* ==================== GNU C and possibly other UNIX compilers ===================== */ #ifndef _WIN32 #if defined(__GNUC__) || defined(__linux__) #define VOLATILE __volatile__ #define ASM __asm__ #else /* if we're neither compiling with gcc or under linux, we can hope * the following lines work, they probably won't */ #define ASM asm #define VOLATILE #endif #define myInt64 unsigned long long #define INT32 unsigned int /* ======================== WIN32 ======================= */ #else #define myInt64 signed __int64 #define INT32 unsigned __int32 #endif /* This is the RDTSC timer. * RDTSC is an instruction on several Intel and compatible CPUs that Reads the * Time Stamp Counter. The Intel manuals contain more information. */ #define COUNTER_LO(a) ((a).int32.lo) #define COUNTER_HI(a) ((a).int32.hi) #define COUNTER_VAL(a) ((a).int64) #define COUNTER(a) \ ((unsigned long long)COUNTER_VAL(a)) #define COUNTER_DIFF(a,b) \ (COUNTER(a)-COUNTER(b)) /* ==================== GNU C and possibly other UNIX compilers ===================== */ #ifndef _WIN32 typedef union { myInt64 int64; struct {INT32 lo, hi;} int32; } tsc_counter; #define RDTSC(cpu_c) \ ASM VOLATILE ("rdtsc" : "=a" ((cpu_c).int32.lo), "=d"((cpu_c).int32.hi)) #define CPUID() \ ASM VOLATILE ("cpuid" : : "a" (0) : "bx", "cx", "dx" ) /* ======================== WIN32 ======================= */ #else typedef union { myInt64 int64; struct {INT32 lo, hi;} int32; } tsc_counter; #define RDTSC(cpu_c) \ { __asm rdtsc \ __asm mov (cpu_c).int32.lo,eax \ __asm mov (cpu_c).int32.hi,edx \ } #define CPUID() \ { \ __asm mov eax, 0 \ __asm cpuid \ } #endif static void init_tsc() { ; // no need to initialize anything for x86 } static myInt64 start_tsc(void) { tsc_counter start; CPUID(); RDTSC(start); return COUNTER_VAL(start); } static myInt64 stop_tsc(myInt64 start) { tsc_counter end; RDTSC(end); CPUID(); return COUNTER_VAL(end) - start; }