mirror of
https://github.com/xmrig/xmrig.git
synced 2024-12-22 19:49:36 +00:00
Removed libcpuid support.
This commit is contained in:
parent
1d5592f303
commit
ab45794b7c
26 changed files with 13 additions and 3886 deletions
|
@ -1,7 +1,6 @@
|
||||||
cmake_minimum_required(VERSION 2.8)
|
cmake_minimum_required(VERSION 2.8)
|
||||||
project(xmrig)
|
project(xmrig)
|
||||||
|
|
||||||
option(WITH_LIBCPUID "Enable libcpuid support" ON)
|
|
||||||
option(WITH_HWLOC "Enable hwloc support" ON)
|
option(WITH_HWLOC "Enable hwloc support" ON)
|
||||||
option(WITH_CN_LITE "Enable CryptoNight-Lite algorithms family" ON)
|
option(WITH_CN_LITE "Enable CryptoNight-Lite algorithms family" ON)
|
||||||
option(WITH_CN_HEAVY "Enable CryptoNight-Heavy algorithms family" ON)
|
option(WITH_CN_HEAVY "Enable CryptoNight-Heavy algorithms family" ON)
|
||||||
|
@ -205,7 +204,7 @@ if (WITH_DEBUG_LOG)
|
||||||
add_definitions(/DAPP_DEBUG)
|
add_definitions(/DAPP_DEBUG)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
add_executable(${CMAKE_PROJECT_NAME} ${HEADERS} ${SOURCES} ${SOURCES_OS} ${SOURCES_CPUID} ${HEADERS_CRYPTO} ${SOURCES_CRYPTO} ${SOURCES_SYSLOG} ${TLS_SOURCES} ${XMRIG_ASM_SOURCES})
|
add_executable(${CMAKE_PROJECT_NAME} ${HEADERS} ${SOURCES} ${SOURCES_OS} ${HEADERS_CRYPTO} ${SOURCES_CRYPTO} ${SOURCES_SYSLOG} ${TLS_SOURCES} ${XMRIG_ASM_SOURCES})
|
||||||
target_link_libraries(${CMAKE_PROJECT_NAME} ${XMRIG_ASM_LIBRARY} ${OPENSSL_LIBRARIES} ${UV_LIBRARIES} ${EXTRA_LIBS} ${CPUID_LIB} ${ARGON2_LIBRARY} ${ETHASH_LIBRARY})
|
target_link_libraries(${CMAKE_PROJECT_NAME} ${XMRIG_ASM_LIBRARY} ${OPENSSL_LIBRARIES} ${UV_LIBRARIES} ${EXTRA_LIBS} ${CPUID_LIB} ${ARGON2_LIBRARY} ${ETHASH_LIBRARY})
|
||||||
|
|
||||||
if (WIN32)
|
if (WIN32)
|
||||||
|
|
|
@ -18,7 +18,6 @@ endif()
|
||||||
|
|
||||||
if (ARM_TARGET AND ARM_TARGET GREATER 6)
|
if (ARM_TARGET AND ARM_TARGET GREATER 6)
|
||||||
set(XMRIG_ARM ON)
|
set(XMRIG_ARM ON)
|
||||||
set(WITH_LIBCPUID OFF)
|
|
||||||
add_definitions(/DXMRIG_ARM)
|
add_definitions(/DXMRIG_ARM)
|
||||||
|
|
||||||
message(STATUS "Use ARM_TARGET=${ARM_TARGET} (${CMAKE_SYSTEM_PROCESSOR})")
|
message(STATUS "Use ARM_TARGET=${ARM_TARGET} (${CMAKE_SYSTEM_PROCESSOR})")
|
||||||
|
|
38
src/3rdparty/libcpuid/CMakeLists.txt
vendored
38
src/3rdparty/libcpuid/CMakeLists.txt
vendored
|
@ -1,38 +0,0 @@
|
||||||
cmake_minimum_required (VERSION 2.8)
|
|
||||||
project (cpuid C)
|
|
||||||
|
|
||||||
add_definitions(/DVERSION="0.4.0")
|
|
||||||
|
|
||||||
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Os")
|
|
||||||
|
|
||||||
set(HEADERS
|
|
||||||
libcpuid.h
|
|
||||||
libcpuid_types.h
|
|
||||||
libcpuid_constants.h
|
|
||||||
libcpuid_internal.h
|
|
||||||
amd_code_t.h
|
|
||||||
intel_code_t.h
|
|
||||||
recog_amd.h
|
|
||||||
recog_intel.h
|
|
||||||
asm-bits.h
|
|
||||||
libcpuid_util.h
|
|
||||||
)
|
|
||||||
|
|
||||||
set(SOURCES
|
|
||||||
cpuid_main.c
|
|
||||||
asm-bits.c
|
|
||||||
recog_amd.c
|
|
||||||
recog_intel.c
|
|
||||||
libcpuid_util.c
|
|
||||||
)
|
|
||||||
|
|
||||||
if (CMAKE_CL_64)
|
|
||||||
enable_language(ASM_MASM)
|
|
||||||
set(SOURCES_ASM masm-x64.asm)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
add_library(cpuid STATIC
|
|
||||||
${HEADERS}
|
|
||||||
${SOURCES}
|
|
||||||
${SOURCES_ASM}
|
|
||||||
)
|
|
39
src/3rdparty/libcpuid/amd_code_t.h
vendored
39
src/3rdparty/libcpuid/amd_code_t.h
vendored
|
@ -1,39 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2016 Veselin Georgiev,
|
|
||||||
* anrieffNOSPAM @ mgail_DOT.com (convert to gmail)
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions
|
|
||||||
* are met:
|
|
||||||
*
|
|
||||||
* 1. Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
||||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
||||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
||||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
||||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
||||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
||||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This file contains a list of internal codes we use in detection. It is
|
|
||||||
* of no external use and isn't a complete list of AMD products.
|
|
||||||
*/
|
|
||||||
CODE2(OPTERON_800, 1000),
|
|
||||||
CODE(PHENOM),
|
|
||||||
CODE(PHENOM2),
|
|
||||||
CODE(FUSION_C),
|
|
||||||
CODE(FUSION_E),
|
|
||||||
CODE(FUSION_EA),
|
|
||||||
CODE(FUSION_Z),
|
|
||||||
CODE(FUSION_A),
|
|
||||||
|
|
836
src/3rdparty/libcpuid/asm-bits.c
vendored
836
src/3rdparty/libcpuid/asm-bits.c
vendored
|
@ -1,836 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2008 Veselin Georgiev,
|
|
||||||
* anrieffNOSPAM @ mgail_DOT.com (convert to gmail)
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions
|
|
||||||
* are met:
|
|
||||||
*
|
|
||||||
* 1. Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
||||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
||||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
||||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
||||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
||||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
||||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "libcpuid.h"
|
|
||||||
#include "asm-bits.h"
|
|
||||||
|
|
||||||
int cpuid_exists_by_eflags(void)
|
|
||||||
{
|
|
||||||
#if defined(PLATFORM_X64)
|
|
||||||
return 1; /* CPUID is always present on the x86_64 */
|
|
||||||
#elif defined(PLATFORM_X86)
|
|
||||||
# if defined(COMPILER_GCC) || defined(COMPILER_CLANG)
|
|
||||||
int result;
|
|
||||||
__asm __volatile(
|
|
||||||
" pushfl\n"
|
|
||||||
" pop %%eax\n"
|
|
||||||
" mov %%eax, %%ecx\n"
|
|
||||||
" xor $0x200000, %%eax\n"
|
|
||||||
" push %%eax\n"
|
|
||||||
" popfl\n"
|
|
||||||
" pushfl\n"
|
|
||||||
" pop %%eax\n"
|
|
||||||
" xor %%ecx, %%eax\n"
|
|
||||||
" mov %%eax, %0\n"
|
|
||||||
" push %%ecx\n"
|
|
||||||
" popfl\n"
|
|
||||||
: "=m"(result)
|
|
||||||
: :"eax", "ecx", "memory");
|
|
||||||
return (result != 0);
|
|
||||||
# elif defined(COMPILER_MICROSOFT)
|
|
||||||
int result;
|
|
||||||
__asm {
|
|
||||||
pushfd
|
|
||||||
pop eax
|
|
||||||
mov ecx, eax
|
|
||||||
xor eax, 0x200000
|
|
||||||
push eax
|
|
||||||
popfd
|
|
||||||
pushfd
|
|
||||||
pop eax
|
|
||||||
xor eax, ecx
|
|
||||||
mov result, eax
|
|
||||||
push ecx
|
|
||||||
popfd
|
|
||||||
};
|
|
||||||
return (result != 0);
|
|
||||||
# else
|
|
||||||
return 0;
|
|
||||||
# endif /* COMPILER_MICROSOFT */
|
|
||||||
#elif defined(PLATFORM_ARM)
|
|
||||||
return 0;
|
|
||||||
#else
|
|
||||||
return 0;
|
|
||||||
#endif /* PLATFORM_X86 */
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef INLINE_ASM_SUPPORTED
|
|
||||||
/*
|
|
||||||
* with MSVC/AMD64, the exec_cpuid() and cpu_rdtsc() functions
|
|
||||||
* are implemented in separate .asm files. Otherwise, use inline assembly
|
|
||||||
*/
|
|
||||||
void exec_cpuid(uint32_t *regs)
|
|
||||||
{
|
|
||||||
# if defined(COMPILER_GCC) || defined(COMPILER_CLANG)
|
|
||||||
# ifdef PLATFORM_X64
|
|
||||||
__asm __volatile(
|
|
||||||
" mov %0, %%rdi\n"
|
|
||||||
|
|
||||||
" push %%rbx\n"
|
|
||||||
" push %%rcx\n"
|
|
||||||
" push %%rdx\n"
|
|
||||||
|
|
||||||
" mov (%%rdi), %%eax\n"
|
|
||||||
" mov 4(%%rdi), %%ebx\n"
|
|
||||||
" mov 8(%%rdi), %%ecx\n"
|
|
||||||
" mov 12(%%rdi), %%edx\n"
|
|
||||||
|
|
||||||
" cpuid\n"
|
|
||||||
|
|
||||||
" movl %%eax, (%%rdi)\n"
|
|
||||||
" movl %%ebx, 4(%%rdi)\n"
|
|
||||||
" movl %%ecx, 8(%%rdi)\n"
|
|
||||||
" movl %%edx, 12(%%rdi)\n"
|
|
||||||
" pop %%rdx\n"
|
|
||||||
" pop %%rcx\n"
|
|
||||||
" pop %%rbx\n"
|
|
||||||
:
|
|
||||||
:"m"(regs)
|
|
||||||
:"memory", "eax", "rdi"
|
|
||||||
);
|
|
||||||
# elif defined(PLATFORM_X86)
|
|
||||||
__asm __volatile(
|
|
||||||
" mov %0, %%edi\n"
|
|
||||||
|
|
||||||
" push %%ebx\n"
|
|
||||||
" push %%ecx\n"
|
|
||||||
" push %%edx\n"
|
|
||||||
|
|
||||||
" mov (%%edi), %%eax\n"
|
|
||||||
" mov 4(%%edi), %%ebx\n"
|
|
||||||
" mov 8(%%edi), %%ecx\n"
|
|
||||||
" mov 12(%%edi), %%edx\n"
|
|
||||||
|
|
||||||
" cpuid\n"
|
|
||||||
|
|
||||||
" mov %%eax, (%%edi)\n"
|
|
||||||
" mov %%ebx, 4(%%edi)\n"
|
|
||||||
" mov %%ecx, 8(%%edi)\n"
|
|
||||||
" mov %%edx, 12(%%edi)\n"
|
|
||||||
" pop %%edx\n"
|
|
||||||
" pop %%ecx\n"
|
|
||||||
" pop %%ebx\n"
|
|
||||||
:
|
|
||||||
:"m"(regs)
|
|
||||||
:"memory", "eax", "edi"
|
|
||||||
);
|
|
||||||
# elif defined(PLATFORM_ARM)
|
|
||||||
# endif /* COMPILER_GCC */
|
|
||||||
#else
|
|
||||||
# ifdef COMPILER_MICROSOFT
|
|
||||||
__asm {
|
|
||||||
push ebx
|
|
||||||
push ecx
|
|
||||||
push edx
|
|
||||||
push edi
|
|
||||||
mov edi, regs
|
|
||||||
|
|
||||||
mov eax, [edi]
|
|
||||||
mov ebx, [edi+4]
|
|
||||||
mov ecx, [edi+8]
|
|
||||||
mov edx, [edi+12]
|
|
||||||
|
|
||||||
cpuid
|
|
||||||
|
|
||||||
mov [edi], eax
|
|
||||||
mov [edi+4], ebx
|
|
||||||
mov [edi+8], ecx
|
|
||||||
mov [edi+12], edx
|
|
||||||
|
|
||||||
pop edi
|
|
||||||
pop edx
|
|
||||||
pop ecx
|
|
||||||
pop ebx
|
|
||||||
}
|
|
||||||
# else
|
|
||||||
# error "Unsupported compiler"
|
|
||||||
# endif /* COMPILER_MICROSOFT */
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#endif /* INLINE_ASSEMBLY_SUPPORTED */
|
|
||||||
|
|
||||||
#ifdef INLINE_ASM_SUPPORTED
|
|
||||||
void cpu_rdtsc(uint64_t* result)
|
|
||||||
{
|
|
||||||
uint32_t low_part, hi_part;
|
|
||||||
#if defined(COMPILER_GCC) || defined(COMPILER_CLANG)
|
|
||||||
#ifdef PLATFORM_ARM
|
|
||||||
low_part = 0;
|
|
||||||
hi_part = 0;
|
|
||||||
#else
|
|
||||||
__asm __volatile (
|
|
||||||
" rdtsc\n"
|
|
||||||
" mov %%eax, %0\n"
|
|
||||||
" mov %%edx, %1\n"
|
|
||||||
:"=m"(low_part), "=m"(hi_part)::"memory", "eax", "edx"
|
|
||||||
);
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
# ifdef COMPILER_MICROSOFT
|
|
||||||
__asm {
|
|
||||||
rdtsc
|
|
||||||
mov low_part, eax
|
|
||||||
mov hi_part, edx
|
|
||||||
};
|
|
||||||
# else
|
|
||||||
# error "Unsupported compiler"
|
|
||||||
# endif /* COMPILER_MICROSOFT */
|
|
||||||
#endif /* COMPILER_GCC */
|
|
||||||
*result = (uint64_t)low_part + (((uint64_t) hi_part) << 32);
|
|
||||||
}
|
|
||||||
#endif /* INLINE_ASM_SUPPORTED */
|
|
||||||
|
|
||||||
#ifdef INLINE_ASM_SUPPORTED
|
|
||||||
void busy_sse_loop(int cycles)
|
|
||||||
{
|
|
||||||
# if defined(COMPILER_GCC) || defined(COMPILER_CLANG)
|
|
||||||
#ifndef __APPLE__
|
|
||||||
# define XALIGN ".balign 16\n"
|
|
||||||
#else
|
|
||||||
# define XALIGN ".align 4\n"
|
|
||||||
#endif
|
|
||||||
#ifdef PLATFORM_ARM
|
|
||||||
#else
|
|
||||||
__asm __volatile (
|
|
||||||
" xorps %%xmm0, %%xmm0\n"
|
|
||||||
" xorps %%xmm1, %%xmm1\n"
|
|
||||||
" xorps %%xmm2, %%xmm2\n"
|
|
||||||
" xorps %%xmm3, %%xmm3\n"
|
|
||||||
" xorps %%xmm4, %%xmm4\n"
|
|
||||||
" xorps %%xmm5, %%xmm5\n"
|
|
||||||
" xorps %%xmm6, %%xmm6\n"
|
|
||||||
" xorps %%xmm7, %%xmm7\n"
|
|
||||||
XALIGN
|
|
||||||
/* ".bsLoop:\n" */
|
|
||||||
"1:\n"
|
|
||||||
// 0:
|
|
||||||
" addps %%xmm1, %%xmm0\n"
|
|
||||||
" addps %%xmm2, %%xmm1\n"
|
|
||||||
" addps %%xmm3, %%xmm2\n"
|
|
||||||
" addps %%xmm4, %%xmm3\n"
|
|
||||||
" addps %%xmm5, %%xmm4\n"
|
|
||||||
" addps %%xmm6, %%xmm5\n"
|
|
||||||
" addps %%xmm7, %%xmm6\n"
|
|
||||||
" addps %%xmm0, %%xmm7\n"
|
|
||||||
// 1:
|
|
||||||
" addps %%xmm1, %%xmm0\n"
|
|
||||||
" addps %%xmm2, %%xmm1\n"
|
|
||||||
" addps %%xmm3, %%xmm2\n"
|
|
||||||
" addps %%xmm4, %%xmm3\n"
|
|
||||||
" addps %%xmm5, %%xmm4\n"
|
|
||||||
" addps %%xmm6, %%xmm5\n"
|
|
||||||
" addps %%xmm7, %%xmm6\n"
|
|
||||||
" addps %%xmm0, %%xmm7\n"
|
|
||||||
// 2:
|
|
||||||
" addps %%xmm1, %%xmm0\n"
|
|
||||||
" addps %%xmm2, %%xmm1\n"
|
|
||||||
" addps %%xmm3, %%xmm2\n"
|
|
||||||
" addps %%xmm4, %%xmm3\n"
|
|
||||||
" addps %%xmm5, %%xmm4\n"
|
|
||||||
" addps %%xmm6, %%xmm5\n"
|
|
||||||
" addps %%xmm7, %%xmm6\n"
|
|
||||||
" addps %%xmm0, %%xmm7\n"
|
|
||||||
// 3:
|
|
||||||
" addps %%xmm1, %%xmm0\n"
|
|
||||||
" addps %%xmm2, %%xmm1\n"
|
|
||||||
" addps %%xmm3, %%xmm2\n"
|
|
||||||
" addps %%xmm4, %%xmm3\n"
|
|
||||||
" addps %%xmm5, %%xmm4\n"
|
|
||||||
" addps %%xmm6, %%xmm5\n"
|
|
||||||
" addps %%xmm7, %%xmm6\n"
|
|
||||||
" addps %%xmm0, %%xmm7\n"
|
|
||||||
// 4:
|
|
||||||
" addps %%xmm1, %%xmm0\n"
|
|
||||||
" addps %%xmm2, %%xmm1\n"
|
|
||||||
" addps %%xmm3, %%xmm2\n"
|
|
||||||
" addps %%xmm4, %%xmm3\n"
|
|
||||||
" addps %%xmm5, %%xmm4\n"
|
|
||||||
" addps %%xmm6, %%xmm5\n"
|
|
||||||
" addps %%xmm7, %%xmm6\n"
|
|
||||||
" addps %%xmm0, %%xmm7\n"
|
|
||||||
// 5:
|
|
||||||
" addps %%xmm1, %%xmm0\n"
|
|
||||||
" addps %%xmm2, %%xmm1\n"
|
|
||||||
" addps %%xmm3, %%xmm2\n"
|
|
||||||
" addps %%xmm4, %%xmm3\n"
|
|
||||||
" addps %%xmm5, %%xmm4\n"
|
|
||||||
" addps %%xmm6, %%xmm5\n"
|
|
||||||
" addps %%xmm7, %%xmm6\n"
|
|
||||||
" addps %%xmm0, %%xmm7\n"
|
|
||||||
// 6:
|
|
||||||
" addps %%xmm1, %%xmm0\n"
|
|
||||||
" addps %%xmm2, %%xmm1\n"
|
|
||||||
" addps %%xmm3, %%xmm2\n"
|
|
||||||
" addps %%xmm4, %%xmm3\n"
|
|
||||||
" addps %%xmm5, %%xmm4\n"
|
|
||||||
" addps %%xmm6, %%xmm5\n"
|
|
||||||
" addps %%xmm7, %%xmm6\n"
|
|
||||||
" addps %%xmm0, %%xmm7\n"
|
|
||||||
// 7:
|
|
||||||
" addps %%xmm1, %%xmm0\n"
|
|
||||||
" addps %%xmm2, %%xmm1\n"
|
|
||||||
" addps %%xmm3, %%xmm2\n"
|
|
||||||
" addps %%xmm4, %%xmm3\n"
|
|
||||||
" addps %%xmm5, %%xmm4\n"
|
|
||||||
" addps %%xmm6, %%xmm5\n"
|
|
||||||
" addps %%xmm7, %%xmm6\n"
|
|
||||||
" addps %%xmm0, %%xmm7\n"
|
|
||||||
// 8:
|
|
||||||
" addps %%xmm1, %%xmm0\n"
|
|
||||||
" addps %%xmm2, %%xmm1\n"
|
|
||||||
" addps %%xmm3, %%xmm2\n"
|
|
||||||
" addps %%xmm4, %%xmm3\n"
|
|
||||||
" addps %%xmm5, %%xmm4\n"
|
|
||||||
" addps %%xmm6, %%xmm5\n"
|
|
||||||
" addps %%xmm7, %%xmm6\n"
|
|
||||||
" addps %%xmm0, %%xmm7\n"
|
|
||||||
// 9:
|
|
||||||
" addps %%xmm1, %%xmm0\n"
|
|
||||||
" addps %%xmm2, %%xmm1\n"
|
|
||||||
" addps %%xmm3, %%xmm2\n"
|
|
||||||
" addps %%xmm4, %%xmm3\n"
|
|
||||||
" addps %%xmm5, %%xmm4\n"
|
|
||||||
" addps %%xmm6, %%xmm5\n"
|
|
||||||
" addps %%xmm7, %%xmm6\n"
|
|
||||||
" addps %%xmm0, %%xmm7\n"
|
|
||||||
//10:
|
|
||||||
" addps %%xmm1, %%xmm0\n"
|
|
||||||
" addps %%xmm2, %%xmm1\n"
|
|
||||||
" addps %%xmm3, %%xmm2\n"
|
|
||||||
" addps %%xmm4, %%xmm3\n"
|
|
||||||
" addps %%xmm5, %%xmm4\n"
|
|
||||||
" addps %%xmm6, %%xmm5\n"
|
|
||||||
" addps %%xmm7, %%xmm6\n"
|
|
||||||
" addps %%xmm0, %%xmm7\n"
|
|
||||||
//11:
|
|
||||||
" addps %%xmm1, %%xmm0\n"
|
|
||||||
" addps %%xmm2, %%xmm1\n"
|
|
||||||
" addps %%xmm3, %%xmm2\n"
|
|
||||||
" addps %%xmm4, %%xmm3\n"
|
|
||||||
" addps %%xmm5, %%xmm4\n"
|
|
||||||
" addps %%xmm6, %%xmm5\n"
|
|
||||||
" addps %%xmm7, %%xmm6\n"
|
|
||||||
" addps %%xmm0, %%xmm7\n"
|
|
||||||
//12:
|
|
||||||
" addps %%xmm1, %%xmm0\n"
|
|
||||||
" addps %%xmm2, %%xmm1\n"
|
|
||||||
" addps %%xmm3, %%xmm2\n"
|
|
||||||
" addps %%xmm4, %%xmm3\n"
|
|
||||||
" addps %%xmm5, %%xmm4\n"
|
|
||||||
" addps %%xmm6, %%xmm5\n"
|
|
||||||
" addps %%xmm7, %%xmm6\n"
|
|
||||||
" addps %%xmm0, %%xmm7\n"
|
|
||||||
//13:
|
|
||||||
" addps %%xmm1, %%xmm0\n"
|
|
||||||
" addps %%xmm2, %%xmm1\n"
|
|
||||||
" addps %%xmm3, %%xmm2\n"
|
|
||||||
" addps %%xmm4, %%xmm3\n"
|
|
||||||
" addps %%xmm5, %%xmm4\n"
|
|
||||||
" addps %%xmm6, %%xmm5\n"
|
|
||||||
" addps %%xmm7, %%xmm6\n"
|
|
||||||
" addps %%xmm0, %%xmm7\n"
|
|
||||||
//14:
|
|
||||||
" addps %%xmm1, %%xmm0\n"
|
|
||||||
" addps %%xmm2, %%xmm1\n"
|
|
||||||
" addps %%xmm3, %%xmm2\n"
|
|
||||||
" addps %%xmm4, %%xmm3\n"
|
|
||||||
" addps %%xmm5, %%xmm4\n"
|
|
||||||
" addps %%xmm6, %%xmm5\n"
|
|
||||||
" addps %%xmm7, %%xmm6\n"
|
|
||||||
" addps %%xmm0, %%xmm7\n"
|
|
||||||
//15:
|
|
||||||
" addps %%xmm1, %%xmm0\n"
|
|
||||||
" addps %%xmm2, %%xmm1\n"
|
|
||||||
" addps %%xmm3, %%xmm2\n"
|
|
||||||
" addps %%xmm4, %%xmm3\n"
|
|
||||||
" addps %%xmm5, %%xmm4\n"
|
|
||||||
" addps %%xmm6, %%xmm5\n"
|
|
||||||
" addps %%xmm7, %%xmm6\n"
|
|
||||||
" addps %%xmm0, %%xmm7\n"
|
|
||||||
//16:
|
|
||||||
" addps %%xmm1, %%xmm0\n"
|
|
||||||
" addps %%xmm2, %%xmm1\n"
|
|
||||||
" addps %%xmm3, %%xmm2\n"
|
|
||||||
" addps %%xmm4, %%xmm3\n"
|
|
||||||
" addps %%xmm5, %%xmm4\n"
|
|
||||||
" addps %%xmm6, %%xmm5\n"
|
|
||||||
" addps %%xmm7, %%xmm6\n"
|
|
||||||
" addps %%xmm0, %%xmm7\n"
|
|
||||||
//17:
|
|
||||||
" addps %%xmm1, %%xmm0\n"
|
|
||||||
" addps %%xmm2, %%xmm1\n"
|
|
||||||
" addps %%xmm3, %%xmm2\n"
|
|
||||||
" addps %%xmm4, %%xmm3\n"
|
|
||||||
" addps %%xmm5, %%xmm4\n"
|
|
||||||
" addps %%xmm6, %%xmm5\n"
|
|
||||||
" addps %%xmm7, %%xmm6\n"
|
|
||||||
" addps %%xmm0, %%xmm7\n"
|
|
||||||
//18:
|
|
||||||
" addps %%xmm1, %%xmm0\n"
|
|
||||||
" addps %%xmm2, %%xmm1\n"
|
|
||||||
" addps %%xmm3, %%xmm2\n"
|
|
||||||
" addps %%xmm4, %%xmm3\n"
|
|
||||||
" addps %%xmm5, %%xmm4\n"
|
|
||||||
" addps %%xmm6, %%xmm5\n"
|
|
||||||
" addps %%xmm7, %%xmm6\n"
|
|
||||||
" addps %%xmm0, %%xmm7\n"
|
|
||||||
//19:
|
|
||||||
" addps %%xmm1, %%xmm0\n"
|
|
||||||
" addps %%xmm2, %%xmm1\n"
|
|
||||||
" addps %%xmm3, %%xmm2\n"
|
|
||||||
" addps %%xmm4, %%xmm3\n"
|
|
||||||
" addps %%xmm5, %%xmm4\n"
|
|
||||||
" addps %%xmm6, %%xmm5\n"
|
|
||||||
" addps %%xmm7, %%xmm6\n"
|
|
||||||
" addps %%xmm0, %%xmm7\n"
|
|
||||||
//20:
|
|
||||||
" addps %%xmm1, %%xmm0\n"
|
|
||||||
" addps %%xmm2, %%xmm1\n"
|
|
||||||
" addps %%xmm3, %%xmm2\n"
|
|
||||||
" addps %%xmm4, %%xmm3\n"
|
|
||||||
" addps %%xmm5, %%xmm4\n"
|
|
||||||
" addps %%xmm6, %%xmm5\n"
|
|
||||||
" addps %%xmm7, %%xmm6\n"
|
|
||||||
" addps %%xmm0, %%xmm7\n"
|
|
||||||
//21:
|
|
||||||
" addps %%xmm1, %%xmm0\n"
|
|
||||||
" addps %%xmm2, %%xmm1\n"
|
|
||||||
" addps %%xmm3, %%xmm2\n"
|
|
||||||
" addps %%xmm4, %%xmm3\n"
|
|
||||||
" addps %%xmm5, %%xmm4\n"
|
|
||||||
" addps %%xmm6, %%xmm5\n"
|
|
||||||
" addps %%xmm7, %%xmm6\n"
|
|
||||||
" addps %%xmm0, %%xmm7\n"
|
|
||||||
//22:
|
|
||||||
" addps %%xmm1, %%xmm0\n"
|
|
||||||
" addps %%xmm2, %%xmm1\n"
|
|
||||||
" addps %%xmm3, %%xmm2\n"
|
|
||||||
" addps %%xmm4, %%xmm3\n"
|
|
||||||
" addps %%xmm5, %%xmm4\n"
|
|
||||||
" addps %%xmm6, %%xmm5\n"
|
|
||||||
" addps %%xmm7, %%xmm6\n"
|
|
||||||
" addps %%xmm0, %%xmm7\n"
|
|
||||||
//23:
|
|
||||||
" addps %%xmm1, %%xmm0\n"
|
|
||||||
" addps %%xmm2, %%xmm1\n"
|
|
||||||
" addps %%xmm3, %%xmm2\n"
|
|
||||||
" addps %%xmm4, %%xmm3\n"
|
|
||||||
" addps %%xmm5, %%xmm4\n"
|
|
||||||
" addps %%xmm6, %%xmm5\n"
|
|
||||||
" addps %%xmm7, %%xmm6\n"
|
|
||||||
" addps %%xmm0, %%xmm7\n"
|
|
||||||
//24:
|
|
||||||
" addps %%xmm1, %%xmm0\n"
|
|
||||||
" addps %%xmm2, %%xmm1\n"
|
|
||||||
" addps %%xmm3, %%xmm2\n"
|
|
||||||
" addps %%xmm4, %%xmm3\n"
|
|
||||||
" addps %%xmm5, %%xmm4\n"
|
|
||||||
" addps %%xmm6, %%xmm5\n"
|
|
||||||
" addps %%xmm7, %%xmm6\n"
|
|
||||||
" addps %%xmm0, %%xmm7\n"
|
|
||||||
//25:
|
|
||||||
" addps %%xmm1, %%xmm0\n"
|
|
||||||
" addps %%xmm2, %%xmm1\n"
|
|
||||||
" addps %%xmm3, %%xmm2\n"
|
|
||||||
" addps %%xmm4, %%xmm3\n"
|
|
||||||
" addps %%xmm5, %%xmm4\n"
|
|
||||||
" addps %%xmm6, %%xmm5\n"
|
|
||||||
" addps %%xmm7, %%xmm6\n"
|
|
||||||
" addps %%xmm0, %%xmm7\n"
|
|
||||||
//26:
|
|
||||||
" addps %%xmm1, %%xmm0\n"
|
|
||||||
" addps %%xmm2, %%xmm1\n"
|
|
||||||
" addps %%xmm3, %%xmm2\n"
|
|
||||||
" addps %%xmm4, %%xmm3\n"
|
|
||||||
" addps %%xmm5, %%xmm4\n"
|
|
||||||
" addps %%xmm6, %%xmm5\n"
|
|
||||||
" addps %%xmm7, %%xmm6\n"
|
|
||||||
" addps %%xmm0, %%xmm7\n"
|
|
||||||
//27:
|
|
||||||
" addps %%xmm1, %%xmm0\n"
|
|
||||||
" addps %%xmm2, %%xmm1\n"
|
|
||||||
" addps %%xmm3, %%xmm2\n"
|
|
||||||
" addps %%xmm4, %%xmm3\n"
|
|
||||||
" addps %%xmm5, %%xmm4\n"
|
|
||||||
" addps %%xmm6, %%xmm5\n"
|
|
||||||
" addps %%xmm7, %%xmm6\n"
|
|
||||||
" addps %%xmm0, %%xmm7\n"
|
|
||||||
//28:
|
|
||||||
" addps %%xmm1, %%xmm0\n"
|
|
||||||
" addps %%xmm2, %%xmm1\n"
|
|
||||||
" addps %%xmm3, %%xmm2\n"
|
|
||||||
" addps %%xmm4, %%xmm3\n"
|
|
||||||
" addps %%xmm5, %%xmm4\n"
|
|
||||||
" addps %%xmm6, %%xmm5\n"
|
|
||||||
" addps %%xmm7, %%xmm6\n"
|
|
||||||
" addps %%xmm0, %%xmm7\n"
|
|
||||||
//29:
|
|
||||||
" addps %%xmm1, %%xmm0\n"
|
|
||||||
" addps %%xmm2, %%xmm1\n"
|
|
||||||
" addps %%xmm3, %%xmm2\n"
|
|
||||||
" addps %%xmm4, %%xmm3\n"
|
|
||||||
" addps %%xmm5, %%xmm4\n"
|
|
||||||
" addps %%xmm6, %%xmm5\n"
|
|
||||||
" addps %%xmm7, %%xmm6\n"
|
|
||||||
" addps %%xmm0, %%xmm7\n"
|
|
||||||
//30:
|
|
||||||
" addps %%xmm1, %%xmm0\n"
|
|
||||||
" addps %%xmm2, %%xmm1\n"
|
|
||||||
" addps %%xmm3, %%xmm2\n"
|
|
||||||
" addps %%xmm4, %%xmm3\n"
|
|
||||||
" addps %%xmm5, %%xmm4\n"
|
|
||||||
" addps %%xmm6, %%xmm5\n"
|
|
||||||
" addps %%xmm7, %%xmm6\n"
|
|
||||||
" addps %%xmm0, %%xmm7\n"
|
|
||||||
//31:
|
|
||||||
" addps %%xmm1, %%xmm0\n"
|
|
||||||
" addps %%xmm2, %%xmm1\n"
|
|
||||||
" addps %%xmm3, %%xmm2\n"
|
|
||||||
" addps %%xmm4, %%xmm3\n"
|
|
||||||
" addps %%xmm5, %%xmm4\n"
|
|
||||||
" addps %%xmm6, %%xmm5\n"
|
|
||||||
" addps %%xmm7, %%xmm6\n"
|
|
||||||
" addps %%xmm0, %%xmm7\n"
|
|
||||||
|
|
||||||
" dec %%eax\n"
|
|
||||||
/* "jnz .bsLoop\n" */
|
|
||||||
" jnz 1b\n"
|
|
||||||
::"a"(cycles)
|
|
||||||
);
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
# ifdef COMPILER_MICROSOFT
|
|
||||||
__asm {
|
|
||||||
mov eax, cycles
|
|
||||||
xorps xmm0, xmm0
|
|
||||||
xorps xmm1, xmm1
|
|
||||||
xorps xmm2, xmm2
|
|
||||||
xorps xmm3, xmm3
|
|
||||||
xorps xmm4, xmm4
|
|
||||||
xorps xmm5, xmm5
|
|
||||||
xorps xmm6, xmm6
|
|
||||||
xorps xmm7, xmm7
|
|
||||||
//--
|
|
||||||
align 16
|
|
||||||
bsLoop:
|
|
||||||
// 0:
|
|
||||||
addps xmm0, xmm1
|
|
||||||
addps xmm1, xmm2
|
|
||||||
addps xmm2, xmm3
|
|
||||||
addps xmm3, xmm4
|
|
||||||
addps xmm4, xmm5
|
|
||||||
addps xmm5, xmm6
|
|
||||||
addps xmm6, xmm7
|
|
||||||
addps xmm7, xmm0
|
|
||||||
// 1:
|
|
||||||
addps xmm0, xmm1
|
|
||||||
addps xmm1, xmm2
|
|
||||||
addps xmm2, xmm3
|
|
||||||
addps xmm3, xmm4
|
|
||||||
addps xmm4, xmm5
|
|
||||||
addps xmm5, xmm6
|
|
||||||
addps xmm6, xmm7
|
|
||||||
addps xmm7, xmm0
|
|
||||||
// 2:
|
|
||||||
addps xmm0, xmm1
|
|
||||||
addps xmm1, xmm2
|
|
||||||
addps xmm2, xmm3
|
|
||||||
addps xmm3, xmm4
|
|
||||||
addps xmm4, xmm5
|
|
||||||
addps xmm5, xmm6
|
|
||||||
addps xmm6, xmm7
|
|
||||||
addps xmm7, xmm0
|
|
||||||
// 3:
|
|
||||||
addps xmm0, xmm1
|
|
||||||
addps xmm1, xmm2
|
|
||||||
addps xmm2, xmm3
|
|
||||||
addps xmm3, xmm4
|
|
||||||
addps xmm4, xmm5
|
|
||||||
addps xmm5, xmm6
|
|
||||||
addps xmm6, xmm7
|
|
||||||
addps xmm7, xmm0
|
|
||||||
// 4:
|
|
||||||
addps xmm0, xmm1
|
|
||||||
addps xmm1, xmm2
|
|
||||||
addps xmm2, xmm3
|
|
||||||
addps xmm3, xmm4
|
|
||||||
addps xmm4, xmm5
|
|
||||||
addps xmm5, xmm6
|
|
||||||
addps xmm6, xmm7
|
|
||||||
addps xmm7, xmm0
|
|
||||||
// 5:
|
|
||||||
addps xmm0, xmm1
|
|
||||||
addps xmm1, xmm2
|
|
||||||
addps xmm2, xmm3
|
|
||||||
addps xmm3, xmm4
|
|
||||||
addps xmm4, xmm5
|
|
||||||
addps xmm5, xmm6
|
|
||||||
addps xmm6, xmm7
|
|
||||||
addps xmm7, xmm0
|
|
||||||
// 6:
|
|
||||||
addps xmm0, xmm1
|
|
||||||
addps xmm1, xmm2
|
|
||||||
addps xmm2, xmm3
|
|
||||||
addps xmm3, xmm4
|
|
||||||
addps xmm4, xmm5
|
|
||||||
addps xmm5, xmm6
|
|
||||||
addps xmm6, xmm7
|
|
||||||
addps xmm7, xmm0
|
|
||||||
// 7:
|
|
||||||
addps xmm0, xmm1
|
|
||||||
addps xmm1, xmm2
|
|
||||||
addps xmm2, xmm3
|
|
||||||
addps xmm3, xmm4
|
|
||||||
addps xmm4, xmm5
|
|
||||||
addps xmm5, xmm6
|
|
||||||
addps xmm6, xmm7
|
|
||||||
addps xmm7, xmm0
|
|
||||||
// 8:
|
|
||||||
addps xmm0, xmm1
|
|
||||||
addps xmm1, xmm2
|
|
||||||
addps xmm2, xmm3
|
|
||||||
addps xmm3, xmm4
|
|
||||||
addps xmm4, xmm5
|
|
||||||
addps xmm5, xmm6
|
|
||||||
addps xmm6, xmm7
|
|
||||||
addps xmm7, xmm0
|
|
||||||
// 9:
|
|
||||||
addps xmm0, xmm1
|
|
||||||
addps xmm1, xmm2
|
|
||||||
addps xmm2, xmm3
|
|
||||||
addps xmm3, xmm4
|
|
||||||
addps xmm4, xmm5
|
|
||||||
addps xmm5, xmm6
|
|
||||||
addps xmm6, xmm7
|
|
||||||
addps xmm7, xmm0
|
|
||||||
// 10:
|
|
||||||
addps xmm0, xmm1
|
|
||||||
addps xmm1, xmm2
|
|
||||||
addps xmm2, xmm3
|
|
||||||
addps xmm3, xmm4
|
|
||||||
addps xmm4, xmm5
|
|
||||||
addps xmm5, xmm6
|
|
||||||
addps xmm6, xmm7
|
|
||||||
addps xmm7, xmm0
|
|
||||||
// 11:
|
|
||||||
addps xmm0, xmm1
|
|
||||||
addps xmm1, xmm2
|
|
||||||
addps xmm2, xmm3
|
|
||||||
addps xmm3, xmm4
|
|
||||||
addps xmm4, xmm5
|
|
||||||
addps xmm5, xmm6
|
|
||||||
addps xmm6, xmm7
|
|
||||||
addps xmm7, xmm0
|
|
||||||
// 12:
|
|
||||||
addps xmm0, xmm1
|
|
||||||
addps xmm1, xmm2
|
|
||||||
addps xmm2, xmm3
|
|
||||||
addps xmm3, xmm4
|
|
||||||
addps xmm4, xmm5
|
|
||||||
addps xmm5, xmm6
|
|
||||||
addps xmm6, xmm7
|
|
||||||
addps xmm7, xmm0
|
|
||||||
// 13:
|
|
||||||
addps xmm0, xmm1
|
|
||||||
addps xmm1, xmm2
|
|
||||||
addps xmm2, xmm3
|
|
||||||
addps xmm3, xmm4
|
|
||||||
addps xmm4, xmm5
|
|
||||||
addps xmm5, xmm6
|
|
||||||
addps xmm6, xmm7
|
|
||||||
addps xmm7, xmm0
|
|
||||||
// 14:
|
|
||||||
addps xmm0, xmm1
|
|
||||||
addps xmm1, xmm2
|
|
||||||
addps xmm2, xmm3
|
|
||||||
addps xmm3, xmm4
|
|
||||||
addps xmm4, xmm5
|
|
||||||
addps xmm5, xmm6
|
|
||||||
addps xmm6, xmm7
|
|
||||||
addps xmm7, xmm0
|
|
||||||
// 15:
|
|
||||||
addps xmm0, xmm1
|
|
||||||
addps xmm1, xmm2
|
|
||||||
addps xmm2, xmm3
|
|
||||||
addps xmm3, xmm4
|
|
||||||
addps xmm4, xmm5
|
|
||||||
addps xmm5, xmm6
|
|
||||||
addps xmm6, xmm7
|
|
||||||
addps xmm7, xmm0
|
|
||||||
// 16:
|
|
||||||
addps xmm0, xmm1
|
|
||||||
addps xmm1, xmm2
|
|
||||||
addps xmm2, xmm3
|
|
||||||
addps xmm3, xmm4
|
|
||||||
addps xmm4, xmm5
|
|
||||||
addps xmm5, xmm6
|
|
||||||
addps xmm6, xmm7
|
|
||||||
addps xmm7, xmm0
|
|
||||||
// 17:
|
|
||||||
addps xmm0, xmm1
|
|
||||||
addps xmm1, xmm2
|
|
||||||
addps xmm2, xmm3
|
|
||||||
addps xmm3, xmm4
|
|
||||||
addps xmm4, xmm5
|
|
||||||
addps xmm5, xmm6
|
|
||||||
addps xmm6, xmm7
|
|
||||||
addps xmm7, xmm0
|
|
||||||
// 18:
|
|
||||||
addps xmm0, xmm1
|
|
||||||
addps xmm1, xmm2
|
|
||||||
addps xmm2, xmm3
|
|
||||||
addps xmm3, xmm4
|
|
||||||
addps xmm4, xmm5
|
|
||||||
addps xmm5, xmm6
|
|
||||||
addps xmm6, xmm7
|
|
||||||
addps xmm7, xmm0
|
|
||||||
// 19:
|
|
||||||
addps xmm0, xmm1
|
|
||||||
addps xmm1, xmm2
|
|
||||||
addps xmm2, xmm3
|
|
||||||
addps xmm3, xmm4
|
|
||||||
addps xmm4, xmm5
|
|
||||||
addps xmm5, xmm6
|
|
||||||
addps xmm6, xmm7
|
|
||||||
addps xmm7, xmm0
|
|
||||||
// 20:
|
|
||||||
addps xmm0, xmm1
|
|
||||||
addps xmm1, xmm2
|
|
||||||
addps xmm2, xmm3
|
|
||||||
addps xmm3, xmm4
|
|
||||||
addps xmm4, xmm5
|
|
||||||
addps xmm5, xmm6
|
|
||||||
addps xmm6, xmm7
|
|
||||||
addps xmm7, xmm0
|
|
||||||
// 21:
|
|
||||||
addps xmm0, xmm1
|
|
||||||
addps xmm1, xmm2
|
|
||||||
addps xmm2, xmm3
|
|
||||||
addps xmm3, xmm4
|
|
||||||
addps xmm4, xmm5
|
|
||||||
addps xmm5, xmm6
|
|
||||||
addps xmm6, xmm7
|
|
||||||
addps xmm7, xmm0
|
|
||||||
// 22:
|
|
||||||
addps xmm0, xmm1
|
|
||||||
addps xmm1, xmm2
|
|
||||||
addps xmm2, xmm3
|
|
||||||
addps xmm3, xmm4
|
|
||||||
addps xmm4, xmm5
|
|
||||||
addps xmm5, xmm6
|
|
||||||
addps xmm6, xmm7
|
|
||||||
addps xmm7, xmm0
|
|
||||||
// 23:
|
|
||||||
addps xmm0, xmm1
|
|
||||||
addps xmm1, xmm2
|
|
||||||
addps xmm2, xmm3
|
|
||||||
addps xmm3, xmm4
|
|
||||||
addps xmm4, xmm5
|
|
||||||
addps xmm5, xmm6
|
|
||||||
addps xmm6, xmm7
|
|
||||||
addps xmm7, xmm0
|
|
||||||
// 24:
|
|
||||||
addps xmm0, xmm1
|
|
||||||
addps xmm1, xmm2
|
|
||||||
addps xmm2, xmm3
|
|
||||||
addps xmm3, xmm4
|
|
||||||
addps xmm4, xmm5
|
|
||||||
addps xmm5, xmm6
|
|
||||||
addps xmm6, xmm7
|
|
||||||
addps xmm7, xmm0
|
|
||||||
// 25:
|
|
||||||
addps xmm0, xmm1
|
|
||||||
addps xmm1, xmm2
|
|
||||||
addps xmm2, xmm3
|
|
||||||
addps xmm3, xmm4
|
|
||||||
addps xmm4, xmm5
|
|
||||||
addps xmm5, xmm6
|
|
||||||
addps xmm6, xmm7
|
|
||||||
addps xmm7, xmm0
|
|
||||||
// 26:
|
|
||||||
addps xmm0, xmm1
|
|
||||||
addps xmm1, xmm2
|
|
||||||
addps xmm2, xmm3
|
|
||||||
addps xmm3, xmm4
|
|
||||||
addps xmm4, xmm5
|
|
||||||
addps xmm5, xmm6
|
|
||||||
addps xmm6, xmm7
|
|
||||||
addps xmm7, xmm0
|
|
||||||
// 27:
|
|
||||||
addps xmm0, xmm1
|
|
||||||
addps xmm1, xmm2
|
|
||||||
addps xmm2, xmm3
|
|
||||||
addps xmm3, xmm4
|
|
||||||
addps xmm4, xmm5
|
|
||||||
addps xmm5, xmm6
|
|
||||||
addps xmm6, xmm7
|
|
||||||
addps xmm7, xmm0
|
|
||||||
// 28:
|
|
||||||
addps xmm0, xmm1
|
|
||||||
addps xmm1, xmm2
|
|
||||||
addps xmm2, xmm3
|
|
||||||
addps xmm3, xmm4
|
|
||||||
addps xmm4, xmm5
|
|
||||||
addps xmm5, xmm6
|
|
||||||
addps xmm6, xmm7
|
|
||||||
addps xmm7, xmm0
|
|
||||||
// 29:
|
|
||||||
addps xmm0, xmm1
|
|
||||||
addps xmm1, xmm2
|
|
||||||
addps xmm2, xmm3
|
|
||||||
addps xmm3, xmm4
|
|
||||||
addps xmm4, xmm5
|
|
||||||
addps xmm5, xmm6
|
|
||||||
addps xmm6, xmm7
|
|
||||||
addps xmm7, xmm0
|
|
||||||
// 30:
|
|
||||||
addps xmm0, xmm1
|
|
||||||
addps xmm1, xmm2
|
|
||||||
addps xmm2, xmm3
|
|
||||||
addps xmm3, xmm4
|
|
||||||
addps xmm4, xmm5
|
|
||||||
addps xmm5, xmm6
|
|
||||||
addps xmm6, xmm7
|
|
||||||
addps xmm7, xmm0
|
|
||||||
// 31:
|
|
||||||
addps xmm0, xmm1
|
|
||||||
addps xmm1, xmm2
|
|
||||||
addps xmm2, xmm3
|
|
||||||
addps xmm3, xmm4
|
|
||||||
addps xmm4, xmm5
|
|
||||||
addps xmm5, xmm6
|
|
||||||
addps xmm6, xmm7
|
|
||||||
addps xmm7, xmm0
|
|
||||||
//----------------------
|
|
||||||
dec eax
|
|
||||||
jnz bsLoop
|
|
||||||
}
|
|
||||||
# else
|
|
||||||
# error "Unsupported compiler"
|
|
||||||
# endif /* COMPILER_MICROSOFT */
|
|
||||||
#endif /* COMPILER_GCC */
|
|
||||||
}
|
|
||||||
#endif /* INLINE_ASSEMBLY_SUPPORTED */
|
|
71
src/3rdparty/libcpuid/asm-bits.h
vendored
71
src/3rdparty/libcpuid/asm-bits.h
vendored
|
@ -1,71 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2008 Veselin Georgiev,
|
|
||||||
* anrieffNOSPAM @ mgail_DOT.com (convert to gmail)
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions
|
|
||||||
* are met:
|
|
||||||
*
|
|
||||||
* 1. Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
||||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
||||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
||||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
||||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
||||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
||||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
#ifndef __ASM_BITS_H__
|
|
||||||
#define __ASM_BITS_H__
|
|
||||||
#include "libcpuid.h"
|
|
||||||
|
|
||||||
/* Determine Compiler: */
|
|
||||||
#if defined(_MSC_VER)
|
|
||||||
#if !defined(COMPILER_MICROSOFT)
|
|
||||||
# define COMPILER_MICROSOFT
|
|
||||||
#endif
|
|
||||||
#elif defined(__GNUC__)
|
|
||||||
#if !defined(COMPILER_GCC)
|
|
||||||
# define COMPILER_GCC
|
|
||||||
#endif
|
|
||||||
#elif defined(__clang__)
|
|
||||||
#if !defined(COMPILER_CLANG)
|
|
||||||
# define COMPILER_CLANG
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Determine Platform */
|
|
||||||
#if defined(__x86_64__) || defined(_M_AMD64)
|
|
||||||
#if !defined(PLATFORM_X64)
|
|
||||||
# define PLATFORM_X64
|
|
||||||
#endif
|
|
||||||
#elif defined(__i386__) || defined(_M_IX86)
|
|
||||||
#if !defined(PLATFORM_X86)
|
|
||||||
# define PLATFORM_X86
|
|
||||||
#endif
|
|
||||||
#elif defined(__ARMEL__)
|
|
||||||
#if !defined(PLATFORM_ARM)
|
|
||||||
# define PLATFORM_ARM
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Under Windows/AMD64 with MSVC, inline assembly isn't supported */
|
|
||||||
#if (((defined(COMPILER_GCC) || defined(COMPILER_CLANG))) && \
|
|
||||||
(defined(PLATFORM_X64) || defined(PLATFORM_X86) || defined(PLATFORM_ARM))) || \
|
|
||||||
(defined(COMPILER_MICROSOFT) && defined(PLATFORM_X86))
|
|
||||||
# define INLINE_ASM_SUPPORTED
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int cpuid_exists_by_eflags(void);
|
|
||||||
void exec_cpuid(uint32_t *regs);
|
|
||||||
void busy_sse_loop(int cycles);
|
|
||||||
|
|
||||||
#endif /* __ASM_BITS_H__ */
|
|
389
src/3rdparty/libcpuid/cpuid_main.c
vendored
389
src/3rdparty/libcpuid/cpuid_main.c
vendored
|
@ -1,389 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2008 Veselin Georgiev,
|
|
||||||
* anrieffNOSPAM @ mgail_DOT.com (convert to gmail)
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions
|
|
||||||
* are met:
|
|
||||||
*
|
|
||||||
* 1. Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
||||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
||||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
||||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
||||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
||||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
||||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
#include "libcpuid.h"
|
|
||||||
#include "libcpuid_internal.h"
|
|
||||||
#include "recog_intel.h"
|
|
||||||
#include "recog_amd.h"
|
|
||||||
#include "asm-bits.h"
|
|
||||||
#include "libcpuid_util.h"
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "config.h"
|
|
||||||
#endif
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
/* Implementation: */
|
|
||||||
|
|
||||||
static int _libcpiud_errno = ERR_OK;
|
|
||||||
|
|
||||||
int set_error(cpu_error_t err)
|
|
||||||
{
|
|
||||||
_libcpiud_errno = (int) err;
|
|
||||||
return (int) err;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void cpu_id_t_constructor(struct cpu_id_t* id)
|
|
||||||
{
|
|
||||||
memset(id, 0, sizeof(struct cpu_id_t));
|
|
||||||
id->l1_data_cache = id->l1_instruction_cache = id->l2_cache = id->l3_cache = id->l4_cache = -1;
|
|
||||||
id->l1_assoc = id->l2_assoc = id->l3_assoc = id->l4_assoc = -1;
|
|
||||||
id->l1_cacheline = id->l2_cacheline = id->l3_cacheline = id->l4_cacheline = -1;
|
|
||||||
id->sse_size = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* get_total_cpus() system specific code: uses OS routines to determine total number of CPUs */
|
|
||||||
#ifdef __APPLE__
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <mach/clock_types.h>
|
|
||||||
#include <mach/clock.h>
|
|
||||||
#include <mach/mach.h>
|
|
||||||
static int get_total_cpus(void)
|
|
||||||
{
|
|
||||||
kern_return_t kr;
|
|
||||||
host_basic_info_data_t basic_info;
|
|
||||||
host_info_t info = (host_info_t)&basic_info;
|
|
||||||
host_flavor_t flavor = HOST_BASIC_INFO;
|
|
||||||
mach_msg_type_number_t count = HOST_BASIC_INFO_COUNT;
|
|
||||||
kr = host_info(mach_host_self(), flavor, info, &count);
|
|
||||||
if (kr != KERN_SUCCESS) return 1;
|
|
||||||
return basic_info.avail_cpus;
|
|
||||||
}
|
|
||||||
#define GET_TOTAL_CPUS_DEFINED
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
#include <windows.h>
|
|
||||||
static int get_total_cpus(void)
|
|
||||||
{
|
|
||||||
SYSTEM_INFO system_info;
|
|
||||||
GetSystemInfo(&system_info);
|
|
||||||
return system_info.dwNumberOfProcessors;
|
|
||||||
}
|
|
||||||
#define GET_TOTAL_CPUS_DEFINED
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined linux || defined __linux__ || defined __sun
|
|
||||||
#include <sys/sysinfo.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
static int get_total_cpus(void)
|
|
||||||
{
|
|
||||||
return sysconf(_SC_NPROCESSORS_ONLN);
|
|
||||||
}
|
|
||||||
#define GET_TOTAL_CPUS_DEFINED
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined __FreeBSD__ || defined __OpenBSD__ || defined __NetBSD__ || defined __bsdi__ || defined __QNX__
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/sysctl.h>
|
|
||||||
|
|
||||||
static int get_total_cpus(void)
|
|
||||||
{
|
|
||||||
int mib[2] = { CTL_HW, HW_NCPU };
|
|
||||||
int ncpus;
|
|
||||||
size_t len = sizeof(ncpus);
|
|
||||||
if (sysctl(mib, 2, &ncpus, &len, (void *) 0, 0) != 0) return 1;
|
|
||||||
return ncpus;
|
|
||||||
}
|
|
||||||
#define GET_TOTAL_CPUS_DEFINED
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef GET_TOTAL_CPUS_DEFINED
|
|
||||||
static int get_total_cpus(void)
|
|
||||||
{
|
|
||||||
static int warning_printed = 0;
|
|
||||||
if (!warning_printed) {
|
|
||||||
warning_printed = 1;
|
|
||||||
warnf("Your system is not supported by libcpuid -- don't know how to detect the\n");
|
|
||||||
warnf("total number of CPUs on your system. It will be reported as 1.\n");
|
|
||||||
printf("Please use cpu_id_t.logical_cpus field instead.\n");
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
#endif /* GET_TOTAL_CPUS_DEFINED */
|
|
||||||
|
|
||||||
|
|
||||||
static void load_features_common(struct cpu_raw_data_t* raw, struct cpu_id_t* data)
|
|
||||||
{
|
|
||||||
const struct feature_map_t matchtable_edx1[] = {
|
|
||||||
{ 0, CPU_FEATURE_FPU },
|
|
||||||
{ 1, CPU_FEATURE_VME },
|
|
||||||
{ 2, CPU_FEATURE_DE },
|
|
||||||
{ 3, CPU_FEATURE_PSE },
|
|
||||||
{ 4, CPU_FEATURE_TSC },
|
|
||||||
{ 5, CPU_FEATURE_MSR },
|
|
||||||
{ 6, CPU_FEATURE_PAE },
|
|
||||||
{ 7, CPU_FEATURE_MCE },
|
|
||||||
{ 8, CPU_FEATURE_CX8 },
|
|
||||||
{ 9, CPU_FEATURE_APIC },
|
|
||||||
{ 11, CPU_FEATURE_SEP },
|
|
||||||
{ 12, CPU_FEATURE_MTRR },
|
|
||||||
{ 13, CPU_FEATURE_PGE },
|
|
||||||
{ 14, CPU_FEATURE_MCA },
|
|
||||||
{ 15, CPU_FEATURE_CMOV },
|
|
||||||
{ 16, CPU_FEATURE_PAT },
|
|
||||||
{ 17, CPU_FEATURE_PSE36 },
|
|
||||||
{ 19, CPU_FEATURE_CLFLUSH },
|
|
||||||
{ 23, CPU_FEATURE_MMX },
|
|
||||||
{ 24, CPU_FEATURE_FXSR },
|
|
||||||
{ 25, CPU_FEATURE_SSE },
|
|
||||||
{ 26, CPU_FEATURE_SSE2 },
|
|
||||||
{ 28, CPU_FEATURE_HT },
|
|
||||||
};
|
|
||||||
const struct feature_map_t matchtable_ecx1[] = {
|
|
||||||
{ 0, CPU_FEATURE_PNI },
|
|
||||||
{ 1, CPU_FEATURE_PCLMUL },
|
|
||||||
{ 3, CPU_FEATURE_MONITOR },
|
|
||||||
{ 9, CPU_FEATURE_SSSE3 },
|
|
||||||
{ 12, CPU_FEATURE_FMA3 },
|
|
||||||
{ 13, CPU_FEATURE_CX16 },
|
|
||||||
{ 19, CPU_FEATURE_SSE4_1 },
|
|
||||||
{ 20, CPU_FEATURE_SSE4_2 },
|
|
||||||
{ 22, CPU_FEATURE_MOVBE },
|
|
||||||
{ 23, CPU_FEATURE_POPCNT },
|
|
||||||
{ 25, CPU_FEATURE_AES },
|
|
||||||
{ 26, CPU_FEATURE_XSAVE },
|
|
||||||
{ 27, CPU_FEATURE_OSXSAVE },
|
|
||||||
{ 28, CPU_FEATURE_AVX },
|
|
||||||
{ 29, CPU_FEATURE_F16C },
|
|
||||||
{ 30, CPU_FEATURE_RDRAND },
|
|
||||||
};
|
|
||||||
const struct feature_map_t matchtable_ebx7[] = {
|
|
||||||
{ 3, CPU_FEATURE_BMI1 },
|
|
||||||
{ 5, CPU_FEATURE_AVX2 },
|
|
||||||
{ 8, CPU_FEATURE_BMI2 },
|
|
||||||
};
|
|
||||||
const struct feature_map_t matchtable_edx81[] = {
|
|
||||||
{ 11, CPU_FEATURE_SYSCALL },
|
|
||||||
{ 27, CPU_FEATURE_RDTSCP },
|
|
||||||
{ 29, CPU_FEATURE_LM },
|
|
||||||
};
|
|
||||||
const struct feature_map_t matchtable_ecx81[] = {
|
|
||||||
{ 0, CPU_FEATURE_LAHF_LM },
|
|
||||||
};
|
|
||||||
const struct feature_map_t matchtable_edx87[] = {
|
|
||||||
{ 8, CPU_FEATURE_CONSTANT_TSC },
|
|
||||||
};
|
|
||||||
if (raw->basic_cpuid[0][0] >= 1) {
|
|
||||||
match_features(matchtable_edx1, COUNT_OF(matchtable_edx1), raw->basic_cpuid[1][3], data);
|
|
||||||
match_features(matchtable_ecx1, COUNT_OF(matchtable_ecx1), raw->basic_cpuid[1][2], data);
|
|
||||||
}
|
|
||||||
if (raw->basic_cpuid[0][0] >= 7) {
|
|
||||||
match_features(matchtable_ebx7, COUNT_OF(matchtable_ebx7), raw->basic_cpuid[7][1], data);
|
|
||||||
}
|
|
||||||
if (raw->ext_cpuid[0][0] >= 0x80000001) {
|
|
||||||
match_features(matchtable_edx81, COUNT_OF(matchtable_edx81), raw->ext_cpuid[1][3], data);
|
|
||||||
match_features(matchtable_ecx81, COUNT_OF(matchtable_ecx81), raw->ext_cpuid[1][2], data);
|
|
||||||
}
|
|
||||||
if (raw->ext_cpuid[0][0] >= 0x80000007) {
|
|
||||||
match_features(matchtable_edx87, COUNT_OF(matchtable_edx87), raw->ext_cpuid[7][3], data);
|
|
||||||
}
|
|
||||||
if (data->flags[CPU_FEATURE_SSE]) {
|
|
||||||
/* apply guesswork to check if the SSE unit width is 128 bit */
|
|
||||||
switch (data->vendor) {
|
|
||||||
case VENDOR_AMD:
|
|
||||||
data->sse_size = (data->ext_family >= 16 && data->ext_family != 17) ? 128 : 64;
|
|
||||||
break;
|
|
||||||
case VENDOR_INTEL:
|
|
||||||
data->sse_size = (data->family == 6 && data->ext_model >= 15) ? 128 : 64;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
/* leave the CPU_FEATURE_128BIT_SSE_AUTH 0; the advanced per-vendor detection routines
|
|
||||||
* will set it accordingly if they detect the needed bit */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static cpu_vendor_t cpuid_vendor_identify(const uint32_t *raw_vendor, char *vendor_str)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
cpu_vendor_t vendor = VENDOR_UNKNOWN;
|
|
||||||
const struct { cpu_vendor_t vendor; char match[16]; }
|
|
||||||
matchtable[NUM_CPU_VENDORS] = {
|
|
||||||
/* source: http://www.sandpile.org/ia32/cpuid.htm */
|
|
||||||
{ VENDOR_INTEL , "GenuineIntel" },
|
|
||||||
{ VENDOR_AMD , "AuthenticAMD" },
|
|
||||||
{ VENDOR_CYRIX , "CyrixInstead" },
|
|
||||||
{ VENDOR_NEXGEN , "NexGenDriven" },
|
|
||||||
{ VENDOR_TRANSMETA , "GenuineTMx86" },
|
|
||||||
{ VENDOR_UMC , "UMC UMC UMC " },
|
|
||||||
{ VENDOR_CENTAUR , "CentaurHauls" },
|
|
||||||
{ VENDOR_RISE , "RiseRiseRise" },
|
|
||||||
{ VENDOR_SIS , "SiS SiS SiS " },
|
|
||||||
{ VENDOR_NSC , "Geode by NSC" },
|
|
||||||
};
|
|
||||||
|
|
||||||
memcpy(vendor_str + 0, &raw_vendor[1], 4);
|
|
||||||
memcpy(vendor_str + 4, &raw_vendor[3], 4);
|
|
||||||
memcpy(vendor_str + 8, &raw_vendor[2], 4);
|
|
||||||
vendor_str[12] = 0;
|
|
||||||
|
|
||||||
/* Determine vendor: */
|
|
||||||
for (i = 0; i < NUM_CPU_VENDORS; i++)
|
|
||||||
if (!strcmp(vendor_str, matchtable[i].match)) {
|
|
||||||
vendor = matchtable[i].vendor;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return vendor;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int cpuid_basic_identify(struct cpu_raw_data_t* raw, struct cpu_id_t* data)
|
|
||||||
{
|
|
||||||
int i, j, basic, xmodel, xfamily, ext;
|
|
||||||
char brandstr[64] = {0};
|
|
||||||
data->vendor = cpuid_vendor_identify(raw->basic_cpuid[0], data->vendor_str);
|
|
||||||
|
|
||||||
if (data->vendor == VENDOR_UNKNOWN)
|
|
||||||
return set_error(ERR_CPU_UNKN);
|
|
||||||
basic = raw->basic_cpuid[0][0];
|
|
||||||
if (basic >= 1) {
|
|
||||||
data->family = (raw->basic_cpuid[1][0] >> 8) & 0xf;
|
|
||||||
data->model = (raw->basic_cpuid[1][0] >> 4) & 0xf;
|
|
||||||
data->stepping = raw->basic_cpuid[1][0] & 0xf;
|
|
||||||
xmodel = (raw->basic_cpuid[1][0] >> 16) & 0xf;
|
|
||||||
xfamily = (raw->basic_cpuid[1][0] >> 20) & 0xff;
|
|
||||||
if (data->vendor == VENDOR_AMD && data->family < 0xf)
|
|
||||||
data->ext_family = data->family;
|
|
||||||
else
|
|
||||||
data->ext_family = data->family + xfamily;
|
|
||||||
data->ext_model = data->model + (xmodel << 4);
|
|
||||||
}
|
|
||||||
ext = raw->ext_cpuid[0][0] - 0x8000000;
|
|
||||||
|
|
||||||
/* obtain the brand string, if present: */
|
|
||||||
if (ext >= 4) {
|
|
||||||
for (i = 0; i < 3; i++)
|
|
||||||
for (j = 0; j < 4; j++)
|
|
||||||
memcpy(brandstr + i * 16 + j * 4,
|
|
||||||
&raw->ext_cpuid[2 + i][j], 4);
|
|
||||||
brandstr[48] = 0;
|
|
||||||
i = 0;
|
|
||||||
while (brandstr[i] == ' ') i++;
|
|
||||||
strncpy(data->brand_str, brandstr + i, sizeof(data->brand_str));
|
|
||||||
data->brand_str[48] = 0;
|
|
||||||
}
|
|
||||||
load_features_common(raw, data);
|
|
||||||
data->total_logical_cpus = get_total_cpus();
|
|
||||||
return set_error(ERR_OK);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Interface: */
|
|
||||||
|
|
||||||
int cpuid_get_total_cpus(void)
|
|
||||||
{
|
|
||||||
return get_total_cpus();
|
|
||||||
}
|
|
||||||
|
|
||||||
int cpuid_present(void)
|
|
||||||
{
|
|
||||||
return cpuid_exists_by_eflags();
|
|
||||||
}
|
|
||||||
|
|
||||||
void cpu_exec_cpuid(uint32_t eax, uint32_t* regs)
|
|
||||||
{
|
|
||||||
regs[0] = eax;
|
|
||||||
regs[1] = regs[2] = regs[3] = 0;
|
|
||||||
exec_cpuid(regs);
|
|
||||||
}
|
|
||||||
|
|
||||||
void cpu_exec_cpuid_ext(uint32_t* regs)
|
|
||||||
{
|
|
||||||
exec_cpuid(regs);
|
|
||||||
}
|
|
||||||
|
|
||||||
int cpuid_get_raw_data(struct cpu_raw_data_t* data)
|
|
||||||
{
|
|
||||||
unsigned i;
|
|
||||||
if (!cpuid_present())
|
|
||||||
return set_error(ERR_NO_CPUID);
|
|
||||||
for (i = 0; i < 32; i++)
|
|
||||||
cpu_exec_cpuid(i, data->basic_cpuid[i]);
|
|
||||||
for (i = 0; i < 32; i++)
|
|
||||||
cpu_exec_cpuid(0x80000000 + i, data->ext_cpuid[i]);
|
|
||||||
for (i = 0; i < MAX_INTELFN4_LEVEL; i++) {
|
|
||||||
memset(data->intel_fn4[i], 0, sizeof(data->intel_fn4[i]));
|
|
||||||
data->intel_fn4[i][0] = 4;
|
|
||||||
data->intel_fn4[i][2] = i;
|
|
||||||
cpu_exec_cpuid_ext(data->intel_fn4[i]);
|
|
||||||
}
|
|
||||||
for (i = 0; i < MAX_INTELFN11_LEVEL; i++) {
|
|
||||||
memset(data->intel_fn11[i], 0, sizeof(data->intel_fn11[i]));
|
|
||||||
data->intel_fn11[i][0] = 11;
|
|
||||||
data->intel_fn11[i][2] = i;
|
|
||||||
cpu_exec_cpuid_ext(data->intel_fn11[i]);
|
|
||||||
}
|
|
||||||
for (i = 0; i < MAX_INTELFN12H_LEVEL; i++) {
|
|
||||||
memset(data->intel_fn12h[i], 0, sizeof(data->intel_fn12h[i]));
|
|
||||||
data->intel_fn12h[i][0] = 0x12;
|
|
||||||
data->intel_fn12h[i][2] = i;
|
|
||||||
cpu_exec_cpuid_ext(data->intel_fn12h[i]);
|
|
||||||
}
|
|
||||||
for (i = 0; i < MAX_INTELFN14H_LEVEL; i++) {
|
|
||||||
memset(data->intel_fn14h[i], 0, sizeof(data->intel_fn14h[i]));
|
|
||||||
data->intel_fn14h[i][0] = 0x14;
|
|
||||||
data->intel_fn14h[i][2] = i;
|
|
||||||
cpu_exec_cpuid_ext(data->intel_fn14h[i]);
|
|
||||||
}
|
|
||||||
return set_error(ERR_OK);
|
|
||||||
}
|
|
||||||
|
|
||||||
int cpu_ident_internal(struct cpu_raw_data_t* raw, struct cpu_id_t* data, struct internal_id_info_t* internal)
|
|
||||||
{
|
|
||||||
int r;
|
|
||||||
struct cpu_raw_data_t myraw;
|
|
||||||
if (!raw) {
|
|
||||||
if ((r = cpuid_get_raw_data(&myraw)) < 0)
|
|
||||||
return set_error(r);
|
|
||||||
raw = &myraw;
|
|
||||||
}
|
|
||||||
cpu_id_t_constructor(data);
|
|
||||||
if ((r = cpuid_basic_identify(raw, data)) < 0)
|
|
||||||
return set_error(r);
|
|
||||||
switch (data->vendor) {
|
|
||||||
case VENDOR_INTEL:
|
|
||||||
r = cpuid_identify_intel(raw, data, internal);
|
|
||||||
break;
|
|
||||||
case VENDOR_AMD:
|
|
||||||
r = cpuid_identify_amd(raw, data, internal);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return set_error(r);
|
|
||||||
}
|
|
||||||
|
|
||||||
int cpu_identify(struct cpu_raw_data_t* raw, struct cpu_id_t* data)
|
|
||||||
{
|
|
||||||
struct internal_id_info_t throwaway;
|
|
||||||
return cpu_ident_internal(raw, data, &throwaway);
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* cpuid_lib_version(void)
|
|
||||||
{
|
|
||||||
return VERSION;
|
|
||||||
}
|
|
58
src/3rdparty/libcpuid/intel_code_t.h
vendored
58
src/3rdparty/libcpuid/intel_code_t.h
vendored
|
@ -1,58 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2016 Veselin Georgiev,
|
|
||||||
* anrieffNOSPAM @ mgail_DOT.com (convert to gmail)
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions
|
|
||||||
* are met:
|
|
||||||
*
|
|
||||||
* 1. Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
||||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
||||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
||||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
||||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
||||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
||||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This file contains a list of internal codes we use in detection. It is
|
|
||||||
* of no external use and isn't a complete list of intel products.
|
|
||||||
*/
|
|
||||||
CODE2(PENTIUM, 2000),
|
|
||||||
|
|
||||||
CODE(IRWIN),
|
|
||||||
CODE(POTOMAC),
|
|
||||||
CODE(GAINESTOWN),
|
|
||||||
CODE(WESTMERE),
|
|
||||||
|
|
||||||
CODE(PENTIUM_M),
|
|
||||||
CODE(NOT_CELERON),
|
|
||||||
|
|
||||||
CODE(CORE_SOLO),
|
|
||||||
CODE(MOBILE_CORE_SOLO),
|
|
||||||
CODE(CORE_DUO),
|
|
||||||
CODE(MOBILE_CORE_DUO),
|
|
||||||
|
|
||||||
CODE(WOLFDALE),
|
|
||||||
CODE(MEROM),
|
|
||||||
CODE(PENRYN),
|
|
||||||
CODE(QUAD_CORE),
|
|
||||||
CODE(DUAL_CORE_HT),
|
|
||||||
CODE(QUAD_CORE_HT),
|
|
||||||
CODE(MORE_THAN_QUADCORE),
|
|
||||||
CODE(PENTIUM_D),
|
|
||||||
|
|
||||||
CODE(SILVERTHORNE),
|
|
||||||
CODE(DIAMONDVILLE),
|
|
||||||
CODE(PINEVIEW),
|
|
||||||
CODE(CEDARVIEW),
|
|
678
src/3rdparty/libcpuid/libcpuid.h
vendored
678
src/3rdparty/libcpuid/libcpuid.h
vendored
|
@ -1,678 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2008 Veselin Georgiev,
|
|
||||||
* anrieffNOSPAM @ mgail_DOT.com (convert to gmail)
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions
|
|
||||||
* are met:
|
|
||||||
*
|
|
||||||
* 1. Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
||||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
||||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
||||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
||||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
||||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
||||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
#ifndef __LIBCPUID_H__
|
|
||||||
#define __LIBCPUID_H__
|
|
||||||
/**
|
|
||||||
* \file libcpuid.h
|
|
||||||
* \author Veselin Georgiev
|
|
||||||
* \date Oct 2008
|
|
||||||
* \version 0.4.0
|
|
||||||
*
|
|
||||||
* Version history:
|
|
||||||
*
|
|
||||||
* * 0.1.0 (2008-10-15): initial adaptation from wxfractgui sources
|
|
||||||
* * 0.1.1 (2009-07-06): Added intel_fn11 fields to cpu_raw_data_t to handle
|
|
||||||
* new processor topology enumeration required on Core i7
|
|
||||||
* * 0.1.2 (2009-09-26): Added support for MSR reading through self-extracting
|
|
||||||
* kernel driver on Win32.
|
|
||||||
* * 0.1.3 (2010-04-20): Added support for greater more accurate CPU clock
|
|
||||||
* measurements with cpu_clock_by_ic()
|
|
||||||
* * 0.2.0 (2011-10-11): Support for AMD Bulldozer CPUs, 128-bit SSE unit size
|
|
||||||
* checking. A backwards-incompatible change, since the
|
|
||||||
* sizeof cpu_id_t is now different.
|
|
||||||
* * 0.2.1 (2012-05-26): Support for Ivy Bridge, and detecting the presence of
|
|
||||||
* the RdRand instruction.
|
|
||||||
* * 0.2.2 (2015-11-04): Support for newer processors up to Haswell and Vishera.
|
|
||||||
* Fix clock detection in cpu_clock_by_ic() for Bulldozer.
|
|
||||||
* More entries supported in cpu_msrinfo().
|
|
||||||
* *BSD and Solaris support (unofficial).
|
|
||||||
* * 0.3.0 (2016-07-09): Support for Skylake; MSR ops in FreeBSD; INFO_VOLTAGE
|
|
||||||
* for AMD CPUs. Level 4 cache support for Crystalwell
|
|
||||||
* (a backwards-incompatible change since the sizeof
|
|
||||||
* cpu_raw_data_t is now different).
|
|
||||||
* * 0.4.0 (2016-09-30): Better detection of AMD clock multiplier with msrinfo.
|
|
||||||
* Support for Intel SGX detection
|
|
||||||
* (a backwards-incompatible change since the sizeof
|
|
||||||
* cpu_raw_data_t and cpu_id_t is now different).
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** @mainpage A simple libcpuid introduction
|
|
||||||
*
|
|
||||||
* LibCPUID provides CPU identification and access to the CPUID and RDTSC
|
|
||||||
* instructions on the x86.
|
|
||||||
* <p>
|
|
||||||
* To execute CPUID, use \ref cpu_exec_cpuid <br>
|
|
||||||
* To execute RDTSC, use \ref cpu_rdtsc <br>
|
|
||||||
* To fetch the CPUID info needed for CPU identification, use
|
|
||||||
* \ref cpuid_get_raw_data <br>
|
|
||||||
* To make sense of that data (decode, extract features), use \ref cpu_identify <br>
|
|
||||||
* To detect the CPU speed, use either \ref cpu_clock, \ref cpu_clock_by_os,
|
|
||||||
* \ref cpu_tsc_mark + \ref cpu_tsc_unmark + \ref cpu_clock_by_mark,
|
|
||||||
* \ref cpu_clock_measure or \ref cpu_clock_by_ic.
|
|
||||||
* Read carefully for pros/cons of each method. <br>
|
|
||||||
*
|
|
||||||
* To read MSRs, use \ref cpu_msr_driver_open to get a handle, and then
|
|
||||||
* \ref cpu_rdmsr for querying abilities. Some MSR decoding is available on recent
|
|
||||||
* CPUs, and can be queried through \ref cpu_msrinfo; the various types of queries
|
|
||||||
* are described in \ref cpu_msrinfo_request_t.
|
|
||||||
* </p>
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** @defgroup libcpuid LibCPUID
|
|
||||||
* @brief LibCPUID provides CPU identification
|
|
||||||
@{ */
|
|
||||||
|
|
||||||
/* Include some integer type specifications: */
|
|
||||||
#include "libcpuid_types.h"
|
|
||||||
|
|
||||||
/* Some limits and other constants */
|
|
||||||
#include "libcpuid_constants.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief CPU vendor, as guessed from the Vendor String.
|
|
||||||
*/
|
|
||||||
typedef enum {
|
|
||||||
VENDOR_INTEL = 0, /*!< Intel CPU */
|
|
||||||
VENDOR_AMD, /*!< AMD CPU */
|
|
||||||
VENDOR_CYRIX, /*!< Cyrix CPU */
|
|
||||||
VENDOR_NEXGEN, /*!< NexGen CPU */
|
|
||||||
VENDOR_TRANSMETA, /*!< Transmeta CPU */
|
|
||||||
VENDOR_UMC, /*!< x86 CPU by UMC */
|
|
||||||
VENDOR_CENTAUR, /*!< x86 CPU by IDT */
|
|
||||||
VENDOR_RISE, /*!< x86 CPU by Rise Technology */
|
|
||||||
VENDOR_SIS, /*!< x86 CPU by SiS */
|
|
||||||
VENDOR_NSC, /*!< x86 CPU by National Semiconductor */
|
|
||||||
|
|
||||||
NUM_CPU_VENDORS, /*!< Valid CPU vendor ids: 0..NUM_CPU_VENDORS - 1 */
|
|
||||||
VENDOR_UNKNOWN = -1,
|
|
||||||
} cpu_vendor_t;
|
|
||||||
#define NUM_CPU_VENDORS NUM_CPU_VENDORS
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Contains just the raw CPUID data.
|
|
||||||
*
|
|
||||||
* This contains only the most basic CPU data, required to do identification
|
|
||||||
* and feature recognition. Every processor should be identifiable using this
|
|
||||||
* data only.
|
|
||||||
*/
|
|
||||||
struct cpu_raw_data_t {
|
|
||||||
/** contains results of CPUID for eax = 0, 1, ...*/
|
|
||||||
uint32_t basic_cpuid[MAX_CPUID_LEVEL][4];
|
|
||||||
|
|
||||||
/** contains results of CPUID for eax = 0x80000000, 0x80000001, ...*/
|
|
||||||
uint32_t ext_cpuid[MAX_EXT_CPUID_LEVEL][4];
|
|
||||||
|
|
||||||
/** when the CPU is intel and it supports deterministic cache
|
|
||||||
information: this contains the results of CPUID for eax = 4
|
|
||||||
and ecx = 0, 1, ... */
|
|
||||||
uint32_t intel_fn4[MAX_INTELFN4_LEVEL][4];
|
|
||||||
|
|
||||||
/** when the CPU is intel and it supports leaf 0Bh (Extended Topology
|
|
||||||
enumeration leaf), this stores the result of CPUID with
|
|
||||||
eax = 11 and ecx = 0, 1, 2... */
|
|
||||||
uint32_t intel_fn11[MAX_INTELFN11_LEVEL][4];
|
|
||||||
|
|
||||||
/** when the CPU is intel and supports leaf 12h (SGX enumeration leaf),
|
|
||||||
* this stores the result of CPUID with eax = 0x12 and
|
|
||||||
* ecx = 0, 1, 2... */
|
|
||||||
uint32_t intel_fn12h[MAX_INTELFN12H_LEVEL][4];
|
|
||||||
|
|
||||||
/** when the CPU is intel and supports leaf 14h (Intel Processor Trace
|
|
||||||
* capabilities leaf).
|
|
||||||
* this stores the result of CPUID with eax = 0x12 and
|
|
||||||
* ecx = 0, 1, 2... */
|
|
||||||
uint32_t intel_fn14h[MAX_INTELFN14H_LEVEL][4];
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief This contains information about SGX features of the processor
|
|
||||||
* Example usage:
|
|
||||||
* @code
|
|
||||||
* ...
|
|
||||||
* struct cpu_raw_data_t raw;
|
|
||||||
* struct cpu_id_t id;
|
|
||||||
*
|
|
||||||
* if (cpuid_get_raw_data(&raw) == 0 && cpu_identify(&raw, &id) == 0 && id.sgx.present) {
|
|
||||||
* printf("SGX is present.\n");
|
|
||||||
* printf("SGX1 instructions: %s.\n", id.sgx.flags[INTEL_SGX1] ? "present" : "absent");
|
|
||||||
* printf("SGX2 instructions: %s.\n", id.sgx.flags[INTEL_SGX2] ? "present" : "absent");
|
|
||||||
* printf("Max 32-bit enclave size: 2^%d bytes.\n", id.sgx.max_enclave_32bit);
|
|
||||||
* printf("Max 64-bit enclave size: 2^%d bytes.\n", id.sgx.max_enclave_64bit);
|
|
||||||
* for (int i = 0; i < id.sgx.num_epc_sections; i++) {
|
|
||||||
* struct cpu_epc_t epc = cpuid_get_epc(i, NULL);
|
|
||||||
* printf("EPC section #%d: address = %x, size = %d bytes.\n", epc.address, epc.size);
|
|
||||||
* }
|
|
||||||
* } else {
|
|
||||||
* printf("SGX is not present.\n");
|
|
||||||
* }
|
|
||||||
* @endcode
|
|
||||||
*/
|
|
||||||
struct cpu_sgx_t {
|
|
||||||
/** Whether SGX is present (boolean) */
|
|
||||||
uint32_t present;
|
|
||||||
|
|
||||||
/** Max enclave size in 32-bit mode. This is a power-of-two value:
|
|
||||||
* if it is "31", then the max enclave size is 2^31 bytes (2 GiB).
|
|
||||||
*/
|
|
||||||
uint8_t max_enclave_32bit;
|
|
||||||
|
|
||||||
/** Max enclave size in 64-bit mode. This is a power-of-two value:
|
|
||||||
* if it is "36", then the max enclave size is 2^36 bytes (64 GiB).
|
|
||||||
*/
|
|
||||||
uint8_t max_enclave_64bit;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* contains SGX feature flags. See the \ref cpu_sgx_feature_t
|
|
||||||
* "INTEL_SGX*" macros below.
|
|
||||||
*/
|
|
||||||
uint8_t flags[SGX_FLAGS_MAX];
|
|
||||||
|
|
||||||
/** number of Enclave Page Cache (EPC) sections. Info for each
|
|
||||||
* section is available through the \ref cpuid_get_epc() function
|
|
||||||
*/
|
|
||||||
int num_epc_sections;
|
|
||||||
|
|
||||||
/** bit vector of the supported extended features that can be written
|
|
||||||
* to the MISC region of the SSA (Save State Area)
|
|
||||||
*/
|
|
||||||
uint32_t misc_select;
|
|
||||||
|
|
||||||
/** a bit vector of the attributes that can be set to SECS.ATTRIBUTES
|
|
||||||
* via ECREATE. Corresponds to bits 0-63 (incl.) of SECS.ATTRIBUTES.
|
|
||||||
*/
|
|
||||||
uint64_t secs_attributes;
|
|
||||||
|
|
||||||
/** a bit vector of the bits that can be set in the XSAVE feature
|
|
||||||
* request mask; Corresponds to bits 64-127 of SECS.ATTRIBUTES.
|
|
||||||
*/
|
|
||||||
uint64_t secs_xfrm;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief This contains the recognized CPU features/info
|
|
||||||
*/
|
|
||||||
struct cpu_id_t {
|
|
||||||
/** contains the CPU vendor string, e.g. "GenuineIntel" */
|
|
||||||
char vendor_str[VENDOR_STR_MAX];
|
|
||||||
|
|
||||||
/** contains the brand string, e.g. "Intel(R) Xeon(TM) CPU 2.40GHz" */
|
|
||||||
char brand_str[BRAND_STR_MAX];
|
|
||||||
|
|
||||||
/** contains the recognized CPU vendor */
|
|
||||||
cpu_vendor_t vendor;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* contain CPU flags. Used to test for features. See
|
|
||||||
* the \ref cpu_feature_t "CPU_FEATURE_*" macros below.
|
|
||||||
* @see Features
|
|
||||||
*/
|
|
||||||
uint8_t flags[CPU_FLAGS_MAX];
|
|
||||||
|
|
||||||
/** CPU family */
|
|
||||||
int32_t family;
|
|
||||||
|
|
||||||
/** CPU model */
|
|
||||||
int32_t model;
|
|
||||||
|
|
||||||
/** CPU stepping */
|
|
||||||
int32_t stepping;
|
|
||||||
|
|
||||||
/** CPU extended family */
|
|
||||||
int32_t ext_family;
|
|
||||||
|
|
||||||
/** CPU extended model */
|
|
||||||
int32_t ext_model;
|
|
||||||
|
|
||||||
/** Number of CPU cores on the current processor */
|
|
||||||
int32_t num_cores;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Number of logical processors on the current processor.
|
|
||||||
* Could be more than the number of physical cores,
|
|
||||||
* e.g. when the processor has HyperThreading.
|
|
||||||
*/
|
|
||||||
int32_t num_logical_cpus;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The total number of logical processors.
|
|
||||||
* The same value is availabe through \ref cpuid_get_total_cpus.
|
|
||||||
*
|
|
||||||
* This is num_logical_cpus * {total physical processors in the system}
|
|
||||||
* (but only on a real system, under a VM this number may be lower).
|
|
||||||
*
|
|
||||||
* If you're writing a multithreaded program and you want to run it on
|
|
||||||
* all CPUs, this is the number of threads you need.
|
|
||||||
*
|
|
||||||
* @note in a VM, this will exactly match the number of CPUs set in
|
|
||||||
* the VM's configuration.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
int32_t total_logical_cpus;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* L1 data cache size in KB. Could be zero, if the CPU lacks cache.
|
|
||||||
* If the size cannot be determined, it will be -1.
|
|
||||||
*/
|
|
||||||
int32_t l1_data_cache;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* L1 instruction cache size in KB. Could be zero, if the CPU lacks
|
|
||||||
* cache. If the size cannot be determined, it will be -1.
|
|
||||||
* @note On some Intel CPUs, whose instruction cache is in fact
|
|
||||||
* a trace cache, the size will be expressed in K uOps.
|
|
||||||
*/
|
|
||||||
int32_t l1_instruction_cache;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* L2 cache size in KB. Could be zero, if the CPU lacks L2 cache.
|
|
||||||
* If the size of the cache could not be determined, it will be -1
|
|
||||||
*/
|
|
||||||
int32_t l2_cache;
|
|
||||||
|
|
||||||
/** L3 cache size in KB. Zero on most systems */
|
|
||||||
int32_t l3_cache;
|
|
||||||
|
|
||||||
/** L4 cache size in KB. Zero on most systems */
|
|
||||||
int32_t l4_cache;
|
|
||||||
|
|
||||||
/** Cache associativity for the L1 data cache. -1 if undetermined */
|
|
||||||
int32_t l1_assoc;
|
|
||||||
|
|
||||||
/** Cache associativity for the L2 cache. -1 if undetermined */
|
|
||||||
int32_t l2_assoc;
|
|
||||||
|
|
||||||
/** Cache associativity for the L3 cache. -1 if undetermined */
|
|
||||||
int32_t l3_assoc;
|
|
||||||
|
|
||||||
/** Cache associativity for the L4 cache. -1 if undetermined */
|
|
||||||
int32_t l4_assoc;
|
|
||||||
|
|
||||||
/** Cache-line size for L1 data cache. -1 if undetermined */
|
|
||||||
int32_t l1_cacheline;
|
|
||||||
|
|
||||||
/** Cache-line size for L2 cache. -1 if undetermined */
|
|
||||||
int32_t l2_cacheline;
|
|
||||||
|
|
||||||
/** Cache-line size for L3 cache. -1 if undetermined */
|
|
||||||
int32_t l3_cacheline;
|
|
||||||
|
|
||||||
/** Cache-line size for L4 cache. -1 if undetermined */
|
|
||||||
int32_t l4_cacheline;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The brief and human-friendly CPU codename, which was recognized.<br>
|
|
||||||
* Examples:
|
|
||||||
* @code
|
|
||||||
* +--------+--------+-------+-------+-------+---------------------------------------+-----------------------+
|
|
||||||
* | Vendor | Family | Model | Step. | Cache | Brand String | cpu_id_t.cpu_codename |
|
|
||||||
* +--------+--------+-------+-------+-------+---------------------------------------+-----------------------+
|
|
||||||
* | AMD | 6 | 8 | 0 | 256 | (not available - will be ignored) | "K6-2" |
|
|
||||||
* | Intel | 15 | 2 | 5 | 512 | "Intel(R) Xeon(TM) CPU 2.40GHz" | "Xeon (Prestonia)" |
|
|
||||||
* | Intel | 6 | 15 | 11 | 4096 | "Intel(R) Core(TM)2 Duo CPU E6550..." | "Conroe (Core 2 Duo)" |
|
|
||||||
* | AMD | 15 | 35 | 2 | 1024 | "Dual Core AMD Opteron(tm) Proces..." | "Opteron (Dual Core)" |
|
|
||||||
* +--------+--------+-------+-------+-------+---------------------------------------+-----------------------+
|
|
||||||
* @endcode
|
|
||||||
*/
|
|
||||||
char cpu_codename[64];
|
|
||||||
|
|
||||||
/** SSE execution unit size (64 or 128; -1 if N/A) */
|
|
||||||
int32_t sse_size;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* contain miscellaneous detection information. Used to test about specifics of
|
|
||||||
* certain detected features. See \ref cpu_hint_t "CPU_HINT_*" macros below.
|
|
||||||
* @see Hints
|
|
||||||
*/
|
|
||||||
uint8_t detection_hints[CPU_HINTS_MAX];
|
|
||||||
|
|
||||||
/** contains information about SGX features if the processor, if present */
|
|
||||||
struct cpu_sgx_t sgx;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief CPU feature identifiers
|
|
||||||
*
|
|
||||||
* Usage:
|
|
||||||
* @code
|
|
||||||
* ...
|
|
||||||
* struct cpu_raw_data_t raw;
|
|
||||||
* struct cpu_id_t id;
|
|
||||||
* if (cpuid_get_raw_data(&raw) == 0 && cpu_identify(&raw, &id) == 0) {
|
|
||||||
* if (id.flags[CPU_FEATURE_SSE2]) {
|
|
||||||
* // The CPU has SSE2...
|
|
||||||
* ...
|
|
||||||
* } else {
|
|
||||||
* // no SSE2
|
|
||||||
* }
|
|
||||||
* } else {
|
|
||||||
* // processor cannot be determined.
|
|
||||||
* }
|
|
||||||
* @endcode
|
|
||||||
*/
|
|
||||||
typedef enum {
|
|
||||||
CPU_FEATURE_FPU = 0, /*!< Floating point unit */
|
|
||||||
CPU_FEATURE_VME, /*!< Virtual mode extension */
|
|
||||||
CPU_FEATURE_DE, /*!< Debugging extension */
|
|
||||||
CPU_FEATURE_PSE, /*!< Page size extension */
|
|
||||||
CPU_FEATURE_TSC, /*!< Time-stamp counter */
|
|
||||||
CPU_FEATURE_MSR, /*!< Model-specific regsisters, RDMSR/WRMSR supported */
|
|
||||||
CPU_FEATURE_PAE, /*!< Physical address extension */
|
|
||||||
CPU_FEATURE_MCE, /*!< Machine check exception */
|
|
||||||
CPU_FEATURE_CX8, /*!< CMPXCHG8B instruction supported */
|
|
||||||
CPU_FEATURE_APIC, /*!< APIC support */
|
|
||||||
CPU_FEATURE_MTRR, /*!< Memory type range registers */
|
|
||||||
CPU_FEATURE_SEP, /*!< SYSENTER / SYSEXIT instructions supported */
|
|
||||||
CPU_FEATURE_PGE, /*!< Page global enable */
|
|
||||||
CPU_FEATURE_MCA, /*!< Machine check architecture */
|
|
||||||
CPU_FEATURE_CMOV, /*!< CMOVxx instructions supported */
|
|
||||||
CPU_FEATURE_PAT, /*!< Page attribute table */
|
|
||||||
CPU_FEATURE_PSE36, /*!< 36-bit page address extension */
|
|
||||||
CPU_FEATURE_PN, /*!< Processor serial # implemented (Intel P3 only) */
|
|
||||||
CPU_FEATURE_CLFLUSH, /*!< CLFLUSH instruction supported */
|
|
||||||
CPU_FEATURE_DTS, /*!< Debug store supported */
|
|
||||||
CPU_FEATURE_ACPI, /*!< ACPI support (power states) */
|
|
||||||
CPU_FEATURE_MMX, /*!< MMX instruction set supported */
|
|
||||||
CPU_FEATURE_FXSR, /*!< FXSAVE / FXRSTOR supported */
|
|
||||||
CPU_FEATURE_SSE, /*!< Streaming-SIMD Extensions (SSE) supported */
|
|
||||||
CPU_FEATURE_SSE2, /*!< SSE2 instructions supported */
|
|
||||||
CPU_FEATURE_SS, /*!< Self-snoop */
|
|
||||||
CPU_FEATURE_HT, /*!< Hyper-threading supported (but might be disabled) */
|
|
||||||
CPU_FEATURE_TM, /*!< Thermal monitor */
|
|
||||||
CPU_FEATURE_IA64, /*!< IA64 supported (Itanium only) */
|
|
||||||
CPU_FEATURE_PBE, /*!< Pending-break enable */
|
|
||||||
CPU_FEATURE_PNI, /*!< PNI (SSE3) instructions supported */
|
|
||||||
CPU_FEATURE_PCLMUL, /*!< PCLMULQDQ instruction supported */
|
|
||||||
CPU_FEATURE_DTS64, /*!< 64-bit Debug store supported */
|
|
||||||
CPU_FEATURE_MONITOR, /*!< MONITOR / MWAIT supported */
|
|
||||||
CPU_FEATURE_DS_CPL, /*!< CPL Qualified Debug Store */
|
|
||||||
CPU_FEATURE_VMX, /*!< Virtualization technology supported */
|
|
||||||
CPU_FEATURE_SMX, /*!< Safer mode exceptions */
|
|
||||||
CPU_FEATURE_EST, /*!< Enhanced SpeedStep */
|
|
||||||
CPU_FEATURE_TM2, /*!< Thermal monitor 2 */
|
|
||||||
CPU_FEATURE_SSSE3, /*!< SSSE3 instructionss supported (this is different from SSE3!) */
|
|
||||||
CPU_FEATURE_CID, /*!< Context ID supported */
|
|
||||||
CPU_FEATURE_CX16, /*!< CMPXCHG16B instruction supported */
|
|
||||||
CPU_FEATURE_XTPR, /*!< Send Task Priority Messages disable */
|
|
||||||
CPU_FEATURE_PDCM, /*!< Performance capabilities MSR supported */
|
|
||||||
CPU_FEATURE_DCA, /*!< Direct cache access supported */
|
|
||||||
CPU_FEATURE_SSE4_1, /*!< SSE 4.1 instructions supported */
|
|
||||||
CPU_FEATURE_SSE4_2, /*!< SSE 4.2 instructions supported */
|
|
||||||
CPU_FEATURE_SYSCALL, /*!< SYSCALL / SYSRET instructions supported */
|
|
||||||
CPU_FEATURE_XD, /*!< Execute disable bit supported */
|
|
||||||
CPU_FEATURE_MOVBE, /*!< MOVBE instruction supported */
|
|
||||||
CPU_FEATURE_POPCNT, /*!< POPCNT instruction supported */
|
|
||||||
CPU_FEATURE_AES, /*!< AES* instructions supported */
|
|
||||||
CPU_FEATURE_XSAVE, /*!< XSAVE/XRSTOR/etc instructions supported */
|
|
||||||
CPU_FEATURE_OSXSAVE, /*!< non-privileged copy of OSXSAVE supported */
|
|
||||||
CPU_FEATURE_AVX, /*!< Advanced vector extensions supported */
|
|
||||||
CPU_FEATURE_MMXEXT, /*!< AMD MMX-extended instructions supported */
|
|
||||||
CPU_FEATURE_3DNOW, /*!< AMD 3DNow! instructions supported */
|
|
||||||
CPU_FEATURE_3DNOWEXT, /*!< AMD 3DNow! extended instructions supported */
|
|
||||||
CPU_FEATURE_NX, /*!< No-execute bit supported */
|
|
||||||
CPU_FEATURE_FXSR_OPT, /*!< FFXSR: FXSAVE and FXRSTOR optimizations */
|
|
||||||
CPU_FEATURE_RDTSCP, /*!< RDTSCP instruction supported (AMD-only) */
|
|
||||||
CPU_FEATURE_LM, /*!< Long mode (x86_64/EM64T) supported */
|
|
||||||
CPU_FEATURE_LAHF_LM, /*!< LAHF/SAHF supported in 64-bit mode */
|
|
||||||
CPU_FEATURE_CMP_LEGACY, /*!< core multi-processing legacy mode */
|
|
||||||
CPU_FEATURE_SVM, /*!< AMD Secure virtual machine */
|
|
||||||
CPU_FEATURE_ABM, /*!< LZCNT instruction support */
|
|
||||||
CPU_FEATURE_MISALIGNSSE,/*!< Misaligned SSE supported */
|
|
||||||
CPU_FEATURE_SSE4A, /*!< SSE 4a from AMD */
|
|
||||||
CPU_FEATURE_3DNOWPREFETCH, /*!< PREFETCH/PREFETCHW support */
|
|
||||||
CPU_FEATURE_OSVW, /*!< OS Visible Workaround (AMD) */
|
|
||||||
CPU_FEATURE_IBS, /*!< Instruction-based sampling */
|
|
||||||
CPU_FEATURE_SSE5, /*!< SSE 5 instructions supported (deprecated, will never be 1) */
|
|
||||||
CPU_FEATURE_SKINIT, /*!< SKINIT / STGI supported */
|
|
||||||
CPU_FEATURE_WDT, /*!< Watchdog timer support */
|
|
||||||
CPU_FEATURE_TS, /*!< Temperature sensor */
|
|
||||||
CPU_FEATURE_FID, /*!< Frequency ID control */
|
|
||||||
CPU_FEATURE_VID, /*!< Voltage ID control */
|
|
||||||
CPU_FEATURE_TTP, /*!< THERMTRIP */
|
|
||||||
CPU_FEATURE_TM_AMD, /*!< AMD-specified hardware thermal control */
|
|
||||||
CPU_FEATURE_STC, /*!< Software thermal control */
|
|
||||||
CPU_FEATURE_100MHZSTEPS,/*!< 100 MHz multiplier control */
|
|
||||||
CPU_FEATURE_HWPSTATE, /*!< Hardware P-state control */
|
|
||||||
CPU_FEATURE_CONSTANT_TSC, /*!< TSC ticks at constant rate */
|
|
||||||
CPU_FEATURE_XOP, /*!< The XOP instruction set (same as the old CPU_FEATURE_SSE5) */
|
|
||||||
CPU_FEATURE_FMA3, /*!< The FMA3 instruction set */
|
|
||||||
CPU_FEATURE_FMA4, /*!< The FMA4 instruction set */
|
|
||||||
CPU_FEATURE_TBM, /*!< Trailing bit manipulation instruction support */
|
|
||||||
CPU_FEATURE_F16C, /*!< 16-bit FP convert instruction support */
|
|
||||||
CPU_FEATURE_RDRAND, /*!< RdRand instruction */
|
|
||||||
CPU_FEATURE_X2APIC, /*!< x2APIC, APIC_BASE.EXTD, MSRs 0000_0800h...0000_0BFFh 64-bit ICR (+030h but not +031h), no DFR (+00Eh), SELF_IPI (+040h) also see standard level 0000_000Bh */
|
|
||||||
CPU_FEATURE_CPB, /*!< Core performance boost */
|
|
||||||
CPU_FEATURE_APERFMPERF, /*!< MPERF/APERF MSRs support */
|
|
||||||
CPU_FEATURE_PFI, /*!< Processor Feedback Interface support */
|
|
||||||
CPU_FEATURE_PA, /*!< Processor accumulator */
|
|
||||||
CPU_FEATURE_AVX2, /*!< AVX2 instructions */
|
|
||||||
CPU_FEATURE_BMI1, /*!< BMI1 instructions */
|
|
||||||
CPU_FEATURE_BMI2, /*!< BMI2 instructions */
|
|
||||||
CPU_FEATURE_HLE, /*!< Hardware Lock Elision prefixes */
|
|
||||||
CPU_FEATURE_RTM, /*!< Restricted Transactional Memory instructions */
|
|
||||||
CPU_FEATURE_AVX512F, /*!< AVX-512 Foundation */
|
|
||||||
CPU_FEATURE_AVX512DQ, /*!< AVX-512 Double/Quad granular insns */
|
|
||||||
CPU_FEATURE_AVX512PF, /*!< AVX-512 Prefetch */
|
|
||||||
CPU_FEATURE_AVX512ER, /*!< AVX-512 Exponential/Reciprocal */
|
|
||||||
CPU_FEATURE_AVX512CD, /*!< AVX-512 Conflict detection */
|
|
||||||
CPU_FEATURE_SHA_NI, /*!< SHA-1/SHA-256 instructions */
|
|
||||||
CPU_FEATURE_AVX512BW, /*!< AVX-512 Byte/Word granular insns */
|
|
||||||
CPU_FEATURE_AVX512VL, /*!< AVX-512 128/256 vector length extensions */
|
|
||||||
CPU_FEATURE_SGX, /*!< SGX extensions. Non-autoritative, check cpu_id_t::sgx::present to verify presence */
|
|
||||||
CPU_FEATURE_RDSEED, /*!< RDSEED instruction */
|
|
||||||
CPU_FEATURE_ADX, /*!< ADX extensions (arbitrary precision) */
|
|
||||||
/* termination: */
|
|
||||||
NUM_CPU_FEATURES,
|
|
||||||
} cpu_feature_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief CPU detection hints identifiers
|
|
||||||
*
|
|
||||||
* Usage: similar to the flags usage
|
|
||||||
*/
|
|
||||||
typedef enum {
|
|
||||||
CPU_HINT_SSE_SIZE_AUTH = 0, /*!< SSE unit size is authoritative (not only a Family/Model guesswork, but based on an actual CPUID bit) */
|
|
||||||
/* termination */
|
|
||||||
NUM_CPU_HINTS,
|
|
||||||
} cpu_hint_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief SGX features flags
|
|
||||||
* \see cpu_sgx_t
|
|
||||||
*
|
|
||||||
* Usage:
|
|
||||||
* @code
|
|
||||||
* ...
|
|
||||||
* struct cpu_raw_data_t raw;
|
|
||||||
* struct cpu_id_t id;
|
|
||||||
* if (cpuid_get_raw_data(&raw) == 0 && cpu_identify(&raw, &id) == 0 && id.sgx.present) {
|
|
||||||
* if (id.sgx.flags[INTEL_SGX1])
|
|
||||||
* // The CPU has SGX1 instructions support...
|
|
||||||
* ...
|
|
||||||
* } else {
|
|
||||||
* // no SGX
|
|
||||||
* }
|
|
||||||
* } else {
|
|
||||||
* // processor cannot be determined.
|
|
||||||
* }
|
|
||||||
* @endcode
|
|
||||||
*/
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
INTEL_SGX1, /*!< SGX1 instructions support */
|
|
||||||
INTEL_SGX2, /*!< SGX2 instructions support */
|
|
||||||
|
|
||||||
/* termination: */
|
|
||||||
NUM_SGX_FEATURES,
|
|
||||||
} cpu_sgx_feature_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Describes common library error codes
|
|
||||||
*/
|
|
||||||
typedef enum {
|
|
||||||
ERR_OK = 0, /*!< No error */
|
|
||||||
ERR_NO_CPUID = -1, /*!< CPUID instruction is not supported */
|
|
||||||
ERR_NO_RDTSC = -2, /*!< RDTSC instruction is not supported */
|
|
||||||
ERR_NO_MEM = -3, /*!< Memory allocation failed */
|
|
||||||
ERR_OPEN = -4, /*!< File open operation failed */
|
|
||||||
ERR_BADFMT = -5, /*!< Bad file format */
|
|
||||||
ERR_NOT_IMP = -6, /*!< Not implemented */
|
|
||||||
ERR_CPU_UNKN = -7, /*!< Unsupported processor */
|
|
||||||
ERR_NO_RDMSR = -8, /*!< RDMSR instruction is not supported */
|
|
||||||
ERR_NO_DRIVER= -9, /*!< RDMSR driver error (generic) */
|
|
||||||
ERR_NO_PERMS = -10, /*!< No permissions to install RDMSR driver */
|
|
||||||
ERR_EXTRACT = -11, /*!< Cannot extract RDMSR driver (read only media?) */
|
|
||||||
ERR_HANDLE = -12, /*!< Bad handle */
|
|
||||||
ERR_INVMSR = -13, /*!< Invalid MSR */
|
|
||||||
ERR_INVCNB = -14, /*!< Invalid core number */
|
|
||||||
ERR_HANDLE_R = -15, /*!< Error on handle read */
|
|
||||||
ERR_INVRANGE = -16, /*!< Invalid given range */
|
|
||||||
} cpu_error_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Internal structure, used in cpu_tsc_mark, cpu_tsc_unmark and
|
|
||||||
* cpu_clock_by_mark
|
|
||||||
*/
|
|
||||||
struct cpu_mark_t {
|
|
||||||
uint64_t tsc; /*!< Time-stamp from RDTSC */
|
|
||||||
uint64_t sys_clock; /*!< In microsecond resolution */
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Returns the total number of logical CPU threads (even if CPUID is not present).
|
|
||||||
*
|
|
||||||
* Under VM, this number (and total_logical_cpus, since they are fetched with the same code)
|
|
||||||
* may be nonsensical, i.e. might not equal NumPhysicalCPUs*NumCoresPerCPU*HyperThreading.
|
|
||||||
* This is because no matter how many logical threads the host machine has, you may limit them
|
|
||||||
* in the VM to any number you like. **This** is the number returned by cpuid_get_total_cpus().
|
|
||||||
*
|
|
||||||
* @returns Number of logical CPU threads available. Equals the \ref cpu_id_t::total_logical_cpus.
|
|
||||||
*/
|
|
||||||
int cpuid_get_total_cpus(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Checks if the CPUID instruction is supported
|
|
||||||
* @retval 1 if CPUID is present
|
|
||||||
* @retval 0 the CPU doesn't have CPUID.
|
|
||||||
*/
|
|
||||||
int cpuid_present(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Executes the CPUID instruction
|
|
||||||
* @param eax - the value of the EAX register when executing CPUID
|
|
||||||
* @param regs - the results will be stored here. regs[0] = EAX, regs[1] = EBX, ...
|
|
||||||
* @note CPUID will be executed with EAX set to the given value and EBX, ECX,
|
|
||||||
* EDX set to zero.
|
|
||||||
*/
|
|
||||||
void cpu_exec_cpuid(uint32_t eax, uint32_t* regs);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Executes the CPUID instruction with the given input registers
|
|
||||||
* @note This is just a bit more generic version of cpu_exec_cpuid - it allows
|
|
||||||
* you to control all the registers.
|
|
||||||
* @param regs - Input/output. Prior to executing CPUID, EAX, EBX, ECX and
|
|
||||||
* EDX will be set to regs[0], regs[1], regs[2] and regs[3].
|
|
||||||
* After CPUID, this array will contain the results.
|
|
||||||
*/
|
|
||||||
void cpu_exec_cpuid_ext(uint32_t* regs);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Obtains the raw CPUID data from the current CPU
|
|
||||||
* @param data - a pointer to cpu_raw_data_t structure
|
|
||||||
* @returns zero if successful, and some negative number on error.
|
|
||||||
* The error message can be obtained by calling \ref cpuid_error.
|
|
||||||
* @see cpu_error_t
|
|
||||||
*/
|
|
||||||
int cpuid_get_raw_data(struct cpu_raw_data_t* data);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Identifies the CPU
|
|
||||||
* @param raw - Input - a pointer to the raw CPUID data, which is obtained
|
|
||||||
* either by cpuid_get_raw_data or cpuid_deserialize_raw_data.
|
|
||||||
* Can also be NULL, in which case the functions calls
|
|
||||||
* cpuid_get_raw_data itself.
|
|
||||||
* @param data - Output - the decoded CPU features/info is written here.
|
|
||||||
* @note The function will not fail, even if some of the information
|
|
||||||
* cannot be obtained. Even when the CPU is new and thus unknown to
|
|
||||||
* libcpuid, some generic info, such as "AMD K9 family CPU" will be
|
|
||||||
* written to data.cpu_codename, and most other things, such as the
|
|
||||||
* CPU flags, cache sizes, etc. should be detected correctly anyway.
|
|
||||||
* However, the function CAN fail, if the CPU is completely alien to
|
|
||||||
* libcpuid.
|
|
||||||
* @note While cpu_identify() and cpuid_get_raw_data() are fast for most
|
|
||||||
* purposes, running them several thousand times per second can hamper
|
|
||||||
* performance significantly. Specifically, avoid writing "cpu feature
|
|
||||||
* checker" wrapping function, which calls cpu_identify and returns the
|
|
||||||
* value of some flag, if that function is going to be called frequently.
|
|
||||||
* @returns zero if successful, and some negative number on error.
|
|
||||||
* The error message can be obtained by calling \ref cpuid_error.
|
|
||||||
* @see cpu_error_t
|
|
||||||
*/
|
|
||||||
int cpu_identify(struct cpu_raw_data_t* raw, struct cpu_id_t* data);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief The return value of cpuid_get_epc().
|
|
||||||
* @details
|
|
||||||
* Describes an EPC (Enclave Page Cache) layout (physical address and size).
|
|
||||||
* A CPU may have one or more EPC areas, and information about each is
|
|
||||||
* fetched via \ref cpuid_get_epc.
|
|
||||||
*/
|
|
||||||
struct cpu_epc_t {
|
|
||||||
uint64_t start_addr;
|
|
||||||
uint64_t length;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Fetches information about an EPC (Enclave Page Cache) area.
|
|
||||||
* @param index - zero-based index, valid range [0..cpu_id_t.egx.num_epc_sections)
|
|
||||||
* @param raw - a pointer to fetched raw CPUID data. Needed only for testing,
|
|
||||||
* you can safely pass NULL here (if you pass a real structure,
|
|
||||||
* it will be used for fetching the leaf 12h data if index < 2;
|
|
||||||
* otherwise the real CPUID instruction will be used).
|
|
||||||
* @returns the requested data. If the CPU doesn't support SGX, or if
|
|
||||||
* index >= cpu_id_t.egx.num_epc_sections, both fields of the returned
|
|
||||||
* structure will be zeros.
|
|
||||||
*/
|
|
||||||
struct cpu_epc_t cpuid_get_epc(int index, const struct cpu_raw_data_t* raw);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Returns the libcpuid version
|
|
||||||
*
|
|
||||||
* @returns the string representation of the libcpuid version, like "0.1.1"
|
|
||||||
*/
|
|
||||||
const char* cpuid_lib_version(void);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
} /* extern "C" */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/** @} */
|
|
||||||
|
|
||||||
#endif /* __LIBCPUID_H__ */
|
|
47
src/3rdparty/libcpuid/libcpuid_constants.h
vendored
47
src/3rdparty/libcpuid/libcpuid_constants.h
vendored
|
@ -1,47 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2008 Veselin Georgiev,
|
|
||||||
* anrieffNOSPAM @ mgail_DOT.com (convert to gmail)
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions
|
|
||||||
* are met:
|
|
||||||
*
|
|
||||||
* 1. Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
||||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
||||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
||||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
||||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
||||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
||||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* @File libcpuid_constants.h
|
|
||||||
* @Author Veselin Georgiev
|
|
||||||
* @Brief Some limits and constants for libcpuid
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __LIBCPUID_CONSTANTS_H__
|
|
||||||
#define __LIBCPUID_CONSTANTS_H__
|
|
||||||
|
|
||||||
#define VENDOR_STR_MAX 16
|
|
||||||
#define BRAND_STR_MAX 64
|
|
||||||
#define CPU_FLAGS_MAX 128
|
|
||||||
#define MAX_CPUID_LEVEL 32
|
|
||||||
#define MAX_EXT_CPUID_LEVEL 32
|
|
||||||
#define MAX_INTELFN4_LEVEL 8
|
|
||||||
#define MAX_INTELFN11_LEVEL 4
|
|
||||||
#define MAX_INTELFN12H_LEVEL 4
|
|
||||||
#define MAX_INTELFN14H_LEVEL 4
|
|
||||||
#define CPU_HINTS_MAX 16
|
|
||||||
#define SGX_FLAGS_MAX 14
|
|
||||||
|
|
||||||
#endif /* __LIBCPUID_CONSTANTS_H__ */
|
|
107
src/3rdparty/libcpuid/libcpuid_internal.h
vendored
107
src/3rdparty/libcpuid/libcpuid_internal.h
vendored
|
@ -1,107 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2016 Veselin Georgiev,
|
|
||||||
* anrieffNOSPAM @ mgail_DOT.com (convert to gmail)
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions
|
|
||||||
* are met:
|
|
||||||
*
|
|
||||||
* 1. Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
||||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
||||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
||||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
||||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
||||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
||||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
#ifndef __LIBCPUID_INTERNAL_H__
|
|
||||||
#define __LIBCPUID_INTERNAL_H__
|
|
||||||
/*
|
|
||||||
* This file contains internal undocumented declarations and function prototypes
|
|
||||||
* for the workings of the internal library infrastructure.
|
|
||||||
*/
|
|
||||||
|
|
||||||
enum _common_codes_t {
|
|
||||||
NA = 0,
|
|
||||||
NC, /* No code */
|
|
||||||
};
|
|
||||||
|
|
||||||
#define CODE(x) x
|
|
||||||
#define CODE2(x, y) x = y
|
|
||||||
enum _amd_code_t {
|
|
||||||
#include "amd_code_t.h"
|
|
||||||
};
|
|
||||||
typedef enum _amd_code_t amd_code_t;
|
|
||||||
|
|
||||||
enum _intel_code_t {
|
|
||||||
#include "intel_code_t.h"
|
|
||||||
};
|
|
||||||
typedef enum _intel_code_t intel_code_t;
|
|
||||||
#undef CODE
|
|
||||||
#undef CODE2
|
|
||||||
|
|
||||||
struct internal_id_info_t {
|
|
||||||
union {
|
|
||||||
amd_code_t amd;
|
|
||||||
intel_code_t intel;
|
|
||||||
} code;
|
|
||||||
uint64_t bits;
|
|
||||||
int score; // detection (matchtable) score
|
|
||||||
};
|
|
||||||
|
|
||||||
#define LBIT(x) (((long long) 1) << x)
|
|
||||||
|
|
||||||
enum _common_bits_t {
|
|
||||||
_M_ = LBIT( 0 ),
|
|
||||||
MOBILE_ = LBIT( 1 ),
|
|
||||||
_MP_ = LBIT( 2 ),
|
|
||||||
};
|
|
||||||
|
|
||||||
// additional detection bits for Intel CPUs:
|
|
||||||
enum _intel_bits_t {
|
|
||||||
PENTIUM_ = LBIT( 10 ),
|
|
||||||
CELERON_ = LBIT( 11 ),
|
|
||||||
CORE_ = LBIT( 12 ),
|
|
||||||
_I_ = LBIT( 13 ),
|
|
||||||
_3 = LBIT( 14 ),
|
|
||||||
_5 = LBIT( 15 ),
|
|
||||||
_7 = LBIT( 16 ),
|
|
||||||
_9 = LBIT( 17 ),
|
|
||||||
XEON_ = LBIT( 18 ),
|
|
||||||
ATOM_ = LBIT( 19 ),
|
|
||||||
};
|
|
||||||
typedef enum _intel_bits_t intel_bits_t;
|
|
||||||
|
|
||||||
enum _amd_bits_t {
|
|
||||||
ATHLON_ = LBIT( 10 ),
|
|
||||||
_XP_ = LBIT( 11 ),
|
|
||||||
DURON_ = LBIT( 12 ),
|
|
||||||
SEMPRON_ = LBIT( 13 ),
|
|
||||||
OPTERON_ = LBIT( 14 ),
|
|
||||||
TURION_ = LBIT( 15 ),
|
|
||||||
_LV_ = LBIT( 16 ),
|
|
||||||
_64_ = LBIT( 17 ),
|
|
||||||
_X2 = LBIT( 18 ),
|
|
||||||
_X3 = LBIT( 19 ),
|
|
||||||
_X4 = LBIT( 20 ),
|
|
||||||
_X6 = LBIT( 21 ),
|
|
||||||
_FX = LBIT( 22 ),
|
|
||||||
_APU_ = LBIT( 23 ),
|
|
||||||
};
|
|
||||||
typedef enum _amd_bits_t amd_bits_t;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int cpu_ident_internal(struct cpu_raw_data_t* raw, struct cpu_id_t* data,
|
|
||||||
struct internal_id_info_t* internal);
|
|
||||||
|
|
||||||
#endif /* __LIBCPUID_INTERNAL_H__ */
|
|
63
src/3rdparty/libcpuid/libcpuid_types.h
vendored
63
src/3rdparty/libcpuid/libcpuid_types.h
vendored
|
@ -1,63 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2008 Veselin Georgiev,
|
|
||||||
* anrieffNOSPAM @ mgail_DOT.com (convert to gmail)
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions
|
|
||||||
* are met:
|
|
||||||
*
|
|
||||||
* 1. Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
||||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
||||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
||||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
||||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
||||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
||||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* @File libcpuid_types.h
|
|
||||||
* @Author Veselin Georgiev
|
|
||||||
* @Brief Type specifications for libcpuid.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __LIBCPUID_TYPES_H__
|
|
||||||
#define __LIBCPUID_TYPES_H__
|
|
||||||
|
|
||||||
#if !defined(_MSC_VER) || _MSC_VER >= 1600
|
|
||||||
# include <stdint.h>
|
|
||||||
#else
|
|
||||||
/* we have to provide our own: */
|
|
||||||
# if !defined(__int32_t_defined)
|
|
||||||
typedef int int32_t;
|
|
||||||
# endif
|
|
||||||
|
|
||||||
# if !defined(__uint32_t_defined)
|
|
||||||
typedef unsigned uint32_t;
|
|
||||||
# endif
|
|
||||||
|
|
||||||
typedef signed char int8_t;
|
|
||||||
typedef unsigned char uint8_t;
|
|
||||||
typedef signed short int16_t;
|
|
||||||
typedef unsigned short uint16_t;
|
|
||||||
#if (defined _MSC_VER) && (_MSC_VER <= 1300)
|
|
||||||
/* MSVC 6.0: no long longs ... */
|
|
||||||
typedef signed __int64 int64_t;
|
|
||||||
typedef unsigned __int64 uint64_t;
|
|
||||||
#else
|
|
||||||
/* all other sane compilers: */
|
|
||||||
typedef signed long long int64_t;
|
|
||||||
typedef unsigned long long uint64_t;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* __LIBCPUID_TYPES_H__ */
|
|
93
src/3rdparty/libcpuid/libcpuid_util.c
vendored
93
src/3rdparty/libcpuid/libcpuid_util.c
vendored
|
@ -1,93 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2008 Veselin Georgiev,
|
|
||||||
* anrieffNOSPAM @ mgail_DOT.com (convert to gmail)
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions
|
|
||||||
* are met:
|
|
||||||
*
|
|
||||||
* 1. Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
||||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
||||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
||||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
||||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
||||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
||||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
#include "libcpuid.h"
|
|
||||||
#include "libcpuid_util.h"
|
|
||||||
|
|
||||||
void match_features(const struct feature_map_t* matchtable, int count, uint32_t reg, struct cpu_id_t* data)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
for (i = 0; i < count; i++)
|
|
||||||
if (reg & (1u << matchtable[i].bit))
|
|
||||||
data->flags[matchtable[i].feature] = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int xmatch_entry(char c, const char* p)
|
|
||||||
{
|
|
||||||
int i, j;
|
|
||||||
if (c == 0) return -1;
|
|
||||||
if (c == p[0]) return 1;
|
|
||||||
if (p[0] == '.') return 1;
|
|
||||||
if (p[0] == '#' && isdigit(c)) return 1;
|
|
||||||
if (p[0] == '[') {
|
|
||||||
j = 1;
|
|
||||||
while (p[j] && p[j] != ']') j++;
|
|
||||||
if (!p[j]) return -1;
|
|
||||||
for (i = 1; i < j; i++)
|
|
||||||
if (p[i] == c) return j + 1;
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int match_pattern(const char* s, const char* p)
|
|
||||||
{
|
|
||||||
int i, j, dj, k, n, m;
|
|
||||||
n = (int) strlen(s);
|
|
||||||
m = (int) strlen(p);
|
|
||||||
for (i = 0; i < n; i++) {
|
|
||||||
if (xmatch_entry(s[i], p) != -1) {
|
|
||||||
j = 0;
|
|
||||||
k = 0;
|
|
||||||
while (j < m && ((dj = xmatch_entry(s[i + k], p + j)) != -1)) {
|
|
||||||
k++;
|
|
||||||
j += dj;
|
|
||||||
}
|
|
||||||
if (j == m) return i + 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct cpu_id_t* get_cached_cpuid(void)
|
|
||||||
{
|
|
||||||
static int initialized = 0;
|
|
||||||
static struct cpu_id_t id;
|
|
||||||
if (initialized) return &id;
|
|
||||||
if (cpu_identify(NULL, &id))
|
|
||||||
memset(&id, 0, sizeof(id));
|
|
||||||
initialized = 1;
|
|
||||||
return &id;
|
|
||||||
}
|
|
||||||
|
|
||||||
int match_all(uint64_t bits, uint64_t mask)
|
|
||||||
{
|
|
||||||
return (bits & mask) == mask;
|
|
||||||
}
|
|
78
src/3rdparty/libcpuid/libcpuid_util.h
vendored
78
src/3rdparty/libcpuid/libcpuid_util.h
vendored
|
@ -1,78 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2008 Veselin Georgiev,
|
|
||||||
* anrieffNOSPAM @ mgail_DOT.com (convert to gmail)
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions
|
|
||||||
* are met:
|
|
||||||
*
|
|
||||||
* 1. Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
||||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
||||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
||||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
||||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
||||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
||||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
#ifndef __LIBCPUID_UTIL_H__
|
|
||||||
#define __LIBCPUID_UTIL_H__
|
|
||||||
|
|
||||||
#define COUNT_OF(array) (sizeof(array) / sizeof(array[0]))
|
|
||||||
|
|
||||||
struct feature_map_t {
|
|
||||||
unsigned bit;
|
|
||||||
cpu_feature_t feature;
|
|
||||||
};
|
|
||||||
|
|
||||||
void match_features(const struct feature_map_t* matchtable, int count,
|
|
||||||
uint32_t reg, struct cpu_id_t* data);
|
|
||||||
|
|
||||||
struct match_entry_t {
|
|
||||||
int family, model, stepping, ext_family, ext_model;
|
|
||||||
int ncores, l2cache, l3cache, brand_code;
|
|
||||||
uint64_t model_bits;
|
|
||||||
int model_code;
|
|
||||||
char name[32];
|
|
||||||
};
|
|
||||||
|
|
||||||
// returns the match score:
|
|
||||||
int match_cpu_codename(const struct match_entry_t* matchtable, int count,
|
|
||||||
struct cpu_id_t* data, int brand_code, uint64_t bits,
|
|
||||||
int model_code);
|
|
||||||
/*
|
|
||||||
* Seek for a pattern in `haystack'.
|
|
||||||
* Pattern may be an fixed string, or contain the special metacharacters
|
|
||||||
* '.' - match any single character
|
|
||||||
* '#' - match any digit
|
|
||||||
* '[<chars>] - match any of the given chars (regex-like ranges are not
|
|
||||||
* supported)
|
|
||||||
* Return val: 0 if the pattern is not found. Nonzero if it is found (actually,
|
|
||||||
* x + 1 where x is the index where the match is found).
|
|
||||||
*/
|
|
||||||
int match_pattern(const char* haystack, const char* pattern);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Gets an initialized cpu_id_t. It is cached, so that internal libcpuid
|
|
||||||
* machinery doesn't need to issue cpu_identify more than once.
|
|
||||||
*/
|
|
||||||
struct cpu_id_t* get_cached_cpuid(void);
|
|
||||||
|
|
||||||
|
|
||||||
/* returns true if all bits of mask are present in `bits'. */
|
|
||||||
int match_all(uint64_t bits, uint64_t mask);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Sets the current errno
|
|
||||||
*/
|
|
||||||
int set_error(cpu_error_t err);
|
|
||||||
|
|
||||||
#endif /* __LIBCPUID_UTIL_H__ */
|
|
359
src/3rdparty/libcpuid/masm-x64.asm
vendored
359
src/3rdparty/libcpuid/masm-x64.asm
vendored
|
@ -1,359 +0,0 @@
|
||||||
|
|
||||||
.code
|
|
||||||
; procedure exec_cpuid
|
|
||||||
; Signature: void exec_cpiud(uint32_t *regs)
|
|
||||||
exec_cpuid Proc
|
|
||||||
push rbx
|
|
||||||
push rcx
|
|
||||||
push rdx
|
|
||||||
push rdi
|
|
||||||
|
|
||||||
mov rdi, rcx
|
|
||||||
|
|
||||||
mov eax, [rdi]
|
|
||||||
mov ebx, [rdi+4]
|
|
||||||
mov ecx, [rdi+8]
|
|
||||||
mov edx, [rdi+12]
|
|
||||||
|
|
||||||
cpuid
|
|
||||||
|
|
||||||
mov [rdi], eax
|
|
||||||
mov [rdi+4], ebx
|
|
||||||
mov [rdi+8], ecx
|
|
||||||
mov [rdi+12], edx
|
|
||||||
pop rdi
|
|
||||||
pop rdx
|
|
||||||
pop rcx
|
|
||||||
pop rbx
|
|
||||||
ret
|
|
||||||
exec_cpuid endp
|
|
||||||
|
|
||||||
; procedure cpu_rdtsc
|
|
||||||
; Signature: void cpu_rdtsc(uint64_t *result)
|
|
||||||
cpu_rdtsc Proc
|
|
||||||
push rdx
|
|
||||||
rdtsc
|
|
||||||
mov [rcx], eax
|
|
||||||
mov [rcx+4], edx
|
|
||||||
pop rdx
|
|
||||||
ret
|
|
||||||
cpu_rdtsc endp
|
|
||||||
|
|
||||||
; procedure busy_sse_loop
|
|
||||||
; Signature: void busy_sse_loop(int cycles)
|
|
||||||
busy_sse_loop Proc
|
|
||||||
; save xmm6 & xmm7 into the shadow area, as Visual C++ 2008
|
|
||||||
; expects that we don't touch them:
|
|
||||||
movups [rsp + 8], xmm6
|
|
||||||
movups [rsp + 24], xmm7
|
|
||||||
|
|
||||||
xorps xmm0, xmm0
|
|
||||||
xorps xmm1, xmm1
|
|
||||||
xorps xmm2, xmm2
|
|
||||||
xorps xmm3, xmm3
|
|
||||||
xorps xmm4, xmm4
|
|
||||||
xorps xmm5, xmm5
|
|
||||||
xorps xmm6, xmm6
|
|
||||||
xorps xmm7, xmm7
|
|
||||||
; --
|
|
||||||
align 16
|
|
||||||
bsLoop:
|
|
||||||
; 0:
|
|
||||||
addps xmm0, xmm1
|
|
||||||
addps xmm1, xmm2
|
|
||||||
addps xmm2, xmm3
|
|
||||||
addps xmm3, xmm4
|
|
||||||
addps xmm4, xmm5
|
|
||||||
addps xmm5, xmm6
|
|
||||||
addps xmm6, xmm7
|
|
||||||
addps xmm7, xmm0
|
|
||||||
; 1:
|
|
||||||
addps xmm0, xmm1
|
|
||||||
addps xmm1, xmm2
|
|
||||||
addps xmm2, xmm3
|
|
||||||
addps xmm3, xmm4
|
|
||||||
addps xmm4, xmm5
|
|
||||||
addps xmm5, xmm6
|
|
||||||
addps xmm6, xmm7
|
|
||||||
addps xmm7, xmm0
|
|
||||||
; 2:
|
|
||||||
addps xmm0, xmm1
|
|
||||||
addps xmm1, xmm2
|
|
||||||
addps xmm2, xmm3
|
|
||||||
addps xmm3, xmm4
|
|
||||||
addps xmm4, xmm5
|
|
||||||
addps xmm5, xmm6
|
|
||||||
addps xmm6, xmm7
|
|
||||||
addps xmm7, xmm0
|
|
||||||
; 3:
|
|
||||||
addps xmm0, xmm1
|
|
||||||
addps xmm1, xmm2
|
|
||||||
addps xmm2, xmm3
|
|
||||||
addps xmm3, xmm4
|
|
||||||
addps xmm4, xmm5
|
|
||||||
addps xmm5, xmm6
|
|
||||||
addps xmm6, xmm7
|
|
||||||
addps xmm7, xmm0
|
|
||||||
; 4:
|
|
||||||
addps xmm0, xmm1
|
|
||||||
addps xmm1, xmm2
|
|
||||||
addps xmm2, xmm3
|
|
||||||
addps xmm3, xmm4
|
|
||||||
addps xmm4, xmm5
|
|
||||||
addps xmm5, xmm6
|
|
||||||
addps xmm6, xmm7
|
|
||||||
addps xmm7, xmm0
|
|
||||||
; 5:
|
|
||||||
addps xmm0, xmm1
|
|
||||||
addps xmm1, xmm2
|
|
||||||
addps xmm2, xmm3
|
|
||||||
addps xmm3, xmm4
|
|
||||||
addps xmm4, xmm5
|
|
||||||
addps xmm5, xmm6
|
|
||||||
addps xmm6, xmm7
|
|
||||||
addps xmm7, xmm0
|
|
||||||
; 6:
|
|
||||||
addps xmm0, xmm1
|
|
||||||
addps xmm1, xmm2
|
|
||||||
addps xmm2, xmm3
|
|
||||||
addps xmm3, xmm4
|
|
||||||
addps xmm4, xmm5
|
|
||||||
addps xmm5, xmm6
|
|
||||||
addps xmm6, xmm7
|
|
||||||
addps xmm7, xmm0
|
|
||||||
; 7:
|
|
||||||
addps xmm0, xmm1
|
|
||||||
addps xmm1, xmm2
|
|
||||||
addps xmm2, xmm3
|
|
||||||
addps xmm3, xmm4
|
|
||||||
addps xmm4, xmm5
|
|
||||||
addps xmm5, xmm6
|
|
||||||
addps xmm6, xmm7
|
|
||||||
addps xmm7, xmm0
|
|
||||||
; 8:
|
|
||||||
addps xmm0, xmm1
|
|
||||||
addps xmm1, xmm2
|
|
||||||
addps xmm2, xmm3
|
|
||||||
addps xmm3, xmm4
|
|
||||||
addps xmm4, xmm5
|
|
||||||
addps xmm5, xmm6
|
|
||||||
addps xmm6, xmm7
|
|
||||||
addps xmm7, xmm0
|
|
||||||
; 9:
|
|
||||||
addps xmm0, xmm1
|
|
||||||
addps xmm1, xmm2
|
|
||||||
addps xmm2, xmm3
|
|
||||||
addps xmm3, xmm4
|
|
||||||
addps xmm4, xmm5
|
|
||||||
addps xmm5, xmm6
|
|
||||||
addps xmm6, xmm7
|
|
||||||
addps xmm7, xmm0
|
|
||||||
; 10:
|
|
||||||
addps xmm0, xmm1
|
|
||||||
addps xmm1, xmm2
|
|
||||||
addps xmm2, xmm3
|
|
||||||
addps xmm3, xmm4
|
|
||||||
addps xmm4, xmm5
|
|
||||||
addps xmm5, xmm6
|
|
||||||
addps xmm6, xmm7
|
|
||||||
addps xmm7, xmm0
|
|
||||||
; 11:
|
|
||||||
addps xmm0, xmm1
|
|
||||||
addps xmm1, xmm2
|
|
||||||
addps xmm2, xmm3
|
|
||||||
addps xmm3, xmm4
|
|
||||||
addps xmm4, xmm5
|
|
||||||
addps xmm5, xmm6
|
|
||||||
addps xmm6, xmm7
|
|
||||||
addps xmm7, xmm0
|
|
||||||
; 12:
|
|
||||||
addps xmm0, xmm1
|
|
||||||
addps xmm1, xmm2
|
|
||||||
addps xmm2, xmm3
|
|
||||||
addps xmm3, xmm4
|
|
||||||
addps xmm4, xmm5
|
|
||||||
addps xmm5, xmm6
|
|
||||||
addps xmm6, xmm7
|
|
||||||
addps xmm7, xmm0
|
|
||||||
; 13:
|
|
||||||
addps xmm0, xmm1
|
|
||||||
addps xmm1, xmm2
|
|
||||||
addps xmm2, xmm3
|
|
||||||
addps xmm3, xmm4
|
|
||||||
addps xmm4, xmm5
|
|
||||||
addps xmm5, xmm6
|
|
||||||
addps xmm6, xmm7
|
|
||||||
addps xmm7, xmm0
|
|
||||||
; 14:
|
|
||||||
addps xmm0, xmm1
|
|
||||||
addps xmm1, xmm2
|
|
||||||
addps xmm2, xmm3
|
|
||||||
addps xmm3, xmm4
|
|
||||||
addps xmm4, xmm5
|
|
||||||
addps xmm5, xmm6
|
|
||||||
addps xmm6, xmm7
|
|
||||||
addps xmm7, xmm0
|
|
||||||
; 15:
|
|
||||||
addps xmm0, xmm1
|
|
||||||
addps xmm1, xmm2
|
|
||||||
addps xmm2, xmm3
|
|
||||||
addps xmm3, xmm4
|
|
||||||
addps xmm4, xmm5
|
|
||||||
addps xmm5, xmm6
|
|
||||||
addps xmm6, xmm7
|
|
||||||
addps xmm7, xmm0
|
|
||||||
; 16:
|
|
||||||
addps xmm0, xmm1
|
|
||||||
addps xmm1, xmm2
|
|
||||||
addps xmm2, xmm3
|
|
||||||
addps xmm3, xmm4
|
|
||||||
addps xmm4, xmm5
|
|
||||||
addps xmm5, xmm6
|
|
||||||
addps xmm6, xmm7
|
|
||||||
addps xmm7, xmm0
|
|
||||||
; 17:
|
|
||||||
addps xmm0, xmm1
|
|
||||||
addps xmm1, xmm2
|
|
||||||
addps xmm2, xmm3
|
|
||||||
addps xmm3, xmm4
|
|
||||||
addps xmm4, xmm5
|
|
||||||
addps xmm5, xmm6
|
|
||||||
addps xmm6, xmm7
|
|
||||||
addps xmm7, xmm0
|
|
||||||
; 18:
|
|
||||||
addps xmm0, xmm1
|
|
||||||
addps xmm1, xmm2
|
|
||||||
addps xmm2, xmm3
|
|
||||||
addps xmm3, xmm4
|
|
||||||
addps xmm4, xmm5
|
|
||||||
addps xmm5, xmm6
|
|
||||||
addps xmm6, xmm7
|
|
||||||
addps xmm7, xmm0
|
|
||||||
; 19:
|
|
||||||
addps xmm0, xmm1
|
|
||||||
addps xmm1, xmm2
|
|
||||||
addps xmm2, xmm3
|
|
||||||
addps xmm3, xmm4
|
|
||||||
addps xmm4, xmm5
|
|
||||||
addps xmm5, xmm6
|
|
||||||
addps xmm6, xmm7
|
|
||||||
addps xmm7, xmm0
|
|
||||||
; 20:
|
|
||||||
addps xmm0, xmm1
|
|
||||||
addps xmm1, xmm2
|
|
||||||
addps xmm2, xmm3
|
|
||||||
addps xmm3, xmm4
|
|
||||||
addps xmm4, xmm5
|
|
||||||
addps xmm5, xmm6
|
|
||||||
addps xmm6, xmm7
|
|
||||||
addps xmm7, xmm0
|
|
||||||
; 21:
|
|
||||||
addps xmm0, xmm1
|
|
||||||
addps xmm1, xmm2
|
|
||||||
addps xmm2, xmm3
|
|
||||||
addps xmm3, xmm4
|
|
||||||
addps xmm4, xmm5
|
|
||||||
addps xmm5, xmm6
|
|
||||||
addps xmm6, xmm7
|
|
||||||
addps xmm7, xmm0
|
|
||||||
; 22:
|
|
||||||
addps xmm0, xmm1
|
|
||||||
addps xmm1, xmm2
|
|
||||||
addps xmm2, xmm3
|
|
||||||
addps xmm3, xmm4
|
|
||||||
addps xmm4, xmm5
|
|
||||||
addps xmm5, xmm6
|
|
||||||
addps xmm6, xmm7
|
|
||||||
addps xmm7, xmm0
|
|
||||||
; 23:
|
|
||||||
addps xmm0, xmm1
|
|
||||||
addps xmm1, xmm2
|
|
||||||
addps xmm2, xmm3
|
|
||||||
addps xmm3, xmm4
|
|
||||||
addps xmm4, xmm5
|
|
||||||
addps xmm5, xmm6
|
|
||||||
addps xmm6, xmm7
|
|
||||||
addps xmm7, xmm0
|
|
||||||
; 24:
|
|
||||||
addps xmm0, xmm1
|
|
||||||
addps xmm1, xmm2
|
|
||||||
addps xmm2, xmm3
|
|
||||||
addps xmm3, xmm4
|
|
||||||
addps xmm4, xmm5
|
|
||||||
addps xmm5, xmm6
|
|
||||||
addps xmm6, xmm7
|
|
||||||
addps xmm7, xmm0
|
|
||||||
; 25:
|
|
||||||
addps xmm0, xmm1
|
|
||||||
addps xmm1, xmm2
|
|
||||||
addps xmm2, xmm3
|
|
||||||
addps xmm3, xmm4
|
|
||||||
addps xmm4, xmm5
|
|
||||||
addps xmm5, xmm6
|
|
||||||
addps xmm6, xmm7
|
|
||||||
addps xmm7, xmm0
|
|
||||||
; 26:
|
|
||||||
addps xmm0, xmm1
|
|
||||||
addps xmm1, xmm2
|
|
||||||
addps xmm2, xmm3
|
|
||||||
addps xmm3, xmm4
|
|
||||||
addps xmm4, xmm5
|
|
||||||
addps xmm5, xmm6
|
|
||||||
addps xmm6, xmm7
|
|
||||||
addps xmm7, xmm0
|
|
||||||
; 27:
|
|
||||||
addps xmm0, xmm1
|
|
||||||
addps xmm1, xmm2
|
|
||||||
addps xmm2, xmm3
|
|
||||||
addps xmm3, xmm4
|
|
||||||
addps xmm4, xmm5
|
|
||||||
addps xmm5, xmm6
|
|
||||||
addps xmm6, xmm7
|
|
||||||
addps xmm7, xmm0
|
|
||||||
; 28:
|
|
||||||
addps xmm0, xmm1
|
|
||||||
addps xmm1, xmm2
|
|
||||||
addps xmm2, xmm3
|
|
||||||
addps xmm3, xmm4
|
|
||||||
addps xmm4, xmm5
|
|
||||||
addps xmm5, xmm6
|
|
||||||
addps xmm6, xmm7
|
|
||||||
addps xmm7, xmm0
|
|
||||||
; 29:
|
|
||||||
addps xmm0, xmm1
|
|
||||||
addps xmm1, xmm2
|
|
||||||
addps xmm2, xmm3
|
|
||||||
addps xmm3, xmm4
|
|
||||||
addps xmm4, xmm5
|
|
||||||
addps xmm5, xmm6
|
|
||||||
addps xmm6, xmm7
|
|
||||||
addps xmm7, xmm0
|
|
||||||
; 30:
|
|
||||||
addps xmm0, xmm1
|
|
||||||
addps xmm1, xmm2
|
|
||||||
addps xmm2, xmm3
|
|
||||||
addps xmm3, xmm4
|
|
||||||
addps xmm4, xmm5
|
|
||||||
addps xmm5, xmm6
|
|
||||||
addps xmm6, xmm7
|
|
||||||
addps xmm7, xmm0
|
|
||||||
; 31:
|
|
||||||
addps xmm0, xmm1
|
|
||||||
addps xmm1, xmm2
|
|
||||||
addps xmm2, xmm3
|
|
||||||
addps xmm3, xmm4
|
|
||||||
addps xmm4, xmm5
|
|
||||||
addps xmm5, xmm6
|
|
||||||
addps xmm6, xmm7
|
|
||||||
addps xmm7, xmm0
|
|
||||||
; ----------------------
|
|
||||||
dec ecx
|
|
||||||
jnz bsLoop
|
|
||||||
|
|
||||||
; restore xmm6 & xmm7:
|
|
||||||
movups xmm6, [rsp + 8]
|
|
||||||
movups xmm7, [rsp + 24]
|
|
||||||
ret
|
|
||||||
busy_sse_loop endp
|
|
||||||
|
|
||||||
END
|
|
173
src/3rdparty/libcpuid/recog_amd.c
vendored
173
src/3rdparty/libcpuid/recog_amd.c
vendored
|
@ -1,173 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2008 Veselin Georgiev,
|
|
||||||
* anrieffNOSPAM @ mgail_DOT.com (convert to gmail)
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions
|
|
||||||
* are met:
|
|
||||||
*
|
|
||||||
* 1. Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
||||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
||||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
||||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
||||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
||||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
||||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
#include "libcpuid.h"
|
|
||||||
#include "libcpuid_util.h"
|
|
||||||
#include "libcpuid_internal.h"
|
|
||||||
#include "recog_amd.h"
|
|
||||||
|
|
||||||
const struct amd_code_str { amd_code_t code; char *str; } amd_code_str[] = {
|
|
||||||
#define CODE(x) { x, #x }
|
|
||||||
#define CODE2(x, y) CODE(x)
|
|
||||||
#include "amd_code_t.h"
|
|
||||||
#undef CODE
|
|
||||||
};
|
|
||||||
|
|
||||||
struct amd_code_and_bits_t {
|
|
||||||
int code;
|
|
||||||
uint64_t bits;
|
|
||||||
};
|
|
||||||
|
|
||||||
enum _amd_model_codes_t {
|
|
||||||
// Only for Ryzen CPUs:
|
|
||||||
_1400,
|
|
||||||
_1500,
|
|
||||||
_1600,
|
|
||||||
_1900,
|
|
||||||
_2400,
|
|
||||||
_2500,
|
|
||||||
_2700,
|
|
||||||
};
|
|
||||||
|
|
||||||
static void load_amd_features(struct cpu_raw_data_t* raw, struct cpu_id_t* data)
|
|
||||||
{
|
|
||||||
const struct feature_map_t matchtable_edx81[] = {
|
|
||||||
{ 20, CPU_FEATURE_NX },
|
|
||||||
{ 22, CPU_FEATURE_MMXEXT },
|
|
||||||
{ 25, CPU_FEATURE_FXSR_OPT },
|
|
||||||
{ 30, CPU_FEATURE_3DNOWEXT },
|
|
||||||
{ 31, CPU_FEATURE_3DNOW },
|
|
||||||
};
|
|
||||||
const struct feature_map_t matchtable_ecx81[] = {
|
|
||||||
{ 1, CPU_FEATURE_CMP_LEGACY },
|
|
||||||
{ 2, CPU_FEATURE_SVM },
|
|
||||||
{ 5, CPU_FEATURE_ABM },
|
|
||||||
{ 6, CPU_FEATURE_SSE4A },
|
|
||||||
{ 7, CPU_FEATURE_MISALIGNSSE },
|
|
||||||
{ 8, CPU_FEATURE_3DNOWPREFETCH },
|
|
||||||
{ 9, CPU_FEATURE_OSVW },
|
|
||||||
{ 10, CPU_FEATURE_IBS },
|
|
||||||
{ 11, CPU_FEATURE_XOP },
|
|
||||||
{ 12, CPU_FEATURE_SKINIT },
|
|
||||||
{ 13, CPU_FEATURE_WDT },
|
|
||||||
{ 16, CPU_FEATURE_FMA4 },
|
|
||||||
{ 21, CPU_FEATURE_TBM },
|
|
||||||
};
|
|
||||||
const struct feature_map_t matchtable_edx87[] = {
|
|
||||||
{ 0, CPU_FEATURE_TS },
|
|
||||||
{ 1, CPU_FEATURE_FID },
|
|
||||||
{ 2, CPU_FEATURE_VID },
|
|
||||||
{ 3, CPU_FEATURE_TTP },
|
|
||||||
{ 4, CPU_FEATURE_TM_AMD },
|
|
||||||
{ 5, CPU_FEATURE_STC },
|
|
||||||
{ 6, CPU_FEATURE_100MHZSTEPS },
|
|
||||||
{ 7, CPU_FEATURE_HWPSTATE },
|
|
||||||
/* id 8 is handled in common */
|
|
||||||
{ 9, CPU_FEATURE_CPB },
|
|
||||||
{ 10, CPU_FEATURE_APERFMPERF },
|
|
||||||
{ 11, CPU_FEATURE_PFI },
|
|
||||||
{ 12, CPU_FEATURE_PA },
|
|
||||||
};
|
|
||||||
if (raw->ext_cpuid[0][0] >= 0x80000001) {
|
|
||||||
match_features(matchtable_edx81, COUNT_OF(matchtable_edx81), raw->ext_cpuid[1][3], data);
|
|
||||||
match_features(matchtable_ecx81, COUNT_OF(matchtable_ecx81), raw->ext_cpuid[1][2], data);
|
|
||||||
}
|
|
||||||
if (raw->ext_cpuid[0][0] >= 0x80000007)
|
|
||||||
match_features(matchtable_edx87, COUNT_OF(matchtable_edx87), raw->ext_cpuid[7][3], data);
|
|
||||||
if (raw->ext_cpuid[0][0] >= 0x8000001a) {
|
|
||||||
/* We have the extended info about SSE unit size */
|
|
||||||
data->detection_hints[CPU_HINT_SSE_SIZE_AUTH] = 1;
|
|
||||||
data->sse_size = (raw->ext_cpuid[0x1a][0] & 1) ? 128 : 64;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void decode_amd_cache_info(struct cpu_raw_data_t* raw, struct cpu_id_t* data)
|
|
||||||
{
|
|
||||||
int l3_result;
|
|
||||||
const int assoc_table[16] = {
|
|
||||||
0, 1, 2, 0, 4, 0, 8, 0, 16, 0, 32, 48, 64, 96, 128, 255
|
|
||||||
};
|
|
||||||
unsigned n = raw->ext_cpuid[0][0];
|
|
||||||
|
|
||||||
if (n >= 0x80000005) {
|
|
||||||
data->l1_data_cache = (raw->ext_cpuid[5][2] >> 24) & 0xff;
|
|
||||||
data->l1_assoc = (raw->ext_cpuid[5][2] >> 16) & 0xff;
|
|
||||||
data->l1_cacheline = (raw->ext_cpuid[5][2]) & 0xff;
|
|
||||||
data->l1_instruction_cache = (raw->ext_cpuid[5][3] >> 24) & 0xff;
|
|
||||||
}
|
|
||||||
if (n >= 0x80000006) {
|
|
||||||
data->l2_cache = (raw->ext_cpuid[6][2] >> 16) & 0xffff;
|
|
||||||
data->l2_assoc = assoc_table[(raw->ext_cpuid[6][2] >> 12) & 0xf];
|
|
||||||
data->l2_cacheline = (raw->ext_cpuid[6][2]) & 0xff;
|
|
||||||
|
|
||||||
l3_result = (raw->ext_cpuid[6][3] >> 18);
|
|
||||||
if (l3_result > 0) {
|
|
||||||
l3_result = 512 * l3_result; /* AMD spec says it's a range,
|
|
||||||
but we take the lower bound */
|
|
||||||
data->l3_cache = l3_result;
|
|
||||||
data->l3_assoc = assoc_table[(raw->ext_cpuid[6][3] >> 12) & 0xf];
|
|
||||||
data->l3_cacheline = (raw->ext_cpuid[6][3]) & 0xff;
|
|
||||||
} else {
|
|
||||||
data->l3_cache = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void decode_amd_number_of_cores(struct cpu_raw_data_t* raw, struct cpu_id_t* data)
|
|
||||||
{
|
|
||||||
int logical_cpus = -1, num_cores = -1;
|
|
||||||
|
|
||||||
if (raw->basic_cpuid[0][0] >= 1) {
|
|
||||||
logical_cpus = (raw->basic_cpuid[1][1] >> 16) & 0xff;
|
|
||||||
if (raw->ext_cpuid[0][0] >= 8) {
|
|
||||||
num_cores = 1 + (raw->ext_cpuid[8][2] & 0xff);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (data->flags[CPU_FEATURE_HT]) {
|
|
||||||
if (num_cores > 1) {
|
|
||||||
if (data->ext_family >= 23)
|
|
||||||
num_cores /= 2; // e.g., Ryzen 7 reports 16 "real" cores, but they are really just 8.
|
|
||||||
data->num_cores = num_cores;
|
|
||||||
data->num_logical_cpus = logical_cpus;
|
|
||||||
} else {
|
|
||||||
data->num_cores = 1;
|
|
||||||
data->num_logical_cpus = (logical_cpus >= 2 ? logical_cpus : 2);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
data->num_cores = data->num_logical_cpus = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int cpuid_identify_amd(struct cpu_raw_data_t* raw, struct cpu_id_t* data, struct internal_id_info_t* internal)
|
|
||||||
{
|
|
||||||
load_amd_features(raw, data);
|
|
||||||
decode_amd_cache_info(raw, data);
|
|
||||||
decode_amd_number_of_cores(raw, data);
|
|
||||||
return 0;
|
|
||||||
}
|
|
31
src/3rdparty/libcpuid/recog_amd.h
vendored
31
src/3rdparty/libcpuid/recog_amd.h
vendored
|
@ -1,31 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2008 Veselin Georgiev,
|
|
||||||
* anrieffNOSPAM @ mgail_DOT.com (convert to gmail)
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions
|
|
||||||
* are met:
|
|
||||||
*
|
|
||||||
* 1. Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
||||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
||||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
||||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
||||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
||||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
||||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
#ifndef __RECOG_AMD_H__
|
|
||||||
#define __RECOG_AMD_H__
|
|
||||||
|
|
||||||
int cpuid_identify_amd(struct cpu_raw_data_t* raw, struct cpu_id_t* data, struct internal_id_info_t* internal);
|
|
||||||
|
|
||||||
#endif /* __RECOG_AMD_H__ */
|
|
543
src/3rdparty/libcpuid/recog_intel.c
vendored
543
src/3rdparty/libcpuid/recog_intel.c
vendored
|
@ -1,543 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2008 Veselin Georgiev,
|
|
||||||
* anrieffNOSPAM @ mgail_DOT.com (convert to gmail)
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions
|
|
||||||
* are met:
|
|
||||||
*
|
|
||||||
* 1. Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
||||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
||||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
||||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
||||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
||||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
||||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
#include <string.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
#include "libcpuid.h"
|
|
||||||
#include "libcpuid_util.h"
|
|
||||||
#include "libcpuid_internal.h"
|
|
||||||
#include "recog_intel.h"
|
|
||||||
|
|
||||||
const struct intel_bcode_str { intel_code_t code; char *str; } intel_bcode_str[] = {
|
|
||||||
#define CODE(x) { x, #x }
|
|
||||||
#define CODE2(x, y) CODE(x)
|
|
||||||
#include "intel_code_t.h"
|
|
||||||
#undef CODE
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
int code;
|
|
||||||
uint64_t bits;
|
|
||||||
} intel_code_and_bits_t;
|
|
||||||
|
|
||||||
enum _intel_model_t {
|
|
||||||
UNKNOWN = -1,
|
|
||||||
_3000 = 100,
|
|
||||||
_3100,
|
|
||||||
_3200,
|
|
||||||
X3200,
|
|
||||||
_3300,
|
|
||||||
X3300,
|
|
||||||
_5100,
|
|
||||||
_5200,
|
|
||||||
_5300,
|
|
||||||
_5400,
|
|
||||||
_2xxx, /* Core i[357] 2xxx */
|
|
||||||
_3xxx, /* Core i[357] 3xxx */
|
|
||||||
};
|
|
||||||
typedef enum _intel_model_t intel_model_t;
|
|
||||||
|
|
||||||
static void load_intel_features(struct cpu_raw_data_t* raw, struct cpu_id_t* data)
|
|
||||||
{
|
|
||||||
const struct feature_map_t matchtable_edx1[] = {
|
|
||||||
{ 18, CPU_FEATURE_PN },
|
|
||||||
{ 21, CPU_FEATURE_DTS },
|
|
||||||
{ 22, CPU_FEATURE_ACPI },
|
|
||||||
{ 27, CPU_FEATURE_SS },
|
|
||||||
{ 29, CPU_FEATURE_TM },
|
|
||||||
{ 30, CPU_FEATURE_IA64 },
|
|
||||||
{ 31, CPU_FEATURE_PBE },
|
|
||||||
};
|
|
||||||
const struct feature_map_t matchtable_ecx1[] = {
|
|
||||||
{ 2, CPU_FEATURE_DTS64 },
|
|
||||||
{ 4, CPU_FEATURE_DS_CPL },
|
|
||||||
{ 5, CPU_FEATURE_VMX },
|
|
||||||
{ 6, CPU_FEATURE_SMX },
|
|
||||||
{ 7, CPU_FEATURE_EST },
|
|
||||||
{ 8, CPU_FEATURE_TM2 },
|
|
||||||
{ 10, CPU_FEATURE_CID },
|
|
||||||
{ 14, CPU_FEATURE_XTPR },
|
|
||||||
{ 15, CPU_FEATURE_PDCM },
|
|
||||||
{ 18, CPU_FEATURE_DCA },
|
|
||||||
{ 21, CPU_FEATURE_X2APIC },
|
|
||||||
};
|
|
||||||
const struct feature_map_t matchtable_edx81[] = {
|
|
||||||
{ 20, CPU_FEATURE_XD },
|
|
||||||
};
|
|
||||||
const struct feature_map_t matchtable_ebx7[] = {
|
|
||||||
{ 2, CPU_FEATURE_SGX },
|
|
||||||
{ 4, CPU_FEATURE_HLE },
|
|
||||||
{ 11, CPU_FEATURE_RTM },
|
|
||||||
{ 16, CPU_FEATURE_AVX512F },
|
|
||||||
{ 17, CPU_FEATURE_AVX512DQ },
|
|
||||||
{ 18, CPU_FEATURE_RDSEED },
|
|
||||||
{ 19, CPU_FEATURE_ADX },
|
|
||||||
{ 26, CPU_FEATURE_AVX512PF },
|
|
||||||
{ 27, CPU_FEATURE_AVX512ER },
|
|
||||||
{ 28, CPU_FEATURE_AVX512CD },
|
|
||||||
{ 29, CPU_FEATURE_SHA_NI },
|
|
||||||
{ 30, CPU_FEATURE_AVX512BW },
|
|
||||||
{ 31, CPU_FEATURE_AVX512VL },
|
|
||||||
};
|
|
||||||
if (raw->basic_cpuid[0][0] >= 1) {
|
|
||||||
match_features(matchtable_edx1, COUNT_OF(matchtable_edx1), raw->basic_cpuid[1][3], data);
|
|
||||||
match_features(matchtable_ecx1, COUNT_OF(matchtable_ecx1), raw->basic_cpuid[1][2], data);
|
|
||||||
}
|
|
||||||
if (raw->ext_cpuid[0][0] >= 1) {
|
|
||||||
match_features(matchtable_edx81, COUNT_OF(matchtable_edx81), raw->ext_cpuid[1][3], data);
|
|
||||||
}
|
|
||||||
// detect TSX/AVX512:
|
|
||||||
if (raw->basic_cpuid[0][0] >= 7) {
|
|
||||||
match_features(matchtable_ebx7, COUNT_OF(matchtable_ebx7), raw->basic_cpuid[7][1], data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
enum _cache_type_t {
|
|
||||||
L1I,
|
|
||||||
L1D,
|
|
||||||
L2,
|
|
||||||
L3,
|
|
||||||
L4
|
|
||||||
};
|
|
||||||
typedef enum _cache_type_t cache_type_t;
|
|
||||||
|
|
||||||
static void check_case(uint8_t on, cache_type_t cache, int size, int assoc, int linesize, struct cpu_id_t* data)
|
|
||||||
{
|
|
||||||
if (!on) return;
|
|
||||||
switch (cache) {
|
|
||||||
case L1I:
|
|
||||||
data->l1_instruction_cache = size;
|
|
||||||
break;
|
|
||||||
case L1D:
|
|
||||||
data->l1_data_cache = size;
|
|
||||||
data->l1_assoc = assoc;
|
|
||||||
data->l1_cacheline = linesize;
|
|
||||||
break;
|
|
||||||
case L2:
|
|
||||||
data->l2_cache = size;
|
|
||||||
data->l2_assoc = assoc;
|
|
||||||
data->l2_cacheline = linesize;
|
|
||||||
break;
|
|
||||||
case L3:
|
|
||||||
data->l3_cache = size;
|
|
||||||
data->l3_assoc = assoc;
|
|
||||||
data->l3_cacheline = linesize;
|
|
||||||
break;
|
|
||||||
case L4:
|
|
||||||
data->l4_cache = size;
|
|
||||||
data->l4_assoc = assoc;
|
|
||||||
data->l4_cacheline = linesize;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void decode_intel_oldstyle_cache_info(struct cpu_raw_data_t* raw, struct cpu_id_t* data)
|
|
||||||
{
|
|
||||||
uint8_t f[256] = {0};
|
|
||||||
int reg, off;
|
|
||||||
uint32_t x;
|
|
||||||
for (reg = 0; reg < 4; reg++) {
|
|
||||||
x = raw->basic_cpuid[2][reg];
|
|
||||||
if (x & 0x80000000) continue;
|
|
||||||
for (off = 0; off < 4; off++) {
|
|
||||||
f[x & 0xff] = 1;
|
|
||||||
x >>= 8;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
check_case(f[0x06], L1I, 8, 4, 32, data);
|
|
||||||
check_case(f[0x08], L1I, 16, 4, 32, data);
|
|
||||||
check_case(f[0x0A], L1D, 8, 2, 32, data);
|
|
||||||
check_case(f[0x0C], L1D, 16, 4, 32, data);
|
|
||||||
check_case(f[0x22], L3, 512, 4, 64, data);
|
|
||||||
check_case(f[0x23], L3, 1024, 8, 64, data);
|
|
||||||
check_case(f[0x25], L3, 2048, 8, 64, data);
|
|
||||||
check_case(f[0x29], L3, 4096, 8, 64, data);
|
|
||||||
check_case(f[0x2C], L1D, 32, 8, 64, data);
|
|
||||||
check_case(f[0x30], L1I, 32, 8, 64, data);
|
|
||||||
check_case(f[0x39], L2, 128, 4, 64, data);
|
|
||||||
check_case(f[0x3A], L2, 192, 6, 64, data);
|
|
||||||
check_case(f[0x3B], L2, 128, 2, 64, data);
|
|
||||||
check_case(f[0x3C], L2, 256, 4, 64, data);
|
|
||||||
check_case(f[0x3D], L2, 384, 6, 64, data);
|
|
||||||
check_case(f[0x3E], L2, 512, 4, 64, data);
|
|
||||||
check_case(f[0x41], L2, 128, 4, 32, data);
|
|
||||||
check_case(f[0x42], L2, 256, 4, 32, data);
|
|
||||||
check_case(f[0x43], L2, 512, 4, 32, data);
|
|
||||||
check_case(f[0x44], L2, 1024, 4, 32, data);
|
|
||||||
check_case(f[0x45], L2, 2048, 4, 32, data);
|
|
||||||
check_case(f[0x46], L3, 4096, 4, 64, data);
|
|
||||||
check_case(f[0x47], L3, 8192, 8, 64, data);
|
|
||||||
check_case(f[0x4A], L3, 6144, 12, 64, data);
|
|
||||||
check_case(f[0x4B], L3, 8192, 16, 64, data);
|
|
||||||
check_case(f[0x4C], L3, 12288, 12, 64, data);
|
|
||||||
check_case(f[0x4D], L3, 16384, 16, 64, data);
|
|
||||||
check_case(f[0x4E], L2, 6144, 24, 64, data);
|
|
||||||
check_case(f[0x60], L1D, 16, 8, 64, data);
|
|
||||||
check_case(f[0x66], L1D, 8, 4, 64, data);
|
|
||||||
check_case(f[0x67], L1D, 16, 4, 64, data);
|
|
||||||
check_case(f[0x68], L1D, 32, 4, 64, data);
|
|
||||||
/* The following four entries are trace cache. Intel does not
|
|
||||||
* specify a cache-line size, so we use -1 instead
|
|
||||||
*/
|
|
||||||
check_case(f[0x70], L1I, 12, 8, -1, data);
|
|
||||||
check_case(f[0x71], L1I, 16, 8, -1, data);
|
|
||||||
check_case(f[0x72], L1I, 32, 8, -1, data);
|
|
||||||
check_case(f[0x73], L1I, 64, 8, -1, data);
|
|
||||||
|
|
||||||
check_case(f[0x78], L2, 1024, 4, 64, data);
|
|
||||||
check_case(f[0x79], L2, 128, 8, 64, data);
|
|
||||||
check_case(f[0x7A], L2, 256, 8, 64, data);
|
|
||||||
check_case(f[0x7B], L2, 512, 8, 64, data);
|
|
||||||
check_case(f[0x7C], L2, 1024, 8, 64, data);
|
|
||||||
check_case(f[0x7D], L2, 2048, 8, 64, data);
|
|
||||||
check_case(f[0x7F], L2, 512, 2, 64, data);
|
|
||||||
check_case(f[0x82], L2, 256, 8, 32, data);
|
|
||||||
check_case(f[0x83], L2, 512, 8, 32, data);
|
|
||||||
check_case(f[0x84], L2, 1024, 8, 32, data);
|
|
||||||
check_case(f[0x85], L2, 2048, 8, 32, data);
|
|
||||||
check_case(f[0x86], L2, 512, 4, 64, data);
|
|
||||||
check_case(f[0x87], L2, 1024, 8, 64, data);
|
|
||||||
|
|
||||||
if (f[0x49]) {
|
|
||||||
/* This flag is overloaded with two meanings. On Xeon MP
|
|
||||||
* (family 0xf, model 0x6) this means L3 cache. On all other
|
|
||||||
* CPUs (notably Conroe et al), this is L2 cache. In both cases
|
|
||||||
* it means 4MB, 16-way associative, 64-byte line size.
|
|
||||||
*/
|
|
||||||
if (data->family == 0xf && data->model == 0x6) {
|
|
||||||
data->l3_cache = 4096;
|
|
||||||
data->l3_assoc = 16;
|
|
||||||
data->l3_cacheline = 64;
|
|
||||||
} else {
|
|
||||||
data->l2_cache = 4096;
|
|
||||||
data->l2_assoc = 16;
|
|
||||||
data->l2_cacheline = 64;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (f[0x40]) {
|
|
||||||
/* Again, a special flag. It means:
|
|
||||||
* 1) If no L2 is specified, then CPU is w/o L2 (0 KB)
|
|
||||||
* 2) If L2 is specified by other flags, then, CPU is w/o L3.
|
|
||||||
*/
|
|
||||||
if (data->l2_cache == -1) {
|
|
||||||
data->l2_cache = 0;
|
|
||||||
} else {
|
|
||||||
data->l3_cache = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void decode_intel_deterministic_cache_info(struct cpu_raw_data_t* raw,
|
|
||||||
struct cpu_id_t* data)
|
|
||||||
{
|
|
||||||
int ecx;
|
|
||||||
int ways, partitions, linesize, sets, size, level, typenumber;
|
|
||||||
cache_type_t type;
|
|
||||||
for (ecx = 0; ecx < MAX_INTELFN4_LEVEL; ecx++) {
|
|
||||||
typenumber = raw->intel_fn4[ecx][0] & 0x1f;
|
|
||||||
if (typenumber == 0) break;
|
|
||||||
level = (raw->intel_fn4[ecx][0] >> 5) & 0x7;
|
|
||||||
if (level == 1 && typenumber == 1)
|
|
||||||
type = L1D;
|
|
||||||
else if (level == 1 && typenumber == 2)
|
|
||||||
type = L1I;
|
|
||||||
else if (level == 2 && typenumber == 3)
|
|
||||||
type = L2;
|
|
||||||
else if (level == 3 && typenumber == 3)
|
|
||||||
type = L3;
|
|
||||||
else if (level == 4 && typenumber == 3)
|
|
||||||
type = L4;
|
|
||||||
else {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
ways = ((raw->intel_fn4[ecx][1] >> 22) & 0x3ff) + 1;
|
|
||||||
partitions = ((raw->intel_fn4[ecx][1] >> 12) & 0x3ff) + 1;
|
|
||||||
linesize = (raw->intel_fn4[ecx][1] & 0xfff) + 1;
|
|
||||||
sets = raw->intel_fn4[ecx][2] + 1;
|
|
||||||
size = ways * partitions * linesize * sets / 1024;
|
|
||||||
check_case(1, type, size, ways, linesize, data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int decode_intel_extended_topology(struct cpu_raw_data_t* raw,
|
|
||||||
struct cpu_id_t* data)
|
|
||||||
{
|
|
||||||
int i, level_type, num_smt = -1, num_core = -1;
|
|
||||||
for (i = 0; i < MAX_INTELFN11_LEVEL; i++) {
|
|
||||||
level_type = (raw->intel_fn11[i][2] & 0xff00) >> 8;
|
|
||||||
switch (level_type) {
|
|
||||||
case 0x01:
|
|
||||||
num_smt = raw->intel_fn11[i][1] & 0xffff;
|
|
||||||
break;
|
|
||||||
case 0x02:
|
|
||||||
num_core = raw->intel_fn11[i][1] & 0xffff;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (num_smt == -1 || num_core == -1) return 0;
|
|
||||||
data->num_logical_cpus = num_core;
|
|
||||||
data->num_cores = num_core / num_smt;
|
|
||||||
// make sure num_cores is at least 1. In VMs, the CPUID instruction
|
|
||||||
// is rigged and may give nonsensical results, but we should at least
|
|
||||||
// avoid outputs like data->num_cores == 0.
|
|
||||||
if (data->num_cores <= 0) data->num_cores = 1;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void decode_intel_number_of_cores(struct cpu_raw_data_t* raw,
|
|
||||||
struct cpu_id_t* data)
|
|
||||||
{
|
|
||||||
int logical_cpus = -1, num_cores = -1;
|
|
||||||
|
|
||||||
if (raw->basic_cpuid[0][0] >= 11) {
|
|
||||||
if (decode_intel_extended_topology(raw, data)) return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (raw->basic_cpuid[0][0] >= 1) {
|
|
||||||
logical_cpus = (raw->basic_cpuid[1][1] >> 16) & 0xff;
|
|
||||||
if (raw->basic_cpuid[0][0] >= 4) {
|
|
||||||
num_cores = 1 + ((raw->basic_cpuid[4][0] >> 26) & 0x3f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (data->flags[CPU_FEATURE_HT]) {
|
|
||||||
if (num_cores > 1) {
|
|
||||||
data->num_cores = num_cores;
|
|
||||||
data->num_logical_cpus = logical_cpus;
|
|
||||||
} else {
|
|
||||||
data->num_cores = 1;
|
|
||||||
data->num_logical_cpus = (logical_cpus >= 1 ? logical_cpus : 1);
|
|
||||||
if (data->num_logical_cpus == 1)
|
|
||||||
data->flags[CPU_FEATURE_HT] = 0;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
data->num_cores = data->num_logical_cpus = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static intel_code_and_bits_t get_brand_code_and_bits(struct cpu_id_t* data)
|
|
||||||
{
|
|
||||||
intel_code_t code = (intel_code_t) NC;
|
|
||||||
intel_code_and_bits_t result;
|
|
||||||
uint64_t bits = 0;
|
|
||||||
int i = 0;
|
|
||||||
const char* bs = data->brand_str;
|
|
||||||
const char* s;
|
|
||||||
const struct { intel_code_t c; const char *search; } matchtable[] = {
|
|
||||||
{ PENTIUM_M, "Pentium(R) M" },
|
|
||||||
{ CORE_SOLO, "Pentium(R) Dual CPU" },
|
|
||||||
{ CORE_SOLO, "Pentium(R) Dual-Core" },
|
|
||||||
{ PENTIUM_D, "Pentium(R) D" },
|
|
||||||
{ CORE_SOLO, "Genuine Intel(R) CPU" },
|
|
||||||
{ CORE_SOLO, "Intel(R) Core(TM)" },
|
|
||||||
{ DIAMONDVILLE, "CPU [N ][23]## " },
|
|
||||||
{ SILVERTHORNE, "CPU Z" },
|
|
||||||
{ PINEVIEW, "CPU [ND][45]## " },
|
|
||||||
{ CEDARVIEW, "CPU [ND]#### " },
|
|
||||||
};
|
|
||||||
|
|
||||||
const struct { uint64_t bit; const char* search; } bit_matchtable[] = {
|
|
||||||
{ XEON_, "Xeon" },
|
|
||||||
{ _MP_, " MP" },
|
|
||||||
{ ATOM_, "Atom(TM) CPU" },
|
|
||||||
{ MOBILE_, "Mobile" },
|
|
||||||
{ CELERON_, "Celeron" },
|
|
||||||
{ PENTIUM_, "Pentium" },
|
|
||||||
};
|
|
||||||
|
|
||||||
for (i = 0; i < COUNT_OF(bit_matchtable); i++) {
|
|
||||||
if (match_pattern(bs, bit_matchtable[i].search))
|
|
||||||
bits |= bit_matchtable[i].bit;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((i = match_pattern(bs, "Core(TM) [im][3579]")) != 0) {
|
|
||||||
bits |= CORE_;
|
|
||||||
i--;
|
|
||||||
switch (bs[i + 9]) {
|
|
||||||
case 'i': bits |= _I_; break;
|
|
||||||
case 'm': bits |= _M_; break;
|
|
||||||
}
|
|
||||||
switch (bs[i + 10]) {
|
|
||||||
case '3': bits |= _3; break;
|
|
||||||
case '5': bits |= _5; break;
|
|
||||||
case '7': bits |= _7; break;
|
|
||||||
case '9': bits |= _9; break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (i = 0; i < COUNT_OF(matchtable); i++)
|
|
||||||
if (match_pattern(bs, matchtable[i].search)) {
|
|
||||||
code = matchtable[i].c;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (bits & XEON_) {
|
|
||||||
if (match_pattern(bs, "W35##") || match_pattern(bs, "[ELXW]75##"))
|
|
||||||
bits |= _7;
|
|
||||||
else if (match_pattern(bs, "[ELXW]55##"))
|
|
||||||
code = GAINESTOWN;
|
|
||||||
else if (match_pattern(bs, "[ELXW]56##"))
|
|
||||||
code = WESTMERE;
|
|
||||||
else if (data->l3_cache > 0 && data->family == 16)
|
|
||||||
/* restrict by family, since later Xeons also have L3 ... */
|
|
||||||
code = IRWIN;
|
|
||||||
}
|
|
||||||
if (match_all(bits, XEON_ + _MP_) && data->l3_cache > 0)
|
|
||||||
code = POTOMAC;
|
|
||||||
if (code == CORE_SOLO) {
|
|
||||||
s = strstr(bs, "CPU");
|
|
||||||
if (s) {
|
|
||||||
s += 3;
|
|
||||||
while (*s == ' ') s++;
|
|
||||||
if (*s == 'T')
|
|
||||||
bits |= MOBILE_;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (code == CORE_SOLO) {
|
|
||||||
switch (data->num_cores) {
|
|
||||||
case 1: break;
|
|
||||||
case 2:
|
|
||||||
{
|
|
||||||
code = CORE_DUO;
|
|
||||||
if (data->num_logical_cpus > 2)
|
|
||||||
code = DUAL_CORE_HT;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 4:
|
|
||||||
{
|
|
||||||
code = QUAD_CORE;
|
|
||||||
if (data->num_logical_cpus > 4)
|
|
||||||
code = QUAD_CORE_HT;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
code = MORE_THAN_QUADCORE; break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (code == CORE_DUO && (bits & MOBILE_) && data->model != 14) {
|
|
||||||
if (data->ext_model < 23) {
|
|
||||||
code = MEROM;
|
|
||||||
} else {
|
|
||||||
code = PENRYN;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (data->ext_model == 23 &&
|
|
||||||
(code == CORE_DUO || code == PENTIUM_D || (bits & CELERON_))) {
|
|
||||||
code = WOLFDALE;
|
|
||||||
}
|
|
||||||
|
|
||||||
result.code = code;
|
|
||||||
result.bits = bits;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void decode_intel_sgx_features(const struct cpu_raw_data_t* raw, struct cpu_id_t* data)
|
|
||||||
{
|
|
||||||
struct cpu_epc_t epc;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (raw->basic_cpuid[0][0] < 0x12) return; // no 12h leaf
|
|
||||||
if (raw->basic_cpuid[0x12][0] == 0) return; // no sub-leafs available, probably it's disabled by BIOS
|
|
||||||
|
|
||||||
// decode sub-leaf 0:
|
|
||||||
if (raw->basic_cpuid[0x12][0] & 1) data->sgx.flags[INTEL_SGX1] = 1;
|
|
||||||
if (raw->basic_cpuid[0x12][0] & 2) data->sgx.flags[INTEL_SGX2] = 1;
|
|
||||||
if (data->sgx.flags[INTEL_SGX1] || data->sgx.flags[INTEL_SGX2])
|
|
||||||
data->sgx.present = 1;
|
|
||||||
data->sgx.misc_select = raw->basic_cpuid[0x12][1];
|
|
||||||
data->sgx.max_enclave_32bit = (raw->basic_cpuid[0x12][3] ) & 0xff;
|
|
||||||
data->sgx.max_enclave_64bit = (raw->basic_cpuid[0x12][3] >> 8) & 0xff;
|
|
||||||
|
|
||||||
// decode sub-leaf 1:
|
|
||||||
data->sgx.secs_attributes = raw->intel_fn12h[1][0] | (((uint64_t) raw->intel_fn12h[1][1]) << 32);
|
|
||||||
data->sgx.secs_xfrm = raw->intel_fn12h[1][2] | (((uint64_t) raw->intel_fn12h[1][3]) << 32);
|
|
||||||
|
|
||||||
// decode higher-order subleafs, whenever present:
|
|
||||||
data->sgx.num_epc_sections = -1;
|
|
||||||
for (i = 0; i < 1000000; i++) {
|
|
||||||
epc = cpuid_get_epc(i, raw);
|
|
||||||
if (epc.length == 0) {
|
|
||||||
data->sgx.num_epc_sections = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (data->sgx.num_epc_sections == -1) {
|
|
||||||
data->sgx.num_epc_sections = 1000000;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct cpu_epc_t cpuid_get_epc(int index, const struct cpu_raw_data_t* raw)
|
|
||||||
{
|
|
||||||
uint32_t regs[4];
|
|
||||||
struct cpu_epc_t retval = {0, 0};
|
|
||||||
if (raw && index < MAX_INTELFN12H_LEVEL - 2) {
|
|
||||||
// this was queried already, use the data:
|
|
||||||
memcpy(regs, raw->intel_fn12h[2 + index], sizeof(regs));
|
|
||||||
} else {
|
|
||||||
// query this ourselves:
|
|
||||||
regs[0] = 0x12;
|
|
||||||
regs[2] = 2 + index;
|
|
||||||
regs[1] = regs[3] = 0;
|
|
||||||
cpu_exec_cpuid_ext(regs);
|
|
||||||
}
|
|
||||||
|
|
||||||
// decode values:
|
|
||||||
if ((regs[0] & 0xf) == 0x1) {
|
|
||||||
retval.start_addr |= (regs[0] & 0xfffff000); // bits [12, 32) -> bits [12, 32)
|
|
||||||
retval.start_addr |= ((uint64_t) (regs[1] & 0x000fffff)) << 32; // bits [0, 20) -> bits [32, 52)
|
|
||||||
retval.length |= (regs[2] & 0xfffff000); // bits [12, 32) -> bits [12, 32)
|
|
||||||
retval.length |= ((uint64_t) (regs[3] & 0x000fffff)) << 32; // bits [0, 20) -> bits [32, 52)
|
|
||||||
}
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
int cpuid_identify_intel(struct cpu_raw_data_t* raw, struct cpu_id_t* data, struct internal_id_info_t* internal)
|
|
||||||
{
|
|
||||||
intel_code_and_bits_t brand;
|
|
||||||
|
|
||||||
load_intel_features(raw, data);
|
|
||||||
if (raw->basic_cpuid[0][0] >= 4) {
|
|
||||||
/* Deterministic way is preferred, being more generic */
|
|
||||||
decode_intel_deterministic_cache_info(raw, data);
|
|
||||||
} else if (raw->basic_cpuid[0][0] >= 2) {
|
|
||||||
decode_intel_oldstyle_cache_info(raw, data);
|
|
||||||
}
|
|
||||||
decode_intel_number_of_cores(raw, data);
|
|
||||||
|
|
||||||
brand = get_brand_code_and_bits(data);
|
|
||||||
|
|
||||||
internal->code.intel = brand.code;
|
|
||||||
internal->bits = brand.bits;
|
|
||||||
|
|
||||||
if (data->flags[CPU_FEATURE_SGX]) {
|
|
||||||
// if SGX is indicated by the CPU, verify its presence:
|
|
||||||
decode_intel_sgx_features(raw, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
31
src/3rdparty/libcpuid/recog_intel.h
vendored
31
src/3rdparty/libcpuid/recog_intel.h
vendored
|
@ -1,31 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2008 Veselin Georgiev,
|
|
||||||
* anrieffNOSPAM @ mgail_DOT.com (convert to gmail)
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions
|
|
||||||
* are met:
|
|
||||||
*
|
|
||||||
* 1. Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
||||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
||||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
||||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
||||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
||||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
||||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
#ifndef __RECOG_INTEL_H__
|
|
||||||
#define __RECOG_INTEL_H__
|
|
||||||
|
|
||||||
int cpuid_identify_intel(struct cpu_raw_data_t* raw, struct cpu_id_t* data, struct internal_id_info_t* internal);
|
|
||||||
|
|
||||||
#endif /*__RECOG_INTEL_H__*/
|
|
|
@ -95,7 +95,7 @@ static void print_cpu(Config *)
|
||||||
info->isX64() ? GREEN_BOLD_S : RED_BOLD_S "-",
|
info->isX64() ? GREEN_BOLD_S : RED_BOLD_S "-",
|
||||||
info->hasAES() ? GREEN_BOLD_S : RED_BOLD_S "-"
|
info->hasAES() ? GREEN_BOLD_S : RED_BOLD_S "-"
|
||||||
);
|
);
|
||||||
# if defined(XMRIG_FEATURE_LIBCPUID) || defined (XMRIG_FEATURE_HWLOC)
|
# if defined(XMRIG_FEATURE_HWLOC)
|
||||||
Log::print(WHITE_BOLD(" %-13s") BLACK_BOLD("L2:") WHITE_BOLD("%.1f MB") BLACK_BOLD(" L3:") WHITE_BOLD("%.1f MB")
|
Log::print(WHITE_BOLD(" %-13s") BLACK_BOLD("L2:") WHITE_BOLD("%.1f MB") BLACK_BOLD(" L3:") WHITE_BOLD("%.1f MB")
|
||||||
CYAN_BOLD(" %zu") "C" BLACK_BOLD("/") CYAN_BOLD("%zu") "T"
|
CYAN_BOLD(" %zu") "C" BLACK_BOLD("/") CYAN_BOLD("%zu") "T"
|
||||||
# ifdef XMRIG_FEATURE_HWLOC
|
# ifdef XMRIG_FEATURE_HWLOC
|
||||||
|
|
|
@ -1,12 +1,6 @@
|
||||||
/* XMRig
|
/* XMRig
|
||||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
|
||||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
|
||||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
|
||||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
|
||||||
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
|
|
||||||
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -32,8 +26,6 @@
|
||||||
|
|
||||||
#if defined(XMRIG_FEATURE_HWLOC)
|
#if defined(XMRIG_FEATURE_HWLOC)
|
||||||
# include "backend/cpu/platform/HwlocCpuInfo.h"
|
# include "backend/cpu/platform/HwlocCpuInfo.h"
|
||||||
#elif defined(XMRIG_FEATURE_LIBCPUID)
|
|
||||||
# include "backend/cpu/platform/AdvancedCpuInfo.h"
|
|
||||||
#else
|
#else
|
||||||
# include "backend/cpu/platform/BasicCpuInfo.h"
|
# include "backend/cpu/platform/BasicCpuInfo.h"
|
||||||
#endif
|
#endif
|
||||||
|
@ -47,8 +39,6 @@ xmrig::ICpuInfo *xmrig::Cpu::info()
|
||||||
if (cpuInfo == nullptr) {
|
if (cpuInfo == nullptr) {
|
||||||
# if defined(XMRIG_FEATURE_HWLOC)
|
# if defined(XMRIG_FEATURE_HWLOC)
|
||||||
cpuInfo = new HwlocCpuInfo();
|
cpuInfo = new HwlocCpuInfo();
|
||||||
# elif defined(XMRIG_FEATURE_LIBCPUID)
|
|
||||||
cpuInfo = new AdvancedCpuInfo();
|
|
||||||
# else
|
# else
|
||||||
cpuInfo = new BasicCpuInfo();
|
cpuInfo = new BasicCpuInfo();
|
||||||
# endif
|
# endif
|
||||||
|
|
|
@ -1,12 +1,6 @@
|
||||||
/* XMRig
|
/* XMRig
|
||||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
|
||||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
|
||||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
|
||||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
|
||||||
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
|
|
||||||
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
set(HEADERS_BACKEND_CPU
|
set(HEADERS_BACKEND_CPU
|
||||||
src/backend/cpu/Cpu.h
|
src/backend/cpu/Cpu.h
|
||||||
src/backend/cpu/CpuBackend.h
|
src/backend/cpu/CpuBackend.h
|
||||||
src/backend/cpu/CpuConfig.h
|
|
||||||
src/backend/cpu/CpuConfig_gen.h
|
src/backend/cpu/CpuConfig_gen.h
|
||||||
|
src/backend/cpu/CpuConfig.h
|
||||||
src/backend/cpu/CpuLaunchData.cpp
|
src/backend/cpu/CpuLaunchData.cpp
|
||||||
src/backend/cpu/CpuThread.h
|
src/backend/cpu/CpuThread.h
|
||||||
src/backend/cpu/CpuThreads.h
|
src/backend/cpu/CpuThreads.h
|
||||||
src/backend/cpu/CpuWorker.h
|
src/backend/cpu/CpuWorker.h
|
||||||
src/backend/cpu/interfaces/ICpuInfo.h
|
src/backend/cpu/interfaces/ICpuInfo.h
|
||||||
|
src/backend/cpu/platform/BasicCpuInfo.h
|
||||||
)
|
)
|
||||||
|
|
||||||
set(SOURCES_BACKEND_CPU
|
set(SOURCES_BACKEND_CPU
|
||||||
|
@ -20,7 +21,6 @@ set(SOURCES_BACKEND_CPU
|
||||||
src/backend/cpu/CpuWorker.cpp
|
src/backend/cpu/CpuWorker.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
if (WITH_HWLOC)
|
if (WITH_HWLOC)
|
||||||
if (CMAKE_CXX_COMPILER_ID MATCHES MSVC)
|
if (CMAKE_CXX_COMPILER_ID MATCHES MSVC)
|
||||||
add_subdirectory(src/3rdparty/hwloc)
|
add_subdirectory(src/3rdparty/hwloc)
|
||||||
|
@ -32,51 +32,26 @@ if (WITH_HWLOC)
|
||||||
set(CPUID_LIB ${HWLOC_LIBRARY})
|
set(CPUID_LIB ${HWLOC_LIBRARY})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(WITH_LIBCPUID OFF)
|
|
||||||
|
|
||||||
remove_definitions(/DXMRIG_FEATURE_LIBCPUID)
|
|
||||||
add_definitions(/DXMRIG_FEATURE_HWLOC)
|
add_definitions(/DXMRIG_FEATURE_HWLOC)
|
||||||
|
|
||||||
if (HWLOC_DEBUG)
|
if (HWLOC_DEBUG)
|
||||||
add_definitions(/DXMRIG_HWLOC_DEBUG)
|
add_definitions(/DXMRIG_HWLOC_DEBUG)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(SOURCES_CPUID
|
list(APPEND HEADERS_BACKEND_CPU src/backend/cpu/platform/HwlocCpuInfo.h)
|
||||||
src/backend/cpu/platform/BasicCpuInfo.h
|
list(APPEND SOURCES_BACKEND_CPU src/backend/cpu/platform/HwlocCpuInfo.cpp)
|
||||||
src/backend/cpu/platform/HwlocCpuInfo.cpp
|
|
||||||
src/backend/cpu/platform/HwlocCpuInfo.h
|
|
||||||
)
|
|
||||||
elseif (WITH_LIBCPUID)
|
|
||||||
message(WARNING, "libcpuid support is deprecated and will be removed in future versions.")
|
|
||||||
set(WITH_HWLOC OFF)
|
|
||||||
|
|
||||||
add_subdirectory(src/3rdparty/libcpuid)
|
|
||||||
include_directories(src/3rdparty/libcpuid)
|
|
||||||
|
|
||||||
add_definitions(/DXMRIG_FEATURE_LIBCPUID)
|
|
||||||
remove_definitions(/DXMRIG_FEATURE_HWLOC)
|
|
||||||
|
|
||||||
set(CPUID_LIB cpuid)
|
|
||||||
set(SOURCES_CPUID
|
|
||||||
src/backend/cpu/platform/AdvancedCpuInfo.cpp
|
|
||||||
src/backend/cpu/platform/AdvancedCpuInfo.h
|
|
||||||
)
|
|
||||||
else()
|
else()
|
||||||
remove_definitions(/DXMRIG_FEATURE_LIBCPUID)
|
|
||||||
remove_definitions(/DXMRIG_FEATURE_HWLOC)
|
remove_definitions(/DXMRIG_FEATURE_HWLOC)
|
||||||
|
|
||||||
set(CPUID_LIB "")
|
set(CPUID_LIB "")
|
||||||
set(SOURCES_CPUID
|
|
||||||
src/backend/cpu/platform/BasicCpuInfo.h
|
|
||||||
)
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (XMRIG_ARM)
|
if (XMRIG_ARM)
|
||||||
list(APPEND SOURCES_CPUID src/backend/cpu/platform/BasicCpuInfo_arm.cpp)
|
list(APPEND SOURCES_BACKEND_CPU src/backend/cpu/platform/BasicCpuInfo_arm.cpp)
|
||||||
|
|
||||||
if (XMRIG_OS_UNIX)
|
if (XMRIG_OS_UNIX)
|
||||||
list(APPEND SOURCES_CPUID src/backend/cpu/platform/lscpu_arm.cpp)
|
list(APPEND SOURCES_BACKEND_CPU src/backend/cpu/platform/lscpu_arm.cpp)
|
||||||
endif()
|
endif()
|
||||||
else()
|
else()
|
||||||
list(APPEND SOURCES_CPUID src/backend/cpu/platform/BasicCpuInfo.cpp)
|
list(APPEND SOURCES_BACKEND_CPU src/backend/cpu/platform/BasicCpuInfo.cpp)
|
||||||
endif()
|
endif()
|
||||||
|
|
|
@ -1,130 +0,0 @@
|
||||||
/* XMRig
|
|
||||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
|
||||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
|
||||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
|
||||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
|
||||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
|
||||||
* Copyright 2017-2019 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
|
||||||
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
|
|
||||||
* Copyright 2016-2020 XMRig <support@xmrig.com>
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "backend/cpu/platform/AdvancedCpuInfo.h"
|
|
||||||
#include "3rdparty/libcpuid/libcpuid.h"
|
|
||||||
|
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
#include <cassert>
|
|
||||||
#include <cmath>
|
|
||||||
#include <cstdio>
|
|
||||||
#include <cstring>
|
|
||||||
|
|
||||||
|
|
||||||
xmrig::AdvancedCpuInfo::AdvancedCpuInfo()
|
|
||||||
{
|
|
||||||
struct cpu_raw_data_t raw = {};
|
|
||||||
struct cpu_id_t data = {};
|
|
||||||
|
|
||||||
cpuid_get_raw_data(&raw);
|
|
||||||
cpu_identify(&raw, &data);
|
|
||||||
|
|
||||||
snprintf(m_backend, sizeof m_backend, "libcpuid/%s", cpuid_lib_version());
|
|
||||||
|
|
||||||
m_threads = static_cast<size_t>(data.total_logical_cpus);
|
|
||||||
m_packages = std::max<size_t>(m_threads / static_cast<size_t>(data.num_logical_cpus), 1);
|
|
||||||
m_cores = static_cast<size_t>(data.num_cores) * m_packages;
|
|
||||||
m_L3 = data.l3_cache > 0 ? static_cast<size_t>(data.l3_cache) * m_packages : 0;
|
|
||||||
|
|
||||||
const auto l2 = static_cast<size_t>(data.l2_cache);
|
|
||||||
|
|
||||||
// Workaround for AMD CPUs https://github.com/anrieff/libcpuid/issues/97
|
|
||||||
if (m_vendor == VENDOR_AMD && data.ext_family >= 0x15 && data.ext_family < 0x17) {
|
|
||||||
m_L2 = l2 * (cores() / 2) * m_packages;
|
|
||||||
m_L2_exclusive = true;
|
|
||||||
}
|
|
||||||
// Workaround for Intel Pentium Dual-Core, Core Duo, Core 2 Duo, Core 2 Quad and their Xeon homologue
|
|
||||||
// These processors have L2 cache shared by 2 cores.
|
|
||||||
else if (m_vendor == VENDOR_INTEL && data.ext_family == 0x06 && (data.ext_model == 0x0E || data.ext_model == 0x0F || data.ext_model == 0x17)) {
|
|
||||||
size_t l2_count_per_socket = cores() > 1 ? cores() / 2 : 1;
|
|
||||||
m_L2 = data.l2_cache > 0 ? l2 * l2_count_per_socket * m_packages : 0;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
m_L2 = data.l2_cache > 0 ? l2 * cores() * m_packages : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_L2 *= 1024;
|
|
||||||
m_L3 *= 1024;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
xmrig::CpuThreads xmrig::AdvancedCpuInfo::threads(const Algorithm &algorithm, uint32_t limit) const
|
|
||||||
{
|
|
||||||
if (threads() == 1) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t cache = 0;
|
|
||||||
size_t count = 0;
|
|
||||||
|
|
||||||
# ifdef XMRIG_ALGO_ASTROBWT
|
|
||||||
if (algorithm == Algorithm::ASTROBWT_DERO) {
|
|
||||||
CpuThreads t;
|
|
||||||
count = threads();
|
|
||||||
for (size_t i = 0; i < count; ++i) {
|
|
||||||
t.add(i, 0);
|
|
||||||
}
|
|
||||||
return t;
|
|
||||||
}
|
|
||||||
# endif
|
|
||||||
|
|
||||||
if (m_L3) {
|
|
||||||
cache = m_L2_exclusive ? (m_L2 + m_L3) : m_L3;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
cache = m_L2;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cache) {
|
|
||||||
const size_t memory = algorithm.l3();
|
|
||||||
assert(memory > 0);
|
|
||||||
|
|
||||||
count = cache / memory;
|
|
||||||
|
|
||||||
if (cache % memory >= memory / 2) {
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
count = threads() / 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t intensity = algorithm.maxIntensity() == 1 ? 0 : 1;
|
|
||||||
|
|
||||||
# ifdef XMRIG_ALGO_CN_PICO
|
|
||||||
if (algorithm == Algorithm::CN_PICO_0 && (count / cores()) >= 2) {
|
|
||||||
intensity = 2;
|
|
||||||
}
|
|
||||||
# endif
|
|
||||||
|
|
||||||
if (limit > 0 && limit < 100) {
|
|
||||||
count = std::min(count, static_cast<size_t>(round(threads() * (limit / 100.0))));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
count = std::min(count, threads());
|
|
||||||
}
|
|
||||||
|
|
||||||
return CpuThreads(std::max<size_t>(count, 1), intensity);
|
|
||||||
}
|
|
|
@ -1,63 +0,0 @@
|
||||||
/* XMRig
|
|
||||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
|
||||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
|
||||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
|
||||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
|
||||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
|
||||||
* Copyright 2017-2019 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
|
||||||
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
|
|
||||||
* Copyright 2016-2020 XMRig <support@xmrig.com>
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef XMRIG_ADVANCEDCPUINFO_H
|
|
||||||
#define XMRIG_ADVANCEDCPUINFO_H
|
|
||||||
|
|
||||||
|
|
||||||
#include "backend/cpu/platform/BasicCpuInfo.h"
|
|
||||||
|
|
||||||
|
|
||||||
namespace xmrig {
|
|
||||||
|
|
||||||
|
|
||||||
class AdvancedCpuInfo : public BasicCpuInfo
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
AdvancedCpuInfo();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
CpuThreads threads(const Algorithm &algorithm, uint32_t limit) const override;
|
|
||||||
|
|
||||||
inline const char *backend() const override { return m_backend; }
|
|
||||||
inline size_t cores() const override { return m_cores; }
|
|
||||||
inline size_t L2() const override { return m_L2; }
|
|
||||||
inline size_t L3() const override { return m_L3; }
|
|
||||||
inline size_t packages() const override { return m_packages; }
|
|
||||||
inline size_t threads() const override { return m_threads; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool m_L2_exclusive = false;
|
|
||||||
char m_backend[32]{};
|
|
||||||
size_t m_cores = 0;
|
|
||||||
size_t m_L2 = 0;
|
|
||||||
size_t m_L3 = 0;
|
|
||||||
size_t m_packages = 1;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
} /* namespace xmrig */
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* XMRIG_ADVANCEDCPUINFO_H */
|
|
|
@ -169,9 +169,6 @@ void xmrig::Api::exec(IApiRequest &request)
|
||||||
# ifdef XMRIG_FEATURE_HTTP
|
# ifdef XMRIG_FEATURE_HTTP
|
||||||
features.PushBack("http", allocator);
|
features.PushBack("http", allocator);
|
||||||
# endif
|
# endif
|
||||||
# ifdef XMRIG_FEATURE_LIBCPUID
|
|
||||||
features.PushBack("cpuid", allocator);
|
|
||||||
# endif
|
|
||||||
# ifdef XMRIG_FEATURE_HWLOC
|
# ifdef XMRIG_FEATURE_HWLOC
|
||||||
features.PushBack("hwloc", allocator);
|
features.PushBack("hwloc", allocator);
|
||||||
# endif
|
# endif
|
||||||
|
|
Loading…
Reference in a new issue