mirror of
https://github.com/google/cpu_features.git
synced 2025-04-28 07:23:37 +02:00
Merge pull request #49 from google/per_arch_build
Per arch build and inlining of cpuid_x86.
This commit is contained in:
commit
94838120ec
@ -20,38 +20,67 @@ option(BUILD_SHARED_LIBS "Build library as shared." OFF)
|
|||||||
# library : cpu_features
|
# library : cpu_features
|
||||||
#
|
#
|
||||||
|
|
||||||
|
include (CheckIncludeFile)
|
||||||
|
include (CheckSymbolExists)
|
||||||
|
|
||||||
|
check_include_file(dlfcn.h HAVE_DLFCN_H)
|
||||||
|
check_symbol_exists(getauxval "sys/auxv.h" HAVE_STRONG_GETAUXVAL)
|
||||||
|
|
||||||
set(_HDRS
|
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
|
include/cpu_features_macros.h
|
||||||
)
|
)
|
||||||
|
|
||||||
add_library(cpu_features
|
set(_SRCS
|
||||||
${_HDRS}
|
|
||||||
include/internal/bit_utils.h
|
include/internal/bit_utils.h
|
||||||
|
)
|
||||||
|
|
||||||
|
macro(add_linux_detection)
|
||||||
|
if(NOT UNIX)
|
||||||
|
message(FATAL_ERROR "Use of add_linux_detection() on non Linux-like OS")
|
||||||
|
endif()
|
||||||
|
list(APPEND _SRCS
|
||||||
include/internal/linux_features_aggregator.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/linux_features_aggregator.c
|
||||||
src/cpuid_x86_clang_gcc.c
|
include/internal/hwcaps.h
|
||||||
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/hwcaps.c
|
||||||
|
include/internal/filesystem.h
|
||||||
|
src/filesystem.c
|
||||||
|
include/internal/stack_line_reader.h
|
||||||
src/stack_line_reader.c
|
src/stack_line_reader.c
|
||||||
|
include/internal/string_view.h
|
||||||
src/string_view.c
|
src/string_view.c
|
||||||
)
|
)
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
if(CMAKE_SYSTEM_PROCESSOR MATCHES "^mips")
|
||||||
|
list(APPEND _HDRS include/cpuinfo_mips.h)
|
||||||
|
list(APPEND _SRCS src/cpuinfo_mips.c)
|
||||||
|
add_linux_detection()
|
||||||
|
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^arm")
|
||||||
|
list(APPEND _HDRS include/cpuinfo_arm.h)
|
||||||
|
list(APPEND _SRCS src/cpuinfo_arm.c)
|
||||||
|
add_linux_detection()
|
||||||
|
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^aarch64")
|
||||||
|
list(APPEND _HDRS include/cpuinfo_aarch64.h)
|
||||||
|
list(APPEND _SRCS src/cpuinfo_aarch64.c)
|
||||||
|
add_linux_detection()
|
||||||
|
elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" OR
|
||||||
|
CMAKE_SYSTEM_PROCESSOR STREQUAL "AMD64" OR
|
||||||
|
CMAKE_SYSTEM_PROCESSOR MATCHES "^i.86$")
|
||||||
|
list(APPEND _HDRS include/cpuinfo_x86.h)
|
||||||
|
list(APPEND _HDRS include/internal/cpuid_x86.h)
|
||||||
|
list(APPEND _SRCS src/cpuinfo_x86.c)
|
||||||
|
# add_linux_detection() is not needed on x86, we fetch the features directly
|
||||||
|
# from the CPU.
|
||||||
|
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(powerpc|ppc)")
|
||||||
|
list(APPEND _HDRS include/cpuinfo_ppc.h)
|
||||||
|
list(APPEND _SRCS src/cpuinfo_ppc.c)
|
||||||
|
add_linux_detection()
|
||||||
|
else()
|
||||||
|
message(FATAL_ERROR "Unsupported architectures ${CMAKE_SYSTEM_PROCESSOR}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
add_library(cpu_features ${_HDRS} ${_SRCS})
|
||||||
|
|
||||||
target_include_directories(cpu_features
|
target_include_directories(cpu_features
|
||||||
PUBLIC
|
PUBLIC
|
||||||
@ -61,8 +90,13 @@ target_include_directories(cpu_features
|
|||||||
include/internal
|
include/internal
|
||||||
)
|
)
|
||||||
set_target_properties(cpu_features PROPERTIES PUBLIC_HEADER "${_HDRS}")
|
set_target_properties(cpu_features PROPERTIES PUBLIC_HEADER "${_HDRS}")
|
||||||
target_compile_definitions(cpu_features
|
target_compile_definitions(cpu_features PUBLIC STACK_LINE_READER_BUFFER_SIZE=1024)
|
||||||
PUBLIC STACK_LINE_READER_BUFFER_SIZE=1024)
|
if(HAVE_DLFCN_H)
|
||||||
|
target_compile_definitions(cpu_features PRIVATE HAVE_DLFCN_H)
|
||||||
|
endif()
|
||||||
|
if(HAVE_STRONG_GETAUXVAL)
|
||||||
|
target_compile_definitions(cpu_features PRIVATE HAVE_STRONG_GETAUXVAL)
|
||||||
|
endif()
|
||||||
target_link_libraries(cpu_features PUBLIC ${CMAKE_DL_LIBS})
|
target_link_libraries(cpu_features PUBLIC ${CMAKE_DL_LIBS})
|
||||||
|
|
||||||
# The use of shared libraries is discouraged.
|
# The use of shared libraries is discouraged.
|
||||||
|
@ -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)
|
|
@ -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)
|
|
@ -19,6 +19,54 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <string.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 const Leaf kEmptyLeaf;
|
||||||
|
|
||||||
static Leaf SafeCpuId(uint32_t max_cpuid_leaf, uint32_t leaf_id) {
|
static Leaf SafeCpuId(uint32_t max_cpuid_leaf, uint32_t leaf_id) {
|
||||||
|
@ -19,7 +19,9 @@
|
|||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/types.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>
|
#include <io.h>
|
||||||
int CpuFeatures_OpenFile(const char* filename) {
|
int CpuFeatures_OpenFile(const char* filename) {
|
||||||
return _open(filename, _O_RDONLY);
|
return _open(filename, _O_RDONLY);
|
||||||
|
45
src/hwcaps.c
45
src/hwcaps.c
@ -31,32 +31,18 @@
|
|||||||
} while (0)
|
} while (0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(CPU_FEATURES_ARCH_MIPS) || defined(CPU_FEATURES_ARCH_ANY_ARM)
|
|
||||||
#define HWCAPS_ANDROID_MIPS_OR_ARM
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(CPU_FEATURES_OS_LINUX_OR_ANDROID) && \
|
|
||||||
!defined(HWCAPS_ANDROID_MIPS_OR_ARM)
|
|
||||||
#define HWCAPS_REGULAR_LINUX
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(HWCAPS_ANDROID_MIPS_OR_ARM) || defined(HWCAPS_REGULAR_LINUX)
|
|
||||||
#define HWCAPS_SUPPORTED
|
|
||||||
#endif
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// Implementation of GetElfHwcapFromGetauxval
|
// Implementation of GetElfHwcapFromGetauxval
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// On Linux we simply use getauxval.
|
#if defined(CPU_FEATURES_MOCK_GET_ELF_HWCAP_FROM_GETAUXVAL)
|
||||||
#if defined(HWCAPS_REGULAR_LINUX)
|
// Implementation will be provided by test/hwcaps_for_testing.cc.
|
||||||
#include <dlfcn.h>
|
#elif defined(HAVE_STRONG_GETAUXVAL)
|
||||||
#include <sys/auxv.h>
|
#include <sys/auxv.h>
|
||||||
static unsigned long GetElfHwcapFromGetauxval(uint32_t hwcap_type) {
|
static unsigned long GetElfHwcapFromGetauxval(uint32_t hwcap_type) {
|
||||||
return getauxval(hwcap_type);
|
return getauxval(hwcap_type);
|
||||||
}
|
}
|
||||||
#endif // defined(HWCAPS_REGULAR_LINUX)
|
#elif defined(HAVE_DLFCN_H)
|
||||||
|
|
||||||
// On Android we probe the system's C library for a 'getauxval' function and
|
// 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
|
// call it if it exits, or return 0 for failure. This function is available
|
||||||
// since API level 20.
|
// since API level 20.
|
||||||
@ -71,7 +57,7 @@ static unsigned long GetElfHwcapFromGetauxval(uint32_t hwcap_type) {
|
|||||||
// implementation does not parse /proc/self/auxv. Instead it depends on values
|
// 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
|
// that are passed by the kernel at process-init time to the C runtime
|
||||||
// initialization layer.
|
// initialization layer.
|
||||||
#if defined(HWCAPS_ANDROID_MIPS_OR_ARM)
|
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
#define AT_HWCAP 16
|
#define AT_HWCAP 16
|
||||||
#define AT_HWCAP2 26
|
#define AT_HWCAP2 26
|
||||||
@ -101,12 +87,12 @@ static uint32_t GetElfHwcapFromGetauxval(uint32_t hwcap_type) {
|
|||||||
dlclose(libc_handle);
|
dlclose(libc_handle);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#endif // defined(HWCAPS_ANDROID_MIPS_OR_ARM)
|
#else
|
||||||
|
#error "This platform does not provide hardware capabilities."
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(HWCAPS_SUPPORTED)
|
// Implementation of GetHardwareCapabilities for OS that provide
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
// GetElfHwcapFromGetauxval().
|
||||||
// Implementation of GetHardwareCapabilities for Android and Linux
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
// Fallback when getauxval is not available, retrieves hwcaps from
|
// Fallback when getauxval is not available, retrieves hwcaps from
|
||||||
// "/proc/self/auxv".
|
// "/proc/self/auxv".
|
||||||
@ -174,14 +160,3 @@ PlatformType CpuFeatures_GetPlatformType(void) {
|
|||||||
sizeof(type.base_platform));
|
sizeof(type.base_platform));
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
#else // (defined(HWCAPS_SUPPORTED)
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Implementation of GetHardwareCapabilities for unsupported platforms.
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
const HardwareCapabilities kEmptyHardwareCapabilities;
|
|
||||||
HardwareCapabilities CpuFeatures_GetHardwareCapabilities(void) {
|
|
||||||
return kEmptyHardwareCapabilities;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
@ -13,8 +13,10 @@ add_definitions(-DCPU_FEATURES_TEST)
|
|||||||
add_library(string_view ../src/string_view.c)
|
add_library(string_view ../src/string_view.c)
|
||||||
##------------------------------------------------------------------------------
|
##------------------------------------------------------------------------------
|
||||||
add_library(filesystem_for_testing filesystem_for_testing.cc)
|
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)
|
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)
|
target_link_libraries(hwcaps_for_testing filesystem_for_testing)
|
||||||
##------------------------------------------------------------------------------
|
##------------------------------------------------------------------------------
|
||||||
add_library(stack_line_reader ../src/stack_line_reader.c)
|
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)
|
add_test(NAME linux_features_aggregator_test COMMAND linux_features_aggregator_test)
|
||||||
##------------------------------------------------------------------------------
|
##------------------------------------------------------------------------------
|
||||||
## cpuinfo_x86_test
|
## cpuinfo_x86_test
|
||||||
|
if(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
|
||||||
add_executable(cpuinfo_x86_test cpuinfo_x86_test.cc ../src/cpuinfo_x86.c)
|
add_executable(cpuinfo_x86_test cpuinfo_x86_test.cc ../src/cpuinfo_x86.c)
|
||||||
|
target_compile_definitions(cpuinfo_x86_test PUBLIC CPU_FEATURES_MOCK_CPUID_X86)
|
||||||
target_link_libraries(cpuinfo_x86_test all_libraries)
|
target_link_libraries(cpuinfo_x86_test all_libraries)
|
||||||
add_test(NAME cpuinfo_x86_test COMMAND cpuinfo_x86_test)
|
add_test(NAME cpuinfo_x86_test COMMAND cpuinfo_x86_test)
|
||||||
|
endif()
|
||||||
##------------------------------------------------------------------------------
|
##------------------------------------------------------------------------------
|
||||||
## cpuinfo_arm_test
|
## cpuinfo_arm_test
|
||||||
add_executable(cpuinfo_arm_test cpuinfo_arm_test.cc ../src/cpuinfo_arm.c)
|
add_executable(cpuinfo_arm_test cpuinfo_arm_test.cc ../src/cpuinfo_arm.c)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user