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