dolphin/Source/Core/Common/ArmCPUDetect.cpp

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

130 lines
2.7 KiB
C++
Raw Normal View History

// Copyright 2013 Dolphin Emulator Project
2015-05-17 23:08:10 +00:00
// Licensed under GPLv2+
// Refer to the license.txt file included.
2013-02-26 19:49:00 +00:00
#include <cstring>
2014-06-02 23:27:50 +00:00
#include <fstream>
#include <sstream>
#include <string>
2019-11-26 04:31:45 +00:00
#include <thread>
#ifndef _WIN32
2020-08-27 20:54:04 +00:00
#ifndef __FreeBSD__
2019-11-26 04:31:45 +00:00
#include <asm/hwcap.h>
2020-08-27 20:54:04 +00:00
#endif
#include <sys/auxv.h>
#include <unistd.h>
2019-11-26 04:31:45 +00:00
#endif
2014-06-02 23:27:50 +00:00
#include <fmt/format.h>
#include "Common/CPUDetect.h"
#include "Common/CommonTypes.h"
#include "Common/FileUtil.h"
2013-02-26 19:49:00 +00:00
2019-11-26 04:31:45 +00:00
#ifndef WIN32
2013-02-26 19:49:00 +00:00
const char procfile[] = "/proc/cpuinfo";
2014-09-22 21:45:42 +00:00
static std::string GetCPUString()
2013-02-26 19:49:00 +00:00
{
2014-06-02 23:27:50 +00:00
const std::string marker = "Hardware\t: ";
std::string cpu_string = "Unknown";
std::string line;
std::ifstream file;
File::OpenFStream(file, procfile, std::ios_base::in);
2014-06-02 23:27:50 +00:00
if (!file)
return cpu_string;
2014-06-02 23:27:50 +00:00
while (std::getline(file, line))
2013-02-26 19:49:00 +00:00
{
2014-06-02 23:27:50 +00:00
if (line.find(marker) != std::string::npos)
{
cpu_string = line.substr(marker.length());
break;
}
2013-02-26 19:49:00 +00:00
}
2014-06-02 23:27:50 +00:00
return cpu_string;
2013-02-26 19:49:00 +00:00
}
2019-11-26 04:31:45 +00:00
#endif
2013-02-26 19:49:00 +00:00
CPUInfo cpu_info;
2014-06-02 23:27:50 +00:00
CPUInfo::CPUInfo()
{
2013-02-26 19:49:00 +00:00
Detect();
}
// Detects the various CPU features
2013-02-26 19:49:00 +00:00
void CPUInfo::Detect()
{
// Set some defaults here
// When ARMv8 CPUs come out, these need to be updated.
2013-02-26 19:49:00 +00:00
HTT = false;
OS64bit = true;
CPU64bit = true;
Mode64bit = true;
vendor = CPUVendor::ARM;
bFlushToZero = true;
2019-11-26 04:31:45 +00:00
#ifdef _WIN32
num_cores = std::thread::hardware_concurrency();
// Windows does not provide any mechanism for querying the system registers on ARMv8, unlike Linux
// which traps the register reads and emulates them in the kernel. There are environment variables
// containing some of the CPU-specific values, which we could use for a lookup table in the
// future. For now, assume all features are present as all known devices which are Windows-on-ARM
// compatible also support these extensions.
bFP = true;
bASIMD = true;
bAES = true;
bCRC32 = true;
bSHA1 = true;
bSHA2 = true;
#else
2013-02-26 19:49:00 +00:00
// Get the information about the CPU
num_cores = sysconf(_SC_NPROCESSORS_CONF);
strncpy(cpu_string, GetCPUString().c_str(), sizeof(cpu_string));
2020-08-27 20:54:04 +00:00
#ifdef __FreeBSD__
u_long hwcaps = 0;
elf_aux_info(AT_HWCAP, &hwcaps, sizeof(u_long));
#else
unsigned long hwcaps = getauxval(AT_HWCAP);
2020-08-27 20:54:04 +00:00
#endif
bFP = hwcaps & HWCAP_FP;
bASIMD = hwcaps & HWCAP_ASIMD;
bAES = hwcaps & HWCAP_AES;
bCRC32 = hwcaps & HWCAP_CRC32;
bSHA1 = hwcaps & HWCAP_SHA1;
bSHA2 = hwcaps & HWCAP_SHA2;
2019-11-26 04:31:45 +00:00
#endif
2013-02-26 19:49:00 +00:00
}
// Turn the CPU info into a string we can show
2013-02-26 19:49:00 +00:00
std::string CPUInfo::Summarize()
{
std::string sum;
if (num_cores == 1)
sum = fmt::format("{}, 1 core", cpu_string);
2013-02-26 19:49:00 +00:00
else
sum = fmt::format("{}, {} cores", cpu_string, num_cores);
if (bAES)
sum += ", AES";
if (bCRC32)
sum += ", CRC32";
if (bSHA1)
sum += ", SHA1";
if (bSHA2)
sum += ", SHA2";
if (CPU64bit)
sum += ", 64-bit";
2013-02-26 19:49:00 +00:00
return sum;
}