cpu_detect_x86.cpp (4795B)
1 //////////////////////////////////////////////////////////////////////////////// 2 /// 3 /// Generic version of the x86 CPU extension detection routine. 4 /// 5 /// This file is for GNU & other non-Windows compilers, see 'cpu_detect_x86_win.cpp' 6 /// for the Microsoft compiler version. 7 /// 8 /// Author : Copyright (c) Olli Parviainen 9 /// Author e-mail : oparviai 'at' iki.fi 10 /// SoundTouch WWW: http://www.surina.net/soundtouch 11 /// 12 //////////////////////////////////////////////////////////////////////////////// 13 // 14 // License : 15 // 16 // SoundTouch audio processing library 17 // Copyright (c) Olli Parviainen 18 // 19 // This library is free software; you can redistribute it and/or 20 // modify it under the terms of the GNU Lesser General Public 21 // License as published by the Free Software Foundation; either 22 // version 2.1 of the License, or (at your option) any later version. 23 // 24 // This library is distributed in the hope that it will be useful, 25 // but WITHOUT ANY WARRANTY; without even the implied warranty of 26 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 27 // Lesser General Public License for more details. 28 // 29 // You should have received a copy of the GNU Lesser General Public 30 // License along with this library; if not, write to the Free Software 31 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 32 // 33 //////////////////////////////////////////////////////////////////////////////// 34 35 #include "cpu_detect.h" 36 #include "STTypes.h" 37 38 39 #if defined(SOUNDTOUCH_ALLOW_X86_OPTIMIZATIONS) 40 #if defined(__GNUC__) && defined(HAVE_CPUID_H) 41 // gcc and clang 42 #include "cpuid.h" 43 #elif defined(_M_IX86) 44 // windows non-gcc 45 #include <intrin.h> 46 #endif 47 48 #define bit_MMX (1 << 23) 49 #define bit_SSE (1 << 25) 50 #define bit_SSE2 (1 << 26) 51 #endif 52 53 54 ////////////////////////////////////////////////////////////////////////////// 55 // 56 // processor instructions extension detection routines 57 // 58 ////////////////////////////////////////////////////////////////////////////// 59 60 // Flag variable indicating whick ISA extensions are disabled (for debugging) 61 static uint _dwDisabledISA = 0x00; // 0xffffffff; //<- use this to disable all extensions 62 63 // Disables given set of instruction extensions. See SUPPORT_... defines. 64 void disableExtensions(uint dwDisableMask) 65 { 66 _dwDisabledISA = dwDisableMask; 67 } 68 69 70 /// Checks which instruction set extensions are supported by the CPU. 71 uint detectCPUextensions(void) 72 { 73 /// If building for RLBox, we enable the SSE code that will be 74 /// translated to WASMSIMD with SIMD-everywhere. 75 #if defined(SOUNDTOUCH_WASM_SIMD) 76 uint res = 0; 77 res = res | SUPPORT_SSE; 78 res = res | SUPPORT_SSE2; 79 return res & ~_dwDisabledISA; 80 81 /// If building for a 64bit system (no Itanium) and the user wants optimizations. 82 /// Return the OR of SUPPORT_{MMX,SSE,SSE2}. 11001 or 0x19. 83 /// Keep the _dwDisabledISA test (2 more operations, could be eliminated). 84 #elif ((defined(__GNUC__) && defined(__x86_64__)) \ 85 || defined(_M_X64)) \ 86 && defined(SOUNDTOUCH_ALLOW_X86_OPTIMIZATIONS) 87 return 0x19 & ~_dwDisabledISA; 88 89 /// If building for a 32bit system and the user wants optimizations. 90 /// Keep the _dwDisabledISA test (2 more operations, could be eliminated). 91 #elif ((defined(__GNUC__) && defined(__i386__)) \ 92 || defined(_M_IX86)) \ 93 && defined(SOUNDTOUCH_ALLOW_X86_OPTIMIZATIONS) 94 95 if (_dwDisabledISA == 0xffffffff) return 0; 96 97 uint res = 0; 98 99 #if !defined(__GNUC__) 100 // Window / VS version of cpuid. Notice that Visual Studio 2005 or later required 101 // for __cpuid intrinsic support. 102 int reg[4] = {-1}; 103 104 // Check if no cpuid support. 105 __cpuid(reg,0); 106 if ((unsigned int)reg[0] == 0) return 0; // always disable extensions. 107 108 __cpuid(reg,1); 109 if ((unsigned int)reg[3] & bit_MMX) res = res | SUPPORT_MMX; 110 if ((unsigned int)reg[3] & bit_SSE) res = res | SUPPORT_SSE; 111 if ((unsigned int)reg[3] & bit_SSE2) res = res | SUPPORT_SSE2; 112 #elif defined(HAVE_CPUID_H) 113 // GCC version of cpuid. Requires GCC 4.3.0 or later for __cpuid intrinsic support. 114 uint eax, ebx, ecx, edx; // unsigned int is the standard type. uint is defined by the compiler and not guaranteed to be portable. 115 116 // Check if no cpuid support. 117 if (!__get_cpuid (1, &eax, &ebx, &ecx, &edx)) return 0; // always disable extensions. 118 119 if (edx & bit_MMX) res = res | SUPPORT_MMX; 120 if (edx & bit_SSE) res = res | SUPPORT_SSE; 121 if (edx & bit_SSE2) res = res | SUPPORT_SSE2; 122 #else 123 // Compatible with GCC but no cpuid.h. 124 return 0; 125 #endif 126 127 return res & ~_dwDisabledISA; 128 129 #else 130 131 /// One of these is true: 132 /// 1) We don't want optimizations. 133 /// 2) Using an unsupported compiler. 134 /// 3) Running on a non-x86 platform. 135 return 0; 136 137 #endif 138 }