JitRegCache: Add BindOrImm
This commit is contained in:
parent
590ec866b0
commit
2e955012b2
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue