src/os_timer.cpp
author celestar
Wed, 21 Mar 2007 11:46:54 +0000
branchgamebalance
changeset 9899 cde52f745560
parent 9895 7bd07f43b0e3
child 6303 84c215fc8eb8
permissions -rw-r--r--
(svn r9386) [gamebalance] -Feature: Selling and buying land costs now take proximity to town centers into account. Move some code around while I'm at it. Also selling land gives as much money as buying land costs.
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
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
     3
#include "stdafx.h"
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
     4
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
     5
#undef RDTSC_AVAILABLE
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
/* 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
     8
 * 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
     9
#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
    10
# if _MSC_VER >= 1400
b7170a1ffb33 (svn r8933) -Fix [Win64]: rdtsc now uses intrinsic on VC8 (michi_cc)
KUDr
parents: 5835
diff changeset
    11
#include <intrin.h>
9895
7bd07f43b0e3 (svn r9321) [gamebalance] -Sync: r9025:9314 from trunk
celestar
parents: 6497
diff changeset
    12
uint64 _rdtsc()
6497
b7170a1ffb33 (svn r8933) -Fix [Win64]: rdtsc now uses intrinsic on VC8 (michi_cc)
KUDr
parents: 5835
diff changeset
    13
{
b7170a1ffb33 (svn r8933) -Fix [Win64]: rdtsc now uses intrinsic on VC8 (michi_cc)
KUDr
parents: 5835
diff changeset
    14
	return __rdtsc();
b7170a1ffb33 (svn r8933) -Fix [Win64]: rdtsc now uses intrinsic on VC8 (michi_cc)
KUDr
parents: 5835
diff changeset
    15
}
3383
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    16
#	else
9895
7bd07f43b0e3 (svn r9321) [gamebalance] -Sync: r9025:9314 from trunk
celestar
parents: 6497
diff changeset
    17
uint64 _declspec(naked) _rdtsc()
3383
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    18
{
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    19
	_asm {
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    20
		rdtsc
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    21
		ret
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    22
	}
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    23
}
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    24
# endif
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    25
# define RDTSC_AVAILABLE
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
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    28
/* 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
    29
#if defined (__WATCOMC__) && !defined(RDTSC_AVAILABLE)
9895
7bd07f43b0e3 (svn r9321) [gamebalance] -Sync: r9025:9314 from trunk
celestar
parents: 6497
diff changeset
    30
unsigned __int64 _rdtsc();
3383
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    31
# 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
    32
# define RDTSC_AVAILABLE
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    33
#endif
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    34
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    35
/* 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
    36
#if defined(__i386__) || defined(__x86_64__) && !defined(RDTSC_AVAILABLE)
9895
7bd07f43b0e3 (svn r9321) [gamebalance] -Sync: r9025:9314 from trunk
celestar
parents: 6497
diff changeset
    37
uint64 _rdtsc()
3383
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    38
{
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    39
	uint32 high, low;
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    40
	__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
    41
	return ((uint64)high << 32) | low;
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    42
}
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    43
# define RDTSC_AVAILABLE
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    44
#endif
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    45
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    46
/* 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
    47
#if (defined(__POWERPC__) || defined(__powerpc__)) && !defined(RDTSC_AVAILABLE)
9895
7bd07f43b0e3 (svn r9321) [gamebalance] -Sync: r9025:9314 from trunk
celestar
parents: 6497
diff changeset
    48
uint64 _rdtsc()
3383
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    49
{
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    50
	uint32 high = 0, high2 = 0, low;
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    51
	/* 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
    52
	 * 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
    53
	 * 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
    54
	 * 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
    55
	asm volatile (
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    56
				  "mftbu %0\n"
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    57
				  "mftb %1\n"
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    58
				  "mftbu %2\n"
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    59
				  "cmpw %3,%4\n"
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    60
				  "bne- $-16\n"
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    61
				  : "=r" (high), "=r" (low), "=r" (high2)
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    62
				  : "0" (high), "2" (high2)
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    63
				  );
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    64
	return ((uint64)high << 32) | low;
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
# define RDTSC_AVAILABLE
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    67
#endif
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    68
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    69
/* 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
    70
 * 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
    71
#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
    72
#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
    73
uint64 _rdtsc() {return 0;}
3383
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    74
#endif