• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright (c) 2011 The LibYuv 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 "libyuv/cpu_id.h"
12 #include "libyuv/basic_types.h"  // for CPU_X86
13 
14 #ifdef _MSC_VER
15 #include <intrin.h>
16 #endif
17 
18 // TODO(fbarchard): Use cpuid.h when gcc 4.4 is used on OSX and Linux.
19 #if (defined(__pic__) || defined(__APPLE__)) && defined(__i386__)
__cpuid(int cpu_info[4],int info_type)20 static inline void __cpuid(int cpu_info[4], int info_type) {
21   __asm__ volatile (
22     "mov %%ebx, %%edi\n"
23     "cpuid\n"
24     "xchg %%edi, %%ebx\n"
25     : "=a"(cpu_info[0]), "=D"(cpu_info[1]), "=c"(cpu_info[2]), "=d"(cpu_info[3])
26     : "a"(info_type)
27   );
28 }
29 #elif defined(__i386__) || defined(__x86_64__)
__cpuid(int cpu_info[4],int info_type)30 static inline void __cpuid(int cpu_info[4], int info_type) {
31   __asm__ volatile (
32     "cpuid\n"
33     : "=a"(cpu_info[0]), "=b"(cpu_info[1]), "=c"(cpu_info[2]), "=d"(cpu_info[3])
34     : "a"(info_type)
35   );
36 }
37 #endif
38 
39 namespace libyuv {
40 
41 // CPU detect function for SIMD instruction sets.
42 static int cpu_info_ = 0;
43 
44 // TODO(fbarchard): (cpu_info[2] & 0x10000000 ? kCpuHasAVX : 0)
InitCpuFlags()45 static void InitCpuFlags() {
46 #ifdef CPU_X86
47   int cpu_info[4];
48   __cpuid(cpu_info, 1);
49   cpu_info_ = (cpu_info[3] & 0x04000000 ? kCpuHasSSE2 : 0) |
50               (cpu_info[2] & 0x00000200 ? kCpuHasSSSE3 : 0) |
51               kCpuInitialized;
52 #elif defined(__ARM_NEON__)
53   // gcc -mfpu=neon defines __ARM_NEON__
54   // Enable Neon if you want support for Neon and Arm, and use MaskCpuFlags
55   // to disable Neon on devices that do not have it.
56   cpu_info_ = kCpuHasNEON | kCpuInitialized;
57 #else
58   cpu_info_ = kCpuInitialized;
59 #endif
60 }
61 
MaskCpuFlags(int enable_flags)62 void MaskCpuFlags(int enable_flags) {
63   InitCpuFlags();
64   cpu_info_ &= enable_flags;
65 }
66 
TestCpuFlag(int flag)67 bool TestCpuFlag(int flag) {
68   if (0 == cpu_info_) {
69     InitCpuFlags();
70   }
71   return cpu_info_ & flag ? true : false;
72 }
73 
74 }  // namespace libyuv
75