xref: /sqlite-3.40.0/src/hwtime.h (revision 594b124f)
19bcbdad2Sshane /*
29bcbdad2Sshane ** 2008 May 27
39bcbdad2Sshane **
49bcbdad2Sshane ** The author disclaims copyright to this source code.  In place of
59bcbdad2Sshane ** a legal notice, here is a blessing:
69bcbdad2Sshane **
79bcbdad2Sshane **    May you do good and not evil.
89bcbdad2Sshane **    May you find forgiveness for yourself and forgive others.
99bcbdad2Sshane **    May you share freely, never taking more than you give.
109bcbdad2Sshane **
119bcbdad2Sshane ******************************************************************************
129bcbdad2Sshane **
139bcbdad2Sshane ** This file contains inline asm code for retrieving "high-performance"
14*594b124fSdrh ** counters for x86 and x86_64 class CPUs.
159bcbdad2Sshane */
1643f58d6aSdrh #ifndef SQLITE_HWTIME_H
1743f58d6aSdrh #define SQLITE_HWTIME_H
189bcbdad2Sshane 
199bcbdad2Sshane /*
209bcbdad2Sshane ** The following routine only works on pentium-class (or newer) processors.
219bcbdad2Sshane ** It uses the RDTSC opcode to read the cycle count value out of the
229bcbdad2Sshane ** processor and returns that value.  This can be used for high-res
239bcbdad2Sshane ** profiling.
249bcbdad2Sshane */
25*594b124fSdrh #if !defined(__STRICT_ANSI__) && \
26*594b124fSdrh     (defined(__GNUC__) || defined(_MSC_VER)) && \
279bcbdad2Sshane     (defined(i386) || defined(__i386__) || defined(_M_IX86))
289bcbdad2Sshane 
299bcbdad2Sshane   #if defined(__GNUC__)
309bcbdad2Sshane 
sqlite3Hwtime(void)319bcbdad2Sshane   __inline__ sqlite_uint64 sqlite3Hwtime(void){
329bcbdad2Sshane      unsigned int lo, hi;
339bcbdad2Sshane      __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
349bcbdad2Sshane      return (sqlite_uint64)hi << 32 | lo;
359bcbdad2Sshane   }
369bcbdad2Sshane 
379bcbdad2Sshane   #elif defined(_MSC_VER)
389bcbdad2Sshane 
sqlite3Hwtime(void)399bcbdad2Sshane   __declspec(naked) __inline sqlite_uint64 __cdecl sqlite3Hwtime(void){
409bcbdad2Sshane      __asm {
419bcbdad2Sshane         rdtsc
429bcbdad2Sshane         ret       ; return value at EDX:EAX
439bcbdad2Sshane      }
449bcbdad2Sshane   }
459bcbdad2Sshane 
469bcbdad2Sshane   #endif
479bcbdad2Sshane 
48*594b124fSdrh #elif !defined(__STRICT_ANSI__) && (defined(__GNUC__) && defined(__x86_64__))
49b08c1d0cSshane 
50b08c1d0cSshane   __inline__ sqlite_uint64 sqlite3Hwtime(void){
51b08c1d0cSshane       unsigned long val;
52b08c1d0cSshane       __asm__ __volatile__ ("rdtsc" : "=A" (val));
53b08c1d0cSshane       return val;
54b08c1d0cSshane   }
55b08c1d0cSshane 
56*594b124fSdrh #elif !defined(__STRICT_ANSI__) && (defined(__GNUC__) && defined(__ppc__))
575cd89cfeSshane 
585cd89cfeSshane   __inline__ sqlite_uint64 sqlite3Hwtime(void){
595cd89cfeSshane       unsigned long long retval;
605cd89cfeSshane       unsigned long junk;
615cd89cfeSshane       __asm__ __volatile__ ("\n\
625cd89cfeSshane           1:      mftbu   %1\n\
635cd89cfeSshane                   mftb    %L0\n\
645cd89cfeSshane                   mftbu   %0\n\
655cd89cfeSshane                   cmpw    %0,%1\n\
665cd89cfeSshane                   bne     1b"
675cd89cfeSshane                   : "=r" (retval), "=r" (junk));
685cd89cfeSshane       return retval;
695cd89cfeSshane   }
705cd89cfeSshane 
719bcbdad2Sshane #else
729bcbdad2Sshane 
739bcbdad2Sshane   /*
74*594b124fSdrh   ** asm() is needed for hardware timing support.  Without asm(),
75*594b124fSdrh   ** disable the sqlite3Hwtime() routine.
76*594b124fSdrh   **
77*594b124fSdrh   ** sqlite3Hwtime() is only used for some obscure debugging
78*594b124fSdrh   ** and analysis configurations, not in any deliverable, so this
79*594b124fSdrh   ** should not be a great loss.
809bcbdad2Sshane   */
819bcbdad2Sshane   sqlite_uint64 sqlite3Hwtime(void){ return ((sqlite_uint64)0); }
829bcbdad2Sshane 
839bcbdad2Sshane #endif
849bcbdad2Sshane 
8543f58d6aSdrh #endif /* !defined(SQLITE_HWTIME_H) */
86