1aed1cc94c105736a5e6010e9c84cc32910b865d6mikhal@webrtc.org/* 2b0c97975894a5eebebf9d93147cdd941a3accb63fbarchard@google.com * Copyright 2011 The LibYuv Project Authors. All rights reserved. 3aed1cc94c105736a5e6010e9c84cc32910b865d6mikhal@webrtc.org * 4aed1cc94c105736a5e6010e9c84cc32910b865d6mikhal@webrtc.org * Use of this source code is governed by a BSD-style license 5aed1cc94c105736a5e6010e9c84cc32910b865d6mikhal@webrtc.org * that can be found in the LICENSE file in the root of the source 6aed1cc94c105736a5e6010e9c84cc32910b865d6mikhal@webrtc.org * tree. An additional intellectual property rights grant can be found 7cde587092fef0dbed2c35602f30b79e7b892e766fbarchard@google.com * in the file PATENTS. All contributing project authors may 8aed1cc94c105736a5e6010e9c84cc32910b865d6mikhal@webrtc.org * be found in the AUTHORS file in the root of the source tree. 9aed1cc94c105736a5e6010e9c84cc32910b865d6mikhal@webrtc.org */ 10aed1cc94c105736a5e6010e9c84cc32910b865d6mikhal@webrtc.org 11a1280730c24b5c94ef16949777f65e597719488efbarchard@google.com#include "libyuv/cpu_id.h" 12aed1cc94c105736a5e6010e9c84cc32910b865d6mikhal@webrtc.org 139ffb92fae0d1c82c1fe6808c7c33b1a76bea41f7fbarchard@google.com#if defined(_MSC_VER) && !defined(__clang__) 14e35422d94bda549997db4fc0f9b6836b325e1888fbarchard@google.com#include <intrin.h> // For __cpuidex() 150b0e91792f8af8729495ad4b0662214064cadd99fbarchard@google.com#endif 162c8108e6c2c6fa0c62670a70be7ef6f59cf03848fbarchard@google.com#if !defined(__pnacl__) && !defined(__CLR_VER) && \ 172c8108e6c2c6fa0c62670a70be7ef6f59cf03848fbarchard@google.com !defined(__native_client__) && defined(_M_X64) && \ 186325869685c2ed4de87ffd368b755150861c3bdbfbarchard@google.com defined(_MSC_VER) && (_MSC_FULL_VER >= 160040219) 196325869685c2ed4de87ffd368b755150861c3bdbfbarchard@google.com#include <immintrin.h> // For _xgetbv() 206325869685c2ed4de87ffd368b755150861c3bdbfbarchard@google.com#endif 210b0e91792f8af8729495ad4b0662214064cadd99fbarchard@google.com 224a1325ade560283c552406d17015293e9e3ce40bfbarchard@google.com#if !defined(__native_client__) 2317f198cd46747349512c5cb2a5037d03669f2365fbarchard@google.com#include <stdlib.h> // For getenv() 244a1325ade560283c552406d17015293e9e3ce40bfbarchard@google.com#endif 25e3ebe7a5cd048c9fa798eaff58ba0bca19204dfffbarchard@google.com 26e3ebe7a5cd048c9fa798eaff58ba0bca19204dfffbarchard@google.com// For ArmCpuCaps() but unittested on all platforms 27e3ebe7a5cd048c9fa798eaff58ba0bca19204dfffbarchard@google.com#include <stdio.h> 28e3ebe7a5cd048c9fa798eaff58ba0bca19204dfffbarchard@google.com#include <string.h> 29aed1cc94c105736a5e6010e9c84cc32910b865d6mikhal@webrtc.org 3017f198cd46747349512c5cb2a5037d03669f2365fbarchard@google.com#include "libyuv/basic_types.h" // For CPU_X86 31c82af4a59ce299da67084916317266a33c2868e1frkoenig@google.com 32fe5ff7ed5451496281697bda9cb85084c532926cfbarchard@google.com#ifdef __cplusplus 33aed1cc94c105736a5e6010e9c84cc32910b865d6mikhal@webrtc.orgnamespace libyuv { 34fe5ff7ed5451496281697bda9cb85084c532926cfbarchard@google.comextern "C" { 35fe5ff7ed5451496281697bda9cb85084c532926cfbarchard@google.com#endif 36aed1cc94c105736a5e6010e9c84cc32910b865d6mikhal@webrtc.org 37d9c9f37ac482ac958519e02db8b7c5b47bf1816afbarchard@google.com// For functions that use the stack and have runtime checks for overflow, 386368c10c9c11e7151c9b3c727c18d25c36df6cc6fbarchard@google.com// use SAFEBUFFERS to avoid additional check. 396368c10c9c11e7151c9b3c727c18d25c36df6cc6fbarchard@google.com#if defined(_MSC_VER) && (_MSC_FULL_VER >= 160040219) 406368c10c9c11e7151c9b3c727c18d25c36df6cc6fbarchard@google.com#define SAFEBUFFERS __declspec(safebuffers) 416368c10c9c11e7151c9b3c727c18d25c36df6cc6fbarchard@google.com#else 426368c10c9c11e7151c9b3c727c18d25c36df6cc6fbarchard@google.com#define SAFEBUFFERS 436368c10c9c11e7151c9b3c727c18d25c36df6cc6fbarchard@google.com#endif 446368c10c9c11e7151c9b3c727c18d25c36df6cc6fbarchard@google.com 4564ce0ab544591b1e26ae6d276932cacdb8137071fbarchard@google.com// Low level cpuid for X86. Returns zeros on other CPUs. 462c8108e6c2c6fa0c62670a70be7ef6f59cf03848fbarchard@google.com#if !defined(__pnacl__) && !defined(__CLR_VER) && \ 472c8108e6c2c6fa0c62670a70be7ef6f59cf03848fbarchard@google.com (defined(_M_IX86) || defined(_M_X64) || \ 48133adc46470722b24fdac30d7537d5009e61ef0cfbarchard@google.com defined(__i386__) || defined(__x86_64__)) 49fc7314e86bc7a1a88b38b815e881183521801ea9fbarchard@google.comLIBYUV_API 50bcccd6b78d76999939a84a1a425e06a56dd08920fbarchard@google.comvoid CpuId(uint32 info_eax, uint32 info_ecx, uint32* cpu_info) { 519ffb92fae0d1c82c1fe6808c7c33b1a76bea41f7fbarchard@google.com#if defined(_MSC_VER) && !defined(__clang__) 52bcccd6b78d76999939a84a1a425e06a56dd08920fbarchard@google.com#if (_MSC_FULL_VER >= 160040219) 53959b290a96ff8dee4ab6a011bd80380df9038e7efbarchard@google.com __cpuidex((int*)(cpu_info), info_eax, info_ecx); 54bcccd6b78d76999939a84a1a425e06a56dd08920fbarchard@google.com#elif defined(_M_IX86) 55bcccd6b78d76999939a84a1a425e06a56dd08920fbarchard@google.com __asm { 56bcccd6b78d76999939a84a1a425e06a56dd08920fbarchard@google.com mov eax, info_eax 57bcccd6b78d76999939a84a1a425e06a56dd08920fbarchard@google.com mov ecx, info_ecx 58bcccd6b78d76999939a84a1a425e06a56dd08920fbarchard@google.com mov edi, cpu_info 59bcccd6b78d76999939a84a1a425e06a56dd08920fbarchard@google.com cpuid 60bcccd6b78d76999939a84a1a425e06a56dd08920fbarchard@google.com mov [edi], eax 61bcccd6b78d76999939a84a1a425e06a56dd08920fbarchard@google.com mov [edi + 4], ebx 62bcccd6b78d76999939a84a1a425e06a56dd08920fbarchard@google.com mov [edi + 8], ecx 63bcccd6b78d76999939a84a1a425e06a56dd08920fbarchard@google.com mov [edi + 12], edx 64bcccd6b78d76999939a84a1a425e06a56dd08920fbarchard@google.com } 650b0e91792f8af8729495ad4b0662214064cadd99fbarchard@google.com#else 66bcccd6b78d76999939a84a1a425e06a56dd08920fbarchard@google.com if (info_ecx == 0) { 67959b290a96ff8dee4ab6a011bd80380df9038e7efbarchard@google.com __cpuid((int*)(cpu_info), info_eax); 68bcccd6b78d76999939a84a1a425e06a56dd08920fbarchard@google.com } else { 69bcccd6b78d76999939a84a1a425e06a56dd08920fbarchard@google.com cpu_info[3] = cpu_info[2] = cpu_info[1] = cpu_info[0] = 0; 70bcccd6b78d76999939a84a1a425e06a56dd08920fbarchard@google.com } 71bcccd6b78d76999939a84a1a425e06a56dd08920fbarchard@google.com#endif 72bcccd6b78d76999939a84a1a425e06a56dd08920fbarchard@google.com#else // defined(_MSC_VER) 73bcccd6b78d76999939a84a1a425e06a56dd08920fbarchard@google.com uint32 info_ebx, info_edx; 74e35422d94bda549997db4fc0f9b6836b325e1888fbarchard@google.com asm volatile ( // NOLINT 75e35422d94bda549997db4fc0f9b6836b325e1888fbarchard@google.com#if defined( __i386__) && defined(__PIC__) 76e35422d94bda549997db4fc0f9b6836b325e1888fbarchard@google.com // Preserve ebx for fpic 32 bit. 77e35422d94bda549997db4fc0f9b6836b325e1888fbarchard@google.com "mov %%ebx, %%edi \n" 78e35422d94bda549997db4fc0f9b6836b325e1888fbarchard@google.com "cpuid \n" 79e35422d94bda549997db4fc0f9b6836b325e1888fbarchard@google.com "xchg %%edi, %%ebx \n" 80bcccd6b78d76999939a84a1a425e06a56dd08920fbarchard@google.com : "=D" (info_ebx), 81e35422d94bda549997db4fc0f9b6836b325e1888fbarchard@google.com#else 82e35422d94bda549997db4fc0f9b6836b325e1888fbarchard@google.com "cpuid \n" 83bcccd6b78d76999939a84a1a425e06a56dd08920fbarchard@google.com : "=b" (info_ebx), 84e35422d94bda549997db4fc0f9b6836b325e1888fbarchard@google.com#endif // defined( __i386__) && defined(__PIC__) 85bcccd6b78d76999939a84a1a425e06a56dd08920fbarchard@google.com "+a" (info_eax), "+c" (info_ecx), "=d" (info_edx)); 86bcccd6b78d76999939a84a1a425e06a56dd08920fbarchard@google.com cpu_info[0] = info_eax; 87bcccd6b78d76999939a84a1a425e06a56dd08920fbarchard@google.com cpu_info[1] = info_ebx; 88bcccd6b78d76999939a84a1a425e06a56dd08920fbarchard@google.com cpu_info[2] = info_ecx; 89bcccd6b78d76999939a84a1a425e06a56dd08920fbarchard@google.com cpu_info[3] = info_edx; 90e35422d94bda549997db4fc0f9b6836b325e1888fbarchard@google.com#endif // defined(_MSC_VER) 914c32b3a017cb3ca5a20cce2422e5370cb8c11ad4fbarchard@google.com} 9215df877b64b3ccdc2e69863755ec492e2fd5784afbarchard@google.com 93a721402a206c35840269edba10f7f4dbde78752cfbarchard@google.com#if !defined(__native_client__) 944c32b3a017cb3ca5a20cce2422e5370cb8c11ad4fbarchard@google.com#define HAS_XGETBV 95e35422d94bda549997db4fc0f9b6836b325e1888fbarchard@google.com// X86 CPUs have xgetbv to detect OS saves high parts of ymm registers. 96e35422d94bda549997db4fc0f9b6836b325e1888fbarchard@google.comint TestOsSaveYmm() { 9715df877b64b3ccdc2e69863755ec492e2fd5784afbarchard@google.com uint32 xcr0 = 0u; 9815df877b64b3ccdc2e69863755ec492e2fd5784afbarchard@google.com#if defined(_MSC_VER) && (_MSC_FULL_VER >= 160040219) 99959b290a96ff8dee4ab6a011bd80380df9038e7efbarchard@google.com xcr0 = (uint32)(_xgetbv(0)); // VS2010 SP1 required. 10015df877b64b3ccdc2e69863755ec492e2fd5784afbarchard@google.com#elif defined(_M_IX86) 10115df877b64b3ccdc2e69863755ec492e2fd5784afbarchard@google.com __asm { 10215df877b64b3ccdc2e69863755ec492e2fd5784afbarchard@google.com xor ecx, ecx // xcr 0 10315df877b64b3ccdc2e69863755ec492e2fd5784afbarchard@google.com _asm _emit 0x0f _asm _emit 0x01 _asm _emit 0xd0 // For VS2010 and earlier. 10415df877b64b3ccdc2e69863755ec492e2fd5784afbarchard@google.com mov xcr0, eax 10515df877b64b3ccdc2e69863755ec492e2fd5784afbarchard@google.com } 10615df877b64b3ccdc2e69863755ec492e2fd5784afbarchard@google.com#elif defined(__i386__) || defined(__x86_64__) 10711a0d48e45a7acd5aaf6b914caeee06432f06b6bfbarchard@google.com asm(".byte 0x0f, 0x01, 0xd0" : "=a" (xcr0) : "c" (0) : "%edx"); 108d2371686c217dcb7c10b366483c39c63919327c4fbarchard@google.com#endif // defined(_MSC_VER) 109e35422d94bda549997db4fc0f9b6836b325e1888fbarchard@google.com return((xcr0 & 6) == 6); // Is ymm saved? 1104c32b3a017cb3ca5a20cce2422e5370cb8c11ad4fbarchard@google.com} 111a721402a206c35840269edba10f7f4dbde78752cfbarchard@google.com#endif // !defined(__native_client__) 112e35422d94bda549997db4fc0f9b6836b325e1888fbarchard@google.com#else 113e35422d94bda549997db4fc0f9b6836b325e1888fbarchard@google.comLIBYUV_API 114d2371686c217dcb7c10b366483c39c63919327c4fbarchard@google.comvoid CpuId(uint32 eax, uint32 ecx, uint32* cpu_info) { 115e35422d94bda549997db4fc0f9b6836b325e1888fbarchard@google.com cpu_info[0] = cpu_info[1] = cpu_info[2] = cpu_info[3] = 0; 1160b0e91792f8af8729495ad4b0662214064cadd99fbarchard@google.com} 1177c4656317c789d2ce3600cd75bca2a8b718cc00efbarchard@google.com#endif 1180b0e91792f8af8729495ad4b0662214064cadd99fbarchard@google.com 119e3ebe7a5cd048c9fa798eaff58ba0bca19204dfffbarchard@google.com// based on libvpx arm_cpudetect.c 1207afffcc4d04661e66234986454d4b8a3fb1d2f98fbarchard@google.com// For Arm, but public to allow testing on any CPU 1216368c10c9c11e7151c9b3c727c18d25c36df6cc6fbarchard@google.comLIBYUV_API SAFEBUFFERS 1227afffcc4d04661e66234986454d4b8a3fb1d2f98fbarchard@google.comint ArmCpuCaps(const char* cpuinfo_name) { 12391dc3eddebc189c8bb19b4af1fadccda2b869729fbarchard@google.com char cpuinfo_line[512]; 124bb6bddc9fb4aea694ef26d7761d9fbcba8f5b6c1fbarchard@google.com FILE* f = fopen(cpuinfo_name, "r"); 125cb3344ae255338f5f6dad2f1d9dc7a4ca9579f11fbarchard@google.com if (!f) { 1266e618676dc9971a67dbe15c3472df62fcec23095fbarchard@google.com // Assume Neon if /proc/cpuinfo is unavailable. 1276e618676dc9971a67dbe15c3472df62fcec23095fbarchard@google.com // This will occur for Chrome sandbox for Pepper or Render process. 1286e618676dc9971a67dbe15c3472df62fcec23095fbarchard@google.com return kCpuHasNEON; 129cb3344ae255338f5f6dad2f1d9dc7a4ca9579f11fbarchard@google.com } 130cb3344ae255338f5f6dad2f1d9dc7a4ca9579f11fbarchard@google.com while (fgets(cpuinfo_line, sizeof(cpuinfo_line) - 1, f)) { 131cb3344ae255338f5f6dad2f1d9dc7a4ca9579f11fbarchard@google.com if (memcmp(cpuinfo_line, "Features", 8) == 0) { 132cb3344ae255338f5f6dad2f1d9dc7a4ca9579f11fbarchard@google.com char* p = strstr(cpuinfo_line, " neon"); 133cb3344ae255338f5f6dad2f1d9dc7a4ca9579f11fbarchard@google.com if (p && (p[5] == ' ' || p[5] == '\n')) { 134cb3344ae255338f5f6dad2f1d9dc7a4ca9579f11fbarchard@google.com fclose(f); 135cb3344ae255338f5f6dad2f1d9dc7a4ca9579f11fbarchard@google.com return kCpuHasNEON; 136e3ebe7a5cd048c9fa798eaff58ba0bca19204dfffbarchard@google.com } 137e3ebe7a5cd048c9fa798eaff58ba0bca19204dfffbarchard@google.com } 138e3ebe7a5cd048c9fa798eaff58ba0bca19204dfffbarchard@google.com } 139cb3344ae255338f5f6dad2f1d9dc7a4ca9579f11fbarchard@google.com fclose(f); 140bb6bddc9fb4aea694ef26d7761d9fbcba8f5b6c1fbarchard@google.com return 0; 141e3ebe7a5cd048c9fa798eaff58ba0bca19204dfffbarchard@google.com} 142e3ebe7a5cd048c9fa798eaff58ba0bca19204dfffbarchard@google.com 143de07146fa46d28bdd7f866791b8e764f3c03b849fbarchard@google.com#if defined(__mips__) && defined(__linux__) 144bb6bddc9fb4aea694ef26d7761d9fbcba8f5b6c1fbarchard@google.comstatic int MipsCpuCaps(const char* search_string) { 14591dc3eddebc189c8bb19b4af1fadccda2b869729fbarchard@google.com char cpuinfo_line[512]; 146bb6bddc9fb4aea694ef26d7761d9fbcba8f5b6c1fbarchard@google.com const char* file_name = "/proc/cpuinfo"; 14791dc3eddebc189c8bb19b4af1fadccda2b869729fbarchard@google.com FILE* f = fopen(file_name, "r"); 14891dc3eddebc189c8bb19b4af1fadccda2b869729fbarchard@google.com if (!f) { 14991dc3eddebc189c8bb19b4af1fadccda2b869729fbarchard@google.com // Assume DSP if /proc/cpuinfo is unavailable. 15091dc3eddebc189c8bb19b4af1fadccda2b869729fbarchard@google.com // This will occur for Chrome sandbox for Pepper or Render process. 15191dc3eddebc189c8bb19b4af1fadccda2b869729fbarchard@google.com return kCpuHasMIPS_DSP; 15291dc3eddebc189c8bb19b4af1fadccda2b869729fbarchard@google.com } 15391dc3eddebc189c8bb19b4af1fadccda2b869729fbarchard@google.com while (fgets(cpuinfo_line, sizeof(cpuinfo_line) - 1, f) != NULL) { 15491dc3eddebc189c8bb19b4af1fadccda2b869729fbarchard@google.com if (strstr(cpuinfo_line, search_string) != NULL) { 15591dc3eddebc189c8bb19b4af1fadccda2b869729fbarchard@google.com fclose(f); 15691dc3eddebc189c8bb19b4af1fadccda2b869729fbarchard@google.com return kCpuHasMIPS_DSP; 157ca41005256d8b16fef98bc3383c44c4a3b79bb44fbarchard@google.com } 158ca41005256d8b16fef98bc3383c44c4a3b79bb44fbarchard@google.com } 15991dc3eddebc189c8bb19b4af1fadccda2b869729fbarchard@google.com fclose(f); 160bb6bddc9fb4aea694ef26d7761d9fbcba8f5b6c1fbarchard@google.com return 0; 161ca41005256d8b16fef98bc3383c44c4a3b79bb44fbarchard@google.com} 162de07146fa46d28bdd7f866791b8e764f3c03b849fbarchard@google.com#endif 163ca41005256d8b16fef98bc3383c44c4a3b79bb44fbarchard@google.com 164aed1cc94c105736a5e6010e9c84cc32910b865d6mikhal@webrtc.org// CPU detect function for SIMD instruction sets. 165fc7314e86bc7a1a88b38b815e881183521801ea9fbarchard@google.comLIBYUV_API 1661d160cb99f2b05df80c4555bd769825ad1175dc9fbarchard@google.comint cpu_info_ = kCpuInit; // cpu_info is not initialized yet. 167aed1cc94c105736a5e6010e9c84cc32910b865d6mikhal@webrtc.org 16864ce0ab544591b1e26ae6d276932cacdb8137071fbarchard@google.com// Test environment variable for disabling CPU features. Any non-zero value 16964ce0ab544591b1e26ae6d276932cacdb8137071fbarchard@google.com// to disable. Zero ignored to make it easy to set the variable on/off. 170064d2768a80c66f318a1eff89aa9d12907d407a4fbarchard@google.com#if !defined(__native_client__) && !defined(_M_ARM) 171064d2768a80c66f318a1eff89aa9d12907d407a4fbarchard@google.com 172959b290a96ff8dee4ab6a011bd80380df9038e7efbarchard@google.comstatic LIBYUV_BOOL TestEnv(const char* name) { 17364ce0ab544591b1e26ae6d276932cacdb8137071fbarchard@google.com const char* var = getenv(name); 17464ce0ab544591b1e26ae6d276932cacdb8137071fbarchard@google.com if (var) { 17564ce0ab544591b1e26ae6d276932cacdb8137071fbarchard@google.com if (var[0] != '0') { 176959b290a96ff8dee4ab6a011bd80380df9038e7efbarchard@google.com return LIBYUV_TRUE; 17764ce0ab544591b1e26ae6d276932cacdb8137071fbarchard@google.com } 17864ce0ab544591b1e26ae6d276932cacdb8137071fbarchard@google.com } 179959b290a96ff8dee4ab6a011bd80380df9038e7efbarchard@google.com return LIBYUV_FALSE; 18064ce0ab544591b1e26ae6d276932cacdb8137071fbarchard@google.com} 1814a1325ade560283c552406d17015293e9e3ce40bfbarchard@google.com#else // nacl does not support getenv(). 182959b290a96ff8dee4ab6a011bd80380df9038e7efbarchard@google.comstatic LIBYUV_BOOL TestEnv(const char*) { 183959b290a96ff8dee4ab6a011bd80380df9038e7efbarchard@google.com return LIBYUV_FALSE; 1844a1325ade560283c552406d17015293e9e3ce40bfbarchard@google.com} 1854a1325ade560283c552406d17015293e9e3ce40bfbarchard@google.com#endif 18664ce0ab544591b1e26ae6d276932cacdb8137071fbarchard@google.com 1876368c10c9c11e7151c9b3c727c18d25c36df6cc6fbarchard@google.comLIBYUV_API SAFEBUFFERS 188fc7314e86bc7a1a88b38b815e881183521801ea9fbarchard@google.comint InitCpuFlags(void) { 1892c8108e6c2c6fa0c62670a70be7ef6f59cf03848fbarchard@google.com#if !defined(__pnacl__) && !defined(__CLR_VER) && defined(CPU_X86) 1902c8108e6c2c6fa0c62670a70be7ef6f59cf03848fbarchard@google.com 191451a7541b7fbbcb85199dfbc6faccdb1955ea1d5fbarchard@google.com uint32 cpu_info0[4] = { 0, 0, 0, 0 }; 192e35422d94bda549997db4fc0f9b6836b325e1888fbarchard@google.com uint32 cpu_info1[4] = { 0, 0, 0, 0 }; 193e35422d94bda549997db4fc0f9b6836b325e1888fbarchard@google.com uint32 cpu_info7[4] = { 0, 0, 0, 0 }; 194451a7541b7fbbcb85199dfbc6faccdb1955ea1d5fbarchard@google.com CpuId(0, 0, cpu_info0); 195e35422d94bda549997db4fc0f9b6836b325e1888fbarchard@google.com CpuId(1, 0, cpu_info1); 196451a7541b7fbbcb85199dfbc6faccdb1955ea1d5fbarchard@google.com if (cpu_info0[0] >= 7) { 197451a7541b7fbbcb85199dfbc6faccdb1955ea1d5fbarchard@google.com CpuId(7, 0, cpu_info7); 198451a7541b7fbbcb85199dfbc6faccdb1955ea1d5fbarchard@google.com } 1990057aeb1a949c226cbf265f42447c764e30f266bfbarchard@google.com cpu_info_ = ((cpu_info1[3] & 0x04000000) ? kCpuHasSSE2 : 0) | 2000057aeb1a949c226cbf265f42447c764e30f266bfbarchard@google.com ((cpu_info1[2] & 0x00000200) ? kCpuHasSSSE3 : 0) | 2010057aeb1a949c226cbf265f42447c764e30f266bfbarchard@google.com ((cpu_info1[2] & 0x00080000) ? kCpuHasSSE41 : 0) | 2020057aeb1a949c226cbf265f42447c764e30f266bfbarchard@google.com ((cpu_info1[2] & 0x00100000) ? kCpuHasSSE42 : 0) | 2030057aeb1a949c226cbf265f42447c764e30f266bfbarchard@google.com ((cpu_info7[1] & 0x00000200) ? kCpuHasERMS : 0) | 2042bbb64df2c997725ab1a024a0a21f1c63f895797fbarchard@google.com ((cpu_info1[2] & 0x00001000) ? kCpuHasFMA3 : 0) | 205c7277d08e8d33d470b0f4a5e9c3c58f5f250f114fbarchard@google.com kCpuHasX86; 206451a7541b7fbbcb85199dfbc6faccdb1955ea1d5fbarchard@google.com 20778070bc1ba0978000268f919f1138bede28df436fbarchard@google.com#ifdef HAS_XGETBV 2080cc0b4df467bc318d085c472fadd34e8bf994165fbarchard@google.com if ((cpu_info1[2] & 0x18000000) == 0x18000000 && // AVX and OSSave 209e35422d94bda549997db4fc0f9b6836b325e1888fbarchard@google.com TestOsSaveYmm()) { // Saves YMM. 2100057aeb1a949c226cbf265f42447c764e30f266bfbarchard@google.com cpu_info_ |= ((cpu_info7[1] & 0x00000020) ? kCpuHasAVX2 : 0) | 2112f620e18ed1640d722e23060d752ebab8d5683fbfbarchard@google.com kCpuHasAVX; 21278070bc1ba0978000268f919f1138bede28df436fbarchard@google.com } 21378070bc1ba0978000268f919f1138bede28df436fbarchard@google.com#endif 2146c1b2d38c685e769cf7db2806e27c8ec4c028fe3fbarchard@google.com // Environment variable overrides for testing. 21564ce0ab544591b1e26ae6d276932cacdb8137071fbarchard@google.com if (TestEnv("LIBYUV_DISABLE_X86")) { 216c5d44a0c5e3f67ebd64626a92d71478876ba4ff2fbarchard@google.com cpu_info_ &= ~kCpuHasX86; 217c5d44a0c5e3f67ebd64626a92d71478876ba4ff2fbarchard@google.com } 21864ce0ab544591b1e26ae6d276932cacdb8137071fbarchard@google.com if (TestEnv("LIBYUV_DISABLE_SSE2")) { 219373cdbdc58d6e7b7e4653840677ef01468607e84fbarchard@google.com cpu_info_ &= ~kCpuHasSSE2; 220373cdbdc58d6e7b7e4653840677ef01468607e84fbarchard@google.com } 22164ce0ab544591b1e26ae6d276932cacdb8137071fbarchard@google.com if (TestEnv("LIBYUV_DISABLE_SSSE3")) { 222373cdbdc58d6e7b7e4653840677ef01468607e84fbarchard@google.com cpu_info_ &= ~kCpuHasSSSE3; 223373cdbdc58d6e7b7e4653840677ef01468607e84fbarchard@google.com } 22464ce0ab544591b1e26ae6d276932cacdb8137071fbarchard@google.com if (TestEnv("LIBYUV_DISABLE_SSE41")) { 225c5d44a0c5e3f67ebd64626a92d71478876ba4ff2fbarchard@google.com cpu_info_ &= ~kCpuHasSSE41; 226c5d44a0c5e3f67ebd64626a92d71478876ba4ff2fbarchard@google.com } 22764ce0ab544591b1e26ae6d276932cacdb8137071fbarchard@google.com if (TestEnv("LIBYUV_DISABLE_SSE42")) { 228ab415818447b05cff5bb4dc9c5f0491c543253d6fbarchard@google.com cpu_info_ &= ~kCpuHasSSE42; 229ab415818447b05cff5bb4dc9c5f0491c543253d6fbarchard@google.com } 23064ce0ab544591b1e26ae6d276932cacdb8137071fbarchard@google.com if (TestEnv("LIBYUV_DISABLE_AVX")) { 231ab415818447b05cff5bb4dc9c5f0491c543253d6fbarchard@google.com cpu_info_ &= ~kCpuHasAVX; 232ab415818447b05cff5bb4dc9c5f0491c543253d6fbarchard@google.com } 23364ce0ab544591b1e26ae6d276932cacdb8137071fbarchard@google.com if (TestEnv("LIBYUV_DISABLE_AVX2")) { 23478070bc1ba0978000268f919f1138bede28df436fbarchard@google.com cpu_info_ &= ~kCpuHasAVX2; 23578070bc1ba0978000268f919f1138bede28df436fbarchard@google.com } 2368c9de166a11222d6aa38deb12449b30451d2eca5fbarchard@google.com if (TestEnv("LIBYUV_DISABLE_ERMS")) { 2378c9de166a11222d6aa38deb12449b30451d2eca5fbarchard@google.com cpu_info_ &= ~kCpuHasERMS; 2388c9de166a11222d6aa38deb12449b30451d2eca5fbarchard@google.com } 2392bbb64df2c997725ab1a024a0a21f1c63f895797fbarchard@google.com if (TestEnv("LIBYUV_DISABLE_FMA3")) { 2402bbb64df2c997725ab1a024a0a21f1c63f895797fbarchard@google.com cpu_info_ &= ~kCpuHasFMA3; 2412bbb64df2c997725ab1a024a0a21f1c63f895797fbarchard@google.com } 242bb6bddc9fb4aea694ef26d7761d9fbcba8f5b6c1fbarchard@google.com#elif defined(__mips__) && defined(__linux__) 2436c1b2d38c685e769cf7db2806e27c8ec4c028fe3fbarchard@google.com // Linux mips parse text file for dsp detect. 244bb6bddc9fb4aea694ef26d7761d9fbcba8f5b6c1fbarchard@google.com cpu_info_ = MipsCpuCaps("dsp"); // set kCpuHasMIPS_DSP. 245ca41005256d8b16fef98bc3383c44c4a3b79bb44fbarchard@google.com#if defined(__mips_dspr2) 246ca41005256d8b16fef98bc3383c44c4a3b79bb44fbarchard@google.com cpu_info_ |= kCpuHasMIPS_DSPR2; 247ca41005256d8b16fef98bc3383c44c4a3b79bb44fbarchard@google.com#endif 248ca41005256d8b16fef98bc3383c44c4a3b79bb44fbarchard@google.com cpu_info_ |= kCpuHasMIPS; 249ca41005256d8b16fef98bc3383c44c4a3b79bb44fbarchard@google.com 250ca41005256d8b16fef98bc3383c44c4a3b79bb44fbarchard@google.com if (getenv("LIBYUV_DISABLE_MIPS")) { 251ca41005256d8b16fef98bc3383c44c4a3b79bb44fbarchard@google.com cpu_info_ &= ~kCpuHasMIPS; 252ca41005256d8b16fef98bc3383c44c4a3b79bb44fbarchard@google.com } 253ca41005256d8b16fef98bc3383c44c4a3b79bb44fbarchard@google.com if (getenv("LIBYUV_DISABLE_MIPS_DSP")) { 254ca41005256d8b16fef98bc3383c44c4a3b79bb44fbarchard@google.com cpu_info_ &= ~kCpuHasMIPS_DSP; 2554d3bd8343b8488f978f42112ed4fa3834fbadd77fbarchard@google.com } 256ca41005256d8b16fef98bc3383c44c4a3b79bb44fbarchard@google.com if (getenv("LIBYUV_DISABLE_MIPS_DSPR2")) { 257ca41005256d8b16fef98bc3383c44c4a3b79bb44fbarchard@google.com cpu_info_ &= ~kCpuHasMIPS_DSPR2; 258ca41005256d8b16fef98bc3383c44c4a3b79bb44fbarchard@google.com } 2597afffcc4d04661e66234986454d4b8a3fb1d2f98fbarchard@google.com#elif defined(__arm__) 2606e618676dc9971a67dbe15c3472df62fcec23095fbarchard@google.com// gcc -mfpu=neon defines __ARM_NEON__ 2616e618676dc9971a67dbe15c3472df62fcec23095fbarchard@google.com// __ARM_NEON__ generates code that requires Neon. NaCL also requires Neon. 2626e618676dc9971a67dbe15c3472df62fcec23095fbarchard@google.com// For Linux, /proc/cpuinfo can be tested but without that assume Neon. 263cb3344ae255338f5f6dad2f1d9dc7a4ca9579f11fbarchard@google.com#if defined(__ARM_NEON__) || defined(__native_client__) || !defined(__linux__) 2647afffcc4d04661e66234986454d4b8a3fb1d2f98fbarchard@google.com cpu_info_ = kCpuHasNEON; 265cb3344ae255338f5f6dad2f1d9dc7a4ca9579f11fbarchard@google.com#else 266cb3344ae255338f5f6dad2f1d9dc7a4ca9579f11fbarchard@google.com // Linux arm parse text file for neon detect. 267cb3344ae255338f5f6dad2f1d9dc7a4ca9579f11fbarchard@google.com cpu_info_ = ArmCpuCaps("/proc/cpuinfo"); 2687afffcc4d04661e66234986454d4b8a3fb1d2f98fbarchard@google.com#endif 269c7277d08e8d33d470b0f4a5e9c3c58f5f250f114fbarchard@google.com cpu_info_ |= kCpuHasARM; 27064ce0ab544591b1e26ae6d276932cacdb8137071fbarchard@google.com if (TestEnv("LIBYUV_DISABLE_NEON")) { 271cc206dee46f09369d5b4dad79ec662fd4289959cfbarchard@google.com cpu_info_ &= ~kCpuHasNEON; 272cc206dee46f09369d5b4dad79ec662fd4289959cfbarchard@google.com } 273ca41005256d8b16fef98bc3383c44c4a3b79bb44fbarchard@google.com#endif // __arm__ 27464ce0ab544591b1e26ae6d276932cacdb8137071fbarchard@google.com if (TestEnv("LIBYUV_DISABLE_ASM")) { 275c7277d08e8d33d470b0f4a5e9c3c58f5f250f114fbarchard@google.com cpu_info_ = 0; 276cc206dee46f09369d5b4dad79ec662fd4289959cfbarchard@google.com } 2773c00cf04f343a71650d8ee5b989311ba885c28f5fbarchard@google.com return cpu_info_; 278aed1cc94c105736a5e6010e9c84cc32910b865d6mikhal@webrtc.org} 279aed1cc94c105736a5e6010e9c84cc32910b865d6mikhal@webrtc.org 280fc7314e86bc7a1a88b38b815e881183521801ea9fbarchard@google.comLIBYUV_API 281891091c6d456699df6abf7f61211cbc7612991fdfbarchard@google.comvoid MaskCpuFlags(int enable_flags) { 282c7277d08e8d33d470b0f4a5e9c3c58f5f250f114fbarchard@google.com cpu_info_ = InitCpuFlags() & enable_flags; 283aed1cc94c105736a5e6010e9c84cc32910b865d6mikhal@webrtc.org} 284aed1cc94c105736a5e6010e9c84cc32910b865d6mikhal@webrtc.org 285fe5ff7ed5451496281697bda9cb85084c532926cfbarchard@google.com#ifdef __cplusplus 286fe5ff7ed5451496281697bda9cb85084c532926cfbarchard@google.com} // extern "C" 287aed1cc94c105736a5e6010e9c84cc32910b865d6mikhal@webrtc.org} // namespace libyuv 288fe5ff7ed5451496281697bda9cb85084c532926cfbarchard@google.com#endif 289