1 |
//////////////////////////////////////////////////////////////////////////////// |
2 |
/// |
3 |
/// Win32 version of the x86 CPU detect routine. |
4 |
/// |
5 |
/// This file is to be compiled in Windows platform with Microsoft Visual C++ |
6 |
/// Compiler. Please see 'cpu_detect_x86_gcc.cpp' for the gcc compiler version |
7 |
/// for all GNU platforms. |
8 |
/// |
9 |
/// Author : Copyright (c) Olli Parviainen |
10 |
/// Author e-mail : oparviai 'at' iki.fi |
11 |
/// SoundTouch WWW: http://www.surina.net/soundtouch |
12 |
/// |
13 |
//////////////////////////////////////////////////////////////////////////////// |
14 |
// |
15 |
// Last changed : $Date: 2009-02-13 18:22:48 +0200 (Fri, 13 Feb 2009) $ |
16 |
// File revision : $Revision: 4 $ |
17 |
// |
18 |
// $Id: cpu_detect_x86_win.cpp 62 2009-02-13 16:22:48Z oparviai $ |
19 |
// |
20 |
//////////////////////////////////////////////////////////////////////////////// |
21 |
// |
22 |
// License : |
23 |
// |
24 |
// SoundTouch audio processing library |
25 |
// Copyright (c) Olli Parviainen |
26 |
// |
27 |
// This library is free software; you can redistribute it and/or |
28 |
// modify it under the terms of the GNU Lesser General Public |
29 |
// License as published by the Free Software Foundation; either |
30 |
// version 2.1 of the License, or (at your option) any later version. |
31 |
// |
32 |
// This library is distributed in the hope that it will be useful, |
33 |
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
34 |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
35 |
// Lesser General Public License for more details. |
36 |
// |
37 |
// You should have received a copy of the GNU Lesser General Public |
38 |
// License along with this library; if not, write to the Free Software |
39 |
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
40 |
// |
41 |
//////////////////////////////////////////////////////////////////////////////// |
42 |
|
43 |
#include "cpu_detect.h" |
44 |
|
45 |
#ifndef WIN32 |
46 |
#error wrong platform - this source code file is exclusively for Win32 platform |
47 |
#endif |
48 |
|
49 |
////////////////////////////////////////////////////////////////////////////// |
50 |
// |
51 |
// processor instructions extension detection routines |
52 |
// |
53 |
////////////////////////////////////////////////////////////////////////////// |
54 |
|
55 |
// Flag variable indicating whick ISA extensions are disabled (for debugging) |
56 |
static uint _dwDisabledISA = 0x00; // 0xffffffff; //<- use this to disable all extensions |
57 |
|
58 |
|
59 |
// Disables given set of instruction extensions. See SUPPORT_... defines. |
60 |
void disableExtensions(uint dwDisableMask) |
61 |
{ |
62 |
_dwDisabledISA = dwDisableMask; |
63 |
} |
64 |
|
65 |
|
66 |
|
67 |
/// Checks which instruction set extensions are supported by the CPU. |
68 |
uint detectCPUextensions(void) |
69 |
{ |
70 |
uint res = 0; |
71 |
|
72 |
if (_dwDisabledISA == 0xffffffff) return 0; |
73 |
|
74 |
_asm |
75 |
{ |
76 |
; check if 'cpuid' instructions is available by toggling eflags bit 21 |
77 |
; |
78 |
xor esi, esi ; clear esi = result register |
79 |
|
80 |
pushfd ; save eflags to stack |
81 |
mov eax,dword ptr [esp] ; load eax from stack (with eflags) |
82 |
mov ecx, eax ; save the original eflags values to ecx |
83 |
xor eax, 0x00200000 ; toggle bit 21 |
84 |
mov dword ptr [esp],eax ; store toggled eflags to stack |
85 |
popfd ; load eflags from stack |
86 |
|
87 |
pushfd ; save updated eflags to stack |
88 |
mov eax,dword ptr [esp] ; load eax from stack |
89 |
popfd ; pop stack to restore stack pointer |
90 |
|
91 |
xor edx, edx ; clear edx for defaulting no mmx |
92 |
cmp eax, ecx ; compare to original eflags values |
93 |
jz end ; jumps to 'end' if cpuid not present |
94 |
|
95 |
; cpuid instruction available, test for presence of mmx instructions |
96 |
mov eax, 1 |
97 |
cpuid |
98 |
test edx, 0x00800000 |
99 |
jz end ; branch if MMX not available |
100 |
|
101 |
or esi, SUPPORT_MMX ; otherwise add MMX support bit |
102 |
|
103 |
test edx, 0x02000000 |
104 |
jz test3DNow ; branch if SSE not available |
105 |
|
106 |
or esi, SUPPORT_SSE ; otherwise add SSE support bit |
107 |
|
108 |
test3DNow: |
109 |
; test for precense of AMD extensions |
110 |
mov eax, 0x80000000 |
111 |
cpuid |
112 |
cmp eax, 0x80000000 |
113 |
jbe end ; branch if no AMD extensions detected |
114 |
|
115 |
; test for precense of 3DNow! extension |
116 |
mov eax, 0x80000001 |
117 |
cpuid |
118 |
test edx, 0x80000000 |
119 |
jz end ; branch if 3DNow! not detected |
120 |
|
121 |
or esi, SUPPORT_3DNOW ; otherwise add 3DNow support bit |
122 |
|
123 |
end: |
124 |
|
125 |
mov res, esi |
126 |
} |
127 |
|
128 |
return res & ~_dwDisabledISA; |
129 |
} |