[dynarmic] improve A32 translate loop (#3780)
Some checks are pending
tx-src / sources (push) Waiting to run
Check Strings / check-strings (push) Waiting to run

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:
lizzie 2026-03-31 05:23:43 +02:00 committed by crueter
parent cf7086de7c
commit e9f4541069
No known key found for this signature in database
GPG key ID: 425ACD2D4830EBC6
2 changed files with 40 additions and 14 deletions

View file

@ -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);

View file

@ -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 )