1/*
2** 2008 May 27
3**
4** The author disclaims copyright to this source code.  In place of
5** a legal notice, here is a blessing:
6**
7**    May you do good and not evil.
8**    May you find forgiveness for yourself and forgive others.
9**    May you share freely, never taking more than you give.
10**
11******************************************************************************
12**
13** This file contains inline asm code for retrieving "high-performance"
14** counters for x86 class CPUs.
15*/
16#ifndef _HWTIME_H_
17#define _HWTIME_H_
18
19/*
20** The following routine only works on pentium-class (or newer) processors.
21** It uses the RDTSC opcode to read the cycle count value out of the
22** processor and returns that value.  This can be used for high-res
23** profiling.
24*/
25#if (defined(__GNUC__) || defined(_MSC_VER)) && \
26      (defined(i386) || defined(__i386__) || defined(_M_IX86))
27
28  #if defined(__GNUC__)
29
30  __inline__ sqlite_uint64 sqlite3Hwtime(void){
31     unsigned int lo, hi;
32     __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
33     return (sqlite_uint64)hi << 32 | lo;
34  }
35
36  #elif defined(_MSC_VER)
37
38  __declspec(naked) __inline sqlite_uint64 __cdecl sqlite3Hwtime(void){
39     __asm {
40        rdtsc
41        ret       ; return value at EDX:EAX
42     }
43  }
44
45  #endif
46
47#elif (defined(__GNUC__) && defined(__x86_64__))
48
49  __inline__ sqlite_uint64 sqlite3Hwtime(void){
50      unsigned long val;
51      __asm__ __volatile__ ("rdtsc" : "=A" (val));
52      return val;
53  }
54
55#elif (defined(__GNUC__) && defined(__ppc__))
56
57  __inline__ sqlite_uint64 sqlite3Hwtime(void){
58      unsigned long long retval;
59      unsigned long junk;
60      __asm__ __volatile__ ("\n\
61          1:      mftbu   %1\n\
62                  mftb    %L0\n\
63                  mftbu   %0\n\
64                  cmpw    %0,%1\n\
65                  bne     1b"
66                  : "=r" (retval), "=r" (junk));
67      return retval;
68  }
69
70#else
71
72  #error Need implementation of sqlite3Hwtime() for your platform.
73
74  /*
75  ** To compile without implementing sqlite3Hwtime() for your platform,
76  ** you can remove the above #error and use the following
77  ** stub function.  You will lose timing support for many
78  ** of the debugging and testing utilities, but it should at
79  ** least compile and run.
80  */
81  sqlite_uint64 sqlite3Hwtime(void){ return ((sqlite_uint64)0); }
82
83#endif
84
85#endif /* !defined(_HWTIME_H_) */
86