|
1 #include "stdafx.h" |
|
2 |
|
3 #undef RDTSC_AVAILABLE |
|
4 |
|
5 /* rdtsc for MSC_VER, uses simple inline assembly, or _rdtsc |
|
6 * from external win64.asm because VS2005 does not support inline assembly */ |
|
7 #if defined(_MSC_VER) && !defined(RDTSC_AVAILABLE) |
|
8 # if defined (_M_AMD64) |
|
9 extern uint64 _rdtsc(void); |
|
10 # else |
|
11 uint64 _declspec(naked) _rdtsc(void) |
|
12 { |
|
13 _asm { |
|
14 rdtsc |
|
15 ret |
|
16 } |
|
17 } |
|
18 # endif |
|
19 # define RDTSC_AVAILABLE |
|
20 #endif |
|
21 |
|
22 /* rdtsc for OS/2. Hopefully this works, who knows */ |
|
23 #if defined (__WATCOMC__) && !defined(RDTSC_AVAILABLE) |
|
24 unsigned __int64 _rdtsc( void); |
|
25 # pragma aux _rdtsc = 0x0F 0x31 value [edx eax] parm nomemory modify exact [edx eax] nomemory; |
|
26 # define RDTSC_AVAILABLE |
|
27 #endif |
|
28 |
|
29 /* rdtsc for all other *nix-en (hopefully). Use GCC syntax */ |
|
30 #if defined(__i386__) || defined(__x86_64__) && !defined(RDTSC_AVAILABLE) |
|
31 uint64 _rdtsc(void) |
|
32 { |
|
33 uint32 high, low; |
|
34 __asm__ __volatile__ ("rdtsc" : "=a" (low), "=d" (high)); |
|
35 return ((uint64)high << 32) | low; |
|
36 } |
|
37 # define RDTSC_AVAILABLE |
|
38 #endif |
|
39 |
|
40 /* rdtsc for PPC which has this not */ |
|
41 #if defined(__POWERPC__) && !defined(RDTSC_AVAILABLE) |
|
42 uint64 _rdtsc(void) |
|
43 { |
|
44 uint32 high, low; |
|
45 uint32 high2 = 0; |
|
46 /* PPC does not have rdtsc, so we cheat by reading the two 32-bit time-counters |
|
47 * it has, 'Move From Time Base (Upper)'. Since these are two reads, in the |
|
48 * very unlikely event that the lower part overflows to the upper part while we |
|
49 * read it; we double-check and reread the registers */ |
|
50 asm volatile ( |
|
51 "mftbu %0\n" |
|
52 "mftb %1\n" |
|
53 "mftbu %2\n" |
|
54 "cmpw %3,%4\n" |
|
55 "bne- $-16\n" |
|
56 : "=r" (high), "=r" (low), "=r" (high2) |
|
57 : "0" (high), "2" (high2) |
|
58 ); |
|
59 return ((uint64)high << 32) | low; |
|
60 } |
|
61 # define RDTSC_AVAILABLE |
|
62 #endif |
|
63 |
|
64 /* In all other cases we have no support for rdtsc. No major issue, |
|
65 * you just won't be able to profile your code with TIC()/TOC() */ |
|
66 #if !defined(RDTSC_AVAILABLE) |
|
67 #warning "OS has no support for rdtsc()" |
|
68 uint64 _rdtsc(void) {return 0;} |
|
69 #endif |