Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cpu_detect_x86_win.cpp « source « SoundTouch « thirdparty « src - github.com/mpc-hc/mpc-hc.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 44e0520d6eb61dc44aa1876ba34dc2f2dc4b69c8 (plain)
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
////////////////////////////////////////////////////////////////////////////////
///
/// 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$
// File revision : $Revision: 4 $
//
// $Id$
//
////////////////////////////////////////////////////////////////////////////////
//
// 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"

#include "STTypes.h"

//////////////////////////////////////////////////////////////////////////////
//
// 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;
}