1
0
mirror of https://github.com/google/cpu_features.git synced 2025-04-27 15:12:30 +02:00

Per arch build and inlining of cpuid_x86.

This commit is contained in:
Guillaume Chatelet 2019-01-15 10:52:56 +01:00
parent b6e7c32c90
commit e8e5610fc4
7 changed files with 98 additions and 117 deletions

View File

@ -21,38 +21,48 @@ option(BUILD_SHARED_LIBS "Build library as shared." OFF)
#
set(_HDRS
include/cpuinfo_aarch64.h
include/cpuinfo_arm.h
include/cpuinfo_mips.h
include/cpuinfo_ppc.h
include/cpuinfo_x86.h
include/cpu_features_macros.h
)
add_library(cpu_features
${_HDRS}
set(_SRCS
include/internal/bit_utils.h
include/internal/linux_features_aggregator.h
include/internal/cpuid_x86.h
include/internal/filesystem.h
include/internal/hwcaps.h
include/internal/stack_line_reader.h
include/internal/string_view.h
include/cpu_features_macros.h
src/linux_features_aggregator.c
src/cpuid_x86_clang_gcc.c
src/cpuid_x86_msvc.c
src/cpuinfo_aarch64.c
src/cpuinfo_arm.c
src/cpuinfo_mips.c
src/cpuinfo_ppc.c
src/cpuinfo_x86.c
src/filesystem.c
src/hwcaps.c
src/stack_line_reader.c
src/string_view.c
)
if(CMAKE_SYSTEM_PROCESSOR MATCHES "^mips")
list(APPEND _HDRS include/cpuinfo_mips.h)
list(APPEND _SRCS src/cpuinfo_mips.c)
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^arm")
list(APPEND _HDRS include/cpuinfo_arm.h)
list(APPEND _SRCS src/cpuinfo_arm.c)
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^aarch64")
list(APPEND _HDRS include/cpuinfo_aarch64.h)
list(APPEND _SRCS src/cpuinfo_aarch64.c)
elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
list(APPEND _HDRS include/cpuinfo_x86.h)
list(APPEND _HDRS include/internal/cpuid_x86.h)
list(APPEND _SRCS src/cpuinfo_x86.c)
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(powerpc|ppc)")
list(APPEND _HDRS include/cpuinfo_ppc.h)
list(APPEND _SRCS src/cpuinfo_ppc.c)
else()
message(SEND_ERROR "Unsupported architectures ${CMAKE_SYSTEM_PROCESSOR}")
endif()
add_library(cpu_features
${_HDRS}
${_SRCS}
)
target_include_directories(cpu_features
PUBLIC
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>

View File

@ -1,36 +0,0 @@
// Copyright 2017 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "internal/cpuid_x86.h"
#if defined(CPU_FEATURES_ARCH_X86)
#if defined(CPU_FEATURES_COMPILER_CLANG) || defined(CPU_FEATURES_COMPILER_GCC)
#include <cpuid.h>
Leaf CpuId(uint32_t leaf_id) {
Leaf leaf;
__cpuid_count(leaf_id, 0, leaf.eax, leaf.ebx, leaf.ecx, leaf.edx);
return leaf;
}
uint32_t GetXCR0Eax(void) {
uint32_t eax, edx;
__asm("XGETBV" : "=a"(eax), "=d"(edx) : "c"(0));
return eax;
}
#endif // defined(CPU_FEATURES_COMPILER_CLANG) ||
// defined(CPU_FEATURES_COMPILER_GCC)
#endif // defined(CPU_FEATURES_ARCH_X86)

View File

@ -1,34 +0,0 @@
// Copyright 2017 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "internal/cpuid_x86.h"
#if defined(CPU_FEATURES_ARCH_X86) && defined(CPU_FEATURES_COMPILER_MSC)
#include <immintrin.h>
#include <intrin.h> // For __cpuidex()
Leaf CpuId(uint32_t leaf_id) {
Leaf leaf;
int data[4];
__cpuid(data, leaf_id);
leaf.eax = data[0];
leaf.ebx = data[1];
leaf.ecx = data[2];
leaf.edx = data[3];
return leaf;
}
uint32_t GetXCR0Eax(void) { return _xgetbv(0); }
#endif // defined(CPU_FEATURES_ARCH_X86) && defined(CPU_FEATURES_COMPILER_MSC)

View File

@ -19,6 +19,54 @@
#include <stdbool.h>
#include <string.h>
#if !defined(CPU_FEATURES_ARCH_X86)
#error "Cannot compile cpuinfo_x86 on a non x86 platform."
#endif
////////////////////////////////////////////////////////////////////////////////
// Definitions for CpuId and GetXCR0Eax.
////////////////////////////////////////////////////////////////////////////////
#if defined(CPU_FEATURES_MOCK_CPUID_X86)
// Implementation will be provided by test/cpuinfo_x86_test.cc.
#elif defined(CPU_FEATURES_COMPILER_CLANG) || defined(CPU_FEATURES_COMPILER_GCC)
#include <cpuid.h>
Leaf CpuId(uint32_t leaf_id) {
Leaf leaf;
__cpuid_count(leaf_id, 0, leaf.eax, leaf.ebx, leaf.ecx, leaf.edx);
return leaf;
}
uint32_t GetXCR0Eax(void) {
uint32_t eax, edx;
__asm("XGETBV" : "=a"(eax), "=d"(edx) : "c"(0));
return eax;
}
#elif defined(CPU_FEATURES_COMPILER_MSC)
#include <immintrin.h>
#include <intrin.h> // For __cpuidex()
Leaf CpuId(uint32_t leaf_id) {
Leaf leaf;
int data[4];
__cpuid(data, leaf_id);
leaf.eax = data[0];
leaf.ebx = data[1];
leaf.ecx = data[2];
leaf.edx = data[3];
return leaf;
}
uint32_t GetXCR0Eax(void) { return _xgetbv(0); }
#else
#error "Unsupported compiler, x86 cpuid requires either GCC, Clang or MSVC."
#endif
static const Leaf kEmptyLeaf;
static Leaf SafeCpuId(uint32_t max_cpuid_leaf, uint32_t leaf_id) {

View File

@ -19,7 +19,9 @@
#include <sys/stat.h>
#include <sys/types.h>
#if defined(_MSC_VER)
#if defined(CPU_FEATURES_MOCK_FILESYSTEM)
// Implementation will be provided by test/filesystem_for_testing.cc.
#elif defined(_MSC_VER)
#include <io.h>
int CpuFeatures_OpenFile(const char* filename) {
return _open(filename, _O_RDONLY);

View File

@ -40,23 +40,13 @@
#define HWCAPS_REGULAR_LINUX
#endif
#if defined(HWCAPS_ANDROID_MIPS_OR_ARM) || defined(HWCAPS_REGULAR_LINUX)
#define HWCAPS_SUPPORTED
#endif
////////////////////////////////////////////////////////////////////////////////
// Implementation of GetElfHwcapFromGetauxval
////////////////////////////////////////////////////////////////////////////////
// On Linux we simply use getauxval.
#if defined(HWCAPS_REGULAR_LINUX)
#include <dlfcn.h>
#include <sys/auxv.h>
static unsigned long GetElfHwcapFromGetauxval(uint32_t hwcap_type) {
return getauxval(hwcap_type);
}
#endif // defined(HWCAPS_REGULAR_LINUX)
#if defined(CPU_FEATURES_MOCK_GET_ELF_HWCAP_FROM_GETAUXVAL)
// Implementation will be provided by test/hwcaps_for_testing.cc.
#elif defined(HWCAPS_ANDROID_MIPS_OR_ARM)
// On Android we probe the system's C library for a 'getauxval' function and
// call it if it exits, or return 0 for failure. This function is available
// since API level 20.
@ -71,7 +61,7 @@ static unsigned long GetElfHwcapFromGetauxval(uint32_t hwcap_type) {
// implementation does not parse /proc/self/auxv. Instead it depends on values
// that are passed by the kernel at process-init time to the C runtime
// initialization layer.
#if defined(HWCAPS_ANDROID_MIPS_OR_ARM)
#include <dlfcn.h>
#define AT_HWCAP 16
#define AT_HWCAP2 26
@ -101,12 +91,19 @@ static uint32_t GetElfHwcapFromGetauxval(uint32_t hwcap_type) {
dlclose(libc_handle);
return ret;
}
#endif // defined(HWCAPS_ANDROID_MIPS_OR_ARM)
#elif defined(CPU_FEATURES_OS_LINUX_OR_ANDROID)
// On Regular Linux we simply use getauxval.
#include <dlfcn.h>
#include <sys/auxv.h>
static unsigned long GetElfHwcapFromGetauxval(uint32_t hwcap_type) {
return getauxval(hwcap_type);
}
#else
#error "This platform does not provide hardware capabilities."
#endif
#if defined(HWCAPS_SUPPORTED)
////////////////////////////////////////////////////////////////////////////////
// Implementation of GetHardwareCapabilities for Android and Linux
////////////////////////////////////////////////////////////////////////////////
// Implementation of GetHardwareCapabilities for OS that provide
// GetElfHwcapFromGetauxval().
// Fallback when getauxval is not available, retrieves hwcaps from
// "/proc/self/auxv".
@ -174,14 +171,3 @@ PlatformType CpuFeatures_GetPlatformType(void) {
sizeof(type.base_platform));
return type;
}
#else // (defined(HWCAPS_SUPPORTED)
////////////////////////////////////////////////////////////////////////////////
// Implementation of GetHardwareCapabilities for unsupported platforms.
////////////////////////////////////////////////////////////////////////////////
const HardwareCapabilities kEmptyHardwareCapabilities;
HardwareCapabilities CpuFeatures_GetHardwareCapabilities(void) {
return kEmptyHardwareCapabilities;
}
#endif

View File

@ -13,8 +13,10 @@ add_definitions(-DCPU_FEATURES_TEST)
add_library(string_view ../src/string_view.c)
##------------------------------------------------------------------------------
add_library(filesystem_for_testing filesystem_for_testing.cc)
target_compile_definitions(filesystem_for_testing PUBLIC CPU_FEATURES_MOCK_FILESYSTEM)
##------------------------------------------------------------------------------
add_library(hwcaps_for_testing hwcaps_for_testing.cc)
target_compile_definitions(hwcaps_for_testing PUBLIC CPU_FEATURES_MOCK_GET_ELF_HWCAP_FROM_GETAUXVAL)
target_link_libraries(hwcaps_for_testing filesystem_for_testing)
##------------------------------------------------------------------------------
add_library(stack_line_reader ../src/stack_line_reader.c)
@ -54,9 +56,12 @@ target_link_libraries(linux_features_aggregator_test all_libraries)
add_test(NAME linux_features_aggregator_test COMMAND linux_features_aggregator_test)
##------------------------------------------------------------------------------
## cpuinfo_x86_test
if(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
add_executable(cpuinfo_x86_test cpuinfo_x86_test.cc ../src/cpuinfo_x86.c)
target_compile_definitions(stack_line_reader PUBLIC CPU_FEATURES_MOCK_CPUID_X86)
target_link_libraries(cpuinfo_x86_test all_libraries)
add_test(NAME cpuinfo_x86_test COMMAND cpuinfo_x86_test)
endif()
##------------------------------------------------------------------------------
## cpuinfo_arm_test
add_executable(cpuinfo_arm_test cpuinfo_arm_test.cc ../src/cpuinfo_arm.c)