diff options
author | chappedm@gmail.com <chappedm@gmail.com@6b5cf1ce-ec42-a296-1ba9-69fdba395a50> | 2012-09-18 00:42:23 +0000 |
---|---|---|
committer | chappedm@gmail.com <chappedm@gmail.com@6b5cf1ce-ec42-a296-1ba9-69fdba395a50> | 2012-09-18 00:42:23 +0000 |
commit | 711232a1ef4997305a681287191de74f6597dabc (patch) | |
tree | b59559f62c794ca4971b90ae1e024c7398df8368 | |
parent | fa0209f261c5e065d523bb1858f84fd91eb2f39a (diff) | |
download | gperftools-711232a1ef4997305a681287191de74f6597dabc.tar.gz |
issue-453 Added support to get the timebase register value using just one instruction and also adjusts the PPC32 code to the recent GLIBC one that implements the same functionality
git-svn-id: http://gperftools.googlecode.com/svn/trunk@153 6b5cf1ce-ec42-a296-1ba9-69fdba395a50
-rw-r--r-- | src/base/cycleclock.h | 23 |
1 files changed, 16 insertions, 7 deletions
diff --git a/src/base/cycleclock.h b/src/base/cycleclock.h index c704e1d..fbf6dfc 100644 --- a/src/base/cycleclock.h +++ b/src/base/cycleclock.h @@ -97,15 +97,24 @@ struct CycleClock { uint64 low, high; __asm__ volatile ("rdtsc" : "=a" (low), "=d" (high)); return (high << 32) | low; +#elif defined(__powerpc64__) || defined(__ppc64__) + uint64 tb; + __asm__ volatile (\ + "mfspr %0, 268" + : "=r" (tb)); + return tb; #elif defined(__powerpc__) || defined(__ppc__) // This returns a time-base, which is not always precisely a cycle-count. - int64 tbl, tbu0, tbu1; - asm("mftbu %0" : "=r" (tbu0)); - asm("mftb %0" : "=r" (tbl)); - asm("mftbu %0" : "=r" (tbu1)); - tbl &= -static_cast<int64>(tbu0 == tbu1); - // high 32 bits in tbu1; low 32 bits in tbl (tbu0 is garbage) - return (tbu1 << 32) | tbl; + uint32 tbu, tbl, tmp; + __asm__ volatile (\ + "0:\n" + "mftbu %0\n" + "mftbl %1\n" + "mftbu %2\n" + "cmpw %0, %2\n" + "bne- 0b" + : "=r" (tbu), "=r" (tbl), "=r" (tmp)); + return (((uint64) tbu << 32) | tbl); #elif defined(__sparc__) int64 tick; asm(".byte 0x83, 0x41, 0x00, 0x00"); |