forked from eden-emu/eden
[nce] common ctx
Signed-off-by: lizzie <lizzie@eden-emu.dev>
This commit is contained in:
parent
20bdcc5731
commit
c44b3423f3
5 changed files with 140 additions and 211 deletions
|
@ -13,9 +13,10 @@
|
|||
#include "core/arm/nce/patcher.h"
|
||||
#include "core/core.h"
|
||||
#include "core/memory.h"
|
||||
|
||||
#include "core/hle/kernel/k_process.h"
|
||||
|
||||
#include "dynarmic/common/context.h"
|
||||
|
||||
#include <signal.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <unistd.h>
|
||||
|
@ -33,20 +34,6 @@ static_assert(offsetof(NativeExecutionParameters, native_context) == TpidrEl0Nat
|
|||
static_assert(offsetof(NativeExecutionParameters, lock) == TpidrEl0Lock);
|
||||
static_assert(offsetof(NativeExecutionParameters, magic) == TpidrEl0TlsMagic);
|
||||
|
||||
#ifdef __APPLE__
|
||||
_STRUCT_ARM_NEON_STATE64* GetFloatingPointState(mcontext_t& host_ctx) {
|
||||
return &(host_ctx.__ns);
|
||||
}
|
||||
#else
|
||||
fpsimd_context* GetFloatingPointState(mcontext_t& host_ctx) {
|
||||
_aarch64_ctx* header = reinterpret_cast<_aarch64_ctx*>(&host_ctx.__reserved);
|
||||
while (header->magic != FPSIMD_MAGIC) {
|
||||
header = reinterpret_cast<_aarch64_ctx*>(reinterpret_cast<char*>(header) + header->size);
|
||||
}
|
||||
return reinterpret_cast<fpsimd_context*>(header);
|
||||
}
|
||||
#endif
|
||||
|
||||
using namespace Common::Literals;
|
||||
constexpr u32 StackSize = 128_KiB;
|
||||
|
||||
|
@ -59,38 +46,21 @@ void* ArmNce::RestoreGuestContext(void* raw_context) {
|
|||
auto* fpctx = GetFloatingPointState(host_ctx);
|
||||
|
||||
// Restore all guest state except tpidr_el0.
|
||||
#ifdef __APPLE__
|
||||
// Thread-local parameters will be located in x9.
|
||||
auto* tpidr = reinterpret_cast<NativeExecutionParameters*>(host_ctx->__ss.__r[9]);
|
||||
auto* tpidr = reinterpret_cast<NativeExecutionParameters*>(CTX_X(9));
|
||||
auto* guest_ctx = static_cast<GuestContext*>(tpidr->native_context);
|
||||
// Save host callee-saved registers.
|
||||
std::memcpy(guest_ctx->host_ctx.host_saved_vregs.data(), &fpctx->__v[8],
|
||||
std::memcpy(guest_ctx->host_ctx.host_saved_vregs.data(), &CTX_Q(8),
|
||||
sizeof(guest_ctx->host_ctx.host_saved_vregs));
|
||||
// Save stack pointer.
|
||||
guest_ctx->host_ctx.host_sp = host_ctx->__ss.__sp;
|
||||
host_ctx->__ss.__pc = guest_ctx->sp;
|
||||
host_ctx->__ss.__sp = guest_ctx->pc;
|
||||
host_ctx->__ss.__pstate = guest_ctx->pstate;
|
||||
fpctx->__fpcr = guest_ctx->fpcr;
|
||||
fpctx->__fpsr = guest_ctx->fpsr;
|
||||
std::memcpy(fpctx->__v, guest_ctx->vector_registers.data(), sizeof(fpctx->__v));
|
||||
#else
|
||||
// Thread-local parameters will be located in x9.
|
||||
auto* tpidr = reinterpret_cast<NativeExecutionParameters*>(host_ctx.regs[9]);
|
||||
auto* guest_ctx = static_cast<GuestContext*>(tpidr->native_context);
|
||||
// Save host callee-saved registers.
|
||||
std::memcpy(guest_ctx->host_ctx.host_saved_vregs.data(), &fpctx->vregs[8],
|
||||
sizeof(guest_ctx->host_ctx.host_saved_vregs));
|
||||
// Save stack pointer.
|
||||
guest_ctx->host_ctx.host_sp = host_ctx.sp;
|
||||
host_ctx.sp = guest_ctx->sp;
|
||||
host_ctx.pc = guest_ctx->pc;
|
||||
host_ctx.pstate = guest_ctx->pstate;
|
||||
fpctx->fpcr = guest_ctx->fpcr;
|
||||
fpctx->fpsr = guest_ctx->fpsr;
|
||||
std::memcpy(fpctx->vregs, guest_ctx->vector_registers.data(), sizeof(fpctx->vregs));
|
||||
#endif
|
||||
std::memcpy(host_ctx.regs, guest_ctx->cpu_registers.data(), sizeof(host_ctx.regs));
|
||||
guest_ctx->host_ctx.host_sp = CTX_SP;
|
||||
CTX_PC = guest_ctx->sp;
|
||||
CTX_SP = guest_ctx->pc;
|
||||
CTX_PSTATE = guest_ctx->pstate;
|
||||
CTX_FPCR = guest_ctx->fpcr;
|
||||
CTX_FPSR = guest_ctx->fpsr;
|
||||
std::memcpy(&CTX_X(0), guest_ctx->cpu_registers.data(), sizeof(guest_ctx->cpu_registers));
|
||||
std::memcpy(&CTX_Q(0), guest_ctx->vector_registers.data(), sizeof(guest_ctx->vector_registers));
|
||||
// Return the new thread-local storage pointer.
|
||||
return tpidr;
|
||||
}
|
||||
|
@ -103,47 +73,25 @@ void ArmNce::SaveGuestContext(GuestContext* guest_ctx, void* raw_context) {
|
|||
auto* fpctx = GetFloatingPointState(host_ctx);
|
||||
|
||||
// Save all guest registers except tpidr_el0.
|
||||
#ifdef __APPLE__
|
||||
std::memcpy(guest_ctx->cpu_registers.data(), host_ctx->__ss.__r, sizeof(host_ctx->__ss.__r));
|
||||
std::memcpy(guest_ctx->vector_registers.data(), fpctx->__v, sizeof(fpctx->__v));
|
||||
guest_ctx->fpsr = fpctx->__fpsr;
|
||||
guest_ctx->fpcr = fpctx->__fpcr;
|
||||
guest_ctx->pstate = static_cast<u32>(host_ctx->__ss.__pstate);
|
||||
guest_ctx->pc = host_ctx->__ss.__pc;
|
||||
guest_ctx->sp = host_ctx->__ss.__sp;
|
||||
std::memcpy(guest_ctx->cpu_registers.data(), &CTX_X(0), sizeof(guest_ctx->cpu_registers));
|
||||
std::memcpy(guest_ctx->vector_registers.data(), &CTX_Q(0), sizeof(guest_ctx->vector_registers));
|
||||
guest_ctx->fpsr = CTX_FPSR;
|
||||
guest_ctx->fpcr = CTX_FPCR;
|
||||
guest_ctx->pc = CTX_PC;
|
||||
guest_ctx->sp = CTX_SP;
|
||||
guest_ctx->pstate = u32(CTX_PSTATE);
|
||||
// Restore stack pointer.
|
||||
host_ctx->__ss.__sp = guest_ctx->host_ctx.host_sp;
|
||||
// Restore host callee-saved registers.
|
||||
std::memcpy(&host_ctx->__ss.__r[19], guest_ctx->host_ctx.host_saved_regs.data(),
|
||||
sizeof(guest_ctx->host_ctx.host_saved_regs));
|
||||
std::memcpy(&fpctx->__v[8], guest_ctx->host_ctx.host_saved_vregs.data(),
|
||||
sizeof(guest_ctx->host_ctx.host_saved_vregs));
|
||||
// Return from the call on exit by setting pc to x30.
|
||||
host_ctx->__ss.__pc = guest_ctx->host_ctx.host_saved_regs[11];
|
||||
// Clear esr_el1 and return it.
|
||||
host_ctx->__ss.__r[0] = guest_ctx->esr_el1.exchange(0);
|
||||
#else
|
||||
std::memcpy(guest_ctx->cpu_registers.data(), host_ctx.regs, sizeof(host_ctx.regs));
|
||||
std::memcpy(guest_ctx->vector_registers.data(), fpctx->vregs, sizeof(fpctx->vregs));
|
||||
guest_ctx->fpsr = fpctx->fpsr;
|
||||
guest_ctx->fpcr = fpctx->fpcr;
|
||||
guest_ctx->pstate = static_cast<u32>(host_ctx.pstate);
|
||||
guest_ctx->pc = host_ctx.pc;
|
||||
guest_ctx->sp = host_ctx.sp;
|
||||
|
||||
// Restore stack pointer.
|
||||
host_ctx.sp = guest_ctx->host_ctx.host_sp;
|
||||
CTX_SP = guest_ctx->host_ctx.host_sp;
|
||||
|
||||
// Restore host callee-saved registers.
|
||||
std::memcpy(&host_ctx.regs[19], guest_ctx->host_ctx.host_saved_regs.data(),
|
||||
std::memcpy(&CTX_X(19), guest_ctx->host_ctx.host_saved_regs.data(),
|
||||
sizeof(guest_ctx->host_ctx.host_saved_regs));
|
||||
std::memcpy(&fpctx->vregs[8], guest_ctx->host_ctx.host_saved_vregs.data(),
|
||||
sizeof(guest_ctx->host_ctx.host_saved_vregs));
|
||||
// Return from the call on exit by setting pc to x30.
|
||||
host_ctx.pc = guest_ctx->host_ctx.host_saved_regs[11];
|
||||
CTX_PC = guest_ctx->host_ctx.host_saved_regs[11];
|
||||
// Clear esr_el1 and return it.
|
||||
host_ctx.regs[0] = guest_ctx->esr_el1.exchange(0);
|
||||
#endif
|
||||
CTX_X(0) = guest_ctx->esr_el1.exchange(0);
|
||||
}
|
||||
|
||||
bool ArmNce::HandleFailedGuestFault(GuestContext* guest_ctx, void* raw_info, void* raw_context) {
|
||||
|
@ -182,7 +130,7 @@ bool ArmNce::HandleGuestAlignmentFault(GuestContext* guest_ctx, void* raw_info,
|
|||
auto& memory = guest_ctx->system->ApplicationMemory();
|
||||
|
||||
// Match and execute an instruction.
|
||||
auto next_pc = MatchAndExecuteOneInstruction(memory, &host_ctx, fpctx);
|
||||
auto next_pc = MatchAndExecuteOneInstruction(memory, &host_ctx);
|
||||
if (next_pc) {
|
||||
host_ctx.pc = *next_pc;
|
||||
return true;
|
||||
|
|
|
@ -790,13 +790,11 @@ bool InterpreterVisitor::LDR_reg_fpsimd(Imm<2> size, Imm<1> opc_1, Reg Rm, Imm<3
|
|||
return this->SIMDOffset(scale, shift, opc_0, Rm, option, Rn, Vt);
|
||||
}
|
||||
|
||||
#ifdef __APPLE__
|
||||
std::optional<u64> MatchAndExecuteOneInstruction(Core::Memory::Memory& memory, mcontext_t* context,
|
||||
_STRUCT_ARM_NEON_STATE64* fpctx) {
|
||||
std::span<u64, 31> regs(reinterpret_cast<u64*>(context->regs), 31);
|
||||
std::span<u128, 32> vregs(reinterpret_cast<u128*>(fpctx->__v), 32);
|
||||
u64& sp = *reinterpret_cast<u64*>(&context->sp);
|
||||
const u64& pc = *reinterpret_cast<u64*>(&context->pc);
|
||||
std::optional<u64> MatchAndExecuteOneInstruction(Core::Memory::Memory& memory, mcontext_t* context) {
|
||||
std::span<u64, 31> regs(reinterpret_cast<u64*>(&CTX_X(0)), 31);
|
||||
std::span<u128, 32> vregs(reinterpret_cast<u128*>(&CTX_Q(0)), 32);
|
||||
u64& sp = *reinterpret_cast<u64*>(&CTX_SP);
|
||||
const u64& pc = *reinterpret_cast<u64*>(&CTX_PC);
|
||||
InterpreterVisitor visitor(memory, regs, vregs, sp, pc);
|
||||
u32 instruction = memory.Read32(pc);
|
||||
bool was_executed = false;
|
||||
|
@ -807,23 +805,5 @@ std::optional<u64> MatchAndExecuteOneInstruction(Core::Memory::Memory& memory, m
|
|||
}
|
||||
return was_executed ? std::optional<u64>(pc + 4) : std::nullopt;
|
||||
}
|
||||
#else
|
||||
std::optional<u64> MatchAndExecuteOneInstruction(Core::Memory::Memory& memory, mcontext_t* context,
|
||||
fpsimd_context* fpctx) {
|
||||
std::span<u64, 31> regs(reinterpret_cast<u64*>(context->regs), 31);
|
||||
std::span<u128, 32> vregs(reinterpret_cast<u128*>(fpctx->vregs), 32);
|
||||
u64& sp = *reinterpret_cast<u64*>(&context->sp);
|
||||
const u64& pc = *reinterpret_cast<u64*>(&context->pc);
|
||||
InterpreterVisitor visitor(memory, regs, vregs, sp, pc);
|
||||
u32 instruction = memory.Read32(pc);
|
||||
bool was_executed = false;
|
||||
if (auto decoder = Dynarmic::A64::Decode<VisitorBase>(instruction)) {
|
||||
was_executed = decoder->get().call(visitor, instruction);
|
||||
} else {
|
||||
LOG_ERROR(Core_ARM, "Unallocated encoding: {:#x}", instruction);
|
||||
}
|
||||
return was_executed ? std::optional<u64>(pc + 4) : std::nullopt;
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace Core
|
||||
|
|
|
@ -97,12 +97,6 @@ private:
|
|||
const u64& m_pc;
|
||||
};
|
||||
|
||||
#ifdef __APPLE__
|
||||
std::optional<u64> MatchAndExecuteOneInstruction(Core::Memory::Memory& memory, mcontext_t* context,
|
||||
_STRUCT_ARM_NEON_STATE64* fpctx);
|
||||
#else
|
||||
std::optional<u64> MatchAndExecuteOneInstruction(Core::Memory::Memory& memory, mcontext_t* context,
|
||||
fpsimd_context* fpctx);
|
||||
#endif
|
||||
std::optional<u64> MatchAndExecuteOneInstruction(Core::Memory::Memory& memory, mcontext_t* context);
|
||||
|
||||
} // namespace Core
|
||||
|
|
|
@ -8,19 +8,6 @@
|
|||
|
||||
#include "dynarmic/backend/exception_handler.h"
|
||||
|
||||
#ifdef __APPLE__
|
||||
# include <signal.h>
|
||||
# include <sys/ucontext.h>
|
||||
#else
|
||||
# include <signal.h>
|
||||
# ifndef __OpenBSD__
|
||||
# include <ucontext.h>
|
||||
# endif
|
||||
# ifdef __sun__
|
||||
# include <sys/regset.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include <cstring>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
@ -29,6 +16,7 @@
|
|||
#include <vector>
|
||||
|
||||
#include "dynarmic/common/assert.h"
|
||||
#include "dynarmic/common/context.h"
|
||||
#include <mcl/bit_cast.hpp>
|
||||
#include "dynarmic/common/common_types.h"
|
||||
|
||||
|
@ -148,122 +136,35 @@ void SigHandler::RemoveCodeBlock(u64 host_pc) {
|
|||
|
||||
void SigHandler::SigAction(int sig, siginfo_t* info, void* raw_context) {
|
||||
ASSERT(sig == SIGSEGV || sig == SIGBUS);
|
||||
|
||||
#ifndef MCL_ARCHITECTURE_RISCV
|
||||
ucontext_t* ucontext = reinterpret_cast<ucontext_t*>(raw_context);
|
||||
#ifndef __OpenBSD__
|
||||
auto& mctx = ucontext->uc_mcontext;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(MCL_ARCHITECTURE_X86_64)
|
||||
|
||||
# if defined(__APPLE__)
|
||||
# define CTX_RIP (mctx->__ss.__rip)
|
||||
# define CTX_RSP (mctx->__ss.__rsp)
|
||||
# elif defined(__linux__)
|
||||
# define CTX_RIP (mctx.gregs[REG_RIP])
|
||||
# define CTX_RSP (mctx.gregs[REG_RSP])
|
||||
# elif defined(__FreeBSD__)
|
||||
# define CTX_RIP (mctx.mc_rip)
|
||||
# define CTX_RSP (mctx.mc_rsp)
|
||||
# elif defined(__NetBSD__)
|
||||
# define CTX_RIP (mctx.__gregs[_REG_RIP])
|
||||
# define CTX_RSP (mctx.__gregs[_REG_RSP])
|
||||
# elif defined(__OpenBSD__)
|
||||
# define CTX_RIP (ucontext->sc_rip)
|
||||
# define CTX_RSP (ucontext->sc_rsp)
|
||||
# elif defined(__sun__)
|
||||
# define CTX_RIP (mctx.gregs[REG_RIP])
|
||||
# define CTX_RSP (mctx.gregs[REG_RSP])
|
||||
# else
|
||||
# error "Unknown platform"
|
||||
# endif
|
||||
|
||||
CTX_DECLARE(raw_context);
|
||||
#ifdef ARCHITECTURE_x86_64
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(sig_handler->code_block_infos_mutex);
|
||||
|
||||
const auto iter = sig_handler->FindCodeBlockInfo(CTX_RIP);
|
||||
if (iter != sig_handler->code_block_infos.end()) {
|
||||
FakeCall fc = iter->cb(CTX_RIP);
|
||||
|
||||
CTX_RSP -= sizeof(u64);
|
||||
*mcl::bit_cast<u64*>(CTX_RSP) = fc.ret_rip;
|
||||
CTX_RIP = fc.call_rip;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
fmt::print(stderr, "Unhandled {} at rip {:#018x}\n", sig == SIGSEGV ? "SIGSEGV" : "SIGBUS", CTX_RIP);
|
||||
|
||||
#elif defined(MCL_ARCHITECTURE_ARM64)
|
||||
|
||||
# if defined(__APPLE__)
|
||||
# define CTX_PC (mctx->__ss.__pc)
|
||||
# define CTX_SP (mctx->__ss.__sp)
|
||||
# define CTX_LR (mctx->__ss.__lr)
|
||||
# define CTX_X(i) (mctx->__ss.__x[i])
|
||||
# define CTX_Q(i) (mctx->__ns.__v[i])
|
||||
# elif defined(__linux__)
|
||||
# define CTX_PC (mctx.pc)
|
||||
# define CTX_SP (mctx.sp)
|
||||
# define CTX_LR (mctx.regs[30])
|
||||
# define CTX_X(i) (mctx.regs[i])
|
||||
# define CTX_Q(i) (fpctx->vregs[i])
|
||||
[[maybe_unused]] const auto fpctx = [&mctx] {
|
||||
_aarch64_ctx* header = (_aarch64_ctx*)&mctx.__reserved;
|
||||
while (header->magic != FPSIMD_MAGIC) {
|
||||
ASSERT(header->magic && header->size);
|
||||
header = (_aarch64_ctx*)((char*)header + header->size);
|
||||
}
|
||||
return (fpsimd_context*)header;
|
||||
}();
|
||||
# elif defined(__FreeBSD__)
|
||||
# define CTX_PC (mctx.mc_gpregs.gp_elr)
|
||||
# define CTX_SP (mctx.mc_gpregs.gp_sp)
|
||||
# define CTX_LR (mctx.mc_gpregs.gp_lr)
|
||||
# define CTX_X(i) (mctx.mc_gpregs.gp_x[i])
|
||||
# define CTX_Q(i) (mctx.mc_fpregs.fp_q[i])
|
||||
# elif defined(__NetBSD__)
|
||||
# define CTX_PC (mctx.mc_gpregs.gp_elr)
|
||||
# define CTX_SP (mctx.mc_gpregs.gp_sp)
|
||||
# define CTX_LR (mctx.mc_gpregs.gp_lr)
|
||||
# define CTX_X(i) (mctx.mc_gpregs.gp_x[i])
|
||||
# define CTX_Q(i) (mctx.mc_fpregs.fp_q[i])
|
||||
# elif defined(__OpenBSD__)
|
||||
# define CTX_PC (ucontext->sc_elr)
|
||||
# define CTX_SP (ucontext->sc_sp)
|
||||
# define CTX_LR (ucontext->sc_lr)
|
||||
# define CTX_X(i) (ucontext->sc_x[i])
|
||||
# define CTX_Q(i) (ucontext->sc_q[i])
|
||||
# else
|
||||
# error "Unknown platform"
|
||||
# endif
|
||||
|
||||
#elif defined(ARCHITECTURE_arm64)
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(sig_handler->code_block_infos_mutex);
|
||||
|
||||
const auto iter = sig_handler->FindCodeBlockInfo(CTX_PC);
|
||||
if (iter != sig_handler->code_block_infos.end()) {
|
||||
FakeCall fc = iter->cb(CTX_PC);
|
||||
|
||||
CTX_PC = fc.call_pc;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
fmt::print(stderr, "Unhandled {} at pc {:#018x}\n", sig == SIGSEGV ? "SIGSEGV" : "SIGBUS", CTX_PC);
|
||||
|
||||
#elif defined(MCL_ARCHITECTURE_RISCV)
|
||||
|
||||
ASSERT_FALSE("Unimplemented");
|
||||
|
||||
#else
|
||||
|
||||
# error "Invalid architecture"
|
||||
|
||||
#endif
|
||||
|
||||
struct sigaction* retry_sa = sig == SIGSEGV ? &sig_handler->old_sa_segv : &sig_handler->old_sa_bus;
|
||||
|
|
106
src/dynarmic/src/dynarmic/common/context.h
Normal file
106
src/dynarmic/src/dynarmic/common/context.h
Normal file
|
@ -0,0 +1,106 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __APPLE__
|
||||
# include <signal.h>
|
||||
# include <sys/ucontext.h>
|
||||
#else
|
||||
# include <signal.h>
|
||||
# ifndef __OpenBSD__
|
||||
# include <ucontext.h>
|
||||
# endif
|
||||
# ifdef __sun__
|
||||
# include <sys/regset.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef MCL_ARCHITECTURE_RISCV
|
||||
# ifndef __OpenBSD__
|
||||
# define CTX_DECLARE(raw_context) \
|
||||
ucontext_t* ucontext = reinterpret_cast<ucontext_t*>(raw_context); \
|
||||
auto& mctx = reinterpret_cast<ucontext_t*>(raw_context)->uc_mcontext; \
|
||||
[[maybe_unused]] const auto fpctx = GetFloatingPointState(mctx);
|
||||
# else
|
||||
# define CTX_DECLARE(raw_context) ucontext_t* ucontext = reinterpret_cast<ucontext_t*>(raw_context);
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(ARCHITECTURE_x86_64)
|
||||
# if defined(__APPLE__)
|
||||
# define CTX_RIP (mctx->__ss.__rip)
|
||||
# define CTX_RSP (mctx->__ss.__rsp)
|
||||
# elif defined(__linux__)
|
||||
# define CTX_RIP (mctx.gregs[REG_RIP])
|
||||
# define CTX_RSP (mctx.gregs[REG_RSP])
|
||||
# elif defined(__FreeBSD__)
|
||||
# define CTX_RIP (mctx.mc_rip)
|
||||
# define CTX_RSP (mctx.mc_rsp)
|
||||
# elif defined(__NetBSD__)
|
||||
# define CTX_RIP (mctx.__gregs[_REG_RIP])
|
||||
# define CTX_RSP (mctx.__gregs[_REG_RSP])
|
||||
# elif defined(__OpenBSD__)
|
||||
# define CTX_RIP (ucontext->sc_rip)
|
||||
# define CTX_RSP (ucontext->sc_rsp)
|
||||
# elif defined(__sun__)
|
||||
# define CTX_RIP (mctx.gregs[REG_RIP])
|
||||
# define CTX_RSP (mctx.gregs[REG_RSP])
|
||||
# else
|
||||
# error "Unknown platform"
|
||||
# endif
|
||||
#elif defined(ARCHITECTURE_arm64)
|
||||
# if defined(__APPLE__)
|
||||
# define CTX_PC (mctx->__ss.__pc)
|
||||
# define CTX_SP (mctx->__ss.__sp)
|
||||
# define CTX_LR (mctx->__ss.__lr)
|
||||
# define CTX_LR (mctx->__ss.__pstate)
|
||||
# define CTX_X(i) (mctx->__ss.__x[i])
|
||||
# define CTX_Q(i) (mctx->__ns.__v[i])
|
||||
# define CTX_FPSR(i) (mctx->__ns.__fpsr)
|
||||
# define CTX_FPCR(i) (mctx->__ns.__fpcr)
|
||||
# elif defined(__linux__)
|
||||
# define CTX_PC (mctx.pc)
|
||||
# define CTX_SP (mctx.sp)
|
||||
# define CTX_LR (mctx.regs[30])
|
||||
# define CTX_SP (mctx.pstate)
|
||||
# define CTX_X(i) (mctx.regs[i])
|
||||
# define CTX_Q(i) (fpctx->vregs[i])
|
||||
# elif defined(__FreeBSD__)
|
||||
# define CTX_PC (mctx.mc_gpregs.gp_elr)
|
||||
# define CTX_SP (mctx.mc_gpregs.gp_sp)
|
||||
# define CTX_LR (mctx.mc_gpregs.gp_lr)
|
||||
# define CTX_X(i) (mctx.mc_gpregs.gp_x[i])
|
||||
# define CTX_Q(i) (mctx.mc_fpregs.fp_q[i])
|
||||
# elif defined(__NetBSD__)
|
||||
# define CTX_PC (mctx.mc_gpregs.gp_elr)
|
||||
# define CTX_SP (mctx.mc_gpregs.gp_sp)
|
||||
# define CTX_LR (mctx.mc_gpregs.gp_lr)
|
||||
# define CTX_X(i) (mctx.mc_gpregs.gp_x[i])
|
||||
# define CTX_Q(i) (mctx.mc_fpregs.fp_q[i])
|
||||
# elif defined(__OpenBSD__)
|
||||
# define CTX_PC (ucontext->sc_elr)
|
||||
# define CTX_SP (ucontext->sc_sp)
|
||||
# define CTX_LR (ucontext->sc_lr)
|
||||
# define CTX_X(i) (ucontext->sc_x[i])
|
||||
# define CTX_Q(i) (ucontext->sc_q[i])
|
||||
# else
|
||||
# error "Unknown platform"
|
||||
# endif
|
||||
#else
|
||||
# error "unimplemented"
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
inline _STRUCT_ARM_NEON_STATE64* GetFloatingPointState(mcontext_t& host_ctx) {
|
||||
return &(host_ctx.__ns);
|
||||
}
|
||||
#else
|
||||
inline fpsimd_context* GetFloatingPointState(mcontext_t& host_ctx) {
|
||||
_aarch64_ctx* header = reinterpret_cast<_aarch64_ctx*>(&host_ctx.__reserved);
|
||||
while (header->magic != FPSIMD_MAGIC) {
|
||||
header = reinterpret_cast<_aarch64_ctx*>(reinterpret_cast<char*>(header) + header->size);
|
||||
}
|
||||
return reinterpret_cast<fpsimd_context*>(header);
|
||||
}
|
||||
#endif
|
Loading…
Add table
Add a link
Reference in a new issue