diff --git a/src/xenia/base/exception_handler_win.cc b/src/xenia/base/exception_handler_win.cc index 786a129a5..49e49643f 100644 --- a/src/xenia/base/exception_handler_win.cc +++ b/src/xenia/base/exception_handler_win.cc @@ -36,12 +36,22 @@ LONG CALLBACK ExceptionHandlerCallback(PEXCEPTION_POINTERS ex_info) { } HostThreadContext thread_context; + +#if XE_ARCH_AMD64 thread_context.rip = ex_info->ContextRecord->Rip; thread_context.eflags = ex_info->ContextRecord->EFlags; std::memcpy(thread_context.int_registers, &ex_info->ContextRecord->Rax, sizeof(thread_context.int_registers)); std::memcpy(thread_context.xmm_registers, &ex_info->ContextRecord->Xmm0, sizeof(thread_context.xmm_registers)); +#elif XE_ARCH_ARM64 + thread_context.pc = ex_info->ContextRecord->Pc; + thread_context.cpsr = ex_info->ContextRecord->Cpsr; + std::memcpy(thread_context.x, &ex_info->ContextRecord->X, + sizeof(thread_context.x)); + std::memcpy(thread_context.v, &ex_info->ContextRecord->V, + sizeof(thread_context.v)); +#endif // https://msdn.microsoft.com/en-us/library/ms679331(v=vs.85).aspx // https://msdn.microsoft.com/en-us/library/aa363082(v=vs.85).aspx @@ -78,6 +88,7 @@ LONG CALLBACK ExceptionHandlerCallback(PEXCEPTION_POINTERS ex_info) { for (size_t i = 0; i < xe::countof(handlers_) && handlers_[i].first; ++i) { if (handlers_[i].first(&ex, handlers_[i].second)) { // Exception handled. +#if XE_ARCH_AMD64 ex_info->ContextRecord->Rip = thread_context.rip; ex_info->ContextRecord->EFlags = thread_context.eflags; uint32_t modified_register_index; @@ -98,6 +109,28 @@ LONG CALLBACK ExceptionHandlerCallback(PEXCEPTION_POINTERS ex_info) { &thread_context.xmm_registers[modified_register_index], sizeof(vec128_t)); } +#elif XE_ARCH_ARM64 + ex_info->ContextRecord->Pc = thread_context.pc; + ex_info->ContextRecord->Cpsr = thread_context.cpsr; + uint32_t modified_register_index; + uint16_t modified_int_registers_remaining = ex.modified_x_registers(); + while (xe::bit_scan_forward(modified_int_registers_remaining, + &modified_register_index)) { + modified_int_registers_remaining &= + ~(UINT16_C(1) << modified_register_index); + ex_info->ContextRecord->X[modified_register_index] = + thread_context.x[modified_register_index]; + } + uint16_t modified_xmm_registers_remaining = ex.modified_v_registers(); + while (xe::bit_scan_forward(modified_xmm_registers_remaining, + &modified_register_index)) { + modified_xmm_registers_remaining &= + ~(UINT16_C(1) << modified_register_index); + std::memcpy(&ex_info->ContextRecord->V + modified_register_index, + &thread_context.v[modified_register_index], + sizeof(vec128_t)); + } +#endif return EXCEPTION_CONTINUE_EXECUTION; } } diff --git a/src/xenia/base/host_thread_context.cc b/src/xenia/base/host_thread_context.cc index bf668bdd3..24b2b6e12 100644 --- a/src/xenia/base/host_thread_context.cc +++ b/src/xenia/base/host_thread_context.cc @@ -67,7 +67,7 @@ std::string HostThreadContext::GetStringFromValue(HostRegister reg, case Arm64Register::kPc: return hex ? string_util::to_hex_string(pc) : std::to_string(pc); case Arm64Register::kPstate: - return hex ? string_util::to_hex_string(pstate) : std::to_string(pstate); + return hex ? string_util::to_hex_string(cpsr) : std::to_string(cpsr); case Arm64Register::kFpsr: return hex ? string_util::to_hex_string(fpsr) : std::to_string(fpsr); case Arm64Register::kFpcr: diff --git a/src/xenia/base/host_thread_context.h b/src/xenia/base/host_thread_context.h index 554d09f44..6379f62f8 100644 --- a/src/xenia/base/host_thread_context.h +++ b/src/xenia/base/host_thread_context.h @@ -202,7 +202,7 @@ class HostThreadContext { uint64_t x[31]; uint64_t sp; uint64_t pc; - uint64_t pstate; + uint32_t cpsr; uint32_t fpsr; uint32_t fpcr; vec128_t v[32];