Commit 0b0e9179 authored by fbarchard@google.com's avatar fbarchard@google.com

libyuv::CpuId as function to reduce header dependencies

BUG=none
TEST=libyuv_unittest.exe  --gtest_catch_exceptions=0 --gtest_filter=*Cpu*
Review URL: https://webrtc-codereview.appspot.com/566007

git-svn-id: http://libyuv.googlecode.com/svn/trunk@259 16f28f9a-4ce2-e073-06de-1de4eb20be90
parent d05ec087
Name: libyuv Name: libyuv
URL: http://code.google.com/p/libyuv/ URL: http://code.google.com/p/libyuv/
Version: 258 Version: 259
License: BSD License: BSD
License File: LICENSE License File: LICENSE
......
...@@ -11,29 +11,6 @@ ...@@ -11,29 +11,6 @@
#ifndef INCLUDE_LIBYUV_CPU_ID_H_ #ifndef INCLUDE_LIBYUV_CPU_ID_H_
#define INCLUDE_LIBYUV_CPU_ID_H_ #define INCLUDE_LIBYUV_CPU_ID_H_
#ifdef _MSC_VER
#include <intrin.h> // 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 #ifdef __cplusplus
namespace libyuv { namespace libyuv {
extern "C" { extern "C" {
...@@ -68,6 +45,9 @@ static __inline int TestCpuFlag(int test_flag) { ...@@ -68,6 +45,9 @@ static __inline int TestCpuFlag(int test_flag) {
// MaskCpuFlags(0) to re-initialize all cpu detection. // MaskCpuFlags(0) to re-initialize all cpu detection.
void MaskCpuFlags(int enable_flags); 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 #ifdef __cplusplus
} // extern "C" } // extern "C"
} // namespace libyuv } // namespace libyuv
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
#ifndef INCLUDE_LIBYUV_VERSION_H_ #ifndef INCLUDE_LIBYUV_VERSION_H_
#define INCLUDE_LIBYUV_VERSION_H_ #define INCLUDE_LIBYUV_VERSION_H_
#define LIBYUV_VERSION 258 #define LIBYUV_VERSION 259
#endif // INCLUDE_LIBYUV_VERSION_H_ #endif // INCLUDE_LIBYUV_VERSION_H_
...@@ -10,6 +10,10 @@ ...@@ -10,6 +10,10 @@
#include "libyuv/cpu_id.h" #include "libyuv/cpu_id.h"
#ifdef _MSC_VER
#include <intrin.h> // For __cpuid()
#endif
#include <stdlib.h> // For getenv() #include <stdlib.h> // For getenv()
// For ArmCpuCaps() but unittested on all platforms // For ArmCpuCaps() but unittested on all platforms
...@@ -18,11 +22,40 @@ ...@@ -18,11 +22,40 @@
#include "libyuv/basic_types.h" // For CPU_X86 #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 #ifdef __cplusplus
namespace libyuv { namespace libyuv {
extern "C" { extern "C" {
#endif #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 // based on libvpx arm_cpudetect.c
// For Arm, but testable on any CPU // For Arm, but testable on any CPU
int ArmCpuCaps(const char* cpuinfoname) { int ArmCpuCaps(const char* cpuinfoname) {
......
...@@ -37,30 +37,42 @@ TEST_F(libyuvTest, TestCpuHas) { ...@@ -37,30 +37,42 @@ TEST_F(libyuvTest, TestCpuHas) {
printf("Has NEON %d\n", has_neon); 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__) || \ #if defined(__i386__) || defined(__x86_64__) || \
defined(_M_IX86) || defined(_M_X64) defined(_M_IX86) || defined(_M_X64)
TEST_F(libyuvTest, TestCpuId) { TEST_F(libyuvTest, TestCpuId) {
int has_x86 = TestCpuFlag(kCpuHasX86); int has_x86 = TestCpuFlag(kCpuHasX86);
if (has_x86) { if (has_x86) {
int cpu_info[4]; 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[0] = cpu_info[1]; // Reorder output
cpu_info[1] = cpu_info[3]; cpu_info[1] = cpu_info[3];
cpu_info[2] = cpu_info[2]; cpu_info[2] = cpu_info[2];
cpu_info[3] = 0; cpu_info[3] = 0;
printf("Cpu Vendor: %s\n", reinterpret_cast<char*>(&cpu_info[0])); printf("Cpu Vendor: %s\n", reinterpret_cast<char*>(&cpu_info[0]));
EXPECT_EQ(12, strlen(reinterpret_cast<char*>(&cpu_info[0]))); EXPECT_EQ(12, strlen(reinterpret_cast<char*>(&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 #endif
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment