cpu: Treat the InvalidRegClass like the zero register.
This is a transitional step towards the InvalidRegClass taking over for the zero register. Change-Id: I423e1f6b5138d8bb41493f9febb3b28f333f9f00 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/49744 Maintainer: Gabe Black <gabe.black@gmail.com> Reviewed-by: Giacomo Travaglini <giacomo.travaglini@arm.com> Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
@@ -196,14 +196,20 @@ class CheckerCPU : public BaseCPU, public ExecContext
|
||||
void
|
||||
setRegOperand(const StaticInst *si, int idx, RegVal val) override
|
||||
{
|
||||
thread->setReg(si->destRegIdx(idx), val);
|
||||
const RegId& id = si->destRegIdx(idx);
|
||||
if (id.is(InvalidRegClass))
|
||||
return;
|
||||
thread->setReg(id, val);
|
||||
result.emplace(val);
|
||||
}
|
||||
|
||||
void
|
||||
setRegOperand(const StaticInst *si, int idx, const void *val) override
|
||||
{
|
||||
thread->setReg(si->destRegIdx(idx), val);
|
||||
const RegId& id = si->destRegIdx(idx);
|
||||
if (id.is(InvalidRegClass))
|
||||
return;
|
||||
thread->setReg(id, val);
|
||||
//TODO setVecResult, setVecPredResult setVecElemResult?
|
||||
}
|
||||
|
||||
|
||||
@@ -584,6 +584,8 @@ Checker<DynInstPtr>::copyResult(
|
||||
if (start_idx >= 0) {
|
||||
const RegId& idx = inst->destRegIdx(start_idx);
|
||||
switch (idx.classValue()) {
|
||||
case InvalidRegClass:
|
||||
break;
|
||||
case IntRegClass:
|
||||
thread->setIntReg(idx.index(), mismatch_val.as<RegVal>());
|
||||
break;
|
||||
@@ -612,6 +614,8 @@ Checker<DynInstPtr>::copyResult(
|
||||
const RegId& idx = inst->destRegIdx(i);
|
||||
res = inst->popResult();
|
||||
switch (idx.classValue()) {
|
||||
case InvalidRegClass:
|
||||
break;
|
||||
case IntRegClass:
|
||||
thread->setIntReg(idx.index(), res.as<RegVal>());
|
||||
break;
|
||||
|
||||
@@ -139,6 +139,9 @@ printRegName(std::ostream &os, const RegId& reg,
|
||||
{
|
||||
const auto ®_class = reg_classes.at(reg.classValue());
|
||||
switch (reg.classValue()) {
|
||||
case InvalidRegClass:
|
||||
os << 'z';
|
||||
break;
|
||||
case MiscRegClass:
|
||||
{
|
||||
RegIndex misc_reg = reg.index();
|
||||
|
||||
@@ -147,7 +147,10 @@ class ExecContext : public gem5::ExecContext
|
||||
RegVal
|
||||
getRegOperand(const StaticInst *si, int idx) override
|
||||
{
|
||||
return thread.getReg(si->srcRegIdx(idx));
|
||||
const RegId ® = si->srcRegIdx(idx);
|
||||
if (reg.is(InvalidRegClass))
|
||||
return 0;
|
||||
return thread.getReg(reg);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -165,6 +168,9 @@ class ExecContext : public gem5::ExecContext
|
||||
void
|
||||
setRegOperand(const StaticInst *si, int idx, RegVal val) override
|
||||
{
|
||||
const RegId ® = si->destRegIdx(idx);
|
||||
if (reg.is(InvalidRegClass))
|
||||
return;
|
||||
thread.setReg(si->destRegIdx(idx), val);
|
||||
}
|
||||
|
||||
|
||||
@@ -1103,6 +1103,7 @@ class DynInst : public ExecContext, public RefCounted
|
||||
setRegOperand(staticInst.get(), idx, &val);
|
||||
}
|
||||
break;
|
||||
case InvalidRegClass:
|
||||
case MiscRegClass:
|
||||
// no need to forward misc reg values
|
||||
break;
|
||||
@@ -1131,13 +1132,19 @@ class DynInst : public ExecContext, public RefCounted
|
||||
RegVal
|
||||
getRegOperand(const StaticInst *si, int idx) override
|
||||
{
|
||||
return cpu->getReg(renamedSrcIdx(idx));
|
||||
const PhysRegIdPtr reg = renamedSrcIdx(idx);
|
||||
if (reg->is(InvalidRegClass))
|
||||
return 0;
|
||||
return cpu->getReg(reg);
|
||||
}
|
||||
|
||||
void
|
||||
getRegOperand(const StaticInst *si, int idx, void *val) override
|
||||
{
|
||||
cpu->getReg(renamedSrcIdx(idx), val);
|
||||
const PhysRegIdPtr reg = renamedSrcIdx(idx);
|
||||
if (reg->is(InvalidRegClass))
|
||||
return;
|
||||
cpu->getReg(reg, val);
|
||||
}
|
||||
|
||||
void *
|
||||
@@ -1152,14 +1159,20 @@ class DynInst : public ExecContext, public RefCounted
|
||||
void
|
||||
setRegOperand(const StaticInst *si, int idx, RegVal val) override
|
||||
{
|
||||
cpu->setReg(renamedDestIdx(idx), val);
|
||||
const PhysRegIdPtr reg = renamedDestIdx(idx);
|
||||
if (reg->is(InvalidRegClass))
|
||||
return;
|
||||
cpu->setReg(reg, val);
|
||||
setResult(val);
|
||||
}
|
||||
|
||||
void
|
||||
setRegOperand(const StaticInst *si, int idx, const void *val) override
|
||||
{
|
||||
cpu->setReg(renamedDestIdx(idx), val);
|
||||
const PhysRegIdPtr reg = renamedDestIdx(idx);
|
||||
if (reg->is(InvalidRegClass))
|
||||
return;
|
||||
cpu->setReg(reg, val);
|
||||
//TODO setResult
|
||||
}
|
||||
};
|
||||
|
||||
@@ -252,7 +252,8 @@ ElasticTrace::updateRegDep(const DynInstConstPtr& dyn_inst)
|
||||
|
||||
const RegId& src_reg = dyn_inst->srcRegIdx(src_idx);
|
||||
if (!src_reg.is(MiscRegClass) &&
|
||||
!(src_reg.is(IntRegClass) && src_reg.index() == zeroReg)) {
|
||||
!((src_reg.is(IntRegClass) && src_reg.index() == zeroReg) ||
|
||||
src_reg.is(InvalidRegClass))) {
|
||||
// Get the physical register index of the i'th source register.
|
||||
PhysRegIdPtr phys_src_reg = dyn_inst->renamedSrcIdx(src_idx);
|
||||
DPRINTFR(ElasticTrace, "[sn:%lli] Check map for src reg"
|
||||
@@ -284,7 +285,8 @@ ElasticTrace::updateRegDep(const DynInstConstPtr& dyn_inst)
|
||||
// CC register and not a Misc register.
|
||||
const RegId& dest_reg = dyn_inst->destRegIdx(dest_idx);
|
||||
if (!dest_reg.is(MiscRegClass) &&
|
||||
!(dest_reg.is(IntRegClass) && dest_reg.index() == zeroReg)) {
|
||||
!((dest_reg.is(IntRegClass) && dest_reg.index() == zeroReg) ||
|
||||
dest_reg.is(InvalidRegClass))) {
|
||||
// Get the physical register index of the i'th destination
|
||||
// register.
|
||||
PhysRegIdPtr phys_dest_reg =
|
||||
|
||||
@@ -252,6 +252,8 @@ class PhysRegFile
|
||||
const RegIndex idx = phys_reg->index();
|
||||
|
||||
switch (type) {
|
||||
case InvalidRegClass:
|
||||
break;
|
||||
case IntRegClass:
|
||||
if (phys_reg->index() != zeroReg.index())
|
||||
intRegFile.reg(idx) = val;
|
||||
|
||||
@@ -1017,6 +1017,8 @@ Rename::renameSrcRegs(const DynInstPtr &inst, ThreadID tid)
|
||||
|
||||
renamed_reg = map->lookup(tc->flattenRegId(src_reg));
|
||||
switch (src_reg.classValue()) {
|
||||
case InvalidRegClass:
|
||||
break;
|
||||
case IntRegClass:
|
||||
stats.intLookups++;
|
||||
break;
|
||||
|
||||
@@ -82,6 +82,9 @@ SimpleRenameMap::rename(const RegId& arch_reg)
|
||||
if (arch_reg == zeroReg) {
|
||||
assert(prev_reg->index() == zeroReg.index());
|
||||
renamed_reg = prev_reg;
|
||||
} else if (arch_reg.is(InvalidRegClass)) {
|
||||
assert(prev_reg->is(InvalidRegClass));
|
||||
renamed_reg = prev_reg;
|
||||
} else if (prev_reg->getNumPinnedWrites() > 0) {
|
||||
// Do not rename if the register is pinned
|
||||
assert(arch_reg.getNumPinnedWrites() == 0); // Prevent pinning the
|
||||
|
||||
@@ -179,6 +179,8 @@ class UnifiedRenameMap
|
||||
private:
|
||||
std::array<SimpleRenameMap, CCRegClass + 1> renameMaps;
|
||||
|
||||
static inline PhysRegId invalidPhysRegId{};
|
||||
|
||||
/**
|
||||
* The register file object is used only to get PhysRegIdPtr
|
||||
* on MiscRegs, as they are stored in it.
|
||||
@@ -210,8 +212,7 @@ class UnifiedRenameMap
|
||||
RenameInfo
|
||||
rename(const RegId& arch_reg)
|
||||
{
|
||||
auto reg_class = arch_reg.classValue();
|
||||
if (reg_class == MiscRegClass) {
|
||||
if (!arch_reg.isRenameable()) {
|
||||
// misc regs aren't really renamed, just remapped
|
||||
PhysRegIdPtr phys_reg = lookup(arch_reg);
|
||||
// Set the new register to the previous one to keep the same
|
||||
@@ -219,7 +220,7 @@ class UnifiedRenameMap
|
||||
return RenameInfo(phys_reg, phys_reg);
|
||||
}
|
||||
|
||||
return renameMaps[reg_class].rename(arch_reg);
|
||||
return renameMaps[arch_reg.classValue()].rename(arch_reg);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -233,7 +234,9 @@ class UnifiedRenameMap
|
||||
lookup(const RegId& arch_reg) const
|
||||
{
|
||||
auto reg_class = arch_reg.classValue();
|
||||
if (reg_class == MiscRegClass) {
|
||||
if (reg_class == InvalidRegClass) {
|
||||
return &invalidPhysRegId;
|
||||
} else if (reg_class == MiscRegClass) {
|
||||
// misc regs aren't really renamed, they keep the same
|
||||
// mapping throughout the execution.
|
||||
return regFile->getMiscRegId(arch_reg.index());
|
||||
@@ -253,8 +256,7 @@ class UnifiedRenameMap
|
||||
setEntry(const RegId& arch_reg, PhysRegIdPtr phys_reg)
|
||||
{
|
||||
assert(phys_reg->is(arch_reg.classValue()));
|
||||
auto reg_class = arch_reg.classValue();
|
||||
if (reg_class == MiscRegClass) {
|
||||
if (!arch_reg.isRenameable()) {
|
||||
// Misc registers do not actually rename, so don't change
|
||||
// their mappings. We end up here when a commit or squash
|
||||
// tries to update or undo a hardwired misc reg nmapping,
|
||||
@@ -263,7 +265,7 @@ class UnifiedRenameMap
|
||||
return;
|
||||
}
|
||||
|
||||
return renameMaps[reg_class].setEntry(arch_reg, phys_reg);
|
||||
return renameMaps[arch_reg.classValue()].setEntry(arch_reg, phys_reg);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "base/compiler.hh"
|
||||
#include "base/logging.hh"
|
||||
#include "base/trace.hh"
|
||||
#include "cpu/reg_class.hh"
|
||||
#include "debug/Scoreboard.hh"
|
||||
@@ -85,17 +86,17 @@ class Scoreboard
|
||||
bool
|
||||
getReg(PhysRegIdPtr phys_reg) const
|
||||
{
|
||||
assert(phys_reg->flatIndex() < numPhysRegs);
|
||||
|
||||
if (phys_reg->isFixedMapping()) {
|
||||
// Fixed mapping regs are always ready
|
||||
return true;
|
||||
}
|
||||
|
||||
assert(phys_reg->flatIndex() < numPhysRegs);
|
||||
|
||||
bool ready = regScoreBoard[phys_reg->flatIndex()];
|
||||
|
||||
if (phys_reg->is(IntRegClass) && phys_reg->index() == zeroReg)
|
||||
assert(ready);
|
||||
gem5_assert(ready);
|
||||
|
||||
return ready;
|
||||
}
|
||||
@@ -104,14 +105,14 @@ class Scoreboard
|
||||
void
|
||||
setReg(PhysRegIdPtr phys_reg)
|
||||
{
|
||||
assert(phys_reg->flatIndex() < numPhysRegs);
|
||||
|
||||
if (phys_reg->isFixedMapping()) {
|
||||
// Fixed mapping regs are always ready, ignore attempts to change
|
||||
// that
|
||||
return;
|
||||
}
|
||||
|
||||
assert(phys_reg->flatIndex() < numPhysRegs);
|
||||
|
||||
DPRINTF(Scoreboard, "Setting reg %i (%s) as ready\n",
|
||||
phys_reg->index(), phys_reg->className());
|
||||
|
||||
@@ -122,14 +123,14 @@ class Scoreboard
|
||||
void
|
||||
unsetReg(PhysRegIdPtr phys_reg)
|
||||
{
|
||||
assert(phys_reg->flatIndex() < numPhysRegs);
|
||||
|
||||
if (phys_reg->isFixedMapping()) {
|
||||
// Fixed mapping regs are always ready, ignore attempts to
|
||||
// change that
|
||||
return;
|
||||
}
|
||||
|
||||
assert(phys_reg->flatIndex() < numPhysRegs);
|
||||
|
||||
// zero reg should never be marked unready
|
||||
if (phys_reg->is(IntRegClass) && phys_reg->index() == zeroReg)
|
||||
return;
|
||||
|
||||
@@ -167,7 +167,7 @@ class RegId
|
||||
bool
|
||||
isRenameable() const
|
||||
{
|
||||
return regClass != MiscRegClass;
|
||||
return regClass != MiscRegClass && regClass != InvalidRegClass;
|
||||
}
|
||||
|
||||
/** @return true if it is of the specified class. */
|
||||
|
||||
@@ -311,6 +311,8 @@ class SimpleExecContext : public ExecContext
|
||||
getRegOperand(const StaticInst *si, int idx) override
|
||||
{
|
||||
const RegId ® = si->srcRegIdx(idx);
|
||||
if (reg.is(InvalidRegClass))
|
||||
return 0;
|
||||
(*execContextStats.numRegReads[reg.classValue()])++;
|
||||
return thread->getReg(reg);
|
||||
}
|
||||
@@ -335,6 +337,8 @@ class SimpleExecContext : public ExecContext
|
||||
setRegOperand(const StaticInst *si, int idx, RegVal val) override
|
||||
{
|
||||
const RegId ® = si->destRegIdx(idx);
|
||||
if (reg.is(InvalidRegClass))
|
||||
return;
|
||||
(*execContextStats.numRegWrites[reg.classValue()])++;
|
||||
thread->setReg(reg, val);
|
||||
}
|
||||
|
||||
@@ -400,6 +400,9 @@ class SimpleThread : public ThreadState, public ThreadContext
|
||||
{
|
||||
const RegId reg = flattenRegId(arch_reg);
|
||||
|
||||
if (reg.is(InvalidRegClass))
|
||||
return;
|
||||
|
||||
const RegIndex idx = reg.index();
|
||||
|
||||
auto ®_file = regFiles[reg.classValue()];
|
||||
@@ -416,6 +419,9 @@ class SimpleThread : public ThreadState, public ThreadContext
|
||||
void
|
||||
setRegFlat(const RegId ®, RegVal val) override
|
||||
{
|
||||
if (reg.is(InvalidRegClass))
|
||||
return;
|
||||
|
||||
const RegIndex idx = reg.index();
|
||||
|
||||
auto ®_file = regFiles[reg.classValue()];
|
||||
|
||||
Reference in New Issue
Block a user