190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)/* 290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) * Copyright 2012 The LibYuv Project Authors. All rights reserved. 390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) * 490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) * Use of this source code is governed by a BSD-style license 590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) * that can be found in the LICENSE file in the root of the source 690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) * tree. An additional intellectual property rights grant can be found 790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) * in the file PATENTS. All contributing project authors may 890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) * be found in the AUTHORS file in the root of the source tree. 990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) */ 1090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 1190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include <stdlib.h> 12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include <string.h> 1390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 1490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "libyuv/basic_types.h" 1558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "libyuv/cpu_id.h" 1690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "libyuv/version.h" 1790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "../unit_test/unit_test.h" 1890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 1990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)namespace libyuv { 2090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 2190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)TEST_F(libyuvTest, TestCpuHas) { 2290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int cpu_flags = TestCpuFlag(-1); 2390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) printf("Cpu Flags %x\n", cpu_flags); 2490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int has_arm = TestCpuFlag(kCpuHasARM); 2590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) printf("Has ARM %x\n", has_arm); 2690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int has_neon = TestCpuFlag(kCpuHasNEON); 2790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) printf("Has NEON %x\n", has_neon); 2890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int has_x86 = TestCpuFlag(kCpuHasX86); 2990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) printf("Has X86 %x\n", has_x86); 3090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int has_sse2 = TestCpuFlag(kCpuHasSSE2); 313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) printf("Has SSE2 %x\n", has_sse2); 323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int has_ssse3 = TestCpuFlag(kCpuHasSSSE3); 333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) printf("Has SSSE3 %x\n", has_ssse3); 343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int has_sse41 = TestCpuFlag(kCpuHasSSE41); 3558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) printf("Has SSE4.1 %x\n", has_sse41); 363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int has_sse42 = TestCpuFlag(kCpuHasSSE42); 3758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) printf("Has SSE4.2 %x\n", has_sse42); 3858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) int has_avx = TestCpuFlag(kCpuHasAVX); 394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) printf("Has AVX %x\n", has_avx); 404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) int has_avx2 = TestCpuFlag(kCpuHasAVX2); 414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) printf("Has AVX2 %x\n", has_avx2); 4258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) int has_erms = TestCpuFlag(kCpuHasERMS); 4358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) printf("Has ERMS %x\n", has_erms); 4458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) int has_fma3 = TestCpuFlag(kCpuHasFMA3); 4568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) printf("Has FMA3 %x\n", has_fma3); 4668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) int has_mips = TestCpuFlag(kCpuHasMIPS); 4768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) printf("Has MIPS %x\n", has_mips); 4858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) int has_mips_dsp = TestCpuFlag(kCpuHasMIPS_DSP); 4958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) printf("Has MIPS DSP %x\n", has_mips_dsp); 5058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) int has_mips_dspr2 = TestCpuFlag(kCpuHasMIPS_DSPR2); 5158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) printf("Has MIPS DSPR2 %x\n", has_mips_dspr2); 5258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 5358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 5458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#if defined(__i386__) || defined(__x86_64__) || \ 553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) defined(_M_IX86) || defined(_M_X64) 563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)TEST_F(libyuvTest, TestCpuId) { 573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int has_x86 = TestCpuFlag(kCpuHasX86); 5858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (has_x86) { 5958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) uint32 cpu_info[4]; 603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Vendor ID: 6158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // AuthenticAMD AMD processor 6258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // CentaurHauls Centaur processor 634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // CyrixInstead Cyrix processor 644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // GenuineIntel Intel processor 654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // GenuineTMx86 Transmeta processor 6658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Geode by NSC National Semiconductor processor 6758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // NexGenDriven NexGen processor 6858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // RiseRiseRise Rise Technology processor 6968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // SiS SiS SiS SiS processor 7068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // UMC UMC UMC UMC processor 7168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) CpuId(0, 0, cpu_info); 7258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) cpu_info[0] = cpu_info[1]; // Reorder output 7358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) cpu_info[1] = cpu_info[3]; 7458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) cpu_info[3] = 0; 7558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) printf("Cpu Vendor: %s %x %x %x\n", reinterpret_cast<char*>(&cpu_info[0]), 7658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) cpu_info[0], cpu_info[1], cpu_info[2]); 7758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) EXPECT_EQ(12, strlen(reinterpret_cast<char*>(&cpu_info[0]))); 7858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // CPU Family and Model 803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // 3:0 - Stepping 8158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // 7:4 - Model 8258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // 11:8 - Family 834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // 13:12 - Processor Type 844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // 19:16 - Extended Model 854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // 27:20 - Extended Family 8658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) CpuId(1, 0, cpu_info); 8758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) int family = ((cpu_info[0] >> 8) & 0x0f) | ((cpu_info[0] >> 16) & 0xff0); 8858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) int model = ((cpu_info[0] >> 4) & 0x0f) | ((cpu_info[0] >> 12) & 0xf0); 8968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) printf("Cpu Family %d (0x%x), Model %d (0x%x)\n", family, family, 9068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) model, model); 9168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 9258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 9358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#endif 9458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 9558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)static int FileExists(const char* file_name) { 9658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) FILE* f = fopen(file_name, "r"); 9758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (!f) { 9858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return 0; 993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 1003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) fclose(f); 10158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return 1; 10258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 1034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TEST_F(libyuvTest, TestLinuxNeon) { 1054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (FileExists("../../unit_test/testdata/arm_v7.txt")) { 10658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) EXPECT_EQ(0, ArmCpuCaps("../../unit_test/testdata/arm_v7.txt")); 10758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) EXPECT_EQ(kCpuHasNEON, ArmCpuCaps("../../unit_test/testdata/tegra3.txt")); 10858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } else { 10968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) printf("WARNING: unable to load \"../../unit_test/testdata/arm_v7.txt\"\n"); 11068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 11168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#if defined(__linux__) && defined(__ARM_NEON__) 11258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) EXPECT_EQ(kCpuHasNEON, ArmCpuCaps("/proc/cpuinfo")); 11358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#endif 11458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 11558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 11658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} // namespace libyuv 11758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)