mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-19 19:15:26 +00:00
android: jit: teach fallback_cpu_detection provide meaningful results for aarch64
This commit is contained in:
parent
709d1e2b59
commit
cf9698ea5b
4 changed files with 71 additions and 7 deletions
|
@ -569,6 +569,6 @@ public:
|
|||
bool add_sub_disk_space(ssz space);
|
||||
};
|
||||
|
||||
llvm::StringRef fallback_cpu_detection();
|
||||
const char *fallback_cpu_detection();
|
||||
|
||||
#endif // LLVM_AVAILABLE
|
||||
|
|
|
@ -46,6 +46,10 @@ LOG_CHANNEL(jit_log, "JIT");
|
|||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
#ifdef ARCH_ARM64
|
||||
#include "Emu/CPU/Backends/AArch64/AArch64Common.h"
|
||||
#endif
|
||||
|
||||
const bool jit_initialize = []() -> bool
|
||||
{
|
||||
llvm::InitializeNativeTarget();
|
||||
|
@ -590,8 +594,10 @@ std::string jit_compiler::triple1()
|
|||
return llvm::Triple::normalize(llvm::sys::getProcessTriple());
|
||||
#elif defined(__APPLE__) && defined(ARCH_X64)
|
||||
return llvm::Triple::normalize("x86_64-unknown-linux-gnu");
|
||||
#elif defined(__APPLE__) && defined(ARCH_ARM64)
|
||||
#elif (defined(__ANDROID__) || defined(__APPLE__)) && defined(ARCH_ARM64)
|
||||
return llvm::Triple::normalize("aarch64-unknown-linux-android"); // Set environment to android to reserve x18
|
||||
#elif defined(__ANDROID__) && defined(ARCH_X64)
|
||||
return llvm::Triple::normalize("x86_64-unknown-linux-android");
|
||||
#else
|
||||
return llvm::Triple::normalize(llvm::sys::getProcessTriple());
|
||||
#endif
|
||||
|
@ -605,8 +611,10 @@ std::string jit_compiler::triple2()
|
|||
return llvm::Triple::normalize("aarch64-unknown-linux-gnu");
|
||||
#elif defined(__APPLE__) && defined(ARCH_X64)
|
||||
return llvm::Triple::normalize("x86_64-unknown-linux-gnu");
|
||||
#elif defined(__APPLE__) && defined(ARCH_ARM64)
|
||||
#elif (defined(__ANDROID__) || defined(__APPLE__)) && defined(ARCH_ARM64)
|
||||
return llvm::Triple::normalize("aarch64-unknown-linux-android"); // Set environment to android to reserve x18
|
||||
#elif defined(__ANDROID__) && defined(ARCH_X64)
|
||||
return llvm::Triple::normalize("x86_64-unknown-linux-android"); // Set environment to android to reserve x18
|
||||
#else
|
||||
return llvm::Triple::normalize(llvm::sys::getProcessTriple());
|
||||
#endif
|
||||
|
@ -817,9 +825,9 @@ u64 jit_compiler::get(const std::string& name)
|
|||
return m_engine->getGlobalValueAddress(name);
|
||||
}
|
||||
|
||||
llvm::StringRef fallback_cpu_detection()
|
||||
const char * fallback_cpu_detection()
|
||||
{
|
||||
#if defined (ARCH_X64)
|
||||
#if defined(ARCH_X64)
|
||||
// If we got here we either have a very old and outdated CPU or a new CPU that has not been seen by LLVM yet.
|
||||
const std::string brand = utils::get_cpu_brand();
|
||||
const auto family = utils::get_cpu_family();
|
||||
|
@ -851,8 +859,8 @@ llvm::StringRef fallback_cpu_detection()
|
|||
default:
|
||||
// Safest guesses
|
||||
return utils::has_avx512() ? "znver4" :
|
||||
utils::has_avx2() ? "znver1" :
|
||||
utils::has_avx() ? "bdver1" :
|
||||
utils::has_avx2() ? "znver1" :
|
||||
utils::has_avx() ? "bdver1" :
|
||||
"nehalem";
|
||||
}
|
||||
}
|
||||
|
@ -883,10 +891,26 @@ llvm::StringRef fallback_cpu_detection()
|
|||
}
|
||||
|
||||
#elif defined(ARCH_ARM64)
|
||||
#ifdef ANDROID
|
||||
static std::string s_result = []() -> std::string
|
||||
{
|
||||
std::string result = aarch64::get_cpu_name();
|
||||
if (result.empty())
|
||||
{
|
||||
return "cortex-a78";
|
||||
}
|
||||
|
||||
std::transform(result.begin(), result.end(), result.begin(), ::tolower);
|
||||
return result;
|
||||
}();
|
||||
|
||||
return s_result.c_str();
|
||||
#else
|
||||
// TODO: Read the data from /proc/cpuinfo. ARM CPU registers are not accessible from usermode.
|
||||
// This will be a pain when supporting snapdragon on windows but we'll cross that bridge when we get there.
|
||||
// Require at least armv8-2a. Older chips are going to be useless anyway.
|
||||
return "cortex-a78";
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Failed to guess, use generic fallback
|
||||
|
|
|
@ -136,6 +136,45 @@ namespace aarch64
|
|||
#endif
|
||||
}
|
||||
|
||||
std::string get_cpu_name()
|
||||
{
|
||||
std::map<u64, int> core_layout;
|
||||
for (u32 i = 0; i < std::thread::hardware_concurrency(); ++i)
|
||||
{
|
||||
const auto midr = read_MIDR_EL1(i);
|
||||
if (midr == umax)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
core_layout[midr]++;
|
||||
}
|
||||
|
||||
if (core_layout.empty())
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
const cpu_entry_t *lowest_part_info = nullptr;
|
||||
for (const auto& [midr, count] : core_layout)
|
||||
{
|
||||
const auto implementer_id = (midr >> 24) & 0xff;
|
||||
const auto part_id = (midr >> 4) & 0xfff;
|
||||
|
||||
const auto part_info = find_cpu_part(implementer_id, part_id);
|
||||
if (!part_info)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
if (lowest_part_info == nullptr || lowest_part_info > part_info) {
|
||||
lowest_part_info = part_info;
|
||||
}
|
||||
}
|
||||
|
||||
return lowest_part_info == nullptr ? "" : lowest_part_info->name;
|
||||
}
|
||||
|
||||
std::string get_cpu_brand()
|
||||
{
|
||||
// Fetch vendor and part numbers. ARM CPUs often have more than 1 architecture on the SoC, so we check all of them.
|
||||
|
|
|
@ -37,5 +37,6 @@ namespace aarch64
|
|||
"xzr", ".", "sp"
|
||||
};
|
||||
|
||||
std::string get_cpu_name();
|
||||
std::string get_cpu_brand();
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue