| OLD | NEW |
| 1 // Copyright 2011 Google Inc. All Rights Reserved. | 1 // Copyright 2011 Google Inc. All Rights Reserved. |
| 2 // | 2 // |
| 3 // Use of this source code is governed by a BSD-style license | 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 | 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 | 5 // tree. An additional intellectual property rights grant can be found |
| 6 // in the file PATENTS. All contributing project authors may | 6 // in the file PATENTS. All contributing project authors may |
| 7 // be found in the AUTHORS file in the root of the source tree. | 7 // be found in the AUTHORS file in the root of the source tree. |
| 8 // ----------------------------------------------------------------------------- | 8 // ----------------------------------------------------------------------------- |
| 9 // | 9 // |
| 10 // CPU detection | 10 // CPU detection |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 88 mov eax_, eax | 88 mov eax_, eax |
| 89 mov edx_, edx | 89 mov edx_, edx |
| 90 } | 90 } |
| 91 return ((uint64_t)edx_ << 32) | eax_; | 91 return ((uint64_t)edx_ << 32) | eax_; |
| 92 } | 92 } |
| 93 #else | 93 #else |
| 94 #define xgetbv() 0U // no AVX for older x64 or unrecognized toolchains. | 94 #define xgetbv() 0U // no AVX for older x64 or unrecognized toolchains. |
| 95 #endif | 95 #endif |
| 96 | 96 |
| 97 #if defined(__i386__) || defined(__x86_64__) || defined(WEBP_MSC_SSE2) | 97 #if defined(__i386__) || defined(__x86_64__) || defined(WEBP_MSC_SSE2) |
| 98 |
| 99 // helper function for run-time detection of slow SSSE3 platforms |
| 100 static int CheckSlowModel(int info) { |
| 101 // Table listing display models with longer latencies for the bsr instruction |
| 102 // (ie 2 cycles vs 10/16 cycles) and some SSSE3 instructions like pshufb. |
| 103 // Refer to Intel 64 and IA-32 Architectures Optimization Reference Manual. |
| 104 static const uint8_t kSlowModels[] = { |
| 105 0x37, 0x4a, 0x4d, // Silvermont Microarchitecture |
| 106 0x1c, 0x26, 0x27 // Atom Microarchitecture |
| 107 }; |
| 108 const uint32_t model = ((info & 0xf0000) >> 12) | ((info >> 4) & 0xf); |
| 109 const uint32_t family = (info >> 8) & 0xf; |
| 110 if (family == 0x06) { |
| 111 size_t i; |
| 112 for (i = 0; i < sizeof(kSlowModels) / sizeof(kSlowModels[0]); ++i) { |
| 113 if (model == kSlowModels[i]) return 1; |
| 114 } |
| 115 } |
| 116 return 0; |
| 117 } |
| 118 |
| 98 static int x86CPUInfo(CPUFeature feature) { | 119 static int x86CPUInfo(CPUFeature feature) { |
| 99 int max_cpuid_value; | 120 int max_cpuid_value; |
| 100 int cpu_info[4]; | 121 int cpu_info[4]; |
| 122 int is_intel = 0; |
| 101 | 123 |
| 102 // get the highest feature value cpuid supports | 124 // get the highest feature value cpuid supports |
| 103 GetCPUInfo(cpu_info, 0); | 125 GetCPUInfo(cpu_info, 0); |
| 104 max_cpuid_value = cpu_info[0]; | 126 max_cpuid_value = cpu_info[0]; |
| 105 if (max_cpuid_value < 1) { | 127 if (max_cpuid_value < 1) { |
| 106 return 0; | 128 return 0; |
| 129 } else { |
| 130 const int VENDOR_ID_INTEL_EBX = 0x756e6547; // uneG |
| 131 const int VENDOR_ID_INTEL_EDX = 0x49656e69; // Ieni |
| 132 const int VENDOR_ID_INTEL_ECX = 0x6c65746e; // letn |
| 133 is_intel = (cpu_info[1] == VENDOR_ID_INTEL_EBX && |
| 134 cpu_info[2] == VENDOR_ID_INTEL_ECX && |
| 135 cpu_info[3] == VENDOR_ID_INTEL_EDX); // genuine Intel? |
| 107 } | 136 } |
| 108 | 137 |
| 109 GetCPUInfo(cpu_info, 1); | 138 GetCPUInfo(cpu_info, 1); |
| 110 if (feature == kSSE2) { | 139 if (feature == kSSE2) { |
| 111 return 0 != (cpu_info[3] & 0x04000000); | 140 return !!(cpu_info[3] & (1 << 26)); |
| 112 } | 141 } |
| 113 if (feature == kSSE3) { | 142 if (feature == kSSE3) { |
| 114 return 0 != (cpu_info[2] & 0x00000001); | 143 return !!(cpu_info[2] & (1 << 0)); |
| 115 } | 144 } |
| 145 if (feature == kSlowSSSE3) { |
| 146 if (is_intel && (cpu_info[2] & (1 << 0))) { // SSSE3? |
| 147 return CheckSlowModel(cpu_info[0]); |
| 148 } |
| 149 return 0; |
| 150 } |
| 151 |
| 116 if (feature == kSSE4_1) { | 152 if (feature == kSSE4_1) { |
| 117 return 0 != (cpu_info[2] & 0x00080000); | 153 return !!(cpu_info[2] & (1 << 19)); |
| 118 } | 154 } |
| 119 if (feature == kAVX) { | 155 if (feature == kAVX) { |
| 120 // bits 27 (OSXSAVE) & 28 (256-bit AVX) | 156 // bits 27 (OSXSAVE) & 28 (256-bit AVX) |
| 121 if ((cpu_info[2] & 0x18000000) == 0x18000000) { | 157 if ((cpu_info[2] & 0x18000000) == 0x18000000) { |
| 122 // XMM state and YMM state enabled by the OS. | 158 // XMM state and YMM state enabled by the OS. |
| 123 return (xgetbv() & 0x6) == 0x6; | 159 return (xgetbv() & 0x6) == 0x6; |
| 124 } | 160 } |
| 125 } | 161 } |
| 126 if (feature == kAVX2) { | 162 if (feature == kAVX2) { |
| 127 if (x86CPUInfo(kAVX) && max_cpuid_value >= 7) { | 163 if (x86CPUInfo(kAVX) && max_cpuid_value >= 7) { |
| 128 GetCPUInfo(cpu_info, 7); | 164 GetCPUInfo(cpu_info, 7); |
| 129 return ((cpu_info[1] & 0x00000020) == 0x00000020); | 165 return !!(cpu_info[1] & (1 << 5)); |
| 130 } | 166 } |
| 131 } | 167 } |
| 132 return 0; | 168 return 0; |
| 133 } | 169 } |
| 134 VP8CPUInfo VP8GetCPUInfo = x86CPUInfo; | 170 VP8CPUInfo VP8GetCPUInfo = x86CPUInfo; |
| 135 #elif defined(WEBP_ANDROID_NEON) // NB: needs to be before generic NEON test. | 171 #elif defined(WEBP_ANDROID_NEON) // NB: needs to be before generic NEON test. |
| 136 static int AndroidCPUInfo(CPUFeature feature) { | 172 static int AndroidCPUInfo(CPUFeature feature) { |
| 137 const AndroidCpuFamily cpu_family = android_getCpuFamily(); | 173 const AndroidCpuFamily cpu_family = android_getCpuFamily(); |
| 138 const uint64_t cpu_features = android_getCpuFeatures(); | 174 const uint64_t cpu_features = android_getCpuFeatures(); |
| 139 if (feature == kNEON) { | 175 if (feature == kNEON) { |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 177 return 1; | 213 return 1; |
| 178 } else { | 214 } else { |
| 179 return 0; | 215 return 0; |
| 180 } | 216 } |
| 181 | 217 |
| 182 } | 218 } |
| 183 VP8CPUInfo VP8GetCPUInfo = mipsCPUInfo; | 219 VP8CPUInfo VP8GetCPUInfo = mipsCPUInfo; |
| 184 #else | 220 #else |
| 185 VP8CPUInfo VP8GetCPUInfo = NULL; | 221 VP8CPUInfo VP8GetCPUInfo = NULL; |
| 186 #endif | 222 #endif |
| 187 | |
| OLD | NEW |