From 1f6a68a6a3970201e7685477cbb7b80a12893a3f Mon Sep 17 00:00:00 2001 From: oparviai Date: Sun, 1 Apr 2012 17:01:42 +0000 Subject: [PATCH] CPUID routine bugfix: replaced inline assembly routine not working with all environment with __cpuid compiler intrinsic. --- configure.ac | 45 ++++---- include/STTypes.h | 2 +- source/SoundTouch/Makefile.am | 26 ++--- source/SoundTouch/SoundTouch.vcproj | 20 +--- source/SoundTouch/cpu_detect_x86.cpp | 136 ++++++++++++++++++++++ source/SoundTouch/cpu_detect_x86_gcc.cpp | 134 ---------------------- source/SoundTouch/cpu_detect_x86_win.cpp | 137 ----------------------- 7 files changed, 174 insertions(+), 326 deletions(-) create mode 100644 source/SoundTouch/cpu_detect_x86.cpp delete mode 100644 source/SoundTouch/cpu_detect_x86_gcc.cpp delete mode 100644 source/SoundTouch/cpu_detect_x86_win.cpp diff --git a/configure.ac b/configure.ac index 5f16422..eaf2827 100644 --- a/configure.ac +++ b/configure.ac @@ -23,7 +23,8 @@ AC_INIT(SoundTouch, 1.6.1, [http://www.surina.net/soundtouch]) AC_CONFIG_AUX_DIR(config) AM_CONFIG_HEADER([include/soundtouch_config.h]) AM_INIT_AUTOMAKE -AC_DISABLE_SHARED dnl This makes libtool only build static libs +#AC_DISABLE_SHARED dnl This makes libtool only build static libs +AC_DISABLE_STATIC dnl This makes libtool only build shared libs #AC_GNU_SOURCE dnl enable posix extensions in glibc AC_LANG(C++) @@ -55,7 +56,7 @@ dnl ############################################################################ AC_HEADER_STDC #AC_HEADER_SYS_WAIT # add any others you want to check for here -#AC_CHECK_HEADERS([fcntl.h limits.h stddef.h stdlib.h string.h sys/ioctl.h sys/vfs.h unistd.h]) +AC_CHECK_HEADERS([cpuid.h],,[AC_MSG_ERROR([cpuid.h not found, install gcc >= 4.3])]) @@ -82,7 +83,7 @@ AC_ARG_ENABLE(integer-samples, # Useful when compiling on non-x86 architectures. AC_ARG_ENABLE([x86-optimizations], [AS_HELP_STRING([--enable-x86-optimizations], - [use MMX or SSE2 optimizations + [use MMX or SSE optimization [default=yes]])],[enable_x86_optimizations="${enableval}"], [enable_x86_optimizations=yes]) @@ -113,7 +114,7 @@ if test "x$enable_x86_optimizations" = "xyes"; then # Check if the user can compile MMX code using intrinsics. # GCC supports MMX intrinsics since version 3.3 # A more recent GCC (>= 4.3) is recommended. - AC_COMPILE_IFELSE([ + AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ #if defined(__GNUC__) && (__GNUC__ < 3 || (__GNUC__ == 3 && __GNUC_MINOR__ < 3)) #error "Need GCC >= 3.3 for MMX intrinsics" #endif @@ -121,7 +122,7 @@ if test "x$enable_x86_optimizations" = "xyes"; then int main () { __m64 loop = _mm_cvtsi32_si64 (1); return _mm_cvtsi64_si32 (loop); - }],[have_mmx_intrinsics=yes]) + }]])],[have_mmx_intrinsics=yes]) CXXFLAGS=$original_saved_CXXFLAGS # Inform the user if we did or did not find MMX support. @@ -139,34 +140,34 @@ if test "x$enable_x86_optimizations" = "xyes"; then fi - have_sse2_intrinsics=no - OPT_CXXFLAGS="-msse2 -Winline" + have_sse_intrinsics=no + OPT_CXXFLAGS="-msse -Winline" CXXFLAGS="$OPT_CXXFLAGS $CXXFLAGS" - # Check if the user can compile SSE2 code using intrinsics. - # GCC supports SSE2 intrinsics since version 3.3 + # Check if the user can compile SSE code using intrinsics. + # GCC supports SSE intrinsics since version 3.3 # A more recent GCC (>= 4.3) is recommended. - AC_COMPILE_IFELSE([ + AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ #if defined(__GNUC__) && (__GNUC__ < 3 || (__GNUC__ == 3 && __GNUC_MINOR__ < 3)) - #error "Need GCC >= 3.3 for SSE2 intrinsics" + #error "Need GCC >= 3.3 for SSE intrinsics" #endif - #include + #include int main () { - __m128i loop = _mm_cvtsi32_si128 (1); - return _mm_cvtsi128_si32 (loop); - }],[have_sse2_intrinsics=yes]) + _mm_setzero_ps(); + return 0; + }]])],[have_sse_intrinsics=yes]) CXXFLAGS=$original_saved_CXXFLAGS - # Inform the user if we did or did not find SSE2 support. + # Inform the user if we did or did not find SSE support. # - # If we enable optimization and float samples we only require SSE2. + # If we enable optimization and float samples we only require SSE. # Disable optimizations in the SSTypes.h file if this is not the case. - if test "x$have_sse2_intrinsics" = "xyes" ; then - echo "****** SSE2 support found ******" + if test "x$have_sse_intrinsics" = "xyes" ; then + echo "****** SSE support found ******" else - echo "****** No SSE2 support found ******" + echo "****** No SSE support found ******" if test "x$enable_integer_samples" != "xyes"; then - echo "****** Disabling optimizations. Using float samples with no SSE2 support ******" + echo "****** Disabling optimizations. Using float samples with no SSE support ******" AC_DEFINE([SOUNDTOUCH_DISABLE_X86_OPTIMIZATIONS],[1],[Do not use x86 optimizations]) fi fi @@ -186,7 +187,7 @@ fi # optimizations by default (if support is available) and then disable all of # them if the user requested it. AM_CONDITIONAL([HAVE_MMX], [test "x$have_mmx_intrinsics" = "xyes"]) -AM_CONDITIONAL([HAVE_SSE2], [test "x$have_sse2_intrinsics" = "xyes"]) +AM_CONDITIONAL([HAVE_SSE], [test "x$have_sse_intrinsics" = "xyes"]) dnl ############################################################################ diff --git a/include/STTypes.h b/include/STTypes.h index e648bc8..9ae26ff 100644 --- a/include/STTypes.h +++ b/include/STTypes.h @@ -86,7 +86,7 @@ namespace soundtouch #endif - #if (_WIN32 || __i386__ || __x86_64__ || _M_X64) + #if (_M_IX86 || __i386__ || __x86_64__ || _M_X64) /// Define this to allow X86-specific assembler/intrinsic optimizations. /// Notice that library contains also usual C++ versions of each of these /// these routines, so if you're having difficulties getting the optimized diff --git a/source/SoundTouch/Makefile.am b/source/SoundTouch/Makefile.am index 3e4b3d9..a8bba5d 100644 --- a/source/SoundTouch/Makefile.am +++ b/source/SoundTouch/Makefile.am @@ -22,27 +22,27 @@ include $(top_srcdir)/config/am_include.mk # set to something if you want other stuff to be included in the distribution tarball -EXTRA_DIST=3dnow_win.cpp cpu_detect_x86_win.cpp SoundTouch.dsp SoundTouch.dsw SoundTouch.sln SoundTouch.vcproj +EXTRA_DIST=3dnow_win.cpp cpu_detect_x86.cpp SoundTouch.dsp SoundTouch.dsw SoundTouch.sln SoundTouch.vcproj -noinst_HEADERS=AAFilter.h cpu_detect.h cpu_detect_x86_gcc.cpp FIRFilter.h RateTransposer.h TDStretch.h PeakFinder.h +noinst_HEADERS=AAFilter.h cpu_detect.h cpu_detect_x86.cpp FIRFilter.h RateTransposer.h TDStretch.h PeakFinder.h lib_LTLIBRARIES=libSoundTouch.la # -libSoundTouch_la_SOURCES=AAFilter.cpp FIRFilter.cpp FIFOSampleBuffer.cpp RateTransposer.cpp SoundTouch.cpp TDStretch.cpp cpu_detect_x86_gcc.cpp BPMDetect.cpp PeakFinder.cpp +libSoundTouch_la_SOURCES=AAFilter.cpp FIRFilter.cpp FIFOSampleBuffer.cpp RateTransposer.cpp SoundTouch.cpp TDStretch.cpp cpu_detect_x86.cpp BPMDetect.cpp PeakFinder.cpp # Compiler flags AM_CXXFLAGS=-O3 -fcheck-new -I../../include # Compile the files that need MMX and SSE individually. -libSoundTouch_la_LIBADD=libSoundTouchMMX.la libSoundTouchSSE2.la -noinst_LTLIBRARIES=libSoundTouchMMX.la libSoundTouchSSE2.la +libSoundTouch_la_LIBADD=libSoundTouchMMX.la libSoundTouchSSE.la +noinst_LTLIBRARIES=libSoundTouchMMX.la libSoundTouchSSE.la libSoundTouchMMX_la_SOURCES=mmx_optimized.cpp -libSoundTouchSSE2_la_SOURCES=sse_optimized.cpp +libSoundTouchSSE_la_SOURCES=sse_optimized.cpp # We enable optimizations by default. # If MMX is supported compile with -mmmx. -# Do not assume -msse2 is also supported. +# Do not assume -msse is also supported. if HAVE_MMX libSoundTouchMMX_la_CXXFLAGS = -mmmx $(AM_CXXFLAGS) else @@ -50,17 +50,17 @@ libSoundTouchMMX_la_CXXFLAGS = $(AM_CXXFLAGS) endif # We enable optimizations by default. -# If SSE2 is supported compile with -msse2. -if HAVE_SSE2 -libSoundTouchSSE2_la_CXXFLAGS = -msse2 $(AM_CXXFLAGS) +# If SSE is supported compile with -msse. +if HAVE_SSE +libSoundTouchSSE_la_CXXFLAGS = -msse $(AM_CXXFLAGS) else -libSoundTouchSSE2_la_CXXFLAGS = $(AM_CXXFLAGS) +libSoundTouchSSE_la_CXXFLAGS = $(AM_CXXFLAGS) endif # Let the user disable optimizations if he wishes to. if !X86_OPTIMIZATIONS libSoundTouchMMX_la_CXXFLAGS = $(AM_CXXFLAGS) -libSoundTouchSSE2_la_CXXFLAGS = $(AM_CXXFLAGS) +libSoundTouchSSE_la_CXXFLAGS = $(AM_CXXFLAGS) endif @@ -68,4 +68,4 @@ endif # noinst_LTLIBRARIES = libSoundTouchOpt.la # libSoundTouch_la_LIBADD = libSoundTouchOpt.la # libSoundTouchOpt_la_SOURCES = mmx_optimized.cpp sse_optimized.cpp -# libSoundTouchOpt_la_CXXFLAGS = -O3 -msse2 -fcheck-new -I../../include +# libSoundTouchOpt_la_CXXFLAGS = -O3 -msse -fcheck-new -I../../include diff --git a/source/SoundTouch/SoundTouch.vcproj b/source/SoundTouch/SoundTouch.vcproj index 51a9b57..e872e14 100644 --- a/source/SoundTouch/SoundTouch.vcproj +++ b/source/SoundTouch/SoundTouch.vcproj @@ -148,25 +148,7 @@ - - - - - - + RelativePath=".\cpu_detect_x86.cpp"> diff --git a/source/SoundTouch/cpu_detect_x86.cpp b/source/SoundTouch/cpu_detect_x86.cpp new file mode 100644 index 0000000..8ec618a --- /dev/null +++ b/source/SoundTouch/cpu_detect_x86.cpp @@ -0,0 +1,136 @@ +//////////////////////////////////////////////////////////////////////////////// +/// +/// Generic version of the x86 CPU extension detection routine. +/// +/// This file is for GNU & other non-Windows compilers, see 'cpu_detect_x86_win.cpp' +/// for the Microsoft compiler version. +/// +/// 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" + +#if defined(SOUNDTOUCH_ALLOW_X86_OPTIMIZATIONS) + + #if defined(__GNUC__) && defined(__i386__) + // gcc + #include "cpuid.h" + #endif + + #if defined(_M_IX86) + // windows + #include + #define bit_MMX (1 << 23) + #define bit_SSE (1 << 25) + #define bit_SSE2 (1 << 26) + #endif + +#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) +{ +/// If building for a 64bit system (no Itanium) and the user wants optimizations. +/// Return the OR of SUPPORT_{MMX,SSE,SSE2}. 11001 or 0x19. +/// Keep the _dwDisabledISA test (2 more operations, could be eliminated). +#if defined(__GNUC__) && defined(__x86_64__) \ + && defined(SOUNDTOUCH_ALLOW_X86_OPTIMIZATIONS) + return 0x19 & ~_dwDisabledISA; + +/// If building for a 32bit system and the user wants optimizations. +/// Keep the _dwDisabledISA test (2 more operations, could be eliminated). +#elif ((defined(__GNUC__) && defined(__i386__)) \ + || defined(_M_IX86)) \ + && defined(SOUNDTOUCH_ALLOW_X86_OPTIMIZATIONS) + + if (_dwDisabledISA == 0xffffffff) return 0; + + uint res = 0; + +#if defined(__GNUC__) + // GCC version of cpuid. Requires GCC 4.3.0 or later for __cpuid intrinsic support. + uint eax, ebx, ecx, edx; // unsigned int is the standard type. uint is defined by the compiler and not guaranteed to be portable. + + if (!__get_cpuid (1, &eax, &ebx, &ecx, &edx)) return 0; // always disable extensions. + if (edx & bit_MMX) res = res | SUPPORT_MMX; + if (edx & bit_SSE) res = res | SUPPORT_SSE; + if (edx & bit_SSE2) res = res | SUPPORT_SSE2; + +#else + // Window / VS version of cpuid. Notice that Visual Studio 2005 or later required + // for __cpuid intrinsic support. + int reg[4] = {-1}; + + // Check if no cpuid support. + __cpuid(reg,0); + if ((unsigned int)reg[0] == 0) return 0; // always disable extensions. + + __cpuid(reg,1); + if ((unsigned int)reg[3] & bit_MMX) res = res | SUPPORT_MMX; + if ((unsigned int)reg[3] & bit_SSE) res = res | SUPPORT_SSE; + if ((unsigned int)reg[3] & bit_SSE2) res = res | SUPPORT_SSE2; + +#endif + + return res & ~_dwDisabledISA; + +#else + +/// One of these is true: +/// 1) We don't want optimizations. +/// 2) Using an unsupported compiler. +/// 3) Running on a non-x86 platform. + return 0; + +#endif +} diff --git a/source/SoundTouch/cpu_detect_x86_gcc.cpp b/source/SoundTouch/cpu_detect_x86_gcc.cpp deleted file mode 100644 index 55c4651..0000000 --- a/source/SoundTouch/cpu_detect_x86_gcc.cpp +++ /dev/null @@ -1,134 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -/// -/// Generic version of the x86 CPU extension detection routine. -/// -/// This file is for GNU & other non-Windows compilers, see 'cpu_detect_x86_win.cpp' -/// for the Microsoft compiler version. -/// -/// 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) -{ -#if (!(SOUNDTOUCH_ALLOW_X86_OPTIMIZATIONS) || !(__GNUC__)) - - return 0; // always disable extensions on non-x86 platforms. - -#else - uint res = 0; - - if (_dwDisabledISA == 0xffffffff) return 0; - - asm volatile( -#ifndef __x86_64__ - // Check if 'cpuid' instructions is available by toggling eflags bit 21. - // Skip this for x86-64 as they always have cpuid while stack manipulation - // differs from 16/32bit ISA. - "\n\txor %%esi, %%esi" // clear %%esi = result register - - "\n\tpushf" // save eflags to stack - "\n\tmovl (%%esp), %%eax" // load eax from stack (with eflags) - "\n\tmovl %%eax, %%ecx" // save the original eflags values to ecx - "\n\txor $0x00200000, %%eax" // toggle bit 21 - "\n\tmovl %%eax, (%%esp)" // store toggled eflags to stack - "\n\tpopf" // load eflags from stack - "\n\tpushf" // save updated eflags to stack - "\n\tmovl (%%esp), %%eax" // load eax from stack - "\n\tpopf" // pop stack to restore esp - "\n\txor %%edx, %%edx" // clear edx for defaulting no mmx - "\n\tcmp %%ecx, %%eax" // compare to original eflags values - "\n\tjz end" // jumps to 'end' if cpuid not present -#endif // __x86_64__ - - // cpuid instruction available, test for presence of mmx instructions - - "\n\tmovl $1, %%eax" - "\n\tcpuid" - "\n\ttest $0x00800000, %%edx" - "\n\tjz end" // branch if MMX not available - - "\n\tor $0x01, %%esi" // otherwise add MMX support bit - - "\n\ttest $0x02000000, %%edx" - "\n\tjz test3DNow" // branch if SSE not available - - "\n\tor $0x08, %%esi" // otherwise add SSE support bit - - "\n\ttest3DNow:" - // test for precense of AMD extensions - "\n\tmov $0x80000000, %%eax" - "\n\tcpuid" - "\n\tcmp $0x80000000, %%eax" - "\n\tjbe end" // branch if no AMD extensions detected - - // test for precense of 3DNow! extension - "\n\tmov $0x80000001, %%eax" - "\n\tcpuid" - "\n\ttest $0x80000000, %%edx" - "\n\tjz end" // branch if 3DNow! not detected - - "\n\tor $0x02, %%esi" // otherwise add 3DNow support bit - - "\n\tend:" - - "\n\tmov %%esi, %0" - - : "=r" (res) - : /* no inputs */ - : "%edx", "%eax", "%ecx", "%esi" ); - - return res & ~_dwDisabledISA; -#endif -} diff --git a/source/SoundTouch/cpu_detect_x86_win.cpp b/source/SoundTouch/cpu_detect_x86_win.cpp deleted file mode 100644 index 44e0520..0000000 --- a/source/SoundTouch/cpu_detect_x86_win.cpp +++ /dev/null @@ -1,137 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -/// -/// 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; -}