diff --git a/README.md b/README.md index 141cb542e..a3b201f59 100755 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ yuzu emulator early access ============= -This is the source code for early-access 2543. +This is the source code for early-access 2545. ## Legal Notice diff --git a/externals/dynarmic/src/dynarmic/CMakeLists.txt b/externals/dynarmic/src/dynarmic/CMakeLists.txt index 126b9dbad..98d11192c 100755 --- a/externals/dynarmic/src/dynarmic/CMakeLists.txt +++ b/externals/dynarmic/src/dynarmic/CMakeLists.txt @@ -98,7 +98,7 @@ add_library(dynarmic ir/type.h ir/value.cpp ir/value.h -) + ir/access_type.h) if ("A32" IN_LIST DYNARMIC_FRONTENDS) target_sources(dynarmic PRIVATE diff --git a/externals/dynarmic/src/dynarmic/backend/x64/a32_emit_x64_memory.cpp b/externals/dynarmic/src/dynarmic/backend/x64/a32_emit_x64_memory.cpp index 33f1ddfc7..82e9ae964 100755 --- a/externals/dynarmic/src/dynarmic/backend/x64/a32_emit_x64_memory.cpp +++ b/externals/dynarmic/src/dynarmic/backend/x64/a32_emit_x64_memory.cpp @@ -85,6 +85,7 @@ void A32EmitX64::GenFastmemFallbacks() { code.mov(code.ABI_PARAM2, Xbyak::Reg64{vaddr_idx}); } } + code.ZeroExtendFrom(bitsize, code.ABI_PARAM3); callback.EmitCall(code); ABI_PopCallerSaveRegistersAndAdjustStack(code); code.ret(); @@ -110,7 +111,9 @@ void A32EmitX64::GenFastmemFallbacks() { code.mov(code.ABI_PARAM2, Xbyak::Reg64{vaddr_idx}); } } + code.ZeroExtendFrom(bitsize, code.ABI_PARAM3); code.mov(code.ABI_PARAM4, rax); + code.ZeroExtendFrom(bitsize, code.ABI_PARAM4); callback.EmitCall(code); ABI_PopCallerSaveRegistersAndAdjustStackExcept(code, HostLoc::RAX); code.ret(); diff --git a/externals/dynarmic/src/dynarmic/backend/x64/a64_emit_x64_memory.cpp b/externals/dynarmic/src/dynarmic/backend/x64/a64_emit_x64_memory.cpp index 2c0e50a5d..f403bba8a 100755 --- a/externals/dynarmic/src/dynarmic/backend/x64/a64_emit_x64_memory.cpp +++ b/externals/dynarmic/src/dynarmic/backend/x64/a64_emit_x64_memory.cpp @@ -22,6 +22,7 @@ #include "dynarmic/common/spin_lock_x64.h" #include "dynarmic/common/x64_disassemble.h" #include "dynarmic/interface/exclusive_monitor.h" +#include "dynarmic/ir/access_type.h" namespace Dynarmic::Backend::X64 { @@ -227,6 +228,7 @@ void A64EmitX64::GenFastmemFallbacks() { code.mov(code.ABI_PARAM2, Xbyak::Reg64{vaddr_idx}); } } + code.ZeroExtendFrom(bitsize, code.ABI_PARAM3); callback.EmitCall(code); ABI_PopCallerSaveRegistersAndAdjustStack(code); code.ret(); @@ -252,7 +254,9 @@ void A64EmitX64::GenFastmemFallbacks() { code.mov(code.ABI_PARAM2, Xbyak::Reg64{vaddr_idx}); } } + code.ZeroExtendFrom(bitsize, code.ABI_PARAM3); code.mov(code.ABI_PARAM4, rax); + code.ZeroExtendFrom(bitsize, code.ABI_PARAM4); callback.EmitCall(code); ABI_PopCallerSaveRegistersAndAdjustStackExcept(code, HostLoc::RAX); code.ret(); @@ -438,45 +442,102 @@ Xbyak::RegExp EmitFastmemVAddr(BlockOfCode& code, A64EmitContext& ctx, Xbyak::La } template -void EmitReadMemoryMov(BlockOfCode& code, int value_idx, const Xbyak::RegExp& addr) { +const void* EmitReadMemoryMov(BlockOfCode& code, int value_idx, const Xbyak::RegExp& addr, bool ordered) { + if (ordered) { + if constexpr (bitsize == 128) { + code.mfence(); + } else { + code.xor_(Xbyak::Reg32{value_idx}, Xbyak::Reg32{value_idx}); + } + + const void* fastmem_location = code.getCurr(); + + switch (bitsize) { + case 8: + code.lock(); + code.xadd(code.byte[addr], Xbyak::Reg32{value_idx}.cvt8()); + return fastmem_location; + case 16: + code.lock(); + code.xadd(word[addr], Xbyak::Reg32{value_idx}); + return fastmem_location; + case 32: + code.lock(); + code.xadd(dword[addr], Xbyak::Reg32{value_idx}); + return fastmem_location; + case 64: + code.lock(); + code.xadd(qword[addr], Xbyak::Reg64{value_idx}); + return fastmem_location; + case 128: + code.movaps(Xbyak::Xmm{value_idx}, xword[addr]); + return fastmem_location; + default: + ASSERT_FALSE("Invalid bitsize"); + } + } + + const void* fastmem_location = code.getCurr(); + switch (bitsize) { case 8: code.movzx(Xbyak::Reg32{value_idx}, code.byte[addr]); - return; + return fastmem_location; case 16: code.movzx(Xbyak::Reg32{value_idx}, word[addr]); - return; + return fastmem_location; case 32: code.mov(Xbyak::Reg32{value_idx}, dword[addr]); - return; + return fastmem_location; case 64: code.mov(Xbyak::Reg64{value_idx}, qword[addr]); - return; + return fastmem_location; case 128: code.movups(Xbyak::Xmm{value_idx}, xword[addr]); - return; + return fastmem_location; default: ASSERT_FALSE("Invalid bitsize"); } } template -void EmitWriteMemoryMov(BlockOfCode& code, const Xbyak::RegExp& addr, int value_idx) { +void EmitWriteMemoryMov(BlockOfCode& code, const Xbyak::RegExp& addr, int value_idx, bool ordered) { switch (bitsize) { case 8: - code.mov(code.byte[addr], Xbyak::Reg64{value_idx}.cvt8()); + if (ordered) { + code.xchg(code.byte[addr], Xbyak::Reg64{value_idx}.cvt8()); + } else { + code.mov(code.byte[addr], Xbyak::Reg64{value_idx}.cvt8()); + } return; case 16: - code.mov(word[addr], Xbyak::Reg16{value_idx}); + if (ordered) { + code.xchg(word[addr], Xbyak::Reg16{value_idx}); + } else { + code.mov(word[addr], Xbyak::Reg16{value_idx}); + } return; case 32: - code.mov(dword[addr], Xbyak::Reg32{value_idx}); + if (ordered) { + code.xchg(dword[addr], Xbyak::Reg32{value_idx}); + } else { + code.mov(dword[addr], Xbyak::Reg32{value_idx}); + } return; case 64: - code.mov(qword[addr], Xbyak::Reg64{value_idx}); + if (ordered) { + code.xchg(qword[addr], Xbyak::Reg64{value_idx}); + } else { + code.mov(qword[addr], Xbyak::Reg64{value_idx}); + } return; case 128: - code.movups(xword[addr], Xbyak::Xmm{value_idx}); + if (ordered) { + code.movaps(xword[addr], Xbyak::Xmm{value_idx}); + code.mfence(); + } else { + code.movups(xword[addr], Xbyak::Xmm{value_idx}); + } return; default: ASSERT_FALSE("Invalid bitsize"); @@ -488,16 +549,24 @@ void EmitWriteMemoryMov(BlockOfCode& code, const Xbyak::RegExp& addr, int value_ template void A64EmitX64::EmitMemoryRead(A64EmitContext& ctx, IR::Inst* inst) { auto args = ctx.reg_alloc.GetArgumentInfo(inst); + const IR::AccessType acctype = args[2].GetImmediateAccType(); + const bool ordered = acctype == IR::AccessType::ORDERED || acctype == IR::AccessType::ORDEREDRW || acctype == IR::AccessType::LIMITEDORDERED; const auto fastmem_marker = ShouldFastmem(ctx, inst); if (!conf.page_table && !fastmem_marker) { // Neither fastmem nor page table: Use callbacks if constexpr (bitsize == 128) { ctx.reg_alloc.HostCall(nullptr, {}, args[0]); + if (ordered) { + code.mfence(); + } code.CallFunction(memory_read_128); ctx.reg_alloc.DefineValue(inst, xmm1); } else { ctx.reg_alloc.HostCall(inst, {}, args[0]); + if (ordered) { + code.mfence(); + } Devirtualize(conf.callbacks).EmitCall(code); code.ZeroExtendFrom(bitsize, code.ABI_RETURN); } @@ -516,8 +585,7 @@ void A64EmitX64::EmitMemoryRead(A64EmitContext& ctx, IR::Inst* inst) { // Use fastmem const auto src_ptr = EmitFastmemVAddr(code, ctx, abort, vaddr, require_abort_handling); - const auto location = code.getCurr(); - EmitReadMemoryMov(code, value_idx, src_ptr); + const auto location = EmitReadMemoryMov(code, value_idx, src_ptr, ordered); fastmem_patch_info.emplace( Common::BitCast(location), @@ -532,13 +600,16 @@ void A64EmitX64::EmitMemoryRead(A64EmitContext& ctx, IR::Inst* inst) { ASSERT(conf.page_table); const auto src_ptr = EmitVAddrLookup(code, ctx, bitsize, abort, vaddr); require_abort_handling = true; - EmitReadMemoryMov(code, value_idx, src_ptr); + EmitReadMemoryMov(code, value_idx, src_ptr, ordered); } code.L(end); if (require_abort_handling) { code.SwitchToFarCode(); code.L(abort); + if (ordered) { + code.mfence(); + } code.call(wrapped_fn); code.jmp(end, code.T_NEAR); code.SwitchToNearCode(); @@ -554,6 +625,8 @@ void A64EmitX64::EmitMemoryRead(A64EmitContext& ctx, IR::Inst* inst) { template void A64EmitX64::EmitMemoryWrite(A64EmitContext& ctx, IR::Inst* inst) { auto args = ctx.reg_alloc.GetArgumentInfo(inst); + const IR::AccessType acctype = args[2].GetImmediateAccType(); + const bool ordered = acctype == IR::AccessType::ORDERED || acctype == IR::AccessType::ORDEREDRW || acctype == IR::AccessType::LIMITEDORDERED; const auto fastmem_marker = ShouldFastmem(ctx, inst); if (!conf.page_table && !fastmem_marker) { @@ -568,11 +641,16 @@ void A64EmitX64::EmitMemoryWrite(A64EmitContext& ctx, IR::Inst* inst) { ctx.reg_alloc.HostCall(nullptr, {}, args[0], args[1]); Devirtualize(conf.callbacks).EmitCall(code); } + if (ordered) { + code.mfence(); + } return; } const Xbyak::Reg64 vaddr = ctx.reg_alloc.UseGpr(args[0]); - const int value_idx = bitsize == 128 ? ctx.reg_alloc.UseXmm(args[1]).getIdx() : ctx.reg_alloc.UseGpr(args[1]).getIdx(); + const int value_idx = bitsize == 128 + ? ctx.reg_alloc.UseXmm(args[1]).getIdx() + : (ordered ? ctx.reg_alloc.UseScratchGpr(args[1]).getIdx() : ctx.reg_alloc.UseGpr(args[1]).getIdx()); const auto wrapped_fn = write_fallbacks[std::make_tuple(bitsize, vaddr.getIdx(), value_idx)]; @@ -584,7 +662,7 @@ void A64EmitX64::EmitMemoryWrite(A64EmitContext& ctx, IR::Inst* inst) { const auto dest_ptr = EmitFastmemVAddr(code, ctx, abort, vaddr, require_abort_handling); const auto location = code.getCurr(); - EmitWriteMemoryMov(code, dest_ptr, value_idx); + EmitWriteMemoryMov(code, dest_ptr, value_idx, ordered); fastmem_patch_info.emplace( Common::BitCast(location), @@ -599,7 +677,7 @@ void A64EmitX64::EmitMemoryWrite(A64EmitContext& ctx, IR::Inst* inst) { ASSERT(conf.page_table); const auto dest_ptr = EmitVAddrLookup(code, ctx, bitsize, abort, vaddr); require_abort_handling = true; - EmitWriteMemoryMov(code, dest_ptr, value_idx); + EmitWriteMemoryMov(code, dest_ptr, value_idx, ordered); } code.L(end); @@ -607,6 +685,9 @@ void A64EmitX64::EmitMemoryWrite(A64EmitContext& ctx, IR::Inst* inst) { code.SwitchToFarCode(); code.L(abort); code.call(wrapped_fn); + if (ordered) { + code.mfence(); + } code.jmp(end, code.T_NEAR); code.SwitchToNearCode(); } @@ -656,6 +737,8 @@ template void A64EmitX64::EmitExclusiveReadMemory(A64EmitContext& ctx, IR::Inst* inst) { ASSERT(conf.global_monitor != nullptr); auto args = ctx.reg_alloc.GetArgumentInfo(inst); + const IR::AccessType acctype = args[2].GetImmediateAccType(); + const bool ordered = acctype == IR::AccessType::ORDERED || acctype == IR::AccessType::ORDEREDRW || acctype == IR::AccessType::LIMITEDORDERED; if constexpr (bitsize != 128) { using T = mp::unsigned_integer_of_size; @@ -664,6 +747,9 @@ void A64EmitX64::EmitExclusiveReadMemory(A64EmitContext& ctx, IR::Inst* inst) { code.mov(code.byte[r15 + offsetof(A64JitState, exclusive_state)], u8(1)); code.mov(code.ABI_PARAM1, reinterpret_cast(&conf)); + if (ordered) { + code.mfence(); + } code.CallLambda( [](A64::UserConfig& conf, u64 vaddr) -> T { return conf.global_monitor->ReadAndMark(conf.processor_id, vaddr, [&]() -> T { @@ -681,6 +767,9 @@ void A64EmitX64::EmitExclusiveReadMemory(A64EmitContext& ctx, IR::Inst* inst) { code.mov(code.ABI_PARAM1, reinterpret_cast(&conf)); ctx.reg_alloc.AllocStackSpace(16 + ABI_SHADOW_SPACE); code.lea(code.ABI_PARAM3, ptr[rsp + ABI_SHADOW_SPACE]); + if (ordered) { + code.mfence(); + } code.CallLambda( [](A64::UserConfig& conf, u64 vaddr, A64::Vector& ret) { ret = conf.global_monitor->ReadAndMark(conf.processor_id, vaddr, [&]() -> A64::Vector { @@ -698,6 +787,8 @@ template void A64EmitX64::EmitExclusiveWriteMemory(A64EmitContext& ctx, IR::Inst* inst) { ASSERT(conf.global_monitor != nullptr); auto args = ctx.reg_alloc.GetArgumentInfo(inst); + const IR::AccessType acctype = args[3].GetImmediateAccType(); + const bool ordered = acctype == IR::AccessType::ORDERED || acctype == IR::AccessType::ORDEREDRW || acctype == IR::AccessType::LIMITEDORDERED; if constexpr (bitsize != 128) { ctx.reg_alloc.HostCall(inst, {}, args[0], args[1]); @@ -727,6 +818,9 @@ void A64EmitX64::EmitExclusiveWriteMemory(A64EmitContext& ctx, IR::Inst* inst) { ? 0 : 1; }); + if (ordered) { + code.mfence(); + } } else { ctx.reg_alloc.AllocStackSpace(16 + ABI_SHADOW_SPACE); code.lea(code.ABI_PARAM3, ptr[rsp + ABI_SHADOW_SPACE]); @@ -740,6 +834,9 @@ void A64EmitX64::EmitExclusiveWriteMemory(A64EmitContext& ctx, IR::Inst* inst) { ? 0 : 1; }); + if (ordered) { + code.mfence(); + } ctx.reg_alloc.ReleaseStackSpace(16 + ABI_SHADOW_SPACE); } code.L(end); @@ -754,6 +851,8 @@ void A64EmitX64::EmitExclusiveReadMemoryInline(A64EmitContext& ctx, IR::Inst* in } auto args = ctx.reg_alloc.GetArgumentInfo(inst); + const IR::AccessType acctype = args[2].GetImmediateAccType(); + const bool ordered = acctype == IR::AccessType::ORDERED || acctype == IR::AccessType::ORDEREDRW || acctype == IR::AccessType::LIMITEDORDERED; const Xbyak::Reg64 vaddr = ctx.reg_alloc.UseGpr(args[0]); const int value_idx = bitsize == 128 ? ctx.reg_alloc.ScratchXmm().getIdx() : ctx.reg_alloc.ScratchGpr().getIdx(); @@ -776,7 +875,7 @@ void A64EmitX64::EmitExclusiveReadMemoryInline(A64EmitContext& ctx, IR::Inst* in const auto src_ptr = EmitFastmemVAddr(code, ctx, abort, vaddr, require_abort_handling); const auto location = code.getCurr(); - EmitReadMemoryMov(code, value_idx, src_ptr); + EmitReadMemoryMov(code, value_idx, src_ptr, ordered); fastmem_patch_info.emplace( Common::BitCast(location), @@ -801,7 +900,7 @@ void A64EmitX64::EmitExclusiveReadMemoryInline(A64EmitContext& ctx, IR::Inst* in } code.mov(tmp, Common::BitCast(GetExclusiveMonitorValuePointer(conf.global_monitor, conf.processor_id))); - EmitWriteMemoryMov(code, tmp, value_idx); + EmitWriteMemoryMov(code, tmp, value_idx, false); EmitExclusiveUnlock(code, conf, tmp, tmp2.cvt32()); @@ -821,6 +920,8 @@ void A64EmitX64::EmitExclusiveWriteMemoryInline(A64EmitContext& ctx, IR::Inst* i } auto args = ctx.reg_alloc.GetArgumentInfo(inst); + const IR::AccessType acctype = args[3].GetImmediateAccType(); + const bool ordered = acctype == IR::AccessType::ORDERED || acctype == IR::AccessType::ORDEREDRW || acctype == IR::AccessType::LIMITEDORDERED; const auto value = [&] { if constexpr (bitsize == 128) { @@ -869,7 +970,7 @@ void A64EmitX64::EmitExclusiveWriteMemoryInline(A64EmitContext& ctx, IR::Inst* i code.movq(rcx, xmm0); } } else { - EmitReadMemoryMov(code, rax.getIdx(), tmp); + EmitReadMemoryMov(code, rax.getIdx(), tmp, false); } const auto fastmem_marker = ShouldFastmem(ctx, inst); @@ -907,6 +1008,10 @@ void A64EmitX64::EmitExclusiveWriteMemoryInline(A64EmitContext& ctx, IR::Inst* i } } + if (ordered) { + code.mfence(); + } + code.setnz(status.cvt8()); code.SwitchToFarCode(); @@ -922,6 +1027,10 @@ void A64EmitX64::EmitExclusiveWriteMemoryInline(A64EmitContext& ctx, IR::Inst* i conf.recompile_on_exclusive_fastmem_failure, }); + if (ordered) { + code.mfence(); + } + code.cmp(al, 0); code.setz(status.cvt8()); code.movzx(status.cvt32(), status.cvt8()); @@ -929,6 +1038,9 @@ void A64EmitX64::EmitExclusiveWriteMemoryInline(A64EmitContext& ctx, IR::Inst* i code.SwitchToNearCode(); } else { code.call(fallback_fn); + if (ordered) { + code.mfence(); + } code.cmp(al, 0); code.setz(status.cvt8()); code.movzx(status.cvt32(), status.cvt8()); diff --git a/externals/dynarmic/src/dynarmic/backend/x64/reg_alloc.cpp b/externals/dynarmic/src/dynarmic/backend/x64/reg_alloc.cpp index 9eef81432..be45e9de1 100755 --- a/externals/dynarmic/src/dynarmic/backend/x64/reg_alloc.cpp +++ b/externals/dynarmic/src/dynarmic/backend/x64/reg_alloc.cpp @@ -207,6 +207,11 @@ IR::Cond Argument::GetImmediateCond() const { return value.GetCond(); } +IR::AccessType Argument::GetImmediateAccType() const { + ASSERT(IsImmediate() && GetType() == IR::Type::AccessType); + return value.GetAccType(); +} + bool Argument::IsInGpr() const { if (IsImmediate()) return false; @@ -410,7 +415,7 @@ void RegAlloc::HostCall(IR::Inst* result_def, for (size_t i = 0; i < args_count; i++) { if (args[i] && !args[i]->get().IsVoid()) { UseScratch(*args[i], args_hostloc[i]); -#if defined(__llvm__) && !defined(_WIN32) + // LLVM puts the burden of zero-extension of 8 and 16 bit values on the caller instead of the callee const Xbyak::Reg64 reg = HostLocToReg64(args_hostloc[i]); switch (args[i]->get().GetType()) { @@ -420,10 +425,12 @@ void RegAlloc::HostCall(IR::Inst* result_def, case IR::Type::U16: code.movzx(reg.cvt32(), reg.cvt16()); break; + case IR::Type::U32: + code.mov(reg.cvt32(), reg.cvt32()); + break; default: break; // Nothing needs to be done } -#endif } } diff --git a/externals/dynarmic/src/dynarmic/backend/x64/reg_alloc.h b/externals/dynarmic/src/dynarmic/backend/x64/reg_alloc.h index 58bfe87f3..f8c88b596 100755 --- a/externals/dynarmic/src/dynarmic/backend/x64/reg_alloc.h +++ b/externals/dynarmic/src/dynarmic/backend/x64/reg_alloc.h @@ -75,6 +75,7 @@ public: u64 GetImmediateS32() const; u64 GetImmediateU64() const; IR::Cond GetImmediateCond() const; + IR::AccessType GetImmediateAccType() const; /// Is this value currently in a GPR? bool IsInGpr() const; diff --git a/externals/dynarmic/src/dynarmic/frontend/A32/translate/impl/synchronization.cpp b/externals/dynarmic/src/dynarmic/frontend/A32/translate/impl/synchronization.cpp index 653732b45..b020164ec 100755 --- a/externals/dynarmic/src/dynarmic/frontend/A32/translate/impl/synchronization.cpp +++ b/externals/dynarmic/src/dynarmic/frontend/A32/translate/impl/synchronization.cpp @@ -60,7 +60,7 @@ bool TranslatorVisitor::arm_LDA(Cond cond, Reg n, Reg t) { } const auto address = ir.GetRegister(n); - ir.SetRegister(t, ir.ReadMemory32(address)); // AccType::Ordered + ir.SetRegister(t, ir.ReadMemory32(address)); // AccessType::Ordered return true; } // LDAB , [] @@ -74,7 +74,7 @@ bool TranslatorVisitor::arm_LDAB(Cond cond, Reg n, Reg t) { } const auto address = ir.GetRegister(n); - ir.SetRegister(t, ir.ZeroExtendToWord(ir.ReadMemory8(address))); // AccType::Ordered + ir.SetRegister(t, ir.ZeroExtendToWord(ir.ReadMemory8(address))); // AccessType::Ordered return true; } // LDAH , [] @@ -88,7 +88,7 @@ bool TranslatorVisitor::arm_LDAH(Cond cond, Reg n, Reg t) { } const auto address = ir.GetRegister(n); - ir.SetRegister(t, ir.ZeroExtendToWord(ir.ReadMemory16(address))); // AccType::Ordered + ir.SetRegister(t, ir.ZeroExtendToWord(ir.ReadMemory16(address))); // AccessType::Ordered return true; } @@ -103,7 +103,7 @@ bool TranslatorVisitor::arm_LDAEX(Cond cond, Reg n, Reg t) { } const auto address = ir.GetRegister(n); - ir.SetRegister(t, ir.ExclusiveReadMemory32(address)); // AccType::Ordered + ir.SetRegister(t, ir.ExclusiveReadMemory32(address)); // AccessType::Ordered return true; } @@ -118,7 +118,7 @@ bool TranslatorVisitor::arm_LDAEXB(Cond cond, Reg n, Reg t) { } const auto address = ir.GetRegister(n); - ir.SetRegister(t, ir.ZeroExtendByteToWord(ir.ExclusiveReadMemory8(address))); // AccType::Ordered + ir.SetRegister(t, ir.ZeroExtendByteToWord(ir.ExclusiveReadMemory8(address))); // AccessType::Ordered return true; } @@ -133,7 +133,7 @@ bool TranslatorVisitor::arm_LDAEXD(Cond cond, Reg n, Reg t) { } const auto address = ir.GetRegister(n); - const auto [lo, hi] = ir.ExclusiveReadMemory64(address); // AccType::Ordered + const auto [lo, hi] = ir.ExclusiveReadMemory64(address); // AccessType::Ordered // DO NOT SWAP hi AND lo IN BIG ENDIAN MODE, THIS IS CORRECT BEHAVIOUR ir.SetRegister(t, lo); ir.SetRegister(t + 1, hi); @@ -151,7 +151,7 @@ bool TranslatorVisitor::arm_LDAEXH(Cond cond, Reg n, Reg t) { } const auto address = ir.GetRegister(n); - ir.SetRegister(t, ir.ZeroExtendHalfToWord(ir.ExclusiveReadMemory16(address))); // AccType::Ordered + ir.SetRegister(t, ir.ZeroExtendHalfToWord(ir.ExclusiveReadMemory16(address))); // AccessType::Ordered return true; } @@ -166,7 +166,7 @@ bool TranslatorVisitor::arm_STL(Cond cond, Reg n, Reg t) { } const auto address = ir.GetRegister(n); - ir.WriteMemory32(address, ir.GetRegister(t)); // AccType::Ordered + ir.WriteMemory32(address, ir.GetRegister(t)); // AccessType::Ordered return true; } @@ -181,7 +181,7 @@ bool TranslatorVisitor::arm_STLB(Cond cond, Reg n, Reg t) { } const auto address = ir.GetRegister(n); - ir.WriteMemory8(address, ir.LeastSignificantByte(ir.GetRegister(t))); // AccType::Ordered + ir.WriteMemory8(address, ir.LeastSignificantByte(ir.GetRegister(t))); // AccessType::Ordered return true; } @@ -196,7 +196,7 @@ bool TranslatorVisitor::arm_STLH(Cond cond, Reg n, Reg t) { } const auto address = ir.GetRegister(n); - ir.WriteMemory16(address, ir.LeastSignificantHalf(ir.GetRegister(t))); // AccType::Ordered + ir.WriteMemory16(address, ir.LeastSignificantHalf(ir.GetRegister(t))); // AccessType::Ordered return true; } @@ -216,7 +216,7 @@ bool TranslatorVisitor::arm_STLEXB(Cond cond, Reg n, Reg d, Reg t) { const auto address = ir.GetRegister(n); const auto value = ir.LeastSignificantByte(ir.GetRegister(t)); - const auto passed = ir.ExclusiveWriteMemory8(address, value); // AccType::Ordered + const auto passed = ir.ExclusiveWriteMemory8(address, value); // AccessType::Ordered ir.SetRegister(d, passed); return true; } @@ -238,7 +238,7 @@ bool TranslatorVisitor::arm_STLEXD(Cond cond, Reg n, Reg d, Reg t) { const auto address = ir.GetRegister(n); const auto value_lo = ir.GetRegister(t); const auto value_hi = ir.GetRegister(t2); - const auto passed = ir.ExclusiveWriteMemory64(address, value_lo, value_hi); // AccType::Ordered + const auto passed = ir.ExclusiveWriteMemory64(address, value_lo, value_hi); // AccessType::Ordered ir.SetRegister(d, passed); return true; } @@ -259,7 +259,7 @@ bool TranslatorVisitor::arm_STLEXH(Cond cond, Reg n, Reg d, Reg t) { const auto address = ir.GetRegister(n); const auto value = ir.LeastSignificantHalf(ir.GetRegister(t)); - const auto passed = ir.ExclusiveWriteMemory16(address, value); // AccType::Ordered + const auto passed = ir.ExclusiveWriteMemory16(address, value); // AccessType::Ordered ir.SetRegister(d, passed); return true; } diff --git a/externals/dynarmic/src/dynarmic/frontend/A64/a64_ir_emitter.cpp b/externals/dynarmic/src/dynarmic/frontend/A64/a64_ir_emitter.cpp index 8e9df1d6a..f9eb671ef 100755 --- a/externals/dynarmic/src/dynarmic/frontend/A64/a64_ir_emitter.cpp +++ b/externals/dynarmic/src/dynarmic/frontend/A64/a64_ir_emitter.cpp @@ -105,84 +105,84 @@ void IREmitter::ClearExclusive() { Inst(Opcode::A64ClearExclusive); } -IR::U8 IREmitter::ReadMemory8(const IR::U64& vaddr) { - return Inst(Opcode::A64ReadMemory8, vaddr); +IR::U8 IREmitter::ReadMemory8(const IR::U64& vaddr, IR::AccessType acctype) { + return Inst(Opcode::A64ReadMemory8, vaddr, IR::Value(acctype)); } -IR::U16 IREmitter::ReadMemory16(const IR::U64& vaddr) { - return Inst(Opcode::A64ReadMemory16, vaddr); +IR::U16 IREmitter::ReadMemory16(const IR::U64& vaddr, IR::AccessType acctype) { + return Inst(Opcode::A64ReadMemory16, vaddr, IR::Value(acctype)); } -IR::U32 IREmitter::ReadMemory32(const IR::U64& vaddr) { - return Inst(Opcode::A64ReadMemory32, vaddr); +IR::U32 IREmitter::ReadMemory32(const IR::U64& vaddr, IR::AccessType acctype) { + return Inst(Opcode::A64ReadMemory32, vaddr, IR::Value(acctype)); } -IR::U64 IREmitter::ReadMemory64(const IR::U64& vaddr) { - return Inst(Opcode::A64ReadMemory64, vaddr); +IR::U64 IREmitter::ReadMemory64(const IR::U64& vaddr, IR::AccessType acctype) { + return Inst(Opcode::A64ReadMemory64, vaddr, IR::Value(acctype)); } -IR::U128 IREmitter::ReadMemory128(const IR::U64& vaddr) { - return Inst(Opcode::A64ReadMemory128, vaddr); +IR::U128 IREmitter::ReadMemory128(const IR::U64& vaddr, IR::AccessType acctype) { + return Inst(Opcode::A64ReadMemory128, vaddr, IR::Value(acctype)); } -IR::U8 IREmitter::ExclusiveReadMemory8(const IR::U64& vaddr) { - return Inst(Opcode::A64ExclusiveReadMemory8, vaddr); +IR::U8 IREmitter::ExclusiveReadMemory8(const IR::U64& vaddr, IR::AccessType acctype) { + return Inst(Opcode::A64ExclusiveReadMemory8, vaddr, IR::Value(acctype)); } -IR::U16 IREmitter::ExclusiveReadMemory16(const IR::U64& vaddr) { - return Inst(Opcode::A64ExclusiveReadMemory16, vaddr); +IR::U16 IREmitter::ExclusiveReadMemory16(const IR::U64& vaddr, IR::AccessType acctype) { + return Inst(Opcode::A64ExclusiveReadMemory16, vaddr, IR::Value(acctype)); } -IR::U32 IREmitter::ExclusiveReadMemory32(const IR::U64& vaddr) { - return Inst(Opcode::A64ExclusiveReadMemory32, vaddr); +IR::U32 IREmitter::ExclusiveReadMemory32(const IR::U64& vaddr, IR::AccessType acctype) { + return Inst(Opcode::A64ExclusiveReadMemory32, vaddr, IR::Value(acctype)); } -IR::U64 IREmitter::ExclusiveReadMemory64(const IR::U64& vaddr) { - return Inst(Opcode::A64ExclusiveReadMemory64, vaddr); +IR::U64 IREmitter::ExclusiveReadMemory64(const IR::U64& vaddr, IR::AccessType acctype) { + return Inst(Opcode::A64ExclusiveReadMemory64, vaddr, IR::Value(acctype)); } -IR::U128 IREmitter::ExclusiveReadMemory128(const IR::U64& vaddr) { - return Inst(Opcode::A64ExclusiveReadMemory128, vaddr); +IR::U128 IREmitter::ExclusiveReadMemory128(const IR::U64& vaddr, IR::AccessType acctype) { + return Inst(Opcode::A64ExclusiveReadMemory128, vaddr, IR::Value(acctype)); } -void IREmitter::WriteMemory8(const IR::U64& vaddr, const IR::U8& value) { - Inst(Opcode::A64WriteMemory8, vaddr, value); +void IREmitter::WriteMemory8(const IR::U64& vaddr, const IR::U8& value, IR::AccessType acctype) { + Inst(Opcode::A64WriteMemory8, vaddr, value, IR::Value(acctype)); } -void IREmitter::WriteMemory16(const IR::U64& vaddr, const IR::U16& value) { - Inst(Opcode::A64WriteMemory16, vaddr, value); +void IREmitter::WriteMemory16(const IR::U64& vaddr, const IR::U16& value, IR::AccessType acctype) { + Inst(Opcode::A64WriteMemory16, vaddr, value, IR::Value(acctype)); } -void IREmitter::WriteMemory32(const IR::U64& vaddr, const IR::U32& value) { - Inst(Opcode::A64WriteMemory32, vaddr, value); +void IREmitter::WriteMemory32(const IR::U64& vaddr, const IR::U32& value, IR::AccessType acctype) { + Inst(Opcode::A64WriteMemory32, vaddr, value, IR::Value(acctype)); } -void IREmitter::WriteMemory64(const IR::U64& vaddr, const IR::U64& value) { - Inst(Opcode::A64WriteMemory64, vaddr, value); +void IREmitter::WriteMemory64(const IR::U64& vaddr, const IR::U64& value, IR::AccessType acctype) { + Inst(Opcode::A64WriteMemory64, vaddr, value, IR::Value(acctype)); } -void IREmitter::WriteMemory128(const IR::U64& vaddr, const IR::U128& value) { - Inst(Opcode::A64WriteMemory128, vaddr, value); +void IREmitter::WriteMemory128(const IR::U64& vaddr, const IR::U128& value, IR::AccessType acctype) { + Inst(Opcode::A64WriteMemory128, vaddr, value, IR::Value(acctype)); } -IR::U32 IREmitter::ExclusiveWriteMemory8(const IR::U64& vaddr, const IR::U8& value) { - return Inst(Opcode::A64ExclusiveWriteMemory8, vaddr, value); +IR::U32 IREmitter::ExclusiveWriteMemory8(const IR::U64& vaddr, const IR::U8& value, IR::AccessType acctype) { + return Inst(Opcode::A64ExclusiveWriteMemory8, vaddr, value, IR::Value(acctype)); } -IR::U32 IREmitter::ExclusiveWriteMemory16(const IR::U64& vaddr, const IR::U16& value) { - return Inst(Opcode::A64ExclusiveWriteMemory16, vaddr, value); +IR::U32 IREmitter::ExclusiveWriteMemory16(const IR::U64& vaddr, const IR::U16& value, IR::AccessType acctype) { + return Inst(Opcode::A64ExclusiveWriteMemory16, vaddr, value, IR::Value(acctype)); } -IR::U32 IREmitter::ExclusiveWriteMemory32(const IR::U64& vaddr, const IR::U32& value) { - return Inst(Opcode::A64ExclusiveWriteMemory32, vaddr, value); +IR::U32 IREmitter::ExclusiveWriteMemory32(const IR::U64& vaddr, const IR::U32& value, IR::AccessType acctype) { + return Inst(Opcode::A64ExclusiveWriteMemory32, vaddr, value, IR::Value(acctype)); } -IR::U32 IREmitter::ExclusiveWriteMemory64(const IR::U64& vaddr, const IR::U64& value) { - return Inst(Opcode::A64ExclusiveWriteMemory64, vaddr, value); +IR::U32 IREmitter::ExclusiveWriteMemory64(const IR::U64& vaddr, const IR::U64& value, IR::AccessType acctype) { + return Inst(Opcode::A64ExclusiveWriteMemory64, vaddr, value, IR::Value(acctype)); } -IR::U32 IREmitter::ExclusiveWriteMemory128(const IR::U64& vaddr, const IR::U128& value) { - return Inst(Opcode::A64ExclusiveWriteMemory128, vaddr, value); +IR::U32 IREmitter::ExclusiveWriteMemory128(const IR::U64& vaddr, const IR::U128& value, IR::AccessType acctype) { + return Inst(Opcode::A64ExclusiveWriteMemory128, vaddr, value, IR::Value(acctype)); } IR::U32 IREmitter::GetW(Reg reg) { diff --git a/externals/dynarmic/src/dynarmic/frontend/A64/a64_ir_emitter.h b/externals/dynarmic/src/dynarmic/frontend/A64/a64_ir_emitter.h index 9928e03b7..ba76f9c6a 100755 --- a/externals/dynarmic/src/dynarmic/frontend/A64/a64_ir_emitter.h +++ b/externals/dynarmic/src/dynarmic/frontend/A64/a64_ir_emitter.h @@ -56,26 +56,26 @@ public: void SetTPIDR(const IR::U64& value); void ClearExclusive(); - IR::U8 ReadMemory8(const IR::U64& vaddr); - IR::U16 ReadMemory16(const IR::U64& vaddr); - IR::U32 ReadMemory32(const IR::U64& vaddr); - IR::U64 ReadMemory64(const IR::U64& vaddr); - IR::U128 ReadMemory128(const IR::U64& vaddr); - IR::U8 ExclusiveReadMemory8(const IR::U64& vaddr); - IR::U16 ExclusiveReadMemory16(const IR::U64& vaddr); - IR::U32 ExclusiveReadMemory32(const IR::U64& vaddr); - IR::U64 ExclusiveReadMemory64(const IR::U64& vaddr); - IR::U128 ExclusiveReadMemory128(const IR::U64& vaddr); - void WriteMemory8(const IR::U64& vaddr, const IR::U8& value); - void WriteMemory16(const IR::U64& vaddr, const IR::U16& value); - void WriteMemory32(const IR::U64& vaddr, const IR::U32& value); - void WriteMemory64(const IR::U64& vaddr, const IR::U64& value); - void WriteMemory128(const IR::U64& vaddr, const IR::U128& value); - IR::U32 ExclusiveWriteMemory8(const IR::U64& vaddr, const IR::U8& value); - IR::U32 ExclusiveWriteMemory16(const IR::U64& vaddr, const IR::U16& value); - IR::U32 ExclusiveWriteMemory32(const IR::U64& vaddr, const IR::U32& value); - IR::U32 ExclusiveWriteMemory64(const IR::U64& vaddr, const IR::U64& value); - IR::U32 ExclusiveWriteMemory128(const IR::U64& vaddr, const IR::U128& value); + IR::U8 ReadMemory8(const IR::U64& vaddr, IR::AccessType acctype); + IR::U16 ReadMemory16(const IR::U64& vaddr, IR::AccessType acctype); + IR::U32 ReadMemory32(const IR::U64& vaddr, IR::AccessType acctype); + IR::U64 ReadMemory64(const IR::U64& vaddr, IR::AccessType acctype); + IR::U128 ReadMemory128(const IR::U64& vaddr, IR::AccessType acctype); + IR::U8 ExclusiveReadMemory8(const IR::U64& vaddr, IR::AccessType acctype); + IR::U16 ExclusiveReadMemory16(const IR::U64& vaddr, IR::AccessType acctype); + IR::U32 ExclusiveReadMemory32(const IR::U64& vaddr, IR::AccessType acctype); + IR::U64 ExclusiveReadMemory64(const IR::U64& vaddr, IR::AccessType acctype); + IR::U128 ExclusiveReadMemory128(const IR::U64& vaddr, IR::AccessType acctype); + void WriteMemory8(const IR::U64& vaddr, const IR::U8& value, IR::AccessType acctype); + void WriteMemory16(const IR::U64& vaddr, const IR::U16& value, IR::AccessType acctype); + void WriteMemory32(const IR::U64& vaddr, const IR::U32& value, IR::AccessType acctype); + void WriteMemory64(const IR::U64& vaddr, const IR::U64& value, IR::AccessType acctype); + void WriteMemory128(const IR::U64& vaddr, const IR::U128& value, IR::AccessType acctype); + IR::U32 ExclusiveWriteMemory8(const IR::U64& vaddr, const IR::U8& value, IR::AccessType acctype); + IR::U32 ExclusiveWriteMemory16(const IR::U64& vaddr, const IR::U16& value, IR::AccessType acctype); + IR::U32 ExclusiveWriteMemory32(const IR::U64& vaddr, const IR::U32& value, IR::AccessType acctype); + IR::U32 ExclusiveWriteMemory64(const IR::U64& vaddr, const IR::U64& value, IR::AccessType acctype); + IR::U32 ExclusiveWriteMemory128(const IR::U64& vaddr, const IR::U128& value, IR::AccessType acctype); IR::U32 GetW(Reg source_reg); IR::U64 GetX(Reg source_reg); diff --git a/externals/dynarmic/src/dynarmic/frontend/A64/translate/impl/impl.cpp b/externals/dynarmic/src/dynarmic/frontend/A64/translate/impl/impl.cpp index 23773727d..f9dd83804 100755 --- a/externals/dynarmic/src/dynarmic/frontend/A64/translate/impl/impl.cpp +++ b/externals/dynarmic/src/dynarmic/frontend/A64/translate/impl/impl.cpp @@ -217,74 +217,74 @@ void TranslatorVisitor::Vpart_scalar(size_t bitsize, Vec vec, size_t part, IR::U } } -IR::UAnyU128 TranslatorVisitor::Mem(IR::U64 address, size_t bytesize, IR::AccType /*acc_type*/) { +IR::UAnyU128 TranslatorVisitor::Mem(IR::U64 address, size_t bytesize, IR::AccessType acctype) { switch (bytesize) { case 1: - return ir.ReadMemory8(address); + return ir.ReadMemory8(address, acctype); case 2: - return ir.ReadMemory16(address); + return ir.ReadMemory16(address, acctype); case 4: - return ir.ReadMemory32(address); + return ir.ReadMemory32(address, acctype); case 8: - return ir.ReadMemory64(address); + return ir.ReadMemory64(address, acctype); case 16: - return ir.ReadMemory128(address); + return ir.ReadMemory128(address, acctype); default: ASSERT_FALSE("Invalid bytesize parameter {}", bytesize); } } -void TranslatorVisitor::Mem(IR::U64 address, size_t bytesize, IR::AccType /*acc_type*/, IR::UAnyU128 value) { +void TranslatorVisitor::Mem(IR::U64 address, size_t bytesize, IR::AccessType acctype, IR::UAnyU128 value) { switch (bytesize) { case 1: - ir.WriteMemory8(address, value); + ir.WriteMemory8(address, value, acctype); return; case 2: - ir.WriteMemory16(address, value); + ir.WriteMemory16(address, value, acctype); return; case 4: - ir.WriteMemory32(address, value); + ir.WriteMemory32(address, value, acctype); return; case 8: - ir.WriteMemory64(address, value); + ir.WriteMemory64(address, value, acctype); return; case 16: - ir.WriteMemory128(address, value); + ir.WriteMemory128(address, value, acctype); return; default: ASSERT_FALSE("Invalid bytesize parameter {}", bytesize); } } -IR::UAnyU128 TranslatorVisitor::ExclusiveMem(IR::U64 address, size_t bytesize, IR::AccType /*acctype*/) { +IR::UAnyU128 TranslatorVisitor::ExclusiveMem(IR::U64 address, size_t bytesize, IR::AccessType acctype) { switch (bytesize) { case 1: - return ir.ExclusiveReadMemory8(address); + return ir.ExclusiveReadMemory8(address, acctype); case 2: - return ir.ExclusiveReadMemory16(address); + return ir.ExclusiveReadMemory16(address, acctype); case 4: - return ir.ExclusiveReadMemory32(address); + return ir.ExclusiveReadMemory32(address, acctype); case 8: - return ir.ExclusiveReadMemory64(address); + return ir.ExclusiveReadMemory64(address, acctype); case 16: - return ir.ExclusiveReadMemory128(address); + return ir.ExclusiveReadMemory128(address, acctype); default: ASSERT_FALSE("Invalid bytesize parameter {}", bytesize); } } -IR::U32 TranslatorVisitor::ExclusiveMem(IR::U64 address, size_t bytesize, IR::AccType /*acctype*/, IR::UAnyU128 value) { +IR::U32 TranslatorVisitor::ExclusiveMem(IR::U64 address, size_t bytesize, IR::AccessType acctype, IR::UAnyU128 value) { switch (bytesize) { case 1: - return ir.ExclusiveWriteMemory8(address, value); + return ir.ExclusiveWriteMemory8(address, value, acctype); case 2: - return ir.ExclusiveWriteMemory16(address, value); + return ir.ExclusiveWriteMemory16(address, value, acctype); case 4: - return ir.ExclusiveWriteMemory32(address, value); + return ir.ExclusiveWriteMemory32(address, value, acctype); case 8: - return ir.ExclusiveWriteMemory64(address, value); + return ir.ExclusiveWriteMemory64(address, value, acctype); case 16: - return ir.ExclusiveWriteMemory128(address, value); + return ir.ExclusiveWriteMemory128(address, value, acctype); default: ASSERT_FALSE("Invalid bytesize parameter {}", bytesize); } diff --git a/externals/dynarmic/src/dynarmic/frontend/A64/translate/impl/impl.h b/externals/dynarmic/src/dynarmic/frontend/A64/translate/impl/impl.h index 86bc534d5..c83c962d1 100755 --- a/externals/dynarmic/src/dynarmic/frontend/A64/translate/impl/impl.h +++ b/externals/dynarmic/src/dynarmic/frontend/A64/translate/impl/impl.h @@ -55,10 +55,10 @@ struct TranslatorVisitor final { IR::UAny Vpart_scalar(size_t bitsize, Vec vec, size_t part); void Vpart_scalar(size_t bitsize, Vec vec, size_t part, IR::UAny value); - IR::UAnyU128 Mem(IR::U64 address, size_t size, IR::AccType acctype); - void Mem(IR::U64 address, size_t size, IR::AccType acctype, IR::UAnyU128 value); - IR::UAnyU128 ExclusiveMem(IR::U64 address, size_t size, IR::AccType acctype); - IR::U32 ExclusiveMem(IR::U64 address, size_t size, IR::AccType acctype, IR::UAnyU128 value); + IR::UAnyU128 Mem(IR::U64 address, size_t size, IR::AccessType acctype); + void Mem(IR::U64 address, size_t size, IR::AccessType acctype, IR::UAnyU128 value); + IR::UAnyU128 ExclusiveMem(IR::U64 address, size_t size, IR::AccessType acctype); + IR::U32 ExclusiveMem(IR::U64 address, size_t size, IR::AccessType acctype, IR::UAnyU128 value); IR::U32U64 SignExtend(IR::UAny value, size_t to_size); IR::U32U64 ZeroExtend(IR::UAny value, size_t to_size); diff --git a/externals/dynarmic/src/dynarmic/frontend/A64/translate/impl/load_store_exclusive.cpp b/externals/dynarmic/src/dynarmic/frontend/A64/translate/impl/load_store_exclusive.cpp index 0e67e11b4..804c53f86 100755 --- a/externals/dynarmic/src/dynarmic/frontend/A64/translate/impl/load_store_exclusive.cpp +++ b/externals/dynarmic/src/dynarmic/frontend/A64/translate/impl/load_store_exclusive.cpp @@ -12,7 +12,7 @@ namespace Dynarmic::A64 { static bool ExclusiveSharedDecodeAndOperation(TranslatorVisitor& v, bool pair, size_t size, bool L, bool o0, std::optional Rs, std::optional Rt2, Reg Rn, Reg Rt) { // Shared Decode - const auto acctype = o0 ? IR::AccType::ORDERED : IR::AccType::ATOMIC; + const auto acctype = o0 ? IR::AccessType::ORDERED : IR::AccessType::ATOMIC; const auto memop = L ? IR::MemOp::LOAD : IR::MemOp::STORE; const size_t elsize = 8 << size; const size_t regsize = elsize == 64 ? 64 : 32; @@ -142,7 +142,7 @@ bool TranslatorVisitor::LDAXP(Imm<1> sz, Reg Rt2, Reg Rn, Reg Rt) { static bool OrderedSharedDecodeAndOperation(TranslatorVisitor& v, size_t size, bool L, bool o0, Reg Rn, Reg Rt) { // Shared Decode - const auto acctype = !o0 ? IR::AccType::LIMITEDORDERED : IR::AccType::ORDERED; + const auto acctype = !o0 ? IR::AccessType::LIMITEDORDERED : IR::AccessType::ORDERED; const auto memop = L ? IR::MemOp::LOAD : IR::MemOp::STORE; const size_t elsize = 8 << size; const size_t regsize = elsize == 64 ? 64 : 32; diff --git a/externals/dynarmic/src/dynarmic/frontend/A64/translate/impl/load_store_load_literal.cpp b/externals/dynarmic/src/dynarmic/frontend/A64/translate/impl/load_store_load_literal.cpp index 995aba425..a4b2beae3 100755 --- a/externals/dynarmic/src/dynarmic/frontend/A64/translate/impl/load_store_load_literal.cpp +++ b/externals/dynarmic/src/dynarmic/frontend/A64/translate/impl/load_store_load_literal.cpp @@ -12,7 +12,7 @@ bool TranslatorVisitor::LDR_lit_gen(bool opc_0, Imm<19> imm19, Reg Rt) { const s64 offset = concatenate(imm19, Imm<2>{0}).SignExtend(); const u64 address = ir.PC() + offset; - const auto data = Mem(ir.Imm64(address), size, IR::AccType::NORMAL); + const auto data = Mem(ir.Imm64(address), size, IR::AccessType::NORMAL); X(8 * size, Rt, data); return true; @@ -26,7 +26,7 @@ bool TranslatorVisitor::LDR_lit_fpsimd(Imm<2> opc, Imm<19> imm19, Vec Vt) { const u64 size = 4 << opc.ZeroExtend(); const u64 offset = imm19.SignExtend() << 2; const IR::U64 address = ir.Imm64(ir.PC() + offset); - const IR::UAnyU128 data = Mem(address, size, IR::AccType::VEC); + const IR::UAnyU128 data = Mem(address, size, IR::AccessType::VEC); if (size == 16) { V(128, Vt, data); @@ -39,7 +39,7 @@ bool TranslatorVisitor::LDR_lit_fpsimd(Imm<2> opc, Imm<19> imm19, Vec Vt) { bool TranslatorVisitor::LDRSW_lit(Imm<19> imm19, Reg Rt) { const s64 offset = concatenate(imm19, Imm<2>{0}).SignExtend(); const u64 address = ir.PC() + offset; - const auto data = Mem(ir.Imm64(address), 4, IR::AccType::NORMAL); + const auto data = Mem(ir.Imm64(address), 4, IR::AccessType::NORMAL); X(64, Rt, ir.SignExtendWordToLong(data)); return true; diff --git a/externals/dynarmic/src/dynarmic/frontend/A64/translate/impl/load_store_multiple_structures.cpp b/externals/dynarmic/src/dynarmic/frontend/A64/translate/impl/load_store_multiple_structures.cpp index 77c57a965..0c1a2d7d1 100755 --- a/externals/dynarmic/src/dynarmic/frontend/A64/translate/impl/load_store_multiple_structures.cpp +++ b/externals/dynarmic/src/dynarmic/frontend/A64/translate/impl/load_store_multiple_structures.cpp @@ -67,11 +67,11 @@ static bool SharedDecodeAndOperation(TranslatorVisitor& v, bool wback, IR::MemOp for (size_t r = 0; r < rpt; r++) { const Vec tt = static_cast((VecNumber(Vt) + r) % 32); if (memop == IR::MemOp::LOAD) { - const IR::UAnyU128 vec = v.Mem(v.ir.Add(address, offs), ebytes * elements, IR::AccType::VEC); + const IR::UAnyU128 vec = v.Mem(v.ir.Add(address, offs), ebytes * elements, IR::AccessType::VEC); v.V_scalar(datasize, tt, vec); } else { const IR::UAnyU128 vec = v.V_scalar(datasize, tt); - v.Mem(v.ir.Add(address, offs), ebytes * elements, IR::AccType::VEC, vec); + v.Mem(v.ir.Add(address, offs), ebytes * elements, IR::AccessType::VEC, vec); } offs = v.ir.Add(offs, v.ir.Imm64(ebytes * elements)); } @@ -80,12 +80,12 @@ static bool SharedDecodeAndOperation(TranslatorVisitor& v, bool wback, IR::MemOp for (size_t s = 0; s < selem; s++) { const Vec tt = static_cast((VecNumber(Vt) + s) % 32); if (memop == IR::MemOp::LOAD) { - const IR::UAny elem = v.Mem(v.ir.Add(address, offs), ebytes, IR::AccType::VEC); + const IR::UAny elem = v.Mem(v.ir.Add(address, offs), ebytes, IR::AccessType::VEC); const IR::U128 vec = v.ir.VectorSetElement(esize, v.V(datasize, tt), e, elem); v.V(datasize, tt, vec); } else { const IR::UAny elem = v.ir.VectorGetElement(esize, v.V(datasize, tt), e); - v.Mem(v.ir.Add(address, offs), ebytes, IR::AccType::VEC, elem); + v.Mem(v.ir.Add(address, offs), ebytes, IR::AccessType::VEC, elem); } offs = v.ir.Add(offs, v.ir.Imm64(ebytes)); } diff --git a/externals/dynarmic/src/dynarmic/frontend/A64/translate/impl/load_store_register_immediate.cpp b/externals/dynarmic/src/dynarmic/frontend/A64/translate/impl/load_store_register_immediate.cpp index d939c45f2..5b17b3353 100755 --- a/externals/dynarmic/src/dynarmic/frontend/A64/translate/impl/load_store_register_immediate.cpp +++ b/externals/dynarmic/src/dynarmic/frontend/A64/translate/impl/load_store_register_immediate.cpp @@ -43,11 +43,11 @@ static bool LoadStoreRegisterImmediate(TranslatorVisitor& v, bool wback, bool po switch (memop) { case IR::MemOp::STORE: { const auto data = v.X(datasize, Rt); - v.Mem(address, datasize / 8, IR::AccType::NORMAL, data); + v.Mem(address, datasize / 8, IR::AccessType::NORMAL, data); break; } case IR::MemOp::LOAD: { - const auto data = v.Mem(address, datasize / 8, IR::AccType::NORMAL); + const auto data = v.Mem(address, datasize / 8, IR::AccessType::NORMAL); if (signed_) { v.X(regsize, Rt, v.SignExtend(data, regsize)); } else { @@ -115,7 +115,7 @@ bool TranslatorVisitor::PRFM_unscaled_imm([[maybe_unused]] Imm<9> imm9, [[maybe_ } static bool LoadStoreSIMD(TranslatorVisitor& v, bool wback, bool postindex, size_t scale, u64 offset, IR::MemOp memop, Reg Rn, Vec Vt) { - const auto acctype = IR::AccType::VEC; + const auto acctype = IR::AccessType::VEC; const size_t datasize = 8 << scale; IR::U64 address; diff --git a/externals/dynarmic/src/dynarmic/frontend/A64/translate/impl/load_store_register_pair.cpp b/externals/dynarmic/src/dynarmic/frontend/A64/translate/impl/load_store_register_pair.cpp index 4c81564f7..acbdf2e48 100755 --- a/externals/dynarmic/src/dynarmic/frontend/A64/translate/impl/load_store_register_pair.cpp +++ b/externals/dynarmic/src/dynarmic/frontend/A64/translate/impl/load_store_register_pair.cpp @@ -46,13 +46,13 @@ bool TranslatorVisitor::STP_LDP_gen(Imm<2> opc, bool not_postindex, bool wback, case IR::MemOp::STORE: { const IR::U32U64 data1 = X(datasize, Rt); const IR::U32U64 data2 = X(datasize, Rt2); - Mem(address, dbytes, IR::AccType::NORMAL, data1); - Mem(ir.Add(address, ir.Imm64(dbytes)), dbytes, IR::AccType::NORMAL, data2); + Mem(address, dbytes, IR::AccessType::NORMAL, data1); + Mem(ir.Add(address, ir.Imm64(dbytes)), dbytes, IR::AccessType::NORMAL, data2); break; } case IR::MemOp::LOAD: { - const IR::U32U64 data1 = Mem(address, dbytes, IR::AccType::NORMAL); - const IR::U32U64 data2 = Mem(ir.Add(address, ir.Imm64(dbytes)), dbytes, IR::AccType::NORMAL); + const IR::U32U64 data1 = Mem(address, dbytes, IR::AccessType::NORMAL); + const IR::U32U64 data2 = Mem(ir.Add(address, ir.Imm64(dbytes)), dbytes, IR::AccessType::NORMAL); if (signed_) { X(64, Rt, SignExtend(data1, 64)); X(64, Rt2, SignExtend(data2, 64)); @@ -117,13 +117,13 @@ bool TranslatorVisitor::STP_LDP_fpsimd(Imm<2> opc, bool not_postindex, bool wbac data1 = ir.VectorGetElement(datasize, data1, 0); data2 = ir.VectorGetElement(datasize, data2, 0); } - Mem(address, dbytes, IR::AccType::VEC, data1); - Mem(ir.Add(address, ir.Imm64(dbytes)), dbytes, IR::AccType::VEC, data2); + Mem(address, dbytes, IR::AccessType::VEC, data1); + Mem(ir.Add(address, ir.Imm64(dbytes)), dbytes, IR::AccessType::VEC, data2); break; } case IR::MemOp::LOAD: { - IR::UAnyU128 data1 = Mem(address, dbytes, IR::AccType::VEC); - IR::UAnyU128 data2 = Mem(ir.Add(address, ir.Imm64(dbytes)), dbytes, IR::AccType::VEC); + IR::UAnyU128 data1 = Mem(address, dbytes, IR::AccessType::VEC); + IR::UAnyU128 data2 = Mem(ir.Add(address, ir.Imm64(dbytes)), dbytes, IR::AccessType::VEC); if (datasize != 128) { data1 = ir.ZeroExtendToQuad(data1); data2 = ir.ZeroExtendToQuad(data2); diff --git a/externals/dynarmic/src/dynarmic/frontend/A64/translate/impl/load_store_register_register_offset.cpp b/externals/dynarmic/src/dynarmic/frontend/A64/translate/impl/load_store_register_register_offset.cpp index 979109586..4c2bfbc49 100755 --- a/externals/dynarmic/src/dynarmic/frontend/A64/translate/impl/load_store_register_register_offset.cpp +++ b/externals/dynarmic/src/dynarmic/frontend/A64/translate/impl/load_store_register_register_offset.cpp @@ -10,7 +10,7 @@ namespace Dynarmic::A64 { static bool RegSharedDecodeAndOperation(TranslatorVisitor& v, size_t scale, u8 shift, Imm<2> size, Imm<1> opc_1, Imm<1> opc_0, Reg Rm, Imm<3> option, Reg Rn, Reg Rt) { // Shared Decode - const auto acctype = IR::AccType::NORMAL; + const auto acctype = IR::AccessType::NORMAL; IR::MemOp memop; size_t regsize = 64; bool signed_ = false; @@ -96,7 +96,7 @@ bool TranslatorVisitor::LDRx_reg(Imm<2> size, Imm<1> opc_1, Reg Rm, Imm<3> optio static bool VecSharedDecodeAndOperation(TranslatorVisitor& v, size_t scale, u8 shift, Imm<1> opc_0, Reg Rm, Imm<3> option, Reg Rn, Vec Vt) { // Shared Decode - const auto acctype = IR::AccType::VEC; + const auto acctype = IR::AccessType::VEC; const auto memop = opc_0 == 1 ? IR::MemOp::LOAD : IR::MemOp::STORE; const size_t datasize = 8 << scale; diff --git a/externals/dynarmic/src/dynarmic/frontend/A64/translate/impl/load_store_register_unprivileged.cpp b/externals/dynarmic/src/dynarmic/frontend/A64/translate/impl/load_store_register_unprivileged.cpp index d3f4194ff..6d12f955e 100755 --- a/externals/dynarmic/src/dynarmic/frontend/A64/translate/impl/load_store_register_unprivileged.cpp +++ b/externals/dynarmic/src/dynarmic/frontend/A64/translate/impl/load_store_register_unprivileged.cpp @@ -9,7 +9,7 @@ namespace Dynarmic::A64 { static bool StoreRegister(TranslatorVisitor& v, const size_t datasize, const Imm<9> imm9, const Reg Rn, const Reg Rt) { const u64 offset = imm9.SignExtend(); - const auto acctype = IR::AccType::UNPRIV; + const auto acctype = IR::AccessType::UNPRIV; IR::U64 address; if (Rn == Reg::SP) { @@ -27,7 +27,7 @@ static bool StoreRegister(TranslatorVisitor& v, const size_t datasize, const Imm static bool LoadRegister(TranslatorVisitor& v, const size_t datasize, const Imm<9> imm9, const Reg Rn, const Reg Rt) { const u64 offset = imm9.SignExtend(); - const auto acctype = IR::AccType::UNPRIV; + const auto acctype = IR::AccessType::UNPRIV; IR::U64 address; if (Rn == Reg::SP) { @@ -47,7 +47,7 @@ static bool LoadRegister(TranslatorVisitor& v, const size_t datasize, const Imm< static bool LoadRegisterSigned(TranslatorVisitor& v, const size_t datasize, const Imm<2> opc, const Imm<9> imm9, const Reg Rn, const Reg Rt) { const u64 offset = imm9.SignExtend(); - const auto acctype = IR::AccType::UNPRIV; + const auto acctype = IR::AccessType::UNPRIV; IR::MemOp memop; bool is_signed; @@ -131,7 +131,7 @@ bool TranslatorVisitor::LDTRSH(Imm<2> opc, Imm<9> imm9, Reg Rn, Reg Rt) { bool TranslatorVisitor::LDTRSW(Imm<9> imm9, Reg Rn, Reg Rt) { const u64 offset = imm9.SignExtend(); - const auto acctype = IR::AccType::UNPRIV; + const auto acctype = IR::AccessType::UNPRIV; IR::U64 address; if (Rn == Reg::SP) { 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 b4bc84294..cbbc4de9d 100755 --- 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 @@ -62,7 +62,7 @@ static bool SharedDecodeAndOperation(TranslatorVisitor& v, bool wback, IR::MemOp if (replicate) { 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::UAnyU128 element = v.Mem(v.ir.Add(address, offs), ebytes, IR::AccessType::VEC); const IR::U128 broadcasted_element = v.ir.VectorBroadcast(esize, element); v.V(datasize, tt, broadcasted_element); @@ -75,12 +75,12 @@ static bool SharedDecodeAndOperation(TranslatorVisitor& v, bool wback, IR::MemOp 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::UAny elem = v.Mem(v.ir.Add(address, offs), ebytes, IR::AccessType::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); + v.Mem(v.ir.Add(address, offs), ebytes, IR::AccessType::VEC, elem); } offs = v.ir.Add(offs, v.ir.Imm64(ebytes)); } diff --git a/externals/dynarmic/src/dynarmic/ir/access_type.h b/externals/dynarmic/src/dynarmic/ir/access_type.h new file mode 100755 index 000000000..3823cfa7e --- /dev/null +++ b/externals/dynarmic/src/dynarmic/ir/access_type.h @@ -0,0 +1,28 @@ +/* This file is part of the dynarmic project. + * Copyright (c) 2022 MerryMage + * SPDX-License-Identifier: 0BSD + */ + +#pragma once + +namespace Dynarmic::IR { + +enum class AccessType { + NORMAL, + VEC, + STREAM, + VECSTREAM, + ATOMIC, + ORDERED, + ORDEREDRW, + LIMITEDORDERED, + UNPRIV, + IFETCH, + PTW, + DC, + IC, + DCZVA, + AT, +}; + +} // namespace Dynarmic::IR diff --git a/externals/dynarmic/src/dynarmic/ir/ir_emitter.h b/externals/dynarmic/src/dynarmic/ir/ir_emitter.h index 7336af58b..4b160f414 100755 --- a/externals/dynarmic/src/dynarmic/ir/ir_emitter.h +++ b/externals/dynarmic/src/dynarmic/ir/ir_emitter.h @@ -6,6 +6,7 @@ #pragma once #include "dynarmic/common/common_types.h" +#include "dynarmic/ir/access_type.h" #include "dynarmic/ir/basic_block.h" #include "dynarmic/ir/location_descriptor.h" #include "dynarmic/ir/terminal.h" @@ -56,24 +57,6 @@ struct UpperAndLower { U128 lower; }; -enum class AccType { - NORMAL, - VEC, - STREAM, - VECSTREAM, - ATOMIC, - ORDERED, - ORDEREDRW, - LIMITEDORDERED, - UNPRIV, - IFETCH, - PTW, - DC, - IC, - DCZVA, - AT, -}; - enum class MemOp { LOAD, STORE, diff --git a/externals/dynarmic/src/dynarmic/ir/opcodes.cpp b/externals/dynarmic/src/dynarmic/ir/opcodes.cpp index 354b8c59d..8fc6c4686 100755 --- a/externals/dynarmic/src/dynarmic/ir/opcodes.cpp +++ b/externals/dynarmic/src/dynarmic/ir/opcodes.cpp @@ -43,6 +43,7 @@ constexpr Type CoprocInfo = Type::CoprocInfo; constexpr Type NZCV = Type::NZCVFlags; constexpr Type Cond = Type::Cond; constexpr Type Table = Type::Table; +constexpr Type AccessType = Type::AccessType; static const std::array opcode_info{ #define OPCODE(name, type, ...) Meta{#name, type, {__VA_ARGS__}}, diff --git a/externals/dynarmic/src/dynarmic/ir/opcodes.inc b/externals/dynarmic/src/dynarmic/ir/opcodes.inc index 0c27dbe6c..351dd65aa 100755 --- a/externals/dynarmic/src/dynarmic/ir/opcodes.inc +++ b/externals/dynarmic/src/dynarmic/ir/opcodes.inc @@ -702,26 +702,26 @@ A32OPC(ExclusiveWriteMemory64, U32, U32, // A64 Memory access A64OPC(ClearExclusive, Void, ) -A64OPC(ReadMemory8, U8, U64 ) -A64OPC(ReadMemory16, U16, U64 ) -A64OPC(ReadMemory32, U32, U64 ) -A64OPC(ReadMemory64, U64, U64 ) -A64OPC(ReadMemory128, U128, U64 ) -A64OPC(ExclusiveReadMemory8, U8, U64 ) -A64OPC(ExclusiveReadMemory16, U16, U64 ) -A64OPC(ExclusiveReadMemory32, U32, U64 ) -A64OPC(ExclusiveReadMemory64, U64, U64 ) -A64OPC(ExclusiveReadMemory128, U128, U64 ) -A64OPC(WriteMemory8, Void, U64, U8 ) -A64OPC(WriteMemory16, Void, U64, U16 ) -A64OPC(WriteMemory32, Void, U64, U32 ) -A64OPC(WriteMemory64, Void, U64, U64 ) -A64OPC(WriteMemory128, Void, U64, U128 ) -A64OPC(ExclusiveWriteMemory8, U32, U64, U8 ) -A64OPC(ExclusiveWriteMemory16, U32, U64, U16 ) -A64OPC(ExclusiveWriteMemory32, U32, U64, U32 ) -A64OPC(ExclusiveWriteMemory64, U32, U64, U64 ) -A64OPC(ExclusiveWriteMemory128, U32, U64, U128 ) +A64OPC(ReadMemory8, U8, U64, AccessType ) +A64OPC(ReadMemory16, U16, U64, AccessType ) +A64OPC(ReadMemory32, U32, U64, AccessType ) +A64OPC(ReadMemory64, U64, U64, AccessType ) +A64OPC(ReadMemory128, U128, U64, AccessType ) +A64OPC(ExclusiveReadMemory8, U8, U64, AccessType ) +A64OPC(ExclusiveReadMemory16, U16, U64, AccessType ) +A64OPC(ExclusiveReadMemory32, U32, U64, AccessType ) +A64OPC(ExclusiveReadMemory64, U64, U64, AccessType ) +A64OPC(ExclusiveReadMemory128, U128, U64, AccessType ) +A64OPC(WriteMemory8, Void, U64, U8, AccessType ) +A64OPC(WriteMemory16, Void, U64, U16, AccessType ) +A64OPC(WriteMemory32, Void, U64, U32, AccessType ) +A64OPC(WriteMemory64, Void, U64, U64, AccessType ) +A64OPC(WriteMemory128, Void, U64, U128, AccessType ) +A64OPC(ExclusiveWriteMemory8, U32, U64, U8, AccessType ) +A64OPC(ExclusiveWriteMemory16, U32, U64, U16, AccessType ) +A64OPC(ExclusiveWriteMemory32, U32, U64, U32, AccessType ) +A64OPC(ExclusiveWriteMemory64, U32, U64, U64, AccessType ) +A64OPC(ExclusiveWriteMemory128, U32, U64, U128, AccessType ) // Coprocessor A32OPC(CoprocInternalOperation, Void, CoprocInfo ) 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 5535c502c..f8e968d5b 100755 --- a/externals/dynarmic/src/dynarmic/ir/opt/a64_callback_config_pass.cpp +++ b/externals/dynarmic/src/dynarmic/ir/opt/a64_callback_config_pass.cpp @@ -32,19 +32,19 @@ void A64CallbackConfigPass(IR::Block& block, const A64::UserConfig& conf) { const IR::U128 zero_u128 = ir.ZeroExtendToQuad(ir.Imm64(0)); while (bytes >= 16) { - ir.WriteMemory128(addr, zero_u128); + ir.WriteMemory128(addr, zero_u128, IR::AccessType::DCZVA); addr = ir.Add(addr, ir.Imm64(16)); bytes -= 16; } while (bytes >= 8) { - ir.WriteMemory64(addr, ir.Imm64(0)); + ir.WriteMemory64(addr, ir.Imm64(0), IR::AccessType::DCZVA); addr = ir.Add(addr, ir.Imm64(8)); bytes -= 8; } while (bytes >= 4) { - ir.WriteMemory32(addr, ir.Imm32(0)); + ir.WriteMemory32(addr, ir.Imm32(0), IR::AccessType::DCZVA); addr = ir.Add(addr, ir.Imm64(4)); bytes -= 4; } diff --git a/externals/dynarmic/src/dynarmic/ir/type.h b/externals/dynarmic/src/dynarmic/ir/type.h index 0c9eda9fe..569738aa1 100755 --- a/externals/dynarmic/src/dynarmic/ir/type.h +++ b/externals/dynarmic/src/dynarmic/ir/type.h @@ -32,6 +32,7 @@ enum class Type { NZCVFlags = 1 << 12, Cond = 1 << 13, Table = 1 << 14, + AccessType = 1 << 15, }; constexpr Type operator|(Type a, Type b) { diff --git a/externals/dynarmic/src/dynarmic/ir/value.cpp b/externals/dynarmic/src/dynarmic/ir/value.cpp index 2132b5beb..a0cc0bbf0 100755 --- a/externals/dynarmic/src/dynarmic/ir/value.cpp +++ b/externals/dynarmic/src/dynarmic/ir/value.cpp @@ -73,6 +73,11 @@ Value::Value(Cond value) inner.imm_cond = value; } +Value::Value(AccessType value) + : type(Type::AccessType) { + inner.imm_acctype = value; +} + bool Value::IsIdentity() const { if (type == Type::Opaque) return inner.inst->GetOpcode() == Opcode::Identity; @@ -178,6 +183,13 @@ Cond Value::GetCond() const { return inner.imm_cond; } +AccessType Value::GetAccType() const { + if (IsIdentity()) + return inner.inst->GetArg(0).GetAccType(); + ASSERT(type == Type::AccessType); + return inner.imm_acctype; +} + s64 Value::GetImmediateAsS64() const { ASSERT(IsImmediate()); diff --git a/externals/dynarmic/src/dynarmic/ir/value.h b/externals/dynarmic/src/dynarmic/ir/value.h index e907614d9..27df0bf3a 100755 --- a/externals/dynarmic/src/dynarmic/ir/value.h +++ b/externals/dynarmic/src/dynarmic/ir/value.h @@ -25,6 +25,7 @@ enum class Vec; namespace Dynarmic::IR { class Inst; +enum class AccessType; enum class Cond; /** @@ -49,6 +50,7 @@ public: explicit Value(u64 value); explicit Value(CoprocessorInfo value); explicit Value(Cond value); + explicit Value(AccessType value); bool IsIdentity() const; bool IsEmpty() const; @@ -68,6 +70,7 @@ public: u64 GetU64() const; CoprocessorInfo GetCoprocInfo() const; Cond GetCond() const; + AccessType GetAccType() const; /** * Retrieves the immediate of a Value instance as a signed 64-bit value. @@ -140,6 +143,7 @@ private: u64 imm_u64; CoprocessorInfo imm_coproc; Cond imm_cond; + AccessType imm_acctype; } inner; }; static_assert(sizeof(Value) <= 2 * sizeof(u64), "IR::Value should be kept small in size"); diff --git a/src/common/intrusive_red_black_tree.h b/src/common/intrusive_red_black_tree.h index 11766a036..1c0bdf165 100755 --- a/src/common/intrusive_red_black_tree.h +++ b/src/common/intrusive_red_black_tree.h @@ -83,8 +83,8 @@ public: using iterator_category = std::bidirectional_iterator_tag; using value_type = typename IntrusiveRedBlackTreeImpl::value_type; using difference_type = typename IntrusiveRedBlackTreeImpl::difference_type; - using pointer = typename std::conditional::type; + using pointer = std::conditional_t; using reference = typename std::conditional::type; @@ -263,7 +263,7 @@ namespace impl { template using RedBlackKeyType = - typename std::remove_pointer())>::type; + typename std::remove_pointer_t())>; template class IntrusiveRedBlackTree { @@ -299,7 +299,7 @@ public: friend class IntrusiveRedBlackTree; using ImplIterator = - typename std::conditional::type; + std::conditional_t; using iterator_category = std::bidirectional_iterator_tag; using value_type = typename IntrusiveRedBlackTree::value_type; @@ -315,7 +315,7 @@ public: private: constexpr explicit Iterator(ImplIterator it) : m_impl(it) {} - constexpr explicit Iterator(typename ImplIterator::pointer p) : m_impl(p) {} + constexpr explicit Iterator(ImplIterator::pointer p) : m_impl(p) {} constexpr ImplIterator GetImplIterator() const { return m_impl; diff --git a/src/common/tree.h b/src/common/tree.h index c282ac2f9..a30aa80dc 100755 --- a/src/common/tree.h +++ b/src/common/tree.h @@ -55,12 +55,6 @@ enum class RBColor { #pragma pack(push, 4) template class RBEntry { -private: - T* m_rbe_left{}; - T* m_rbe_right{}; - T* m_rbe_parent{}; - RBColor m_rbe_color{RBColor::RB_BLACK}; - public: constexpr RBEntry() = default; @@ -110,6 +104,12 @@ public: constexpr void SetColor(RBColor c) { m_rbe_color = c; } + +private: + T* m_rbe_left{}; + T* m_rbe_right{}; + T* m_rbe_parent{}; + RBColor m_rbe_color{RBColor::RB_BLACK}; }; #pragma pack(pop) diff --git a/src/core/hle/kernel/init/init_slab_setup.cpp b/src/core/hle/kernel/init/init_slab_setup.cpp index d2f57587d..e75ffd912 100755 --- a/src/core/hle/kernel/init/init_slab_setup.cpp +++ b/src/core/hle/kernel/init/init_slab_setup.cpp @@ -107,6 +107,12 @@ VAddr InitializeSlabHeap(Core::System& system, KMemoryLayout& memory_layout, VAd return start + size; } +size_t CalculateSlabHeapGapSize() { + constexpr size_t KernelSlabHeapGapSize = 2_MiB - 296_KiB; + static_assert(KernelSlabHeapGapSize <= KernelSlabHeapGapsSizeMax); + return KernelSlabHeapGapSize; +} + } // namespace KSlabResourceCounts KSlabResourceCounts::CreateDefault() { @@ -137,12 +143,6 @@ void InitializeSlabResourceCounts(KernelCore& kernel) { } } -size_t CalculateSlabHeapGapSize() { - constexpr size_t KernelSlabHeapGapSize = 2_MiB - 296_KiB; - static_assert(KernelSlabHeapGapSize <= KernelSlabHeapGapsSizeMax); - return KernelSlabHeapGapSize; -} - size_t CalculateTotalSlabHeapSize(const KernelCore& kernel) { size_t size = 0; diff --git a/src/core/hle/kernel/k_page_buffer.h b/src/core/hle/kernel/k_page_buffer.h index c8e04a889..b6876a1c9 100755 --- a/src/core/hle/kernel/k_page_buffer.h +++ b/src/core/hle/kernel/k_page_buffer.h @@ -16,13 +16,8 @@ namespace Kernel { class KPageBuffer final : public KSlabAllocated { -private: - alignas(PageSize) std::array m_buffer; - public: - KPageBuffer() { - std::memset(&m_buffer, 0, m_buffer.size()); - } + KPageBuffer() = default; PAddr GetPhysicalAddress(Core::System& system) const { return system.DeviceMemory().GetPhysicalAddr(this); @@ -32,6 +27,9 @@ public: ASSERT(Common::IsAligned(phys_addr, PageSize)); return reinterpret_cast(system.DeviceMemory().GetPointer(phys_addr)); } + +private: + alignas(PageSize) std::array m_buffer{}; }; static_assert(sizeof(KPageBuffer) == PageSize); diff --git a/src/core/hle/kernel/k_server_session.cpp b/src/core/hle/kernel/k_server_session.cpp index 435e90fe1..30c56ff29 100755 --- a/src/core/hle/kernel/k_server_session.cpp +++ b/src/core/hle/kernel/k_server_session.cpp @@ -98,7 +98,7 @@ ResultCode KServerSession::HandleDomainSyncRequest(Kernel::HLERequestContext& co UNREACHABLE(); return ResultSuccess; // Ignore error if asserts are off } - if (auto strong_ptr = manager->DomainHandler(object_id - 1).lock(); strong_ptr) { + if (auto strong_ptr = manager->DomainHandler(object_id - 1).lock()) { return strong_ptr->HandleSyncRequest(*this, context); } else { UNREACHABLE(); diff --git a/src/core/hle/kernel/k_thread_local_page.h b/src/core/hle/kernel/k_thread_local_page.h index 993da4804..1e2a7770e 100755 --- a/src/core/hle/kernel/k_thread_local_page.h +++ b/src/core/hle/kernel/k_thread_local_page.h @@ -4,6 +4,7 @@ #pragma once +#include #include #include "common/alignment.h" @@ -28,9 +29,7 @@ public: public: explicit KThreadLocalPage(VAddr addr = {}) : m_virt_addr(addr) { - for (size_t i = 0; i < m_is_region_free.size(); i++) { - m_is_region_free[i] = true; - } + m_is_region_free.fill(true); } constexpr VAddr GetAddress() const { @@ -44,21 +43,13 @@ public: void Release(VAddr addr); bool IsAllUsed() const { - for (size_t i = 0; i < RegionsPerPage; i++) { - if (m_is_region_free[i]) { - return false; - } - } - return true; + return std::ranges::all_of(m_is_region_free.begin(), m_is_region_free.end(), + [](bool is_free) { return !is_free; }); } bool IsAllFree() const { - for (size_t i = 0; i < RegionsPerPage; i++) { - if (!m_is_region_free[i]) { - return false; - } - } - return true; + return std::ranges::all_of(m_is_region_free.begin(), m_is_region_free.end(), + [](bool is_free) { return is_free; }); } bool IsAnyUsed() const { diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index c1a43a70c..f9aa5cc98 100755 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -284,16 +284,16 @@ struct KernelCore::Impl { // Gets the dummy KThread for the caller, allocating a new one if this is the first time KThread* GetHostDummyThread() { - auto init_thread_ = [this](KThread* thread) { + auto initialize = [this](KThread* thread) { ASSERT(KThread::InitializeDummyThread(thread).IsSuccess()); thread->SetName(fmt::format("DummyThread:{}", GetHostThreadId())); return thread; }; - thread_local auto thread = KThread(system.Kernel()); - thread_local auto init_thread = init_thread_(&thread); + thread_local auto raw_thread = KThread(system.Kernel()); + thread_local auto thread = initialize(&raw_thread); - return &thread; + return thread; } /// Registers a CPU core thread by allocating a host thread ID for it diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp index 5ac7a4533..84b6406ef 100755 --- a/src/yuzu/configuration/config.cpp +++ b/src/yuzu/configuration/config.cpp @@ -1189,6 +1189,8 @@ void Config::SaveCpuValues() { WriteBasicSetting(Settings::values.cpuopt_misc_ir); WriteBasicSetting(Settings::values.cpuopt_reduce_misalign_checks); WriteBasicSetting(Settings::values.cpuopt_fastmem); + WriteBasicSetting(Settings::values.cpuopt_fastmem_exclusives); + WriteBasicSetting(Settings::values.cpuopt_recompile_exclusives); } qt_config->endGroup();