diff --git a/README.chromium b/README.chromium index 6e57f3fdd..0ecd0692d 100644 --- a/README.chromium +++ b/README.chromium @@ -1,6 +1,6 @@ Name: libyuv URL: http://code.google.com/p/libyuv/ -Version: 258 +Version: 259 License: BSD License File: LICENSE diff --git a/include/libyuv/cpu_id.h b/include/libyuv/cpu_id.h index 9f00fc692..e0235f7c2 100644 --- a/include/libyuv/cpu_id.h +++ b/include/libyuv/cpu_id.h @@ -11,29 +11,6 @@ #ifndef INCLUDE_LIBYUV_CPU_ID_H_ #define INCLUDE_LIBYUV_CPU_ID_H_ -#ifdef _MSC_VER -#include // For __cpuid() -#endif - -// TODO(fbarchard): Use cpuid.h when gcc 4.4 is used on OSX and Linux. -#if (defined(__pic__) || defined(__APPLE__)) && defined(__i386__) -static __inline void __cpuid(int cpu_info[4], int info_type) { - asm volatile ( - "mov %%ebx, %%edi \n" - "cpuid \n" - "xchg %%edi, %%ebx \n" - : "=a"(cpu_info[0]), "=D"(cpu_info[1]), "=c"(cpu_info[2]), "=d"(cpu_info[3]) - : "a"(info_type)); -} -#elif defined(__i386__) || defined(__x86_64__) -static __inline void __cpuid(int cpu_info[4], int info_type) { - asm volatile ( - "cpuid \n" - : "=a"(cpu_info[0]), "=b"(cpu_info[1]), "=c"(cpu_info[2]), "=d"(cpu_info[3]) - : "a"(info_type)); -} -#endif - #ifdef __cplusplus namespace libyuv { extern "C" { @@ -68,6 +45,9 @@ static __inline int TestCpuFlag(int test_flag) { // MaskCpuFlags(0) to re-initialize all cpu detection. void MaskCpuFlags(int enable_flags); +// Low level cpuid for X86. Returns zeros on other CPUs. +void CpuId(int cpu_info[4], int info_type); + #ifdef __cplusplus } // extern "C" } // namespace libyuv diff --git a/include/libyuv/version.h b/include/libyuv/version.h index ce7a81d9f..e4686841f 100644 --- a/include/libyuv/version.h +++ b/include/libyuv/version.h @@ -11,7 +11,7 @@ #ifndef INCLUDE_LIBYUV_VERSION_H_ #define INCLUDE_LIBYUV_VERSION_H_ -#define LIBYUV_VERSION 258 +#define LIBYUV_VERSION 259 #endif // INCLUDE_LIBYUV_VERSION_H_ diff --git a/source/cpu_id.cc b/source/cpu_id.cc index a2f6c9b51..9832e0d8c 100644 --- a/source/cpu_id.cc +++ b/source/cpu_id.cc @@ -10,6 +10,10 @@ #include "libyuv/cpu_id.h" +#ifdef _MSC_VER +#include // For __cpuid() +#endif + #include // For getenv() // For ArmCpuCaps() but unittested on all platforms @@ -18,11 +22,40 @@ #include "libyuv/basic_types.h" // For CPU_X86 +// TODO(fbarchard): Use cpuid.h when gcc 4.4 is used on OSX and Linux. +#if (defined(__pic__) || defined(__APPLE__)) && defined(__i386__) +static __inline void __cpuid(int cpu_info[4], int info_type) { + asm volatile ( + "mov %%ebx, %%edi \n" + "cpuid \n" + "xchg %%edi, %%ebx \n" + : "=a"(cpu_info[0]), "=D"(cpu_info[1]), "=c"(cpu_info[2]), "=d"(cpu_info[3]) + : "a"(info_type)); +} +#elif defined(__i386__) || defined(__x86_64__) +static __inline void __cpuid(int cpu_info[4], int info_type) { + asm volatile ( + "cpuid \n" + : "=a"(cpu_info[0]), "=b"(cpu_info[1]), "=c"(cpu_info[2]), "=d"(cpu_info[3]) + : "a"(info_type)); +} +#endif + #ifdef __cplusplus namespace libyuv { extern "C" { #endif +// Low level cpuid for X86. Returns zeros on other CPUs. +void CpuId(int cpu_info[4], int info_type) { +#if defined(__i386__) || defined(__x86_64__) || \ + defined(_M_IX86) || defined(_M_X64) + __cpuid(cpu_info, info_type); +#else + cpu_info[0] = cpu_info[1] = cpu_info[2] = cpu_info[3] = 0; +#endif +} + // based on libvpx arm_cpudetect.c // For Arm, but testable on any CPU int ArmCpuCaps(const char* cpuinfoname) { diff --git a/unit_test/cpu_test.cc b/unit_test/cpu_test.cc index 7def0b375..d9682cb0b 100644 --- a/unit_test/cpu_test.cc +++ b/unit_test/cpu_test.cc @@ -37,30 +37,42 @@ TEST_F(libyuvTest, TestCpuHas) { printf("Has NEON %d\n", has_neon); } -// Known Vendor IDs are: -// AuthenticAMD AMD processor -// CentaurHauls Centaur processor -// CyrixInstead Cyrix processor -// GenuineIntel Intel processor -// GenuineTMx86 Transmeta processor -// Geode by NSC National Semiconductor processor -// NexGenDriven NexGen processor -// RiseRiseRise Rise Technology processor -// SiS SiS SiS SiS processor -// UMC UMC UMC UMC processor #if defined(__i386__) || defined(__x86_64__) || \ defined(_M_IX86) || defined(_M_X64) TEST_F(libyuvTest, TestCpuId) { int has_x86 = TestCpuFlag(kCpuHasX86); if (has_x86) { int cpu_info[4]; - __cpuid(cpu_info, 0); + // Vendor ID: + // AuthenticAMD AMD processor + // CentaurHauls Centaur processor + // CyrixInstead Cyrix processor + // GenuineIntel Intel processor + // GenuineTMx86 Transmeta processor + // Geode by NSC National Semiconductor processor + // NexGenDriven NexGen processor + // RiseRiseRise Rise Technology processor + // SiS SiS SiS SiS processor + // UMC UMC UMC UMC processor + CpuId(cpu_info, 0); cpu_info[0] = cpu_info[1]; // Reorder output cpu_info[1] = cpu_info[3]; cpu_info[2] = cpu_info[2]; cpu_info[3] = 0; printf("Cpu Vendor: %s\n", reinterpret_cast(&cpu_info[0])); EXPECT_EQ(12, strlen(reinterpret_cast(&cpu_info[0]))); + + // CPU Family and Model + // 3:0 - Stepping + // 7:4 - Model + // 11:8 - Family + // 13:12 - Processor Type + // 19:16 - Extended Model + // 27:20 - Extended Family + CpuId(cpu_info, 1); + int family = ((cpu_info[0] >> 8) & 0x0f) | ((cpu_info[0] >> 16) & 0xff0); + int model = ((cpu_info[0] >> 4) & 0x0f) | ((cpu_info[0] >> 12) & 0xf0); + printf("Cpu Family %d, Model %d\n", family, model); } } #endif