summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorchappedm@gmail.com <chappedm@gmail.com@6b5cf1ce-ec42-a296-1ba9-69fdba395a50>2012-09-18 00:42:23 +0000
committerchappedm@gmail.com <chappedm@gmail.com@6b5cf1ce-ec42-a296-1ba9-69fdba395a50>2012-09-18 00:42:23 +0000
commit711232a1ef4997305a681287191de74f6597dabc (patch)
treeb59559f62c794ca4971b90ae1e024c7398df8368
parentfa0209f261c5e065d523bb1858f84fd91eb2f39a (diff)
downloadgperftools-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.h23
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");