Index: base/cpu.cc |
diff --git a/base/cpu.cc b/base/cpu.cc |
index 0fef897ae6e1fdddff60fafdf7fad85fb85fb344..3232f1543507e8b97babef2d0a977abea5b13d0a 100644 |
--- a/base/cpu.cc |
+++ b/base/cpu.cc |
@@ -1,10 +1,16 @@ |
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. |
+// Copyright (c) 2006-2011 The Chromium Authors. All rights reserved. |
// Use of this source code is governed by a BSD-style license that can be |
// found in the LICENSE file. |
#include "base/cpu.h" |
+ |
+#if defined(ARCH_CPU_X86_FAMILY) |
+#if defined(_MSC_VER) |
#include <intrin.h> |
-#include <string> |
+#endif |
+#endif |
+ |
+#include <string.h> |
namespace base { |
@@ -15,11 +21,66 @@ CPU::CPU() |
stepping_(0), |
ext_model_(0), |
ext_family_(0), |
+ has_mmx_(false), |
+ has_sse_(false), |
+ has_sse2_(false), |
+ has_sse3_(false), |
+ has_ssse3_(false), |
+ has_sse41_(false), |
+ has_sse42_(false), |
cpu_vendor_("unknown") { |
Initialize(); |
} |
+#if defined(ARCH_CPU_X86_FAMILY) |
+#ifndef _MSC_VER |
+ |
+#if defined(__pic__) && defined(__i386__) |
+ |
+void __cpuid(int cpu_info[4], int info_type) { |
+ __asm__ volatile ( |
+ "mov %%ebx, %%edi\n" |
+ "cpuid\n" |
+ "xchg %%edi, %%ebx\n" |
+ : "=a"(cpu_info[0]), "=D"(cpu_info[1]), "=c"(cpu_info[2]), "=d"(cpu_info[3]) |
+ : "a"(info_type) |
+ ); |
+} |
+ |
+void __cpuidex(int cpu_info[4], int info_type, int info_index) { |
+ __asm__ volatile ( |
+ "mov %%ebx, %%edi\n" |
+ "cpuid\n" |
+ "xchg %%edi, %%ebx\n" |
+ : "=a"(cpu_info[0]), "=D"(cpu_info[1]), "=c"(cpu_info[2]), "=d"(cpu_info[3]) |
+ : "a"(info_type), "c"(info_index) |
+ ); |
+} |
+ |
+#else |
+ |
+void __cpuid(int cpu_info[4], int info_type) { |
+ __asm__ volatile ( |
+ "cpuid \n\t" |
+ : "=a"(cpu_info[0]), "=b"(cpu_info[1]), "=c"(cpu_info[2]), "=d"(cpu_info[3]) |
+ : "a"(info_type) |
+ ); |
+} |
+ |
+void __cpuidex(int cpu_info[4], int info_type, int info_index) { |
+ __asm__ volatile ( |
+ "cpuid \n\t" |
+ : "=a"(cpu_info[0]), "=b"(cpu_info[1]), "=c"(cpu_info[2]), "=d"(cpu_info[3]) |
+ : "a"(info_type), "c"(info_index) |
+ ); |
+} |
+ |
+#endif |
+#endif // _MSC_VER |
+#endif // ARCH_CPU_X86_FAMILY |
+ |
void CPU::Initialize() { |
+#if defined(ARCH_CPU_X86_FAMILY) |
int cpu_info[4] = {-1}; |
char cpu_string[0x20]; |
@@ -42,13 +103,23 @@ void CPU::Initialize() { |
if (num_ids > 0) { |
__cpuid(cpu_info, 1); |
stepping_ = cpu_info[0] & 0xf; |
- model_ = (cpu_info[0] >> 4) & 0xf; |
+ model_ = ((cpu_info[0] >> 4) & 0xf) + ((cpu_info[0] >> 12) & 0xf0); |
family_ = (cpu_info[0] >> 8) & 0xf; |
type_ = (cpu_info[0] >> 12) & 0x3; |
ext_model_ = (cpu_info[0] >> 16) & 0xf; |
ext_family_ = (cpu_info[0] >> 20) & 0xff; |
cpu_vendor_ = cpu_string; |
+ has_mmx_ = (cpu_info[3] & 0x00800000) != 0; |
+ has_sse_ = (cpu_info[3] & 0x02000000) != 0; |
+ has_sse2_ = (cpu_info[3] & 0x04000000) != 0; |
+ has_sse3_ = (cpu_info[2] & 0x00000001) != 0; |
+ has_ssse3_ = (cpu_info[2] & 0x00000200) != 0; |
+ has_sse41_ = (cpu_info[2] & 0x00080000) != 0; |
+ has_sse42_ = (cpu_info[2] & 0x00100000) != 0; |
} |
+#endif |
} |
+ |
+ |
} // namespace base |