diff libavcodec/x86/cpuid.c @ 2:897f711a7157

rearrange to work with autoconf
author Nina Engelhardt <nengel@mailbox.tu-berlin.de>
date Tue, 25 Sep 2012 15:55:33 +0200
parents
children
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/libavcodec/x86/cpuid.c	Tue Sep 25 15:55:33 2012 +0200
     1.3 @@ -0,0 +1,135 @@
     1.4 +/*
     1.5 + * CPU detection code, extracted from mmx.h
     1.6 + * (c)1997-99 by H. Dietz and R. Fisher
     1.7 + * Converted to C and improved by Fabrice Bellard.
     1.8 + *
     1.9 + * This file is part of FFmpeg.
    1.10 + *
    1.11 + * FFmpeg is free software; you can redistribute it and/or
    1.12 + * modify it under the terms of the GNU Lesser General Public
    1.13 + * License as published by the Free Software Foundation; either
    1.14 + * version 2.1 of the License, or (at your option) any later version.
    1.15 + *
    1.16 + * FFmpeg is distributed in the hope that it will be useful,
    1.17 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    1.18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    1.19 + * Lesser General Public License for more details.
    1.20 + *
    1.21 + * You should have received a copy of the GNU Lesser General Public
    1.22 + * License along with FFmpeg; if not, write to the Free Software
    1.23 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
    1.24 + */
    1.25 +
    1.26 +#include <stdlib.h>
    1.27 +#include "libavutil/x86_cpu.h"
    1.28 +#include "libavcodec/dsputil.h"
    1.29 +
    1.30 +#undef printf
    1.31 +
    1.32 +/* ebx saving is necessary for PIC. gcc seems unable to see it alone */
    1.33 +#define cpuid(index,eax,ebx,ecx,edx)\
    1.34 +    __asm__ volatile\
    1.35 +        ("mov %%"REG_b", %%"REG_S"\n\t"\
    1.36 +         "cpuid\n\t"\
    1.37 +         "xchg %%"REG_b", %%"REG_S\
    1.38 +         : "=a" (eax), "=S" (ebx),\
    1.39 +           "=c" (ecx), "=d" (edx)\
    1.40 +         : "0" (index));
    1.41 +
    1.42 +/* Function to test if multimedia instructions are supported...  */
    1.43 +int mm_support()
    1.44 +{
    1.45 +    int rval = 0;
    1.46 +    int eax, ebx, ecx, edx;
    1.47 +    int max_std_level, max_ext_level, std_caps=0, ext_caps=0;
    1.48 +
    1.49 +#if ARCH_X86_32
    1.50 +    x86_reg a, c;
    1.51 +    __asm__ volatile (
    1.52 +        /* See if CPUID instruction is supported ... */
    1.53 +        /* ... Get copies of EFLAGS into eax and ecx */
    1.54 +        "pushfl\n\t"
    1.55 +        "pop %0\n\t"
    1.56 +        "mov %0, %1\n\t"
    1.57 +
    1.58 +        /* ... Toggle the ID bit in one copy and store */
    1.59 +        /*     to the EFLAGS reg */
    1.60 +        "xor $0x200000, %0\n\t"
    1.61 +        "push %0\n\t"
    1.62 +        "popfl\n\t"
    1.63 +
    1.64 +        /* ... Get the (hopefully modified) EFLAGS */
    1.65 +        "pushfl\n\t"
    1.66 +        "pop %0\n\t"
    1.67 +        : "=a" (a), "=c" (c)
    1.68 +        :
    1.69 +        : "cc"
    1.70 +        );
    1.71 +
    1.72 +    if (a == c)
    1.73 +        return 0; /* CPUID not supported */
    1.74 +#endif
    1.75 +
    1.76 +    cpuid(0, max_std_level, ebx, ecx, edx);
    1.77 +
    1.78 +    if(max_std_level >= 1){
    1.79 +        cpuid(1, eax, ebx, ecx, std_caps);
    1.80 +        if (std_caps & (1<<23))
    1.81 +            rval |= FF_MM_MMX;
    1.82 +        if (std_caps & (1<<25))
    1.83 +            rval |= FF_MM_MMX2
    1.84 +#if HAVE_SSE
    1.85 +                  | FF_MM_SSE;
    1.86 +        if (std_caps & (1<<26))
    1.87 +            rval |= FF_MM_SSE2;
    1.88 +        if (ecx & 1)
    1.89 +            rval |= FF_MM_SSE3;
    1.90 +        if (ecx & 0x00000200 )
    1.91 +            rval |= FF_MM_SSSE3;
    1.92 +        if (ecx & 0x00080000 )
    1.93 +            rval |= FF_MM_SSE4;
    1.94 +        if (ecx & 0x00100000 )
    1.95 +            rval |= FF_MM_SSE42;
    1.96 +#endif
    1.97 +                  ;
    1.98 +    }
    1.99 +
   1.100 +    cpuid(0x80000000, max_ext_level, ebx, ecx, edx);
   1.101 +
   1.102 +    if(max_ext_level >= 0x80000001){
   1.103 +        cpuid(0x80000001, eax, ebx, ecx, ext_caps);
   1.104 +        if (ext_caps & (1<<31))
   1.105 +            rval |= FF_MM_3DNOW;
   1.106 +        if (ext_caps & (1<<30))
   1.107 +            rval |= FF_MM_3DNOWEXT;
   1.108 +        if (ext_caps & (1<<23))
   1.109 +            rval |= FF_MM_MMX;
   1.110 +        if (ext_caps & (1<<22))
   1.111 +            rval |= FF_MM_MMX2;
   1.112 +    }
   1.113 +
   1.114 +#if 0
   1.115 +    av_log(NULL, AV_LOG_DEBUG, "%s%s%s%s%s%s%s%s%s%s\n",
   1.116 +        (rval&FF_MM_MMX) ? "MMX ":"",
   1.117 +        (rval&FF_MM_MMX2) ? "MMX2 ":"",
   1.118 +        (rval&FF_MM_SSE) ? "SSE ":"",
   1.119 +        (rval&FF_MM_SSE2) ? "SSE2 ":"",
   1.120 +        (rval&FF_MM_SSE3) ? "SSE3 ":"",
   1.121 +        (rval&FF_MM_SSSE3) ? "SSSE3 ":"",
   1.122 +        (rval&FF_MM_SSE4) ? "SSE4.1 ":"",
   1.123 +        (rval&FF_MM_SSE42) ? "SSE4.2 ":"",
   1.124 +        (rval&FF_MM_3DNOW) ? "3DNow ":"",
   1.125 +        (rval&FF_MM_3DNOWEXT) ? "3DNowExt ":"");
   1.126 +#endif
   1.127 +    return rval;
   1.128 +}
   1.129 +
   1.130 +#ifdef TEST
   1.131 +int main ( void )
   1.132 +{
   1.133 +    int mm_flags;
   1.134 +    mm_flags = mm_support();
   1.135 +    printf("mm_support = 0x%08X\n",mm_flags);
   1.136 +    return 0;
   1.137 +}
   1.138 +#endif