6#if !defined(DART_HOST_OS_MACOS)
11#if defined(HOST_ARCH_IA32) || defined(HOST_ARCH_X64)
13#if defined(DART_HOST_OS_WINDOWS)
22DEFINE_FLAG(
bool, trace_cpuid,
false,
"Trace CPU ID discovery")
24bool CpuId::sse2_ =
false;
25bool CpuId::sse41_ =
false;
26bool CpuId::popcnt_ =
false;
27bool CpuId::abm_ =
false;
29const
char* CpuId::id_string_ =
nullptr;
30const
char* CpuId::brand_string_ =
nullptr;
32#if defined(HOST_ARCH_IA32) || defined(HOST_ARCH_X64)
34static void GetCpuId(int32_t level, uint32_t
info[4]) {
35#if defined(DART_HOST_OS_WINDOWS)
38 __cpuid(
reinterpret_cast<int*
>(
info), level);
45 const int info_length = 4;
46 uint32_t
info[info_length] = {
static_cast<uint32_t
>(-1)};
49 if (FLAG_trace_cpuid) {
50 for (intptr_t i = 0; i < info_length; i++) {
55 char* id_string =
reinterpret_cast<char*
>(
malloc(3 *
sizeof(int32_t)));
58 *
reinterpret_cast<uint32_t*
>(id_string) =
info[1];
59 *
reinterpret_cast<uint32_t*
>(id_string + 4) =
info[3];
60 *
reinterpret_cast<uint32_t*
>(id_string + 8) =
info[2];
61 CpuId::id_string_ = id_string;
62 if (FLAG_trace_cpuid) {
67 if (FLAG_trace_cpuid) {
68 for (intptr_t i = 0; i < info_length; i++) {
72 CpuId::sse41_ = (
info[2] & (1 << 19)) != 0;
73 CpuId::sse2_ = (
info[3] & (1 << 26)) != 0;
74 CpuId::popcnt_ = (
info[2] & (1 << 23)) != 0;
75 if (FLAG_trace_cpuid) {
77 CpuId::sse41_ ?
"yes" :
"no", CpuId::sse2_ ?
"yes" :
"no",
78 CpuId::popcnt_ ?
"yes" :
"no");
81 GetCpuId(0x80000001,
info);
82 if (FLAG_trace_cpuid) {
83 for (intptr_t i = 0; i < info_length; i++) {
87 CpuId::abm_ = (
info[2] & (1 << 5)) != 0;
95 char* brand_string =
reinterpret_cast<char*
>(
calloc(3 *
sizeof(
info) + 1, 1));
96 for (uint32_t i = 0; i < 2; i++) {
97 GetCpuId(0x80000002U + i,
info);
98 if (FLAG_trace_cpuid) {
99 for (intptr_t j = 0; j < info_length; j++) {
100 OS::PrintErr(
"cpuid(0x80000002U + %u) info[%" Pd "]: %0x\n", i, j,
104 memmove(&brand_string[i *
sizeof(
info)], &
info,
sizeof(
info));
106 CpuId::brand_string_ = brand_string;
107 if (FLAG_trace_cpuid) {
113 ASSERT(id_string_ !=
nullptr);
114 free(
const_cast<char*
>(id_string_));
115 id_string_ =
nullptr;
117 ASSERT(brand_string_ !=
nullptr);
118 free(
const_cast<char*
>(brand_string_));
119 brand_string_ =
nullptr;
122const char* CpuId::id_string() {
126const char* CpuId::brand_string() {
135 return brand_string();
137 return brand_string();
141 const char* q =
p + 100;
144 p += snprintf(p, q - p,
"sse2 ");
147 p += snprintf(p, q - p,
"sse4.1 ");
150 p += snprintf(p, q - p,
"popcnt ");
153 p += snprintf(p, q - p,
"abm ");
156 if (p !=
buffer) *(
p - 1) =
'\0';
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
static const char * field(CpuInfoIndices idx)
static void static void PrintErr(const char *format,...) PRINTF_ATTRIBUTE(1
static char * StrDup(const char *s)
static const uint8_t buffer[]
#define DEFINE_FLAG(type, name, default_value, comment)
void * malloc(size_t size)
void * calloc(size_t n, size_t size)