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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
|
////////////////////////////////////////////////////////////////////////////////
///
/// Win32 version of the x86 CPU detect routine.
///
/// This file is to be compiled in Windows platform with Microsoft Visual C++
/// Compiler. Please see 'cpu_detect_x86_gcc.cpp' for the gcc compiler version
/// for all GNU platforms.
///
/// Author : Copyright (c) Olli Parviainen
/// Author e-mail : oparviai 'at' iki.fi
/// SoundTouch WWW: http://www.surina.net/soundtouch
///
////////////////////////////////////////////////////////////////////////////////
//
// Last changed : $Date: 2011-07-16 11:46:37 +0300 (Sat, 16 Jul 2011) $
// File revision : $Revision: 4 $
//
// $Id: cpu_detect_x86_win.cpp 120 2011-07-16 08:46:37Z oparviai $
//
////////////////////////////////////////////////////////////////////////////////
//
// License :
//
// SoundTouch audio processing library
// Copyright (c) Olli Parviainen
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
////////////////////////////////////////////////////////////////////////////////
#include "cpu_detect.h"
#ifndef WIN32
#error wrong platform - this source code file is exclusively for Win32 platform
#endif
//////////////////////////////////////////////////////////////////////////////
//
// processor instructions extension detection routines
//
//////////////////////////////////////////////////////////////////////////////
// Flag variable indicating whick ISA extensions are disabled (for debugging)
static uint _dwDisabledISA = 0x00; // 0xffffffff; //<- use this to disable all extensions
// Disables given set of instruction extensions. See SUPPORT_... defines.
void disableExtensions(uint dwDisableMask)
{
_dwDisabledISA = dwDisableMask;
}
/// Checks which instruction set extensions are supported by the CPU.
uint detectCPUextensions(void)
{
uint res = 0;
if (_dwDisabledISA == 0xffffffff) return 0;
#ifndef _M_X64
// 32bit compilation, detect CPU capabilities with inline assembler.
__asm
{
; check if 'cpuid' instructions is available by toggling eflags bit 21
;
xor esi, esi ; clear esi = result register
pushfd ; save eflags to stack
mov eax,dword ptr [esp] ; load eax from stack (with eflags)
mov ecx, eax ; save the original eflags values to ecx
xor eax, 0x00200000 ; toggle bit 21
mov dword ptr [esp],eax ; store toggled eflags to stack
popfd ; load eflags from stack
pushfd ; save updated eflags to stack
mov eax,dword ptr [esp] ; load eax from stack
popfd ; pop stack to restore stack pointer
xor edx, edx ; clear edx for defaulting no mmx
cmp eax, ecx ; compare to original eflags values
jz end ; jumps to 'end' if cpuid not present
; cpuid instruction available, test for presence of mmx instructions
mov eax, 1
cpuid
test edx, 0x00800000
jz end ; branch if MMX not available
or esi, SUPPORT_MMX ; otherwise add MMX support bit
test edx, 0x02000000
jz test3DNow ; branch if SSE not available
or esi, SUPPORT_SSE ; otherwise add SSE support bit
test3DNow:
; test for precense of AMD extensions
mov eax, 0x80000000
cpuid
cmp eax, 0x80000000
jbe end ; branch if no AMD extensions detected
; test for precense of 3DNow! extension
mov eax, 0x80000001
cpuid
test edx, 0x80000000
jz end ; branch if 3DNow! not detected
or esi, SUPPORT_3DNOW ; otherwise add 3DNow support bit
end:
mov res, esi
}
#else
// Visual C++ 64bit compilation doesn't support inline assembler. However,
// all x64 compatible CPUs support MMX & SSE extensions.
res = SUPPORT_MMX | SUPPORT_SSE | SUPPORT_SSE2;
#endif
return res & ~_dwDisabledISA;
}
|