Merge pull request #9441 from skylersaleh/master

Apple M1 Support for MacOS
This commit is contained in:
Léo Lam authored and GitHub committed 2021-05-24 12:39:01 +02:00
commit 51671921c4
22 files changed
+598 -38

No files matched your search

+9 -3
View File
@@ -289,11 +289,17 @@ void DolphinAnalytics::MakeBaseBuilder()
s64 minor_version; // NSInteger minorVersion
s64 patch_version; // NSInteger patchVersion
};
// Under arm64, we need to call objc_msgSend to recieve a struct.
// On x86_64, we need to explicitly call objc_msgSend_stret for a struct.
#if _M_ARM_64
#define msgSend objc_msgSend
#else
#define msgSend objc_msgSend_stret
#endif
// NSOperatingSystemVersion version = [processInfo operatingSystemVersion]
OSVersion version = reinterpret_cast<OSVersion (*)(id, SEL)>(objc_msgSend_stret)(
OSVersion version = reinterpret_cast<OSVersion (*)(id, SEL)>(msgSend)(
processInfo, sel_getUid("operatingSystemVersion"));
#undef msgSend
builder.AddData("osx-ver-major", version.major_version);
builder.AddData("osx-ver-minor", version.minor_version);
builder.AddData("osx-ver-bugfix", version.patch_version);
+6
View File
@@ -67,6 +67,12 @@ typedef x86_thread_state64_t SContext;
#define CTX_R14 __r14
#define CTX_R15 __r15
#define CTX_RIP __rip
#elif _M_ARM_64
typedef arm_thread_state64_t SContext;
#define CTX_REG(x) __x[x]
#define CTX_LR __x[30]
#define CTX_SP __sp
#define CTX_PC __pc
#else
#error No context definition for architecture
#endif
+23 -9
View File
@@ -25,6 +25,20 @@
#include <unistd.h> // Needed for _POSIX_VERSION
#endif
#if defined(__APPLE__)
#ifdef _M_X86_64
#define THREAD_STATE64_COUNT x86_THREAD_STATE64_COUNT
#define THREAD_STATE64 x86_THREAD_STATE64
#define thread_state64_t x86_thread_state64_t
#elif defined(_M_ARM_64)
#define THREAD_STATE64_COUNT ARM_THREAD_STATE64_COUNT
#define THREAD_STATE64 ARM_THREAD_STATE64
#define thread_state64_t arm_thread_state64_t
#else
#error Unsupported architecture
#endif
#endif
namespace EMM
{
#ifdef _WIN32
@@ -123,7 +137,7 @@ static void ExceptionThread(mach_port_t port)
int64_t code[2];
int flavor;
mach_msg_type_number_t old_stateCnt;
natural_t old_state[x86_THREAD_STATE64_COUNT];
natural_t old_state[THREAD_STATE64_COUNT];
mach_msg_trailer_t trailer;
} msg_in;
@@ -134,7 +148,7 @@ static void ExceptionThread(mach_port_t port)
kern_return_t RetCode;
int flavor;
mach_msg_type_number_t new_stateCnt;
natural_t new_state[x86_THREAD_STATE64_COUNT];
natural_t new_state[THREAD_STATE64_COUNT];
} msg_out;
#pragma pack()
memset(&msg_in, 0xee, sizeof(msg_in));
@@ -165,13 +179,13 @@ static void ExceptionThread(mach_port_t port)
return;
}
if (msg_in.flavor != x86_THREAD_STATE64)
if (msg_in.flavor != THREAD_STATE64)
{
PanicAlertFmt("unknown flavor {} (expected {})", msg_in.flavor, x86_THREAD_STATE64);
PanicAlertFmt("unknown flavor {} (expected {})", msg_in.flavor, THREAD_STATE64);
return;
}
x86_thread_state64_t* state = (x86_thread_state64_t*)msg_in.old_state;
thread_state64_t* state = (thread_state64_t*)msg_in.old_state;
bool ok = JitInterface::HandleFault((uintptr_t)msg_in.code[1], state);
@@ -184,9 +198,9 @@ static void ExceptionThread(mach_port_t port)
if (ok)
{
msg_out.RetCode = KERN_SUCCESS;
msg_out.flavor = x86_THREAD_STATE64;
msg_out.new_stateCnt = x86_THREAD_STATE64_COUNT;
memcpy(msg_out.new_state, msg_in.old_state, x86_THREAD_STATE64_COUNT * sizeof(natural_t));
msg_out.flavor = THREAD_STATE64;
msg_out.new_stateCnt = THREAD_STATE64_COUNT;
memcpy(msg_out.new_state, msg_in.old_state, THREAD_STATE64_COUNT * sizeof(natural_t));
}
else
{
@@ -218,7 +232,7 @@ void InstallExceptionHandler()
// Debuggers set the task port, so we grab the thread port.
CheckKR("thread_set_exception_ports",
thread_set_exception_ports(mach_thread_self(), EXC_MASK_BAD_ACCESS, port,
EXCEPTION_STATE | MACH_EXCEPTION_CODES, x86_THREAD_STATE64));
EXCEPTION_STATE | MACH_EXCEPTION_CODES, THREAD_STATE64));
// ...and get rid of our copy so that MACH_NOTIFY_NO_SENDERS works.
CheckKR("mach_port_mod_refs",
mach_port_mod_refs(mach_task_self(), port, MACH_PORT_RIGHT_SEND, -1));
@@ -73,6 +73,8 @@ void JitArm64::Init()
bool JitArm64::HandleFault(uintptr_t access_address, SContext* ctx)
{
// Ifdef this since the exception handler runs on a separate thread on macOS (ARM)
#if !(defined(__APPLE__) && defined(_M_ARM_64))
// We can't handle any fault from other threads.
if (!Core::IsCPUThread())
{
@@ -80,6 +82,7 @@ bool JitArm64::HandleFault(uintptr_t access_address, SContext* ctx)
DoBacktrace(access_address, ctx);
return false;
}
#endif
bool success = false;
@@ -124,6 +127,7 @@ void JitArm64::ClearCache()
m_handler_to_loc.clear();
blocks.Clear();
const Common::ScopedJITPageWriteAndNoExecute enable_jit_page_writes;
ClearCodeSpace();
farcode.ClearCodeSpace();
UpdateMemoryOptions();
@@ -596,6 +600,7 @@ void JitArm64::Jit(u32)
{
ClearCache();
}
const Common::ScopedJITPageWriteAndNoExecute enable_jit_page_writes;
std::size_t block_size = m_code_buffer.size();
const u32 em_address = PowerPC::ppcState.pc;
@@ -59,11 +59,11 @@ void JitArm64BlockCache::WriteLinkBlock(Arm64Gen::ARM64XEmitter& emit,
void JitArm64BlockCache::WriteLinkBlock(const JitBlock::LinkData& source, const JitBlock* dest)
{
const Common::ScopedJITPageWriteAndNoExecute enable_jit_page_writes;
u8* location = source.exitPtrs;
ARM64XEmitter emit(location);
WriteLinkBlock(emit, source, dest);
emit.FlushIcache();
}
@@ -71,9 +71,8 @@ void JitArm64BlockCache::WriteDestroyBlock(const JitBlock& block)
{
// Only clear the entry points as we might still be within this block.
ARM64XEmitter emit(block.checkedEntry);
const Common::ScopedJITPageWriteAndNoExecute enable_jit_page_writes;
while (emit.GetWritableCodePtr() <= block.normalEntry)
emit.BRK(0x123);
emit.FlushIcache();
}
@@ -289,6 +289,7 @@ bool JitArm64::HandleFastmemFault(uintptr_t access_address, SContext* ctx)
if ((const u8*)ctx->CTX_PC - fault_location > fastmem_area_length)
return false;
const Common::ScopedJITPageWriteAndNoExecute enable_jit_page_writes;
ARM64XEmitter emitter((u8*)fault_location);
emitter.BL(slow_handler_iter->second.slowmem_code);
@@ -300,6 +301,7 @@ bool JitArm64::HandleFastmemFault(uintptr_t access_address, SContext* ctx)
m_fault_to_handler.erase(slow_handler_iter);
emitter.FlushIcache();
ctx->CTX_PC = reinterpret_cast<std::uintptr_t>(fault_location);
return true;
}
@@ -25,6 +25,8 @@ using namespace Arm64Gen;
void JitArm64::GenerateAsm()
{
const Common::ScopedJITPageWriteAndNoExecute enable_jit_page_writes;
// This value is all of the callee saved registers that we are required to save.
// According to the AACPS64 we need to save R19 ~ R30 and Q8 ~ Q15.
const u32 ALL_CALLEE_SAVED = 0x7FF80000;
+2 -3
View File
@@ -71,9 +71,8 @@ CPUCoreBase* InitJitCore(PowerPC::CPUCore core)
break;
default:
PanicAlertFmtT("The selected CPU emulation core ({0}) is not available. "
"Please select a different CPU emulation core in the settings.",
core);
// Under this case the caller overrides the CPU core to the default and logs that
// it performed the override.
g_jit = nullptr;
return nullptr;
}