JitArm64: Rename BindToRegister parameters for clarity

This commit is contained in:
JosJuice 2022-10-03 21:41:34 +02:00
parent 42775eed36
commit f4f189c51f
2 changed files with 33 additions and 22 deletions

View File

@ -343,7 +343,7 @@ void Arm64GPRCache::SetImmediate(const GuestRegInfo& guest_reg, u32 imm)
reg.LoadToImm(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; OpArg& reg = guest_reg.reg;
const size_t bitsize = guest_reg.bitsize; 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()); const ARM64Reg host_reg = bitsize != 64 ? GetReg() : EncodeRegTo64(GetReg());
reg.Load(host_reg); reg.Load(host_reg);
reg.SetDirty(set_dirty); reg.SetDirty(will_write);
if (do_load) if (will_read)
{ {
ASSERT_MSG(DYNA_REC, reg_type != RegType::Discarded, "Attempted to load a discarded value"); 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)); 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) else if (reg_type == RegType::Immediate)
{ {
const ARM64Reg host_reg = bitsize != 64 ? GetReg() : EncodeRegTo64(GetReg()); 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 // had some way to indicate to Flush that the immediate value should be written to ppcState
// even though there is a host register allocated // even though there is a host register allocated
m_emit->MOVI2R(host_reg, reg.GetImm()); 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 // If the register had an immediate value, the register was effectively already dirty
reg.SetDirty(true); reg.SetDirty(true);
} }
else if (set_dirty) else if (will_write)
{ {
reg.SetDirty(true); reg.SetDirty(true);
} }

View File

@ -272,28 +272,39 @@ public:
// Binds a guest GPR to a host register, optionally loading its value. // 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 // preg: The guest register index.
// have to be rolled back. (Don't use set_dirty = false in other circumstances.) By calling this // will_read: Whether the caller intends to read from the register.
// function with set_dirty = false before performing the load, this function guarantees that the // will_write: Whether the caller intends to write to the register.
// 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 a problem that would otherwise happen where the call to this function could // Normally, you should call this function if you intend to write to a register, and shouldn't
// allocate a new host register without writing anything to it (if do_load = false), and then // call this function if you don't intend to write to a register. There is however one situation
// later when preparing to jump to an exception handler, a call to Flush would write the old value // where calling this function with will_write = false is a useful trick: When emulating a memory
// in the host register to ppcState because the register was marked dirty. // 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 // By calling this function with will_write = false before performing the load, this function
// later. // guarantees that the guest register will be marked as dirty (needing to be written back to
void BindToRegister(size_t preg, bool do_load, bool set_dirty = true) // 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. // 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; BitSet32 GetCallerSavedUsed() const override;
@ -335,7 +346,7 @@ private:
Arm64Gen::ARM64Reg R(const GuestRegInfo& guest_reg); Arm64Gen::ARM64Reg R(const GuestRegInfo& guest_reg);
void SetImmediate(const GuestRegInfo& guest_reg, u32 imm); 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 FlushRegisters(BitSet32 regs, bool maintain_state, Arm64Gen::ARM64Reg tmp_reg);
void FlushCRRegisters(BitSet32 regs, bool maintain_state, Arm64Gen::ARM64Reg tmp_reg); void FlushCRRegisters(BitSet32 regs, bool maintain_state, Arm64Gen::ARM64Reg tmp_reg);