summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorJosJuice <josjuice@gmail.com>2021-06-29 16:55:05 +0200
committerJosJuice <josjuice@gmail.com>2023-11-28 18:59:31 +0100
commit8e9609df6e031568537550d9d193aaa650de3eed (patch)
tree5822ce2e8e1266c171d874f6080beb89535ffd4a /Source/Core
parent6cc4f593e54fbce4f9b8920ae4053549050e86a1 (diff)
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.
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/Core/PowerPC/JitArm64/Jit.cpp3
-rw-r--r--Source/Core/Core/PowerPC/JitArm64/JitArm64_RegCache.cpp21
-rw-r--r--Source/Core/Core/PowerPC/JitArm64/JitArm64_RegCache.h3
3 files changed, 27 insertions, 0 deletions
diff --git a/Source/Core/Core/PowerPC/JitArm64/Jit.cpp b/Source/Core/Core/PowerPC/JitArm64/Jit.cpp
index a2dc1cb6b7..9433e48b49 100644
--- a/Source/Core/Core/PowerPC/JitArm64/Jit.cpp
+++ b/Source/Core/Core/PowerPC/JitArm64/Jit.cpp
@@ -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;
diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_RegCache.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_RegCache.cpp
index d4e933aaf3..5da455cb61 100644
--- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_RegCache.cpp
+++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_RegCache.cpp
@@ -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);
diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_RegCache.h b/Source/Core/Core/PowerPC/JitArm64/JitArm64_RegCache.h
index fbe1f30134..dad43ce9ef 100644
--- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_RegCache.h
+++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_RegCache.h
@@ -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;