author | celestar |
Tue, 19 Jun 2007 07:21:01 +0000 | |
branch | gamebalance |
changeset 9913 | e79cd19772dd |
parent 9906 | 6f41b8713b65 |
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 |
|
9906
6f41b8713b65
(svn r9674) [gamebalance] -Sync: r9322:9420 from trunk
celestar
parents:
9895
diff
changeset
|
3 |
/** @file os_timer.cpp */ |
6f41b8713b65
(svn r9674) [gamebalance] -Sync: r9322:9420 from trunk
celestar
parents:
9895
diff
changeset
|
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) |
6497
b7170a1ffb33
(svn r8933) -Fix [Win64]: rdtsc now uses intrinsic on VC8 (michi_cc)
KUDr
parents:
5835
diff
changeset
|
12 |
# if _MSC_VER >= 1400 |
b7170a1ffb33
(svn r8933) -Fix [Win64]: rdtsc now uses intrinsic on VC8 (michi_cc)
KUDr
parents:
5835
diff
changeset
|
13 |
#include <intrin.h> |
9895
7bd07f43b0e3
(svn r9321) [gamebalance] -Sync: r9025:9314 from trunk
celestar
parents:
6497
diff
changeset
|
14 |
uint64 _rdtsc() |
6497
b7170a1ffb33
(svn r8933) -Fix [Win64]: rdtsc now uses intrinsic on VC8 (michi_cc)
KUDr
parents:
5835
diff
changeset
|
15 |
{ |
b7170a1ffb33
(svn r8933) -Fix [Win64]: rdtsc now uses intrinsic on VC8 (michi_cc)
KUDr
parents:
5835
diff
changeset
|
16 |
return __rdtsc(); |
b7170a1ffb33
(svn r8933) -Fix [Win64]: rdtsc now uses intrinsic on VC8 (michi_cc)
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 |
9895
7bd07f43b0e3
(svn r9321) [gamebalance] -Sync: r9025:9314 from trunk
celestar
parents:
6497
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) |
9895
7bd07f43b0e3
(svn r9321) [gamebalance] -Sync: r9025:9314 from trunk
celestar
parents:
6497
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) |
9895
7bd07f43b0e3
(svn r9321) [gamebalance] -Sync: r9025:9314 from trunk
celestar
parents:
6497
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) |
9895
7bd07f43b0e3
(svn r9321) [gamebalance] -Sync: r9025:9314 from trunk
celestar
parents:
6497
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" |
9895
7bd07f43b0e3
(svn r9321) [gamebalance] -Sync: r9025:9314 from trunk
celestar
parents:
6497
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 |