From f4f189c51f2abf92ccf8f176bb0507b473f9d958 Mon Sep 17 00:00:00 2001 From: JosJuice Date: Mon, 3 Oct 2022 21:41:34 +0200 Subject: [PATCH] JitArm64: Rename BindToRegister parameters for clarity --- .../PowerPC/JitArm64/JitArm64_RegCache.cpp | 12 +++--- .../Core/PowerPC/JitArm64/JitArm64_RegCache.h | 43 ++++++++++++------- 2 files changed, 33 insertions(+), 22 deletions(-) diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_RegCache.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_RegCache.cpp index c9826fe681..3913cdff79 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_RegCache.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_RegCache.cpp @@ -343,7 +343,7 @@ void Arm64GPRCache::SetImmediate(const GuestRegInfo& guest_reg, u32 imm) reg.LoadToImm(imm); } -void Arm64GPRCache::BindToRegister(const GuestRegInfo& guest_reg, bool do_load, bool set_dirty) +void Arm64GPRCache::BindToRegister(const GuestRegInfo& guest_reg, bool will_read, bool will_write) { OpArg& reg = guest_reg.reg; const size_t bitsize = guest_reg.bitsize; @@ -355,8 +355,8 @@ void Arm64GPRCache::BindToRegister(const GuestRegInfo& guest_reg, bool do_load, { const ARM64Reg host_reg = bitsize != 64 ? GetReg() : EncodeRegTo64(GetReg()); reg.Load(host_reg); - reg.SetDirty(set_dirty); - if (do_load) + reg.SetDirty(will_write); + if (will_read) { ASSERT_MSG(DYNA_REC, reg_type != RegType::Discarded, "Attempted to load a discarded value"); m_emit->LDR(IndexType::Unsigned, host_reg, PPC_REG, u32(guest_reg.ppc_offset)); @@ -365,9 +365,9 @@ void Arm64GPRCache::BindToRegister(const GuestRegInfo& guest_reg, bool do_load, else if (reg_type == RegType::Immediate) { const ARM64Reg host_reg = bitsize != 64 ? GetReg() : EncodeRegTo64(GetReg()); - if (do_load || !set_dirty) + if (will_read || !will_write) { - // TODO: Emitting this instruction when (!do_load && !set_dirty) would be unnecessary if we + // TODO: Emitting this instruction when (!will_read && !will_write) would be unnecessary if we // had some way to indicate to Flush that the immediate value should be written to ppcState // even though there is a host register allocated m_emit->MOVI2R(host_reg, reg.GetImm()); @@ -376,7 +376,7 @@ void Arm64GPRCache::BindToRegister(const GuestRegInfo& guest_reg, bool do_load, // If the register had an immediate value, the register was effectively already dirty reg.SetDirty(true); } - else if (set_dirty) + else if (will_write) { reg.SetDirty(true); } diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_RegCache.h b/Source/Core/Core/PowerPC/JitArm64/JitArm64_RegCache.h index 33861f65b4..d814e846f2 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_RegCache.h +++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_RegCache.h @@ -272,28 +272,39 @@ public: // Binds a guest GPR to a host register, optionally loading its value. // - // Using set_dirty = false is a little trick that's useful when emulating a memory load that might - // have to be rolled back. (Don't use set_dirty = false in other circumstances.) By calling this - // function with set_dirty = false before performing the load, this function guarantees that the - // guest register will be marked as dirty (needing to be written back to ppcState) only if the - // guest register previously contained a value that needs to be written back to ppcState. + // preg: The guest register index. + // will_read: Whether the caller intends to read from the register. + // will_write: Whether the caller intends to write to the register. // - // This trick prevents a problem that would otherwise happen where the call to this function could - // allocate a new host register without writing anything to it (if do_load = false), and then - // later when preparing to jump to an exception handler, a call to Flush would write the old value - // in the host register to ppcState because the register was marked dirty. + // Normally, you should call this function if you intend to write to a register, and shouldn't + // call this function if you don't intend to write to a register. There is however one situation + // where calling this function with will_write = false is a useful trick: When emulating a memory + // load that might have to be rolled back. // - // If you call this with set_dirty = false, you must make sure to call this with set_dirty = true - // later. - void BindToRegister(size_t preg, bool do_load, bool set_dirty = true) + // By calling this function with will_write = false before performing the load, this function + // guarantees that the guest register will be marked as dirty (needing to be written back to + // ppcState) only if the guest register previously contained a value that needs to be written back + // to ppcState. This trick prevents the following problem that otherwise would happen: + // + // 1. The caller calls this function with will_read = false and will_write = true. + // 2. The guest register didn't have a host register allocated, so this function allocates one. + // 3. This function does *not* write anything to the host register, since will_read was false. + // 4. The caller emits code for the load. + // 5. The caller calls Flush (to emit code for jumping to an exception handler). + // 6. Flush writes the value in the host register to ppcState, even though it was a stale value. + // + // By calling this function with will_write = false before the Flush call, no stale values will be + // flushed. Just remember to call this function again with will_write = true after the Flush call. + void BindToRegister(size_t preg, bool will_read, bool will_write = true) { - BindToRegister(GetGuestGPR(preg), do_load, set_dirty); + BindToRegister(GetGuestGPR(preg), will_read, will_write); } // Binds a guest CR to a host register, optionally loading its value. - void BindCRToRegister(size_t preg, bool do_load, bool set_dirty = true) + // The description of BindToRegister above applies to this function as well. + void BindCRToRegister(size_t preg, bool will_read, bool will_write = true) { - BindToRegister(GetGuestCR(preg), do_load, set_dirty); + BindToRegister(GetGuestCR(preg), will_read, will_write); } BitSet32 GetCallerSavedUsed() const override; @@ -335,7 +346,7 @@ private: Arm64Gen::ARM64Reg R(const GuestRegInfo& guest_reg); void SetImmediate(const GuestRegInfo& guest_reg, u32 imm); - void BindToRegister(const GuestRegInfo& guest_reg, bool do_load, bool set_dirty = true); + void BindToRegister(const GuestRegInfo& guest_reg, bool will_read, bool will_write = true); void FlushRegisters(BitSet32 regs, bool maintain_state, Arm64Gen::ARM64Reg tmp_reg); void FlushCRRegisters(BitSet32 regs, bool maintain_state, Arm64Gen::ARM64Reg tmp_reg);