mirror of
https://git.eden-emu.dev/eden-emu/eden
synced 2026-04-10 03:18:55 +02:00
[dynarmic] improve A32 translate loop (#3780)
Signed-off-by: lizzie <lizzie@eden-emu.dev> Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3780 Reviewed-by: Maufeat <sahyno1996@gmail.com> Reviewed-by: CamilleLaVey <camillelavey99@gmail.com> Co-authored-by: lizzie <lizzie@eden-emu.dev> Co-committed-by: lizzie <lizzie@eden-emu.dev>
This commit is contained in:
parent
cf7086de7c
commit
e9f4541069
2 changed files with 40 additions and 14 deletions
|
|
@ -121,28 +121,49 @@ A32EmitX64::BlockDescriptor A32EmitX64::Emit(IR::Block& block) {
|
||||||
code.lea(rbp, code.ptr[rsp + ABI_SHADOW_SPACE + offsetof(StackLayout, abi_base_pointer) - 8]);
|
code.lea(rbp, code.ptr[rsp + ABI_SHADOW_SPACE + offsetof(StackLayout, abi_base_pointer) - 8]);
|
||||||
|
|
||||||
EmitCondPrelude(ctx);
|
EmitCondPrelude(ctx);
|
||||||
|
typedef void (EmitX64::*EmitHandlerFn)(EmitContext& context, IR::Inst* inst);
|
||||||
for (auto iter = block.instructions.begin(); iter != block.instructions.end(); ++iter) [[likely]] {
|
constexpr EmitHandlerFn opcode_handlers[] = {
|
||||||
auto* inst = &*iter;
|
#define OPCODE(name, type, ...) &EmitX64::Emit##name,
|
||||||
// Call the relevant Emit* member function.
|
#define A32OPC(name, type, ...)
|
||||||
switch (inst->GetOpcode()) {
|
#define A64OPC(name, type, ...)
|
||||||
#define OPCODE(name, type, ...) \
|
#include "dynarmic/ir/opcodes.inc"
|
||||||
case IR::Opcode::name: \
|
#undef OPCODE
|
||||||
A32EmitX64::Emit##name(ctx, inst); \
|
#undef A32OPC
|
||||||
break;
|
#undef A64OPC
|
||||||
#define A32OPC(name, type, ...) \
|
};
|
||||||
case IR::Opcode::A32##name: \
|
typedef void (A32EmitX64::*A32EmitHandlerFn)(A32EmitContext& context, IR::Inst* inst);
|
||||||
A32EmitX64::EmitA32##name(ctx, inst);\
|
constexpr A32EmitHandlerFn a32_handlers[] = {
|
||||||
break;
|
#define OPCODE(...)
|
||||||
|
#define A32OPC(name, type, ...) &A32EmitX64::EmitA32##name,
|
||||||
#define A64OPC(...)
|
#define A64OPC(...)
|
||||||
#include "dynarmic/ir/opcodes.inc"
|
#include "dynarmic/ir/opcodes.inc"
|
||||||
#undef OPCODE
|
#undef OPCODE
|
||||||
#undef A32OPC
|
#undef A32OPC
|
||||||
|
#undef A64OPC
|
||||||
|
};
|
||||||
|
|
||||||
|
for (auto& inst : block.instructions) {
|
||||||
|
auto const opcode = inst.GetOpcode();
|
||||||
|
// Call the relevant Emit* member function.
|
||||||
|
switch (opcode) {
|
||||||
|
#define OPCODE(name, type, ...) case IR::Opcode::name: goto opcode_branch;
|
||||||
|
#define A32OPC(name, type, ...) case IR::Opcode::A32##name: goto a32_branch;
|
||||||
|
#define A64OPC(name, type, ...)
|
||||||
|
#include "dynarmic/ir/opcodes.inc"
|
||||||
|
#undef OPCODE
|
||||||
|
#undef A32OPC
|
||||||
#undef A64OPC
|
#undef A64OPC
|
||||||
default:
|
default:
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
}
|
}
|
||||||
reg_alloc.EndOfAllocScope();
|
opcode_branch:
|
||||||
|
(this->*opcode_handlers[size_t(opcode)])(ctx, &inst);
|
||||||
|
goto finish_this_inst;
|
||||||
|
a32_branch:
|
||||||
|
// Update with FIRST A32 instruction
|
||||||
|
(this->*a32_handlers[size_t(opcode) - size_t(IR::Opcode::A32SetCheckBit)])(ctx, &inst);
|
||||||
|
finish_this_inst:
|
||||||
|
ctx.reg_alloc.EndOfAllocScope();
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
if (conf.very_verbose_debugging_output)
|
if (conf.very_verbose_debugging_output)
|
||||||
EmitVerboseDebuggingOutput(reg_alloc);
|
EmitVerboseDebuggingOutput(reg_alloc);
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,6 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
// First we list common shared opcodes
|
// First we list common shared opcodes
|
||||||
// Since we give priority to A64 performance, we include them first, this is so we
|
// Since we give priority to A64 performance, we include them first, this is so we
|
||||||
// can discard all A32 opcodes instead of having a "hole" in our checks
|
// can discard all A32 opcodes instead of having a "hole" in our checks
|
||||||
|
|
@ -710,6 +713,8 @@ A64OPC(ExclusiveWriteMemory32, U32, U64,
|
||||||
A64OPC(ExclusiveWriteMemory64, U32, U64, U64, U64, AccType )
|
A64OPC(ExclusiveWriteMemory64, U32, U64, U64, U64, AccType )
|
||||||
A64OPC(ExclusiveWriteMemory128, U32, U64, U64, U128, AccType )
|
A64OPC(ExclusiveWriteMemory128, U32, U64, U64, U128, AccType )
|
||||||
|
|
||||||
|
// Remember to update:
|
||||||
|
// - a32_emit_x64.cpp
|
||||||
|
|
||||||
// A32 Context getters/setters
|
// A32 Context getters/setters
|
||||||
A32OPC(SetCheckBit, Void, U1 )
|
A32OPC(SetCheckBit, Void, U1 )
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue