⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cpu.c

📁 VLC Player Source Code
💻 C
字号:
/***************************************************************************** * cpu.c: CPU detection code ***************************************************************************** * Copyright (C) 1998-2004 the VideoLAN team * $Id$ * * Authors: Samuel Hocevar <sam@zoy.org> *          Christophe Massiot <massiot@via.ecp.fr> *          Eugenio Jarosiewicz <ej0@cise.ufl.eduEujenio> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************//***************************************************************************** * Preamble *****************************************************************************/#ifdef HAVE_CONFIG_H# include "config.h"#endif#include <vlc_common.h>#ifdef HAVE_SIGNAL_H#   include <signal.h>                            /* SIGHUP, SIGINT, SIGKILL */#   include <setjmp.h>                                    /* longjmp, setjmp */#endif#include "libvlc.h"#if defined(__APPLE__) && (defined(__ppc__) || defined(__ppc64__))#include <sys/sysctl.h>#endif/***************************************************************************** * Local prototypes *****************************************************************************/#ifdef HAVE_SIGNAL_Hstatic void SigHandler   ( int );#endif/***************************************************************************** * Global variables - they're needed for signal handling *****************************************************************************/#ifdef HAVE_SIGNAL_Hstatic jmp_buf env;static int     i_illegal;#if defined( __i386__ ) || defined( __x86_64__ )static const char *psz_capability;#endif#endif/***************************************************************************** * CPUCapabilities: get the CPU capabilities ***************************************************************************** * This function is called to list extensions the CPU may have. *****************************************************************************/uint32_t CPUCapabilities( void ){    volatile uint32_t i_capabilities = CPU_CAPABILITY_NONE;#if defined(__APPLE__) && (defined(__ppc__) || defined(__ppc64__))    int selectors[2] = { CTL_HW, HW_VECTORUNIT };    int i_has_altivec = 0;    size_t i_length = sizeof( i_has_altivec );    int i_error = sysctl( selectors, 2, &i_has_altivec, &i_length, NULL, 0);    i_capabilities |= CPU_CAPABILITY_FPU;    if( i_error == 0 && i_has_altivec != 0 )        i_capabilities |= CPU_CAPABILITY_ALTIVEC;    return i_capabilities;#elif defined( __i386__ ) || defined( __x86_64__ )    volatile unsigned int  i_eax, i_ebx, i_ecx, i_edx;    volatile bool    b_amd;    /* Needed for x86 CPU capabilities detection */#   if defined( __x86_64__ )#       define cpuid( reg )                    \            asm volatile ( "cpuid\n\t"         \                           "movl %%ebx,%1\n\t" \                         : "=a" ( i_eax ),     \                           "=b" ( i_ebx ),     \                           "=c" ( i_ecx ),     \                           "=d" ( i_edx )      \                         : "a"  ( reg )        \                         : "cc" );#   else#       define cpuid( reg )                    \            asm volatile ( "push %%ebx\n\t"    \                           "cpuid\n\t"         \                           "movl %%ebx,%1\n\t" \                           "pop %%ebx\n\t"     \                         : "=a" ( i_eax ),     \                           "=r" ( i_ebx ),     \                           "=c" ( i_ecx ),     \                           "=d" ( i_edx )      \                         : "a"  ( reg )        \                         : "cc" );#   endif#   if defined( CAN_COMPILE_SSE ) || defined ( CAN_COMPILE_3DNOW ) \     && defined( HAVE_SIGNAL_H )    void (*pf_sigill) (int) = signal( SIGILL, SigHandler );#   endif    i_capabilities |= CPU_CAPABILITY_FPU;#   if defined( __i386__ )    /* check if cpuid instruction is supported */    asm volatile ( "push %%ebx\n\t"                   "pushf\n\t"                   "pop %%eax\n\t"                   "movl %%eax, %%ebx\n\t"                   "xorl $0x200000, %%eax\n\t"                   "push %%eax\n\t"                   "popf\n\t"                   "pushf\n\t"                   "pop %%eax\n\t"                   "movl %%ebx,%1\n\t"                   "pop %%ebx\n\t"                 : "=a" ( i_eax ),                   "=r" ( i_ebx )                 :                 : "cc" );    if( i_eax == i_ebx )    {#       if defined( CAN_COMPILE_SSE ) || defined ( CAN_COMPILE_3DNOW ) \            && defined( HAVE_SIGNAL_H )        signal( SIGILL, pf_sigill );#       endif        return i_capabilities;    }#   else    /* x86_64 supports cpuid instruction, so we dont need to check it */#   endif    i_capabilities |= CPU_CAPABILITY_486;    /* the CPU supports the CPUID instruction - get its level */    cpuid( 0x00000000 );    if( !i_eax )    {#   if defined( CAN_COMPILE_SSE ) || defined ( CAN_COMPILE_3DNOW ) \     && defined( HAVE_SIGNAL_H )        signal( SIGILL, pf_sigill );#   endif        return i_capabilities;    }    /* FIXME: this isn't correct, since some 486s have cpuid */    i_capabilities |= CPU_CAPABILITY_586;    /* borrowed from mpeg2dec */    b_amd = ( i_ebx == 0x68747541 ) && ( i_ecx == 0x444d4163 )                    && ( i_edx == 0x69746e65 );    /* test for the MMX flag */    cpuid( 0x00000001 );    if( ! (i_edx & 0x00800000) )    {#   if defined( CAN_COMPILE_SSE ) || defined ( CAN_COMPILE_3DNOW ) \     && defined( HAVE_SIGNAL_H )        signal( SIGILL, pf_sigill );#   endif        return i_capabilities;    }    i_capabilities |= CPU_CAPABILITY_MMX;    if( i_edx & 0x02000000 )    {        i_capabilities |= CPU_CAPABILITY_MMXEXT;#   ifdef CAN_COMPILE_SSE        /* We test if OS supports the SSE instructions */        psz_capability = "SSE";        i_illegal = 0;        if( setjmp( env ) == 0 )        {            /* Test a SSE instruction */            __asm__ __volatile__ ( "xorps %%xmm0,%%xmm0\n" : : );        }        if( i_illegal == 0 )        {            i_capabilities |= CPU_CAPABILITY_SSE;        }#   endif    }    if( i_edx & 0x04000000 )    {#   if defined(CAN_COMPILE_SSE)        /* We test if OS supports the SSE instructions */        psz_capability = "SSE2";        i_illegal = 0;        if( setjmp( env ) == 0 )        {            /* Test a SSE2 instruction */            __asm__ __volatile__ ( "movupd %%xmm0, %%xmm0\n" : : );        }        if( i_illegal == 0 )        {            i_capabilities |= CPU_CAPABILITY_SSE2;        }#   endif    }    /* test for additional capabilities */    cpuid( 0x80000000 );    if( i_eax < 0x80000001 )    {#   if defined( CAN_COMPILE_SSE ) || defined ( CAN_COMPILE_3DNOW ) \     && defined( HAVE_SIGNAL_H )        signal( SIGILL, pf_sigill );#   endif        return i_capabilities;    }    /* list these additional capabilities */    cpuid( 0x80000001 );#   ifdef CAN_COMPILE_3DNOW    if( i_edx & 0x80000000 )    {        psz_capability = "3D Now!";        i_illegal = 0;        if( setjmp( env ) == 0 )        {            /* Test a 3D Now! instruction */            __asm__ __volatile__ ( "pfadd %%mm0,%%mm0\n" "femms\n" : : );        }        if( i_illegal == 0 )        {            i_capabilities |= CPU_CAPABILITY_3DNOW;        }    }#   endif    if( b_amd && ( i_edx & 0x00400000 ) )    {        i_capabilities |= CPU_CAPABILITY_MMXEXT;    }#   if defined( CAN_COMPILE_SSE ) || defined ( CAN_COMPILE_3DNOW ) \     && defined( HAVE_SIGNAL_H )    signal( SIGILL, pf_sigill );#   endif    return i_capabilities;#elif defined( __powerpc__ ) || defined( __ppc__ ) || defined( __ppc64__ )#   ifdef CAN_COMPILE_ALTIVEC && defined( HAVE_SIGNAL_H )    void (*pf_sigill) (int) = signal( SIGILL, SigHandler );    i_capabilities |= CPU_CAPABILITY_FPU;    i_illegal = 0;    if( setjmp( env ) == 0 )    {        asm volatile ("mtspr 256, %0\n\t"                      "vand %%v0, %%v0, %%v0"                      :                      : "r" (-1));    }    if( i_illegal == 0 )    {        i_capabilities |= CPU_CAPABILITY_ALTIVEC;    }    signal( SIGILL, pf_sigill );#   else    (void)SigHandler; /* Don't complain about dead code here */#   endif    return i_capabilities;#elif defined( __sparc__ )    i_capabilities |= CPU_CAPABILITY_FPU;    return i_capabilities;#elif defined( _MSC_VER ) && !defined( UNDER_CE )    i_capabilities |= CPU_CAPABILITY_FPU;    return i_capabilities;#else    /* default behaviour */    return i_capabilities;#endif}/***************************************************************************** * SigHandler: system signal handler ***************************************************************************** * This function is called when an illegal instruction signal is received by * the program. We use this function to test OS and CPU capabilities *****************************************************************************/#if defined( HAVE_SIGNAL_H )static void SigHandler( int i_signal ){    /* Acknowledge the signal received */    i_illegal = 1;#ifdef HAVE_SIGRELSE    sigrelse( i_signal );#else    VLC_UNUSED( i_signal );#endif#if defined( __i386__ )    fprintf( stderr, "warning: your CPU has %s instructions, but not your "                     "operating system.\n", psz_capability );    fprintf( stderr, "         some optimizations will be disabled unless "                     "you upgrade your OS\n" );#   if defined( __linux__ )    fprintf( stderr, "         (for instance Linux kernel 2.4.x or later)\n" );#   endif#endif    longjmp( env, 1 );}#endifuint32_t cpu_flags = 0;/***************************************************************************** * vlc_CPU: get pre-computed CPU capability flags ****************************************************************************/unsigned vlc_CPU (void){    return cpu_flags;}static vlc_memcpy_t pf_vlc_memcpy = memcpy;static vlc_memset_t pf_vlc_memset = memset;void vlc_fastmem_register (vlc_memcpy_t cpy, vlc_memset_t set){    if (cpy)        pf_vlc_memcpy = cpy;    if (set)        pf_vlc_memset = set;}/** * vlc_memcpy: fast CPU-dependent memcpy */void *vlc_memcpy (void *tgt, const void *src, size_t n){    return pf_vlc_memcpy (tgt, src, n);}/** * vlc_memset: fast CPU-dependent memset */void *vlc_memset (void *tgt, int c, size_t n){    return pf_vlc_memset (tgt, c, n);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -