JitArm64: Add flush/discard support for condition registers

By flushing the condition registers as soon as we no longer
need them, we reduce the register pressure.
This commit is contained in:
JosJuice 2021-06-29 16:55:05 +02:00
parent 6cc4f593e5
commit 8e9609df6e
3 changed files with 27 additions and 0 deletions

View File

@ -205,6 +205,7 @@ void JitArm64::FallBackToInterpreter(UGeckoInstruction inst)
// we must mark them as no longer discarded
gpr.ResetRegisters(js.op->regsOut);
fpr.ResetRegisters(js.op->GetFregsOut());
gpr.ResetCRRegisters(js.op->crOut);
if (js.op->opinfo->flags & FL_ENDBLOCK)
{
@ -1199,9 +1200,11 @@ bool JitArm64::DoJit(u32 em_address, JitBlock* b, u32 nextPC)
{
gpr.DiscardRegisters(op.gprDiscardable);
fpr.DiscardRegisters(op.fprDiscardable);
gpr.DiscardCRRegisters(op.crDiscardable);
}
gpr.StoreRegisters(~op.gprInUse & (op.regsIn | op.regsOut));
fpr.StoreRegisters(~op.fprInUse & (op.fregsIn | op.GetFregsOut()));
gpr.StoreCRRegisters(~op.crInUse & (op.crIn | op.crOut));
if (opinfo->flags & FL_LOADSTORE)
++js.numLoadStoreInst;

View File

@ -129,6 +129,8 @@ void Arm64RegCache::DiscardRegister(size_t preg)
{
OpArg& reg = m_guest_registers[preg];
ARM64Reg host_reg = reg.GetReg();
if (!IsVector(host_reg))
host_reg = EncodeRegTo32(host_reg);
reg.Discard();
if (host_reg != ARM64Reg::INVALID_REG)
@ -288,6 +290,25 @@ void Arm64GPRCache::FlushCRRegisters(BitSet8 regs, bool maintain_state, ARM64Reg
}
}
void Arm64GPRCache::DiscardCRRegisters(BitSet8 regs)
{
for (int i : regs)
DiscardRegister(GUEST_CR_OFFSET + i);
}
void Arm64GPRCache::ResetCRRegisters(BitSet8 regs)
{
for (int i : regs)
{
OpArg& reg = m_guest_registers[GUEST_CR_OFFSET + i];
ARM64Reg host_reg = reg.GetReg();
ASSERT_MSG(DYNA_REC, host_reg == ARM64Reg::INVALID_REG,
"Attempted to reset a loaded register (did you mean to flush it?)");
reg.Flush();
}
}
void Arm64GPRCache::Flush(FlushMode mode, ARM64Reg tmp_reg)
{
FlushRegisters(BitSet32(0xFFFFFFFF), mode == FlushMode::MaintainState, tmp_reg);

View File

@ -335,6 +335,9 @@ public:
FlushCRRegisters(regs, false, tmp_reg);
}
void DiscardCRRegisters(BitSet8 regs);
void ResetCRRegisters(BitSet8 regs);
protected:
// Get the order of the host registers
void GetAllocationOrder() override;