PageRenderTime 33ms CodeModel.GetById 14ms app.highlight 13ms RepoModel.GetById 2ms app.codeStats 0ms

/media/libvpx/vpx_ports/arm_cpudetect.c

http://github.com/zpao/v8monkey
C | 190 lines | 152 code | 11 blank | 27 comment | 34 complexity | 4fe0f5ecbd696637666e11b14d275665 MD5 | raw file
  1/*
  2 *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
  3 *
  4 *  Use of this source code is governed by a BSD-style license
  5 *  that can be found in the LICENSE file in the root of the source
  6 *  tree. An additional intellectual property rights grant can be found
  7 *  in the file PATENTS.  All contributing project authors may
  8 *  be found in the AUTHORS file in the root of the source tree.
  9 */
 10
 11#include <stdlib.h>
 12#include <string.h>
 13#include "arm.h"
 14
 15static int arm_cpu_env_flags(int *flags)
 16{
 17    char *env;
 18    env = getenv("VPX_SIMD_CAPS");
 19    if (env && *env)
 20    {
 21        *flags = (int)strtol(env, NULL, 0);
 22        return 0;
 23    }
 24    *flags = 0;
 25    return -1;
 26}
 27
 28static int arm_cpu_env_mask(void)
 29{
 30    char *env;
 31    env = getenv("VPX_SIMD_CAPS_MASK");
 32    return env && *env ? (int)strtol(env, NULL, 0) : ~0;
 33}
 34
 35
 36#if defined(_MSC_VER)
 37/*For GetExceptionCode() and EXCEPTION_ILLEGAL_INSTRUCTION.*/
 38#define WIN32_LEAN_AND_MEAN
 39#define WIN32_EXTRA_LEAN
 40#include <windows.h>
 41
 42int arm_cpu_caps(void)
 43{
 44    int flags;
 45    int mask;
 46    if (!arm_cpu_env_flags(&flags))
 47    {
 48        return flags;
 49    }
 50    mask = arm_cpu_env_mask();
 51    /* MSVC has no inline __asm support for ARM, but it does let you __emit
 52     *  instructions via their assembled hex code.
 53     * All of these instructions should be essentially nops.
 54     */
 55#if defined(HAVE_ARMV5TE)
 56    if (mask & HAS_EDSP)
 57    {
 58        __try
 59        {
 60            /*PLD [r13]*/
 61            __emit(0xF5DDF000);
 62            flags |= HAS_EDSP;
 63        }
 64        __except(GetExceptionCode() == EXCEPTION_ILLEGAL_INSTRUCTION)
 65        {
 66            /*Ignore exception.*/
 67        }
 68    }
 69#if defined(HAVE_ARMV6)
 70    if (mask & HAS_MEDIA)
 71        __try
 72        {
 73            /*SHADD8 r3,r3,r3*/
 74            __emit(0xE6333F93);
 75            flags |= HAS_MEDIA;
 76        }
 77        __except(GetExceptionCode() == EXCEPTION_ILLEGAL_INSTRUCTION)
 78        {
 79            /*Ignore exception.*/
 80        }
 81    }
 82#if defined(HAVE_ARMV7)
 83    if (mask & HAS_NEON)
 84    {
 85        __try
 86        {
 87            /*VORR q0,q0,q0*/
 88            __emit(0xF2200150);
 89            flags |= HAS_NEON;
 90        }
 91        __except(GetExceptionCode() == EXCEPTION_ILLEGAL_INSTRUCTION)
 92        {
 93            /*Ignore exception.*/
 94        }
 95    }
 96#endif
 97#endif
 98#endif
 99    return flags & mask;
100}
101
102#elif defined(__linux__)
103#include <stdio.h>
104
105int arm_cpu_caps(void)
106{
107    FILE *fin;
108    int flags;
109    int mask;
110    if (!arm_cpu_env_flags(&flags))
111    {
112        return flags;
113    }
114    mask = arm_cpu_env_mask();
115    /* Reading /proc/self/auxv would be easier, but that doesn't work reliably
116     *  on Android.
117     * This also means that detection will fail in Scratchbox.
118     */
119    fin = fopen("/proc/cpuinfo","r");
120    if(fin != NULL)
121    {
122        /* 512 should be enough for anybody (it's even enough for all the flags
123         * that x86 has accumulated... so far).
124         */
125        char buf[512];
126        while (fgets(buf, 511, fin) != NULL)
127        {
128#if defined(HAVE_ARMV5TE) || defined(HAVE_ARMV7)
129            if (memcmp(buf, "Features", 8) == 0)
130            {
131                char *p;
132#if defined(HAVE_ARMV5TE)
133                p=strstr(buf, " edsp");
134                if (p != NULL && (p[5] == ' ' || p[5] == '\n'))
135                {
136                    flags |= HAS_EDSP;
137                }
138#if defined(HAVE_ARMV7)
139                p = strstr(buf, " neon");
140                if (p != NULL && (p[5] == ' ' || p[5] == '\n'))
141                {
142                    flags |= HAS_NEON;
143                }
144#endif
145#endif
146            }
147#endif
148#if defined(HAVE_ARMV6)
149            if (memcmp(buf, "CPU architecture:",17) == 0){
150                int version;
151                version = atoi(buf+17);
152                if (version >= 6)
153                {
154                    flags |= HAS_MEDIA;
155                }
156            }
157#endif
158        }
159        fclose(fin);
160    }
161    return flags & mask;
162}
163
164#elif !CONFIG_RUNTIME_CPU_DETECT
165
166int arm_cpu_caps(void)
167{
168    int flags;
169    int mask;
170    if (!arm_cpu_env_flags(&flags))
171    {
172        return flags;
173    }
174    mask = arm_cpu_env_mask();
175#if defined(HAVE_ARMV5TE)
176    flags |= HAS_EDSP;
177#endif
178#if defined(HAVE_ARMV6)
179    flags |= HAS_MEDIA;
180#endif
181#if defined(HAVE_ARMV7)
182    flags |= HAS_NEON;
183#endif
184    return flags & mask;
185}
186
187#else
188#error "--enable-runtime-cpu-detect selected, but no CPU detection method " \
189 "available for your platform. Reconfigure without --enable-runtime-cpu-detect."
190#endif