arch,cpu: Store pointers to RegClass-es instead of instances.

This lets us put the actual RegClass-es somewhere else and give them
names.

Change-Id: I51743d6956de632fa6498d3b5ef0a20939849464
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/49784
Maintainer: Giacomo Travaglini <giacomo.travaglini@arm.com>
Reviewed-by: Giacomo Travaglini <giacomo.travaglini@arm.com>
Tested-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Boris Shingarov <shingarov@labware.com>
This commit is contained in:
Gabe Black
2021-08-30 19:46:20 -07:00
parent 705351768c
commit 70289e72cd
36 changed files with 298 additions and 168 deletions

View File

@@ -137,7 +137,7 @@ static void
printRegName(std::ostream &os, const RegId& reg,
const BaseISA::RegClasses &reg_classes)
{
const auto &reg_class = reg_classes.at(reg.classValue());
const auto &reg_class = *reg_classes.at(reg.classValue());
switch (reg.classValue()) {
case InvalidRegClass:
os << 'z';

View File

@@ -112,12 +112,12 @@ class Scoreboard : public Named
Named(name),
regClasses(reg_classes),
intRegOffset(0),
floatRegOffset(intRegOffset + reg_classes.at(IntRegClass).numRegs()),
ccRegOffset(floatRegOffset + reg_classes.at(FloatRegClass).numRegs()),
vecRegOffset(ccRegOffset + reg_classes.at(CCRegClass).numRegs()),
floatRegOffset(intRegOffset + reg_classes.at(IntRegClass)->numRegs()),
ccRegOffset(floatRegOffset + reg_classes.at(FloatRegClass)->numRegs()),
vecRegOffset(ccRegOffset + reg_classes.at(CCRegClass)->numRegs()),
vecPredRegOffset(vecRegOffset +
reg_classes.at(VecElemClass).numRegs()),
numRegs(vecPredRegOffset + reg_classes.at(VecPredRegClass).numRegs()),
reg_classes.at(VecElemClass)->numRegs()),
numRegs(vecPredRegOffset + reg_classes.at(VecPredRegClass)->numRegs()),
numResults(numRegs, 0),
numUnpredictableResults(numRegs, 0),
fuIndices(numRegs, invalidFUIndex),

View File

@@ -194,19 +194,19 @@ CPU::CPU(const BaseO3CPUParams &params)
const auto &regClasses = params.isa[0]->regClasses();
assert(params.numPhysIntRegs >=
numThreads * regClasses.at(IntRegClass).numRegs());
numThreads * regClasses.at(IntRegClass)->numRegs());
assert(params.numPhysFloatRegs >=
numThreads * regClasses.at(FloatRegClass).numRegs());
numThreads * regClasses.at(FloatRegClass)->numRegs());
assert(params.numPhysVecRegs >=
numThreads * regClasses.at(VecRegClass).numRegs());
numThreads * regClasses.at(VecRegClass)->numRegs());
assert(params.numPhysVecPredRegs >=
numThreads * regClasses.at(VecPredRegClass).numRegs());
numThreads * regClasses.at(VecPredRegClass)->numRegs());
assert(params.numPhysCCRegs >=
numThreads * regClasses.at(CCRegClass).numRegs());
numThreads * regClasses.at(CCRegClass)->numRegs());
// Just make this a warning and go ahead anyway, to keep from having to
// add checks everywhere.
warn_if(regClasses.at(CCRegClass).numRegs() == 0 &&
warn_if(regClasses.at(CCRegClass)->numRegs() == 0 &&
params.numPhysCCRegs != 0,
"Non-zero number of physical CC regs specified, even though\n"
" ISA does not use them.");
@@ -226,7 +226,7 @@ CPU::CPU(const BaseO3CPUParams &params)
for (ThreadID tid = 0; tid < active_threads; tid++) {
for (auto type = (RegClassType)0; type <= CCRegClass;
type = (RegClassType)(type + 1)) {
for (auto &id: regClasses.at(type)) {
for (auto &id: *regClasses.at(type)) {
// Note that we can't use the rename() method because we don't
// want special treatment for the zero register at this point
PhysRegIdPtr phys_reg = freeList.getReg(type);
@@ -692,7 +692,7 @@ CPU::insertThread(ThreadID tid)
for (auto type = (RegClassType)0; type <= CCRegClass;
type = (RegClassType)(type + 1)) {
for (auto &id: regClasses.at(type)) {
for (auto &id: *regClasses.at(type)) {
PhysRegIdPtr phys_reg = freeList.getReg(type);
renameMap[tid].setEntry(id, phys_reg);
scoreboard.setReg(phys_reg);

View File

@@ -105,8 +105,8 @@ InstructionQueue::InstructionQueue(CPU *cpu_ptr, IEW *iew_ptr,
numPhysRegs = params.numPhysIntRegs + params.numPhysFloatRegs +
params.numPhysVecRegs +
params.numPhysVecRegs * (
reg_classes.at(VecElemClass).numRegs() /
reg_classes.at(VecRegClass).numRegs()) +
reg_classes.at(VecElemClass)->numRegs() /
reg_classes.at(VecRegClass)->numRegs()) +
params.numPhysVecPredRegs +
params.numPhysCCRegs;

View File

@@ -55,20 +55,21 @@ PhysRegFile::PhysRegFile(unsigned _numPhysicalIntRegs,
unsigned _numPhysicalVecPredRegs,
unsigned _numPhysicalCCRegs,
const BaseISA::RegClasses &reg_classes)
: intRegFile(reg_classes.at(IntRegClass), _numPhysicalIntRegs),
floatRegFile(reg_classes.at(FloatRegClass), _numPhysicalFloatRegs),
vectorRegFile(reg_classes.at(VecRegClass), _numPhysicalVecRegs),
vectorElemRegFile(reg_classes.at(VecElemClass), _numPhysicalVecRegs * (
reg_classes.at(VecElemClass).numRegs() /
reg_classes.at(VecRegClass).numRegs())),
vecPredRegFile(reg_classes.at(VecPredRegClass), _numPhysicalVecPredRegs),
ccRegFile(reg_classes.at(CCRegClass), _numPhysicalCCRegs),
: intRegFile(*reg_classes.at(IntRegClass), _numPhysicalIntRegs),
floatRegFile(*reg_classes.at(FloatRegClass), _numPhysicalFloatRegs),
vectorRegFile(*reg_classes.at(VecRegClass), _numPhysicalVecRegs),
vectorElemRegFile(*reg_classes.at(VecElemClass), _numPhysicalVecRegs * (
reg_classes.at(VecElemClass)->numRegs() /
reg_classes.at(VecRegClass)->numRegs())),
vecPredRegFile(*reg_classes.at(VecPredRegClass),
_numPhysicalVecPredRegs),
ccRegFile(*reg_classes.at(CCRegClass), _numPhysicalCCRegs),
numPhysicalIntRegs(_numPhysicalIntRegs),
numPhysicalFloatRegs(_numPhysicalFloatRegs),
numPhysicalVecRegs(_numPhysicalVecRegs),
numPhysicalVecElemRegs(_numPhysicalVecRegs * (
reg_classes.at(VecElemClass).numRegs() /
reg_classes.at(VecRegClass).numRegs())),
reg_classes.at(VecElemClass)->numRegs() /
reg_classes.at(VecRegClass)->numRegs())),
numPhysicalVecPredRegs(_numPhysicalVecPredRegs),
numPhysicalCCRegs(_numPhysicalCCRegs),
totalNumRegs(_numPhysicalIntRegs
@@ -116,7 +117,7 @@ PhysRegFile::PhysRegFile(unsigned _numPhysicalIntRegs,
}
// Misc regs have a fixed mapping but still need PhysRegIds.
for (phys_reg = 0; phys_reg < reg_classes.at(MiscRegClass).numRegs();
for (phys_reg = 0; phys_reg < reg_classes.at(MiscRegClass)->numRegs();
phys_reg++) {
miscRegIds.emplace_back(MiscRegClass, phys_reg, 0);
}

View File

@@ -114,7 +114,7 @@ UnifiedRenameMap::init(const BaseISA::RegClasses &regClasses,
regFile = _regFile;
for (int i = 0; i < renameMaps.size(); i++)
renameMaps[i].init(regClasses.at(i), &(freeList->freeLists[i]));
renameMaps[i].init(*regClasses.at(i), &(freeList->freeLists[i]));
}
bool

View File

@@ -71,12 +71,12 @@ SimpleThread::SimpleThread(BaseCPU *_cpu, int _thread_num, System *_sys,
BaseISA *_isa, InstDecoder *_decoder)
: ThreadState(_cpu, _thread_num, _process),
regFiles{{
{_isa->regClasses().at(IntRegClass)},
{_isa->regClasses().at(FloatRegClass)},
{_isa->regClasses().at(VecRegClass)},
{_isa->regClasses().at(VecElemClass)},
{_isa->regClasses().at(VecPredRegClass)},
{_isa->regClasses().at(CCRegClass)}
{*_isa->regClasses().at(IntRegClass)},
{*_isa->regClasses().at(FloatRegClass)},
{*_isa->regClasses().at(VecRegClass)},
{*_isa->regClasses().at(VecElemClass)},
{*_isa->regClasses().at(VecPredRegClass)},
{*_isa->regClasses().at(CCRegClass)}
}},
isa(dynamic_cast<TheISA::ISA *>(_isa)),
predicate(true), memAccPredicate(true),

View File

@@ -65,7 +65,7 @@ ThreadContext::compare(ThreadContext *one, ThreadContext *two)
DPRINTF(Context, "Comparing thread contexts\n");
// First loop through the integer registers.
for (auto &id: regClasses.at(IntRegClass)) {
for (auto &id: *regClasses.at(IntRegClass)) {
RegVal t1 = one->getReg(id);
RegVal t2 = two->getReg(id);
if (t1 != t2)
@@ -74,7 +74,7 @@ ThreadContext::compare(ThreadContext *one, ThreadContext *two)
}
// Then loop through the floating point registers.
for (auto &id: regClasses.at(FloatRegClass)) {
for (auto &id: *regClasses.at(FloatRegClass)) {
RegVal t1 = one->getReg(id);
RegVal t2 = two->getReg(id);
if (t1 != t2)
@@ -83,34 +83,34 @@ ThreadContext::compare(ThreadContext *one, ThreadContext *two)
}
// Then loop through the vector registers.
const auto &vec_class = regClasses.at(VecRegClass);
std::vector<uint8_t> vec1(vec_class.regBytes());
std::vector<uint8_t> vec2(vec_class.regBytes());
for (auto &id: regClasses.at(VecRegClass)) {
const auto *vec_class = regClasses.at(VecRegClass);
std::vector<uint8_t> vec1(vec_class->regBytes());
std::vector<uint8_t> vec2(vec_class->regBytes());
for (auto &id: *regClasses.at(VecRegClass)) {
one->getReg(id, vec1.data());
two->getReg(id, vec2.data());
if (vec1 != vec2) {
panic("Vec reg idx %d doesn't match, one: %#x, two: %#x",
id.index(), vec_class.valString(vec1.data()),
vec_class.valString(vec2.data()));
id.index(), vec_class->valString(vec1.data()),
vec_class->valString(vec2.data()));
}
}
// Then loop through the predicate registers.
const auto &vec_pred_class = regClasses.at(VecPredRegClass);
std::vector<uint8_t> pred1(vec_pred_class.regBytes());
std::vector<uint8_t> pred2(vec_pred_class.regBytes());
for (auto &id: regClasses.at(VecPredRegClass)) {
const auto *vec_pred_class = regClasses.at(VecPredRegClass);
std::vector<uint8_t> pred1(vec_pred_class->regBytes());
std::vector<uint8_t> pred2(vec_pred_class->regBytes());
for (auto &id: *regClasses.at(VecPredRegClass)) {
one->getReg(id, pred1.data());
two->getReg(id, pred2.data());
if (pred1 != pred2) {
panic("Pred reg idx %d doesn't match, one: %s, two: %s",
id.index(), vec_pred_class.valString(pred1.data()),
vec_pred_class.valString(pred2.data()));
id.index(), vec_pred_class->valString(pred1.data()),
vec_pred_class->valString(pred2.data()));
}
}
for (int i = 0; i < regClasses.at(MiscRegClass).numRegs(); ++i) {
for (int i = 0; i < regClasses.at(MiscRegClass)->numRegs(); ++i) {
RegVal t1 = one->readMiscRegNoEffect(i);
RegVal t2 = two->readMiscRegNoEffect(i);
if (t1 != t2)
@@ -119,7 +119,7 @@ ThreadContext::compare(ThreadContext *one, ThreadContext *two)
}
// loop through the Condition Code registers.
for (auto &id: regClasses.at(CCRegClass)) {
for (auto &id: *regClasses.at(CCRegClass)) {
RegVal t1 = one->getReg(id);
RegVal t2 = two->getReg(id);
if (t1 != t2)
@@ -215,36 +215,36 @@ serialize(const ThreadContext &tc, CheckpointOut &cp)
auto &nc_tc = const_cast<ThreadContext &>(tc);
const auto &regClasses = nc_tc.getIsaPtr()->regClasses();
const size_t numFloats = regClasses.at(FloatRegClass).numRegs();
const size_t numFloats = regClasses.at(FloatRegClass)->numRegs();
RegVal floatRegs[numFloats];
for (auto &id: regClasses.at(FloatRegClass))
for (auto &id: *regClasses.at(FloatRegClass))
floatRegs[id.index()] = tc.getRegFlat(id);
// This is a bit ugly, but needed to maintain backwards
// compatibility.
arrayParamOut(cp, "floatRegs.i", floatRegs, numFloats);
const size_t numVecs = regClasses.at(VecRegClass).numRegs();
const size_t numVecs = regClasses.at(VecRegClass)->numRegs();
std::vector<TheISA::VecRegContainer> vecRegs(numVecs);
for (auto &id: regClasses.at(VecRegClass))
for (auto &id: *regClasses.at(VecRegClass))
tc.getRegFlat(id, &vecRegs[id.index()]);
SERIALIZE_CONTAINER(vecRegs);
const size_t numPreds = regClasses.at(VecPredRegClass).numRegs();
const size_t numPreds = regClasses.at(VecPredRegClass)->numRegs();
std::vector<TheISA::VecPredRegContainer> vecPredRegs(numPreds);
for (auto &id: regClasses.at(VecPredRegClass))
for (auto &id: *regClasses.at(VecPredRegClass))
tc.getRegFlat(id, &vecPredRegs[id.index()]);
SERIALIZE_CONTAINER(vecPredRegs);
const size_t numInts = regClasses.at(IntRegClass).numRegs();
const size_t numInts = regClasses.at(IntRegClass)->numRegs();
RegVal intRegs[numInts];
for (auto &id: regClasses.at(IntRegClass))
for (auto &id: *regClasses.at(IntRegClass))
intRegs[id.index()] = tc.getRegFlat(id);
SERIALIZE_ARRAY(intRegs, numInts);
const size_t numCcs = regClasses.at(CCRegClass).numRegs();
const size_t numCcs = regClasses.at(CCRegClass)->numRegs();
if (numCcs) {
RegVal ccRegs[numCcs];
for (auto &id: regClasses.at(CCRegClass))
for (auto &id: *regClasses.at(CCRegClass))
ccRegs[id.index()] = tc.getRegFlat(id);
SERIALIZE_ARRAY(ccRegs, numCcs);
}
@@ -259,37 +259,37 @@ unserialize(ThreadContext &tc, CheckpointIn &cp)
{
const auto &regClasses = tc.getIsaPtr()->regClasses();
const size_t numFloats = regClasses.at(FloatRegClass).numRegs();
const size_t numFloats = regClasses.at(FloatRegClass)->numRegs();
RegVal floatRegs[numFloats];
// This is a bit ugly, but needed to maintain backwards
// compatibility.
arrayParamIn(cp, "floatRegs.i", floatRegs, numFloats);
for (auto &id: regClasses.at(FloatRegClass))
for (auto &id: *regClasses.at(FloatRegClass))
tc.setRegFlat(id, floatRegs[id.index()]);
const size_t numVecs = regClasses.at(VecRegClass).numRegs();
const size_t numVecs = regClasses.at(VecRegClass)->numRegs();
std::vector<TheISA::VecRegContainer> vecRegs(numVecs);
UNSERIALIZE_CONTAINER(vecRegs);
for (auto &id: regClasses.at(VecRegClass))
for (auto &id: *regClasses.at(VecRegClass))
tc.setRegFlat(id, &vecRegs[id.index()]);
const size_t numPreds = regClasses.at(VecPredRegClass).numRegs();
const size_t numPreds = regClasses.at(VecPredRegClass)->numRegs();
std::vector<TheISA::VecPredRegContainer> vecPredRegs(numPreds);
UNSERIALIZE_CONTAINER(vecPredRegs);
for (auto &id: regClasses.at(VecPredRegClass))
for (auto &id: *regClasses.at(VecPredRegClass))
tc.setRegFlat(id, &vecPredRegs[id.index()]);
const size_t numInts = regClasses.at(IntRegClass).numRegs();
const size_t numInts = regClasses.at(IntRegClass)->numRegs();
RegVal intRegs[numInts];
UNSERIALIZE_ARRAY(intRegs, numInts);
for (auto &id: regClasses.at(IntRegClass))
for (auto &id: *regClasses.at(IntRegClass))
tc.setRegFlat(id, intRegs[id.index()]);
const size_t numCcs = regClasses.at(CCRegClass).numRegs();
const size_t numCcs = regClasses.at(CCRegClass)->numRegs();
if (numCcs) {
RegVal ccRegs[numCcs];
UNSERIALIZE_ARRAY(ccRegs, numCcs);
for (auto &id: regClasses.at(CCRegClass))
for (auto &id: *regClasses.at(CCRegClass))
tc.setRegFlat(id, ccRegs[id.index()]);
}