15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 2008 May 27
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The author disclaims copyright to this source code.  In place of
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** a legal notice, here is a blessing:
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**    May you do good and not evil.
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**    May you find forgiveness for yourself and forgive others.
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**    May you share freely, never taking more than you give.
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)******************************************************************************
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** This file contains inline asm code for retrieving "high-performance"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** counters for x86 class CPUs.
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef _HWTIME_H_
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define _HWTIME_H_
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The following routine only works on pentium-class (or newer) processors.
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** It uses the RDTSC opcode to read the cycle count value out of the
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** processor and returns that value.  This can be used for high-res
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** profiling.
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if (defined(__GNUC__) || defined(_MSC_VER)) && \
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (defined(i386) || defined(__i386__) || defined(_M_IX86))
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  #if defined(__GNUC__)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  __inline__ sqlite_uint64 sqlite3Hwtime(void){
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     unsigned int lo, hi;
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     return (sqlite_uint64)hi << 32 | lo;
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  #elif defined(_MSC_VER)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  __declspec(naked) __inline sqlite_uint64 __cdecl sqlite3Hwtime(void){
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     __asm {
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        rdtsc
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ret       ; return value at EDX:EAX
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     }
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  #endif
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif (defined(__GNUC__) && defined(__x86_64__))
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  __inline__ sqlite_uint64 sqlite3Hwtime(void){
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      unsigned long val;
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      __asm__ __volatile__ ("rdtsc" : "=A" (val));
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return val;
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif (defined(__GNUC__) && defined(__ppc__))
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  __inline__ sqlite_uint64 sqlite3Hwtime(void){
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      unsigned long long retval;
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      unsigned long junk;
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      __asm__ __volatile__ ("\n\
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          1:      mftbu   %1\n\
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  mftb    %L0\n\
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  mftbu   %0\n\
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  cmpw    %0,%1\n\
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  bne     1b"
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  : "=r" (retval), "=r" (junk));
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return retval;
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  #error Need implementation of sqlite3Hwtime() for your platform.
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /*
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ** To compile without implementing sqlite3Hwtime() for your platform,
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ** you can remove the above #error and use the following
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ** stub function.  You will lose timing support for many
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ** of the debugging and testing utilities, but it should at
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ** least compile and run.
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  */
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite_uint64 sqlite3Hwtime(void){ return ((sqlite_uint64)0); }
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* !defined(_HWTIME_H_) */
86