os_timer.c
author peter1138
Sun, 01 Oct 2006 12:00:32 +0000
changeset 4694 c917a3ad0dd2
parent 3407 150783e37553
child 5363 11cbdbe10de6
permissions -rw-r--r--
(svn r6601) - Codechange: Support cargo subtypes in the refit window. The refit window has been altered to support resizing and scrolling. Note that the cargo subtype isn't yet passed for actual refitting yet. (Based on mart3p's patch)
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
a4828297b799 (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
     3
#include "stdafx.h"
a4828297b799 (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
     4
a4828297b799 (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
     5
#undef RDTSC_AVAILABLE
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
/* 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
     8
 * from external win64.asm because VS2005 does not support inline assembly */
a4828297b799 (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)
a4828297b799 (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    10
# if defined (_M_AMD64)
a4828297b799 (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    11
extern uint64 _rdtsc(void);
a4828297b799 (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    12
#	else
a4828297b799 (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    13
uint64 _declspec(naked) _rdtsc(void)
a4828297b799 (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    14
{
a4828297b799 (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    15
	_asm {
a4828297b799 (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    16
		rdtsc
a4828297b799 (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    17
		ret
a4828297b799 (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    18
	}
a4828297b799 (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    19
}
a4828297b799 (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    20
# endif
a4828297b799 (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    21
# define RDTSC_AVAILABLE
a4828297b799 (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    22
#endif
a4828297b799 (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    23
a4828297b799 (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    24
/* 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
    25
#if defined (__WATCOMC__) && !defined(RDTSC_AVAILABLE)
a4828297b799 (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    26
unsigned __int64 _rdtsc( void);
a4828297b799 (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    27
# 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
    28
# define RDTSC_AVAILABLE
a4828297b799 (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    29
#endif
a4828297b799 (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    30
a4828297b799 (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    31
/* 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
    32
#if defined(__i386__) || defined(__x86_64__) && !defined(RDTSC_AVAILABLE)
a4828297b799 (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    33
uint64 _rdtsc(void)
a4828297b799 (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    34
{
a4828297b799 (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    35
	uint32 high, low;
a4828297b799 (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    36
	__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
    37
	return ((uint64)high << 32) | low;
a4828297b799 (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    38
}
a4828297b799 (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    39
# define RDTSC_AVAILABLE
a4828297b799 (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    40
#endif
a4828297b799 (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    41
a4828297b799 (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    42
/* rdtsc for PPC which has this not */
a4828297b799 (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    43
#if defined(__POWERPC__) && !defined(RDTSC_AVAILABLE)
a4828297b799 (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    44
uint64 _rdtsc(void)
a4828297b799 (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    45
{
a4828297b799 (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    46
	uint32 high = 0, high2 = 0, low;
a4828297b799 (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    47
	/* 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
    48
	 * 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
    49
	 * 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
    50
	 * 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
    51
	asm volatile (
a4828297b799 (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    52
				  "mftbu %0\n"
a4828297b799 (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    53
				  "mftb %1\n"
a4828297b799 (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    54
				  "mftbu %2\n"
a4828297b799 (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    55
				  "cmpw %3,%4\n"
a4828297b799 (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    56
				  "bne- $-16\n"
a4828297b799 (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    57
				  : "=r" (high), "=r" (low), "=r" (high2)
a4828297b799 (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    58
				  : "0" (high), "2" (high2)
a4828297b799 (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    59
				  );
a4828297b799 (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    60
	return ((uint64)high << 32) | low;
a4828297b799 (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    61
}
a4828297b799 (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    62
# define RDTSC_AVAILABLE
a4828297b799 (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    63
#endif
a4828297b799 (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    64
a4828297b799 (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    65
/* 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
    66
 * 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
    67
#if !defined(RDTSC_AVAILABLE)
3407
150783e37553 (svn r4218) - Codechange: Try to make the rdtsc() not present warning message a bit more clear
Darkvater
parents: 3383
diff changeset
    68
#warning "(non-fatal) No support for rdtsc(), you won't be able to profile with TIC/TOC"
3383
a4828297b799 (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    69
uint64 _rdtsc(void) {return 0;}
a4828297b799 (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    70
#endif