Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MacOS - Implement remaining portions for native ARM64 #15992

Merged
merged 4 commits into from
Aug 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions Utilities/JITASM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -185,8 +185,13 @@ static u8* add_jit_memory(usz size, usz align)
if (olda != newa) [[unlikely]]
{
#ifndef CAN_OVERCOMMIT
// Commit more memory
utils::memory_commit(pointer + olda, newa - olda, Prot);
// Commit more memory.
// NOTE: Calling memory commit in parallel on the same addresses can throw a permission error.
{
static std::mutex mcommit_lock;
std::lock_guard lock(mcommit_lock);
utils::memory_commit(pointer + olda, newa - olda, Prot);
Copy link
Contributor

@elad335 elad335 Aug 25, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm, this should somehow be implemented insidr memory_commit
edit: I'll add locks by pointer hash or something

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Beware of overlapping regions as well, though I doubt that's a problem in practice.
This operation is pretty quick so I haven't experienced any slowdown. It can also be copied as-is into the memory_commit function.

}
#endif
// Acknowledge committed memory
Ctr.atomic_op([&](u64& ctr)
Expand Down
4 changes: 2 additions & 2 deletions Utilities/JITLLVM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -517,7 +517,7 @@ std::string jit_compiler::triple1()
#elif defined(__APPLE__) && defined(ARCH_X64)
return llvm::Triple::normalize("x86_64-unknown-linux-gnu");
#elif defined(__APPLE__) && defined(ARCH_ARM64)
return llvm::Triple::normalize("aarch64-unknown-linux-gnu");
return llvm::Triple::normalize("aarch64-unknown-linux-android"); // Set environment to android to reserve x18
#else
return llvm::Triple::normalize(llvm::sys::getProcessTriple());
#endif
Expand All @@ -532,7 +532,7 @@ std::string jit_compiler::triple2()
#elif defined(__APPLE__) && defined(ARCH_X64)
return llvm::Triple::normalize("x86_64-unknown-linux-gnu");
#elif defined(__APPLE__) && defined(ARCH_ARM64)
return llvm::Triple::normalize("aarch64-unknown-linux-gnu");
return llvm::Triple::normalize("aarch64-unknown-linux-android"); // Set environment to android to reserve x18
#else
return llvm::Triple::normalize(llvm::sys::getProcessTriple());
#endif
Expand Down
64 changes: 64 additions & 0 deletions rpcs3/Emu/CPU/Backends/AArch64/AArch64Common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,13 @@
#include <thread>
#include <map>

#if defined(__APPLE__)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could this path also be used for FREEBSD?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe, but I have no idea if they use a different path. I have 0 experience with BSD unfortunately, we'll have to rely on their community to help fill in the missing pieces.

#include <sys/sysctl.h>
#endif

namespace aarch64
{
#if !defined(__APPLE__)
struct cpu_entry_t
{
u32 vendor;
Expand Down Expand Up @@ -194,4 +199,63 @@ namespace aarch64
result += suffix;
return result;
}
#else
static std::string sysctl_s(const std::string_view& variable_name)
{
// Determine required buffer size
size_t length = 0;
if (sysctlbyname(variable_name.data(), nullptr, &length, nullptr, 0) == -1)
{
return "";
}

// Allocate space for the variable.
std::vector<char> text(length + 1);
text[length] = 0;
if (sysctlbyname(variable_name.data(), text.data(), &length, nullptr, 0) == -1)
{
return "";
}

return text.data();
}

static u64 sysctl_u64(const std::string_view& variable_name)
{
u64 value = 0;
size_t data_len = sizeof(value);
if (sysctlbyname(variable_name.data(), &value, &data_len, nullptr, 0) == -1)
{
return umax;
}
return value;
}

// We can get the brand name from sysctl directly
// Once we have windows implemented, we should probably separate the different OS-dependent bits to avoid clutter
std::string get_cpu_brand()
{
const auto brand = sysctl_s("machdep.cpu.brand_string");
if (brand.empty())
{
return "Unidentified CPU";
}

// Parse extra core information (P and E cores)
if (sysctl_u64("hw.nperflevels") < 2)
{
return brand;
}

u64 pcores = sysctl_u64("hw.perflevel0.physicalcpu");
u64 ecores = sysctl_u64("hw.perflevel1.physicalcpu");

if (sysctl_s("hw.perflevel0.name") == "Efficiency")
{
std::swap(ecores, pcores);
}

return fmt::format("%s (%lluP+%lluE)", brand, pcores, ecores);
}
#endif
}