| Index: third_party/libwebp/dsp/cpu.c
|
| diff --git a/third_party/libwebp/dsp/cpu.c b/third_party/libwebp/dsp/cpu.c
|
| index cbb08db90ae33840d381519930d5980178fbd8bf..b5583b6e9b3953cfe046b2badcb5340318da0918 100644
|
| --- a/third_party/libwebp/dsp/cpu.c
|
| +++ b/third_party/libwebp/dsp/cpu.c
|
| @@ -95,26 +95,62 @@ static WEBP_INLINE uint64_t xgetbv(void) {
|
| #endif
|
|
|
| #if defined(__i386__) || defined(__x86_64__) || defined(WEBP_MSC_SSE2)
|
| +
|
| +// helper function for run-time detection of slow SSSE3 platforms
|
| +static int CheckSlowModel(int info) {
|
| + // Table listing display models with longer latencies for the bsr instruction
|
| + // (ie 2 cycles vs 10/16 cycles) and some SSSE3 instructions like pshufb.
|
| + // Refer to Intel 64 and IA-32 Architectures Optimization Reference Manual.
|
| + static const uint8_t kSlowModels[] = {
|
| + 0x37, 0x4a, 0x4d, // Silvermont Microarchitecture
|
| + 0x1c, 0x26, 0x27 // Atom Microarchitecture
|
| + };
|
| + const uint32_t model = ((info & 0xf0000) >> 12) | ((info >> 4) & 0xf);
|
| + const uint32_t family = (info >> 8) & 0xf;
|
| + if (family == 0x06) {
|
| + size_t i;
|
| + for (i = 0; i < sizeof(kSlowModels) / sizeof(kSlowModels[0]); ++i) {
|
| + if (model == kSlowModels[i]) return 1;
|
| + }
|
| + }
|
| + return 0;
|
| +}
|
| +
|
| static int x86CPUInfo(CPUFeature feature) {
|
| int max_cpuid_value;
|
| int cpu_info[4];
|
| + int is_intel = 0;
|
|
|
| // get the highest feature value cpuid supports
|
| GetCPUInfo(cpu_info, 0);
|
| max_cpuid_value = cpu_info[0];
|
| if (max_cpuid_value < 1) {
|
| return 0;
|
| + } else {
|
| + const int VENDOR_ID_INTEL_EBX = 0x756e6547; // uneG
|
| + const int VENDOR_ID_INTEL_EDX = 0x49656e69; // Ieni
|
| + const int VENDOR_ID_INTEL_ECX = 0x6c65746e; // letn
|
| + is_intel = (cpu_info[1] == VENDOR_ID_INTEL_EBX &&
|
| + cpu_info[2] == VENDOR_ID_INTEL_ECX &&
|
| + cpu_info[3] == VENDOR_ID_INTEL_EDX); // genuine Intel?
|
| }
|
|
|
| GetCPUInfo(cpu_info, 1);
|
| if (feature == kSSE2) {
|
| - return 0 != (cpu_info[3] & 0x04000000);
|
| + return !!(cpu_info[3] & (1 << 26));
|
| }
|
| if (feature == kSSE3) {
|
| - return 0 != (cpu_info[2] & 0x00000001);
|
| + return !!(cpu_info[2] & (1 << 0));
|
| + }
|
| + if (feature == kSlowSSSE3) {
|
| + if (is_intel && (cpu_info[2] & (1 << 0))) { // SSSE3?
|
| + return CheckSlowModel(cpu_info[0]);
|
| + }
|
| + return 0;
|
| }
|
| +
|
| if (feature == kSSE4_1) {
|
| - return 0 != (cpu_info[2] & 0x00080000);
|
| + return !!(cpu_info[2] & (1 << 19));
|
| }
|
| if (feature == kAVX) {
|
| // bits 27 (OSXSAVE) & 28 (256-bit AVX)
|
| @@ -126,7 +162,7 @@ static int x86CPUInfo(CPUFeature feature) {
|
| if (feature == kAVX2) {
|
| if (x86CPUInfo(kAVX) && max_cpuid_value >= 7) {
|
| GetCPUInfo(cpu_info, 7);
|
| - return ((cpu_info[1] & 0x00000020) == 0x00000020);
|
| + return !!(cpu_info[1] & (1 << 5));
|
| }
|
| }
|
| return 0;
|
| @@ -184,4 +220,3 @@ VP8CPUInfo VP8GetCPUInfo = mipsCPUInfo;
|
| #else
|
| VP8CPUInfo VP8GetCPUInfo = NULL;
|
| #endif
|
| -
|
|
|