arch,cpu: Create register class descriptors.
These currently only hold the number of registers in a particular class, but can be extended in the future to hold other information about each class. The ISA class holds a vector of descriptors which other parts of gem5 can retrieve to set up storage for each class, etc. Currently, the RegClass enum is used to explicitly index into the vector of descriptors to get information about a particular class. Once enough information is stored in the descriptors, the other parts of gem5 should be able to set up for each register class generically, and the ISAs will be able to leave out or create new register classes without having to set up global plumbing for it. The more immediate benefit is that this should (mostly) parameterize away the ISA register constants to break another TheISA style dependency. Currently a global set of descriptors are set up in the BaseISA class using the old TheISA constants, but it should be easy to break those out and make the ISAs set up their own descriptors. That will bring arch/registers.hh significantly closer to being eliminated. Change-Id: I6d6d1256288f880391246b71045482a4a03c4198 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/41733 Reviewed-by: Gabe Black <gabe.black@gmail.com> Maintainer: Gabe Black <gabe.black@gmail.com> Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
@@ -40,23 +40,44 @@
|
||||
#ifndef __ARCH_GENERIC_ISA_HH__
|
||||
#define __ARCH_GENERIC_ISA_HH__
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "arch/registers.hh"
|
||||
#include "cpu/reg_class.hh"
|
||||
#include "sim/sim_object.hh"
|
||||
|
||||
class ThreadContext;
|
||||
|
||||
class BaseISA : public SimObject
|
||||
{
|
||||
public:
|
||||
typedef std::vector<RegClassInfo> RegClasses;
|
||||
|
||||
protected:
|
||||
using SimObject::SimObject;
|
||||
|
||||
ThreadContext *tc = nullptr;
|
||||
|
||||
RegClasses _regClasses = {
|
||||
#if THE_ISA != NULL_ISA
|
||||
{ TheISA::NumIntRegs },
|
||||
{ TheISA::NumFloatRegs },
|
||||
{ TheISA::NumVecRegs },
|
||||
{ TheISA::NumVecRegs * TheISA::NumVecElemPerVecReg },
|
||||
{ TheISA::NumVecPredRegs },
|
||||
{ TheISA::NumCCRegs },
|
||||
{ TheISA::NumMiscRegs }
|
||||
#endif // THE_ISA != NULL_ISA
|
||||
};
|
||||
|
||||
public:
|
||||
virtual void takeOverFrom(ThreadContext *new_tc, ThreadContext *old_tc) {}
|
||||
virtual void setThreadContext(ThreadContext *_tc) { tc = _tc; }
|
||||
|
||||
virtual uint64_t getExecutingAsid() const { return 0; }
|
||||
virtual bool inUserMode() const = 0;
|
||||
|
||||
const RegClasses ®Classes() const { return _regClasses; }
|
||||
};
|
||||
|
||||
#endif // __ARCH_GENERIC_ISA_HH__
|
||||
|
||||
@@ -175,8 +175,10 @@ Execute::Execute(const std::string &name_,
|
||||
name_ + ".inputBuffer" + tid_str, "insts",
|
||||
params.executeInputBufferSize));
|
||||
|
||||
const auto ®Classes = cpu.threads[tid]->getIsaPtr()->regClasses();
|
||||
|
||||
/* Scoreboards */
|
||||
scoreboard.push_back(Scoreboard(name_ + ".scoreboard" + tid_str));
|
||||
scoreboard.emplace_back(name_ + ".scoreboard" + tid_str, regClasses);
|
||||
|
||||
/* In-flight instruction records */
|
||||
executeInfo[tid].inFlightInsts = new Queue<QueuedInst,
|
||||
|
||||
@@ -61,27 +61,20 @@ Scoreboard::findIndex(const RegId& reg, Index &scoreboard_index)
|
||||
ret = true;
|
||||
break;
|
||||
case FloatRegClass:
|
||||
scoreboard_index = TheISA::NumIntRegs + TheISA::NumCCRegs +
|
||||
reg.index();
|
||||
scoreboard_index = floatRegOffset + reg.index();
|
||||
ret = true;
|
||||
break;
|
||||
case VecRegClass:
|
||||
scoreboard_index = TheISA::NumIntRegs + TheISA::NumCCRegs +
|
||||
TheISA::NumFloatRegs + reg.index();
|
||||
ret = true;
|
||||
break;
|
||||
case VecElemClass:
|
||||
scoreboard_index = TheISA::NumIntRegs + TheISA::NumCCRegs +
|
||||
TheISA::NumFloatRegs + reg.flatIndex();
|
||||
scoreboard_index = vecRegOffset + reg.index();
|
||||
ret = true;
|
||||
break;
|
||||
case VecPredRegClass:
|
||||
scoreboard_index = TheISA::NumIntRegs + TheISA::NumCCRegs +
|
||||
TheISA::NumFloatRegs + TheISA::NumVecRegs + reg.index();
|
||||
scoreboard_index = vecPredRegOffset + reg.index();
|
||||
ret = true;
|
||||
break;
|
||||
case CCRegClass:
|
||||
scoreboard_index = TheISA::NumIntRegs + reg.index();
|
||||
scoreboard_index = ccRegOffset + reg.index();
|
||||
ret = true;
|
||||
break;
|
||||
case MiscRegClass:
|
||||
|
||||
@@ -50,6 +50,7 @@
|
||||
#include "cpu/minor/cpu.hh"
|
||||
#include "cpu/minor/dyn_inst.hh"
|
||||
#include "cpu/minor/trace.hh"
|
||||
#include "cpu/reg_class.hh"
|
||||
|
||||
namespace Minor
|
||||
{
|
||||
@@ -60,6 +61,14 @@ namespace Minor
|
||||
class Scoreboard : public Named
|
||||
{
|
||||
public:
|
||||
const BaseISA::RegClasses regClasses;
|
||||
|
||||
const unsigned intRegOffset;
|
||||
const unsigned floatRegOffset;
|
||||
const unsigned ccRegOffset;
|
||||
const unsigned vecRegOffset;
|
||||
const unsigned vecPredRegOffset;
|
||||
|
||||
/** The number of registers in the Scoreboard. These
|
||||
* are just the integer, CC and float registers packed
|
||||
* together with integer regs in the range [0,NumIntRegs-1],
|
||||
@@ -92,12 +101,16 @@ class Scoreboard : public Named
|
||||
std::vector<InstSeqNum> writingInst;
|
||||
|
||||
public:
|
||||
Scoreboard(const std::string &name) :
|
||||
Scoreboard(const std::string &name,
|
||||
const BaseISA::RegClasses& reg_classes) :
|
||||
Named(name),
|
||||
numRegs(TheISA::NumIntRegs + TheISA::NumCCRegs +
|
||||
TheISA::NumFloatRegs +
|
||||
(TheISA::NumVecRegs * TheISA::NumVecElemPerVecReg) +
|
||||
TheISA::NumVecPredRegs),
|
||||
regClasses(reg_classes),
|
||||
intRegOffset(0),
|
||||
floatRegOffset(intRegOffset + reg_classes.at(IntRegClass).size()),
|
||||
ccRegOffset(floatRegOffset + reg_classes.at(FloatRegClass).size()),
|
||||
vecRegOffset(ccRegOffset + reg_classes.at(CCRegClass).size()),
|
||||
vecPredRegOffset(vecRegOffset + reg_classes.at(VecElemClass).size()),
|
||||
numRegs(vecPredRegOffset + reg_classes.at(VecPredRegClass).size()),
|
||||
numResults(numRegs, 0),
|
||||
numUnpredictableResults(numRegs, 0),
|
||||
fuIndices(numRegs, 0),
|
||||
|
||||
@@ -95,6 +95,7 @@ FullO3CPU<Impl>::FullO3CPU(const DerivO3CPUParams ¶ms)
|
||||
params.numPhysVecRegs,
|
||||
params.numPhysVecPredRegs,
|
||||
params.numPhysCCRegs,
|
||||
params.isa[0]->regClasses().at(MiscRegClass).size(),
|
||||
vecMode),
|
||||
|
||||
freeList(name() + ".freelist", ®File),
|
||||
@@ -194,12 +195,26 @@ FullO3CPU<Impl>::FullO3CPU(const DerivO3CPUParams ¶ms)
|
||||
}
|
||||
}
|
||||
|
||||
//Make Sure That this a Valid Architeture
|
||||
assert(params.numPhysIntRegs >= numThreads * TheISA::NumIntRegs);
|
||||
assert(params.numPhysFloatRegs >= numThreads * TheISA::NumFloatRegs);
|
||||
assert(params.numPhysVecRegs >= numThreads * TheISA::NumVecRegs);
|
||||
assert(params.numPhysVecPredRegs >= numThreads * TheISA::NumVecPredRegs);
|
||||
assert(params.numPhysCCRegs >= numThreads * TheISA::NumCCRegs);
|
||||
// Make Sure That this a Valid Architeture
|
||||
assert(numThreads);
|
||||
const auto ®Classes = params.isa[0]->regClasses();
|
||||
|
||||
assert(params.numPhysIntRegs >=
|
||||
numThreads * regClasses.at(IntRegClass).size());
|
||||
assert(params.numPhysFloatRegs >=
|
||||
numThreads * regClasses.at(FloatRegClass).size());
|
||||
assert(params.numPhysVecRegs >=
|
||||
numThreads * regClasses.at(VecRegClass).size());
|
||||
assert(params.numPhysVecPredRegs >=
|
||||
numThreads * regClasses.at(VecPredRegClass).size());
|
||||
assert(params.numPhysCCRegs >=
|
||||
numThreads * regClasses.at(CCRegClass).size());
|
||||
|
||||
// Just make this a warning and go ahead anyway, to keep from having to
|
||||
// add checks everywhere.
|
||||
warn_if(regClasses.at(CCRegClass).size() == 0 && params.numPhysCCRegs != 0,
|
||||
"Non-zero number of physical CC regs specified, even though\n"
|
||||
" ISA does not use them.");
|
||||
|
||||
rename.setScoreboard(&scoreboard);
|
||||
iew.setScoreboard(&scoreboard);
|
||||
@@ -213,19 +228,20 @@ FullO3CPU<Impl>::FullO3CPU(const DerivO3CPUParams ¶ms)
|
||||
// Only Alpha has an FP zero register, so for other ISAs we
|
||||
// use an invalid FP register index to avoid special treatment
|
||||
// of any valid FP reg.
|
||||
RegIndex invalidFPReg = TheISA::NumFloatRegs + 1;
|
||||
RegIndex invalidFPReg = regClasses.at(FloatRegClass).size() + 1;
|
||||
|
||||
commitRenameMap[tid].init(®File, TheISA::ZeroReg, invalidFPReg,
|
||||
&freeList, vecMode);
|
||||
commitRenameMap[tid].init(regClasses, ®File, TheISA::ZeroReg,
|
||||
invalidFPReg, &freeList, vecMode);
|
||||
|
||||
renameMap[tid].init(®File, TheISA::ZeroReg, invalidFPReg,
|
||||
&freeList, vecMode);
|
||||
renameMap[tid].init(regClasses, ®File, TheISA::ZeroReg,
|
||||
invalidFPReg, &freeList, vecMode);
|
||||
}
|
||||
|
||||
// Initialize rename map to assign physical registers to the
|
||||
// architectural registers for active threads only.
|
||||
for (ThreadID tid = 0; tid < active_threads; tid++) {
|
||||
for (RegIndex ridx = 0; ridx < TheISA::NumIntRegs; ++ridx) {
|
||||
for (RegIndex ridx = 0; ridx < regClasses.at(IntRegClass).size();
|
||||
++ridx) {
|
||||
// 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.getIntReg();
|
||||
@@ -233,7 +249,8 @@ FullO3CPU<Impl>::FullO3CPU(const DerivO3CPUParams ¶ms)
|
||||
commitRenameMap[tid].setEntry(RegId(IntRegClass, ridx), phys_reg);
|
||||
}
|
||||
|
||||
for (RegIndex ridx = 0; ridx < TheISA::NumFloatRegs; ++ridx) {
|
||||
for (RegIndex ridx = 0; ridx < regClasses.at(FloatRegClass).size();
|
||||
++ridx) {
|
||||
PhysRegIdPtr phys_reg = freeList.getFloatReg();
|
||||
renameMap[tid].setEntry(RegId(FloatRegClass, ridx), phys_reg);
|
||||
commitRenameMap[tid].setEntry(
|
||||
@@ -243,9 +260,10 @@ FullO3CPU<Impl>::FullO3CPU(const DerivO3CPUParams ¶ms)
|
||||
/* Here we need two 'interfaces' the 'whole register' and the
|
||||
* 'register element'. At any point only one of them will be
|
||||
* active. */
|
||||
const size_t numVecs = regClasses.at(VecRegClass).size();
|
||||
if (vecMode == Enums::Full) {
|
||||
/* Initialize the full-vector interface */
|
||||
for (RegIndex ridx = 0; ridx < TheISA::NumVecRegs; ++ridx) {
|
||||
for (RegIndex ridx = 0; ridx < numVecs; ++ridx) {
|
||||
RegId rid = RegId(VecRegClass, ridx);
|
||||
PhysRegIdPtr phys_reg = freeList.getVecReg();
|
||||
renameMap[tid].setEntry(rid, phys_reg);
|
||||
@@ -253,9 +271,10 @@ FullO3CPU<Impl>::FullO3CPU(const DerivO3CPUParams ¶ms)
|
||||
}
|
||||
} else {
|
||||
/* Initialize the vector-element interface */
|
||||
for (RegIndex ridx = 0; ridx < TheISA::NumVecRegs; ++ridx) {
|
||||
for (ElemIndex ldx = 0; ldx < TheISA::NumVecElemPerVecReg;
|
||||
++ldx) {
|
||||
const size_t numElems = regClasses.at(VecElemClass).size();
|
||||
const size_t elemsPerVec = numElems / numVecs;
|
||||
for (RegIndex ridx = 0; ridx < numVecs; ++ridx) {
|
||||
for (ElemIndex ldx = 0; ldx < elemsPerVec; ++ldx) {
|
||||
RegId lrid = RegId(VecElemClass, ridx, ldx);
|
||||
PhysRegIdPtr phys_elem = freeList.getVecElem();
|
||||
renameMap[tid].setEntry(lrid, phys_elem);
|
||||
@@ -264,14 +283,16 @@ FullO3CPU<Impl>::FullO3CPU(const DerivO3CPUParams ¶ms)
|
||||
}
|
||||
}
|
||||
|
||||
for (RegIndex ridx = 0; ridx < TheISA::NumVecPredRegs; ++ridx) {
|
||||
for (RegIndex ridx = 0; ridx < regClasses.at(VecPredRegClass).size();
|
||||
++ridx) {
|
||||
PhysRegIdPtr phys_reg = freeList.getVecPredReg();
|
||||
renameMap[tid].setEntry(RegId(VecPredRegClass, ridx), phys_reg);
|
||||
commitRenameMap[tid].setEntry(
|
||||
RegId(VecPredRegClass, ridx), phys_reg);
|
||||
}
|
||||
|
||||
for (RegIndex ridx = 0; ridx < TheISA::NumCCRegs; ++ridx) {
|
||||
for (RegIndex ridx = 0; ridx < regClasses.at(CCRegClass).size();
|
||||
++ridx) {
|
||||
PhysRegIdPtr phys_reg = freeList.getCCReg();
|
||||
renameMap[tid].setEntry(RegId(CCRegClass, ridx), phys_reg);
|
||||
commitRenameMap[tid].setEntry(RegId(CCRegClass, ridx), phys_reg);
|
||||
@@ -750,25 +771,29 @@ FullO3CPU<Impl>::insertThread(ThreadID tid)
|
||||
src_tc = tcBase(tid);
|
||||
|
||||
//Bind Int Regs to Rename Map
|
||||
const auto ®Classes = isa[tid]->regClasses();
|
||||
|
||||
for (RegId reg_id(IntRegClass, 0); reg_id.index() < TheISA::NumIntRegs;
|
||||
reg_id.index()++) {
|
||||
for (RegId reg_id(IntRegClass, 0);
|
||||
reg_id.index() < regClasses.at(IntRegClass).size();
|
||||
reg_id.index()++) {
|
||||
PhysRegIdPtr phys_reg = freeList.getIntReg();
|
||||
renameMap[tid].setEntry(reg_id, phys_reg);
|
||||
scoreboard.setReg(phys_reg);
|
||||
}
|
||||
|
||||
//Bind Float Regs to Rename Map
|
||||
for (RegId reg_id(FloatRegClass, 0); reg_id.index() < TheISA::NumFloatRegs;
|
||||
reg_id.index()++) {
|
||||
for (RegId reg_id(FloatRegClass, 0);
|
||||
reg_id.index() < regClasses.at(FloatRegClass).size();
|
||||
reg_id.index()++) {
|
||||
PhysRegIdPtr phys_reg = freeList.getFloatReg();
|
||||
renameMap[tid].setEntry(reg_id, phys_reg);
|
||||
scoreboard.setReg(phys_reg);
|
||||
}
|
||||
|
||||
//Bind condition-code Regs to Rename Map
|
||||
for (RegId reg_id(CCRegClass, 0); reg_id.index() < TheISA::NumCCRegs;
|
||||
reg_id.index()++) {
|
||||
for (RegId reg_id(CCRegClass, 0);
|
||||
reg_id.index() < regClasses.at(CCRegClass).size();
|
||||
reg_id.index()++) {
|
||||
PhysRegIdPtr phys_reg = freeList.getCCReg();
|
||||
renameMap[tid].setEntry(reg_id, phys_reg);
|
||||
scoreboard.setReg(phys_reg);
|
||||
@@ -845,21 +870,23 @@ template <class Impl>
|
||||
void
|
||||
FullO3CPU<Impl>::setVectorsAsReady(ThreadID tid)
|
||||
{
|
||||
const auto ®Classes = isa[tid]->regClasses();
|
||||
|
||||
const size_t numVecs = regClasses.at(VecRegClass).size();
|
||||
if (vecMode == Enums::Elem) {
|
||||
for (auto v = 0; v < TheISA::NumVecRegs; v++)
|
||||
for (auto e = 0; e < TheISA::NumVecElemPerVecReg; e++)
|
||||
scoreboard.setReg(
|
||||
commitRenameMap[tid].lookup(
|
||||
RegId(VecElemClass, v, e)
|
||||
)
|
||||
);
|
||||
const size_t numElems = regClasses.at(VecElemClass).size();
|
||||
const size_t elemsPerVec = numElems / numVecs;
|
||||
for (auto v = 0; v < numVecs; v++) {
|
||||
for (auto e = 0; e < elemsPerVec; e++) {
|
||||
scoreboard.setReg(commitRenameMap[tid].lookup(
|
||||
RegId(VecElemClass, v, e)));
|
||||
}
|
||||
}
|
||||
} else if (vecMode == Enums::Full) {
|
||||
for (auto v = 0; v < TheISA::NumVecRegs; v++)
|
||||
scoreboard.setReg(
|
||||
commitRenameMap[tid].lookup(
|
||||
RegId(VecRegClass, v)
|
||||
)
|
||||
);
|
||||
for (auto v = 0; v < numVecs; v++) {
|
||||
scoreboard.setReg(commitRenameMap[tid].lookup(
|
||||
RegId(VecRegClass, v)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -29,9 +29,7 @@
|
||||
|
||||
#include "cpu/o3/free_list.hh"
|
||||
|
||||
#include "arch/registers.hh"
|
||||
#include "base/trace.hh"
|
||||
#include "config/the_isa.hh"
|
||||
#include "debug/FreeList.hh"
|
||||
|
||||
UnifiedFreeList::UnifiedFreeList(const std::string &_my_name,
|
||||
|
||||
@@ -50,6 +50,7 @@ PhysRegFile::PhysRegFile(unsigned _numPhysicalIntRegs,
|
||||
unsigned _numPhysicalVecRegs,
|
||||
unsigned _numPhysicalVecPredRegs,
|
||||
unsigned _numPhysicalCCRegs,
|
||||
unsigned _numPhysicalMiscRegs,
|
||||
VecMode vmode)
|
||||
: intRegFile(_numPhysicalIntRegs),
|
||||
floatRegFile(_numPhysicalFloatRegs),
|
||||
@@ -74,12 +75,6 @@ PhysRegFile::PhysRegFile(unsigned _numPhysicalIntRegs,
|
||||
PhysRegIndex phys_reg;
|
||||
PhysRegIndex flat_reg_idx = 0;
|
||||
|
||||
if (TheISA::NumCCRegs == 0 && _numPhysicalCCRegs != 0) {
|
||||
// Just make this a warning and go ahead and allocate them
|
||||
// anyway, to keep from having to add checks everywhere
|
||||
warn("Non-zero number of physical CC regs specified, even though\n"
|
||||
" ISA does not use them.\n");
|
||||
}
|
||||
// The initial batch of registers are the integer ones
|
||||
for (phys_reg = 0; phys_reg < numPhysicalIntRegs; phys_reg++) {
|
||||
intRegIds.emplace_back(IntRegClass, phys_reg, flat_reg_idx++);
|
||||
@@ -121,7 +116,7 @@ PhysRegFile::PhysRegFile(unsigned _numPhysicalIntRegs,
|
||||
}
|
||||
|
||||
// Misc regs have a fixed mapping but still need PhysRegIds.
|
||||
for (phys_reg = 0; phys_reg < TheISA::NumMiscRegs; phys_reg++) {
|
||||
for (phys_reg = 0; phys_reg < _numPhysicalMiscRegs; phys_reg++) {
|
||||
miscRegIds.emplace_back(MiscRegClass, phys_reg, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,6 +136,7 @@ class PhysRegFile
|
||||
unsigned _numPhysicalVecRegs,
|
||||
unsigned _numPhysicalVecPredRegs,
|
||||
unsigned _numPhysicalCCRegs,
|
||||
unsigned _numPhysicalMiscRegs,
|
||||
VecMode vmode
|
||||
);
|
||||
|
||||
|
||||
@@ -44,8 +44,6 @@
|
||||
|
||||
#include <list>
|
||||
|
||||
#include "arch/registers.hh"
|
||||
#include "config/the_isa.hh"
|
||||
#include "cpu/o3/rename.hh"
|
||||
#include "cpu/reg_class.hh"
|
||||
#include "debug/Activity.hh"
|
||||
|
||||
@@ -43,25 +43,26 @@
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "arch/registers.hh"
|
||||
#include "cpu/reg_class.hh"
|
||||
#include "debug/Rename.hh"
|
||||
|
||||
/**** SimpleRenameMap methods ****/
|
||||
|
||||
SimpleRenameMap::SimpleRenameMap()
|
||||
: freeList(NULL), zeroReg(IntRegClass,0)
|
||||
: freeList(NULL), zeroReg(IntRegClass, 0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SimpleRenameMap::init(unsigned size, SimpleFreeList *_freeList,
|
||||
RegIndex _zeroReg)
|
||||
SimpleRenameMap::init(const RegClassInfo ®_class_info,
|
||||
SimpleFreeList *_freeList, RegIndex _zeroReg)
|
||||
{
|
||||
assert(freeList == NULL);
|
||||
assert(map.empty());
|
||||
|
||||
map.resize(size);
|
||||
map.resize(reg_class_info.size());
|
||||
freeList = _freeList;
|
||||
zeroReg = RegId(IntRegClass, _zeroReg);
|
||||
}
|
||||
@@ -105,7 +106,8 @@ SimpleRenameMap::rename(const RegId& arch_reg)
|
||||
/**** UnifiedRenameMap methods ****/
|
||||
|
||||
void
|
||||
UnifiedRenameMap::init(PhysRegFile *_regFile,
|
||||
UnifiedRenameMap::init(const BaseISA::RegClasses ®Classes,
|
||||
PhysRegFile *_regFile,
|
||||
RegIndex _intZeroReg,
|
||||
RegIndex _floatZeroReg,
|
||||
UnifiedFreeList *freeList,
|
||||
@@ -114,18 +116,21 @@ UnifiedRenameMap::init(PhysRegFile *_regFile,
|
||||
regFile = _regFile;
|
||||
vecMode = _mode;
|
||||
|
||||
intMap.init(TheISA::NumIntRegs, &(freeList->intList), _intZeroReg);
|
||||
intMap.init(regClasses.at(IntRegClass), &(freeList->intList), _intZeroReg);
|
||||
|
||||
floatMap.init(TheISA::NumFloatRegs, &(freeList->floatList), _floatZeroReg);
|
||||
floatMap.init(regClasses.at(FloatRegClass), &(freeList->floatList),
|
||||
_floatZeroReg);
|
||||
|
||||
vecMap.init(TheISA::NumVecRegs, &(freeList->vecList), (RegIndex)-1);
|
||||
vecMap.init(regClasses.at(VecRegClass), &(freeList->vecList),
|
||||
(RegIndex)-1);
|
||||
|
||||
vecElemMap.init(TheISA::NumVecRegs * TheISA::NumVecElemPerVecReg,
|
||||
&(freeList->vecElemList), (RegIndex)-1);
|
||||
vecElemMap.init(regClasses.at(VecElemClass), &(freeList->vecElemList),
|
||||
(RegIndex)-1);
|
||||
|
||||
predMap.init(TheISA::NumVecPredRegs, &(freeList->predList), (RegIndex)-1);
|
||||
predMap.init(regClasses.at(VecPredRegClass), &(freeList->predList),
|
||||
(RegIndex)-1);
|
||||
|
||||
ccMap.init(TheISA::NumCCRegs, &(freeList->ccList), (RegIndex)-1);
|
||||
ccMap.init(regClasses.at(CCRegClass), &(freeList->ccList), (RegIndex)-1);
|
||||
|
||||
}
|
||||
|
||||
@@ -138,7 +143,7 @@ UnifiedRenameMap::switchFreeList(UnifiedFreeList* freeList)
|
||||
panic_if(freeList->hasFreeVecElems(),
|
||||
"The free list is already tracking Vec elems");
|
||||
panic_if(freeList->numFreeVecRegs() !=
|
||||
regFile->numVecPhysRegs() - TheISA::NumVecRegs,
|
||||
regFile->numVecPhysRegs() - vecMap.numArchRegs(),
|
||||
"The free list has lost vector registers");
|
||||
|
||||
/* Split the free regs. */
|
||||
@@ -154,12 +159,11 @@ UnifiedRenameMap::switchFreeList(UnifiedFreeList* freeList)
|
||||
panic_if(freeList->hasFreeVecRegs(),
|
||||
"The free list is already tracking full Vec");
|
||||
panic_if(freeList->numFreeVecElems() !=
|
||||
regFile->numVecElemPhysRegs() -
|
||||
TheISA::NumVecRegs * TheISA::NumVecElemPerVecReg,
|
||||
regFile->numVecElemPhysRegs() - vecElemMap.numArchRegs(),
|
||||
"The free list has lost vector register elements");
|
||||
|
||||
auto range = regFile->getRegIds(VecRegClass);
|
||||
freeList->addRegs(range.first + TheISA::NumVecRegs, range.second);
|
||||
freeList->addRegs(range.first + vecMap.numArchRegs(), range.second);
|
||||
|
||||
/* We remove the elems from the free list. */
|
||||
while (freeList->hasFreeVecElems())
|
||||
@@ -198,23 +202,26 @@ UnifiedRenameMap::switchMode(VecMode newVecMode)
|
||||
* 2.- Replace the contents of the register file with the vectors
|
||||
* 3.- Set the remaining registers as free
|
||||
*/
|
||||
TheISA::VecRegContainer new_RF[TheISA::NumVecRegs];
|
||||
for (uint32_t i = 0; i < TheISA::NumVecRegs; i++) {
|
||||
TheISA::VecRegContainer new_RF[vecMap.numArchRegs()];
|
||||
const size_t numVecs = vecMap.numArchRegs();
|
||||
const size_t numElems = vecElemMap.numArchRegs();
|
||||
const size_t elemsPerVec = numElems / numVecs;
|
||||
for (uint32_t i = 0; i < numVecs; i++) {
|
||||
TheISA::VecReg dst = new_RF[i].as<TheISA::VecElem>();
|
||||
for (uint32_t l = 0; l < TheISA::NumVecElemPerVecReg; l++) {
|
||||
for (uint32_t l = 0; l < elemsPerVec; l++) {
|
||||
RegId s_rid(VecElemClass, i, l);
|
||||
PhysRegIdPtr s_prid = vecElemMap.lookup(s_rid);
|
||||
dst[l] = regFile->readVecElem(s_prid);
|
||||
}
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < TheISA::NumVecRegs; i++) {
|
||||
for (uint32_t i = 0; i < numVecs; i++) {
|
||||
PhysRegId pregId(VecRegClass, i, 0);
|
||||
regFile->setVecReg(regFile->getTrueId(&pregId), new_RF[i]);
|
||||
}
|
||||
|
||||
auto range = regFile->getRegIds(VecRegClass);
|
||||
for (uint32_t i = 0; i < TheISA::NumVecRegs; i++) {
|
||||
for (uint32_t i = 0; i < numVecs; i++) {
|
||||
setEntry(RegId(VecRegClass, i), &(*(range.first + i)));
|
||||
}
|
||||
|
||||
|
||||
@@ -90,14 +90,13 @@ class SimpleRenameMap
|
||||
|
||||
SimpleRenameMap();
|
||||
|
||||
~SimpleRenameMap() {};
|
||||
|
||||
/**
|
||||
* Because we have an array of rename maps (one per thread) in the CPU,
|
||||
* it's awkward to initialize this object via the constructor.
|
||||
* Instead, this method is used for initialization.
|
||||
*/
|
||||
void init(unsigned size, SimpleFreeList *_freeList, RegIndex _zeroReg);
|
||||
void init(const RegClassInfo ®_class_info, SimpleFreeList *_freeList,
|
||||
RegIndex _zeroReg);
|
||||
|
||||
/**
|
||||
* Pair of a physical register and a physical register. Used to
|
||||
@@ -144,6 +143,8 @@ class SimpleRenameMap
|
||||
/** Return the number of free entries on the associated free list. */
|
||||
unsigned numFreeEntries() const { return freeList->numFreeRegs(); }
|
||||
|
||||
size_t numArchRegs() const { return map.size(); }
|
||||
|
||||
/** Forward begin/cbegin to the map. */
|
||||
/** @{ */
|
||||
iterator begin() { return map.begin(); }
|
||||
@@ -207,7 +208,8 @@ class UnifiedRenameMap
|
||||
~UnifiedRenameMap() {};
|
||||
|
||||
/** Initializes rename map with given parameters. */
|
||||
void init(PhysRegFile *_regFile,
|
||||
void init(const BaseISA::RegClasses ®Classes,
|
||||
PhysRegFile *_regFile,
|
||||
RegIndex _intZeroReg,
|
||||
RegIndex _floatZeroReg,
|
||||
UnifiedFreeList *freeList,
|
||||
|
||||
@@ -61,6 +61,17 @@ enum RegClass {
|
||||
MiscRegClass ///< Control (misc) register
|
||||
};
|
||||
|
||||
class RegClassInfo
|
||||
{
|
||||
private:
|
||||
size_t _size;
|
||||
|
||||
public:
|
||||
RegClassInfo(size_t new_size) : _size(new_size) {}
|
||||
|
||||
size_t size() const { return _size; }
|
||||
};
|
||||
|
||||
/** Number of register classes.
|
||||
* This value is not part of the enum, because putting it there makes the
|
||||
* compiler complain about unhandled cases in some switch statements.
|
||||
|
||||
@@ -74,22 +74,19 @@ SimpleThread::SimpleThread(BaseCPU *_cpu, int _thread_num, System *_sys,
|
||||
htmTransactionStarts(0), htmTransactionStops(0)
|
||||
{
|
||||
assert(isa);
|
||||
const auto ®Classes = isa->regClasses();
|
||||
intRegs.resize(regClasses.at(IntRegClass).size());
|
||||
floatRegs.resize(regClasses.at(FloatRegClass).size());
|
||||
vecRegs.resize(regClasses.at(VecRegClass).size());
|
||||
vecPredRegs.resize(regClasses.at(VecPredRegClass).size());
|
||||
ccRegs.resize(regClasses.at(CCRegClass).size());
|
||||
clearArchRegs();
|
||||
}
|
||||
|
||||
SimpleThread::SimpleThread(BaseCPU *_cpu, int _thread_num, System *_sys,
|
||||
BaseMMU *_mmu, BaseISA *_isa)
|
||||
: ThreadState(_cpu, _thread_num, NULL),
|
||||
isa(dynamic_cast<TheISA::ISA *>(_isa)),
|
||||
predicate(true), memAccPredicate(true),
|
||||
comInstEventQueue("instruction-based event queue"),
|
||||
system(_sys), mmu(_mmu), decoder(isa),
|
||||
htmTransactionStarts(0), htmTransactionStops(0)
|
||||
{
|
||||
assert(isa);
|
||||
|
||||
clearArchRegs();
|
||||
}
|
||||
: SimpleThread(_cpu, _thread_num, _sys, nullptr, _mmu, _isa)
|
||||
{}
|
||||
|
||||
void
|
||||
SimpleThread::takeOverFrom(ThreadContext *oldContext)
|
||||
|
||||
@@ -42,7 +42,8 @@
|
||||
#ifndef __CPU_SIMPLE_THREAD_HH__
|
||||
#define __CPU_SIMPLE_THREAD_HH__
|
||||
|
||||
#include <array>
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
|
||||
#include "arch/decoder.hh"
|
||||
#include "arch/generic/htm.hh"
|
||||
@@ -93,12 +94,11 @@ class SimpleThread : public ThreadState, public ThreadContext
|
||||
typedef ThreadContext::Status Status;
|
||||
|
||||
protected:
|
||||
std::array<RegVal, TheISA::NumFloatRegs> floatRegs;
|
||||
std::array<RegVal, TheISA::NumIntRegs> intRegs;
|
||||
std::array<TheISA::VecRegContainer, TheISA::NumVecRegs> vecRegs;
|
||||
std::array<TheISA::VecPredRegContainer, TheISA::NumVecPredRegs>
|
||||
vecPredRegs;
|
||||
std::array<RegVal, TheISA::NumCCRegs> ccRegs;
|
||||
std::vector<RegVal> floatRegs;
|
||||
std::vector<RegVal> intRegs;
|
||||
std::vector<TheISA::VecRegContainer> vecRegs;
|
||||
std::vector<TheISA::VecPredRegContainer> vecPredRegs;
|
||||
std::vector<RegVal> ccRegs;
|
||||
TheISA::ISA *const isa; // one "instance" of the current ISA.
|
||||
|
||||
TheISA::PCState _pcState;
|
||||
@@ -253,13 +253,13 @@ class SimpleThread : public ThreadState, public ThreadContext
|
||||
clearArchRegs() override
|
||||
{
|
||||
_pcState = 0;
|
||||
intRegs.fill(0);
|
||||
floatRegs.fill(0);
|
||||
std::fill(intRegs.begin(), intRegs.end(), 0);
|
||||
std::fill(floatRegs.begin(), floatRegs.end(), 0);
|
||||
for (auto &vec_reg: vecRegs)
|
||||
vec_reg.zero();
|
||||
for (auto &pred_reg: vecPredRegs)
|
||||
pred_reg.reset();
|
||||
ccRegs.fill(0);
|
||||
std::fill(ccRegs.begin(), ccRegs.end(), 0);
|
||||
isa->clear();
|
||||
}
|
||||
|
||||
@@ -270,8 +270,8 @@ class SimpleThread : public ThreadState, public ThreadContext
|
||||
readIntReg(RegIndex reg_idx) const override
|
||||
{
|
||||
int flatIndex = isa->flattenIntIndex(reg_idx);
|
||||
assert(flatIndex < TheISA::NumIntRegs);
|
||||
uint64_t regVal(readIntRegFlat(flatIndex));
|
||||
assert(flatIndex < intRegs.size());
|
||||
uint64_t regVal = readIntRegFlat(flatIndex);
|
||||
DPRINTF(IntRegs, "Reading int reg %d (%d) as %#x.\n",
|
||||
reg_idx, flatIndex, regVal);
|
||||
return regVal;
|
||||
@@ -281,8 +281,8 @@ class SimpleThread : public ThreadState, public ThreadContext
|
||||
readFloatReg(RegIndex reg_idx) const override
|
||||
{
|
||||
int flatIndex = isa->flattenFloatIndex(reg_idx);
|
||||
assert(flatIndex < TheISA::NumFloatRegs);
|
||||
RegVal regVal(readFloatRegFlat(flatIndex));
|
||||
assert(flatIndex < floatRegs.size());
|
||||
RegVal regVal = readFloatRegFlat(flatIndex);
|
||||
DPRINTF(FloatRegs, "Reading float reg %d (%d) bits as %#x.\n",
|
||||
reg_idx, flatIndex, regVal);
|
||||
return regVal;
|
||||
@@ -292,7 +292,7 @@ class SimpleThread : public ThreadState, public ThreadContext
|
||||
readVecReg(const RegId& reg) const override
|
||||
{
|
||||
int flatIndex = isa->flattenVecIndex(reg.index());
|
||||
assert(flatIndex < TheISA::NumVecRegs);
|
||||
assert(flatIndex < vecRegs.size());
|
||||
const TheISA::VecRegContainer& regVal = readVecRegFlat(flatIndex);
|
||||
DPRINTF(VecRegs, "Reading vector reg %d (%d) as %s.\n",
|
||||
reg.index(), flatIndex, regVal);
|
||||
@@ -303,7 +303,7 @@ class SimpleThread : public ThreadState, public ThreadContext
|
||||
getWritableVecReg(const RegId& reg) override
|
||||
{
|
||||
int flatIndex = isa->flattenVecIndex(reg.index());
|
||||
assert(flatIndex < TheISA::NumVecRegs);
|
||||
assert(flatIndex < vecRegs.size());
|
||||
TheISA::VecRegContainer& regVal = getWritableVecRegFlat(flatIndex);
|
||||
DPRINTF(VecRegs, "Reading vector reg %d (%d) as %s for modify.\n",
|
||||
reg.index(), flatIndex, regVal);
|
||||
@@ -314,7 +314,7 @@ class SimpleThread : public ThreadState, public ThreadContext
|
||||
readVecElem(const RegId ®) const override
|
||||
{
|
||||
int flatIndex = isa->flattenVecElemIndex(reg.index());
|
||||
assert(flatIndex < TheISA::NumVecRegs);
|
||||
assert(flatIndex < vecRegs.size());
|
||||
const TheISA::VecElem& regVal =
|
||||
readVecElemFlat(flatIndex, reg.elemIndex());
|
||||
DPRINTF(VecRegs, "Reading element %d of vector reg %d (%d) as"
|
||||
@@ -326,7 +326,7 @@ class SimpleThread : public ThreadState, public ThreadContext
|
||||
readVecPredReg(const RegId ®) const override
|
||||
{
|
||||
int flatIndex = isa->flattenVecPredIndex(reg.index());
|
||||
assert(flatIndex < TheISA::NumVecPredRegs);
|
||||
assert(flatIndex < vecPredRegs.size());
|
||||
const TheISA::VecPredRegContainer& regVal =
|
||||
readVecPredRegFlat(flatIndex);
|
||||
DPRINTF(VecPredRegs, "Reading predicate reg %d (%d) as %s.\n",
|
||||
@@ -338,7 +338,7 @@ class SimpleThread : public ThreadState, public ThreadContext
|
||||
getWritableVecPredReg(const RegId ®) override
|
||||
{
|
||||
int flatIndex = isa->flattenVecPredIndex(reg.index());
|
||||
assert(flatIndex < TheISA::NumVecPredRegs);
|
||||
assert(flatIndex < vecPredRegs.size());
|
||||
TheISA::VecPredRegContainer& regVal =
|
||||
getWritableVecPredRegFlat(flatIndex);
|
||||
DPRINTF(VecPredRegs,
|
||||
@@ -352,7 +352,7 @@ class SimpleThread : public ThreadState, public ThreadContext
|
||||
{
|
||||
int flatIndex = isa->flattenCCIndex(reg_idx);
|
||||
assert(0 <= flatIndex);
|
||||
assert(flatIndex < TheISA::NumCCRegs);
|
||||
assert(flatIndex < ccRegs.size());
|
||||
uint64_t regVal(readCCRegFlat(flatIndex));
|
||||
DPRINTF(CCRegs, "Reading CC reg %d (%d) as %#x.\n",
|
||||
reg_idx, flatIndex, regVal);
|
||||
@@ -363,7 +363,7 @@ class SimpleThread : public ThreadState, public ThreadContext
|
||||
setIntReg(RegIndex reg_idx, RegVal val) override
|
||||
{
|
||||
int flatIndex = isa->flattenIntIndex(reg_idx);
|
||||
assert(flatIndex < TheISA::NumIntRegs);
|
||||
assert(flatIndex < intRegs.size());
|
||||
DPRINTF(IntRegs, "Setting int reg %d (%d) to %#x.\n",
|
||||
reg_idx, flatIndex, val);
|
||||
setIntRegFlat(flatIndex, val);
|
||||
@@ -373,10 +373,10 @@ class SimpleThread : public ThreadState, public ThreadContext
|
||||
setFloatReg(RegIndex reg_idx, RegVal val) override
|
||||
{
|
||||
int flatIndex = isa->flattenFloatIndex(reg_idx);
|
||||
assert(flatIndex < TheISA::NumFloatRegs);
|
||||
assert(flatIndex < floatRegs.size());
|
||||
// XXX: Fix array out of bounds compiler error for gem5.fast
|
||||
// when checkercpu enabled
|
||||
if (flatIndex < TheISA::NumFloatRegs)
|
||||
if (flatIndex < floatRegs.size())
|
||||
setFloatRegFlat(flatIndex, val);
|
||||
DPRINTF(FloatRegs, "Setting float reg %d (%d) bits to %#x.\n",
|
||||
reg_idx, flatIndex, val);
|
||||
@@ -386,7 +386,7 @@ class SimpleThread : public ThreadState, public ThreadContext
|
||||
setVecReg(const RegId ®, const TheISA::VecRegContainer &val) override
|
||||
{
|
||||
int flatIndex = isa->flattenVecIndex(reg.index());
|
||||
assert(flatIndex < TheISA::NumVecRegs);
|
||||
assert(flatIndex < vecRegs.size());
|
||||
setVecRegFlat(flatIndex, val);
|
||||
DPRINTF(VecRegs, "Setting vector reg %d (%d) to %s.\n",
|
||||
reg.index(), flatIndex, val);
|
||||
@@ -396,7 +396,7 @@ class SimpleThread : public ThreadState, public ThreadContext
|
||||
setVecElem(const RegId ®, const TheISA::VecElem &val) override
|
||||
{
|
||||
int flatIndex = isa->flattenVecElemIndex(reg.index());
|
||||
assert(flatIndex < TheISA::NumVecRegs);
|
||||
assert(flatIndex < vecRegs.size());
|
||||
setVecElemFlat(flatIndex, reg.elemIndex(), val);
|
||||
DPRINTF(VecRegs, "Setting element %d of vector reg %d (%d) to"
|
||||
" %#x.\n", reg.elemIndex(), reg.index(), flatIndex, val);
|
||||
@@ -407,7 +407,7 @@ class SimpleThread : public ThreadState, public ThreadContext
|
||||
const TheISA::VecPredRegContainer &val) override
|
||||
{
|
||||
int flatIndex = isa->flattenVecPredIndex(reg.index());
|
||||
assert(flatIndex < TheISA::NumVecPredRegs);
|
||||
assert(flatIndex < vecPredRegs.size());
|
||||
setVecPredRegFlat(flatIndex, val);
|
||||
DPRINTF(VecPredRegs, "Setting predicate reg %d (%d) to %s.\n",
|
||||
reg.index(), flatIndex, val.print());
|
||||
@@ -417,7 +417,7 @@ class SimpleThread : public ThreadState, public ThreadContext
|
||||
setCCReg(RegIndex reg_idx, RegVal val) override
|
||||
{
|
||||
int flatIndex = isa->flattenCCIndex(reg_idx);
|
||||
assert(flatIndex < TheISA::NumCCRegs);
|
||||
assert(flatIndex < ccRegs.size());
|
||||
DPRINTF(CCRegs, "Setting CC reg %d (%d) to %#x.\n",
|
||||
reg_idx, flatIndex, val);
|
||||
setCCRegFlat(flatIndex, val);
|
||||
|
||||
@@ -54,10 +54,12 @@
|
||||
void
|
||||
ThreadContext::compare(ThreadContext *one, ThreadContext *two)
|
||||
{
|
||||
const auto ®Classes = one->getIsaPtr()->regClasses();
|
||||
|
||||
DPRINTF(Context, "Comparing thread contexts\n");
|
||||
|
||||
// First loop through the integer registers.
|
||||
for (int i = 0; i < TheISA::NumIntRegs; ++i) {
|
||||
for (int i = 0; i < regClasses.at(IntRegClass).size(); ++i) {
|
||||
RegVal t1 = one->readIntReg(i);
|
||||
RegVal t2 = two->readIntReg(i);
|
||||
if (t1 != t2)
|
||||
@@ -66,7 +68,7 @@ ThreadContext::compare(ThreadContext *one, ThreadContext *two)
|
||||
}
|
||||
|
||||
// Then loop through the floating point registers.
|
||||
for (int i = 0; i < TheISA::NumFloatRegs; ++i) {
|
||||
for (int i = 0; i < regClasses.at(FloatRegClass).size(); ++i) {
|
||||
RegVal t1 = one->readFloatReg(i);
|
||||
RegVal t2 = two->readFloatReg(i);
|
||||
if (t1 != t2)
|
||||
@@ -75,7 +77,7 @@ ThreadContext::compare(ThreadContext *one, ThreadContext *two)
|
||||
}
|
||||
|
||||
// Then loop through the vector registers.
|
||||
for (int i = 0; i < TheISA::NumVecRegs; ++i) {
|
||||
for (int i = 0; i < regClasses.at(VecRegClass).size(); ++i) {
|
||||
RegId rid(VecRegClass, i);
|
||||
const TheISA::VecRegContainer& t1 = one->readVecReg(rid);
|
||||
const TheISA::VecRegContainer& t2 = two->readVecReg(rid);
|
||||
@@ -85,7 +87,7 @@ ThreadContext::compare(ThreadContext *one, ThreadContext *two)
|
||||
}
|
||||
|
||||
// Then loop through the predicate registers.
|
||||
for (int i = 0; i < TheISA::NumVecPredRegs; ++i) {
|
||||
for (int i = 0; i < regClasses.at(VecPredRegClass).size(); ++i) {
|
||||
RegId rid(VecPredRegClass, i);
|
||||
const TheISA::VecPredRegContainer& t1 = one->readVecPredReg(rid);
|
||||
const TheISA::VecPredRegContainer& t2 = two->readVecPredReg(rid);
|
||||
@@ -94,7 +96,7 @@ ThreadContext::compare(ThreadContext *one, ThreadContext *two)
|
||||
i, t1, t2);
|
||||
}
|
||||
|
||||
for (int i = 0; i < TheISA::NumMiscRegs; ++i) {
|
||||
for (int i = 0; i < regClasses.at(MiscRegClass).size(); ++i) {
|
||||
RegVal t1 = one->readMiscRegNoEffect(i);
|
||||
RegVal t2 = two->readMiscRegNoEffect(i);
|
||||
if (t1 != t2)
|
||||
@@ -103,7 +105,7 @@ ThreadContext::compare(ThreadContext *one, ThreadContext *two)
|
||||
}
|
||||
|
||||
// loop through the Condition Code registers.
|
||||
for (int i = 0; i < TheISA::NumCCRegs; ++i) {
|
||||
for (int i = 0; i < regClasses.at(CCRegClass).size(); ++i) {
|
||||
RegVal t1 = one->readCCReg(i);
|
||||
RegVal t2 = two->readCCReg(i);
|
||||
if (t1 != t2)
|
||||
@@ -141,36 +143,45 @@ ThreadContext::quiesceTick(Tick resume)
|
||||
void
|
||||
serialize(const ThreadContext &tc, CheckpointOut &cp)
|
||||
{
|
||||
RegVal floatRegs[TheISA::NumFloatRegs];
|
||||
for (int i = 0; i < TheISA::NumFloatRegs; ++i)
|
||||
// Cast away the const so we can get the non-const ISA ptr, which we then
|
||||
// use to get the const register classes.
|
||||
auto &nc_tc = const_cast<ThreadContext &>(tc);
|
||||
const auto ®Classes = nc_tc.getIsaPtr()->regClasses();
|
||||
|
||||
const size_t numFloats = regClasses.at(FloatRegClass).size();
|
||||
RegVal floatRegs[numFloats];
|
||||
for (int i = 0; i < numFloats; ++i)
|
||||
floatRegs[i] = tc.readFloatRegFlat(i);
|
||||
// This is a bit ugly, but needed to maintain backwards
|
||||
// compatibility.
|
||||
arrayParamOut(cp, "floatRegs.i", floatRegs, TheISA::NumFloatRegs);
|
||||
arrayParamOut(cp, "floatRegs.i", floatRegs, numFloats);
|
||||
|
||||
std::vector<TheISA::VecRegContainer> vecRegs(TheISA::NumVecRegs);
|
||||
for (int i = 0; i < TheISA::NumVecRegs; ++i) {
|
||||
const size_t numVecs = regClasses.at(VecRegClass).size();
|
||||
std::vector<TheISA::VecRegContainer> vecRegs(numVecs);
|
||||
for (int i = 0; i < numVecs; ++i) {
|
||||
vecRegs[i] = tc.readVecRegFlat(i);
|
||||
}
|
||||
SERIALIZE_CONTAINER(vecRegs);
|
||||
|
||||
std::vector<TheISA::VecPredRegContainer>
|
||||
vecPredRegs(TheISA::NumVecPredRegs);
|
||||
for (int i = 0; i < TheISA::NumVecPredRegs; ++i) {
|
||||
const size_t numPreds = regClasses.at(VecPredRegClass).size();
|
||||
std::vector<TheISA::VecPredRegContainer> vecPredRegs(numPreds);
|
||||
for (int i = 0; i < numPreds; ++i) {
|
||||
vecPredRegs[i] = tc.readVecPredRegFlat(i);
|
||||
}
|
||||
SERIALIZE_CONTAINER(vecPredRegs);
|
||||
|
||||
RegVal intRegs[TheISA::NumIntRegs];
|
||||
for (int i = 0; i < TheISA::NumIntRegs; ++i)
|
||||
const size_t numInts = regClasses.at(IntRegClass).size();
|
||||
RegVal intRegs[numInts];
|
||||
for (int i = 0; i < numInts; ++i)
|
||||
intRegs[i] = tc.readIntRegFlat(i);
|
||||
SERIALIZE_ARRAY(intRegs, TheISA::NumIntRegs);
|
||||
SERIALIZE_ARRAY(intRegs, numInts);
|
||||
|
||||
if (TheISA::NumCCRegs) {
|
||||
RegVal ccRegs[TheISA::NumCCRegs];
|
||||
for (int i = 0; i < TheISA::NumCCRegs; ++i)
|
||||
const size_t numCcs = regClasses.at(CCRegClass).size();
|
||||
if (numCcs) {
|
||||
RegVal ccRegs[numCcs];
|
||||
for (int i = 0; i < numCcs; ++i)
|
||||
ccRegs[i] = tc.readCCRegFlat(i);
|
||||
SERIALIZE_ARRAY(ccRegs, TheISA::NumCCRegs);
|
||||
SERIALIZE_ARRAY(ccRegs, numCcs);
|
||||
}
|
||||
|
||||
tc.pcState().serialize(cp);
|
||||
@@ -181,35 +192,41 @@ serialize(const ThreadContext &tc, CheckpointOut &cp)
|
||||
void
|
||||
unserialize(ThreadContext &tc, CheckpointIn &cp)
|
||||
{
|
||||
RegVal floatRegs[TheISA::NumFloatRegs];
|
||||
const auto ®Classes = tc.getIsaPtr()->regClasses();
|
||||
|
||||
const size_t numFloats = regClasses.at(FloatRegClass).size();
|
||||
RegVal floatRegs[numFloats];
|
||||
// This is a bit ugly, but needed to maintain backwards
|
||||
// compatibility.
|
||||
arrayParamIn(cp, "floatRegs.i", floatRegs, TheISA::NumFloatRegs);
|
||||
for (int i = 0; i < TheISA::NumFloatRegs; ++i)
|
||||
arrayParamIn(cp, "floatRegs.i", floatRegs, numFloats);
|
||||
for (int i = 0; i < numFloats; ++i)
|
||||
tc.setFloatRegFlat(i, floatRegs[i]);
|
||||
|
||||
std::vector<TheISA::VecRegContainer> vecRegs(TheISA::NumVecRegs);
|
||||
const size_t numVecs = regClasses.at(VecRegClass).size();
|
||||
std::vector<TheISA::VecRegContainer> vecRegs(numVecs);
|
||||
UNSERIALIZE_CONTAINER(vecRegs);
|
||||
for (int i = 0; i < TheISA::NumVecRegs; ++i) {
|
||||
for (int i = 0; i < numVecs; ++i) {
|
||||
tc.setVecRegFlat(i, vecRegs[i]);
|
||||
}
|
||||
|
||||
std::vector<TheISA::VecPredRegContainer>
|
||||
vecPredRegs(TheISA::NumVecPredRegs);
|
||||
const size_t numPreds = regClasses.at(VecPredRegClass).size();
|
||||
std::vector<TheISA::VecPredRegContainer> vecPredRegs(numPreds);
|
||||
UNSERIALIZE_CONTAINER(vecPredRegs);
|
||||
for (int i = 0; i < TheISA::NumVecPredRegs; ++i) {
|
||||
for (int i = 0; i < numPreds; ++i) {
|
||||
tc.setVecPredRegFlat(i, vecPredRegs[i]);
|
||||
}
|
||||
|
||||
RegVal intRegs[TheISA::NumIntRegs];
|
||||
UNSERIALIZE_ARRAY(intRegs, TheISA::NumIntRegs);
|
||||
for (int i = 0; i < TheISA::NumIntRegs; ++i)
|
||||
const size_t numInts = regClasses.at(IntRegClass).size();
|
||||
RegVal intRegs[numInts];
|
||||
UNSERIALIZE_ARRAY(intRegs, numInts);
|
||||
for (int i = 0; i < numInts; ++i)
|
||||
tc.setIntRegFlat(i, intRegs[i]);
|
||||
|
||||
if (TheISA::NumCCRegs) {
|
||||
RegVal ccRegs[TheISA::NumCCRegs];
|
||||
UNSERIALIZE_ARRAY(ccRegs, TheISA::NumCCRegs);
|
||||
for (int i = 0; i < TheISA::NumCCRegs; ++i)
|
||||
const size_t numCcs = regClasses.at(CCRegClass).size();
|
||||
if (numCcs) {
|
||||
RegVal ccRegs[numCcs];
|
||||
UNSERIALIZE_ARRAY(ccRegs, numCcs);
|
||||
for (int i = 0; i < numCcs; ++i)
|
||||
tc.setCCRegFlat(i, ccRegs[i]);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user