author | KUDr |
Sat, 21 Apr 2007 08:23:57 +0000 | |
branch | cpp_gui |
changeset 6308 | 646711c5feaa |
parent 6303 | 84c215fc8eb8 |
child 6800 | 6c09e1e86fcb |
permissions | -rw-r--r-- |
3383
24871cb73dbf
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
1 |
/* $Id$ */ |
24871cb73dbf
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
2 |
|
6303 | 3 |
/** @file os_timer.cpp */ |
4 |
||
3383
24871cb73dbf
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
5 |
#include "stdafx.h" |
24871cb73dbf
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
6 |
|
24871cb73dbf
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
7 |
#undef RDTSC_AVAILABLE |
24871cb73dbf
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
8 |
|
24871cb73dbf
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
9 |
/* rdtsc for MSC_VER, uses simple inline assembly, or _rdtsc |
24871cb73dbf
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
10 |
* from external win64.asm because VS2005 does not support inline assembly */ |
24871cb73dbf
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
11 |
#if defined(_MSC_VER) && !defined(RDTSC_AVAILABLE) |
6285
187e3ef04cc9
(svn r9004) [cpp_gui] -Sync with trunk (r8900..r9003)
KUDr
parents:
5835
diff
changeset
|
12 |
# if _MSC_VER >= 1400 |
187e3ef04cc9
(svn r9004) [cpp_gui] -Sync with trunk (r8900..r9003)
KUDr
parents:
5835
diff
changeset
|
13 |
#include <intrin.h> |
6298
c30fe89622df
(svn r9119) [cpp_gui] -Sync with trunk (r9003:9100)
bjarni
parents:
6285
diff
changeset
|
14 |
uint64 _rdtsc() |
6285
187e3ef04cc9
(svn r9004) [cpp_gui] -Sync with trunk (r8900..r9003)
KUDr
parents:
5835
diff
changeset
|
15 |
{ |
187e3ef04cc9
(svn r9004) [cpp_gui] -Sync with trunk (r8900..r9003)
KUDr
parents:
5835
diff
changeset
|
16 |
return __rdtsc(); |
187e3ef04cc9
(svn r9004) [cpp_gui] -Sync with trunk (r8900..r9003)
KUDr
parents:
5835
diff
changeset
|
17 |
} |
3383
24871cb73dbf
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
18 |
# else |
6298
c30fe89622df
(svn r9119) [cpp_gui] -Sync with trunk (r9003:9100)
bjarni
parents:
6285
diff
changeset
|
19 |
uint64 _declspec(naked) _rdtsc() |
3383
24871cb73dbf
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
20 |
{ |
24871cb73dbf
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
21 |
_asm { |
24871cb73dbf
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
22 |
rdtsc |
24871cb73dbf
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
23 |
ret |
24871cb73dbf
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
24 |
} |
24871cb73dbf
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
25 |
} |
24871cb73dbf
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
26 |
# endif |
24871cb73dbf
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
27 |
# define RDTSC_AVAILABLE |
24871cb73dbf
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
28 |
#endif |
24871cb73dbf
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
29 |
|
24871cb73dbf
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
30 |
/* rdtsc for OS/2. Hopefully this works, who knows */ |
24871cb73dbf
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
31 |
#if defined (__WATCOMC__) && !defined(RDTSC_AVAILABLE) |
6298
c30fe89622df
(svn r9119) [cpp_gui] -Sync with trunk (r9003:9100)
bjarni
parents:
6285
diff
changeset
|
32 |
unsigned __int64 _rdtsc(); |
3383
24871cb73dbf
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
33 |
# pragma aux _rdtsc = 0x0F 0x31 value [edx eax] parm nomemory modify exact [edx eax] nomemory; |
24871cb73dbf
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
34 |
# define RDTSC_AVAILABLE |
24871cb73dbf
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
35 |
#endif |
24871cb73dbf
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
36 |
|
24871cb73dbf
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
37 |
/* rdtsc for all other *nix-en (hopefully). Use GCC syntax */ |
24871cb73dbf
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
38 |
#if defined(__i386__) || defined(__x86_64__) && !defined(RDTSC_AVAILABLE) |
6298
c30fe89622df
(svn r9119) [cpp_gui] -Sync with trunk (r9003:9100)
bjarni
parents:
6285
diff
changeset
|
39 |
uint64 _rdtsc() |
3383
24871cb73dbf
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
40 |
{ |
24871cb73dbf
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
41 |
uint32 high, low; |
24871cb73dbf
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
42 |
__asm__ __volatile__ ("rdtsc" : "=a" (low), "=d" (high)); |
24871cb73dbf
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
43 |
return ((uint64)high << 32) | low; |
24871cb73dbf
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
44 |
} |
24871cb73dbf
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
45 |
# define RDTSC_AVAILABLE |
24871cb73dbf
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
46 |
#endif |
24871cb73dbf
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
47 |
|
24871cb73dbf
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
48 |
/* rdtsc for PPC which has this not */ |
5551
5cc56d0e6f5f
(svn r7548) -Codechange: Some MorphOS changes to get OpenTTD compiled, packaged (tokai)
Darkvater
parents:
3407
diff
changeset
|
49 |
#if (defined(__POWERPC__) || defined(__powerpc__)) && !defined(RDTSC_AVAILABLE) |
6298
c30fe89622df
(svn r9119) [cpp_gui] -Sync with trunk (r9003:9100)
bjarni
parents:
6285
diff
changeset
|
50 |
uint64 _rdtsc() |
3383
24871cb73dbf
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
51 |
{ |
24871cb73dbf
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
52 |
uint32 high = 0, high2 = 0, low; |
24871cb73dbf
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
53 |
/* PPC does not have rdtsc, so we cheat by reading the two 32-bit time-counters |
24871cb73dbf
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
54 |
* it has, 'Move From Time Base (Upper)'. Since these are two reads, in the |
24871cb73dbf
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
55 |
* very unlikely event that the lower part overflows to the upper part while we |
24871cb73dbf
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
56 |
* read it; we double-check and reread the registers */ |
24871cb73dbf
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
57 |
asm volatile ( |
24871cb73dbf
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
58 |
"mftbu %0\n" |
24871cb73dbf
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
59 |
"mftb %1\n" |
24871cb73dbf
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
60 |
"mftbu %2\n" |
24871cb73dbf
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
61 |
"cmpw %3,%4\n" |
24871cb73dbf
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
62 |
"bne- $-16\n" |
24871cb73dbf
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
63 |
: "=r" (high), "=r" (low), "=r" (high2) |
24871cb73dbf
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
64 |
: "0" (high), "2" (high2) |
24871cb73dbf
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
65 |
); |
24871cb73dbf
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
66 |
return ((uint64)high << 32) | low; |
24871cb73dbf
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
67 |
} |
24871cb73dbf
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
68 |
# define RDTSC_AVAILABLE |
24871cb73dbf
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
69 |
#endif |
24871cb73dbf
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
70 |
|
24871cb73dbf
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
71 |
/* In all other cases we have no support for rdtsc. No major issue, |
24871cb73dbf
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
72 |
* you just won't be able to profile your code with TIC()/TOC() */ |
24871cb73dbf
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
73 |
#if !defined(RDTSC_AVAILABLE) |
3407
eb0845aa1db7
(svn r4218) - Codechange: Try to make the rdtsc() not present warning message a bit more clear
Darkvater
parents:
3383
diff
changeset
|
74 |
#warning "(non-fatal) No support for rdtsc(), you won't be able to profile with TIC/TOC" |
6298
c30fe89622df
(svn r9119) [cpp_gui] -Sync with trunk (r9003:9100)
bjarni
parents:
6285
diff
changeset
|
75 |
uint64 _rdtsc() {return 0;} |
3383
24871cb73dbf
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
76 |
#endif |