author | rubidium |
Sun, 25 May 2008 19:17:03 +0000 | |
changeset 9354 | 845e07db4549 |
parent 9111 | 48ce04029fe4 |
child 10383 | 7aee0e95303f |
permissions | -rw-r--r-- |
3383
a4828297b799
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
1 |
/* $Id$ */ |
a4828297b799
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
2 |
|
9111
48ce04029fe4
(svn r12971) -Documentation: add @file in files that missed them and add something more than whitespace as description of files that don't have a description.
rubidium
parents:
7405
diff
changeset
|
3 |
/** @file os_timer.cpp OS/compiler dependant real time tick sampling. */ |
6351
8d0b6cce8d6d
(svn r9390) -Documentation : correct Doxygen of comments and @file inclusion. This time, brought to you by the letter O
belugas
parents:
6247
diff
changeset
|
4 |
|
3383
a4828297b799
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
5 |
#include "stdafx.h" |
a4828297b799
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
6 |
|
a4828297b799
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
7 |
#undef RDTSC_AVAILABLE |
a4828297b799
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
8 |
|
a4828297b799
(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 |
a4828297b799
(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 */ |
7405
2fd57f130eca
(svn r10778) -Fix: one-liners to allow MSVC and WINCE to work together (or anyway, a step towards that goal)
truelight
parents:
6351
diff
changeset
|
11 |
#if defined(_MSC_VER) && !defined(RDTSC_AVAILABLE) && !defined(WINCE) |
6171
fb9997933c24
(svn r8933) -Fix [Win64]: rdtsc now uses intrinsic on VC8 (michi_cc)
KUDr
parents:
5584
diff
changeset
|
12 |
# if _MSC_VER >= 1400 |
fb9997933c24
(svn r8933) -Fix [Win64]: rdtsc now uses intrinsic on VC8 (michi_cc)
KUDr
parents:
5584
diff
changeset
|
13 |
#include <intrin.h> |
6247 | 14 |
uint64 _rdtsc() |
6171
fb9997933c24
(svn r8933) -Fix [Win64]: rdtsc now uses intrinsic on VC8 (michi_cc)
KUDr
parents:
5584
diff
changeset
|
15 |
{ |
fb9997933c24
(svn r8933) -Fix [Win64]: rdtsc now uses intrinsic on VC8 (michi_cc)
KUDr
parents:
5584
diff
changeset
|
16 |
return __rdtsc(); |
fb9997933c24
(svn r8933) -Fix [Win64]: rdtsc now uses intrinsic on VC8 (michi_cc)
KUDr
parents:
5584
diff
changeset
|
17 |
} |
3383
a4828297b799
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
18 |
# else |
6247 | 19 |
uint64 _declspec(naked) _rdtsc() |
3383
a4828297b799
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
20 |
{ |
a4828297b799
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
21 |
_asm { |
a4828297b799
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
22 |
rdtsc |
a4828297b799
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
23 |
ret |
a4828297b799
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
24 |
} |
a4828297b799
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
25 |
} |
a4828297b799
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
26 |
# endif |
a4828297b799
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
27 |
# define RDTSC_AVAILABLE |
a4828297b799
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
28 |
#endif |
a4828297b799
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
29 |
|
a4828297b799
(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 */ |
a4828297b799
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
31 |
#if defined (__WATCOMC__) && !defined(RDTSC_AVAILABLE) |
6247 | 32 |
unsigned __int64 _rdtsc(); |
3383
a4828297b799
(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; |
a4828297b799
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
34 |
# define RDTSC_AVAILABLE |
a4828297b799
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
35 |
#endif |
a4828297b799
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
36 |
|
a4828297b799
(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 */ |
a4828297b799
(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) |
6247 | 39 |
uint64 _rdtsc() |
3383
a4828297b799
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
40 |
{ |
a4828297b799
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
41 |
uint32 high, low; |
a4828297b799
(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)); |
a4828297b799
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
43 |
return ((uint64)high << 32) | low; |
a4828297b799
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
44 |
} |
a4828297b799
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
45 |
# define RDTSC_AVAILABLE |
a4828297b799
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
46 |
#endif |
a4828297b799
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
47 |
|
a4828297b799
(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 */ |
5363
11cbdbe10de6
(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) |
6247 | 50 |
uint64 _rdtsc() |
3383
a4828297b799
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
51 |
{ |
a4828297b799
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
52 |
uint32 high = 0, high2 = 0, low; |
a4828297b799
(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 |
a4828297b799
(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 |
a4828297b799
(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 |
a4828297b799
(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 */ |
a4828297b799
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
57 |
asm volatile ( |
a4828297b799
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
58 |
"mftbu %0\n" |
a4828297b799
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
59 |
"mftb %1\n" |
a4828297b799
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
60 |
"mftbu %2\n" |
a4828297b799
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
61 |
"cmpw %3,%4\n" |
a4828297b799
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
62 |
"bne- $-16\n" |
a4828297b799
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
63 |
: "=r" (high), "=r" (low), "=r" (high2) |
a4828297b799
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
64 |
: "0" (high), "2" (high2) |
a4828297b799
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
65 |
); |
a4828297b799
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
66 |
return ((uint64)high << 32) | low; |
a4828297b799
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
67 |
} |
a4828297b799
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
68 |
# define RDTSC_AVAILABLE |
a4828297b799
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
69 |
#endif |
a4828297b799
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
70 |
|
a4828297b799
(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, |
a4828297b799
(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() */ |
a4828297b799
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
73 |
#if !defined(RDTSC_AVAILABLE) |
7405
2fd57f130eca
(svn r10778) -Fix: one-liners to allow MSVC and WINCE to work together (or anyway, a step towards that goal)
truelight
parents:
6351
diff
changeset
|
74 |
/* MSVC (in case of WinCE) can't handle #warning */ |
2fd57f130eca
(svn r10778) -Fix: one-liners to allow MSVC and WINCE to work together (or anyway, a step towards that goal)
truelight
parents:
6351
diff
changeset
|
75 |
# if !defined(_MSC_VER) |
3407
150783e37553
(svn r4218) - Codechange: Try to make the rdtsc() not present warning message a bit more clear
Darkvater
parents:
3383
diff
changeset
|
76 |
#warning "(non-fatal) No support for rdtsc(), you won't be able to profile with TIC/TOC" |
7405
2fd57f130eca
(svn r10778) -Fix: one-liners to allow MSVC and WINCE to work together (or anyway, a step towards that goal)
truelight
parents:
6351
diff
changeset
|
77 |
# endif |
6247 | 78 |
uint64 _rdtsc() {return 0;} |
3383
a4828297b799
(svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents:
3362
diff
changeset
|
79 |
#endif |