1// Copyright 2011 Google Inc. All Rights Reserved.
2//
3// Use of this source code is governed by a BSD-style license
4// that can be found in the COPYING file in the root of the source
5// tree. An additional intellectual property rights grant can be found
6// in the file PATENTS. All contributing project authors may
7// be found in the AUTHORS file in the root of the source tree.
8// -----------------------------------------------------------------------------
9//
10// CPU detection
11//
12// Author: Christian Duvivier (cduvivier@google.com)
13
14#include "./dsp.h"
15
16#if defined(__ANDROID__)
17#include "./cpu-features.h"
18#endif
19
20#if defined(__cplusplus) || defined(c_plusplus)
21extern "C" {
22#endif
23
24//------------------------------------------------------------------------------
25// SSE2 detection.
26//
27
28// apple/darwin gcc-4.0.1 defines __PIC__, but not __pic__ with -fPIC.
29#if (defined(__pic__) || defined(__PIC__)) && defined(__i386__)
30static WEBP_INLINE void GetCPUInfo(int cpu_info[4], int info_type) {
31  __asm__ volatile (
32    "mov %%ebx, %%edi\n"
33    "cpuid\n"
34    "xchg %%edi, %%ebx\n"
35    : "=a"(cpu_info[0]), "=D"(cpu_info[1]), "=c"(cpu_info[2]), "=d"(cpu_info[3])
36    : "a"(info_type));
37}
38#elif defined(__i386__) || defined(__x86_64__)
39static WEBP_INLINE void GetCPUInfo(int cpu_info[4], int info_type) {
40  __asm__ volatile (
41    "cpuid\n"
42    : "=a"(cpu_info[0]), "=b"(cpu_info[1]), "=c"(cpu_info[2]), "=d"(cpu_info[3])
43    : "a"(info_type));
44}
45#elif defined(WEBP_MSC_SSE2)
46#define GetCPUInfo __cpuid
47#endif
48
49#if defined(__i386__) || defined(__x86_64__) || defined(WEBP_MSC_SSE2)
50static int x86CPUInfo(CPUFeature feature) {
51  int cpu_info[4];
52  GetCPUInfo(cpu_info, 1);
53  if (feature == kSSE2) {
54    return 0 != (cpu_info[3] & 0x04000000);
55  }
56  if (feature == kSSE3) {
57    return 0 != (cpu_info[2] & 0x00000001);
58  }
59  return 0;
60}
61VP8CPUInfo VP8GetCPUInfo = x86CPUInfo;
62#elif defined(WEBP_ANDROID_NEON)
63static int AndroidCPUInfo(CPUFeature feature) {
64  const AndroidCpuFamily cpu_family = android_getCpuFamily();
65  const uint64_t cpu_features = android_getCpuFeatures();
66  if (feature == kNEON) {
67    return (cpu_family == ANDROID_CPU_FAMILY_ARM &&
68            0 != (cpu_features & ANDROID_CPU_ARM_FEATURE_NEON));
69  }
70  return 0;
71}
72VP8CPUInfo VP8GetCPUInfo = AndroidCPUInfo;
73#elif defined(__ARM_NEON__)
74// define a dummy function to enable turning off NEON at runtime by setting
75// VP8DecGetCPUInfo = NULL
76static int armCPUInfo(CPUFeature feature) {
77  (void)feature;
78  return 1;
79}
80VP8CPUInfo VP8GetCPUInfo = armCPUInfo;
81#else
82VP8CPUInfo VP8GetCPUInfo = NULL;
83#endif
84
85#if defined(__cplusplus) || defined(c_plusplus)
86}    // extern "C"
87#endif
88