diff --git a/Source/Core/Core/PowerPC/Jit64Common/EmuCodeBlock.cpp b/Source/Core/Core/PowerPC/Jit64Common/EmuCodeBlock.cpp index 0fa9cfdcc0..9ea80d4d06 100644 --- a/Source/Core/Core/PowerPC/Jit64Common/EmuCodeBlock.cpp +++ b/Source/Core/Core/PowerPC/Jit64Common/EmuCodeBlock.cpp @@ -441,7 +441,7 @@ void EmuCodeBlock::SafeLoadToRegImmediate(X64Reg reg_value, u32 address, int acc BitSet32 registersInUse, bool signExtend) { // If the address is known to be RAM, just load it directly. - if (m_jit.jo.fastmem_arena && m_jit.m_mmu.IsOptimizableRAMAddress(address)) + if (m_jit.jo.fastmem_arena && m_jit.m_mmu.IsOptimizableRAMAddress(address, accessSize)) { UnsafeLoadToReg(reg_value, Imm32(address), accessSize, 0, signExtend); return; @@ -656,7 +656,7 @@ bool EmuCodeBlock::WriteToConstAddress(int accessSize, OpArg arg, u32 address, m_jit.js.fifoBytesSinceCheck += accessSize >> 3; return false; } - else if (m_jit.jo.fastmem_arena && m_jit.m_mmu.IsOptimizableRAMAddress(address)) + else if (m_jit.jo.fastmem_arena && m_jit.m_mmu.IsOptimizableRAMAddress(address, accessSize)) { WriteToConstRamAddress(accessSize, arg, address); return false; diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_LoadStore.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_LoadStore.cpp index 06d8d65b95..49e4d50617 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_LoadStore.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_LoadStore.cpp @@ -136,7 +136,7 @@ void JitArm64::SafeLoadToReg(u32 dest, s32 addr, s32 offsetReg, u32 flags, s32 o if (is_immediate) mmio_address = m_mmu.IsOptimizableMMIOAccess(imm_addr, access_size); - if (is_immediate && m_mmu.IsOptimizableRAMAddress(imm_addr)) + if (is_immediate && m_mmu.IsOptimizableRAMAddress(imm_addr, access_size)) { set_addr_reg_if_needed(); EmitBackpatchRoutine(flags, MemAccessMode::AlwaysFastAccess, dest_reg, XA, regs_in_use, @@ -308,7 +308,7 @@ void JitArm64::SafeStoreFromReg(s32 dest, u32 value, s32 regOffset, u32 flags, s js.fifoBytesSinceCheck += accessSize >> 3; } - else if (is_immediate && m_mmu.IsOptimizableRAMAddress(imm_addr)) + else if (is_immediate && m_mmu.IsOptimizableRAMAddress(imm_addr, access_size)) { set_addr_reg_if_needed(); EmitBackpatchRoutine(flags, MemAccessMode::AlwaysFastAccess, RS, XA, regs_in_use, fprs_in_use); diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_LoadStoreFloating.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_LoadStoreFloating.cpp index 4fe8ca4cb3..0e471e355b 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_LoadStoreFloating.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_LoadStoreFloating.cpp @@ -174,7 +174,7 @@ void JitArm64::lfXX(UGeckoInstruction inst) if (!jo.memcheck) fprs_in_use[DecodeReg(VD)] = 0; - if (is_immediate && m_mmu.IsOptimizableRAMAddress(imm_addr)) + if (is_immediate && m_mmu.IsOptimizableRAMAddress(imm_addr, BackPatchInfo::GetFlagSize(flags))) { EmitBackpatchRoutine(flags, MemAccessMode::AlwaysFastAccess, VD, XA, regs_in_use, fprs_in_use); } @@ -399,7 +399,7 @@ void JitArm64::stfXX(UGeckoInstruction inst) STR(IndexType::Unsigned, ARM64Reg::X2, PPC_REG, PPCSTATE_OFF(gather_pipe_ptr)); js.fifoBytesSinceCheck += accessSize >> 3; } - else if (m_mmu.IsOptimizableRAMAddress(imm_addr)) + else if (m_mmu.IsOptimizableRAMAddress(imm_addr, BackPatchInfo::GetFlagSize(flags))) { set_addr_reg_if_needed(); EmitBackpatchRoutine(flags, MemAccessMode::AlwaysFastAccess, V0, XA, regs_in_use, diff --git a/Source/Core/Core/PowerPC/MMU.cpp b/Source/Core/Core/PowerPC/MMU.cpp index 4574657bad..49a85a3337 100644 --- a/Source/Core/Core/PowerPC/MMU.cpp +++ b/Source/Core/Core/PowerPC/MMU.cpp @@ -915,7 +915,7 @@ std::optional> MMU::HostTryReadString(const Core::CPUThr return ReadResult(c->translated, std::move(s)); } -bool MMU::IsOptimizableRAMAddress(const u32 address) const +bool MMU::IsOptimizableRAMAddress(const u32 address, const u32 access_size) const { if (m_power_pc.GetMemChecks().HasAny()) return false; @@ -926,12 +926,12 @@ bool MMU::IsOptimizableRAMAddress(const u32 address) const if (m_ppc_state.m_enable_dcache) return false; - // TODO: This API needs to take an access size - // // We store whether an access can be optimized to an unchecked access // in dbat_table. - u32 bat_result = m_dbat_table[address >> BAT_INDEX_SHIFT]; - return (bat_result & BAT_PHYSICAL_BIT) != 0; + const u32 last_byte_address = address + (access_size >> 3) - 1; + const u32 bat_result_1 = m_dbat_table[address >> BAT_INDEX_SHIFT]; + const u32 bat_result_2 = m_dbat_table[last_byte_address >> BAT_INDEX_SHIFT]; + return (bat_result_1 & bat_result_2 & BAT_PHYSICAL_BIT) != 0; } template diff --git a/Source/Core/Core/PowerPC/MMU.h b/Source/Core/Core/PowerPC/MMU.h index 3147802cbb..faf6776389 100644 --- a/Source/Core/Core/PowerPC/MMU.h +++ b/Source/Core/Core/PowerPC/MMU.h @@ -245,7 +245,7 @@ public: // Result changes based on the BAT registers and MSR.DR. Returns whether // it's safe to optimize a read or write to this address to an unguarded // memory access. Does not consider page tables. - bool IsOptimizableRAMAddress(u32 address) const; + bool IsOptimizableRAMAddress(u32 address, u32 access_size) const; u32 IsOptimizableMMIOAccess(u32 address, u32 access_size) const; bool IsOptimizableGatherPipeWrite(u32 address) const;