/external/pysoundtouch14/libsoundtouch/cpu_detect_x86_gcc.cpp

http://echo-nest-remix.googlecode.com/ · C++ · 141 lines · 60 code · 27 blank · 54 comment · 3 complexity · 9476fecb33d4d9eaef01241a9b817f51 MD5 · raw file

  1. ////////////////////////////////////////////////////////////////////////////////
  2. ///
  3. /// gcc version of the x86 CPU detect routine.
  4. ///
  5. /// This file is to be compiled on any platform with the GNU C compiler.
  6. /// Compiler. Please see 'cpu_detect_x86_win.cpp' for the x86 Windows version
  7. /// of this file.
  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-01-11 13:36:36 +0200 (Sun, 11 Jan 2009) $
  16. // File revision : $Revision: 4 $
  17. //
  18. // $Id: cpu_detect_x86_gcc.cpp 47 2009-01-11 11:36:36Z 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. #include <stdexcept>
  43. #include <string>
  44. #include "cpu_detect.h"
  45. #include "STTypes.h"
  46. #ifndef __GNUC__
  47. #error wrong platform - this source code file is for the GNU C compiler.
  48. #endif
  49. using namespace std;
  50. #include <stdio.h>
  51. //////////////////////////////////////////////////////////////////////////////
  52. //
  53. // processor instructions extension detection routines
  54. //
  55. //////////////////////////////////////////////////////////////////////////////
  56. // Flag variable indicating whick ISA extensions are disabled (for debugging)
  57. static uint _dwDisabledISA = 0x00; // 0xffffffff; //<- use this to disable all extensions
  58. // Disables given set of instruction extensions. See SUPPORT_... defines.
  59. void disableExtensions(uint dwDisableMask)
  60. {
  61. _dwDisabledISA = dwDisableMask;
  62. }
  63. /// Checks which instruction set extensions are supported by the CPU.
  64. uint detectCPUextensions(void)
  65. {
  66. #ifndef ALLOW_X86_OPTIMIZATIONS
  67. return 0; // always disable extensions on non-x86 platforms.
  68. #else
  69. uint res = 0;
  70. if (_dwDisabledISA == 0xffffffff) return 0;
  71. asm volatile(
  72. "\n\txor %%esi, %%esi" // clear %%esi = result register
  73. // check if 'cpuid' instructions is available by toggling eflags bit 21
  74. "\n\tpushf" // save eflags to stack
  75. "\n\tpop %%eax" // load eax from stack (with eflags)
  76. "\n\tmovl %%eax, %%ecx" // save the original eflags values to ecx
  77. "\n\txor $0x00200000, %%eax" // toggle bit 21
  78. "\n\tpush %%eax" // store toggled eflags to stack
  79. "\n\tpopf" // load eflags from stack
  80. "\n\tpushf" // save updated eflags to stack
  81. "\n\tpop %%eax" // load from stack
  82. "\n\txor %%edx, %%edx" // clear edx for defaulting no mmx
  83. "\n\tcmp %%ecx, %%eax" // compare to original eflags values
  84. "\n\tjz end" // jumps to 'end' if cpuid not present
  85. // cpuid instruction available, test for presence of mmx instructions
  86. "\n\tmovl $1, %%eax"
  87. "\n\tcpuid"
  88. // movl $0x00800000, %edx // force enable MMX
  89. "\n\ttest $0x00800000, %%edx"
  90. "\n\tjz end" // branch if MMX not available
  91. "\n\tor $0x01, %%esi" // otherwise add MMX support bit
  92. "\n\ttest $0x02000000, %%edx"
  93. "\n\tjz test3DNow" // branch if SSE not available
  94. "\n\tor $0x08, %%esi" // otherwise add SSE support bit
  95. "\n\ttest3DNow:"
  96. // test for precense of AMD extensions
  97. "\n\tmov $0x80000000, %%eax"
  98. "\n\tcpuid"
  99. "\n\tcmp $0x80000000, %%eax"
  100. "\n\tjbe end" // branch if no AMD extensions detected
  101. // test for precense of 3DNow! extension
  102. "\n\tmov $0x80000001, %%eax"
  103. "\n\tcpuid"
  104. "\n\ttest $0x80000000, %%edx"
  105. "\n\tjz end" // branch if 3DNow! not detected
  106. "\n\tor $0x02, %%esi" // otherwise add 3DNow support bit
  107. "\n\tend:"
  108. "\n\tmov %%esi, %0"
  109. : "=r" (res)
  110. : /* no inputs */
  111. : "%edx", "%eax", "%ecx", "%esi" );
  112. return res & ~_dwDisabledISA;
  113. #endif
  114. }