Fix build on FreeBSD/powerpc (#616)

* Fix build on FreeBSD/powerpc

Only glibc has __ppc_get_timebase(), __ppc_get_timebase_freq() and sys/platform/ppc.h.
This commit is contained in:
kgotlinux 2020-02-25 22:27:31 +01:00 committed by GitHub
parent 0d5ce2797e
commit 0033c9ea91
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -21,7 +21,12 @@
#endif
#if defined(__powerpc__) || defined(__ppc__)
#ifdef __GLIBC__
#include <sys/platform/ppc.h>
#elif defined(__FreeBSD__)
#include <sys/sysctl.h>
#include <sys/types.h>
#endif
#endif
#include "absl/base/internal/sysinfo.h"
@ -57,11 +62,43 @@ double UnscaledCycleClock::Frequency() {
#elif defined(__powerpc__) || defined(__ppc__)
int64_t UnscaledCycleClock::Now() {
#ifdef __GLIBC__
return __ppc_get_timebase();
#else
#ifdef __powerpc64__
int64_t tbr;
asm volatile("mfspr %0, 268" : "=r"(tbr));
return tbr;
#else
int32_t tbu, tbl, tmp;
asm volatile(
"0:\n"
"mftbu %[hi32]\n"
"mftb %[lo32]\n"
"mftbu %[tmp]\n"
"cmpw %[tmp],%[hi32]\n"
"bne 0b\n"
: [ hi32 ] "=r"(tbu), [ lo32 ] "=r"(tbl), [ tmp ] "=r"(tmp));
return (static_cast<int64_t>(tbu) << 32) | tbl;
#endif
#endif
}
double UnscaledCycleClock::Frequency() {
#ifdef __GLIBC__
return __ppc_get_timebase_freq();
#elif defined(__FreeBSD__)
static once_flag init_timebase_frequency_once;
static double timebase_frequency = 0.0;
base_internal::LowLevelCallOnce(&init_timebase_frequency_once, [&]() {
size_t length = sizeof(timebase_frequency);
sysctlbyname("kern.timecounter.tc.timebase.frequency", &timebase_frequency,
&length, nullptr, 0);
});
return timebase_frequency;
#else
#error Must implement UnscaledCycleClock::Frequency()
#endif
}
#elif defined(__aarch64__)