mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-12-16 12:09:07 +00:00
register state preservation infra
This commit is contained in:
parent
7326c11a3e
commit
32f08343b2
@ -2,6 +2,7 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <cstring>
|
||||
#include "arm64_codegen.h"
|
||||
#include "common/assert.h"
|
||||
#include "register_mapping.h"
|
||||
|
||||
@ -116,8 +117,152 @@ bool RegisterMapper::IsRegisterSpilled(X86_64Register x86_reg) const {
|
||||
return spilled_registers[index];
|
||||
}
|
||||
|
||||
void RegisterMapper::SaveAllRegisters() {}
|
||||
void RegisterMapper::SaveRegister(Arm64CodeGenerator& codegen, X86_64Register x86_reg,
|
||||
RegisterContext* ctx) {
|
||||
if (!ctx) {
|
||||
return;
|
||||
}
|
||||
|
||||
void RegisterMapper::RestoreAllRegisters() {}
|
||||
int arm64_reg = MapX86_64ToArm64(x86_reg);
|
||||
if (arm64_reg == INVALID_MAPPING) {
|
||||
return;
|
||||
}
|
||||
|
||||
size_t index = static_cast<size_t>(x86_reg);
|
||||
if (IsXmmRegister(x86_reg)) {
|
||||
int vreg = MapX86_64XmmToArm64Neon(x86_reg);
|
||||
if (vreg != INVALID_MAPPING) {
|
||||
codegen.movz(SCRATCH_REG,
|
||||
reinterpret_cast<u64>(&ctx->xmm_regs[index - 16][0]) & 0xFFFF);
|
||||
codegen.movk(SCRATCH_REG,
|
||||
(reinterpret_cast<u64>(&ctx->xmm_regs[index - 16][0]) >> 16) & 0xFFFF, 16);
|
||||
codegen.movk(SCRATCH_REG,
|
||||
(reinterpret_cast<u64>(&ctx->xmm_regs[index - 16][0]) >> 32) & 0xFFFF, 32);
|
||||
codegen.movk(SCRATCH_REG,
|
||||
(reinterpret_cast<u64>(&ctx->xmm_regs[index - 16][0]) >> 48) & 0xFFFF, 48);
|
||||
codegen.str_v(vreg, SCRATCH_REG, 0);
|
||||
}
|
||||
} else if (x86_reg == X86_64Register::FLAGS) {
|
||||
codegen.movz(SCRATCH_REG, reinterpret_cast<u64>(&ctx->flags) & 0xFFFF);
|
||||
codegen.movk(SCRATCH_REG, (reinterpret_cast<u64>(&ctx->flags) >> 16) & 0xFFFF, 16);
|
||||
codegen.movk(SCRATCH_REG, (reinterpret_cast<u64>(&ctx->flags) >> 32) & 0xFFFF, 32);
|
||||
codegen.movk(SCRATCH_REG, (reinterpret_cast<u64>(&ctx->flags) >> 48) & 0xFFFF, 48);
|
||||
codegen.str(arm64_reg, SCRATCH_REG, 0);
|
||||
} else if (x86_reg == X86_64Register::RSP || x86_reg == X86_64Register::RBP) {
|
||||
if (arm64_reg == STACK_POINTER) {
|
||||
codegen.mov(SCRATCH_REG, STACK_POINTER);
|
||||
codegen.movz(SCRATCH_REG2, reinterpret_cast<u64>(&ctx->rsp) & 0xFFFF);
|
||||
codegen.movk(SCRATCH_REG2, (reinterpret_cast<u64>(&ctx->rsp) >> 16) & 0xFFFF, 16);
|
||||
codegen.movk(SCRATCH_REG2, (reinterpret_cast<u64>(&ctx->rsp) >> 32) & 0xFFFF, 32);
|
||||
codegen.movk(SCRATCH_REG2, (reinterpret_cast<u64>(&ctx->rsp) >> 48) & 0xFFFF, 48);
|
||||
codegen.str(SCRATCH_REG, SCRATCH_REG2, 0);
|
||||
} else {
|
||||
codegen.movz(SCRATCH_REG, reinterpret_cast<u64>(&ctx->rbp) & 0xFFFF);
|
||||
codegen.movk(SCRATCH_REG, (reinterpret_cast<u64>(&ctx->rbp) >> 16) & 0xFFFF, 16);
|
||||
codegen.movk(SCRATCH_REG, (reinterpret_cast<u64>(&ctx->rbp) >> 32) & 0xFFFF, 32);
|
||||
codegen.movk(SCRATCH_REG, (reinterpret_cast<u64>(&ctx->rbp) >> 48) & 0xFFFF, 48);
|
||||
codegen.str(arm64_reg, SCRATCH_REG, 0);
|
||||
}
|
||||
} else {
|
||||
if (index < 16) {
|
||||
codegen.movz(SCRATCH_REG, reinterpret_cast<u64>(&ctx->gp_regs[index]) & 0xFFFF);
|
||||
codegen.movk(SCRATCH_REG, (reinterpret_cast<u64>(&ctx->gp_regs[index]) >> 16) & 0xFFFF,
|
||||
16);
|
||||
codegen.movk(SCRATCH_REG, (reinterpret_cast<u64>(&ctx->gp_regs[index]) >> 32) & 0xFFFF,
|
||||
32);
|
||||
codegen.movk(SCRATCH_REG, (reinterpret_cast<u64>(&ctx->gp_regs[index]) >> 48) & 0xFFFF,
|
||||
48);
|
||||
codegen.str(arm64_reg, SCRATCH_REG, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RegisterMapper::RestoreRegister(Arm64CodeGenerator& codegen, X86_64Register x86_reg,
|
||||
RegisterContext* ctx) {
|
||||
if (!ctx) {
|
||||
return;
|
||||
}
|
||||
|
||||
int arm64_reg = MapX86_64ToArm64(x86_reg);
|
||||
if (arm64_reg == INVALID_MAPPING) {
|
||||
return;
|
||||
}
|
||||
|
||||
size_t index = static_cast<size_t>(x86_reg);
|
||||
if (IsXmmRegister(x86_reg)) {
|
||||
int vreg = MapX86_64XmmToArm64Neon(x86_reg);
|
||||
if (vreg != INVALID_MAPPING) {
|
||||
codegen.movz(SCRATCH_REG,
|
||||
reinterpret_cast<u64>(&ctx->xmm_regs[index - 16][0]) & 0xFFFF);
|
||||
codegen.movk(SCRATCH_REG,
|
||||
(reinterpret_cast<u64>(&ctx->xmm_regs[index - 16][0]) >> 16) & 0xFFFF, 16);
|
||||
codegen.movk(SCRATCH_REG,
|
||||
(reinterpret_cast<u64>(&ctx->xmm_regs[index - 16][0]) >> 32) & 0xFFFF, 32);
|
||||
codegen.movk(SCRATCH_REG,
|
||||
(reinterpret_cast<u64>(&ctx->xmm_regs[index - 16][0]) >> 48) & 0xFFFF, 48);
|
||||
codegen.ldr_v(vreg, SCRATCH_REG, 0);
|
||||
}
|
||||
} else if (x86_reg == X86_64Register::FLAGS) {
|
||||
codegen.movz(SCRATCH_REG, reinterpret_cast<u64>(&ctx->flags) & 0xFFFF);
|
||||
codegen.movk(SCRATCH_REG, (reinterpret_cast<u64>(&ctx->flags) >> 16) & 0xFFFF, 16);
|
||||
codegen.movk(SCRATCH_REG, (reinterpret_cast<u64>(&ctx->flags) >> 32) & 0xFFFF, 32);
|
||||
codegen.movk(SCRATCH_REG, (reinterpret_cast<u64>(&ctx->flags) >> 48) & 0xFFFF, 48);
|
||||
codegen.ldr(arm64_reg, SCRATCH_REG, 0);
|
||||
} else if (x86_reg == X86_64Register::RSP || x86_reg == X86_64Register::RBP) {
|
||||
if (arm64_reg == STACK_POINTER) {
|
||||
codegen.movz(SCRATCH_REG, reinterpret_cast<u64>(&ctx->rsp) & 0xFFFF);
|
||||
codegen.movk(SCRATCH_REG, (reinterpret_cast<u64>(&ctx->rsp) >> 16) & 0xFFFF, 16);
|
||||
codegen.movk(SCRATCH_REG, (reinterpret_cast<u64>(&ctx->rsp) >> 32) & 0xFFFF, 32);
|
||||
codegen.movk(SCRATCH_REG, (reinterpret_cast<u64>(&ctx->rsp) >> 48) & 0xFFFF, 48);
|
||||
codegen.ldr(SCRATCH_REG2, SCRATCH_REG, 0);
|
||||
codegen.mov(STACK_POINTER, SCRATCH_REG2);
|
||||
} else {
|
||||
codegen.movz(SCRATCH_REG, reinterpret_cast<u64>(&ctx->rbp) & 0xFFFF);
|
||||
codegen.movk(SCRATCH_REG, (reinterpret_cast<u64>(&ctx->rbp) >> 16) & 0xFFFF, 16);
|
||||
codegen.movk(SCRATCH_REG, (reinterpret_cast<u64>(&ctx->rbp) >> 32) & 0xFFFF, 32);
|
||||
codegen.movk(SCRATCH_REG, (reinterpret_cast<u64>(&ctx->rbp) >> 48) & 0xFFFF, 48);
|
||||
codegen.ldr(arm64_reg, SCRATCH_REG, 0);
|
||||
}
|
||||
} else {
|
||||
if (index < 16) {
|
||||
codegen.movz(SCRATCH_REG, reinterpret_cast<u64>(&ctx->gp_regs[index]) & 0xFFFF);
|
||||
codegen.movk(SCRATCH_REG, (reinterpret_cast<u64>(&ctx->gp_regs[index]) >> 16) & 0xFFFF,
|
||||
16);
|
||||
codegen.movk(SCRATCH_REG, (reinterpret_cast<u64>(&ctx->gp_regs[index]) >> 32) & 0xFFFF,
|
||||
32);
|
||||
codegen.movk(SCRATCH_REG, (reinterpret_cast<u64>(&ctx->gp_regs[index]) >> 48) & 0xFFFF,
|
||||
48);
|
||||
codegen.ldr(arm64_reg, SCRATCH_REG, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RegisterMapper::SaveAllRegisters(Arm64CodeGenerator& codegen, RegisterContext* ctx) {
|
||||
if (!ctx) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 16; i++) {
|
||||
SaveRegister(codegen, static_cast<X86_64Register>(i), ctx);
|
||||
}
|
||||
for (int i = 16; i < 32; i++) {
|
||||
SaveRegister(codegen, static_cast<X86_64Register>(i), ctx);
|
||||
}
|
||||
SaveRegister(codegen, X86_64Register::FLAGS, ctx);
|
||||
}
|
||||
|
||||
void RegisterMapper::RestoreAllRegisters(Arm64CodeGenerator& codegen, RegisterContext* ctx) {
|
||||
if (!ctx) {
|
||||
return;
|
||||
}
|
||||
|
||||
RestoreRegister(codegen, X86_64Register::FLAGS, ctx);
|
||||
for (int i = 16; i < 32; i++) {
|
||||
RestoreRegister(codegen, static_cast<X86_64Register>(i), ctx);
|
||||
}
|
||||
for (int i = 0; i < 16; i++) {
|
||||
RestoreRegister(codegen, static_cast<X86_64Register>(i), ctx);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Core::Jit
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
|
||||
#include <array>
|
||||
#include "common/types.h"
|
||||
#include "core/jit/arm64_codegen.h"
|
||||
|
||||
namespace Core::Jit {
|
||||
|
||||
@ -97,6 +98,14 @@ enum class Arm64Register : u8 {
|
||||
COUNT = 48
|
||||
};
|
||||
|
||||
struct RegisterContext {
|
||||
u64 gp_regs[16];
|
||||
u64 xmm_regs[16][2];
|
||||
u64 flags;
|
||||
u64 rsp;
|
||||
u64 rbp;
|
||||
};
|
||||
|
||||
class RegisterMapper {
|
||||
public:
|
||||
RegisterMapper();
|
||||
@ -109,8 +118,10 @@ public:
|
||||
void ReloadRegister(X86_64Register x86_reg);
|
||||
bool IsRegisterSpilled(X86_64Register x86_reg) const;
|
||||
|
||||
void SaveAllRegisters();
|
||||
void RestoreAllRegisters();
|
||||
void SaveAllRegisters(Arm64CodeGenerator& codegen, RegisterContext* ctx);
|
||||
void RestoreAllRegisters(Arm64CodeGenerator& codegen, RegisterContext* ctx);
|
||||
void SaveRegister(Arm64CodeGenerator& codegen, X86_64Register x86_reg, RegisterContext* ctx);
|
||||
void RestoreRegister(Arm64CodeGenerator& codegen, X86_64Register x86_reg, RegisterContext* ctx);
|
||||
|
||||
static constexpr int SCRATCH_REG = 9;
|
||||
static constexpr int SCRATCH_REG2 = 10;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user