PageRenderTime 294ms CodeModel.GetById 160ms app.highlight 5ms RepoModel.GetById 126ms app.codeStats 0ms

/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
 43#include <stdexcept>

 44#include <string>

 45#include "cpu_detect.h"

 46#include "STTypes.h"

 47
 48#ifndef __GNUC__

 49#error wrong platform - this source code file is for the GNU C compiler.

 50#endif

 51
 52using namespace std;
 53
 54#include <stdio.h>

 55//////////////////////////////////////////////////////////////////////////////
 56//
 57// processor instructions extension detection routines
 58//
 59//////////////////////////////////////////////////////////////////////////////
 60
 61
 62// Flag variable indicating whick ISA extensions are disabled (for debugging)
 63static uint _dwDisabledISA = 0x00;      // 0xffffffff; //<- use this to disable all extensions
 64
 65// Disables given set of instruction extensions. See SUPPORT_... defines.
 66void disableExtensions(uint dwDisableMask)
 67{
 68    _dwDisabledISA = dwDisableMask;
 69}
 70
 71
 72
 73/// Checks which instruction set extensions are supported by the CPU.
 74uint detectCPUextensions(void)
 75{
 76#ifndef ALLOW_X86_OPTIMIZATIONS

 77
 78    return 0; // always disable extensions on non-x86 platforms.
 79
 80#else

 81    uint res = 0;
 82
 83    if (_dwDisabledISA == 0xffffffff) return 0;
 84
 85    asm volatile(
 86        "\n\txor     %%esi, %%esi"       // clear %%esi = result register
 87        // check if 'cpuid' instructions is available by toggling eflags bit 21
 88
 89        "\n\tpushf"                      // save eflags to stack
 90        "\n\tpop     %%eax"              // load eax from stack (with eflags)
 91        "\n\tmovl    %%eax, %%ecx"       // save the original eflags values to ecx
 92        "\n\txor     $0x00200000, %%eax" // toggle bit 21
 93        "\n\tpush    %%eax"              // store toggled eflags to stack
 94        "\n\tpopf"                       // load eflags from stack
 95        "\n\tpushf"                      // save updated eflags to stack
 96        "\n\tpop     %%eax"              // load from stack
 97        "\n\txor     %%edx, %%edx"       // clear edx for defaulting no mmx
 98        "\n\tcmp     %%ecx, %%eax"       // compare to original eflags values
 99        "\n\tjz      end"                // jumps to 'end' if cpuid not present
100
101        // cpuid instruction available, test for presence of mmx instructions
102
103        "\n\tmovl    $1, %%eax"
104        "\n\tcpuid"
105//        movl       $0x00800000, %edx   // force enable MMX
106        "\n\ttest    $0x00800000, %%edx"
107        "\n\tjz      end"                // branch if MMX not available
108
109        "\n\tor      $0x01, %%esi"       // otherwise add MMX support bit
110
111        "\n\ttest    $0x02000000, %%edx"
112        "\n\tjz      test3DNow"          // branch if SSE not available
113
114        "\n\tor      $0x08, %%esi"       // otherwise add SSE support bit
115
116    "\n\ttest3DNow:"
117        // test for precense of AMD extensions
118        "\n\tmov     $0x80000000, %%eax"
119        "\n\tcpuid"
120        "\n\tcmp     $0x80000000, %%eax"
121        "\n\tjbe     end"                 // branch if no AMD extensions detected
122
123        // test for precense of 3DNow! extension
124        "\n\tmov     $0x80000001, %%eax"
125        "\n\tcpuid"
126        "\n\ttest    $0x80000000, %%edx"
127        "\n\tjz      end"                  // branch if 3DNow! not detected
128
129        "\n\tor      $0x02, %%esi"         // otherwise add 3DNow support bit
130
131    "\n\tend:"
132
133        "\n\tmov     %%esi, %0"
134
135      : "=r" (res)
136      : /* no inputs */
137      : "%edx", "%eax", "%ecx", "%esi" );
138      
139    return res & ~_dwDisabledISA;
140#endif

141}