Some more improvements of MUtils::CPUFetaures code.
This commit is contained in:
parent
7128c12680
commit
7c2c14bed5
@ -54,9 +54,12 @@ namespace MUtils
|
||||
static const quint32 FLAG_SSE2 = 0x008U; ///< \brief CPU feature flag \details Indicates that the CPU supports the *SSE2* instruction set extension
|
||||
static const quint32 FLAG_SSE3 = 0x010U; ///< \brief CPU feature flag \details Indicates that the CPU supports the *SSE3* instruction set extension
|
||||
static const quint32 FLAG_SSSE3 = 0x020U; ///< \brief CPU feature flag \details Indicates that the CPU supports the *SSSE3* instruction set extension
|
||||
static const quint32 FLAG_SSE4 = 0x030U; ///< \brief CPU feature flag \details Indicates that the CPU supports the *SSE4.1* instruction set extension
|
||||
static const quint32 FLAG_SSE41 = 0x040U; ///< \brief CPU feature flag \details Indicates that the CPU supports the *SSE4.1* instruction set extension
|
||||
static const quint32 FLAG_SSE42 = 0x080U; ///< \brief CPU feature flag \details Indicates that the CPU supports the *SSE4.2* instruction set extension
|
||||
static const quint32 FLAG_AVX = 0x100U; ///< \brief CPU feature flag \details Indicates that the CPU supports the *AVX* instruction set extension
|
||||
static const quint32 FLAG_AVX2 = 0x200U; ///< \brief CPU feature flag \details Indicates that the CPU supports the *AVX2* instruction set extension
|
||||
static const quint32 FLAG_FMA3 = 0x400U; ///< \brief CPU feature flag \details Indicates that the CPU supports the *FMA3* instruction
|
||||
static const quint32 FLAG_LZCNT = 0x800U; ///< \brief CPU feature flag \details Indicates that the CPU supports the *LZCNT* instruction
|
||||
|
||||
/**
|
||||
* \brief Struct to hold information about the CPU. See `_cpu_info_t` for details!
|
||||
|
@ -49,6 +49,7 @@ MUtils::CPUFetaures::cpu_info_t MUtils::CPUFetaures::detect(void)
|
||||
|
||||
//Detect the CPU identifier string
|
||||
MY_CPUID(&cpuInfo[0], 0);
|
||||
const uint32_t max_basic_cap = cpuInfo[0];
|
||||
memcpy(&features.idstr[0U * sizeof(uint32_t)], &cpuInfo[1], sizeof(uint32_t));
|
||||
memcpy(&features.idstr[1U * sizeof(uint32_t)], &cpuInfo[3], sizeof(uint32_t));
|
||||
memcpy(&features.idstr[2U * sizeof(uint32_t)], &cpuInfo[2], sizeof(uint32_t));
|
||||
@ -57,7 +58,7 @@ MUtils::CPUFetaures::cpu_info_t MUtils::CPUFetaures::detect(void)
|
||||
features.vendor |= CHECK_VENDOR(features.idstr, "AuthenticAMD", VENDOR_AMD);
|
||||
|
||||
//Detect the CPU model and feature flags
|
||||
if(cpuInfo[0] >= 1)
|
||||
if(max_basic_cap >= 1)
|
||||
{
|
||||
MY_CPUID(&cpuInfo[0], 1);
|
||||
features.features |= CHECK_FLAG(cpuInfo[3], 0x00008000, FLAG_CMOV);
|
||||
@ -66,7 +67,7 @@ MUtils::CPUFetaures::cpu_info_t MUtils::CPUFetaures::detect(void)
|
||||
features.features |= CHECK_FLAG(cpuInfo[3], 0x04000000, FLAG_SSE2);
|
||||
features.features |= CHECK_FLAG(cpuInfo[2], 0x00000001, FLAG_SSE3);
|
||||
features.features |= CHECK_FLAG(cpuInfo[2], 0x00000200, FLAG_SSSE3);
|
||||
features.features |= CHECK_FLAG(cpuInfo[2], 0x00080000, FLAG_SSE4);
|
||||
features.features |= CHECK_FLAG(cpuInfo[2], 0x00080000, FLAG_SSE41);
|
||||
features.features |= CHECK_FLAG(cpuInfo[2], 0x00100000, FLAG_SSE42);
|
||||
|
||||
//Check for AVX
|
||||
@ -75,6 +76,7 @@ MUtils::CPUFetaures::cpu_info_t MUtils::CPUFetaures::detect(void)
|
||||
if((_xgetbv(0) & 0x6ui64) == 0x6ui64) /*AVX requires OS support!*/
|
||||
{
|
||||
features.features |= FLAG_AVX;
|
||||
features.features |= CHECK_FLAG(cpuInfo[2], 0x00001000, FLAG_FMA3);
|
||||
}
|
||||
}
|
||||
|
||||
@ -84,15 +86,33 @@ MUtils::CPUFetaures::cpu_info_t MUtils::CPUFetaures::detect(void)
|
||||
features.family = ((cpuInfo[0] >> 8) & 0xf) + ((cpuInfo[0] >> 20) & 0xff);
|
||||
}
|
||||
|
||||
//Read the CPU "brand" string
|
||||
MY_CPUID(&cpuInfo[0], 0x80000000);
|
||||
const uint32_t nExIds = qBound(0x80000000, cpuInfo[0], 0x80000004);
|
||||
for(uint32_t i = 0x80000002; i <= nExIds; ++i)
|
||||
//Detect extended feature flags
|
||||
if (max_basic_cap >= 7)
|
||||
{
|
||||
MY_CPUID(&cpuInfo[0], i);
|
||||
memcpy(&features.brand[(i - 0x80000002) * sizeof(cpuInfo)], &cpuInfo[0], sizeof(cpuInfo));
|
||||
MY_CPUID(&cpuInfo[1], 7);
|
||||
if (features.features & FLAG_AVX)
|
||||
{
|
||||
features.features |= CHECK_FLAG(cpuInfo[2], 0x00000020, FLAG_AVX2);
|
||||
}
|
||||
}
|
||||
|
||||
//Read the CPU "brand" string
|
||||
if (max_basic_cap > 0)
|
||||
{
|
||||
MY_CPUID(&cpuInfo[0], 0x80000000);
|
||||
const uint32_t max_extended_cap = qBound(0x80000000, cpuInfo[0], 0x80000004);
|
||||
if (max_extended_cap >= 0x80000001)
|
||||
{
|
||||
MY_CPUID(&cpuInfo[0], 0x80000001);
|
||||
features.features |= CHECK_FLAG(cpuInfo[2], 0x00000020, FLAG_LZCNT);
|
||||
for (uint32_t i = 0x80000002; i <= max_extended_cap; ++i)
|
||||
{
|
||||
MY_CPUID(&cpuInfo[0], i);
|
||||
memcpy(&features.brand[(i - 0x80000002) * sizeof(cpuInfo)], &cpuInfo[0], sizeof(cpuInfo));
|
||||
}
|
||||
features.brand[sizeof(features.brand) - 1] = '\0';
|
||||
}
|
||||
}
|
||||
features.brand[sizeof(features.brand) - 1] = '\0';
|
||||
|
||||
//Detect 64-Bit processors
|
||||
#if (!(defined(_M_X64) || defined(_M_IA64)))
|
||||
|
Loading…
Reference in New Issue
Block a user