1b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/*
2b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
3b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *
4b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  Use of this source code is governed by a BSD-style license
5b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  that can be found in the LICENSE file in the root of the source
6b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  tree. An additional intellectual property rights grant can be found
7b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  in the file PATENTS.  All contributing project authors may
8b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  be found in the AUTHORS file in the root of the source tree.
9b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */
10b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
11b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Parts of this file derived from Chromium's base/cpu.cc.
12b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
13c6d6fed3c0a82bb7a09095381b974e8e5eebcb35pbos@webrtc.org#include "webrtc/system_wrappers/interface/cpu_features_wrapper.h"
14b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
154c5465095c9d2322c63685cd2760c57913a58ec1phoglund@webrtc.org#if defined(WEBRTC_ARCH_X86_FAMILY) && defined(_MSC_VER)
16b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include <intrin.h>
17b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#endif
184c5465095c9d2322c63685cd2760c57913a58ec1phoglund@webrtc.org
19c6d6fed3c0a82bb7a09095381b974e8e5eebcb35pbos@webrtc.org#include "webrtc/typedefs.h"
20b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
21b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// No CPU feature is available => straight C path.
22b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint GetCPUInfoNoASM(CPUFeature feature) {
23b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  (void)feature;
24b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return 0;
25b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
26b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
27b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#if defined(WEBRTC_ARCH_X86_FAMILY)
28b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#ifndef _MSC_VER
29b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Intrinsic for "cpuid".
30b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#if defined(__pic__) && defined(__i386__)
31b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgstatic inline void __cpuid(int cpu_info[4], int info_type) {
324c5465095c9d2322c63685cd2760c57913a58ec1phoglund@webrtc.org  __asm__ volatile(
33b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    "mov %%ebx, %%edi\n"
34b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    "cpuid\n"
35b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    "xchg %%edi, %%ebx\n"
36b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    : "=a"(cpu_info[0]), "=D"(cpu_info[1]), "=c"(cpu_info[2]), "=d"(cpu_info[3])
37b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    : "a"(info_type));
38b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
39b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#else
40b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgstatic inline void __cpuid(int cpu_info[4], int info_type) {
414c5465095c9d2322c63685cd2760c57913a58ec1phoglund@webrtc.org  __asm__ volatile(
42b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    "cpuid\n"
43b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    : "=a"(cpu_info[0]), "=b"(cpu_info[1]), "=c"(cpu_info[2]), "=d"(cpu_info[3])
44b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    : "a"(info_type));
45b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
46b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#endif
47b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#endif  // _MSC_VER
48b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#endif  // WEBRTC_ARCH_X86_FAMILY
49b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
50b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#if defined(WEBRTC_ARCH_X86_FAMILY)
51b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Actual feature detection for x86.
52b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgstatic int GetCPUInfo(CPUFeature feature) {
53b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  int cpu_info[4];
54b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  __cpuid(cpu_info, 1);
55b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (feature == kSSE2) {
56b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return 0 != (cpu_info[3] & 0x04000000);
57b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
58b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (feature == kSSE3) {
59b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return 0 != (cpu_info[2] & 0x00000001);
60b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
61b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return 0;
62b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
63b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#else
64b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Default to straight C for other platforms.
65b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgstatic int GetCPUInfo(CPUFeature feature) {
66b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  (void)feature;
67b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return 0;
68b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
69b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#endif
70b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
71b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgWebRtc_CPUInfo WebRtc_GetCPUInfo = GetCPUInfo;
72b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgWebRtc_CPUInfo WebRtc_GetCPUInfoNoASM = GetCPUInfoNoASM;
73