Updated to soundtouch-1.3 (plus modifications)
[ardour.git] / libs / soundtouch / cpu_detect_x86_win.cpp
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 @ iki.fi
11 /// SoundTouch WWW: http://www.iki.fi/oparviai/soundtouch
12 ///
13 ////////////////////////////////////////////////////////////////////////////////
14 //
15 // Last changed  : $Date$
16 // File revision : $Revision$
17 //
18 // $Id$
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         pop     eax                 ; 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         push    eax                 ; store toggled eflags to stack
85         popfd                       ; load eflags from stack
86         pushfd                      ; save updated eflags to stack
87         pop     eax                 ; load from stack
88         xor     edx, edx            ; clear edx for defaulting no mmx
89         cmp     eax, ecx            ; compare to original eflags values
90         jz      end                 ; jumps to 'end' if cpuid not present
91
92         ; cpuid instruction available, test for presence of mmx instructions 
93         mov     eax, 1
94         cpuid
95         test    edx, 0x00800000
96         jz      end                 ; branch if MMX not available
97
98         or      esi, SUPPORT_MMX    ; otherwise add MMX support bit
99
100         test    edx, 0x02000000
101         jz      test3DNow           ; branch if SSE not available
102
103         or      esi, SUPPORT_SSE    ; otherwise add SSE support bit
104
105     test3DNow:
106         ; test for precense of AMD extensions
107         mov     eax, 0x80000000
108         cpuid
109         cmp     eax, 0x80000000
110         jbe     end                ; branch if no AMD extensions detected
111
112         ; test for precense of 3DNow! extension
113         mov     eax, 0x80000001
114         cpuid
115         test    edx, 0x80000000
116         jz      end                 ; branch if 3DNow! not detected
117
118         or      esi, SUPPORT_3DNOW  ; otherwise add 3DNow support bit
119
120     end:
121
122         mov     res, esi
123     }
124
125     return res & ~_dwDisabledISA;
126 }