From 5abe0ff4dfdd34eb0b68c3dfa8d9e764218ffb84 Mon Sep 17 00:00:00 2001 From: lizzie Date: Tue, 10 Mar 2026 08:18:48 +0000 Subject: [PATCH] boost::stable_Vector evil --- .../arm64/emit_arm64_data_processing.cpp | 26 ++++++++--------- .../backend/arm64/emit_arm64_packed.cpp | 21 ++++++++------ .../backend/arm64/emit_arm64_saturation.cpp | 10 +++---- .../riscv64/emit_riscv64_data_processing.cpp | 11 +++++--- .../backend/x64/emit_x64_data_processing.cpp | 24 ++++++++-------- .../dynarmic/backend/x64/emit_x64_packed.cpp | 20 ++++++------- .../backend/x64/emit_x64_saturation.cpp | 6 ++-- .../dynarmic/backend/x64/emit_x64_vector.cpp | 16 +++++------ src/dynarmic/src/dynarmic/ir/basic_block.h | 2 +- .../src/dynarmic/ir/microinstruction.cpp | 4 +-- .../src/dynarmic/ir/microinstruction.h | 7 +++-- src/dynarmic/src/dynarmic/ir/opt_passes.cpp | 28 +++++++++---------- 12 files changed, 91 insertions(+), 84 deletions(-) diff --git a/src/dynarmic/src/dynarmic/backend/arm64/emit_arm64_data_processing.cpp b/src/dynarmic/src/dynarmic/backend/arm64/emit_arm64_data_processing.cpp index ef21fd45bd..227476a90e 100644 --- a/src/dynarmic/src/dynarmic/backend/arm64/emit_arm64_data_processing.cpp +++ b/src/dynarmic/src/dynarmic/backend/arm64/emit_arm64_data_processing.cpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later /* This file is part of the dynarmic project. @@ -133,7 +133,7 @@ void EmitIR(oaknut::CodeGenerator& code, EmitC template<> void EmitIR(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) { - const auto carry_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetCarryFromOp); + const auto carry_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetCarryFromOp); auto args = ctx.reg_alloc.GetArgumentInfo(inst); @@ -242,7 +242,7 @@ void EmitIR(oaknut::CodeGenerator& code, Emit template<> void EmitIR(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) { - const auto carry_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetCarryFromOp); + const auto carry_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetCarryFromOp); auto args = ctx.reg_alloc.GetArgumentInfo(inst); auto& operand_arg = args[0]; @@ -379,7 +379,7 @@ void EmitIR(oaknut::CodeGenerator& code, EmitCon template<> void EmitIR(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) { - const auto carry_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetCarryFromOp); + const auto carry_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetCarryFromOp); auto args = ctx.reg_alloc.GetArgumentInfo(inst); auto& operand_arg = args[0]; @@ -517,7 +517,7 @@ void EmitIR(oaknut::CodeGenerator& code, EmitCo template<> void EmitIR(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) { - const auto carry_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetCarryFromOp); + const auto carry_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetCarryFromOp); auto args = ctx.reg_alloc.GetArgumentInfo(inst); auto& operand_arg = args[0]; @@ -643,7 +643,7 @@ void EmitIR(oaknut::CodeGenerator& code, Emi template<> void EmitIR(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) { - const auto carry_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetCarryFromOp); + const auto carry_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetCarryFromOp); auto args = ctx.reg_alloc.GetArgumentInfo(inst); auto& operand_arg = args[0]; @@ -730,7 +730,7 @@ void EmitIR(oaknut::CodeGenerator& code, EmitContext& template<> void EmitIR(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) { - const auto carry_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetCarryFromOp); + const auto carry_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetCarryFromOp); auto args = ctx.reg_alloc.GetArgumentInfo(inst); auto Wresult = ctx.reg_alloc.WriteW(inst); @@ -884,8 +884,8 @@ static void MaybeAddSubImm(oaknut::CodeGenerator& code, u64 imm, EmitFn emit_fn) template static void EmitAddSub(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) { - const auto nzcv_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetNZCVFromOp); - const auto overflow_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetOverflowFromOp); + const auto nzcv_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetNZCVFromOp); + const auto overflow_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetOverflowFromOp); auto args = ctx.reg_alloc.GetArgumentInfo(inst); @@ -1133,8 +1133,8 @@ static void EmitBitOp(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* i auto Ra = ctx.reg_alloc.ReadReg(args[0]); if constexpr (!std::is_same_v) { - const auto nz_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetNZFromOp); - const auto nzcv_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetNZCVFromOp); + const auto nz_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetNZFromOp); + const auto nzcv_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetNZCVFromOp); ASSERT(!(nz_inst && nzcv_inst)); const auto flag_inst = nz_inst ? nz_inst : nzcv_inst; @@ -1170,8 +1170,8 @@ static void EmitBitOp(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* i template static void EmitAndNot(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) { - const auto nz_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetNZFromOp); - const auto nzcv_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetNZCVFromOp); + const auto nz_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetNZFromOp); + const auto nzcv_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetNZCVFromOp); ASSERT(!(nz_inst && nzcv_inst)); const auto flag_inst = nz_inst ? nz_inst : nzcv_inst; diff --git a/src/dynarmic/src/dynarmic/backend/arm64/emit_arm64_packed.cpp b/src/dynarmic/src/dynarmic/backend/arm64/emit_arm64_packed.cpp index b9f13ac6f2..2421c3a496 100644 --- a/src/dynarmic/src/dynarmic/backend/arm64/emit_arm64_packed.cpp +++ b/src/dynarmic/src/dynarmic/backend/arm64/emit_arm64_packed.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + /* This file is part of the dynarmic project. * Copyright (c) 2022 MerryMage * SPDX-License-Identifier: 0BSD @@ -46,7 +49,7 @@ static void EmitSaturatedPackedOp(oaknut::CodeGenerator&, EmitContext& ctx, IR:: template<> void EmitIR(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) { - const auto ge_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetGEFromOp); + const auto ge_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetGEFromOp); auto args = ctx.reg_alloc.GetArgumentInfo(inst); auto Vresult = ctx.reg_alloc.WriteD(inst); @@ -66,7 +69,7 @@ void EmitIR(oaknut::CodeGenerator& code, EmitContext& c template<> void EmitIR(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) { - const auto ge_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetGEFromOp); + const auto ge_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetGEFromOp); auto args = ctx.reg_alloc.GetArgumentInfo(inst); auto Vresult = ctx.reg_alloc.WriteD(inst); @@ -87,7 +90,7 @@ void EmitIR(oaknut::CodeGenerator& code, EmitContext& c template<> void EmitIR(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) { - const auto ge_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetGEFromOp); + const auto ge_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetGEFromOp); auto args = ctx.reg_alloc.GetArgumentInfo(inst); auto Vresult = ctx.reg_alloc.WriteD(inst); @@ -108,7 +111,7 @@ void EmitIR(oaknut::CodeGenerator& code, EmitContext& c template<> void EmitIR(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) { - const auto ge_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetGEFromOp); + const auto ge_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetGEFromOp); auto args = ctx.reg_alloc.GetArgumentInfo(inst); auto Vresult = ctx.reg_alloc.WriteD(inst); @@ -129,7 +132,7 @@ void EmitIR(oaknut::CodeGenerator& code, EmitContext& c template<> void EmitIR(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) { - const auto ge_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetGEFromOp); + const auto ge_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetGEFromOp); auto args = ctx.reg_alloc.GetArgumentInfo(inst); auto Vresult = ctx.reg_alloc.WriteD(inst); @@ -149,7 +152,7 @@ void EmitIR(oaknut::CodeGenerator& code, EmitContext& template<> void EmitIR(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) { - const auto ge_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetGEFromOp); + const auto ge_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetGEFromOp); auto args = ctx.reg_alloc.GetArgumentInfo(inst); auto Vresult = ctx.reg_alloc.WriteD(inst); @@ -170,7 +173,7 @@ void EmitIR(oaknut::CodeGenerator& code, EmitContext& template<> void EmitIR(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) { - const auto ge_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetGEFromOp); + const auto ge_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetGEFromOp); auto args = ctx.reg_alloc.GetArgumentInfo(inst); auto Vresult = ctx.reg_alloc.WriteD(inst); @@ -191,7 +194,7 @@ void EmitIR(oaknut::CodeGenerator& code, EmitContext& template<> void EmitIR(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) { - const auto ge_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetGEFromOp); + const auto ge_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetGEFromOp); auto args = ctx.reg_alloc.GetArgumentInfo(inst); auto Vresult = ctx.reg_alloc.WriteD(inst); @@ -212,7 +215,7 @@ void EmitIR(oaknut::CodeGenerator& code, EmitContext& template static void EmitPackedAddSub(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) { - const auto ge_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetGEFromOp); + const auto ge_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetGEFromOp); auto args = ctx.reg_alloc.GetArgumentInfo(inst); auto Vresult = ctx.reg_alloc.WriteD(inst); diff --git a/src/dynarmic/src/dynarmic/backend/arm64/emit_arm64_saturation.cpp b/src/dynarmic/src/dynarmic/backend/arm64/emit_arm64_saturation.cpp index f9d1e5d619..9681701a28 100644 --- a/src/dynarmic/src/dynarmic/backend/arm64/emit_arm64_saturation.cpp +++ b/src/dynarmic/src/dynarmic/backend/arm64/emit_arm64_saturation.cpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later /* This file is part of the dynarmic project. @@ -23,7 +23,7 @@ using namespace oaknut::util; template<> void EmitIR(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) { - const auto overflow_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetOverflowFromOp); + const auto overflow_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetOverflowFromOp); ASSERT(overflow_inst); auto args = ctx.reg_alloc.GetArgumentInfo(inst); @@ -43,7 +43,7 @@ void EmitIR(oaknut::CodeGenerator& cod template<> void EmitIR(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) { - const auto overflow_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetOverflowFromOp); + const auto overflow_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetOverflowFromOp); ASSERT(overflow_inst); auto args = ctx.reg_alloc.GetArgumentInfo(inst); @@ -63,7 +63,7 @@ void EmitIR(oaknut::CodeGenerator& cod template<> void EmitIR(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) { - const auto overflow_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetOverflowFromOp); + const auto overflow_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetOverflowFromOp); auto args = ctx.reg_alloc.GetArgumentInfo(inst); const size_t N = args[1].GetImmediateU8(); @@ -104,7 +104,7 @@ void EmitIR(oaknut::CodeGenerator& code, EmitConte template<> void EmitIR(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) { - const auto overflow_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetOverflowFromOp); + const auto overflow_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetOverflowFromOp); auto args = ctx.reg_alloc.GetArgumentInfo(inst); auto Wresult = ctx.reg_alloc.WriteW(inst); diff --git a/src/dynarmic/src/dynarmic/backend/riscv64/emit_riscv64_data_processing.cpp b/src/dynarmic/src/dynarmic/backend/riscv64/emit_riscv64_data_processing.cpp index 51ed027a05..3a812cb860 100644 --- a/src/dynarmic/src/dynarmic/backend/riscv64/emit_riscv64_data_processing.cpp +++ b/src/dynarmic/src/dynarmic/backend/riscv64/emit_riscv64_data_processing.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + /* This file is part of the dynarmic project. * Copyright (c) 2024 MerryMage * SPDX-License-Identifier: 0BSD @@ -84,7 +87,7 @@ void EmitIR(biscuit::Assembler&, EmitContext& template<> void EmitIR(biscuit::Assembler& as, EmitContext& ctx, IR::Inst* inst) { - const auto carry_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetCarryFromOp); + const auto carry_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetCarryFromOp); auto args = ctx.reg_alloc.GetArgumentInfo(inst); auto& operand_arg = args[0]; @@ -126,7 +129,7 @@ void EmitIR(biscuit::Assembler&, EmitContext&, I template<> void EmitIR(biscuit::Assembler& as, EmitContext& ctx, IR::Inst* inst) { - const auto carry_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetCarryFromOp); + const auto carry_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetCarryFromOp); auto args = ctx.reg_alloc.GetArgumentInfo(inst); auto& operand_arg = args[0]; @@ -267,8 +270,8 @@ static void AddImmWithFlags(biscuit::Assembler& as, biscuit::GPR rd, biscuit::GP template static void EmitAddSub(biscuit::Assembler& as, EmitContext& ctx, IR::Inst* inst) { - const auto nzcv_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetNZCVFromOp); - const auto overflow_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetOverflowFromOp); + const auto nzcv_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetNZCVFromOp); + const auto overflow_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetOverflowFromOp); auto args = ctx.reg_alloc.GetArgumentInfo(inst); diff --git a/src/dynarmic/src/dynarmic/backend/x64/emit_x64_data_processing.cpp b/src/dynarmic/src/dynarmic/backend/x64/emit_x64_data_processing.cpp index f2af4e5b80..18f733a419 100644 --- a/src/dynarmic/src/dynarmic/backend/x64/emit_x64_data_processing.cpp +++ b/src/dynarmic/src/dynarmic/backend/x64/emit_x64_data_processing.cpp @@ -63,7 +63,7 @@ void EmitX64::EmitLeastSignificantWord(EmitContext& ctx, IR::Inst* inst) { } void EmitX64::EmitMostSignificantWord(EmitContext& ctx, IR::Inst* inst) { - const auto carry_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetCarryFromOp); + const auto carry_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetCarryFromOp); auto args = ctx.reg_alloc.GetArgumentInfo(inst); const Xbyak::Reg64 result = ctx.reg_alloc.UseScratchGpr(code, args[0]); @@ -265,7 +265,7 @@ void EmitX64::EmitReplicateBit64(Dynarmic::Backend::X64::EmitContext& ctx, IR::I } void EmitX64::EmitLogicalShiftLeft32(EmitContext& ctx, IR::Inst* inst) { - const auto carry_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetCarryFromOp); + const auto carry_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetCarryFromOp); auto args = ctx.reg_alloc.GetArgumentInfo(inst); auto& operand_arg = args[0]; @@ -401,7 +401,7 @@ void EmitX64::EmitLogicalShiftLeft64(EmitContext& ctx, IR::Inst* inst) { } void EmitX64::EmitLogicalShiftRight32(EmitContext& ctx, IR::Inst* inst) { - const auto carry_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetCarryFromOp); + const auto carry_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetCarryFromOp); auto args = ctx.reg_alloc.GetArgumentInfo(inst); auto& operand_arg = args[0]; @@ -535,7 +535,7 @@ void EmitX64::EmitLogicalShiftRight64(EmitContext& ctx, IR::Inst* inst) { } void EmitX64::EmitArithmeticShiftRight32(EmitContext& ctx, IR::Inst* inst) { - const auto carry_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetCarryFromOp); + const auto carry_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetCarryFromOp); auto args = ctx.reg_alloc.GetArgumentInfo(inst); auto& operand_arg = args[0]; @@ -664,7 +664,7 @@ void EmitX64::EmitArithmeticShiftRight64(EmitContext& ctx, IR::Inst* inst) { } void EmitX64::EmitRotateRight32(EmitContext& ctx, IR::Inst* inst) { - const auto carry_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetCarryFromOp); + const auto carry_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetCarryFromOp); auto args = ctx.reg_alloc.GetArgumentInfo(inst); auto& operand_arg = args[0]; @@ -768,7 +768,7 @@ void EmitX64::EmitRotateRight64(EmitContext& ctx, IR::Inst* inst) { } void EmitX64::EmitRotateRightExtended(EmitContext& ctx, IR::Inst* inst) { - const auto carry_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetCarryFromOp); + const auto carry_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetCarryFromOp); auto args = ctx.reg_alloc.GetArgumentInfo(inst); const Xbyak::Reg32 result = ctx.reg_alloc.UseScratchGpr(code, args[0]).cvt32(); @@ -919,9 +919,9 @@ static Xbyak::Reg64 DoNZCV(BlockOfCode& code, RegAlloc& reg_alloc, IR::Inst* nzc } static void EmitAdd(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, size_t bitsize) { - const auto carry_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetCarryFromOp); - const auto overflow_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetOverflowFromOp); - const auto nzcv_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetNZCVFromOp); + const auto carry_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetCarryFromOp); + const auto overflow_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetOverflowFromOp); + const auto nzcv_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetNZCVFromOp); auto args = ctx.reg_alloc.GetArgumentInfo(inst); auto& carry_in = args[2]; @@ -1006,9 +1006,9 @@ void EmitX64::EmitAdd64(EmitContext& ctx, IR::Inst* inst) { } static void EmitSub(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, int bitsize) { - const auto carry_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetCarryFromOp); - const auto overflow_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetOverflowFromOp); - const auto nzcv_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetNZCVFromOp); + const auto carry_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetCarryFromOp); + const auto overflow_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetOverflowFromOp); + const auto nzcv_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetNZCVFromOp); auto args = ctx.reg_alloc.GetArgumentInfo(inst); auto& carry_in = args[2]; diff --git a/src/dynarmic/src/dynarmic/backend/x64/emit_x64_packed.cpp b/src/dynarmic/src/dynarmic/backend/x64/emit_x64_packed.cpp index c29d7d2648..e737e16d69 100644 --- a/src/dynarmic/src/dynarmic/backend/x64/emit_x64_packed.cpp +++ b/src/dynarmic/src/dynarmic/backend/x64/emit_x64_packed.cpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later /* This file is part of the dynarmic project. @@ -17,7 +17,7 @@ using namespace Xbyak::util; void EmitX64::EmitPackedAddU8(EmitContext& ctx, IR::Inst* inst) { auto args = ctx.reg_alloc.GetArgumentInfo(inst); - const auto ge_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetGEFromOp); + const auto ge_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetGEFromOp); const Xbyak::Xmm xmm_a = ctx.reg_alloc.UseScratchXmm(code, args[0]); const Xbyak::Xmm xmm_b = ctx.reg_alloc.UseXmm(code, args[1]); @@ -43,7 +43,7 @@ void EmitX64::EmitPackedAddU8(EmitContext& ctx, IR::Inst* inst) { void EmitX64::EmitPackedAddS8(EmitContext& ctx, IR::Inst* inst) { auto args = ctx.reg_alloc.GetArgumentInfo(inst); - const auto ge_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetGEFromOp); + const auto ge_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetGEFromOp); const Xbyak::Xmm xmm_a = ctx.reg_alloc.UseScratchXmm(code, args[0]); const Xbyak::Xmm xmm_b = ctx.reg_alloc.UseXmm(code, args[1]); @@ -67,7 +67,7 @@ void EmitX64::EmitPackedAddS8(EmitContext& ctx, IR::Inst* inst) { void EmitX64::EmitPackedAddU16(EmitContext& ctx, IR::Inst* inst) { auto args = ctx.reg_alloc.GetArgumentInfo(inst); - const auto ge_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetGEFromOp); + const auto ge_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetGEFromOp); const Xbyak::Xmm xmm_a = ctx.reg_alloc.UseScratchXmm(code, args[0]); const Xbyak::Xmm xmm_b = ctx.reg_alloc.UseXmm(code, args[1]); @@ -107,7 +107,7 @@ void EmitX64::EmitPackedAddU16(EmitContext& ctx, IR::Inst* inst) { void EmitX64::EmitPackedAddS16(EmitContext& ctx, IR::Inst* inst) { auto args = ctx.reg_alloc.GetArgumentInfo(inst); - const auto ge_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetGEFromOp); + const auto ge_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetGEFromOp); const Xbyak::Xmm xmm_a = ctx.reg_alloc.UseScratchXmm(code, args[0]); const Xbyak::Xmm xmm_b = ctx.reg_alloc.UseXmm(code, args[1]); @@ -131,7 +131,7 @@ void EmitX64::EmitPackedAddS16(EmitContext& ctx, IR::Inst* inst) { void EmitX64::EmitPackedSubU8(EmitContext& ctx, IR::Inst* inst) { auto args = ctx.reg_alloc.GetArgumentInfo(inst); - const auto ge_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetGEFromOp); + const auto ge_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetGEFromOp); const Xbyak::Xmm xmm_a = ctx.reg_alloc.UseScratchXmm(code, args[0]); const Xbyak::Xmm xmm_b = ctx.reg_alloc.UseXmm(code, args[1]); @@ -153,7 +153,7 @@ void EmitX64::EmitPackedSubU8(EmitContext& ctx, IR::Inst* inst) { void EmitX64::EmitPackedSubS8(EmitContext& ctx, IR::Inst* inst) { auto args = ctx.reg_alloc.GetArgumentInfo(inst); - const auto ge_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetGEFromOp); + const auto ge_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetGEFromOp); const Xbyak::Xmm xmm_a = ctx.reg_alloc.UseScratchXmm(code, args[0]); const Xbyak::Xmm xmm_b = ctx.reg_alloc.UseXmm(code, args[1]); @@ -177,7 +177,7 @@ void EmitX64::EmitPackedSubS8(EmitContext& ctx, IR::Inst* inst) { void EmitX64::EmitPackedSubU16(EmitContext& ctx, IR::Inst* inst) { auto args = ctx.reg_alloc.GetArgumentInfo(inst); - const auto ge_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetGEFromOp); + const auto ge_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetGEFromOp); if (!ge_inst) { const Xbyak::Xmm xmm_a = ctx.reg_alloc.UseScratchXmm(code, args[0]); @@ -226,7 +226,7 @@ void EmitX64::EmitPackedSubU16(EmitContext& ctx, IR::Inst* inst) { void EmitX64::EmitPackedSubS16(EmitContext& ctx, IR::Inst* inst) { auto args = ctx.reg_alloc.GetArgumentInfo(inst); - const auto ge_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetGEFromOp); + const auto ge_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetGEFromOp); const Xbyak::Xmm xmm_a = ctx.reg_alloc.UseScratchXmm(code, args[0]); const Xbyak::Xmm xmm_b = ctx.reg_alloc.UseXmm(code, args[1]); @@ -493,7 +493,7 @@ void EmitX64::EmitPackedHalvingSubS16(EmitContext& ctx, IR::Inst* inst) { static void EmitPackedSubAdd(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, bool hi_is_sum, bool is_signed, bool is_halving) { auto args = ctx.reg_alloc.GetArgumentInfo(inst); - const auto ge_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetGEFromOp); + const auto ge_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetGEFromOp); const Xbyak::Reg32 reg_a_hi = ctx.reg_alloc.UseScratchGpr(code, args[0]).cvt32(); const Xbyak::Reg32 reg_b_hi = ctx.reg_alloc.UseScratchGpr(code, args[1]).cvt32(); diff --git a/src/dynarmic/src/dynarmic/backend/x64/emit_x64_saturation.cpp b/src/dynarmic/src/dynarmic/backend/x64/emit_x64_saturation.cpp index 85ee3584eb..244595625c 100644 --- a/src/dynarmic/src/dynarmic/backend/x64/emit_x64_saturation.cpp +++ b/src/dynarmic/src/dynarmic/backend/x64/emit_x64_saturation.cpp @@ -65,7 +65,7 @@ void EmitSignedSaturatedOp(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) code.seto(overflow.cvt8()); if constexpr (has_overflow_inst) { - if (const auto overflow_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetOverflowFromOp)) { + if (const auto overflow_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetOverflowFromOp)) { ctx.reg_alloc.DefineValue(code, overflow_inst, overflow); } } else { @@ -114,7 +114,7 @@ void EmitX64::EmitSignedSaturatedSubWithFlag32(EmitContext& ctx, IR::Inst* inst) } void EmitX64::EmitSignedSaturation(EmitContext& ctx, IR::Inst* inst) { - const auto overflow_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetOverflowFromOp); + const auto overflow_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetOverflowFromOp); auto args = ctx.reg_alloc.GetArgumentInfo(inst); const size_t N = args[1].GetImmediateU8(); @@ -163,7 +163,7 @@ void EmitX64::EmitSignedSaturation(EmitContext& ctx, IR::Inst* inst) { } void EmitX64::EmitUnsignedSaturation(EmitContext& ctx, IR::Inst* inst) { - const auto overflow_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetOverflowFromOp); + const auto overflow_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetOverflowFromOp); auto args = ctx.reg_alloc.GetArgumentInfo(inst); const size_t N = args[1].GetImmediateU8(); diff --git a/src/dynarmic/src/dynarmic/backend/x64/emit_x64_vector.cpp b/src/dynarmic/src/dynarmic/backend/x64/emit_x64_vector.cpp index 1f96939d88..229be30090 100644 --- a/src/dynarmic/src/dynarmic/backend/x64/emit_x64_vector.cpp +++ b/src/dynarmic/src/dynarmic/backend/x64/emit_x64_vector.cpp @@ -3910,8 +3910,8 @@ void EmitX64::EmitVectorSignedAbsoluteDifference32(EmitContext& ctx, IR::Inst* i } void EmitX64::EmitVectorSignedMultiply16(EmitContext& ctx, IR::Inst* inst) { - const auto upper_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetUpperFromOp); - const auto lower_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetLowerFromOp); + const auto upper_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetUpperFromOp); + const auto lower_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetLowerFromOp); auto args = ctx.reg_alloc.GetArgumentInfo(inst); const Xbyak::Xmm x = ctx.reg_alloc.UseXmm(code, args[0]); @@ -3942,8 +3942,8 @@ void EmitX64::EmitVectorSignedMultiply16(EmitContext& ctx, IR::Inst* inst) { } void EmitX64::EmitVectorSignedMultiply32(EmitContext& ctx, IR::Inst* inst) { - const auto upper_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetUpperFromOp); - const auto lower_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetLowerFromOp); + const auto upper_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetUpperFromOp); + const auto lower_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetLowerFromOp); auto args = ctx.reg_alloc.GetArgumentInfo(inst); @@ -5508,8 +5508,8 @@ void EmitX64::EmitVectorUnsignedAbsoluteDifference32(EmitContext& ctx, IR::Inst* } void EmitX64::EmitVectorUnsignedMultiply16(EmitContext& ctx, IR::Inst* inst) { - const auto upper_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetUpperFromOp); - const auto lower_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetLowerFromOp); + const auto upper_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetUpperFromOp); + const auto lower_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetLowerFromOp); auto args = ctx.reg_alloc.GetArgumentInfo(inst); const Xbyak::Xmm x = ctx.reg_alloc.UseXmm(code, args[0]); @@ -5540,8 +5540,8 @@ void EmitX64::EmitVectorUnsignedMultiply16(EmitContext& ctx, IR::Inst* inst) { } void EmitX64::EmitVectorUnsignedMultiply32(EmitContext& ctx, IR::Inst* inst) { - const auto upper_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetUpperFromOp); - const auto lower_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetLowerFromOp); + const auto upper_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetUpperFromOp); + const auto lower_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetLowerFromOp); auto args = ctx.reg_alloc.GetArgumentInfo(inst); diff --git a/src/dynarmic/src/dynarmic/ir/basic_block.h b/src/dynarmic/src/dynarmic/ir/basic_block.h index 1bb27a03e4..ec7ac4b836 100644 --- a/src/dynarmic/src/dynarmic/ir/basic_block.h +++ b/src/dynarmic/src/dynarmic/ir/basic_block.h @@ -35,7 +35,7 @@ enum class Opcode; /// order memory accesses. class Block final { public: - using instruction_list_type = std::list; + using instruction_list_type = boost::container::stable_vector; using iterator = instruction_list_type::iterator; using const_iterator = instruction_list_type::const_iterator; using reverse_iterator = instruction_list_type::reverse_iterator; diff --git a/src/dynarmic/src/dynarmic/ir/microinstruction.cpp b/src/dynarmic/src/dynarmic/ir/microinstruction.cpp index cc555474ef..c34d7f6a1c 100644 --- a/src/dynarmic/src/dynarmic/ir/microinstruction.cpp +++ b/src/dynarmic/src/dynarmic/ir/microinstruction.cpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later /* This file is part of the dynarmic project. @@ -23,7 +23,7 @@ bool Inst::AreAllArgsImmediates() const { }); } -Inst* Inst::GetAssociatedPseudoOperation(Opcode opcode) { +Inst* Inst::GetAssociatedPseudoOperation(Block& block, Opcode opcode) { Inst* pseudoop = next_pseudoop; while (pseudoop) { if (pseudoop->GetOpcode() == opcode) { diff --git a/src/dynarmic/src/dynarmic/ir/microinstruction.h b/src/dynarmic/src/dynarmic/ir/microinstruction.h index c3e3cb4382..d73dcc3546 100644 --- a/src/dynarmic/src/dynarmic/ir/microinstruction.h +++ b/src/dynarmic/src/dynarmic/ir/microinstruction.h @@ -18,6 +18,7 @@ namespace Dynarmic::IR { enum class Opcode; enum class Type : u16; +class Block; constexpr size_t max_arg_count = 4; @@ -38,7 +39,7 @@ public: return next_pseudoop && !IsAPseudoOperation(op); } /// Gets a pseudo-operation associated with this instruction. - Inst* GetAssociatedPseudoOperation(Opcode opcode); + Inst* GetAssociatedPseudoOperation(Block& block, Opcode opcode); /// Get the microop this microinstruction represents. Opcode GetOpcode() const { return op; } @@ -76,12 +77,12 @@ public: // TODO: so much padding wasted with mcl::intrusive_node // 16 + 1, 24 - Opcode op; //2 (6) + std::array args; //16 * 4 = 64 (1 cache line) // Linked list of pseudooperations associated with this instruction. Inst* next_pseudoop = nullptr; //8 (14) unsigned use_count = 0; //4 (0) unsigned name = 0; //4 (4) - alignas(64) std::array args; //16 * 4 = 64 (1 cache line) + Opcode op; //2 (6) }; //static_assert(sizeof(Inst) == 128); diff --git a/src/dynarmic/src/dynarmic/ir/opt_passes.cpp b/src/dynarmic/src/dynarmic/ir/opt_passes.cpp index a0da0d0c81..8bdaec96d1 100644 --- a/src/dynarmic/src/dynarmic/ir/opt_passes.cpp +++ b/src/dynarmic/src/dynarmic/ir/opt_passes.cpp @@ -868,8 +868,8 @@ static void FoldMostSignificantBit(IR::Inst& inst) { inst.ReplaceUsesWith(IR::Value{(operand.GetImmediateAsU64() >> 31) != 0}); } -static void FoldMostSignificantWord(IR::Inst& inst) { - IR::Inst* carry_inst = inst.GetAssociatedPseudoOperation(Op::GetCarryFromOp); +static void FoldMostSignificantWord(IR::Block& block, IR::Inst& inst) { + IR::Inst* carry_inst = inst.GetAssociatedPseudoOperation(block, Op::GetCarryFromOp); if (!inst.AreAllArgsImmediates()) { return; @@ -928,8 +928,8 @@ static void FoldOR(IR::Inst& inst, bool is_32_bit) { } } -static bool FoldShifts(IR::Inst& inst) { - IR::Inst* carry_inst = inst.GetAssociatedPseudoOperation(Op::GetCarryFromOp); +static bool FoldShifts(IR::Block& block, IR::Inst& inst) { + IR::Inst* carry_inst = inst.GetAssociatedPseudoOperation(block, Op::GetCarryFromOp); // The 32-bit variants can contain 3 arguments, while the // 64-bit variants only contain 2. @@ -1013,14 +1013,14 @@ static void ConstantPropagation(IR::Block& block) { // skip NZCV so we dont end up discarding side effects :) // TODO(lizzie): hey stupid maybe fix the A64 codegen for folded constants AND // redirect the mfer properly?!??! just saying :) - if (IR::MayGetNZCVFromOp(opcode) && inst.GetAssociatedPseudoOperation(IR::Opcode::GetNZCVFromOp)) + if (IR::MayGetNZCVFromOp(opcode) && inst.GetAssociatedPseudoOperation(block, IR::Opcode::GetNZCVFromOp)) continue; switch (opcode) { case Op::LeastSignificantWord: FoldLeastSignificantWord(inst); break; case Op::MostSignificantWord: - FoldMostSignificantWord(inst); + FoldMostSignificantWord(block, inst); break; case Op::LeastSignificantHalf: FoldLeastSignificantHalf(inst); @@ -1042,42 +1042,42 @@ static void ConstantPropagation(IR::Block& block) { } break; case Op::LogicalShiftLeft32: - if (FoldShifts(inst)) { + if (FoldShifts(block, inst)) { ReplaceUsesWith(inst, true, Safe::LogicalShiftLeft(inst.GetArg(0).GetU32(), inst.GetArg(1).GetU8())); } break; case Op::LogicalShiftLeft64: - if (FoldShifts(inst)) { + if (FoldShifts(block, inst)) { ReplaceUsesWith(inst, false, Safe::LogicalShiftLeft(inst.GetArg(0).GetU64(), inst.GetArg(1).GetU8())); } break; case Op::LogicalShiftRight32: - if (FoldShifts(inst)) { + if (FoldShifts(block, inst)) { ReplaceUsesWith(inst, true, Safe::LogicalShiftRight(inst.GetArg(0).GetU32(), inst.GetArg(1).GetU8())); } break; case Op::LogicalShiftRight64: - if (FoldShifts(inst)) { + if (FoldShifts(block, inst)) { ReplaceUsesWith(inst, false, Safe::LogicalShiftRight(inst.GetArg(0).GetU64(), inst.GetArg(1).GetU8())); } break; case Op::ArithmeticShiftRight32: - if (FoldShifts(inst)) { + if (FoldShifts(block, inst)) { ReplaceUsesWith(inst, true, Safe::ArithmeticShiftRight(inst.GetArg(0).GetU32(), inst.GetArg(1).GetU8())); } break; case Op::ArithmeticShiftRight64: - if (FoldShifts(inst)) { + if (FoldShifts(block, inst)) { ReplaceUsesWith(inst, false, Safe::ArithmeticShiftRight(inst.GetArg(0).GetU64(), inst.GetArg(1).GetU8())); } break; case Op::RotateRight32: - if (FoldShifts(inst)) { + if (FoldShifts(block, inst)) { ReplaceUsesWith(inst, true, mcl::bit::rotate_right(inst.GetArg(0).GetU32(), inst.GetArg(1).GetU8())); } break; case Op::RotateRight64: - if (FoldShifts(inst)) { + if (FoldShifts(block, inst)) { ReplaceUsesWith(inst, false, mcl::bit::rotate_right(inst.GetArg(0).GetU64(), inst.GetArg(1).GetU8())); } break;