1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Use of this source code is governed by a BSD-style license that can be 3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// found in the LICENSE file. 4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/cpu.h" 6dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 7dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#if defined(ARCH_CPU_X86_FAMILY) 8dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#if defined(_MSC_VER) 9c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <intrin.h> 10dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#endif 11dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#endif 12dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 13dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include <string.h> 14c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 15c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace base { 16c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 17c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottCPU::CPU() 18c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott : type_(0), 19c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott family_(0), 20c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott model_(0), 21c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott stepping_(0), 22c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ext_model_(0), 23c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ext_family_(0), 24dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen has_mmx_(false), 25dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen has_sse_(false), 26dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen has_sse2_(false), 27dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen has_sse3_(false), 28dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen has_ssse3_(false), 29dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen has_sse41_(false), 30dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen has_sse42_(false), 31c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott cpu_vendor_("unknown") { 32c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Initialize(); 33c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 34c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 35dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#if defined(ARCH_CPU_X86_FAMILY) 36dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#ifndef _MSC_VER 37dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 38dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#if defined(__pic__) && defined(__i386__) 39dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 40dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid __cpuid(int cpu_info[4], int info_type) { 41dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen __asm__ volatile ( 42dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen "mov %%ebx, %%edi\n" 43dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen "cpuid\n" 44dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen "xchg %%edi, %%ebx\n" 45dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen : "=a"(cpu_info[0]), "=D"(cpu_info[1]), "=c"(cpu_info[2]), "=d"(cpu_info[3]) 46dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen : "a"(info_type) 47dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen ); 48dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 49dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 50dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid __cpuidex(int cpu_info[4], int info_type, int info_index) { 51dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen __asm__ volatile ( 52dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen "mov %%ebx, %%edi\n" 53dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen "cpuid\n" 54dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen "xchg %%edi, %%ebx\n" 55dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen : "=a"(cpu_info[0]), "=D"(cpu_info[1]), "=c"(cpu_info[2]), "=d"(cpu_info[3]) 56dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen : "a"(info_type), "c"(info_index) 57dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen ); 58dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 59dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 60dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#else 61dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 62dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid __cpuid(int cpu_info[4], int info_type) { 63dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen __asm__ volatile ( 64dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen "cpuid \n\t" 65dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen : "=a"(cpu_info[0]), "=b"(cpu_info[1]), "=c"(cpu_info[2]), "=d"(cpu_info[3]) 66dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen : "a"(info_type) 67dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen ); 68dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 69dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 70dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid __cpuidex(int cpu_info[4], int info_type, int info_index) { 71dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen __asm__ volatile ( 72dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen "cpuid \n\t" 73dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen : "=a"(cpu_info[0]), "=b"(cpu_info[1]), "=c"(cpu_info[2]), "=d"(cpu_info[3]) 74dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen : "a"(info_type), "c"(info_index) 75dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen ); 76dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 77dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 78dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#endif 79dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#endif // _MSC_VER 80dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#endif // ARCH_CPU_X86_FAMILY 81dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 82c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid CPU::Initialize() { 83dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#if defined(ARCH_CPU_X86_FAMILY) 84c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int cpu_info[4] = {-1}; 85c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott char cpu_string[0x20]; 86c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 87c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // __cpuid with an InfoType argument of 0 returns the number of 88c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // valid Ids in CPUInfo[0] and the CPU identification string in 89c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // the other three array elements. The CPU identification string is 90c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // not in linear order. The code below arranges the information 91c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // in a human readable form. 92c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // 93c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // More info can be found here: 94c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // http://msdn.microsoft.com/en-us/library/hskdteyh.aspx 95c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott __cpuid(cpu_info, 0); 96c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int num_ids = cpu_info[0]; 97c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott memset(cpu_string, 0, sizeof(cpu_string)); 98c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott *(reinterpret_cast<int*>(cpu_string)) = cpu_info[1]; 99c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott *(reinterpret_cast<int*>(cpu_string+4)) = cpu_info[3]; 100c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott *(reinterpret_cast<int*>(cpu_string+8)) = cpu_info[2]; 101c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 102c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Interpret CPU feature information. 103c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (num_ids > 0) { 104c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott __cpuid(cpu_info, 1); 105c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott stepping_ = cpu_info[0] & 0xf; 106dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen model_ = ((cpu_info[0] >> 4) & 0xf) + ((cpu_info[0] >> 12) & 0xf0); 107c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott family_ = (cpu_info[0] >> 8) & 0xf; 108c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott type_ = (cpu_info[0] >> 12) & 0x3; 109c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ext_model_ = (cpu_info[0] >> 16) & 0xf; 110c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ext_family_ = (cpu_info[0] >> 20) & 0xff; 111c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott cpu_vendor_ = cpu_string; 112dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen has_mmx_ = (cpu_info[3] & 0x00800000) != 0; 113dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen has_sse_ = (cpu_info[3] & 0x02000000) != 0; 114dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen has_sse2_ = (cpu_info[3] & 0x04000000) != 0; 115dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen has_sse3_ = (cpu_info[2] & 0x00000001) != 0; 116dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen has_ssse3_ = (cpu_info[2] & 0x00000200) != 0; 117dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen has_sse41_ = (cpu_info[2] & 0x00080000) != 0; 118dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen has_sse42_ = (cpu_info[2] & 0x00100000) != 0; 119c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 120dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#endif 121c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 122c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 123c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} // namespace base 124