1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
|
// Copyright (c) 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.
// Code in this file is taked from
// third_party/skia/src/opts/opts_check_SSE2.cpp.
// Note that this file cannot be compiled with -msse2 in gcc.
#include "build/build_config.h"
#include "media/base/cpu_features.h"
namespace media {
#ifdef _MSC_VER
static inline void getcpuid(int info_type, int info[4]) {
__asm {
mov eax, [info_type]
cpuid
mov edi, [info]
mov [edi], eax
mov [edi+4], ebx
mov [edi+8], ecx
mov [edi+12], edx
}
}
#else
static inline void getcpuid(int info_type, int info[4]) {
// We save and restore ebx, so this code can be compatible with -fPIC
#if defined(__i386__)
asm volatile (
"pushl %%ebx \n\t"
"cpuid \n\t"
"movl %%ebx, %1 \n\t"
"popl %%ebx \n\t"
: "=a"(info[0]), "=r"(info[1]), "=c"(info[2]), "=d"(info[3])
: "a"(info_type)
);
#else
// We can use cpuid instruction without pushing ebx on gcc x86-64 because it
// does not use ebx (or rbx) as a GOT register.
asm volatile (
"cpuid \n\t"
: "=a"(info[0]), "=r"(info[1]), "=c"(info[2]), "=d"(info[3])
: "a"(info_type)
: "%rbx"
);
#endif
}
#endif
bool hasMMX() {
#if defined(ARCH_CPU_X86_64)
// Every X86_64 processor has MMX.
return true;
#else
int cpu_info[4] = { 0 };
getcpuid(1, cpu_info);
return (cpu_info[3] & (1<<23)) != 0;
#endif
}
bool hasSSE() {
#if defined(ARCH_CPU_X86_64)
// Every X86_64 processor has SSE.
return true;
#else
int cpu_info[4] = { 0 };
getcpuid(1, cpu_info);
return (cpu_info[3] & (1<<25)) != 0;
#endif
}
bool hasSSE2() {
#if defined(ARCH_CPU_X86_64)
// All X86_64 machines have SSE2, so don't even bother checking.
return true;
#else
int cpu_info[4] = { 0 };
getcpuid(1, cpu_info);
return (cpu_info[3] & (1<<26)) != 0;
#endif
}
bool hasSSSE3() {
int cpu_info[4] = { 0 };
getcpuid(1, cpu_info);
return (cpu_info[3] & 0x04000000) != 0 && (cpu_info[2] & 0x00000001) != 0 &&
(cpu_info[2] & 0x00000200) != 0;
}
} // namespace media
|