From 2e955012b232a88f88ae7eb4f78d99b7a0dcdf8c Mon Sep 17 00:00:00 2001 From: MerryMage Date: Mon, 15 Oct 2018 21:00:53 +0100 Subject: [PATCH] JitRegCache: Add BindOrImm --- .../Core/PowerPC/Jit64/RegCache/CachedReg.h | 133 ++++++++++++------ .../PowerPC/Jit64/RegCache/JitRegCache.cpp | 35 ++--- .../Core/PowerPC/Jit64/RegCache/JitRegCache.h | 1 + 3 files changed, 110 insertions(+), 59 deletions(-) diff --git a/Source/Core/Core/PowerPC/Jit64/RegCache/CachedReg.h b/Source/Core/Core/PowerPC/Jit64/RegCache/CachedReg.h index 2755604247..127073b5cf 100644 --- a/Source/Core/Core/PowerPC/Jit64/RegCache/CachedReg.h +++ b/Source/Core/Core/PowerPC/Jit64/RegCache/CachedReg.h @@ -154,45 +154,74 @@ private: class RCConstraint { public: - bool IsActive() const { return realized || bind || write || read || kill_imm; } - bool IsRealized() const { return realized; } - - bool ShouldBind() const { return bind; } - bool ShouldLoad() const { return read; } - bool ShouldDirty() const { return write; } - bool ShouldKillImmediate() const { return kill_imm; } - bool ShouldBeRevertable() const { return revertable; } - - void Realized() { realized = true; } - void RealizedBound() + bool IsRealized() const { return realized != RealizedLoc::Invalid; } + bool IsActive() const { - realized = true; - bind = true; + return IsRealized() || write || read || kill_imm || kill_mem || revertable; } - void AddUse(RCMode mode) { AddConstraint(false, mode, false, false); } - void AddUseNoImm(RCMode mode) { AddConstraint(false, mode, true, false); } - void AddBind(RCMode mode) { AddConstraint(true, mode, false, false); } - void AddRevertableBind(RCMode mode) { AddConstraint(true, mode, false, true); } + bool ShouldLoad() const { return read; } + bool ShouldDirty() const { return write; } + bool ShouldBeRevertable() const { return revertable; } + bool ShouldKillImmediate() const { return kill_imm; } + bool ShouldKillMemory() const { return kill_mem; } + + enum class RealizedLoc + { + Invalid, + Bound, + Imm, + Mem, + }; + + void Realized(RealizedLoc loc) + { + realized = loc; + ASSERT(IsRealized()); + } + + enum class ConstraintLoc + { + Bound, + BoundOrImm, + BoundOrMem, + Any, + }; + + void AddUse(RCMode mode) { AddConstraint(mode, ConstraintLoc::Any, false); } + void AddUseNoImm(RCMode mode) { AddConstraint(mode, ConstraintLoc::BoundOrMem, false); } + void AddBindOrImm(RCMode mode) { AddConstraint(mode, ConstraintLoc::BoundOrImm, false); } + void AddBind(RCMode mode) { AddConstraint(mode, ConstraintLoc::Bound, false); } + void AddRevertableBind(RCMode mode) { AddConstraint(mode, ConstraintLoc::Bound, true); } private: - void AddConstraint(bool should_bind, RCMode mode, bool should_kill_imm, bool should_revertable) + void AddConstraint(RCMode mode, ConstraintLoc loc, bool should_revertable) { - if (realized) + if (IsRealized()) { - ASSERT(IsCompatible(should_bind, mode, should_kill_imm, should_revertable)); + ASSERT(IsCompatible(mode, loc, should_revertable)); return; } - if (should_bind) - bind = true; - - if (should_kill_imm) - kill_imm = true; - if (should_revertable) revertable = true; + switch (loc) + { + case ConstraintLoc::Bound: + kill_imm = true; + kill_mem = true; + break; + case ConstraintLoc::BoundOrImm: + kill_mem = true; + break; + case ConstraintLoc::BoundOrMem: + kill_imm = true; + break; + case ConstraintLoc::Any: + break; + } + switch (mode) { case RCMode::Read: @@ -208,30 +237,50 @@ private: } } - bool IsCompatible(bool should_bind, RCMode mode, bool should_kill_imm, bool should_revertable) + bool IsCompatible(RCMode mode, ConstraintLoc loc, bool should_revertable) const { - if (should_bind && !bind) - return false; - if (should_kill_imm && !kill_imm) - return false; if (should_revertable && !revertable) - return false; - - switch (mode) { - case RCMode::Read: - return read; - case RCMode::Write: - return write; - case RCMode::ReadWrite: - return read && write; + return false; } + + const bool is_loc_compatible = [&] { + switch (loc) + { + case ConstraintLoc::Bound: + return realized == RealizedLoc::Bound; + case ConstraintLoc::BoundOrImm: + return realized == RealizedLoc::Bound || realized == RealizedLoc::Imm; + case ConstraintLoc::BoundOrMem: + return realized == RealizedLoc::Bound || realized == RealizedLoc::Mem; + case ConstraintLoc::Any: + return true; + } + ASSERT(false); + return false; + }(); + + const bool is_mode_compatible = [&] { + switch (mode) + { + case RCMode::Read: + return read; + case RCMode::Write: + return write; + case RCMode::ReadWrite: + return read && write; + } + ASSERT(false); + return false; + }(); + + return is_loc_compatible && is_mode_compatible; } - bool realized = false; - bool bind = false; + RealizedLoc realized = RealizedLoc::Invalid; bool write = false; bool read = false; bool kill_imm = false; + bool kill_mem = false; bool revertable = false; }; diff --git a/Source/Core/Core/PowerPC/Jit64/RegCache/JitRegCache.cpp b/Source/Core/Core/PowerPC/Jit64/RegCache/JitRegCache.cpp index 4c02b739bb..1608c37a8d 100644 --- a/Source/Core/Core/PowerPC/Jit64/RegCache/JitRegCache.cpp +++ b/Source/Core/Core/PowerPC/Jit64/RegCache/JitRegCache.cpp @@ -610,18 +610,18 @@ RCOpArg RegCache::UseNoImm(preg_t preg, RCMode mode) return RCOpArg{this, preg}; } +RCOpArg RegCache::BindOrImm(preg_t preg, RCMode mode) +{ + m_constraints[preg].AddBindOrImm(mode); + return RCOpArg{this, preg}; +} + RCX64Reg RegCache::Bind(preg_t preg, RCMode mode) { m_constraints[preg].AddBind(mode); return RCX64Reg{this, preg}; } -RCX64Reg RegCache::BindOrImm(preg_t preg, RCMode mode) -{ - m_constraints[preg].AddBindOrImm(mode); - return RCX64Reg{this, preg}; -} - RCX64Reg RegCache::RevertableBind(preg_t preg, RCMode mode) { m_constraints[preg].AddRevertableBind(mode); @@ -704,10 +704,11 @@ void RegCache::Realize(preg_t preg) const bool load = m_constraints[preg].ShouldLoad(); const bool dirty = m_constraints[preg].ShouldDirty(); const bool kill_imm = m_constraints[preg].ShouldKillImmediate(); + const bool kill_mem = m_constraints[preg].ShouldKillMemory(); const auto do_bind = [&] { BindToRegister(preg, load, dirty); - m_constraints[preg].RealizedBound(); + m_constraints[preg].Realized(RCConstraint::RealizedLoc::Bound); }; if (m_constraints[preg].ShouldBeRevertable()) @@ -718,29 +719,29 @@ void RegCache::Realize(preg_t preg) return; } - if (m_constraints[preg].ShouldBind()) - { - do_bind(); - return; - } - switch (m_regs[preg].GetLocationType()) { case PPCCachedReg::LocationType::Default: - break; + if (kill_mem) + { + do_bind(); + return; + } + m_constraints[preg].Realized(RCConstraint::RealizedLoc::Mem); + return; case PPCCachedReg::LocationType::Bound: do_bind(); - break; + return; case PPCCachedReg::LocationType::Immediate: case PPCCachedReg::LocationType::SpeculativeImmediate: if (dirty || kill_imm) { do_bind(); + return; } + m_constraints[preg].Realized(RCConstraint::RealizedLoc::Imm); break; } - - m_constraints[preg].Realized(); } bool RegCache::IsAnyConstraintActive() const diff --git a/Source/Core/Core/PowerPC/Jit64/RegCache/JitRegCache.h b/Source/Core/Core/PowerPC/Jit64/RegCache/JitRegCache.h index 99cba2141e..5579d03328 100644 --- a/Source/Core/Core/PowerPC/Jit64/RegCache/JitRegCache.h +++ b/Source/Core/Core/PowerPC/Jit64/RegCache/JitRegCache.h @@ -234,6 +234,7 @@ public: RCOpArg Use(preg_t preg, RCMode mode); RCOpArg UseNoImm(preg_t preg, RCMode mode); + RCOpArg BindOrImm(preg_t preg, RCMode mode); RCX64Reg Bind(preg_t preg, RCMode mode); RCX64Reg RevertableBind(preg_t preg, RCMode mode); RCX64Reg Scratch(Gen::X64Reg xr);