diff --git a/externals/dynarmic/src/dynarmic/CMakeLists.txt b/externals/dynarmic/src/dynarmic/CMakeLists.txt index a43c9eae10..a91ee4cfda 100644 --- a/externals/dynarmic/src/dynarmic/CMakeLists.txt +++ b/externals/dynarmic/src/dynarmic/CMakeLists.txt @@ -53,8 +53,6 @@ add_library(dynarmic common/lut_from_list.h common/math_util.cpp common/math_util.h - common/memory_pool.cpp - common/memory_pool.h common/safe_ops.h common/spin_lock.h common/string_util.h @@ -153,6 +151,7 @@ if ("A64" IN_LIST DYNARMIC_FRONTENDS) ir/opt/a64_callback_config_pass.cpp ir/opt/a64_get_set_elimination_pass.cpp ir/opt/a64_merge_interpret_blocks.cpp + ir/opt/x64_peepholes.cpp ) endif() diff --git a/externals/dynarmic/src/dynarmic/backend/arm64/a64_address_space.cpp b/externals/dynarmic/src/dynarmic/backend/arm64/a64_address_space.cpp index d4fe9a9cb7..f9f674f30f 100644 --- a/externals/dynarmic/src/dynarmic/backend/arm64/a64_address_space.cpp +++ b/externals/dynarmic/src/dynarmic/backend/arm64/a64_address_space.cpp @@ -344,6 +344,8 @@ IR::Block A64AddressSpace::GenerateIR(IR::LocationDescriptor descriptor) const { } if (conf.HasOptimization(OptimizationFlag::MiscIROpt)) { Optimization::A64MergeInterpretBlocksPass(ir_block, conf.callbacks); + Optimization::X64Peepholes(ir_block); + Optimization::DeadCodeElimination(ir_block); } Optimization::VerificationPass(ir_block); diff --git a/externals/dynarmic/src/dynarmic/backend/x64/a64_interface.cpp b/externals/dynarmic/src/dynarmic/backend/x64/a64_interface.cpp index 7c0fa8d205..9069eefec9 100644 --- a/externals/dynarmic/src/dynarmic/backend/x64/a64_interface.cpp +++ b/externals/dynarmic/src/dynarmic/backend/x64/a64_interface.cpp @@ -285,6 +285,8 @@ private: } if (conf.HasOptimization(OptimizationFlag::MiscIROpt)) { Optimization::A64MergeInterpretBlocksPass(ir_block, conf.callbacks); + Optimization::X64Peepholes(ir_block); + Optimization::DeadCodeElimination(ir_block); } Optimization::VerificationPass(ir_block); return emitter.Emit(ir_block).entrypoint; diff --git a/externals/dynarmic/src/dynarmic/backend/x64/block_of_code.cpp b/externals/dynarmic/src/dynarmic/backend/x64/block_of_code.cpp index e5fb25573b..14d1f0e17b 100644 --- a/externals/dynarmic/src/dynarmic/backend/x64/block_of_code.cpp +++ b/externals/dynarmic/src/dynarmic/backend/x64/block_of_code.cpp @@ -364,10 +364,10 @@ void BlockOfCode::GenRunCode(std::function rcp) { return_from_run_code[0] = getCurr(); cmp(dword[r15 + jsi.offsetof_halt_reason], 0); - jne(return_to_caller); + jne(return_to_caller, T_NEAR); if (cb.enable_cycle_counting) { cmp(qword[rsp + ABI_SHADOW_SPACE + offsetof(StackLayout, cycles_remaining)], 0); - jng(return_to_caller); + jng(return_to_caller, T_NEAR); } cb.LookupBlock->EmitCall(*this); jmp(ABI_RETURN); @@ -376,10 +376,10 @@ void BlockOfCode::GenRunCode(std::function rcp) { return_from_run_code[MXCSR_ALREADY_EXITED] = getCurr(); cmp(dword[r15 + jsi.offsetof_halt_reason], 0); - jne(return_to_caller_mxcsr_already_exited); + jne(return_to_caller_mxcsr_already_exited, T_NEAR); if (cb.enable_cycle_counting) { cmp(qword[rsp + ABI_SHADOW_SPACE + offsetof(StackLayout, cycles_remaining)], 0); - jng(return_to_caller_mxcsr_already_exited); + jng(return_to_caller_mxcsr_already_exited, T_NEAR); } SwitchMxcsrOnEntry(); cb.LookupBlock->EmitCall(*this); @@ -403,8 +403,7 @@ void BlockOfCode::GenRunCode(std::function rcp) { } xor_(eax, eax); - lock(); - xchg(dword[r15 + jsi.offsetof_halt_reason], eax); + /* implicit LOCK */ xchg(dword[r15 + jsi.offsetof_halt_reason], eax); ABI_PopCalleeSaveRegistersAndAdjustStack(*this, sizeof(StackLayout)); ret(); diff --git a/externals/dynarmic/src/dynarmic/backend/x64/emit_x64.cpp b/externals/dynarmic/src/dynarmic/backend/x64/emit_x64.cpp index b9a705813f..ba3244eb65 100644 --- a/externals/dynarmic/src/dynarmic/backend/x64/emit_x64.cpp +++ b/externals/dynarmic/src/dynarmic/backend/x64/emit_x64.cpp @@ -35,11 +35,6 @@ EmitContext::EmitContext(RegAlloc& reg_alloc, IR::Block& block) EmitContext::~EmitContext() = default; -void EmitContext::EraseInstruction(IR::Inst* inst) { - block.Instructions().erase(inst); - inst->ClearArgs(); -} - EmitX64::EmitX64(BlockOfCode& code) : code(code) { exception_handler.Register(code); diff --git a/externals/dynarmic/src/dynarmic/backend/x64/emit_x64.h b/externals/dynarmic/src/dynarmic/backend/x64/emit_x64.h index fbe749b2ab..3c885192b5 100644 --- a/externals/dynarmic/src/dynarmic/backend/x64/emit_x64.h +++ b/externals/dynarmic/src/dynarmic/backend/x64/emit_x64.h @@ -54,10 +54,7 @@ struct EmitContext { EmitContext(RegAlloc& reg_alloc, IR::Block& block); virtual ~EmitContext(); - void EraseInstruction(IR::Inst* inst); - virtual FP::FPCR FPCR(bool fpcr_controlled = true) const = 0; - virtual bool HasOptimization(OptimizationFlag flag) const = 0; RegAlloc& reg_alloc; diff --git a/externals/dynarmic/src/dynarmic/backend/x64/emit_x64_crc32.cpp b/externals/dynarmic/src/dynarmic/backend/x64/emit_x64_crc32.cpp index 842a8612ee..736e15b195 100644 --- a/externals/dynarmic/src/dynarmic/backend/x64/emit_x64_crc32.cpp +++ b/externals/dynarmic/src/dynarmic/backend/x64/emit_x64_crc32.cpp @@ -40,7 +40,6 @@ static void EmitCRC32Castagnoli(BlockOfCode& code, EmitContext& ctx, IR::Inst* i static void EmitCRC32ISO(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, const int data_size) { auto args = ctx.reg_alloc.GetArgumentInfo(inst); - if (code.HasHostFeature(HostFeature::PCLMULQDQ) && data_size < 32) { const Xbyak::Reg32 crc = ctx.reg_alloc.UseScratchGpr(args[0]).cvt32(); const Xbyak::Reg64 value = ctx.reg_alloc.UseScratchGpr(args[1]); @@ -69,10 +68,7 @@ static void EmitCRC32ISO(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, co code.pextrd(crc, xmm_value, 2); ctx.reg_alloc.DefineValue(inst, crc); - return; - } - - if (code.HasHostFeature(HostFeature::PCLMULQDQ) && data_size == 32) { + } else if (code.HasHostFeature(HostFeature::PCLMULQDQ) && data_size == 32) { const Xbyak::Reg32 crc = ctx.reg_alloc.UseScratchGpr(args[0]).cvt32(); const Xbyak::Reg32 value = ctx.reg_alloc.UseGpr(args[1]).cvt32(); const Xbyak::Xmm xmm_value = ctx.reg_alloc.ScratchXmm(); @@ -90,10 +86,7 @@ static void EmitCRC32ISO(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, co code.pextrd(crc, xmm_value, 2); ctx.reg_alloc.DefineValue(inst, crc); - return; - } - - if (code.HasHostFeature(HostFeature::PCLMULQDQ) && data_size == 64) { + } else if (code.HasHostFeature(HostFeature::PCLMULQDQ) && data_size == 64) { const Xbyak::Reg32 crc = ctx.reg_alloc.UseScratchGpr(args[0]).cvt32(); const Xbyak::Reg64 value = ctx.reg_alloc.UseGpr(args[1]); const Xbyak::Xmm xmm_value = ctx.reg_alloc.ScratchXmm(); @@ -111,12 +104,11 @@ static void EmitCRC32ISO(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, co code.pextrd(crc, xmm_value, 2); ctx.reg_alloc.DefineValue(inst, crc); - return; + } else { + ctx.reg_alloc.HostCall(inst, args[0], args[1], {}); + code.mov(code.ABI_PARAM3, data_size / CHAR_BIT); + code.CallFunction(&CRC32::ComputeCRC32ISO); } - - ctx.reg_alloc.HostCall(inst, args[0], args[1], {}); - code.mov(code.ABI_PARAM3, data_size / CHAR_BIT); - code.CallFunction(&CRC32::ComputeCRC32ISO); } void EmitX64::EmitCRC32Castagnoli8(EmitContext& ctx, IR::Inst* inst) { diff --git a/externals/dynarmic/src/dynarmic/backend/x64/emit_x64_vector_floating_point.cpp b/externals/dynarmic/src/dynarmic/backend/x64/emit_x64_vector_floating_point.cpp index 88d0786b03..f67fd53467 100644 --- a/externals/dynarmic/src/dynarmic/backend/x64/emit_x64_vector_floating_point.cpp +++ b/externals/dynarmic/src/dynarmic/backend/x64/emit_x64_vector_floating_point.cpp @@ -236,23 +236,19 @@ void DenormalsAreZero(BlockOfCode& code, FP::FPCR fpcr, std::initializer_list(xword, denormal_to_zero)); - - for (const Xbyak::Xmm& xmm : to_daz) { + for (const Xbyak::Xmm& xmm : to_daz) FCODE(vfixupimmp)(xmm, xmm, tmp, u8(0)); - } - return; - } - - if (fpcr.RMode() != FP::RoundingMode::TowardsMinusInfinity) { - code.movaps(tmp, GetNegativeZeroVector(code)); } else { - code.xorps(tmp, tmp); - } - for (const Xbyak::Xmm& xmm : to_daz) { - FCODE(addp)(xmm, tmp); + if (fpcr.RMode() != FP::RoundingMode::TowardsMinusInfinity) { + code.movaps(tmp, GetNegativeZeroVector(code)); + } else { + code.xorps(tmp, tmp); + } + for (const Xbyak::Xmm& xmm : to_daz) + FCODE(addp)(xmm, tmp); } } } diff --git a/externals/dynarmic/src/dynarmic/backend/x64/reg_alloc.cpp b/externals/dynarmic/src/dynarmic/backend/x64/reg_alloc.cpp index a0ee8ae9ed..2a30c52e01 100644 --- a/externals/dynarmic/src/dynarmic/backend/x64/reg_alloc.cpp +++ b/externals/dynarmic/src/dynarmic/backend/x64/reg_alloc.cpp @@ -415,21 +415,48 @@ void RegAlloc::ReleaseStackSpace(const size_t stack_space) noexcept { } HostLoc RegAlloc::SelectARegister(const boost::container::static_vector& desired_locations) const noexcept { - boost::container::static_vector candidates = desired_locations; //Who let someone copy an ENTIRE VECTOR here? - - // Find all locations that have not been allocated.. - const auto allocated_locs = std::partition(candidates.begin(), candidates.end(), [this](auto loc) noexcept { - return !this->LocInfo(loc).IsLocked(); - }); - candidates.erase(allocated_locs, candidates.end()); - ASSERT_MSG(!candidates.empty(), "All candidate registers have already been allocated"); - // Selects the best location out of the available locations. + // NOTE: Using last is BAD because new REX prefix for each insn using the last regs // TODO: Actually do LRU or something. Currently we just try to pick something without a value if possible. - auto const it = std::find_if(candidates.begin(), candidates.end(), [this](auto const loc) noexcept { - return this->LocInfo(loc).IsEmpty(); - }); - return it != candidates.end() ? *it : candidates.front(); + auto min_lru_counter = size_t(-1); + auto it_candidate = desired_locations.cend(); //default fallback if everything fails + auto it_rex_candidate = desired_locations.cend(); + auto it_empty_candidate = desired_locations.cend(); + for (auto it = desired_locations.cbegin(); it != desired_locations.cend(); it++) { + auto const& loc_info = LocInfo(*it); + // Abstain from using upper registers unless absolutely nescesary + if (loc_info.IsLocked()) { + // skip, not suitable for allocation + } else { + // idempotency, only assign once + if (it_empty_candidate == desired_locations.cend() && loc_info.IsEmpty()) + it_empty_candidate = it; + if (loc_info.lru_counter < min_lru_counter) { + // Otherwise a "quasi"-LRU + min_lru_counter = loc_info.lru_counter; + if (*it >= HostLoc::R8 && *it <= HostLoc::R15) { + it_rex_candidate = it; + } else { + it_candidate = it; + } + if (min_lru_counter == 0) + break; //early exit + } + } + } + // Final resolution goes as follows: + // 1 => Try normal candidate (no REX prefix) + // 2 => Try an empty candidate + // 3 => Try using a REX prefixed one + // We avoid using REX-addressable registers because they add +1 REX prefix which + // do we really need? The trade-off may not be worth it. + auto const it_final = it_candidate != desired_locations.cend() + ? it_candidate : it_empty_candidate != desired_locations.cend() + ? it_empty_candidate : it_rex_candidate; + ASSERT_MSG(it_final != desired_locations.cend(), "All candidate registers have already been allocated"); + // Evil magic - increment LRU counter (will wrap at 256) + const_cast(this)->LocInfo(*it_final).lru_counter++; + return *it_final; } void RegAlloc::DefineValueImpl(IR::Inst* def_inst, HostLoc host_loc) noexcept { diff --git a/externals/dynarmic/src/dynarmic/backend/x64/reg_alloc.h b/externals/dynarmic/src/dynarmic/backend/x64/reg_alloc.h index 599aab12a8..64f7c1ec40 100644 --- a/externals/dynarmic/src/dynarmic/backend/x64/reg_alloc.h +++ b/externals/dynarmic/src/dynarmic/backend/x64/reg_alloc.h @@ -92,8 +92,8 @@ private: uint8_t max_bit_width = 0; //Valid values: 1,2,4,8,16,32,128 bool is_scratch : 1 = false; //1 bool is_set_last_use : 1 = false; //1 - - alignas(16) char padding; + alignas(16) uint8_t lru_counter = 0; //1 + friend class RegAlloc; }; static_assert(sizeof(HostLocInfo) == 64); diff --git a/externals/dynarmic/src/dynarmic/common/memory_pool.cpp b/externals/dynarmic/src/dynarmic/common/memory_pool.cpp deleted file mode 100644 index f41dd92af5..0000000000 --- a/externals/dynarmic/src/dynarmic/common/memory_pool.cpp +++ /dev/null @@ -1,13 +0,0 @@ -/* This file is part of the dynarmic project. - * Copyright (c) 2016 MerryMage - * SPDX-License-Identifier: 0BSD - */ - -#include "dynarmic/common/memory_pool.h" - -#include - -namespace Dynarmic::Common { - - -} // namespace Dynarmic::Common diff --git a/externals/dynarmic/src/dynarmic/common/memory_pool.h b/externals/dynarmic/src/dynarmic/common/memory_pool.h deleted file mode 100644 index c99316e107..0000000000 --- a/externals/dynarmic/src/dynarmic/common/memory_pool.h +++ /dev/null @@ -1,61 +0,0 @@ -/* This file is part of the dynarmic project. - * Copyright (c) 2016 MerryMage - * SPDX-License-Identifier: 0BSD - */ - -#pragma once - -#include -#include - -namespace Dynarmic::Common { - -/// @tparam object_size Byte-size of objects to construct -/// @tparam slab_size Number of objects to have per slab -template -class Pool { -public: - inline Pool() noexcept { - AllocateNewSlab(); - } - inline ~Pool() noexcept { - std::free(current_slab); - for (char* slab : slabs) { - std::free(slab); - } - } - - Pool(const Pool&) = delete; - Pool(Pool&&) = delete; - - Pool& operator=(const Pool&) = delete; - Pool& operator=(Pool&&) = delete; - - /// @brief Returns a pointer to an `object_size`-bytes block of memory. - [[nodiscard]] void* Alloc() noexcept { - if (remaining == 0) { - slabs.push_back(current_slab); - AllocateNewSlab(); - } - void* ret = static_cast(current_ptr); - current_ptr += object_size; - remaining--; - return ret; - } -private: - /// @brief Allocates a completely new memory slab. - /// Used when an entirely new slab is needed - /// due the current one running out of usable space. - void AllocateNewSlab() noexcept { - current_slab = static_cast(std::malloc(object_size * slab_size)); - current_ptr = current_slab; - remaining = slab_size; - } - - std::vector slabs; - char* current_slab = nullptr; - char* current_ptr = nullptr; - size_t remaining = 0; -}; - -} // namespace Dynarmic::Common diff --git a/externals/dynarmic/src/dynarmic/frontend/A64/translate/impl/load_store_single_structure.cpp b/externals/dynarmic/src/dynarmic/frontend/A64/translate/impl/load_store_single_structure.cpp index b4bc842942..9615abb153 100644 --- a/externals/dynarmic/src/dynarmic/frontend/A64/translate/impl/load_store_single_structure.cpp +++ b/externals/dynarmic/src/dynarmic/frontend/A64/translate/impl/load_store_single_structure.cpp @@ -58,46 +58,51 @@ static bool SharedDecodeAndOperation(TranslatorVisitor& v, bool wback, IR::MemOp address = v.X(64, Rn); } - IR::U64 offs = v.ir.Imm64(0); if (replicate) { - for (size_t s = 0; s < selem; s++) { + // CPU likes when we read first and then we do operations; Sure, OOO, but might as well + IR::UAnyU128 p_elements[4] = {}; //max upper bound=4 elements + for (size_t s = 0; s < selem; ++s) { + p_elements[s] = v.Mem(v.ir.Add(address, v.ir.Imm64(ebytes * s)), ebytes, IR::AccType::VEC); + } + // schedule ops after + for (size_t s = 0; s < selem; ++s) { const Vec tt = static_cast((VecNumber(Vt) + s) % 32); - const IR::UAnyU128 element = v.Mem(v.ir.Add(address, offs), ebytes, IR::AccType::VEC); - const IR::U128 broadcasted_element = v.ir.VectorBroadcast(esize, element); - + const IR::U128 broadcasted_element = v.ir.VectorBroadcast(esize, p_elements[s]); v.V(datasize, tt, broadcasted_element); - - offs = v.ir.Add(offs, v.ir.Imm64(ebytes)); } } else { - for (size_t s = 0; s < selem; s++) { - const Vec tt = static_cast((VecNumber(Vt) + s) % 32); - const IR::U128 rval = v.V(128, tt); - - if (memop == IR::MemOp::LOAD) { - const IR::UAny elem = v.Mem(v.ir.Add(address, offs), ebytes, IR::AccType::VEC); - const IR::U128 vec = v.ir.VectorSetElement(esize, rval, index, elem); - v.V(128, tt, vec); - } else { - const IR::UAny elem = v.ir.VectorGetElement(esize, rval, index); - v.Mem(v.ir.Add(address, offs), ebytes, IR::AccType::VEC, elem); + if (memop == IR::MemOp::LOAD) { + IR::UAny p_elements[4] = {}; //max upper bound=4 elements + for (size_t s = 0; s < selem; ++s) { + p_elements[s] = v.Mem(v.ir.Add(address, v.ir.Imm64(ebytes * s)), ebytes, IR::AccType::VEC); + } + for (size_t s = 0; s < selem; ++s) { + const Vec tt = static_cast((VecNumber(Vt) + s) % 32); + const IR::U128 rval = v.V(128, tt); + const IR::U128 vec = v.ir.VectorSetElement(esize, rval, index, p_elements[s]); + v.V(128, tt, vec); + } + } else { + for (size_t s = 0; s < selem; ++s) { + const Vec tt = static_cast((VecNumber(Vt) + s) % 32); + const IR::U128 rval = v.V(128, tt); + const IR::UAny elem = v.ir.VectorGetElement(esize, rval, index); + v.Mem(v.ir.Add(address, v.ir.Imm64(ebytes * s)), ebytes, IR::AccType::VEC, elem); } - offs = v.ir.Add(offs, v.ir.Imm64(ebytes)); } } + IR::U64 offs = v.ir.Imm64(ebytes * selem); if (wback) { if (*Rm != Reg::SP) { offs = v.X(64, *Rm); } - if (Rn == Reg::SP) { v.SP(64, v.ir.Add(address, offs)); } else { v.X(64, Rn, v.ir.Add(address, offs)); } } - return true; } diff --git a/externals/dynarmic/src/dynarmic/frontend/A64/translate/impl/simd_three_different.cpp b/externals/dynarmic/src/dynarmic/frontend/A64/translate/impl/simd_three_different.cpp index 8f460665da..32f4550979 100644 --- a/externals/dynarmic/src/dynarmic/frontend/A64/translate/impl/simd_three_different.cpp +++ b/externals/dynarmic/src/dynarmic/frontend/A64/translate/impl/simd_three_different.cpp @@ -25,16 +25,18 @@ bool AbsoluteDifferenceLong(TranslatorVisitor& v, bool Q, Imm<2> size, Vec Vm, V const size_t esize = 8 << size.ZeroExtend(); const size_t datasize = 64; - const IR::U128 operand1 = v.ir.VectorZeroExtend(esize, v.Vpart(datasize, Vn, Q)); - const IR::U128 operand2 = v.ir.VectorZeroExtend(esize, v.Vpart(datasize, Vm, Q)); - IR::U128 result = sign == SignednessSTD::Signed ? v.ir.VectorSignedAbsoluteDifference(esize, operand1, operand2) - : v.ir.VectorUnsignedAbsoluteDifference(esize, operand1, operand2); - + // Loads first, then operations + auto const s_operand1 = v.Vpart(datasize, Vn, Q); + auto const s_operand2 = v.Vpart(datasize, Vm, Q); + const IR::U128 operand1 = v.ir.VectorZeroExtend(esize, s_operand1); + const IR::U128 operand2 = v.ir.VectorZeroExtend(esize, s_operand2); + IR::U128 result = sign == SignednessSTD::Signed + ? v.ir.VectorSignedAbsoluteDifference(esize, operand1, operand2) + : v.ir.VectorUnsignedAbsoluteDifference(esize, operand1, operand2); if (behavior == AbsoluteDifferenceBehavior::Accumulate) { const IR::U128 data = v.V(2 * datasize, Vd); result = v.ir.VectorAdd(2 * esize, result, data); } - v.V(2 * datasize, Vd, result); return true; } diff --git a/externals/dynarmic/src/dynarmic/frontend/A64/translate/impl/simd_three_same.cpp b/externals/dynarmic/src/dynarmic/frontend/A64/translate/impl/simd_three_same.cpp index 1cfc2ced78..a4ab1774c1 100644 --- a/externals/dynarmic/src/dynarmic/frontend/A64/translate/impl/simd_three_same.cpp +++ b/externals/dynarmic/src/dynarmic/frontend/A64/translate/impl/simd_three_same.cpp @@ -134,10 +134,8 @@ bool FPCompareRegister(TranslatorVisitor& v, bool Q, bool sz, Vec Vm, Vec Vn, Ve if (sz && !Q) { return v.ReservedValue(); } - const size_t esize = sz ? 64 : 32; const size_t datasize = Q ? 128 : 64; - const IR::U128 operand1 = v.V(datasize, Vn); const IR::U128 operand2 = v.V(datasize, Vm); const IR::U128 result = [&] { @@ -146,21 +144,22 @@ bool FPCompareRegister(TranslatorVisitor& v, bool Q, bool sz, Vec Vm, Vec Vn, Ve return v.ir.FPVectorEqual(esize, operand1, operand2); case ComparisonTypeSTS::GE: return v.ir.FPVectorGreaterEqual(esize, operand1, operand2); - case ComparisonTypeSTS::AbsoluteGE: - return v.ir.FPVectorGreaterEqual(esize, - v.ir.FPVectorAbs(esize, operand1), - v.ir.FPVectorAbs(esize, operand2)); + case ComparisonTypeSTS::AbsoluteGE: { + auto const tmp1 = v.ir.FPVectorAbs(esize, operand1); + auto const tmp2 = v.ir.FPVectorAbs(esize, operand2); + return v.ir.FPVectorGreaterEqual(esize, tmp1, tmp2); + } case ComparisonTypeSTS::GT: return v.ir.FPVectorGreater(esize, operand1, operand2); - case ComparisonTypeSTS::AbsoluteGT: - return v.ir.FPVectorGreater(esize, - v.ir.FPVectorAbs(esize, operand1), - v.ir.FPVectorAbs(esize, operand2)); + case ComparisonTypeSTS::AbsoluteGT: { + auto const tmp1 = v.ir.FPVectorAbs(esize, operand1); + auto const tmp2 = v.ir.FPVectorAbs(esize, operand2); + return v.ir.FPVectorGreater(esize, tmp1, tmp2); + } } UNREACHABLE(); }(); - v.V(datasize, Vd, result); return true; } diff --git a/externals/dynarmic/src/dynarmic/ir/basic_block.cpp b/externals/dynarmic/src/dynarmic/ir/basic_block.cpp index c818fe0b17..8b5b5972a4 100644 --- a/externals/dynarmic/src/dynarmic/ir/basic_block.cpp +++ b/externals/dynarmic/src/dynarmic/ir/basic_block.cpp @@ -13,7 +13,6 @@ #include #include -#include "dynarmic/common/memory_pool.h" #include "dynarmic/frontend/A32/a32_types.h" #include "dynarmic/frontend/A64/a64_types.h" #include "dynarmic/ir/cond.h" @@ -24,8 +23,7 @@ namespace Dynarmic::IR { Block::Block(const LocationDescriptor& location) : location{location}, end_location{location}, - cond{Cond::AL}, - instruction_alloc_pool{std::make_unique>()} + cond{Cond::AL} { } @@ -37,7 +35,7 @@ Block::Block(const LocationDescriptor& location) /// @param args A sequence of Value instances used as arguments for the instruction. /// @returns Iterator to the newly created instruction. Block::iterator Block::PrependNewInst(iterator insertion_point, Opcode opcode, std::initializer_list args) noexcept { - IR::Inst* inst = new (instruction_alloc_pool->Alloc()) IR::Inst(opcode); + IR::Inst* inst = new IR::Inst(opcode); DEBUG_ASSERT(args.size() == inst->NumArgs()); std::for_each(args.begin(), args.end(), [&inst, index = size_t(0)](const auto& arg) mutable { inst->SetArg(index, arg); @@ -83,9 +81,7 @@ static std::string TerminalToString(const Terminal& terminal_variant) noexcept { } std::string DumpBlock(const IR::Block& block) noexcept { - std::string ret; - - ret += fmt::format("Block: location={}\n", block.Location()); + std::string ret = fmt::format("Block: location={}\n", block.Location()); ret += fmt::format("cycles={}", block.CycleCount()); ret += fmt::format(", entry_cond={}", A64::CondToString(block.GetCondition())); if (block.GetCondition() != Cond::AL) { @@ -113,6 +109,8 @@ std::string DumpBlock(const IR::Block& block) noexcept { return fmt::format("#{:#x}", arg.GetU32()); case Type::U64: return fmt::format("#{:#x}", arg.GetU64()); + case Type::U128: + return fmt::format("#"); case Type::A32Reg: return A32::RegToString(arg.GetA32RegRef()); case Type::A32ExtReg: @@ -155,14 +153,9 @@ std::string DumpBlock(const IR::Block& block) noexcept { ret += fmt::format("", GetNameOf(actual_type), GetNameOf(expected_type)); } } - - ret += fmt::format(" (uses: {})", inst.UseCount()); - - ret += '\n'; + ret += fmt::format(" (uses: {})\n", inst.UseCount()); } - ret += "terminal = " + TerminalToString(block.GetTerminal()) + '\n'; - return ret; } diff --git a/externals/dynarmic/src/dynarmic/ir/basic_block.h b/externals/dynarmic/src/dynarmic/ir/basic_block.h index 6608f0e3a2..b1ccf672a0 100644 --- a/externals/dynarmic/src/dynarmic/ir/basic_block.h +++ b/externals/dynarmic/src/dynarmic/ir/basic_block.h @@ -17,8 +17,6 @@ #include "dynarmic/ir/microinstruction.h" #include "dynarmic/ir/terminal.h" #include "dynarmic/ir/value.h" -#include "dynarmic/ir/dense_list.h" -#include "dynarmic/common/memory_pool.h" namespace Dynarmic::IR { @@ -76,7 +74,7 @@ public: /// @param op Opcode representing the instruction to add. /// @param args A sequence of Value instances used as arguments for the instruction. inline void AppendNewInst(const Opcode opcode, const std::initializer_list args) noexcept { - PrependNewInst(end(), opcode, args); + PrependNewInst(instructions.end(), opcode, args); } iterator PrependNewInst(iterator insertion_point, Opcode op, std::initializer_list args) noexcept; @@ -171,8 +169,6 @@ private: LocationDescriptor end_location; /// Conditional to pass in order to execute this block Cond cond; - /// Memory pool for instruction list - std::unique_ptr> instruction_alloc_pool; /// Terminal instruction of this block. Terminal terminal = Term::Invalid{}; /// Number of cycles this block takes to execute if the conditional fails. diff --git a/externals/dynarmic/src/dynarmic/ir/dense_list.h b/externals/dynarmic/src/dynarmic/ir/dense_list.h deleted file mode 100644 index a399c12d0b..0000000000 --- a/externals/dynarmic/src/dynarmic/ir/dense_list.h +++ /dev/null @@ -1,58 +0,0 @@ -#pragma once - -#include -#include -#include - -namespace Dynarmic { - template struct dense_list { - using difference_type = std::ptrdiff_t; - using size_type = std::size_t; - using value_type = T; - using pointer = value_type*; - using const_pointer = const value_type*; - using reference = value_type&; - using const_reference = const value_type&; - using iterator = std::deque::iterator; - using const_iterator = std::deque::const_iterator; - using reverse_iterator = std::reverse_iterator; - using const_reverse_iterator = std::reverse_iterator; - - inline bool empty() const noexcept { return list.empty(); } - inline size_type size() const noexcept { return list.size(); } - - inline value_type& front() noexcept { return list.front(); } - inline const value_type& front() const noexcept { return list.front(); } - - inline value_type& back() noexcept { return list.back(); } - inline const value_type& back() const noexcept { return list.back(); } - - inline iterator begin() noexcept { return list.begin(); } - inline const_iterator begin() const noexcept { return list.begin(); } - inline iterator end() noexcept { return list.end(); } - inline const_iterator end() const noexcept { return list.end(); } - - inline reverse_iterator rbegin() noexcept { return list.rbegin(); } - inline const_reverse_iterator rbegin() const noexcept { return list.rbegin(); } - inline reverse_iterator rend() noexcept { return list.rend(); } - inline const_reverse_iterator rend() const noexcept { return list.rend(); } - - inline const_iterator cbegin() const noexcept { return list.cbegin(); } - inline const_iterator cend() const noexcept { return list.cend(); } - - inline const_reverse_iterator crbegin() const noexcept { return list.crbegin(); } - inline const_reverse_iterator crend() const noexcept { return list.crend(); } - - inline iterator insert_before(iterator it, value_type& value) noexcept { - if (it == list.begin()) { - list.push_front(value); - return list.begin(); - } - auto const index = std::distance(list.begin(), it - 1); - list.insert(it - 1, value); - return list.begin() + index; - } - - std::deque list; - }; -} diff --git a/externals/dynarmic/src/dynarmic/ir/ir_emitter.h b/externals/dynarmic/src/dynarmic/ir/ir_emitter.h index 23cfb47498..6f216089b9 100644 --- a/externals/dynarmic/src/dynarmic/ir/ir_emitter.h +++ b/externals/dynarmic/src/dynarmic/ir/ir_emitter.h @@ -2947,19 +2947,10 @@ public: block.SetTerminal(terminal); } - void SetInsertionPointBefore(IR::Inst* new_insertion_point) { - insertion_point = IR::Block::iterator{*new_insertion_point}; - } - void SetInsertionPointBefore(IR::Block::iterator new_insertion_point) { insertion_point = new_insertion_point; } - void SetInsertionPointAfter(IR::Inst* new_insertion_point) { - insertion_point = IR::Block::iterator{*new_insertion_point}; - ++insertion_point; - } - void SetInsertionPointAfter(IR::Block::iterator new_insertion_point) { insertion_point = new_insertion_point; ++insertion_point; diff --git a/externals/dynarmic/src/dynarmic/ir/opt/a32_get_set_elimination_pass.cpp b/externals/dynarmic/src/dynarmic/ir/opt/a32_get_set_elimination_pass.cpp index 06e159ba48..fe46a9341d 100644 --- a/externals/dynarmic/src/dynarmic/ir/opt/a32_get_set_elimination_pass.cpp +++ b/externals/dynarmic/src/dynarmic/ir/opt/a32_get_set_elimination_pass.cpp @@ -22,8 +22,7 @@ namespace Dynarmic::Optimization { namespace { void FlagsPass(IR::Block& block) { - using Iterator = std::reverse_iterator; - + using Iterator = IR::Block::reverse_iterator; struct FlagInfo { bool set_not_required = false; bool has_value_request = false; @@ -185,10 +184,10 @@ void RegisterPass(IR::Block& block) { using Iterator = IR::Block::iterator; struct RegInfo { - IR::Value register_value; std::optional last_set_instruction; + IR::Value register_value; }; - std::array reg_info; + alignas(64) std::array reg_info; const auto do_get = [](RegInfo& info, Iterator get_inst) { if (info.register_value.IsEmpty()) { @@ -203,12 +202,12 @@ void RegisterPass(IR::Block& block) { (*info.last_set_instruction)->Invalidate(); } info = { - .register_value = value, .last_set_instruction = set_inst, + .register_value = value, }; }; - enum class ExtValueType { + enum class ExtValueType : std::uint8_t { Empty, Single, Double, @@ -216,19 +215,20 @@ void RegisterPass(IR::Block& block) { VectorQuad, }; struct ExtRegInfo { - ExtValueType value_type = {}; IR::Value register_value; std::optional last_set_instruction; + ExtValueType value_type = {}; }; - std::array ext_reg_info; + // Max returned by RegNumber = 31 (but multiplied by 4 in some cases) + alignas(64) std::array ext_reg_info; const auto do_ext_get = [](ExtValueType type, std::initializer_list> infos, Iterator get_inst) { if (!std::all_of(infos.begin(), infos.end(), [type](const auto& info) { return info.get().value_type == type; })) { for (auto& info : infos) { info.get() = { - .value_type = type, .register_value = IR::Value(&*get_inst), .last_set_instruction = std::nullopt, + .value_type = type, }; } return; @@ -244,9 +244,9 @@ void RegisterPass(IR::Block& block) { } for (auto& info : infos) { info.get() = { - .value_type = type, .register_value = value, .last_set_instruction = set_inst, + .value_type = type, }; } }; diff --git a/externals/dynarmic/src/dynarmic/ir/opt/a64_callback_config_pass.cpp b/externals/dynarmic/src/dynarmic/ir/opt/a64_callback_config_pass.cpp index 79d9769520..36f2a9c495 100644 --- a/externals/dynarmic/src/dynarmic/ir/opt/a64_callback_config_pass.cpp +++ b/externals/dynarmic/src/dynarmic/ir/opt/a64_callback_config_pass.cpp @@ -17,7 +17,8 @@ void A64CallbackConfigPass(IR::Block& block, const A64::UserConfig& conf) { return; } - for (auto& inst : block) { + for (auto iter = block.begin(); iter != block.end(); iter++) { + auto& inst = *iter; if (inst.GetOpcode() != IR::Opcode::A64DataCacheOperationRaised) { continue; } @@ -26,7 +27,7 @@ void A64CallbackConfigPass(IR::Block& block, const A64::UserConfig& conf) { if (op == A64::DataCacheOperation::ZeroByVA) { A64::IREmitter ir{block}; ir.current_location = A64::LocationDescriptor{IR::LocationDescriptor{inst.GetArg(0).GetU64()}}; - ir.SetInsertionPointBefore(&inst); + ir.SetInsertionPointBefore(iter); size_t bytes = 4 << static_cast(conf.dczid_el0 & 0b1111); IR::U64 addr{inst.GetArg(2)}; diff --git a/externals/dynarmic/src/dynarmic/ir/opt/constant_propagation_pass.cpp b/externals/dynarmic/src/dynarmic/ir/opt/constant_propagation_pass.cpp index 83530fc453..ad40a3367c 100644 --- a/externals/dynarmic/src/dynarmic/ir/opt/constant_propagation_pass.cpp +++ b/externals/dynarmic/src/dynarmic/ir/opt/constant_propagation_pass.cpp @@ -22,9 +22,9 @@ using Op = Dynarmic::IR::Opcode; namespace { -// Tiny helper to avoid the need to store based off the opcode -// bit size all over the place within folding functions. -void ReplaceUsesWith(IR::Inst& inst, bool is_32_bit, u64 value) { +/// Tiny helper to avoid the need to store based off the opcode +/// bit size all over the place within folding functions. +static void ReplaceUsesWith(IR::Inst& inst, bool is_32_bit, u64 value) { if (is_32_bit) { inst.ReplaceUsesWith(IR::Value{static_cast(value)}); } else { @@ -32,12 +32,12 @@ void ReplaceUsesWith(IR::Inst& inst, bool is_32_bit, u64 value) { } } -IR::Value Value(bool is_32_bit, u64 value) { +static IR::Value Value(bool is_32_bit, u64 value) { return is_32_bit ? IR::Value{static_cast(value)} : IR::Value{value}; } template -bool FoldCommutative(IR::Inst& inst, bool is_32_bit, ImmFn imm_fn) { +static bool FoldCommutative(IR::Inst& inst, bool is_32_bit, ImmFn imm_fn) { const auto lhs = inst.GetArg(0); const auto rhs = inst.GetArg(1); @@ -75,7 +75,7 @@ bool FoldCommutative(IR::Inst& inst, bool is_32_bit, ImmFn imm_fn) { return true; } -void FoldAdd(IR::Inst& inst, bool is_32_bit) { +static void FoldAdd(IR::Inst& inst, bool is_32_bit) { const auto lhs = inst.GetArg(0); const auto rhs = inst.GetArg(1); const auto carry = inst.GetArg(2); @@ -125,7 +125,7 @@ void FoldAdd(IR::Inst& inst, bool is_32_bit) { /// 4. x & y -> y (where x has all bits set to 1) /// 5. x & y -> x (where y has all bits set to 1) /// -void FoldAND(IR::Inst& inst, bool is_32_bit) { +static void FoldAND(IR::Inst& inst, bool is_32_bit) { if (FoldCommutative(inst, is_32_bit, [](u64 a, u64 b) { return a & b; })) { const auto rhs = inst.GetArg(1); if (rhs.IsZero()) { @@ -140,7 +140,7 @@ void FoldAND(IR::Inst& inst, bool is_32_bit) { /// /// 1. imm -> swap(imm) /// -void FoldByteReverse(IR::Inst& inst, Op op) { +static void FoldByteReverse(IR::Inst& inst, Op op) { const auto operand = inst.GetArg(0); if (!operand.IsImmediate()) { @@ -165,7 +165,7 @@ void FoldByteReverse(IR::Inst& inst, Op op) { /// 2. imm_x / imm_y -> result /// 3. x / 1 -> x /// -void FoldDivide(IR::Inst& inst, bool is_32_bit, bool is_signed) { +static void FoldDivide(IR::Inst& inst, bool is_32_bit, bool is_signed) { const auto rhs = inst.GetArg(1); if (rhs.IsZero()) { @@ -193,7 +193,7 @@ void FoldDivide(IR::Inst& inst, bool is_32_bit, bool is_signed) { // 2. x ^ 0 -> x // 3. 0 ^ y -> y // -void FoldEOR(IR::Inst& inst, bool is_32_bit) { +static void FoldEOR(IR::Inst& inst, bool is_32_bit) { if (FoldCommutative(inst, is_32_bit, [](u64 a, u64 b) { return a ^ b; })) { const auto rhs = inst.GetArg(1); if (rhs.IsZero()) { @@ -202,7 +202,7 @@ void FoldEOR(IR::Inst& inst, bool is_32_bit) { } } -void FoldLeastSignificantByte(IR::Inst& inst) { +static void FoldLeastSignificantByte(IR::Inst& inst) { if (!inst.AreAllArgsImmediates()) { return; } @@ -211,7 +211,7 @@ void FoldLeastSignificantByte(IR::Inst& inst) { inst.ReplaceUsesWith(IR::Value{static_cast(operand.GetImmediateAsU64())}); } -void FoldLeastSignificantHalf(IR::Inst& inst) { +static void FoldLeastSignificantHalf(IR::Inst& inst) { if (!inst.AreAllArgsImmediates()) { return; } @@ -220,7 +220,7 @@ void FoldLeastSignificantHalf(IR::Inst& inst) { inst.ReplaceUsesWith(IR::Value{static_cast(operand.GetImmediateAsU64())}); } -void FoldLeastSignificantWord(IR::Inst& inst) { +static void FoldLeastSignificantWord(IR::Inst& inst) { if (!inst.AreAllArgsImmediates()) { return; } @@ -229,7 +229,7 @@ void FoldLeastSignificantWord(IR::Inst& inst) { inst.ReplaceUsesWith(IR::Value{static_cast(operand.GetImmediateAsU64())}); } -void FoldMostSignificantBit(IR::Inst& inst) { +static void FoldMostSignificantBit(IR::Inst& inst) { if (!inst.AreAllArgsImmediates()) { return; } @@ -238,7 +238,7 @@ void FoldMostSignificantBit(IR::Inst& inst) { inst.ReplaceUsesWith(IR::Value{(operand.GetImmediateAsU64() >> 31) != 0}); } -void FoldMostSignificantWord(IR::Inst& inst) { +static void FoldMostSignificantWord(IR::Inst& inst) { IR::Inst* carry_inst = inst.GetAssociatedPseudoOperation(Op::GetCarryFromOp); if (!inst.AreAllArgsImmediates()) { @@ -260,7 +260,7 @@ void FoldMostSignificantWord(IR::Inst& inst) { // 4. x * 1 -> x // 5. 1 * y -> y // -void FoldMultiply(IR::Inst& inst, bool is_32_bit) { +static void FoldMultiply(IR::Inst& inst, bool is_32_bit) { if (FoldCommutative(inst, is_32_bit, [](u64 a, u64 b) { return a * b; })) { const auto rhs = inst.GetArg(1); if (rhs.IsZero()) { @@ -272,7 +272,7 @@ void FoldMultiply(IR::Inst& inst, bool is_32_bit) { } // Folds NOT operations if the contained value is an immediate. -void FoldNOT(IR::Inst& inst, bool is_32_bit) { +static void FoldNOT(IR::Inst& inst, bool is_32_bit) { const auto operand = inst.GetArg(0); if (!operand.IsImmediate()) { @@ -289,7 +289,7 @@ void FoldNOT(IR::Inst& inst, bool is_32_bit) { // 2. x | 0 -> x // 3. 0 | y -> y // -void FoldOR(IR::Inst& inst, bool is_32_bit) { +static void FoldOR(IR::Inst& inst, bool is_32_bit) { if (FoldCommutative(inst, is_32_bit, [](u64 a, u64 b) { return a | b; })) { const auto rhs = inst.GetArg(1); if (rhs.IsZero()) { @@ -298,7 +298,7 @@ void FoldOR(IR::Inst& inst, bool is_32_bit) { } } -bool FoldShifts(IR::Inst& inst) { +static bool FoldShifts(IR::Inst& inst) { IR::Inst* carry_inst = inst.GetAssociatedPseudoOperation(Op::GetCarryFromOp); // The 32-bit variants can contain 3 arguments, while the @@ -328,7 +328,7 @@ bool FoldShifts(IR::Inst& inst) { return true; } -void FoldSignExtendXToWord(IR::Inst& inst) { +static void FoldSignExtendXToWord(IR::Inst& inst) { if (!inst.AreAllArgsImmediates()) { return; } @@ -337,7 +337,7 @@ void FoldSignExtendXToWord(IR::Inst& inst) { inst.ReplaceUsesWith(IR::Value{static_cast(value)}); } -void FoldSignExtendXToLong(IR::Inst& inst) { +static void FoldSignExtendXToLong(IR::Inst& inst) { if (!inst.AreAllArgsImmediates()) { return; } @@ -346,7 +346,7 @@ void FoldSignExtendXToLong(IR::Inst& inst) { inst.ReplaceUsesWith(IR::Value{static_cast(value)}); } -void FoldSub(IR::Inst& inst, bool is_32_bit) { +static void FoldSub(IR::Inst& inst, bool is_32_bit) { if (!inst.AreAllArgsImmediates() || inst.HasAssociatedPseudoOperation()) { return; } @@ -359,7 +359,7 @@ void FoldSub(IR::Inst& inst, bool is_32_bit) { ReplaceUsesWith(inst, is_32_bit, result); } -void FoldZeroExtendXToWord(IR::Inst& inst) { +static void FoldZeroExtendXToWord(IR::Inst& inst) { if (!inst.AreAllArgsImmediates()) { return; } @@ -368,7 +368,7 @@ void FoldZeroExtendXToWord(IR::Inst& inst) { inst.ReplaceUsesWith(IR::Value{static_cast(value)}); } -void FoldZeroExtendXToLong(IR::Inst& inst) { +static void FoldZeroExtendXToLong(IR::Inst& inst) { if (!inst.AreAllArgsImmediates()) { return; } diff --git a/externals/dynarmic/src/dynarmic/ir/opt/identity_removal_pass.cpp b/externals/dynarmic/src/dynarmic/ir/opt/identity_removal_pass.cpp index e87fcc335b..a3bab8e37a 100644 --- a/externals/dynarmic/src/dynarmic/ir/opt/identity_removal_pass.cpp +++ b/externals/dynarmic/src/dynarmic/ir/opt/identity_removal_pass.cpp @@ -13,11 +13,8 @@ namespace Dynarmic::Optimization { void IdentityRemovalPass(IR::Block& block) { std::vector to_invalidate; - - auto iter = block.begin(); - while (iter != block.end()) { + for (auto iter = block.begin(); iter != block.end(); ) { IR::Inst& inst = *iter; - const size_t num_args = inst.NumArgs(); for (size_t i = 0; i < num_args; i++) { while (true) { @@ -27,18 +24,15 @@ void IdentityRemovalPass(IR::Block& block) { inst.SetArg(i, arg.GetInst()->GetArg(0)); } } - if (inst.GetOpcode() == IR::Opcode::Identity || inst.GetOpcode() == IR::Opcode::Void) { - iter = block.Instructions().erase(inst); + iter = block.Instructions().erase(iter); to_invalidate.push_back(&inst); } else { ++iter; } } - - for (IR::Inst* inst : to_invalidate) { + for (auto* inst : to_invalidate) inst->Invalidate(); - } } } // namespace Dynarmic::Optimization diff --git a/externals/dynarmic/src/dynarmic/ir/opt/passes.h b/externals/dynarmic/src/dynarmic/ir/opt/passes.h index 703145b556..6e8d5bd5ee 100644 --- a/externals/dynarmic/src/dynarmic/ir/opt/passes.h +++ b/externals/dynarmic/src/dynarmic/ir/opt/passes.h @@ -43,5 +43,6 @@ void DeadCodeElimination(IR::Block& block); void IdentityRemovalPass(IR::Block& block); void VerificationPass(const IR::Block& block); void NamingPass(IR::Block& block); +void X64Peepholes(IR::Block& block); } // namespace Dynarmic::Optimization diff --git a/externals/dynarmic/src/dynarmic/ir/opt/polyfill_pass.cpp b/externals/dynarmic/src/dynarmic/ir/opt/polyfill_pass.cpp index 1aa3aea91e..1a28817036 100644 --- a/externals/dynarmic/src/dynarmic/ir/opt/polyfill_pass.cpp +++ b/externals/dynarmic/src/dynarmic/ir/opt/polyfill_pass.cpp @@ -13,7 +13,7 @@ namespace Dynarmic::Optimization { namespace { -void PolyfillSHA256MessageSchedule0(IR::IREmitter& ir, IR::Inst& inst) { +static void PolyfillSHA256MessageSchedule0(IR::IREmitter& ir, IR::Inst& inst) { const IR::U128 x = (IR::U128)inst.GetArg(0); const IR::U128 y = (IR::U128)inst.GetArg(1); @@ -37,13 +37,14 @@ void PolyfillSHA256MessageSchedule0(IR::IREmitter& ir, IR::Inst& inst) { inst.ReplaceUsesWith(result); } -void PolyfillSHA256MessageSchedule1(IR::IREmitter& ir, IR::Inst& inst) { +static void PolyfillSHA256MessageSchedule1(IR::IREmitter& ir, IR::Inst& inst) { const IR::U128 x = (IR::U128)inst.GetArg(0); const IR::U128 y = (IR::U128)inst.GetArg(1); const IR::U128 z = (IR::U128)inst.GetArg(2); const IR::U128 T0 = ir.VectorExtract(y, z, 32); + // TODO: this can use better pipelining m8 const IR::U128 lower_half = [&] { const IR::U128 T = ir.VectorRotateWholeVectorRight(z, 64); const IR::U128 tmp1 = ir.VectorRotateRight(32, T, 17); @@ -73,15 +74,15 @@ void PolyfillSHA256MessageSchedule1(IR::IREmitter& ir, IR::Inst& inst) { inst.ReplaceUsesWith(result); } -IR::U32 SHAchoose(IR::IREmitter& ir, IR::U32 x, IR::U32 y, IR::U32 z) { +static IR::U32 SHAchoose(IR::IREmitter& ir, IR::U32 x, IR::U32 y, IR::U32 z) { return ir.Eor(ir.And(ir.Eor(y, z), x), z); } -IR::U32 SHAmajority(IR::IREmitter& ir, IR::U32 x, IR::U32 y, IR::U32 z) { +static IR::U32 SHAmajority(IR::IREmitter& ir, IR::U32 x, IR::U32 y, IR::U32 z) { return ir.Or(ir.And(x, y), ir.And(ir.Or(x, y), z)); } -IR::U32 SHAhashSIGMA0(IR::IREmitter& ir, IR::U32 x) { +static IR::U32 SHAhashSIGMA0(IR::IREmitter& ir, IR::U32 x) { const IR::U32 tmp1 = ir.RotateRight(x, ir.Imm8(2)); const IR::U32 tmp2 = ir.RotateRight(x, ir.Imm8(13)); const IR::U32 tmp3 = ir.RotateRight(x, ir.Imm8(22)); @@ -89,7 +90,7 @@ IR::U32 SHAhashSIGMA0(IR::IREmitter& ir, IR::U32 x) { return ir.Eor(tmp1, ir.Eor(tmp2, tmp3)); } -IR::U32 SHAhashSIGMA1(IR::IREmitter& ir, IR::U32 x) { +static IR::U32 SHAhashSIGMA1(IR::IREmitter& ir, IR::U32 x) { const IR::U32 tmp1 = ir.RotateRight(x, ir.Imm8(6)); const IR::U32 tmp2 = ir.RotateRight(x, ir.Imm8(11)); const IR::U32 tmp3 = ir.RotateRight(x, ir.Imm8(25)); @@ -97,7 +98,7 @@ IR::U32 SHAhashSIGMA1(IR::IREmitter& ir, IR::U32 x) { return ir.Eor(tmp1, ir.Eor(tmp2, tmp3)); } -void PolyfillSHA256Hash(IR::IREmitter& ir, IR::Inst& inst) { +static void PolyfillSHA256Hash(IR::IREmitter& ir, IR::Inst& inst) { IR::U128 x = (IR::U128)inst.GetArg(0); IR::U128 y = (IR::U128)inst.GetArg(1); const IR::U128 w = (IR::U128)inst.GetArg(2); @@ -139,7 +140,7 @@ void PolyfillSHA256Hash(IR::IREmitter& ir, IR::Inst& inst) { } template -void PolyfillVectorMultiplyWiden(IR::IREmitter& ir, IR::Inst& inst) { +static void PolyfillVectorMultiplyWiden(IR::IREmitter& ir, IR::Inst& inst) { IR::U128 n = (IR::U128)inst.GetArg(0); IR::U128 m = (IR::U128)inst.GetArg(1); @@ -159,54 +160,52 @@ void PolyfillPass(IR::Block& block, const PolyfillOptions& polyfill) { } IR::IREmitter ir{block}; - - for (auto& inst : block) { - ir.SetInsertionPointBefore(&inst); - - switch (inst.GetOpcode()) { + for (auto iter = block.begin(); iter != block.end(); iter++) { + ir.SetInsertionPointBefore(iter); + switch (iter->GetOpcode()) { case IR::Opcode::SHA256MessageSchedule0: if (polyfill.sha256) { - PolyfillSHA256MessageSchedule0(ir, inst); + PolyfillSHA256MessageSchedule0(ir, *iter); } break; case IR::Opcode::SHA256MessageSchedule1: if (polyfill.sha256) { - PolyfillSHA256MessageSchedule1(ir, inst); + PolyfillSHA256MessageSchedule1(ir, *iter); } break; case IR::Opcode::SHA256Hash: if (polyfill.sha256) { - PolyfillSHA256Hash(ir, inst); + PolyfillSHA256Hash(ir, *iter); } break; case IR::Opcode::VectorMultiplySignedWiden8: if (polyfill.vector_multiply_widen) { - PolyfillVectorMultiplyWiden<8, true>(ir, inst); + PolyfillVectorMultiplyWiden<8, true>(ir, *iter); } break; case IR::Opcode::VectorMultiplySignedWiden16: if (polyfill.vector_multiply_widen) { - PolyfillVectorMultiplyWiden<16, true>(ir, inst); + PolyfillVectorMultiplyWiden<16, true>(ir, *iter); } break; case IR::Opcode::VectorMultiplySignedWiden32: if (polyfill.vector_multiply_widen) { - PolyfillVectorMultiplyWiden<32, true>(ir, inst); + PolyfillVectorMultiplyWiden<32, true>(ir, *iter); } break; case IR::Opcode::VectorMultiplyUnsignedWiden8: if (polyfill.vector_multiply_widen) { - PolyfillVectorMultiplyWiden<8, false>(ir, inst); + PolyfillVectorMultiplyWiden<8, false>(ir, *iter); } break; case IR::Opcode::VectorMultiplyUnsignedWiden16: if (polyfill.vector_multiply_widen) { - PolyfillVectorMultiplyWiden<16, false>(ir, inst); + PolyfillVectorMultiplyWiden<16, false>(ir, *iter); } break; case IR::Opcode::VectorMultiplyUnsignedWiden32: if (polyfill.vector_multiply_widen) { - PolyfillVectorMultiplyWiden<32, false>(ir, inst); + PolyfillVectorMultiplyWiden<32, false>(ir, *iter); } break; default: diff --git a/externals/dynarmic/src/dynarmic/ir/opt/x64_peepholes.cpp b/externals/dynarmic/src/dynarmic/ir/opt/x64_peepholes.cpp new file mode 100644 index 0000000000..7d901a1026 --- /dev/null +++ b/externals/dynarmic/src/dynarmic/ir/opt/x64_peepholes.cpp @@ -0,0 +1,24 @@ +/* This file is part of the dynarmic project. + * Copyright (c) 2018 MerryMage + * SPDX-License-Identifier: 0BSD + */ + +#include +#include + +#include "dynarmic/frontend/A64/a64_location_descriptor.h" +#include "dynarmic/frontend/A64/translate/a64_translate.h" +#include "dynarmic/interface/A64/config.h" +#include "dynarmic/ir/basic_block.h" +#include "dynarmic/ir/opt/passes.h" + +namespace Dynarmic::Optimization { + +// blind peepholes +void X64Peepholes(IR::Block& block) { + for (auto iter = block.begin(); iter != block.end(); iter++) { + + } +} + +} // namespace Dynarmic::Optimization diff --git a/externals/dynarmic/tests/A32/test_arm_instructions.cpp b/externals/dynarmic/tests/A32/test_arm_instructions.cpp index 3232f1a8f1..598f9d2248 100644 --- a/externals/dynarmic/tests/A32/test_arm_instructions.cpp +++ b/externals/dynarmic/tests/A32/test_arm_instructions.cpp @@ -539,7 +539,8 @@ TEST_CASE("arm: Memory access (fastmem)", "[arm][A32]") { char* backing_memory = reinterpret_cast(std::align(page_size, memory_size, buffer_ptr, buffer_size_nconst)); A32FastmemTestEnv env{backing_memory}; - Dynarmic::A32::UserConfig config{&env}; + Dynarmic::A32::UserConfig config{}; + config.callbacks = &env; config.fastmem_pointer = reinterpret_cast(backing_memory); config.recompile_on_fastmem_failure = false; config.processor_id = 0; diff --git a/externals/dynarmic/tests/A64/a64.cpp b/externals/dynarmic/tests/A64/a64.cpp index 246e61e122..801b01d555 100644 --- a/externals/dynarmic/tests/A64/a64.cpp +++ b/externals/dynarmic/tests/A64/a64.cpp @@ -15,7 +15,9 @@ using namespace oaknut::util; TEST_CASE("A64: ADD", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; env.code_mem.emplace_back(0x8b020020); // ADD X0, X1, X2 env.code_mem.emplace_back(0x14000000); // B . @@ -36,7 +38,9 @@ TEST_CASE("A64: ADD", "[a64]") { TEST_CASE("A64: ADD{V,P}", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; env.code_mem.emplace_back(0x0E31B801); // ADDV b1, v0.8b env.code_mem.emplace_back(0x4E31B802); // ADDV b2, v0.16b @@ -62,7 +66,9 @@ TEST_CASE("A64: ADD{V,P}", "[a64]") { TEST_CASE("A64: CLZ", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; oaknut::VectorCodeGenerator code{env.code_mem, nullptr}; code.CLZ(V3.B16(), V0.B16()); @@ -84,7 +90,9 @@ TEST_CASE("A64: CLZ", "[a64]") { TEST_CASE("A64: UADDL{V,P}", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; env.code_mem.emplace_back(0x2E303801); // UADDLV h1, v0.8b env.code_mem.emplace_back(0x6E303802); // UADDLV h2, v0.16b @@ -110,7 +118,9 @@ TEST_CASE("A64: UADDL{V,P}", "[a64]") { TEST_CASE("A64: SADDL{V,P}", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; env.code_mem.emplace_back(0x0E303801); // SADDLV h1, v0.8b env.code_mem.emplace_back(0x4E303802); // SADDLV h2, v0.16b @@ -136,7 +146,9 @@ TEST_CASE("A64: SADDL{V,P}", "[a64]") { TEST_CASE("A64: VQADD", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; env.code_mem.emplace_back(0x6e210c02); // UQADD v2.16b, v0.16b, v1.16b env.code_mem.emplace_back(0x4e210c03); // SQADD v3.16b, v0.16b, v1.16b @@ -167,7 +179,9 @@ TEST_CASE("A64: VQADD", "[a64]") { TEST_CASE("A64: VQSUB", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; env.code_mem.emplace_back(0x6e212c02); // UQSUB v2.16b, v0.16b, v1.16b env.code_mem.emplace_back(0x4e212c03); // SQSUB v3.16b, v0.16b, v1.16b @@ -198,7 +212,9 @@ TEST_CASE("A64: VQSUB", "[a64]") { TEST_CASE("A64: REV", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; env.code_mem.emplace_back(0xdac00c00); // REV X0, X0 env.code_mem.emplace_back(0x5ac00821); // REV W1, W1 @@ -218,7 +234,9 @@ TEST_CASE("A64: REV", "[a64]") { TEST_CASE("A64: REV32", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; env.code_mem.emplace_back(0xdac00800); // REV32 X0, X0 env.code_mem.emplace_back(0x14000000); // B . @@ -234,7 +252,9 @@ TEST_CASE("A64: REV32", "[a64]") { TEST_CASE("A64: REV16", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; env.code_mem.emplace_back(0xdac00400); // REV16 X0, X0 env.code_mem.emplace_back(0x5ac00421); // REV16 W1, W1 @@ -254,7 +274,9 @@ TEST_CASE("A64: REV16", "[a64]") { TEST_CASE("A64: SSHL", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; oaknut::VectorCodeGenerator code{env.code_mem, nullptr}; code.SSHL(V4.B16(), V4.B16(), V0.B16()); @@ -288,7 +310,9 @@ TEST_CASE("A64: SSHL", "[a64]") { TEST_CASE("A64: USHL", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; oaknut::VectorCodeGenerator code{env.code_mem, nullptr}; code.USHL(V4.B16(), V4.B16(), V0.B16()); @@ -334,7 +358,9 @@ TEST_CASE("A64: USHL", "[a64]") { TEST_CASE("A64: URSHL", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; oaknut::VectorCodeGenerator code{env.code_mem, nullptr}; code.URSHL(V0.S4(), V1.S4(), V2.S4()); @@ -365,7 +391,9 @@ TEST_CASE("A64: URSHL", "[a64]") { TEST_CASE("A64: XTN", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; env.code_mem.emplace_back(0x0e212803); // XTN v3.8b, v0.8h env.code_mem.emplace_back(0x0e612824); // XTN v4.4h, v1.4s @@ -387,7 +415,9 @@ TEST_CASE("A64: XTN", "[a64]") { TEST_CASE("A64: TBL", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; env.code_mem.emplace_back(0x0e000100); // TBL v0.8b, { v8.16b }, v0.8b env.code_mem.emplace_back(0x4e010101); // TBL v1.16b, { v8.16b }, v1.16b @@ -433,7 +463,9 @@ TEST_CASE("A64: TBL", "[a64]") { TEST_CASE("A64: TBX", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; env.code_mem.emplace_back(0x0e001100); // TBX v0.8b, { v8.16b }, v0.8b env.code_mem.emplace_back(0x4e011101); // TBX v1.16b, { v8.16b }, v1.16b @@ -479,7 +511,9 @@ TEST_CASE("A64: TBX", "[a64]") { TEST_CASE("A64: AND", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; env.code_mem.emplace_back(0x8a020020); // AND X0, X1, X2 env.code_mem.emplace_back(0x14000000); // B . @@ -500,7 +534,9 @@ TEST_CASE("A64: AND", "[a64]") { TEST_CASE("A64: Bitmasks", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; env.code_mem.emplace_back(0x3200c3e0); // ORR W0, WZR, #0x01010101 env.code_mem.emplace_back(0x320c8fe1); // ORR W1, WZR, #0x00F000F0 @@ -520,7 +556,9 @@ TEST_CASE("A64: Bitmasks", "[a64]") { TEST_CASE("A64: ANDS NZCV", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; env.code_mem.emplace_back(0x6a020020); // ANDS W0, W1, W2 env.code_mem.emplace_back(0x14000000); // B . @@ -575,7 +613,9 @@ TEST_CASE("A64: ANDS NZCV", "[a64]") { TEST_CASE("A64: CBZ", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; env.code_mem.emplace_back(0x34000060); // 0x00 : CBZ X0, label env.code_mem.emplace_back(0x320003e2); // 0x04 : MOV X2, 1 @@ -608,7 +648,9 @@ TEST_CASE("A64: CBZ", "[a64]") { TEST_CASE("A64: TBZ", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; env.code_mem.emplace_back(0x36180060); // 0x00 : TBZ X0, 3, label env.code_mem.emplace_back(0x320003e2); // 0x04 : MOV X2, 1 @@ -652,7 +694,9 @@ TEST_CASE("A64: TBZ", "[a64]") { TEST_CASE("A64: FABD", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; env.code_mem.emplace_back(0x6eb5d556); // FABD.4S V22, V10, V21 env.code_mem.emplace_back(0x14000000); // B . @@ -669,7 +713,9 @@ TEST_CASE("A64: FABD", "[a64]") { TEST_CASE("A64: FABS", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; env.code_mem.emplace_back(0x4ef8f804); // FABS v4.8h, v0.8h env.code_mem.emplace_back(0x4ea0f825); // FABS v5.4s, v1.4s @@ -691,7 +737,9 @@ TEST_CASE("A64: FABS", "[a64]") { TEST_CASE("A64: FMIN (example)", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; env.code_mem.emplace_back(0x4ea1f400); // FMIN.4S V0, V0, V1 env.code_mem.emplace_back(0x4ee3f442); // FMIN.2D V2, V2, V3 @@ -713,7 +761,9 @@ TEST_CASE("A64: FMIN (example)", "[a64]") { TEST_CASE("A64: FMAX (example)", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; env.code_mem.emplace_back(0x4e21f400); // FMAX.4S V0, V0, V1 env.code_mem.emplace_back(0x4e63f442); // FMAX.2D V2, V2, V3 @@ -735,7 +785,9 @@ TEST_CASE("A64: FMAX (example)", "[a64]") { TEST_CASE("A64: FMINNM (example)", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; env.code_mem.emplace_back(0x4ea1c400); // FMINNM.4S V0, V0, V1 env.code_mem.emplace_back(0x4ee3c442); // FMINNM.2D V2, V2, V3 @@ -757,7 +809,9 @@ TEST_CASE("A64: FMINNM (example)", "[a64]") { TEST_CASE("A64: FMAXNM (example)", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; env.code_mem.emplace_back(0x4e21c400); // FMAXNM.4S V0, V0, V1 env.code_mem.emplace_back(0x4e63c442); // FMAXNM.2D V2, V2, V3 @@ -779,7 +833,9 @@ TEST_CASE("A64: FMAXNM (example)", "[a64]") { TEST_CASE("A64: FMAXNM (example 2)", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; env.code_mem.emplace_back(0x4e3bc6fd); // FMAXNM.4S V29, V23, V27 env.code_mem.emplace_back(0x14000000); // B . @@ -831,7 +887,9 @@ TEST_CASE("A64: 128-bit exclusive read/write", "[a64]") { TEST_CASE("A64: CNTPCT_EL0", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; env.code_mem.emplace_back(0xd53be021); // MRS X1, CNTPCT_EL0 env.code_mem.emplace_back(0xd503201f); // NOP @@ -852,7 +910,9 @@ TEST_CASE("A64: CNTPCT_EL0", "[a64]") { TEST_CASE("A64: FNMSUB 1", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; env.code_mem.emplace_back(0x1f618a9c); // FNMSUB D28, D20, D1, D2 env.code_mem.emplace_back(0x14000000); // B . @@ -870,7 +930,9 @@ TEST_CASE("A64: FNMSUB 1", "[a64]") { TEST_CASE("A64: FNMSUB 2", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; env.code_mem.emplace_back(0x1f2ab88e); // FNMSUB S14, S4, S10, S14 env.code_mem.emplace_back(0x14000000); // B . @@ -889,7 +951,9 @@ TEST_CASE("A64: FNMSUB 2", "[a64]") { TEST_CASE("A64: FMADD", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; env.code_mem.emplace_back(0x1f5e0e4a); // FMADD D10, D18, D30, D3 env.code_mem.emplace_back(0x14000000); // B . @@ -908,7 +972,9 @@ TEST_CASE("A64: FMADD", "[a64]") { TEST_CASE("A64: FMLA.4S(lane)", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; env.code_mem.emplace_back(0x4f8f11c0); // FMLA.4S V0, V14, V15[0] env.code_mem.emplace_back(0x4faf11c1); // FMLA.4S V1, V14, V15[1] @@ -936,7 +1002,9 @@ TEST_CASE("A64: FMLA.4S(lane)", "[a64]") { TEST_CASE("A64: FMUL.4S(lane)", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; env.code_mem.emplace_back(0x4f8f91c0); // FMUL.4S V0, V14, V15[0] env.code_mem.emplace_back(0x4faf91c1); // FMUL.4S V1, V14, V15[1] @@ -959,7 +1027,9 @@ TEST_CASE("A64: FMUL.4S(lane)", "[a64]") { TEST_CASE("A64: FMLA.4S (denormal)", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; env.code_mem.emplace_back(0x4e2fcccc); // FMLA.4S V12, V6, V15 env.code_mem.emplace_back(0x14000000); // B . @@ -978,7 +1048,9 @@ TEST_CASE("A64: FMLA.4S (denormal)", "[a64]") { TEST_CASE("A64: FMLA.4S (0x80800000)", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; env.code_mem.emplace_back(0x4e38cc2b); // FMLA.4S V11, V1, V24 env.code_mem.emplace_back(0x14000000); // B . @@ -1000,7 +1072,9 @@ TEST_CASE("A64: FMLA.4S (0x80800000)", "[a64]") { // x64 performs rounding before flushing-to-zero. TEST_CASE("A64: FMADD (0x80800000)", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; env.code_mem.emplace_back(0x1f0f7319); // FMADD S25, S24, S15, S28 env.code_mem.emplace_back(0x14000000); // B . @@ -1019,7 +1093,9 @@ TEST_CASE("A64: FMADD (0x80800000)", "[a64]") { TEST_CASE("A64: FNEG failed to zero upper", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; env.code_mem.emplace_back(0x2ea0fb50); // FNEG.2S V16, V26 env.code_mem.emplace_back(0x2e207a1c); // SQNEG.8B V28, V16 @@ -1038,7 +1114,9 @@ TEST_CASE("A64: FNEG failed to zero upper", "[a64]") { TEST_CASE("A64: FRSQRTS", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; env.code_mem.emplace_back(0x5eb8fcad); // FRSQRTS S13, S5, S24 env.code_mem.emplace_back(0x14000000); // B . @@ -1060,7 +1138,9 @@ TEST_CASE("A64: FRSQRTS", "[a64]") { TEST_CASE("A64: SQDMULH.8H (saturate)", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; env.code_mem.emplace_back(0x4e62b420); // SQDMULH.8H V0, V1, V2 env.code_mem.emplace_back(0x14000000); // B . @@ -1081,7 +1161,9 @@ TEST_CASE("A64: SQDMULH.8H (saturate)", "[a64]") { TEST_CASE("A64: SQDMULH.4S (saturate)", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; env.code_mem.emplace_back(0x4ea2b420); // SQDMULH.4S V0, V1, V2 env.code_mem.emplace_back(0x14000000); // B . @@ -1102,7 +1184,8 @@ TEST_CASE("A64: SQDMULH.4S (saturate)", "[a64]") { TEST_CASE("A64: This is an infinite loop if fast dispatch is enabled", "[a64]") { A64TestEnv env; - A64::UserConfig conf{&env}; + A64::UserConfig conf{}; + conf.callbacks = &env; conf.optimizations &= ~OptimizationFlag::FastDispatch; A64::Jit jit{conf}; @@ -1119,7 +1202,9 @@ TEST_CASE("A64: This is an infinite loop if fast dispatch is enabled", "[a64]") TEST_CASE("A64: EXTR", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; env.code_mem.emplace_back(0x93d8fef7); // EXTR X23, X23, X24, #63 env.code_mem.emplace_back(0x14000000); // B . @@ -1136,7 +1221,9 @@ TEST_CASE("A64: EXTR", "[a64]") { TEST_CASE("A64: Isolated GetNZCVFromOp", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; env.code_mem.emplace_back(0xaa1f03f5); // MOV X21, XZR env.code_mem.emplace_back(0x912a02da); // ADD X26, X22, #0xa80 @@ -1167,7 +1254,9 @@ TEST_CASE("A64: Isolated GetNZCVFromOp", "[a64]") { TEST_CASE("A64: Optimization failure when folding ADD", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; env.code_mem.emplace_back(0xbc4f84be); // LDR S30, [X5], #248 env.code_mem.emplace_back(0x9a0c00ea); // ADC X10, X7, X12 @@ -1263,7 +1352,8 @@ TEST_CASE("A64: Cache Maintenance Instructions", "[a64]") { }; CacheMaintenanceTestEnv env; - A64::UserConfig conf{&env}; + A64::UserConfig conf{}; + conf.callbacks = &env; conf.hook_data_cache_operations = true; A64::Jit jit{conf}; @@ -1290,7 +1380,8 @@ TEST_CASE("A64: Memory access (fastmem)", "[a64]") { char* backing_memory = reinterpret_cast(std::align(page_size, memory_size, buffer_ptr, buffer_size_nconst)); A64FastmemTestEnv env{backing_memory}; - Dynarmic::A64::UserConfig config{&env}; + Dynarmic::A64::UserConfig config{}; + config.callbacks = &env; config.fastmem_pointer = reinterpret_cast(backing_memory); config.fastmem_address_space_bits = address_width; config.recompile_on_fastmem_failure = false; @@ -1323,7 +1414,9 @@ TEST_CASE("A64: Memory access (fastmem)", "[a64]") { TEST_CASE("A64: SQRDMULH QC flag when output invalidated", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; env.code_mem.emplace_back(0x0fbcd38b); // SQRDMULH.2S V11, V28, V28[1] env.code_mem.emplace_back(0x7ef0f8eb); // FMINP.2D D11, V7 @@ -1343,7 +1436,9 @@ TEST_CASE("A64: SQRDMULH QC flag when output invalidated", "[a64]") { TEST_CASE("A64: SDIV maximally", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; env.code_mem.emplace_back(0x9ac00c22); // SDIV X2, X1, X0 env.code_mem.emplace_back(0x14000000); // B . @@ -1367,7 +1462,9 @@ TEST_CASE("A64: SDIV maximally", "[a64]") { // const HostLocList any_xmm = { HostLoc::XMM1, HostLoc::XMM2, HostLoc::XMM3, HostLoc::XMM4, HostLoc::XMM5, HostLoc::XMM6 }; TEST_CASE("A64: rand1", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; env.code_mem = {0x2ea2e69a, 0x6f7168e7, 0x7eb0f816, 0x6ebd369d, 0x1e65c302, 0x1e63011c, 0x1e67c349, 0x0f861bd6, 0x9e59cbbc, 0x5e61cb8b, 0x6e218b01, 0x4eb2409f, 0x7f7c2452, 0x7e207a8d, 0xd503369f}; env.code_mem.emplace_back(0x14000000); // B . @@ -1480,7 +1577,10 @@ TEST_CASE("A64: rand1", "[a64]") { TEST_CASE("A64: rand2", "[a64][.]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{.callbacks = &env, .fastmem_pointer = 0xffffffff00000000}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + jit_user_config.fastmem_pointer = 0xffffffff00000000; + A64::Jit jit{jit_user_config}; env.code_mem = {0xea80f352, 0x6e65e59d, 0x1e20c343, 0x2e3a7192, 0x2e267249, 0xd500405f, 0x6f01f461, 0x6eb684fc, 0x58028edd, 0x0ea5f5b6, 0x0ea069fb, 0x2e769517, 0x5e066063, 0x1e65c3f5, 0x4f00ff52, 0x93401cf6, 0x1e274248, 0x6f67aaf5, 0x5e0c0782, 0x5ef43f3c, 0x2e6595b7, 0x4e20590f, 0xb35aa451, 0x6ee2c5ed, 0x4e32bf46, 0x2ea1ba8f, 0x2f68a85e, 0x9237d90a, 0x5e23dd10, 0x0e762e32, 0x4e31a8cf, 0xce1f3360, 0x781a4ac0, 0x13834066, 0x5fa8101c, 0x6f7c5594, 0x0e71bb68, 0xbc0b3e8f, 0x785dbbda, 0x6f51e794, 0xce50af75, 0x1ad728ec, 0x6ee0da4c, 0xb84efa14, 0x2eb3f613, 0x4e287ade, 0x4eb8c734, 0x2e83f4e8, 0x0e397c80, 0xd08f93f8, 0xce718e48, 0x0f672a0d, 0x2e9edd40, 0x0e14128b, 0x6f5942e6, 0x8b3a0f03, 0x3c5d16b9, 0x7f7e3743, 0x4f4c54e4, 0x0ea0a9e9, 0x9e59dbe6, 0x6e7ddcd3, 0xcec08377, 0x9ba759f8, 0x2ea5046e, 0x0e24c569, 0xb8979780, 0x4e31b98c, 0x4efe4f46, 0x4ea7c762, 0x7e61c9c6, 0x6e30c880, 0x1ada0c25, 0x4e603a2f, 0xda9d7218, 0x0d40c5d9, 0x5e214b05, 0x9ba9efc5, 0x5e61b81e, 0x6e7bc31c, 0x0e61a163, 0x9e5832d2, 0x4e772248, 0x4e3d17c8, 0x92624f60, 0x7a1a02dc, 0x79891f65, 0x6eb45036, 0x0e321ee8, 0x4e2566f0, 0x4ea02b9b, 0x0f9dcb3d, 0x2e21b9f9, 0x0e21a8c3, 0xda1700bd, 0x6ea0fb38, 0x7e607a0b, 0x72845817, 0x7f61068e, 0x0d60e529, 0x4ea0ca5c, 0x1a94b20f, 0x8b87419d, 0x7ea9ed71, 0x2ea1a86e, 0x4d40c4da, 0x5ea0eada, 0x784ba96e, 0x7eb6ee02, 0x3db1c710, 0x0e217836, 0x7ee0bb96, 0x4e786c08, 0x4e976a08, 0x489ffe86, 0x4e79fc9b, 0x0e21cbce, 0x5ef7fc65, 0x4ea1286d, 0xd29c771e, 0x6f5c2839, 0x0ea00a9d, 0x6ee44c06, 0x5ee1d858, 0x5ef2fda6, 0x7eb0c9fe, 0x7f762791, 0x2e212ae6, 0x4e61c9db, 0x13003c57, 0x5ee1b8f8, 0x0f2396d2, 0x6ea0db1e, 0x0e71ba82, 0xab29c807, 0x6ef8f8b3, 0x1f18d4a1, 0x0e261d15, 0x1e290081, 0x1b0c7d12, 0x4e7771c3, 0xf845f1e4, 0x4d40c9e8, 0xce778452, 0x6eb9879d, 0x6e21c93d, 0xcec0829f, 0x52a0969f, 0x1e772b4f, 0x7ee1da88, 0x5f52fe0a, 0x7f3387b1, 0x5e214850, 0x1e65c025, 0x0e2ca294, 0x2e614829, 0x1e640077, 0x9e240048, 0x4ebe9537, 0x9bb7925e, 0x38b669c5, 0x2840d089, 0x6f43e648, 0x2e662d28, 0x4eabaff3, 0x6e734cc7, 0x0e31baee, 0x7ee0d93c, 0x5e282bde, 0x7e21bba4, 0x4e6c75fa, 0x5ac01217, 0x7f4304af, 0x1e7878ed, 0x1ada2196, 0x7ee1aba3, 0x93407f3c, 0x4f6c34eb, 0x6e3447a9, 0x7e7ae545, 0x5e0802bb, 0x6eeae63a, 0x7ee1da62, 0x5e280bb3, 0xf81d4009, 0x1e603b21, 0x5e281a14, 0x6eb0a99b, 0x1e266a25, 0x0d60cafe, 0x0e0b6194, 0x7a4ed2c5, 0x92b762ec, 0x4e6b5749, 0x3c16a6e5, 0x4ea0a92b, 0x0fa58b6a, 0x5f76148c, 0x6e30c95f, 0x1e6540fd, 0x5e28e40f, 0x0d403fd4, 0x7e30da36, 0x7fda9b51, 0x2ea04bde, 0x1e25c3d2, 0x1ee0434c, 0x5e21d8e7, 0x5ee1ba51, 0x5e61aba9, 0x4e2849fb, 0x5ee098ea, 0x4e60f63d, 0x0f280443, 0x5ee0da27, 0x2e78a6ce, 0x78054afc, 0x4e14286b, 0x4e218bd8, 0x2a3d2551, 0x3a04017a, 0x5f4317cd, 0x0e604a37, 0x9a834614, 0x0e2edf4d, 0x7a51a0a0, 0x5f8e9043, 0x6ea06bb2, 0xaa2857dd, 0x7a1903fc, 0x301ba9ba, 0x9ac929cd, 0x4e061ff0, 0x2e38fcfc, 0x0e2f614a, 0x7ee0d8e4, 0x6e73afda, 0x7f4156f7, 0x0e6078bf, 0x4ee1d9ed, 0x93403fbe, 0xce6f8640, 0x4e3855e3, 0x6f76fe23, 0x112466e8, 0x1e358a90, 0x7f45272c, 0x6ea19a9d, 0x8a696350, 0x1e3900f6, 0x5e61c866, 0x0e3fbfd0, 0x5ee09ad0, 0x0e651d27, 0x4dffc35e, 0x2e20c6ce, 0x0fbe118d, 0x1e656a15, 0xd1357365, 0x0e20a847, 0xce4a835c, 0x4e203905, 0x2e60090d, 0x7f4a27bb, 0x1e64c316, 0xce7d86a4, 0x7ebded2d, 0x6e70a97e, 0x4eb9a42b, 0x0e209bef, 0x6f151730, 0x0e7e30f7, 0x4e724509, 0xd503375f, 0xce58b6ae, 0x5e21a9b8, 0xcb2ca538, 0x5ac01131, 0x6ea19a24, 0xeb40c8b3, 0xc8df7d65, 0x78108341, 0x3218ab9b, 0x0f3da7dd, 0x2e003089, 0x4e21cab5, 0x8aa5c924, 0x1a94950c, 0x123e506f, 0x13117e37, 0x1ee6005b, 0x5ac00647, 0x5eec8cd5, 0x7ef0fb3d, 0x9223272a, 0x5ee0cb02, 0x6e66071d, 0x6ea1dbbf, 0x5e61c903, 0x5ac015ea, 0x93db6206, 0x7e62b5e3, 0x6ea0c87b, 0xdac0090e, 0x48df7d90, 0x6e206ba5, 0x9e2503c2, 0x6e25fc89, 0x4d60e2db, 0x1e3e22a0, 0x2eb81c19, 0x7856ea00, 0x5fbfb22d, 0x1e630244, 0x4e202a83, 0x1f50a722, 0x7f7b55d2, 0x0fae89b9, 0x4e781d73, 0xce738c3a, 0x4f15a591, 0x6e21c7e1, 0x586ff77e, 0x8a5d3592, 0x93401c67, 0x5e61cb86, 0xce6bc2c1, 0x6e393f10, 0x9bb70ec3, 0xdac0098c, 0x4da84b95, 0x7f494476, 0x9ace5c11, 0x7e61ca14, 0x4f7a60ef, 0x1ad32b39, 0x0ea3777f, 0x5e61da7f, 0x4f1404e2, 0x4e3244e2, 0x6e1b1ceb, 0x0dee5aac, 0x4e2f9dc4, 0x5ea1b8c3, 0x1e59f863, 0xd500403f, 0x4e3ae7d0, 0x4ef5c6ea, 0x08dffe3b, 0x6e36f4f6, 0x2e764f29, 0x0e726f23, 0x5f42375b, 0x7f71fc40, 0x6e618aad, 0x93403e5b, 0x0e205976, 0x0e7250c4, 0x6eb0abc9, 0x2e2049f0, 0x5f14754d, 0x7f6ce468, 0x6f950bbe, 0x6e31aa47, 0x4eb83396, 0x0dccc952, 0x2ea1ca90, 0xce69c701, 0xb0bed69e, 0x7c5dec39, 0x4e2868a2, 0x0e591b08, 0x5f34e6dd, 0x3a449184, 0x5e3ce6de, 0x4ea149b7, 0x4e7ad29b, 0xba198503, 0x1f683e8f, 0xfa52f2a7, 0x6e30dffc, 0x4e6c3d17, 0x2eae3248, 0xd503349f, 0x1e60002c, 0x0f180680, 0x9e240049, 0x6f75774e, 0xa90d8678, 0x9ad924c4, 0x7eb0f85b, 0x0e205aaf, 0x7ee08899, 0x5f4bffd8, 0x1b0ff5f3, 0x4ee11dcd, 0x2e218948, 0x0dcb2733, 0x4eac107c, 0x4ea04a53, 0x4e287b44, 0x0e60b82a, 0x5ee0ebbc, 0xce454ff1, 0x5e1761e7, 0x5e09202f, 0x0e0c0754, 0x1e72e6b9, 0x7e21da70, 0x0fbdb20c, 0x5efb8c84, 0xd500401f, 0x3a47526e, 0x1e680acf, 0x7f7375fc, 0xf80522da, 0x4ee60c02, 0x4d40c2e7, 0x6f89096b, 0x7ee1bb6e, 0x5e280b4a, 0x1e3120c8, 0x7eb2ef96, 0x4fd012dd, 0x0f3027ef, 0x4e2078a8, 0xd503201f, 0x2e2312d9, 0x6ebf1c6e, 0x5ee1f8df, 0x4e607a46, 0x6e30c877, 0x6c09d2d1, 0x4e61abd8, 0x0e35267e, 0x6ac17728, 0x0e861aa0, 0x6f63fe26, 0x6f157628, 0x6f30a5f9, 0x4d60cc0c, 0x4e21cb59, 0x2e68a3fb, 0x7efae601, 0x6ea0f82c, 0x9b25ec12, 0x1a1a0305, 0x0e043fe1, 0x6e73c0ed, 0x6ea1b8c0, 0x7e20380b, 0x0f0534e8, 0x1f56bc7d, 0xba0c0128, 0x1e672160, 0x6e7b259b, 0x7ee07b5d, 0x9a820443, 0x4e040581, 0x2f1d87e8, 0x1acd2f5b, 0x6e20794f, 0x2e6a3c93, 0xc8dffe13, 0xce5ab1c6, 0x6eea55f6, 0x4ea039b3, 0x0d602fec, 0x2e246e2f, 0x7857be39, 0xb80608fb, 0x1e67c017, 0x9bcf7f63, 0x0f92d857, 0x5e0812f7, 0x1e210172, 0x7e6128e9, 0x7ea94d41, 0x981179e1, 0x1effb018, 0x2e600828, 0x0eb9c6b2, 0x6ee1baae, 0x4ea0db28, 0x2ea1487b, 0x4ea6c7f0, 0x2e2374c7, 0x7e30d8dd, 0xb9991fa7, 0x4e791e3e, 0x889f7c4b, 0x0e6c753c, 0x1e740ad1, 0x1e244324, 0x1ef33010, 0x5ac01102, 0x9bd97fba, 0x6e290143, 0x1e2220d8, 0x4d8d5aee, 0x6f28570b, 0xfa4ab0c1, 0xdac00b14, 0x7ea1a90e, 0x2e3027d8, 0x6f25a733, 0x4e61a96e, 0x4e1a2fcb, 0x0e22fe0a, 0xc8df7cd0, 0x5e280a55, 0x4e012b20, 0x7e70dbf4, 0x520c5a4e, 0x6ea6c57f, 0x0e861af8, 0xd503233f, 0x889ffe3c, 0x5e274ea9, 0x4e21a89a, 0x0e170c02, 0x6efd4c0b, 0xd5033ebf, 0x6e61a92c, 0x2e205b72, 0x789fb828, 0x0e626e94, 0x2ea6724c, 0x9a10028b, 0x2c6c51fc, 0x5a9de6b9, 0x6e6881f3, 0x5ee0ea6b, 0x0faec36e, 0x0e955bca, 0x1acf206d, 0x7f6f571b, 0x4e286930, 0x12b41ceb, 0x1e770b7a, 0x0ea18ac2, 0x5e282aaf, 0xf2b7fa1e, 0x1ac34311, 0x13167d11, 0x4ea63412, 0x6e758038, 0x2f1d85d6, 0x0f275480, 0x0ead6c71, 0x6e204b69, 0x1e6303f4, 0x5e0031ef, 0x13001e40, 0x7a16006f, 0x6e6ae4c0, 0x0f0f242f, 0x6e674f50, 0x4e606b7a, 0x7e6ee684, 0x1e6b5957, 0x7ea1bbab, 0x7ea0b6cb, 0xce4da241, 0x0ea1b953, 0x0eb2af4b, 0x9ac309d0, 0x6e61d8bd, 0x5ea0d890, 0x5f47d1e7, 0xfa5981ca, 0x1e7f7959, 0x6ef24dd8, 0x0e0a41d1, 0x5ee0e898, 0x4e6038e2, 0x13097d65, 0x6f839088, 0x9e290265, 0x0e208824, 0x2e65af79, 0x6f36a561, 0x9ad3204b, 0x0e21482e, 0x1e24431d, 0xd50330bf, 0x0df641aa, 0x6e602a83, 0xce30505f, 0x5e025238, 0xd503201f, 0x4e608880, 0x4de9c38d, 0x5e0f5348, 0x6eb48ca9, 0x50fda31b, 0x2e251eec, 0x7842ba50, 0xd8a1cd86, 0x2ea09862, 0x0ea09983, 0x2ea333b0, 0x0ea6032c, 0x4f94801b, 0x7e3ee57d, 0x38135e4f, 0xd8fdd9dd, 0x5ee0fcde, 0x9e64033d, 0x6e37f547, 0x6e3dd7ef, 0x13003f3d, 0x0e602f9f, 0x4e7ad014, 0x9b3b6857, 0x5ea0cb67, 0x0eb31c9f, 0x4e7c5372, 0x5e61b8c0, 0x0ea19b23, 0x0ee6e1df, 0x6e63a626, 0x2f139405, 0x7eb0f96d, 0x9e588c63, 0x2e714c3a, 0x6e8c941e, 0x0f61b331, 0x6f01f625, 0x4e78d4ea, 0x6f403709, 0x1a0300da, 0xda0102c8, 0x7e61d9fd, 0xb89469bb, 0x0c838780, 0x2e60a590, 0x4dfd29e1, 0x4e150f2e, 0xce2810bc, 0x5f541591, 0x9ee60259, 0x2eb40e56, 0x5e014027, 0x2ef71faf, 0x4e2d452f, 0x5ee0a813, 0x4eb03301, 0x38443acf, 0x6eabd502, 0x0e2ee71e, 0x5a960364, 0xce7ec596, 0x7efbed09, 0x4ef42ea2, 0x0eb30ea5, 0x5ee0d9f8, 0x6f513552, 0xf89eb3fa, 0x7ea2eca6, 0x9b00cc19, 0xf897409e, 0x1e73485f, 0x381afa77, 0x0f169f3b, 0x5ee1aa70, 0x5e1803ee, 0x0dbf5a4c, 0xce78c7a6, 0x9b0b260c, 0x2ef8fa19, 0x6e70aa4b, 0xce45b805, 0x2ea08e86, 0x4ee0bafd, 0x2ea09a1f, 0x4e218900, 0x6e744f13, 0xce518653, 0xf81b7a68, 0xce45ac5e, 0x7e62e416, 0x1a1b02b6, 0x7e21db48, 0x381daaaf, 0x6b2c0987, 0x0e2ec651, 0x4eae8502, 0x9bde7ca0, 0x6f47201f, 0x7e61a8a3, 0x6e60d5db, 0x4e2879de, 0xf81d194e, 0x4f1b8d05, 0x4d0048b2, 0x6e203be9, 0x4e3e7eb1, 0x0e260ef8, 0x2e688518, 0x7e3fec46, 0xdac00843, 0xf85c8917, 0x2e212a0f, 0x0e8196da, 0xd503359f, 0xce4c81f2, 0x6ee19992, 0x6e21ca79, 0x4d40c1d2, 0x4f5816ef, 0x4e34c3ea, 0x4df7c283, 0x7ef7eeb6, 0x18e276ce, 0xab0d21c0, 0xd5032f7f, 0x4ea00dbf, 0x5ac01251, 0xd0121955, 0x7f1495e4, 0x7ef0fa11, 0x5e24dd9c, 0x9add25b5, 0x0eb2bdef, 0x9e1977c7, 0x6f4b26bd, 0x0e200a9c, 0x9b4f7c00, 0x0ea0392e, 0x7e212a2c, 0x0b248b90, 0x1acc27a1, 0x2e701c90, 0x5ee1b870, 0x5e280aba, 0x5ea0780e, 0x1e264246, 0x4e052d04, 0x0e731dc4, 0xce461997, 0x9a9e9413, 0x3d462048, 0x5ea1fac5, 0x2ea0c8c4, 0x9a030280, 0x2ebda4b8, 0x5eef8614, 0x6eadc4e0, 0xbd035a8f, 0x4e606b84, 0x4eb1aba1, 0x4e286928, 0x4e2858cc, 0x9add0ce9, 0x4e070d65, 0x5fd399d5, 0x0f03fde7, 0x6ee90c74, 0x4ef8e31e, 0x381d986a, 0x5ea0ebf4, 0x5ea0d87e, 0x2e76ac9e, 0x6eb36cd4, 0x2e6e1c4c, 0x2e2feebc, 0x1ace4b03, 0x5ee0db12, 0x5ea0e9b1, 0x2e1c32d5, 0x5fa49a09, 0x0e258737, 0x7e21ca8e, 0xce4f9988, 0x5f7f56a6, 0x0e739766, 0x4e28586c, 0x6e619908, 0xd500401f, 0xf88b9252, 0x6e251c8e, 0x9e20015b, 0x7f1486b9, 0x717c339b, 0x1f31ff70, 0x4ea0eb62, 0x9acb0926, 0x489f7d85, 0x4e209b54, 0x2e84cf03, 0x2e65946c, 0x0e7d80cd, 0xc8dffecc, 0xce668bd8, 0x6e2188af, 0xeb4ada34, 0x2b25ec33, 0x0d40e6e7, 0x4eb2c757, 0x4ec82ad0, 0x7e21cb0a, 0x0e21a847, 0x4e0b1ec0, 0x381e6ac0, 0x6e61c8f5, 0x0f10071c, 0x2ee21daa, 0x5e61ab31, 0x6e218892, 0x2e7e7cb5, 0x6f2826aa, 0x7f6b54df, 0x4eaa2620, 0xdac00034, 0x4f6477be, 0x7e6148ea, 0x4eef1f57, 0x78459aeb, 0x2ebc3f10, 0x2e35f4eb, 0x4fbf19ce, 0xd8d0e58e, 0x2e21bbc7, 0x6ee0cab6, 0x9bc57e3f, 0x2f854037, 0x4e92181c, 0x6e6d1f89, 0x0f305545, 0x4ee19a57, 0x0e887bdf, 0x5e1a4185, 0x7ef0c821, 0x2eb6607c, 0x2ea0d9b8, 0x9e0380f4, 0x2ebf1c83, 0x1e62597d, 0x7f6e2548, 0x5ac00205, 0x4e616adb, 0xce638b8c, 0x5e1653cf, 0x2e6069be, 0x0e2ac641, 0x1e33c76f, 0xce44956d, 0x9bb90d31, 0x1e24c20a, 0x7ee038c1, 0x93407e5e, 0x4e280127, 0xc8df7f7d, 0xba42f263, 0x1e6f199c, 0x6e212889, 0x6e92f60e, 0x6ebdc499, 0x8b9acbf8, 0x4d40c581, 0x3a020250, 0x6e6a6716, 0x9248403b, 0x9081ffea, 0x4e603856, 0x9ad1242b, 0x6f270579, 0x1a070349, 0xcec08133, 0xd503305f, 0x5a1a00ca, 0x2e60b8a2, 0x0e5f28fd, 0x0e31a3da, 0x7e61cbc1, 0xd503399f, 0x5f5e54aa, 0x0eb8bdea, 0x4eba8f10, 0x4e2a2e60, 0x2f3da7d6, 0x1e58e297, 0x6e71aa3e, 0x6b86701a, 0xce4fa5e6, 0x4ee7c463, 0x8a79307f, 0x0ebea541, 0x2e218af4, 0x4e774f8a, 0xb9b95dc5, 0x6e61abd5, 0x4dd1e814, 0x4da72098, 0x98307582, 0x3a512101, 0x7ef95497, 0x1ace5535, 0x5a0c0349, 0x4e28581b, 0x6ebf1c02, 0x5ea1da23, 0x1e274314, 0x5e25dd29, 0x6e75f594, 0x6eaf6ed5, 0x4e214abe, 0x4e064172, 0x2e21c8f4, 0xf84c5b08, 0x1e244312, 0x14000000}; env.code_mem.emplace_back(0x14000000); // B . @@ -1596,7 +1696,9 @@ TEST_CASE("A64: rand2", "[a64][.]") { TEST_CASE("A64: SABD", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; oaknut::VectorCodeGenerator code{env.code_mem, nullptr}; code.SABD(V0.B16(), V3.B16(), V4.B16()); @@ -1654,7 +1756,9 @@ TEST_CASE("A64: SABD", "[a64]") { TEST_CASE("A64: UZP{1,2}.2D", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; oaknut::VectorCodeGenerator code{env.code_mem, nullptr}; code.UZP1(V2.D2(), V0.D2(), V1.D2()); @@ -1673,7 +1777,9 @@ TEST_CASE("A64: UZP{1,2}.2D", "[a64]") { TEST_CASE("A64: UZP{1,2}.S", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; oaknut::VectorCodeGenerator code{env.code_mem, nullptr}; code.UZP1(V2.S2(), V0.S2(), V1.S2()); @@ -1696,7 +1802,9 @@ TEST_CASE("A64: UZP{1,2}.S", "[a64]") { TEST_CASE("A64: UZP{1,2}.H", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; oaknut::VectorCodeGenerator code{env.code_mem, nullptr}; code.UZP1(V2.H4(), V0.H4(), V1.H4()); @@ -1719,7 +1827,9 @@ TEST_CASE("A64: UZP{1,2}.H", "[a64]") { TEST_CASE("A64: UZP{1,2}.B", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; oaknut::VectorCodeGenerator code{env.code_mem, nullptr}; code.UZP1(V2.B8(), V0.B8(), V1.B8()); @@ -1742,7 +1852,9 @@ TEST_CASE("A64: UZP{1,2}.B", "[a64]") { TEST_CASE("A64: {S,U}MIN.S, {S,U}MAX.S", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; oaknut::VectorCodeGenerator code{env.code_mem, nullptr}; code.SMIN(V2.S4(), V0.S4(), V1.S4()); @@ -1786,7 +1898,9 @@ TEST_CASE("A64: {S,U}MIN.S, {S,U}MAX.S", "[a64]") { TEST_CASE("A64: {S,U}MIN.H, {S,U}MAX.H", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; oaknut::VectorCodeGenerator code{env.code_mem, nullptr}; code.SMIN(V2.H8(), V0.H8(), V1.H8()); @@ -1830,7 +1944,9 @@ TEST_CASE("A64: {S,U}MIN.H, {S,U}MAX.H", "[a64]") { TEST_CASE("A64: {S,U}MIN.B, {S,U}MAX.B", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; oaknut::VectorCodeGenerator code{env.code_mem, nullptr}; code.SMIN(V2.B16(), V0.B16(), V1.B16()); @@ -1874,7 +1990,9 @@ TEST_CASE("A64: {S,U}MIN.B, {S,U}MAX.B", "[a64]") { TEST_CASE("A64: {S,U}MINP.S, {S,U}MAXP.S", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; oaknut::VectorCodeGenerator code{env.code_mem, nullptr}; code.SMINP(V2.S2(), V0.S2(), V1.S2()); @@ -1942,7 +2060,9 @@ TEST_CASE("A64: {S,U}MINP.S, {S,U}MAXP.S", "[a64]") { TEST_CASE("A64: {S,U}MINP.H, {S,U}MAXP.H", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; oaknut::VectorCodeGenerator code{env.code_mem, nullptr}; code.SMINP(V2.H4(), V0.H4(), V1.H4()); @@ -2010,7 +2130,9 @@ TEST_CASE("A64: {S,U}MINP.H, {S,U}MAXP.H", "[a64]") { TEST_CASE("A64: {S,U}MINP.B, {S,U}MAXP.B", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; oaknut::VectorCodeGenerator code{env.code_mem, nullptr}; code.SMINP(V2.B8(), V0.B8(), V1.B8()); @@ -2084,7 +2206,9 @@ TEST_CASE("A64: {S,U}MINP.B, {S,U}MAXP.B", "[a64]") { TEST_CASE("A64: SQABS", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; oaknut::VectorCodeGenerator code{env.code_mem, nullptr}; // should set QC flag diff --git a/externals/dynarmic/tests/A64/fp_min_max.cpp b/externals/dynarmic/tests/A64/fp_min_max.cpp index 7aa1ef4407..a857005d15 100644 --- a/externals/dynarmic/tests/A64/fp_min_max.cpp +++ b/externals/dynarmic/tests/A64/fp_min_max.cpp @@ -64,7 +64,9 @@ u32 force_default_nan(u32 value) { template void run_test(u32 instruction, Fn fn) { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; env.code_mem.emplace_back(instruction); // FMAX S0, S1, S2 env.code_mem.emplace_back(0x14000000); // B . diff --git a/externals/dynarmic/tests/A64/fuzz_with_unicorn.cpp b/externals/dynarmic/tests/A64/fuzz_with_unicorn.cpp index 1a56a982ef..27d014f71e 100644 --- a/externals/dynarmic/tests/A64/fuzz_with_unicorn.cpp +++ b/externals/dynarmic/tests/A64/fuzz_with_unicorn.cpp @@ -154,7 +154,8 @@ static u32 GenFloatInst(u64 pc, bool is_last_inst) { } static Dynarmic::A64::UserConfig GetUserConfig(A64TestEnv& jit_env) { - Dynarmic::A64::UserConfig jit_user_config{&jit_env}; + Dynarmic::A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &jit_env; jit_user_config.optimizations &= ~OptimizationFlag::FastDispatch; // The below corresponds to the settings for qemu's aarch64_max_initfn jit_user_config.dczid_el0 = 7; diff --git a/externals/dynarmic/tests/A64/misaligned_page_table.cpp b/externals/dynarmic/tests/A64/misaligned_page_table.cpp index f54aa58641..75ac41e06d 100644 --- a/externals/dynarmic/tests/A64/misaligned_page_table.cpp +++ b/externals/dynarmic/tests/A64/misaligned_page_table.cpp @@ -10,7 +10,8 @@ TEST_CASE("misaligned load/store do not use page_table when detect_misaligned_access_via_page_table is set", "[a64]") { A64TestEnv env; - Dynarmic::A64::UserConfig conf{&env}; + Dynarmic::A64::UserConfig conf{}; + conf.callbacks = &env; conf.page_table = nullptr; conf.detect_misaligned_access_via_page_table = 128; conf.only_detect_misalignment_via_page_table_on_page_boundary = true; diff --git a/externals/dynarmic/tests/A64/test_invalidation.cpp b/externals/dynarmic/tests/A64/test_invalidation.cpp index fa35b02b7f..cba47dd8ca 100644 --- a/externals/dynarmic/tests/A64/test_invalidation.cpp +++ b/externals/dynarmic/tests/A64/test_invalidation.cpp @@ -12,8 +12,8 @@ using namespace Dynarmic; TEST_CASE("ensure fast dispatch entry is cleared even when a block does not have any patching requirements", "[a64]") { A64TestEnv env; - - A64::UserConfig conf{&env}; + A64::UserConfig conf{}; + conf.callbacks = &env; A64::Jit jit{conf}; REQUIRE(conf.HasOptimization(OptimizationFlag::FastDispatch)); @@ -64,8 +64,8 @@ TEST_CASE("ensure fast dispatch entry is cleared even when a block does not have TEST_CASE("ensure fast dispatch entry is cleared even when a block does not have any patching requirements 2", "[a64]") { A64TestEnv env; - - A64::UserConfig conf{&env}; + A64::UserConfig conf{}; + conf.callbacks = &env; A64::Jit jit{conf}; REQUIRE(conf.HasOptimization(OptimizationFlag::FastDispatch)); diff --git a/externals/dynarmic/tests/test_generator.cpp b/externals/dynarmic/tests/test_generator.cpp index cfdd8ea436..450d3e3fc4 100644 --- a/externals/dynarmic/tests/test_generator.cpp +++ b/externals/dynarmic/tests/test_generator.cpp @@ -23,6 +23,7 @@ #include "./rand_int.h" #include "dynarmic/common/fp/fpcr.h" #include "dynarmic/common/fp/fpsr.h" +#include "dynarmic/common/llvm_disassemble.h" #include "dynarmic/frontend/A32/ITState.h" #include "dynarmic/frontend/A32/a32_location_descriptor.h" #include "dynarmic/frontend/A32/a32_types.h" @@ -396,39 +397,41 @@ Dynarmic::A32::UserConfig GetA32UserConfig(TestEnv& testenv, bool noopt) { template void RunTestInstance(Dynarmic::A32::Jit& jit, - TestEnv& jit_env, - const std::array& regs, - const std::array& vecs, - const std::vector& instructions, - const u32 cpsr, - const u32 fpscr, - const size_t ticks_left) { + TestEnv& jit_env, + const std::array& regs, + const std::array& vecs, + const std::vector& instructions, + const u32 cpsr, + const u32 fpscr, + const size_t ticks_left, + const bool show_disas) { const u32 initial_pc = regs[15]; const u32 num_words = initial_pc / sizeof(typename TestEnv::InstructionType); const u32 code_mem_size = num_words + static_cast(instructions.size()); - fmt::print("instructions:"); - for (auto instruction : instructions) { - if constexpr (sizeof(decltype(instruction)) == 2) { - fmt::print(" {:04x}", instruction); - } else { - fmt::print(" {:08x}", instruction); + if (show_disas) { + fmt::print("instructions:\n"); + auto current_pc = initial_pc; + for (auto instruction : instructions) { + if constexpr (sizeof(decltype(instruction)) == 2) { + fmt::print("{:04x} ?\n", instruction); + } else { + fmt::print("{}", Dynarmic::Common::DisassembleAArch64(instruction, current_pc)); + } + current_pc += sizeof(decltype(instruction)); } - } - fmt::print("\n"); - fmt::print("initial_regs:"); - for (u32 i : regs) { - fmt::print(" {:08x}", i); + fmt::print("initial_regs:"); + for (u32 i : regs) + fmt::print(" {:08x}", i); + fmt::print("\n"); + fmt::print("initial_vecs:"); + for (u32 i : vecs) + fmt::print(" {:08x}", i); + fmt::print("\n"); + fmt::print("initial_cpsr: {:08x}\n", cpsr); + fmt::print("initial_fpcr: {:08x}\n", fpscr); } - fmt::print("\n"); - fmt::print("initial_vecs:"); - for (u32 i : vecs) { - fmt::print(" {:08x}", i); - } - fmt::print("\n"); - fmt::print("initial_cpsr: {:08x}\n", cpsr); - fmt::print("initial_fpcr: {:08x}\n", fpscr); jit.ClearCache(); @@ -450,36 +453,37 @@ void RunTestInstance(Dynarmic::A32::Jit& jit, jit.Run(); } - fmt::print("final_regs:"); - for (u32 i : jit.Regs()) { - fmt::print(" {:08x}", i); + if (show_disas) { + fmt::print("final_regs:"); + for (u32 i : jit.Regs()) { + fmt::print(" {:08x}", i); + } + fmt::print("\n"); + fmt::print("final_vecs:"); + for (u32 i : jit.ExtRegs()) { + fmt::print(" {:08x}", i); + } + fmt::print("\n"); + fmt::print("final_cpsr: {:08x}\n", jit.Cpsr()); + fmt::print("final_fpsr: {:08x}\n", mask_fpsr_cum_bits ? jit.Fpscr() & 0xffffff00 : jit.Fpscr()); + fmt::print("mod_mem: "); + for (auto [addr, value] : jit_env.modified_memory) { + fmt::print("{:08x}:{:02x} ", addr, value); + } + fmt::print("\n"); + fmt::print("interrupts:\n"); + for (const auto& i : jit_env.interrupts) { + std::puts(i.c_str()); + } + fmt::print("===\n"); + jit.DumpDisassembly(); } - fmt::print("\n"); - fmt::print("final_vecs:"); - for (u32 i : jit.ExtRegs()) { - fmt::print(" {:08x}", i); - } - fmt::print("\n"); - fmt::print("final_cpsr: {:08x}\n", jit.Cpsr()); - fmt::print("final_fpsr: {:08x}\n", mask_fpsr_cum_bits ? jit.Fpscr() & 0xffffff00 : jit.Fpscr()); - - fmt::print("mod_mem: "); - for (auto [addr, value] : jit_env.modified_memory) { - fmt::print("{:08x}:{:02x} ", addr, value); - } - fmt::print("\n"); - - fmt::print("interrupts:\n"); - for (const auto& i : jit_env.interrupts) { - std::puts(i.c_str()); - } - - fmt::print("===\n"); } Dynarmic::A64::UserConfig GetA64UserConfig(A64TestEnv& jit_env, bool noopt) { - Dynarmic::A64::UserConfig jit_user_config{&jit_env}; - jit_user_config.optimizations &= ~OptimizationFlag::FastDispatch; + Dynarmic::A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &jit_env; + jit_user_config.optimizations = all_safe_optimizations; // The below corresponds to the settings for qemu's aarch64_max_initfn jit_user_config.dczid_el0 = 7; jit_user_config.ctr_el0 = 0x80038003; @@ -491,15 +495,16 @@ Dynarmic::A64::UserConfig GetA64UserConfig(A64TestEnv& jit_env, bool noopt) { template void RunTestInstance(Dynarmic::A64::Jit& jit, - A64TestEnv& jit_env, - const std::array& regs, - const std::array, 32>& vecs, - const std::vector& instructions, - const u32 pstate, - const u32 fpcr, - const u64 initial_sp, - const u64 start_address, - const size_t ticks_left) { + A64TestEnv& jit_env, + const std::array& regs, + const std::array, 32>& vecs, + const std::vector& instructions, + const u32 pstate, + const u32 fpcr, + const u64 initial_sp, + const u64 start_address, + const size_t ticks_left, + const bool show_disas) { jit.ClearCache(); for (size_t jit_rerun_count = 0; jit_rerun_count < num_jit_reruns; ++jit_rerun_count) { @@ -522,59 +527,53 @@ void RunTestInstance(Dynarmic::A64::Jit& jit, jit.Run(); } - fmt::print("instructions:"); - for (u32 instruction : instructions) { - fmt::print(" {:08x}", instruction); - } - fmt::print("\n"); + if (show_disas) { + fmt::print("instructions:\n"); + auto current_pc = start_address; + for (u32 instruction : instructions) { + fmt::print("{}", Dynarmic::Common::DisassembleAArch64(instruction, current_pc)); + current_pc += 4; + } - fmt::print("initial_regs:"); - for (u64 i : regs) { - fmt::print(" {:016x}", i); + fmt::print("initial_regs:"); + for (u64 i : regs) + fmt::print(" {:016x}", i); + fmt::print("\n"); + fmt::print("initial_vecs:"); + for (auto i : vecs) + fmt::print(" {:016x}:{:016x}", i[0], i[1]); + fmt::print("\n"); + fmt::print("initial_sp: {:016x}\n", initial_sp); + fmt::print("initial_pstate: {:08x}\n", pstate); + fmt::print("initial_fpcr: {:08x}\n", fpcr); + fmt::print("final_regs:"); + for (u64 i : jit.GetRegisters()) + fmt::print(" {:016x}", i); + fmt::print("\n"); + fmt::print("final_vecs:"); + for (auto i : jit.GetVectors()) + fmt::print(" {:016x}:{:016x}", i[0], i[1]); + fmt::print("\n"); + fmt::print("final_sp: {:016x}\n", jit.GetSP()); + fmt::print("final_pc: {:016x}\n", jit.GetPC()); + fmt::print("final_pstate: {:08x}\n", jit.GetPstate()); + fmt::print("final_fpcr: {:08x}\n", jit.GetFpcr()); + fmt::print("final_qc : {}\n", FP::FPSR{jit.GetFpsr()}.QC()); + fmt::print("mod_mem:"); + for (auto [addr, value] : jit_env.modified_memory) + fmt::print(" {:08x}:{:02x}", addr, value); + fmt::print("\n"); + fmt::print("interrupts:\n"); + for (const auto& i : jit_env.interrupts) + std::puts(i.c_str()); + fmt::print("===\n"); + jit.DumpDisassembly(); } - fmt::print("\n"); - fmt::print("initial_vecs:"); - for (auto i : vecs) { - fmt::print(" {:016x}:{:016x}", i[0], i[1]); - } - fmt::print("\n"); - fmt::print("initial_sp: {:016x}\n", initial_sp); - fmt::print("initial_pstate: {:08x}\n", pstate); - fmt::print("initial_fpcr: {:08x}\n", fpcr); - - fmt::print("final_regs:"); - for (u64 i : jit.GetRegisters()) { - fmt::print(" {:016x}", i); - } - fmt::print("\n"); - fmt::print("final_vecs:"); - for (auto i : jit.GetVectors()) { - fmt::print(" {:016x}:{:016x}", i[0], i[1]); - } - fmt::print("\n"); - fmt::print("final_sp: {:016x}\n", jit.GetSP()); - fmt::print("final_pc: {:016x}\n", jit.GetPC()); - fmt::print("final_pstate: {:08x}\n", jit.GetPstate()); - fmt::print("final_fpcr: {:08x}\n", jit.GetFpcr()); - fmt::print("final_qc : {}\n", FP::FPSR{jit.GetFpsr()}.QC()); - - fmt::print("mod_mem:"); - for (auto [addr, value] : jit_env.modified_memory) { - fmt::print(" {:08x}:{:02x}", addr, value); - } - fmt::print("\n"); - - fmt::print("interrupts:\n"); - for (const auto& i : jit_env.interrupts) { - std::puts(i.c_str()); - } - - fmt::print("===\n"); } } // Anonymous namespace -void TestThumb(size_t num_instructions, size_t num_iterations, bool noopt) { +void TestThumb(size_t num_instructions, size_t num_iterations, bool noopt, bool show_disas) { ThumbTestEnv jit_env{}; Dynarmic::A32::Jit jit{GetA32UserConfig(jit_env, noopt)}; @@ -597,11 +596,11 @@ void TestThumb(size_t num_instructions, size_t num_iterations, bool noopt) { } regs[15] = start_address; - RunTestInstance(jit, jit_env, regs, ext_reg, instructions, cpsr, fpcr, num_instructions); + RunTestInstance(jit, jit_env, regs, ext_reg, instructions, cpsr, fpcr, num_instructions, show_disas); } } -void TestArm(size_t num_instructions, size_t num_iterations, bool noopt) { +void TestArm(size_t num_instructions, size_t num_iterations, bool noopt, bool show_disas) { ArmTestEnv jit_env{}; Dynarmic::A32::Jit jit{GetA32UserConfig(jit_env, noopt)}; @@ -623,11 +622,11 @@ void TestArm(size_t num_instructions, size_t num_iterations, bool noopt) { } regs[15] = start_address; - RunTestInstance(jit, jit_env, regs, ext_reg, instructions, cpsr, fpcr, num_instructions); + RunTestInstance(jit, jit_env, regs, ext_reg, instructions, cpsr, fpcr, num_instructions, show_disas); } } -void TestA64(size_t num_instructions, size_t num_iterations, bool noopt) { +void TestA64(size_t num_instructions, size_t num_iterations, bool noopt, bool show_disas) { A64TestEnv jit_env{}; Dynarmic::A64::Jit jit{GetA64UserConfig(jit_env, noopt)}; @@ -649,7 +648,7 @@ void TestA64(size_t num_instructions, size_t num_iterations, bool noopt) { instructions.emplace_back(GenRandomA64Inst(static_cast(start_address + 4 * instructions.size()), i == num_instructions - 1)); } - RunTestInstance(jit, jit_env, regs, vecs, instructions, pstate, fpcr, initial_sp, start_address, num_instructions); + RunTestInstance(jit, jit_env, regs, vecs, instructions, pstate, fpcr, initial_sp, start_address, num_instructions, show_disas); } } @@ -677,6 +676,7 @@ int main(int argc, char* argv[]) { const auto instruction_count = str2sz(argv[3]); const auto iterator_count = str2sz(argv[4]); const bool noopt = argc == 6 && (strcmp(argv[5], "noopt") == 0); + const bool show_disas = argc == 6 && (strcmp(argv[5], "disas") == 0); if (!seed || !instruction_count || !iterator_count) { fmt::print("invalid numeric arguments\n"); @@ -686,11 +686,11 @@ int main(int argc, char* argv[]) { detail::g_rand_int_generator.seed(static_cast(*seed)); if (strcmp(argv[1], "thumb") == 0) { - TestThumb(*instruction_count, *iterator_count, noopt); + TestThumb(*instruction_count, *iterator_count, noopt, show_disas); } else if (strcmp(argv[1], "arm") == 0) { - TestArm(*instruction_count, *iterator_count, noopt); + TestArm(*instruction_count, *iterator_count, noopt, show_disas); } else if (strcmp(argv[1], "a64") == 0) { - TestA64(*instruction_count, *iterator_count, noopt); + TestA64(*instruction_count, *iterator_count, noopt, show_disas); } else { fmt::print("unrecognized instruction class\n"); return 1; diff --git a/externals/dynarmic/tests/test_reader.cpp b/externals/dynarmic/tests/test_reader.cpp index 44d6e966ea..211d26adda 100644 --- a/externals/dynarmic/tests/test_reader.cpp +++ b/externals/dynarmic/tests/test_reader.cpp @@ -158,7 +158,8 @@ void RunTestInstance(Dynarmic::A32::Jit& jit, } A64::UserConfig GetA64UserConfig(A64TestEnv& jit_env, bool noopt) { - A64::UserConfig jit_user_config{&jit_env}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &jit_env; jit_user_config.optimizations &= ~OptimizationFlag::FastDispatch; // The below corresponds to the settings for qemu's aarch64_max_initfn jit_user_config.dczid_el0 = 7; diff --git a/src/audio_core/sink/cubeb_sink.cpp b/src/audio_core/sink/cubeb_sink.cpp index 49efae8e3e..7f4b1c365a 100644 --- a/src/audio_core/sink/cubeb_sink.cpp +++ b/src/audio_core/sink/cubeb_sink.cpp @@ -208,7 +208,7 @@ CubebSink::CubebSink(std::string_view target_device_name) { com_init_result = CoInitializeEx(nullptr, COINIT_MULTITHREADED); #endif - if (cubeb_init(&ctx, "yuzu", nullptr) != CUBEB_OK) { + if (cubeb_init(&ctx, "Eden", nullptr) != CUBEB_OK) { LOG_CRITICAL(Audio_Sink, "cubeb_init failed"); return; } @@ -304,7 +304,7 @@ std::vector ListCubebSinkDevices(bool capture) { auto com_init_result = CoInitializeEx(nullptr, COINIT_MULTITHREADED); #endif - if (cubeb_init(&ctx, "yuzu Device Enumerator", nullptr) != CUBEB_OK) { + if (cubeb_init(&ctx, "Eden Device Enumerator", nullptr) != CUBEB_OK) { LOG_CRITICAL(Audio_Sink, "cubeb_init failed"); return {}; } @@ -352,7 +352,7 @@ bool IsCubebSuitable() { #endif // Init cubeb - if (cubeb_init(&ctx, "yuzu Latency Getter", nullptr) != CUBEB_OK) { + if (cubeb_init(&ctx, "Eden Latency Getter", nullptr) != CUBEB_OK) { LOG_ERROR(Audio_Sink, "Cubeb failed to init, it is not suitable."); return false; } @@ -386,7 +386,7 @@ bool IsCubebSuitable() { // Test opening a device with standard parameters cubeb_devid output_device{0}; cubeb_devid input_device{0}; - std::string name{"Yuzu test"}; + std::string name{"Eden test"}; cubeb_stream* stream{nullptr}; if (cubeb_stream_init(ctx, &stream, name.c_str(), input_device, nullptr, output_device, ¶ms, diff --git a/src/common/settings.cpp b/src/common/settings.cpp index f66c24455f..63d46722ea 100644 --- a/src/common/settings.cpp +++ b/src/common/settings.cpp @@ -118,7 +118,7 @@ void LogSettings() { LOG_INFO(Config, "{}: {}", name, Common::FS::PathToUTF8String(path)); }; - LOG_INFO(Config, "yuzu Configuration:"); + LOG_INFO(Config, "Eden Configuration:"); for (auto& [category, settings] : values.linkage.by_category) { for (const auto& setting : settings) { if (setting->Id() == values.eden_token.Id()) { diff --git a/src/common/settings.h b/src/common/settings.h index 551e66c57e..1bf460c8b0 100644 --- a/src/common/settings.h +++ b/src/common/settings.h @@ -564,7 +564,7 @@ struct Values { linkage, 0, "rng_seed", Category::System, Specialization::Hex, true, true, &rng_seed_enabled}; Setting device_name{ - linkage, "eden", "device_name", Category::System, Specialization::Default, true, true}; + linkage, "Eden", "device_name", Category::System, Specialization::Default, true, true}; Setting current_user{linkage, 0, "current_user", Category::System}; diff --git a/src/common/uuid.h b/src/common/uuid.h index 81bfefbbbe..60c5d75f12 100644 --- a/src/common/uuid.h +++ b/src/common/uuid.h @@ -76,13 +76,13 @@ struct UUID { u128 AsU128() const; /** - * Creates a default UUID "yuzu Default UID". + * Creates a default UUID "Eden Default UID". * - * @returns A UUID with its bytes set to the ASCII values of "yuzu Default UID". + * @returns A UUID with its bytes set to the ASCII values of "Eden Default UID". */ static constexpr UUID MakeDefault() { return UUID{ - {'y', 'u', 'z', 'u', ' ', 'D', 'e', 'f', 'a', 'u', 'l', 't', ' ', 'U', 'I', 'D'}, + {'E', 'd', 'e', 'n', ' ', 'D', 'e', 'f', 'a', 'u', 'l', 't', ' ', 'U', 'I', 'D'}, }; } diff --git a/src/core/frontend/applets/software_keyboard.cpp b/src/core/frontend/applets/software_keyboard.cpp index d00da8ac9e..bd0ec64f47 100644 --- a/src/core/frontend/applets/software_keyboard.cpp +++ b/src/core/frontend/applets/software_keyboard.cpp @@ -65,7 +65,7 @@ void DefaultSoftwareKeyboardApplet::ShowNormalKeyboard() const { LOG_WARNING(Service_AM, "(STUBBED) called, backend requested to show the normal software keyboard."); - SubmitNormalText(u"yuzu"); + SubmitNormalText(u"Eden"); } void DefaultSoftwareKeyboardApplet::ShowTextCheckDialog( @@ -100,7 +100,7 @@ void DefaultSoftwareKeyboardApplet::ShowInlineKeyboard( appear_parameters.key_top_as_floating, appear_parameters.enable_backspace_button, appear_parameters.enable_return_button, appear_parameters.disable_cancel_button); - std::thread([this] { SubmitInlineText(u"yuzu"); }).detach(); + std::thread([this] { SubmitInlineText(u"Eden"); }).detach(); } void DefaultSoftwareKeyboardApplet::HideInlineKeyboard() const { diff --git a/src/core/hle/service/acc/acc.cpp b/src/core/hle/service/acc/acc.cpp index 4562217d5e..51a542e5e6 100644 --- a/src/core/hle/service/acc/acc.cpp +++ b/src/core/hle/service/acc/acc.cpp @@ -969,7 +969,7 @@ void Module::Interface::InitializeApplicationInfoV2(HLERequestContext& ctx) { void Module::Interface::BeginUserRegistration(HLERequestContext& ctx) { const auto user_id = Common::UUID::MakeRandom(); - profile_manager->CreateNewUser(user_id, "yuzu"); + profile_manager->CreateNewUser(user_id, "Eden"); LOG_INFO(Service_ACC, "called, uuid={}", user_id.FormattedString()); diff --git a/src/core/hle/service/acc/profile_manager.cpp b/src/core/hle/service/acc/profile_manager.cpp index 80a2b0b72b..b4cc35b5c0 100644 --- a/src/core/hle/service/acc/profile_manager.cpp +++ b/src/core/hle/service/acc/profile_manager.cpp @@ -49,7 +49,7 @@ ProfileManager::ProfileManager() { // Create an user if none are present if (user_count == 0) { - CreateNewUser(UUID::MakeRandom(), "eden"); + CreateNewUser(UUID::MakeRandom(), "Eden"); WriteUserSaveFile(); } diff --git a/src/dedicated_room/yuzu_room.cpp b/src/dedicated_room/yuzu_room.cpp index 156bff62dc..880431fa85 100644 --- a/src/dedicated_room/yuzu_room.cpp +++ b/src/dedicated_room/yuzu_room.cpp @@ -68,14 +68,13 @@ static void PrintHelp(const char* argv0) { "-a, --web-api-url yuzu Web API url\n" "-b, --ban-list-file The file for storing the room ban list\n" "-l, --log-file The file for storing the room log\n" - "-e, --enable-mods Allow Community Moderators to moderate on your room\n" "-h, --help Display this help and exit\n" "-v, --version Output version information and exit\n", argv0); } static void PrintVersion() { - LOG_INFO(Network, "yuzu dedicated room {} {} Libnetwork: {}", Common::g_scm_branch, + LOG_INFO(Network, "Eden dedicated room {} {} Libnetwork: {}", Common::g_scm_branch, Common::g_scm_desc, Network::network_version); } @@ -229,7 +228,6 @@ void LaunchRoom(int argc, char** argv, bool called_by_option) {"web-api-url", required_argument, 0, 'a'}, {"ban-list-file", required_argument, 0, 'b'}, {"log-file", required_argument, 0, 'l'}, - {"enable-mods", no_argument, 0, 'e'}, {"help", no_argument, 0, 'h'}, {"version", no_argument, 0, 'v'}, // Entry option @@ -369,7 +367,7 @@ void LaunchRoom(int argc, char** argv, bool called_by_option) std::make_unique(Settings::values.web_api_url.GetValue()); #else LOG_INFO(Network, - "yuzu Web Services is not available with this build: validation is disabled."); + "Eden Web Services is not available with this build: validation is disabled."); verify_backend = std::make_unique(); #endif } else { diff --git a/src/input_common/drivers/sdl_driver.cpp b/src/input_common/drivers/sdl_driver.cpp index 78f458afe3..ef898527ec 100644 --- a/src/input_common/drivers/sdl_driver.cpp +++ b/src/input_common/drivers/sdl_driver.cpp @@ -489,7 +489,7 @@ void SDLDriver::CloseJoysticks() { SDLDriver::SDLDriver(std::string input_engine_) : InputEngine(std::move(input_engine_)) { // Set our application name. Currently passed to DBus by SDL and visible to the user through // their desktop environment. - SDL_SetHint(SDL_HINT_APP_NAME, "yuzu"); + SDL_SetHint(SDL_HINT_APP_NAME, "Eden"); if (!Settings::values.enable_raw_input) { // Disable raw input. When enabled this setting causes SDL to die when a web applet opens diff --git a/src/video_core/fence_manager.h b/src/video_core/fence_manager.h index 2135f1f2da..a2411af63c 100644 --- a/src/video_core/fence_manager.h +++ b/src/video_core/fence_manager.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -73,15 +76,27 @@ public: void SignalFence(std::function&& func) { bool delay_fence = Settings::IsGPULevelHigh(); + #ifdef __ANDROID__ + if (!delay_fence) { + TryReleasePendingFences(); + } + #else if constexpr (!can_async_check) { TryReleasePendingFences(); } + #endif const bool should_flush = ShouldFlush(); CommitAsyncFlushes(); TFence new_fence = CreateFence(!should_flush); + #ifdef __ANDROID__ + if (delay_fence) { + guard.lock(); + } + #else if constexpr (can_async_check) { guard.lock(); } + #endif if (delay_fence) { uncommitted_operations.emplace_back(std::move(func)); } @@ -94,10 +109,17 @@ public: if (should_flush) { rasterizer.FlushCommands(); } + #ifdef __ANDROID__ + if (delay_fence) { + guard.unlock(); + cv.notify_all(); + } + #else if constexpr (can_async_check) { guard.unlock(); cv.notify_all(); } + #endif rasterizer.InvalidateGPUCache(); } diff --git a/src/video_core/vulkan_common/nsight_aftermath_tracker.cpp b/src/video_core/vulkan_common/nsight_aftermath_tracker.cpp index a185f0a52b..9d57e3635f 100644 --- a/src/video_core/vulkan_common/nsight_aftermath_tracker.cpp +++ b/src/video_core/vulkan_common/nsight_aftermath_tracker.cpp @@ -186,7 +186,7 @@ void NsightAftermathTracker::OnShaderDebugInfoCallback(const void* shader_debug_ void NsightAftermathTracker::OnCrashDumpDescriptionCallback( PFN_GFSDK_Aftermath_AddGpuCrashDumpDescription add_description) { - add_description(GFSDK_Aftermath_GpuCrashDumpDescriptionKey_ApplicationName, "yuzu"); + add_description(GFSDK_Aftermath_GpuCrashDumpDescriptionKey_ApplicationName, "Eden"); } void NsightAftermathTracker::GpuCrashDumpCallback(const void* gpu_crash_dump, diff --git a/src/video_core/vulkan_common/vulkan_wrapper.cpp b/src/video_core/vulkan_common/vulkan_wrapper.cpp index 0caf415212..c703abe40e 100644 --- a/src/video_core/vulkan_common/vulkan_wrapper.cpp +++ b/src/video_core/vulkan_common/vulkan_wrapper.cpp @@ -437,9 +437,9 @@ Instance Instance::Create(u32 version, Span layers, Span - <html><head/><body><p><span style=" font-size:28pt;">eden</span></p></body></html> + <html><head/><body><p><span style=" font-size:28pt;">Eden</span></p></body></html> @@ -101,8 +101,8 @@ p, li { white-space: pre-wrap; } hr { height: 1px; border-width: 0; } li.unchecked::marker { content: "\2610"; } li.checked::marker { content: "\2612"; } -</style></head><body style=" font-family:'Adwaita Sans'; font-size:11pt; font-weight:400; font-style:normal;"> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-size:12pt;">eden is an experimental open-source emulator for the Nintendo Switch licensed under GPLv3.0+ which is based on the yuzu emulator which ended development back in March 2024. <br /><br />This software should not be used to play games you have not legally obtained.</span></p></body></html> +</style></head><body style=" font-family:'Noto Sans'; font-size:9pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-size:12pt;">Eden is an experimental open-source emulator for the Nintendo Switch licensed under GPLv3.0+ which is based on the yuzu emulator which ended development back in March 2024. <br /><br />This software should not be used to play games you have not legally obtained.</span></p></body></html> Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignVCenter @@ -165,7 +165,6 @@ li.checked::marker { content: "\2612"; } - diff --git a/src/yuzu/bootmanager.cpp b/src/yuzu/bootmanager.cpp index d14c46af86..6852193b1b 100644 --- a/src/yuzu/bootmanager.cpp +++ b/src/yuzu/bootmanager.cpp @@ -286,7 +286,7 @@ GRenderWindow::GRenderWindow(GMainWindow* parent, EmuThread* emu_thread_, Core::System& system_) : QWidget(parent), emu_thread(emu_thread_), input_subsystem{std::move(input_subsystem_)}, system{system_} { - setWindowTitle(QStringLiteral("eden %1 | %2-%3") + setWindowTitle(QStringLiteral("Eden %1 | %2-%3") .arg(QString::fromUtf8(Common::g_build_name), QString::fromUtf8(Common::g_scm_branch), QString::fromUtf8(Common::g_scm_desc))); @@ -1034,7 +1034,7 @@ bool GRenderWindow::InitializeOpenGL() { return true; #else QMessageBox::warning(this, tr("OpenGL not available!"), - tr("eden has not been compiled with OpenGL support.")); + tr("Eden has not been compiled with OpenGL support.")); return false; #endif } diff --git a/src/yuzu/configuration/configure_debug.ui b/src/yuzu/configuration/configure_debug.ui index 5408d485b4..bd7125712c 100644 --- a/src/yuzu/configuration/configure_debug.ui +++ b/src/yuzu/configuration/configure_debug.ui @@ -560,7 +560,7 @@ - **This will be reset automatically when eden closes. + **This will be reset automatically when Eden closes. 20 diff --git a/src/yuzu/configuration/configure_general.cpp b/src/yuzu/configuration/configure_general.cpp index 30e5f08d67..918fa15d4d 100644 --- a/src/yuzu/configuration/configure_general.cpp +++ b/src/yuzu/configuration/configure_general.cpp @@ -96,7 +96,7 @@ void ConfigureGeneral::SetResetCallback(std::function callback) { void ConfigureGeneral::ResetDefaults() { QMessageBox::StandardButton answer = QMessageBox::question( - this, tr("eden"), + this, tr("Eden"), tr("This reset all settings and remove all per-game configurations. This will not delete " "game directories, profiles, or input profiles. Proceed?"), QMessageBox::Yes | QMessageBox::No, QMessageBox::No); diff --git a/src/yuzu/configuration/configure_input_advanced.ui b/src/yuzu/configuration/configure_input_advanced.ui index 2bdd137b08..f489d93965 100644 --- a/src/yuzu/configuration/configure_input_advanced.ui +++ b/src/yuzu/configuration/configure_input_advanced.ui @@ -2656,7 +2656,7 @@ - Requires restarting eden + Requires restarting Eden @@ -2698,7 +2698,7 @@ - Requires restarting eden + Requires restarting Eden @@ -2714,7 +2714,7 @@ - Requires restarting eden + Requires restarting Eden diff --git a/src/yuzu/configuration/configure_motion_touch.cpp b/src/yuzu/configuration/configure_motion_touch.cpp index 7a1cee463b..e6d7d58299 100644 --- a/src/yuzu/configuration/configure_motion_touch.cpp +++ b/src/yuzu/configuration/configure_motion_touch.cpp @@ -170,27 +170,27 @@ void ConfigureMotionTouch::OnUDPAddServer() { const int row = udp_server_list_model->rowCount(); if (!ok) { - QMessageBox::warning(this, tr("eden"), tr("Port number has invalid characters")); + QMessageBox::warning(this, tr("Eden"), tr("Port number has invalid characters")); return; } if (port_number < 0 || port_number > 65353) { - QMessageBox::warning(this, tr("eden"), tr("Port has to be in range 0 and 65353")); + QMessageBox::warning(this, tr("Eden"), tr("Port has to be in range 0 and 65353")); return; } if (!re.match(server_text).hasMatch()) { - QMessageBox::warning(this, tr("eden"), tr("IP address is not valid")); + QMessageBox::warning(this, tr("Eden"), tr("IP address is not valid")); return; } // Search for duplicates for (const auto& item : udp_server_list_model->stringList()) { if (item == server_string) { - QMessageBox::warning(this, tr("eden"), tr("This UDP server already exists")); + QMessageBox::warning(this, tr("Eden"), tr("This UDP server already exists")); return; } } // Limit server count to 8 if (row == 8) { - QMessageBox::warning(this, tr("eden"), tr("Unable to add more than 8 servers")); + QMessageBox::warning(this, tr("Eden"), tr("Unable to add more than 8 servers")); return; } @@ -284,7 +284,7 @@ void ConfigureMotionTouch::OnConfigureTouchFromButton() { bool ConfigureMotionTouch::CanCloseDialog() { if (udp_test_in_progress) { - QMessageBox::warning(this, tr("eden"), + QMessageBox::warning(this, tr("Eden"), tr("UDP Test or calibration configuration is in progress.
Please " "wait for them to finish.")); return false; diff --git a/src/yuzu/configuration/configure_tas.ui b/src/yuzu/configuration/configure_tas.ui index d24f54b77b..b0d0a39d8b 100644 --- a/src/yuzu/configuration/configure_tas.ui +++ b/src/yuzu/configuration/configure_tas.ui @@ -14,7 +14,7 @@ - <html><head/><body><p>Reads controller input from scripts in the same format as TAS-nx scripts.<br/>For a more detailed explanation, please consult the <a href="https://eden-emulator.github.io/help/feature/tas/"><span style=" text-decoration: underline; color:#039be5;">help page</span></a> on the eden website.</p></body></html> + <html><head/><body><p>Reads controller input from scripts in the same format as TAS-nx scripts.<br/>For a more detailed explanation, please consult the <a href="https://eden-emulator.github.io/help/feature/tas/"><span style=" text-decoration: underline; color:#039be5;">help page</span></a> on the Eden website.</p></body></html> true diff --git a/src/yuzu/configuration/configure_touchscreen_advanced.ui b/src/yuzu/configuration/configure_touchscreen_advanced.ui index 6dce2e0097..afedfdc70d 100644 --- a/src/yuzu/configuration/configure_touchscreen_advanced.ui +++ b/src/yuzu/configuration/configure_touchscreen_advanced.ui @@ -23,7 +23,7 @@
- Warning: The settings in this page affect the inner workings of eden's emulated touchscreen. Changing them may result in undesirable behavior, such as the touchscreen partially or not working. You should only use this page if you know what you are doing. + Warning: The settings in this page affect the inner workings of Eden's emulated touchscreen. Changing them may result in undesirable behavior, such as the touchscreen partially or not working. You should only use this page if you know what you are doing. true diff --git a/src/yuzu/configuration/configure_web.ui b/src/yuzu/configuration/configure_web.ui index d440fd0409..964c6a245f 100644 --- a/src/yuzu/configuration/configure_web.ui +++ b/src/yuzu/configuration/configure_web.ui @@ -22,7 +22,7 @@ - eden Web Service + Eden Web Service diff --git a/src/yuzu/configuration/shared_translation.cpp b/src/yuzu/configuration/shared_translation.cpp index c743e65ae3..770a16a481 100644 --- a/src/yuzu/configuration/shared_translation.cpp +++ b/src/yuzu/configuration/shared_translation.cpp @@ -420,12 +420,12 @@ std::unique_ptr InitializeTranslations(QWidget* parent) INSERT(UISettings, select_user_on_boot, tr("Prompt for user on game boot"), - tr("Ask to select a user profile on each boot, useful if multiple people use eden on " + tr("Ask to select a user profile on each boot, useful if multiple people use Eden on " "the same PC.")); INSERT(UISettings, pause_when_in_background, tr("Pause emulation when in background"), - tr("This setting pauses eden when focusing other windows.")); + tr("This setting pauses Eden when focusing other windows.")); INSERT(UISettings, confirm_before_stopping, tr("Confirm before stopping emulation"), diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index 8e3082a58e..6b2608375c 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -390,13 +390,13 @@ GMainWindow::GMainWindow(bool has_broken_vulkan) const auto description = std::string(Common::g_scm_desc); const auto build_id = std::string(Common::g_build_id); - const auto yuzu_build = fmt::format("eden Development Build | {}-{}", branch_name, description); + const auto yuzu_build = fmt::format("Eden Development Build | {}-{}", branch_name, description); const auto override_build = fmt::format(fmt::runtime(std::string(Common::g_title_bar_format_idle)), build_id); const auto yuzu_build_version = override_build.empty() ? yuzu_build : override_build; const auto processor_count = std::thread::hardware_concurrency(); - LOG_INFO(Frontend, "eden Version: {}", yuzu_build_version); + LOG_INFO(Frontend, "Eden Version: {}", yuzu_build_version); LogRuntimes(); #ifdef ARCHITECTURE_x86_64 const auto& caps = Common::GetCPUCaps(); @@ -1410,7 +1410,7 @@ void GMainWindow::InitializeHotkeys() { LinkActionShortcut(ui->action_Load_File, QStringLiteral("Load File")); LinkActionShortcut(ui->action_Load_Amiibo, QStringLiteral("Load/Remove Amiibo")); - LinkActionShortcut(ui->action_Exit, QStringLiteral("Exit eden")); + LinkActionShortcut(ui->action_Exit, QStringLiteral("Exit Eden")); LinkActionShortcut(ui->action_Restart, QStringLiteral("Restart Emulation")); LinkActionShortcut(ui->action_Pause, QStringLiteral("Continue/Pause Emulation")); LinkActionShortcut(ui->action_Stop, QStringLiteral("Stop Emulation")); @@ -1969,7 +1969,7 @@ bool GMainWindow::LoadROM(const QString& filename, Service::AM::FrontendAppletPa tr("You are using the deconstructed ROM directory format for this game, which is an " "outdated format that has been superseded by others such as NCA, NAX, XCI, or " "NSP. Deconstructed ROM directories lack icons, metadata, and update " - "support.

For an explanation of the various Switch formats eden supports,
For an explanation of the various Switch formats Eden supports,
check out our " "wiki. This message will not be shown again.")); } @@ -1984,7 +1984,7 @@ bool GMainWindow::LoadROM(const QString& filename, Service::AM::FrontendAppletPa case Core::SystemResultStatus::ErrorVideoCore: QMessageBox::critical( this, tr("An error occurred initializing the video core."), - tr("eden has encountered an error while running the video core. " + tr("Eden has encountered an error while running the video core. " "This is usually caused by outdated GPU drivers, including integrated ones. " "Please see the log for more details. " "For more information on accessing the log, please see the following page: " @@ -2076,7 +2076,7 @@ void GMainWindow::ConfigureFilesystemProvider(const std::string& filepath) { void GMainWindow::BootGame(const QString& filename, Service::AM::FrontendAppletParameters params, StartGameType type) { - LOG_INFO(Frontend, "eden starting..."); + LOG_INFO(Frontend, "Eden starting..."); if (params.program_id == 0 || params.program_id > static_cast(Service::AM::AppletProgramId::MaxProgramId)) { @@ -3621,8 +3621,8 @@ void GMainWindow::OnMenuReportCompatibility() { } else { QMessageBox::critical( this, tr("Missing yuzu Account"), - tr("In order to submit a game compatibility test case, you must link your eden " - "account.

To link your eden account, go to Emulation > Configuration " + tr("In order to submit a game compatibility test case, you must set up your web token and " + "username.

To link your eden account, go to Emulation > Configuration " "> " "Web.")); } @@ -3650,7 +3650,7 @@ void GMainWindow::OnOpenQuickstartGuide() { } void GMainWindow::OnOpenFAQ() { - OpenURL(QUrl(QStringLiteral("https://eden-emulator.github.io/"))); + OpenURL(QUrl(QStringLiteral("https://eden-emu.dev"))); } void GMainWindow::OnOpenDiscord() @@ -5260,8 +5260,8 @@ bool GMainWindow::ConfirmClose() { UISettings::values.confirm_before_stopping.GetValue() == ConfirmStop::Ask_Based_On_Game) { return true; } - const auto text = tr("Are you sure you want to close eden?"); - return question(this, tr("eden"), text); + const auto text = tr("Are you sure you want to close Eden?"); + return question(this, tr("Eden"), text); } void GMainWindow::closeEvent(QCloseEvent* event) { @@ -5341,7 +5341,7 @@ bool GMainWindow::ConfirmChangeGame() { // Use custom question to link controller navigation return question( - this, tr("eden"), + this, tr("Eden"), tr("Are you sure you want to stop the emulation? Any unsaved progress will be lost."), QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes); } @@ -5350,10 +5350,10 @@ bool GMainWindow::ConfirmForceLockedExit() { if (emu_thread == nullptr) { return true; } - const auto text = tr("The currently running application has requested eden to not exit.\n\n" + const auto text = tr("The currently running application has requested Eden to not exit.\n\n" "Would you like to bypass this and exit anyway?"); - return question(this, tr("eden"), text); + return question(this, tr("Eden"), text); } void GMainWindow::RequestGameExit() { diff --git a/src/yuzu/main.ui b/src/yuzu/main.ui index 970f8d2901..bcc596cec2 100644 --- a/src/yuzu/main.ui +++ b/src/yuzu/main.ui @@ -269,7 +269,7 @@ - &About eden + &About Eden diff --git a/src/yuzu/multiplayer/host_room.cpp b/src/yuzu/multiplayer/host_room.cpp index 6471ad1632..d8e63da600 100644 --- a/src/yuzu/multiplayer/host_room.cpp +++ b/src/yuzu/multiplayer/host_room.cpp @@ -60,7 +60,7 @@ HostRoomWindow::HostRoomWindow(QWidget* parent, QStandardItemModel* list, ui->username->setText( QString::fromStdString(UISettings::values.multiplayer_room_nickname.GetValue())); if (ui->username->text().isEmpty() && !Settings::values.eden_username.GetValue().empty()) { - // Use eden Web Service user name as nickname by default + // Use Eden Web Service user name as nickname by default ui->username->setText(QString::fromStdString(Settings::values.eden_username.GetValue())); } ui->room_name->setText( @@ -186,7 +186,7 @@ void HostRoomWindow::Host() { QMessageBox::warning( this, tr("Error"), tr("Failed to announce the room to the public lobby. In order to host a " - "room publicly, you must have a valid eden account configured in " + "room publicly, you must have a valid Eden account configured in " "Emulation -> Configure -> Web. If you do not want to publish a room in " "the public lobby, then select Unlisted instead.\nDebug Message: ") + QString::fromStdString(result.result_string), diff --git a/src/yuzu/multiplayer/lobby.cpp b/src/yuzu/multiplayer/lobby.cpp index 93ff56a652..ed6ba6a15c 100644 --- a/src/yuzu/multiplayer/lobby.cpp +++ b/src/yuzu/multiplayer/lobby.cpp @@ -66,14 +66,14 @@ Lobby::Lobby(QWidget* parent, QStandardItemModel* list, QString::fromStdString(UISettings::values.multiplayer_nickname.GetValue())); // Try find the best nickname by default - if (ui->nickname->text().isEmpty() || ui->nickname->text() == QStringLiteral("eden")) { + if (ui->nickname->text().isEmpty() || ui->nickname->text() == QStringLiteral("Eden")) { if (!Settings::values.eden_username.GetValue().empty()) { ui->nickname->setText( QString::fromStdString(Settings::values.eden_username.GetValue())); } else if (!GetProfileUsername().empty()) { ui->nickname->setText(QString::fromStdString(GetProfileUsername())); } else { - ui->nickname->setText(QStringLiteral("eden")); + ui->nickname->setText(QStringLiteral("Eden")); } } diff --git a/src/yuzu/multiplayer/message.cpp b/src/yuzu/multiplayer/message.cpp index ede444a1da..10d62bcf3d 100644 --- a/src/yuzu/multiplayer/message.cpp +++ b/src/yuzu/multiplayer/message.cpp @@ -29,12 +29,12 @@ const ConnectionError ErrorManager::UNABLE_TO_CONNECT( const ConnectionError ErrorManager::ROOM_IS_FULL( QT_TR_NOOP("Unable to connect to the room because it is already full.")); const ConnectionError ErrorManager::COULD_NOT_CREATE_ROOM( - QT_TR_NOOP("Creating a room failed. Please retry. Restarting eden might be necessary.")); + QT_TR_NOOP("Creating a room failed. Please retry. Restarting Eden might be necessary.")); const ConnectionError ErrorManager::HOST_BANNED( QT_TR_NOOP("The host of the room has banned you. Speak with the host to unban you " "or try a different room.")); const ConnectionError ErrorManager::WRONG_VERSION( - QT_TR_NOOP("Version mismatch! Please update to the latest version of eden. If the problem " + QT_TR_NOOP("Version mismatch! Please update to the latest version of Eden. If the problem " "persists, contact the room host and ask them to update the server.")); const ConnectionError ErrorManager::WRONG_PASSWORD(QT_TR_NOOP("Incorrect password.")); const ConnectionError ErrorManager::GENERIC_ERROR(QT_TR_NOOP( diff --git a/src/yuzu/uisettings.h b/src/yuzu/uisettings.h index 1ec2f51f15..b713b52fcc 100644 --- a/src/yuzu/uisettings.h +++ b/src/yuzu/uisettings.h @@ -242,7 +242,7 @@ const std::array default_hotkeys{{ {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Configure Current Game")).toStdString(), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")).toStdString(), {std::string("Ctrl+."), std::string(""), Qt::WidgetWithChildrenShortcut, false}}, {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Continue/Pause Emulation")).toStdString(), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")).toStdString(), {std::string("F4"), std::string("Home+Plus"), Qt::WindowShortcut, false}}, {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Exit Fullscreen")).toStdString(), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")).toStdString(), {std::string("Esc"), std::string(""), Qt::WindowShortcut, false}}, - {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Exit eden")).toStdString(), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")).toStdString(), {std::string("Ctrl+Q"), std::string("Home+Minus"), Qt::WindowShortcut, false}}, + {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Exit Eden")).toStdString(), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")).toStdString(), {std::string("Ctrl+Q"), std::string("Home+Minus"), Qt::WindowShortcut, false}}, {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Fullscreen")).toStdString(), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")).toStdString(), {std::string("F11"), std::string("Home+B"), Qt::WindowShortcut, false}}, {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Load File")).toStdString(), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")).toStdString(), {std::string("Ctrl+O"), std::string(""), Qt::WidgetWithChildrenShortcut, false}}, {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Load/Remove Amiibo")).toStdString(), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")).toStdString(), {std::string("F2"), std::string("Home+A"), Qt::WidgetWithChildrenShortcut, false}}, diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp b/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp index 3974e4b357..41697a22e8 100644 --- a/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp +++ b/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp @@ -223,7 +223,7 @@ void EmuWindow_SDL2::WaitEvent() { const u32 current_time = SDL_GetTicks(); if (current_time > last_time + 2000) { const auto results = system.GetAndResetPerfStats(); - const auto title = fmt::format("eden {} | {}-{} | FPS: {:.0f} ({:.0f}%)", + const auto title = fmt::format("Eden {} | {}-{} | FPS: {:.0f} ({:.0f}%)", Common::g_build_fullname, Common::g_scm_branch, Common::g_scm_desc, @@ -238,7 +238,7 @@ void EmuWindow_SDL2::WaitEvent() { void EmuWindow_SDL2::SetWindowIcon() { SDL_RWops* const yuzu_icon_stream = SDL_RWFromConstMem((void*)yuzu_icon, yuzu_icon_size); if (yuzu_icon_stream == nullptr) { - LOG_WARNING(Frontend, "Failed to create eden icon stream."); + LOG_WARNING(Frontend, "Failed to create Eden icon stream."); return; } SDL_Surface* const window_icon = SDL_LoadBMP_RW(yuzu_icon_stream, 1); diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp b/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp index 2e90be35ae..4b012fe134 100644 --- a/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp +++ b/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp @@ -90,7 +90,7 @@ EmuWindow_SDL2_GL::EmuWindow_SDL2_GL(InputCommon::InputSubsystem* input_subsyste } SDL_GL_SetSwapInterval(0); - std::string window_title = fmt::format("eden {} | {}-{}", Common::g_build_fullname, + std::string window_title = fmt::format("Eden {} | {}-{}", Common::g_build_fullname, Common::g_scm_branch, Common::g_scm_desc); render_window = SDL_CreateWindow(window_title.c_str(), @@ -138,7 +138,7 @@ EmuWindow_SDL2_GL::EmuWindow_SDL2_GL(InputCommon::InputSubsystem* input_subsyste OnResize(); OnMinimalClientAreaChangeRequest(GetActiveConfig().min_client_area_size); SDL_PumpEvents(); - LOG_INFO(Frontend, "eden Version: {} | {}-{}", Common::g_build_fullname, Common::g_scm_branch, + LOG_INFO(Frontend, "Eden Version: {} | {}-{}", Common::g_build_fullname, Common::g_scm_branch, Common::g_scm_desc); Settings::LogSettings(); } diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2_null.cpp b/src/yuzu_cmd/emu_window/emu_window_sdl2_null.cpp index 043cdbf68d..506137bd8a 100644 --- a/src/yuzu_cmd/emu_window/emu_window_sdl2_null.cpp +++ b/src/yuzu_cmd/emu_window/emu_window_sdl2_null.cpp @@ -23,7 +23,7 @@ EmuWindow_SDL2_Null::EmuWindow_SDL2_Null(InputCommon::InputSubsystem* input_subsystem_, Core::System& system_, bool fullscreen) : EmuWindow_SDL2{input_subsystem_, system_} { - const std::string window_title = fmt::format("eden {} | {}-{} (Vulkan)", Common::g_build_name, + const std::string window_title = fmt::format("Eden {} | {}-{} (Vulkan)", Common::g_build_name, Common::g_scm_branch, Common::g_scm_desc); render_window = SDL_CreateWindow(window_title.c_str(), SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, @@ -40,7 +40,7 @@ EmuWindow_SDL2_Null::EmuWindow_SDL2_Null(InputCommon::InputSubsystem* input_subs OnResize(); OnMinimalClientAreaChangeRequest(GetActiveConfig().min_client_area_size); SDL_PumpEvents(); - LOG_INFO(Frontend, "eden Version: {} | {}-{} (Null)", Common::g_build_name, + LOG_INFO(Frontend, "Eden Version: {} | {}-{} (Null)", Common::g_build_name, Common::g_scm_branch, Common::g_scm_desc); } diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.cpp b/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.cpp index f4980932ed..f509652bf6 100644 --- a/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.cpp +++ b/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.cpp @@ -18,7 +18,7 @@ EmuWindow_SDL2_VK::EmuWindow_SDL2_VK(InputCommon::InputSubsystem* input_subsystem_, Core::System& system_, bool fullscreen) : EmuWindow_SDL2{input_subsystem_, system_} { - const std::string window_title = fmt::format("eden {} | {}-{} (Vulkan)", + const std::string window_title = fmt::format("Eden {} | {}-{} (Vulkan)", Common::g_build_name, Common::g_scm_branch, Common::g_scm_desc); @@ -84,7 +84,7 @@ EmuWindow_SDL2_VK::EmuWindow_SDL2_VK(InputCommon::InputSubsystem* input_subsyste OnResize(); OnMinimalClientAreaChangeRequest(GetActiveConfig().min_client_area_size); SDL_PumpEvents(); - LOG_INFO(Frontend, "eden Version: {} | {}-{} (Vulkan)", Common::g_build_name, + LOG_INFO(Frontend, "Eden Version: {} | {}-{} (Vulkan)", Common::g_build_name, Common::g_scm_branch, Common::g_scm_desc); } diff --git a/src/yuzu_cmd/yuzu.cpp b/src/yuzu_cmd/yuzu.cpp index c1d714be77..be30c2931f 100644 --- a/src/yuzu_cmd/yuzu.cpp +++ b/src/yuzu_cmd/yuzu.cpp @@ -88,7 +88,7 @@ static void PrintHelp(const char* argv0) { } static void PrintVersion() { - std::cout << "eden " << Common::g_scm_branch << " " << Common::g_scm_desc << std::endl; + std::cout << "Eden " << Common::g_scm_branch << " " << Common::g_scm_desc << std::endl; } static void OnStateChanged(const Network::RoomMember::State& state) { @@ -408,7 +408,7 @@ int main(int argc, char** argv) { const u16 error_id = static_cast(load_result) - loader_id; LOG_CRITICAL(Frontend, "While attempting to load the ROM requested, an error occurred. Please " - "refer to the eden wiki for more information or the eden discord for " + "refer to the Eden wiki for more information or the Eden discord for " "additional help.\n\nError Code: {:04X}-{:04X}\nError Description: {}", loader_id, error_id,