arch, cpu: Architectural Register structural indexing

Replace the unified register mapping with a structure associating
a class and an index. It is now much easier to know which class of
register the index is referring to. Also, when adding a new class
there is no need to modify existing ones.

Change-Id: I55b3ac80763702aa2cd3ed2cbff0a75ef7620373
Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com>
[ Fix RISCV build issues ]
Signed-off-by: Andreas Sandberg <andreas.sandberg@arm.com>
Reviewed-on: https://gem5-review.googlesource.com/2700
This commit is contained in:
Nathanael Premillieu
2017-04-05 12:46:06 -05:00
committed by Andreas Sandberg
parent 864f87f9c5
commit 5e8287d2e2
70 changed files with 854 additions and 790 deletions

View File

@@ -82,9 +82,6 @@ class BaseDynInst : public ExecContext, public RefCounted
typedef typename Impl::CPUType ImplCPU;
typedef typename ImplCPU::ImplState ImplState;
// Logical register index type.
typedef TheISA::RegIndex RegIndex;
// The DynInstPtr type.
typedef typename Impl::DynInstPtr DynInstPtr;
typedef RefCountingPtr<BaseDynInst<Impl> > BaseDynInstPtr;
@@ -265,7 +262,7 @@ class BaseDynInst : public ExecContext, public RefCounted
/** Flattened register index of the destination registers of this
* instruction.
*/
std::array<TheISA::RegIndex, TheISA::MaxInstDestRegs> _flatDestRegIdx;
std::array<RegId, TheISA::MaxInstDestRegs> _flatDestRegIdx;
/** Physical register index of the destination registers of this
* instruction.
@@ -386,7 +383,7 @@ class BaseDynInst : public ExecContext, public RefCounted
/** Returns the flattened register index of the i'th destination
* register.
*/
TheISA::RegIndex flattenedDestRegIdx(int idx) const
RegId flattenedDestRegIdx(int idx) const
{
return _flatDestRegIdx[idx];
}
@@ -422,7 +419,7 @@ class BaseDynInst : public ExecContext, public RefCounted
/** Flattens a destination architectural register index into a logical
* index.
*/
void flattenDestReg(int idx, TheISA::RegIndex flattened_dest)
void flattenDestReg(int idx, RegId flattened_dest)
{
_flatDestRegIdx[idx] = flattened_dest;
}
@@ -604,10 +601,10 @@ class BaseDynInst : public ExecContext, public RefCounted
int8_t numCCDestRegs() const { return staticInst->numCCDestRegs(); }
/** Returns the logical register index of the i'th destination register. */
RegIndex destRegIdx(int i) const { return staticInst->destRegIdx(i); }
RegId destRegIdx(int i) const { return staticInst->destRegIdx(i); }
/** Returns the logical register index of the i'th source register. */
RegIndex srcRegIdx(int i) const { return staticInst->srcRegIdx(i); }
RegId srcRegIdx(int i) const { return staticInst->srcRegIdx(i); }
/** Pops a result off the instResult queue */
template <class T>

View File

@@ -213,26 +213,31 @@ class CheckerCPU : public BaseCPU, public ExecContext
IntReg readIntRegOperand(const StaticInst *si, int idx) override
{
return thread->readIntReg(si->srcRegIdx(idx));
RegId reg = si->srcRegIdx(idx);
assert(reg.regClass == IntRegClass);
return thread->readIntReg(reg.regIdx);
}
FloatReg readFloatRegOperand(const StaticInst *si, int idx) override
{
int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Reg_Base;
return thread->readFloatReg(reg_idx);
RegId reg = si->srcRegIdx(idx);
assert(reg.regClass == FloatRegClass);
return thread->readFloatReg(reg.regIdx);
}
FloatRegBits readFloatRegOperandBits(const StaticInst *si,
int idx) override
{
int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Reg_Base;
return thread->readFloatRegBits(reg_idx);
RegId reg = si->srcRegIdx(idx);
assert(reg.regClass == FloatRegClass);
return thread->readFloatRegBits(reg.regIdx);
}
CCReg readCCRegOperand(const StaticInst *si, int idx) override
{
int reg_idx = si->srcRegIdx(idx) - TheISA::CC_Reg_Base;
return thread->readCCReg(reg_idx);
RegId reg = si->srcRegIdx(idx);
assert(reg.regClass == CCRegClass);
return thread->readCCReg(reg.regIdx);
}
template <class T>
@@ -246,30 +251,35 @@ class CheckerCPU : public BaseCPU, public ExecContext
void setIntRegOperand(const StaticInst *si, int idx,
IntReg val) override
{
thread->setIntReg(si->destRegIdx(idx), val);
RegId reg = si->destRegIdx(idx);
assert(reg.regClass == IntRegClass);
thread->setIntReg(reg.regIdx, val);
setResult<uint64_t>(val);
}
void setFloatRegOperand(const StaticInst *si, int idx,
FloatReg val) override
{
int reg_idx = si->destRegIdx(idx) - TheISA::FP_Reg_Base;
thread->setFloatReg(reg_idx, val);
RegId reg = si->destRegIdx(idx);
assert(reg.regClass == FloatRegClass);
thread->setFloatReg(reg.regIdx, val);
setResult<double>(val);
}
void setFloatRegOperandBits(const StaticInst *si, int idx,
FloatRegBits val) override
{
int reg_idx = si->destRegIdx(idx) - TheISA::FP_Reg_Base;
thread->setFloatRegBits(reg_idx, val);
RegId reg = si->destRegIdx(idx);
assert(reg.regClass == FloatRegClass);
thread->setFloatRegBits(reg.regIdx, val);
setResult<uint64_t>(val);
}
void setCCRegOperand(const StaticInst *si, int idx, CCReg val) override
{
int reg_idx = si->destRegIdx(idx) - TheISA::CC_Reg_Base;
thread->setCCReg(reg_idx, val);
RegId reg = si->destRegIdx(idx);
assert(reg.regClass == CCRegClass);
thread->setCCReg(reg.regIdx, val);
setResult<uint64_t>(val);
}
@@ -317,25 +327,27 @@ class CheckerCPU : public BaseCPU, public ExecContext
MiscReg readMiscRegOperand(const StaticInst *si, int idx) override
{
int reg_idx = si->srcRegIdx(idx) - TheISA::Misc_Reg_Base;
return thread->readMiscReg(reg_idx);
RegId reg = si->srcRegIdx(idx);
assert(reg.regClass == MiscRegClass);
return thread->readMiscReg(reg.regIdx);
}
void setMiscRegOperand(const StaticInst *si, int idx,
const MiscReg &val) override
{
int reg_idx = si->destRegIdx(idx) - TheISA::Misc_Reg_Base;
return this->setMiscReg(reg_idx, val);
RegId reg = si->destRegIdx(idx);
assert(reg.regClass == MiscRegClass);
return this->setMiscReg(reg.regIdx, val);
}
#if THE_ISA == MIPS_ISA
MiscReg readRegOtherThread(int misc_reg, ThreadID tid) override
MiscReg readRegOtherThread(RegId misc_reg, ThreadID tid) override
{
panic("MIPS MT not defined for CheckerCPU.\n");
return 0;
}
void setRegOtherThread(int misc_reg, MiscReg val, ThreadID tid) override
void setRegOtherThread(RegId misc_reg, MiscReg val, ThreadID tid) override
{
panic("MIPS MT not defined for CheckerCPU.\n");
}

View File

@@ -595,41 +595,40 @@ Checker<Impl>::copyResult(DynInstPtr &inst, uint64_t mismatch_val,
// We've already popped one dest off the queue,
// so do the fix-up then start with the next dest reg;
if (start_idx >= 0) {
RegIndex idx = inst->destRegIdx(start_idx);
switch (regIdxToClass(idx)) {
RegId idx = inst->destRegIdx(start_idx);
switch (idx.regClass) {
case IntRegClass:
thread->setIntReg(idx, mismatch_val);
thread->setIntReg(idx.regIdx, mismatch_val);
break;
case FloatRegClass:
thread->setFloatRegBits(idx - TheISA::FP_Reg_Base, mismatch_val);
thread->setFloatRegBits(idx.regIdx, mismatch_val);
break;
case CCRegClass:
thread->setCCReg(idx - TheISA::CC_Reg_Base, mismatch_val);
thread->setCCReg(idx.regIdx, mismatch_val);
break;
case MiscRegClass:
thread->setMiscReg(idx - TheISA::Misc_Reg_Base,
mismatch_val);
thread->setMiscReg(idx.regIdx, mismatch_val);
break;
}
}
start_idx++;
uint64_t res = 0;
for (int i = start_idx; i < inst->numDestRegs(); i++) {
RegIndex idx = inst->destRegIdx(i);
RegId idx = inst->destRegIdx(i);
inst->template popResult<uint64_t>(res);
switch (regIdxToClass(idx)) {
switch (idx.regClass) {
case IntRegClass:
thread->setIntReg(idx, res);
thread->setIntReg(idx.regIdx, res);
break;
case FloatRegClass:
thread->setFloatRegBits(idx - TheISA::FP_Reg_Base, res);
thread->setFloatRegBits(idx.regIdx, res);
break;
case CCRegClass:
thread->setCCReg(idx - TheISA::CC_Reg_Base, res);
thread->setCCReg(idx.regIdx, res);
break;
case MiscRegClass:
// Try to get the proper misc register index for ARM here...
thread->setMiscReg(idx - TheISA::Misc_Reg_Base, res);
thread->setMiscReg(idx.regIdx, res);
break;
// else Register is out of range...
}

View File

@@ -49,6 +49,7 @@
#include "base/types.hh"
#include "config/the_isa.hh"
#include "cpu/base.hh"
#include "cpu/reg_class.hh"
#include "cpu/static_inst_fwd.hh"
#include "cpu/translation.hh"
#include "mem/request.hh"
@@ -286,9 +287,9 @@ class ExecContext {
*/
#if THE_ISA == MIPS_ISA
virtual MiscReg readRegOtherThread(int regIdx,
virtual MiscReg readRegOtherThread(RegId reg,
ThreadID tid = InvalidThreadID) = 0;
virtual void setRegOtherThread(int regIdx, MiscReg val,
virtual void setRegOtherThread(RegId reg, MiscReg val,
ThreadID tid = InvalidThreadID) = 0;
#endif

View File

@@ -133,15 +133,15 @@ operator <<(std::ostream &os, const MinorDynInst &inst)
/** Print a register in the form r<n>, f<n>, m<n>(<name>), z for integer,
* float, misc and zero registers given an 'architectural register number' */
static void
printRegName(std::ostream &os, TheISA::RegIndex reg)
printRegName(std::ostream &os, RegId reg)
{
RegClass reg_class = regIdxToClass(reg);
RegClass reg_class = reg.regClass;
switch (reg_class)
{
case MiscRegClass:
{
TheISA::RegIndex misc_reg = reg - TheISA::Misc_Reg_Base;
RegIndex misc_reg = reg.regIdx;
/* This is an ugly test because not all archs. have miscRegName */
#if THE_ISA == ARM_ISA
@@ -153,17 +153,17 @@ printRegName(std::ostream &os, TheISA::RegIndex reg)
}
break;
case FloatRegClass:
os << 'f' << static_cast<unsigned int>(reg - TheISA::FP_Reg_Base);
os << 'f' << static_cast<unsigned int>(reg.regIdx);
break;
case IntRegClass:
if (reg == TheISA::ZeroReg) {
if (reg.isZeroReg()) {
os << 'z';
} else {
os << 'r' << static_cast<unsigned int>(reg);
os << 'r' << static_cast<unsigned int>(reg.regIdx);
}
break;
case CCRegClass:
os << 'c' << static_cast<unsigned int>(reg - TheISA::CC_Reg_Base);
os << 'c' << static_cast<unsigned int>(reg.regIdx);
}
}

View File

@@ -219,7 +219,7 @@ class MinorDynInst : public RefCounted
/** Flat register indices so that, when clearing the scoreboard, we
* have the same register indices as when the instruction was marked
* up */
TheISA::RegIndex flatDestRegIdx[TheISA::MaxInstDestRegs];
RegId flatDestRegIdx[TheISA::MaxInstDestRegs];
/** Effective address as set by ExecContext::setEA */
Addr ea;

View File

@@ -124,43 +124,51 @@ class ExecContext : public ::ExecContext
IntReg
readIntRegOperand(const StaticInst *si, int idx) override
{
return thread.readIntReg(si->srcRegIdx(idx));
RegId reg = si->srcRegIdx(idx);
assert(reg.regClass == IntRegClass);
return thread.readIntReg(reg.regIdx);
}
TheISA::FloatReg
readFloatRegOperand(const StaticInst *si, int idx) override
{
int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Reg_Base;
return thread.readFloatReg(reg_idx);
RegId reg = si->srcRegIdx(idx);
assert(reg.regClass == FloatRegClass);
return thread.readFloatReg(reg.regIdx);
}
TheISA::FloatRegBits
readFloatRegOperandBits(const StaticInst *si, int idx) override
{
int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Reg_Base;
return thread.readFloatRegBits(reg_idx);
RegId reg = si->srcRegIdx(idx);
assert(reg.regClass == FloatRegClass);
return thread.readFloatRegBits(reg.regIdx);
}
void
setIntRegOperand(const StaticInst *si, int idx, IntReg val) override
{
thread.setIntReg(si->destRegIdx(idx), val);
RegId reg = si->destRegIdx(idx);
assert(reg.regClass == IntRegClass);
thread.setIntReg(reg.regIdx, val);
}
void
setFloatRegOperand(const StaticInst *si, int idx,
TheISA::FloatReg val) override
{
int reg_idx = si->destRegIdx(idx) - TheISA::FP_Reg_Base;
thread.setFloatReg(reg_idx, val);
RegId reg = si->destRegIdx(idx);
assert(reg.regClass == FloatRegClass);
thread.setFloatReg(reg.regIdx, val);
}
void
setFloatRegOperandBits(const StaticInst *si, int idx,
TheISA::FloatRegBits val) override
{
int reg_idx = si->destRegIdx(idx) - TheISA::FP_Reg_Base;
thread.setFloatRegBits(reg_idx, val);
RegId reg = si->destRegIdx(idx);
assert(reg.regClass == FloatRegClass);
thread.setFloatRegBits(reg.regIdx, val);
}
bool
@@ -208,16 +216,18 @@ class ExecContext : public ::ExecContext
TheISA::MiscReg
readMiscRegOperand(const StaticInst *si, int idx) override
{
int reg_idx = si->srcRegIdx(idx) - TheISA::Misc_Reg_Base;
return thread.readMiscReg(reg_idx);
RegId reg = si->srcRegIdx(idx);
assert(reg.regClass == MiscRegClass);
return thread.readMiscReg(reg.regIdx);
}
void
setMiscRegOperand(const StaticInst *si, int idx,
const TheISA::MiscReg &val) override
{
int reg_idx = si->destRegIdx(idx) - TheISA::Misc_Reg_Base;
return thread.setMiscReg(reg_idx, val);
RegId reg = si->destRegIdx(idx);
assert(reg.regClass == MiscRegClass);
return thread.setMiscReg(reg.regIdx, val);
}
Fault
@@ -269,15 +279,17 @@ class ExecContext : public ::ExecContext
TheISA::CCReg
readCCRegOperand(const StaticInst *si, int idx) override
{
int reg_idx = si->srcRegIdx(idx) - TheISA::CC_Reg_Base;
return thread.readCCReg(reg_idx);
RegId reg = si->srcRegIdx(idx);
assert(reg.regClass == CCRegClass);
return thread.readCCReg(reg.regIdx);
}
void
setCCRegOperand(const StaticInst *si, int idx, TheISA::CCReg val) override
{
int reg_idx = si->destRegIdx(idx) - TheISA::CC_Reg_Base;
thread.setCCReg(reg_idx, val);
RegId reg = si->destRegIdx(idx);
assert(reg.regClass == CCRegClass);
thread.setCCReg(reg.regIdx, val);
}
void
@@ -308,37 +320,46 @@ class ExecContext : public ::ExecContext
/* MIPS: other thread register reading/writing */
uint64_t
readRegOtherThread(int idx, ThreadID tid = InvalidThreadID)
readRegOtherThread(RegId reg, ThreadID tid = InvalidThreadID)
{
SimpleThread *other_thread = (tid == InvalidThreadID
? &thread : cpu.threads[tid]);
if (idx < TheISA::FP_Reg_Base) { /* Integer */
return other_thread->readIntReg(idx);
} else if (idx < TheISA::Misc_Reg_Base) { /* Float */
return other_thread->readFloatRegBits(idx
- TheISA::FP_Reg_Base);
} else { /* Misc */
return other_thread->readMiscReg(idx
- TheISA::Misc_Reg_Base);
switch(reg.regClass) {
case IntRegClass:
return other_thread->readIntReg(reg.regIdx);
break;
case FloatRegClass:
return other_thread->readFloatRegBits(reg.regIdx);
break;
case MiscRegClass:
return other_thread->readMiscReg(reg.regIdx);
default:
panic("Unexpected reg class! (%s)",
RegClassStrings[reg.regClass]);
return 0;
}
}
void
setRegOtherThread(int idx, const TheISA::MiscReg &val,
setRegOtherThread(RegId reg, const TheISA::MiscReg &val,
ThreadID tid = InvalidThreadID)
{
SimpleThread *other_thread = (tid == InvalidThreadID
? &thread : cpu.threads[tid]);
if (idx < TheISA::FP_Reg_Base) { /* Integer */
return other_thread->setIntReg(idx, val);
} else if (idx < TheISA::Misc_Reg_Base) { /* Float */
return other_thread->setFloatRegBits(idx
- TheISA::FP_Reg_Base, val);
} else { /* Misc */
return other_thread->setMiscReg(idx
- TheISA::Misc_Reg_Base, val);
switch(reg.regClass) {
case IntRegClass:
return other_thread->setIntReg(reg.regIdx, val);
break;
case FloatRegClass:
return other_thread->setFloatRegBits(reg.regIdx, val);
break;
case MiscRegClass:
return other_thread->setMiscReg(reg.regIdx, val);
default:
panic("Unexpected reg class! (%s)",
RegClassStrings[reg.regClass]);
}
}

View File

@@ -48,28 +48,27 @@ namespace Minor
{
bool
Scoreboard::findIndex(RegIndex reg, Index &scoreboard_index)
Scoreboard::findIndex(RegId reg, Index &scoreboard_index)
{
RegClass reg_class = regIdxToClass(reg);
bool ret = false;
if (reg == TheISA::ZeroReg) {
if (reg.isZeroReg()) {
/* Don't bother with the zero register */
ret = false;
} else {
switch (reg_class)
switch (reg.regClass)
{
case IntRegClass:
scoreboard_index = reg;
scoreboard_index = reg.regIdx;
ret = true;
break;
case FloatRegClass:
scoreboard_index = TheISA::NumIntRegs + TheISA::NumCCRegs +
reg - TheISA::FP_Reg_Base;
reg.regIdx;
ret = true;
break;
case CCRegClass:
scoreboard_index = TheISA::NumIntRegs + reg - TheISA::FP_Reg_Base;
scoreboard_index = TheISA::NumIntRegs + reg.regIdx;
ret = true;
break;
case MiscRegClass:
@@ -82,32 +81,28 @@ Scoreboard::findIndex(RegIndex reg, Index &scoreboard_index)
return ret;
}
/** Flatten a RegIndex, irrespective of what reg type it's pointing to */
static TheISA::RegIndex
flattenRegIndex(TheISA::RegIndex reg, ThreadContext *thread_context)
/** Flatten a RegId, irrespective of what reg type it's pointing to */
static RegId
flattenRegIndex(RegId reg, ThreadContext *thread_context)
{
RegClass reg_class = regIdxToClass(reg);
TheISA::RegIndex ret = reg;
switch (reg_class)
switch (reg.regClass)
{
case IntRegClass:
ret = thread_context->flattenIntIndex(reg);
reg.regIdx = thread_context->flattenIntIndex(reg.regIdx);
break;
case FloatRegClass:
ret = thread_context->flattenFloatIndex(reg);
reg.regIdx = thread_context->flattenFloatIndex(reg.regIdx);
break;
case CCRegClass:
ret = thread_context->flattenCCIndex(reg);
reg.regIdx = thread_context->flattenCCIndex(reg.regIdx);
break;
case MiscRegClass:
/* Don't bother to flatten misc regs as we don't need them here */
/* return thread_context->flattenMiscIndex(reg); */
ret = reg;
break;
}
return ret;
return reg;
}
void
@@ -124,8 +119,8 @@ Scoreboard::markupInstDests(MinorDynInstPtr inst, Cycles retire_time,
for (unsigned int dest_index = 0; dest_index < num_dests;
dest_index++)
{
RegIndex reg = flattenRegIndex(
staticInst->destRegIdx(dest_index), thread_context);
RegId reg = flattenRegIndex(
staticInst->destRegIdx(dest_index), thread_context);
Index index;
if (findIndex(reg, index)) {
@@ -148,7 +143,7 @@ Scoreboard::markupInstDests(MinorDynInstPtr inst, Cycles retire_time,
*inst, index, numResults[index], returnCycle[index]);
} else {
/* Use ZeroReg to mark invalid/untracked dests */
inst->flatDestRegIdx[dest_index] = TheISA::ZeroReg;
inst->flatDestRegIdx[dest_index] = RegId::zeroReg;
}
}
}
@@ -166,7 +161,7 @@ Scoreboard::execSeqNumToWaitFor(MinorDynInstPtr inst,
unsigned int num_srcs = staticInst->numSrcRegs();
for (unsigned int src_index = 0; src_index < num_srcs; src_index++) {
RegIndex reg = flattenRegIndex(staticInst->srcRegIdx(src_index),
RegId reg = flattenRegIndex(staticInst->srcRegIdx(src_index),
thread_context);
unsigned short int index;
@@ -195,7 +190,7 @@ Scoreboard::clearInstDests(MinorDynInstPtr inst, bool clear_unpredictable)
for (unsigned int dest_index = 0; dest_index < num_dests;
dest_index++)
{
RegIndex reg = inst->flatDestRegIdx[dest_index];
RegId reg = inst->flatDestRegIdx[dest_index];
Index index;
if (findIndex(reg, index)) {
@@ -252,7 +247,7 @@ Scoreboard::canInstIssue(MinorDynInstPtr inst,
while (src_index < num_srcs && /* More registers */
ret /* Still possible */)
{
RegIndex reg = flattenRegIndex(staticInst->srcRegIdx(src_index),
RegId reg = flattenRegIndex(staticInst->srcRegIdx(src_index),
thread_context);
unsigned short int index;

View File

@@ -67,9 +67,6 @@ class Scoreboard : public Named
* [NumIntRegs+NumCCRegs, NumFloatRegs+NumIntRegs+NumCCRegs-1] */
const unsigned numRegs;
/** Type to use for thread context registers */
typedef TheISA::RegIndex RegIndex;
/** Type to use when indexing numResults */
typedef unsigned short int Index;
@@ -109,7 +106,7 @@ class Scoreboard : public Named
/** Sets scoreboard_index to the index into numResults of the
* given register index. Returns true if the given register
* is in the scoreboard and false if it isn't */
bool findIndex(RegIndex reg, Index &scoreboard_index);
bool findIndex(RegId reg, Index &scoreboard_index);
/** Mark up an instruction's effects by incrementing
* numResults counts. If mark_unpredictable is true, the inst's

View File

@@ -788,29 +788,27 @@ FullO3CPU<Impl>::insertThread(ThreadID tid)
src_tc = tcBase(tid);
//Bind Int Regs to Rename Map
for (int ireg = 0; ireg < TheISA::NumIntRegs; ireg++) {
PhysRegIndex phys_reg = freeList.getIntReg();
renameMap[tid].setEntry(ireg,phys_reg);
for (RegId reg_id(IntRegClass, 0); reg_id.regIdx < TheISA::NumIntRegs;
reg_id.regIdx++) {
PhysRegIndex phys_reg = freeList.getIntReg();
renameMap[tid].setEntry(reg_id, phys_reg);
scoreboard.setReg(phys_reg);
}
//Bind Float Regs to Rename Map
int max_reg = TheISA::FP_Reg_Base + TheISA::NumFloatRegs;
for (int freg = TheISA::FP_Reg_Base; freg < max_reg; freg++) {
for (RegId reg_id(FloatRegClass, 0); reg_id.regIdx < TheISA::NumFloatRegs;
reg_id.regIdx++) {
PhysRegIndex phys_reg = freeList.getFloatReg();
renameMap[tid].setEntry(freg,phys_reg);
renameMap[tid].setEntry(reg_id, phys_reg);
scoreboard.setReg(phys_reg);
}
//Bind condition-code Regs to Rename Map
max_reg = TheISA::CC_Reg_Base + TheISA::NumCCRegs;
for (int creg = TheISA::CC_Reg_Base;
creg < max_reg; creg++) {
for (RegId reg_id(CCRegClass, 0); reg_id.regIdx < TheISA::NumCCRegs;
reg_id.regIdx++) {
PhysRegIndex phys_reg = freeList.getCCReg();
renameMap[tid].setEntry(creg,phys_reg);
renameMap[tid].setEntry(reg_id, phys_reg);
scoreboard.setReg(phys_reg);
}
@@ -845,24 +843,25 @@ FullO3CPU<Impl>::removeThread(ThreadID tid)
// in SMT workloads.
// Unbind Int Regs from Rename Map
for (int ireg = 0; ireg < TheISA::NumIntRegs; ireg++) {
PhysRegIndex phys_reg = renameMap[tid].lookup(ireg);
for (RegId reg_id(IntRegClass, 0); reg_id.regIdx < TheISA::NumIntRegs;
reg_id.regIdx++) {
PhysRegIndex phys_reg = renameMap[tid].lookup(reg_id);
scoreboard.unsetReg(phys_reg);
freeList.addReg(phys_reg);
}
// Unbind Float Regs from Rename Map
int max_reg = TheISA::FP_Reg_Base + TheISA::NumFloatRegs;
for (int freg = TheISA::FP_Reg_Base; freg < max_reg; freg++) {
PhysRegIndex phys_reg = renameMap[tid].lookup(freg);
for (RegId reg_id(FloatRegClass, 0); reg_id.regIdx < TheISA::NumFloatRegs;
reg_id.regIdx++) {
PhysRegIndex phys_reg = renameMap[tid].lookup(reg_id);
scoreboard.unsetReg(phys_reg);
freeList.addReg(phys_reg);
}
// Unbind condition-code Regs from Rename Map
max_reg = TheISA::CC_Reg_Base + TheISA::NumCCRegs;
for (int creg = TheISA::CC_Reg_Base; creg < max_reg; creg++) {
PhysRegIndex phys_reg = renameMap[tid].lookup(creg);
for (RegId reg_id(CCRegClass, 0); reg_id.regIdx < TheISA::NumCCRegs;
reg_id.regIdx++) {
PhysRegIndex phys_reg = renameMap[tid].lookup(reg_id);
scoreboard.unsetReg(phys_reg);
freeList.addReg(phys_reg);
}

View File

@@ -67,15 +67,13 @@ class BaseO3DynInst : public BaseDynInst<Impl>
typedef TheISA::MachInst MachInst;
/** Extended machine instruction type. */
typedef TheISA::ExtMachInst ExtMachInst;
/** Logical register index type. */
typedef TheISA::RegIndex RegIndex;
/** Integer register index type. */
/** Register types. */
typedef TheISA::IntReg IntReg;
typedef TheISA::FloatReg FloatReg;
typedef TheISA::FloatRegBits FloatRegBits;
typedef TheISA::CCReg CCReg;
/** Misc register index type. */
/** Misc register type. */
typedef TheISA::MiscReg MiscReg;
enum {
@@ -172,9 +170,9 @@ class BaseO3DynInst : public BaseDynInst<Impl>
*/
TheISA::MiscReg readMiscRegOperand(const StaticInst *si, int idx)
{
return this->cpu->readMiscReg(
si->srcRegIdx(idx) - TheISA::Misc_Reg_Base,
this->threadNumber);
RegId reg = si->srcRegIdx(idx);
assert(reg.regClass == MiscRegClass);
return this->cpu->readMiscReg(reg.regIdx, this->threadNumber);
}
/** Sets a misc. register, including any side-effects the write
@@ -183,8 +181,9 @@ class BaseO3DynInst : public BaseDynInst<Impl>
void setMiscRegOperand(const StaticInst *si, int idx,
const MiscReg &val)
{
int misc_reg = si->destRegIdx(idx) - TheISA::Misc_Reg_Base;
setMiscReg(misc_reg, val);
RegId reg = si->destRegIdx(idx);
assert(reg.regClass == MiscRegClass);
setMiscReg(reg.regIdx, val);
}
/** Called at the commit stage to update the misc. registers. */
@@ -209,9 +208,9 @@ class BaseO3DynInst : public BaseDynInst<Impl>
for (int idx = 0; idx < this->numDestRegs(); idx++) {
PhysRegIndex prev_phys_reg = this->prevDestRegIdx(idx);
TheISA::RegIndex original_dest_reg =
RegId original_dest_reg =
this->staticInst->destRegIdx(idx);
switch (regIdxToClass(original_dest_reg)) {
switch (original_dest_reg.regClass) {
case IntRegClass:
this->setIntRegOperand(this->staticInst.get(), idx,
this->cpu->readIntReg(prev_phys_reg));
@@ -301,13 +300,13 @@ class BaseO3DynInst : public BaseDynInst<Impl>
}
#if THE_ISA == MIPS_ISA
MiscReg readRegOtherThread(int misc_reg, ThreadID tid)
MiscReg readRegOtherThread(RegId misc_reg, ThreadID tid)
{
panic("MIPS MT not defined for O3 CPU.\n");
return 0;
}
void setRegOtherThread(int misc_reg, MiscReg val, ThreadID tid)
void setRegOtherThread(RegId misc_reg, MiscReg val, ThreadID tid)
{
panic("MIPS MT not defined for O3 CPU.\n");
}

View File

@@ -110,11 +110,11 @@ BaseO3DynInst<Impl>::initVars()
// as the normal register entries. It will allow the IQ to work
// without any modifications.
for (int i = 0; i < this->staticInst->numDestRegs(); i++) {
this->_destRegIdx[i] = this->staticInst->destRegIdx(i);
this->_destRegIdx[i] = this->staticInst->destRegIdx(i).regIdx;
}
for (int i = 0; i < this->staticInst->numSrcRegs(); i++) {
this->_srcRegIdx[i] = this->staticInst->srcRegIdx(i);
this->_srcRegIdx[i] = this->staticInst->srcRegIdx(i).regIdx;
}
this->_readySrcRegIdx.reset();

View File

@@ -262,15 +262,15 @@ ElasticTrace::updateRegDep(const DynInstPtr &dyn_inst)
for (int dest_idx = 0; dest_idx < max_regs; dest_idx++) {
// For data dependency tracking the register must be an int, float or
// CC register and not a Misc register.
TheISA::RegIndex dest_reg = dyn_inst->destRegIdx(dest_idx);
if (regIdxToClass(dest_reg) != MiscRegClass) {
// Get the physical register index of the i'th destination register.
dest_reg = dyn_inst->renamedDestRegIdx(dest_idx);
if (dest_reg != TheISA::ZeroReg) {
DPRINTFR(ElasticTrace, "[sn:%lli] Update map for dest reg %i\n",
seq_num, dest_reg);
physRegDepMap[dest_reg] = seq_num;
}
RegId dest_reg = dyn_inst->destRegIdx(dest_idx);
if (dest_reg.isRenameable() &&
!dest_reg.isZeroReg()) {
// Get the physical register index of the i'th destination
// register.
PhysRegIndex phys_dest_reg = dyn_inst->renamedDestRegIdx(dest_idx);
DPRINTFR(ElasticTrace, "[sn:%lli] Update map for dest reg %i\n",
seq_num, dest_reg.regIdx);
physRegDepMap[phys_dest_reg] = seq_num;
}
}
maxPhysRegDepMapSize = std::max(physRegDepMap.size(),

View File

@@ -85,9 +85,6 @@ class DefaultRename
typedef typename CPUPol::IEW IEW;
typedef typename CPUPol::Commit Commit;
// Typedefs from the ISA.
typedef TheISA::RegIndex RegIndex;
// A deque is used to queue the instructions. Barrier insts must
// be added to the front of the queue, which is the only reason for
// using a deque instead of a queue. (Most other stages use a
@@ -301,7 +298,7 @@ class DefaultRename
* register for that arch. register, and the new physical register.
*/
struct RenameHistory {
RenameHistory(InstSeqNum _instSeqNum, RegIndex _archReg,
RenameHistory(InstSeqNum _instSeqNum, RegId _archReg,
PhysRegIndex _newPhysReg, PhysRegIndex _prevPhysReg)
: instSeqNum(_instSeqNum), archReg(_archReg),
newPhysReg(_newPhysReg), prevPhysReg(_prevPhysReg)
@@ -311,7 +308,7 @@ class DefaultRename
/** The sequence number of the instruction that renamed. */
InstSeqNum instSeqNum;
/** The architectural register index that was renamed. */
RegIndex archReg;
RegId archReg;
/** The new physical register that the arch. register is renamed to. */
PhysRegIndex newPhysReg;
/** The old physical register that the arch. register was renamed to. */

View File

@@ -1011,42 +1011,41 @@ DefaultRename<Impl>::renameSrcRegs(DynInstPtr &inst, ThreadID tid)
// Get the architectual register numbers from the source and
// operands, and redirect them to the right physical register.
for (int src_idx = 0; src_idx < num_src_regs; src_idx++) {
RegIndex src_reg = inst->srcRegIdx(src_idx);
RegIndex rel_src_reg;
RegIndex flat_rel_src_reg;
RegId src_reg = inst->srcRegIdx(src_idx);
RegIndex flat_src_reg;
PhysRegIndex renamed_reg;
switch (regIdxToClass(src_reg, &rel_src_reg)) {
switch (src_reg.regClass) {
case IntRegClass:
flat_rel_src_reg = tc->flattenIntIndex(rel_src_reg);
renamed_reg = map->lookupInt(flat_rel_src_reg);
flat_src_reg = tc->flattenIntIndex(src_reg.regIdx);
renamed_reg = map->lookupInt(flat_src_reg);
intRenameLookups++;
break;
case FloatRegClass:
flat_rel_src_reg = tc->flattenFloatIndex(rel_src_reg);
renamed_reg = map->lookupFloat(flat_rel_src_reg);
flat_src_reg = tc->flattenFloatIndex(src_reg.regIdx);
renamed_reg = map->lookupFloat(flat_src_reg);
fpRenameLookups++;
break;
case CCRegClass:
flat_rel_src_reg = tc->flattenCCIndex(rel_src_reg);
renamed_reg = map->lookupCC(flat_rel_src_reg);
flat_src_reg = tc->flattenCCIndex(src_reg.regIdx);
renamed_reg = map->lookupCC(flat_src_reg);
break;
case MiscRegClass:
// misc regs don't get flattened
flat_rel_src_reg = rel_src_reg;
renamed_reg = map->lookupMisc(flat_rel_src_reg);
flat_src_reg = src_reg.regIdx;
renamed_reg = map->lookupMisc(flat_src_reg);
break;
default:
panic("Reg index is out of bound: %d.", src_reg);
panic("Invalid register class: %d.", src_reg.regClass);
}
DPRINTF(Rename, "[tid:%u]: Looking up %s arch reg %i (flattened %i), "
"got phys reg %i\n", tid, RegClassStrings[regIdxToClass(src_reg)],
(int)src_reg, (int)flat_rel_src_reg, (int)renamed_reg);
"got phys reg %i\n", tid, RegClassStrings[src_reg.regClass],
(int)src_reg.regIdx, (int)flat_src_reg, (int)renamed_reg);
inst->renameSrcReg(src_idx, renamed_reg);
@@ -1075,49 +1074,45 @@ DefaultRename<Impl>::renameDestRegs(DynInstPtr &inst, ThreadID tid)
// Rename the destination registers.
for (int dest_idx = 0; dest_idx < num_dest_regs; dest_idx++) {
RegIndex dest_reg = inst->destRegIdx(dest_idx);
RegIndex rel_dest_reg;
RegIndex flat_rel_dest_reg;
RegIndex flat_uni_dest_reg;
RegId dest_reg = inst->destRegIdx(dest_idx);
RegIndex flat_dest_reg;
typename RenameMap::RenameInfo rename_result;
switch (regIdxToClass(dest_reg, &rel_dest_reg)) {
switch (dest_reg.regClass) {
case IntRegClass:
flat_rel_dest_reg = tc->flattenIntIndex(rel_dest_reg);
rename_result = map->renameInt(flat_rel_dest_reg);
flat_uni_dest_reg = flat_rel_dest_reg; // 1:1 mapping
flat_dest_reg = tc->flattenIntIndex(dest_reg.regIdx);
rename_result = map->renameInt(flat_dest_reg);
break;
case FloatRegClass:
flat_rel_dest_reg = tc->flattenFloatIndex(rel_dest_reg);
rename_result = map->renameFloat(flat_rel_dest_reg);
flat_uni_dest_reg = flat_rel_dest_reg + TheISA::FP_Reg_Base;
flat_dest_reg = tc->flattenFloatIndex(dest_reg.regIdx);
rename_result = map->renameFloat(flat_dest_reg);
break;
case CCRegClass:
flat_rel_dest_reg = tc->flattenCCIndex(rel_dest_reg);
rename_result = map->renameCC(flat_rel_dest_reg);
flat_uni_dest_reg = flat_rel_dest_reg + TheISA::CC_Reg_Base;
flat_dest_reg = tc->flattenCCIndex(dest_reg.regIdx);
rename_result = map->renameCC(flat_dest_reg);
break;
case MiscRegClass:
// misc regs don't get flattened
flat_rel_dest_reg = rel_dest_reg;
rename_result = map->renameMisc(flat_rel_dest_reg);
flat_uni_dest_reg = flat_rel_dest_reg + TheISA::Misc_Reg_Base;
flat_dest_reg = dest_reg.regIdx;
rename_result = map->renameMisc(dest_reg.regIdx);
break;
default:
panic("Reg index is out of bound: %d.", dest_reg);
panic("Invalid register class: %d.", dest_reg.regClass);
}
RegId flat_uni_dest_reg(dest_reg.regClass, flat_dest_reg);
inst->flattenDestReg(dest_idx, flat_uni_dest_reg);
// Mark Scoreboard entry as not ready
scoreboard->unsetReg(rename_result.first);
DPRINTF(Rename, "[tid:%u]: Renaming arch reg %i to physical "
"reg %i.\n", tid, (int)flat_rel_dest_reg,
"reg %i.\n", tid, (int)flat_dest_reg,
(int)rename_result.first);
// Record the rename information so that a history can be kept.
@@ -1431,8 +1426,10 @@ DefaultRename<Impl>::dumpHistory()
buf_it = historyBuffer[tid].begin();
while (buf_it != historyBuffer[tid].end()) {
cprintf("Seq num: %i\nArch reg: %i New phys reg: %i Old phys "
"reg: %i\n", (*buf_it).instSeqNum, (int)(*buf_it).archReg,
cprintf("Seq num: %i\nArch reg[%s]: %i New phys reg: %i Old phys "
"reg: %i\n", (*buf_it).instSeqNum,
RegClassStrings[(*buf_it).archReg.regClass],
(*buf_it).archReg.regIdx,
(int)(*buf_it).newPhysReg, (int)(*buf_it).prevPhysReg);
buf_it++;

View File

@@ -104,79 +104,73 @@ UnifiedRenameMap::init(PhysRegFile *_regFile,
UnifiedRenameMap::RenameInfo
UnifiedRenameMap::rename(RegIndex arch_reg)
UnifiedRenameMap::rename(RegId arch_reg)
{
RegIndex rel_arch_reg;
switch (regIdxToClass(arch_reg, &rel_arch_reg)) {
switch (arch_reg.regClass) {
case IntRegClass:
return renameInt(rel_arch_reg);
return renameInt(arch_reg.regIdx);
case FloatRegClass:
return renameFloat(rel_arch_reg);
return renameFloat(arch_reg.regIdx);
case CCRegClass:
return renameCC(rel_arch_reg);
return renameCC(arch_reg.regIdx);
case MiscRegClass:
return renameMisc(rel_arch_reg);
return renameMisc(arch_reg.regIdx);
default:
panic("rename rename(): unknown reg class %s\n",
RegClassStrings[regIdxToClass(arch_reg)]);
RegClassStrings[arch_reg.regClass]);
}
}
PhysRegIndex
UnifiedRenameMap::lookup(RegIndex arch_reg) const
UnifiedRenameMap::lookup(RegId arch_reg) const
{
RegIndex rel_arch_reg;
switch (regIdxToClass(arch_reg, &rel_arch_reg)) {
switch (arch_reg.regClass) {
case IntRegClass:
return lookupInt(rel_arch_reg);
return lookupInt(arch_reg.regIdx);
case FloatRegClass:
return lookupFloat(rel_arch_reg);
return lookupFloat(arch_reg.regIdx);
case CCRegClass:
return lookupCC(rel_arch_reg);
return lookupCC(arch_reg.regIdx);
case MiscRegClass:
return lookupMisc(rel_arch_reg);
return lookupMisc(arch_reg.regIdx);
default:
panic("rename lookup(): unknown reg class %s\n",
RegClassStrings[regIdxToClass(arch_reg)]);
RegClassStrings[arch_reg.regClass]);
}
}
void
UnifiedRenameMap::setEntry(RegIndex arch_reg, PhysRegIndex phys_reg)
UnifiedRenameMap::setEntry(RegId arch_reg, PhysRegIndex phys_reg)
{
RegIndex rel_arch_reg;
switch (regIdxToClass(arch_reg, &rel_arch_reg)) {
switch (arch_reg.regClass) {
case IntRegClass:
return setIntEntry(rel_arch_reg, phys_reg);
return setIntEntry(arch_reg.regIdx, phys_reg);
case FloatRegClass:
return setFloatEntry(rel_arch_reg, phys_reg);
return setFloatEntry(arch_reg.regIdx, phys_reg);
case CCRegClass:
return setCCEntry(rel_arch_reg, phys_reg);
return setCCEntry(arch_reg.regIdx, phys_reg);
case MiscRegClass:
// 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,
// which should always be setting it to what it already is.
assert(phys_reg == lookupMisc(rel_arch_reg));
assert(phys_reg == lookupMisc(arch_reg.regIdx));
return;
default:
panic("rename setEntry(): unknown reg class %s\n",
RegClassStrings[regIdxToClass(arch_reg)]);
RegClassStrings[arch_reg.regClass]);
}
}

View File

@@ -68,10 +68,6 @@
*/
class SimpleRenameMap
{
public:
typedef TheISA::RegIndex RegIndex;
private:
/** The acutal arch-to-phys register map */
@@ -152,9 +148,9 @@ class SimpleRenameMap
/**
* Unified register rename map for all classes of registers. Wraps a
* set of class-specific rename maps. Methods that do not specify a
* register class (e.g., rename()) take unified register indices,
* register class (e.g., rename()) take register ids,
* while methods that do specify a register class (e.g., renameInt())
* take relative register indices. See http://gem5.org/Register_Indexing.
* take register indices.
*/
class UnifiedRenameMap
{
@@ -179,7 +175,6 @@ class UnifiedRenameMap
SimpleRenameMap ccMap;
public:
typedef TheISA::RegIndex RegIndex;
typedef SimpleRenameMap::RenameInfo RenameInfo;
@@ -197,17 +192,17 @@ class UnifiedRenameMap
/**
* Tell rename map to get a new free physical register to remap
* the specified architectural register. This version takes a
* unified flattened architectural register index and calls the
* the specified architectural register. This version takes a
* flattened architectural register id and calls the
* appropriate class-specific rename table.
* @param arch_reg The unified architectural register index to remap.
* @param arch_reg The architectural register index to remap.
* @return A RenameInfo pair indicating both the new and previous
* physical registers.
*/
RenameInfo rename(RegIndex arch_reg);
RenameInfo rename(RegId arch_reg);
/**
* Perform rename() on an integer register, given a relative
* Perform rename() on an integer register, given a
* integer register index.
*/
RenameInfo renameInt(RegIndex rel_arch_reg)
@@ -218,7 +213,7 @@ class UnifiedRenameMap
}
/**
* Perform rename() on a floating-point register, given a relative
* Perform rename() on a floating-point register, given a
* floating-point register index.
*/
RenameInfo renameFloat(RegIndex rel_arch_reg)
@@ -229,7 +224,7 @@ class UnifiedRenameMap
}
/**
* Perform rename() on a condition-code register, given a relative
* Perform rename() on a condition-code register, given a
* condition-code register index.
*/
RenameInfo renameCC(RegIndex rel_arch_reg)
@@ -240,7 +235,7 @@ class UnifiedRenameMap
}
/**
* Perform rename() on a misc register, given a relative
* Perform rename() on a misc register, given a
* misc register index.
*/
RenameInfo renameMisc(RegIndex rel_arch_reg)
@@ -256,15 +251,15 @@ class UnifiedRenameMap
/**
* Look up the physical register mapped to an architectural register.
* This version takes a unified flattened architectural register index
* This version takes a flattened architectural register id
* and calls the appropriate class-specific rename table.
* @param arch_reg The unified architectural register to look up.
* @param arch_reg The architectural register to look up.
* @return The physical register it is currently mapped to.
*/
PhysRegIndex lookup(RegIndex arch_reg) const;
PhysRegIndex lookup(RegId arch_reg) const;
/**
* Perform lookup() on an integer register, given a relative
* Perform lookup() on an integer register, given a
* integer register index.
*/
PhysRegIndex lookupInt(RegIndex rel_arch_reg) const
@@ -275,7 +270,7 @@ class UnifiedRenameMap
}
/**
* Perform lookup() on a floating-point register, given a relative
* Perform lookup() on a floating-point register, given a
* floating-point register index.
*/
PhysRegIndex lookupFloat(RegIndex rel_arch_reg) const
@@ -286,7 +281,7 @@ class UnifiedRenameMap
}
/**
* Perform lookup() on a condition-code register, given a relative
* Perform lookup() on a condition-code register, given a
* condition-code register index.
*/
PhysRegIndex lookupCC(RegIndex rel_arch_reg) const
@@ -311,15 +306,15 @@ class UnifiedRenameMap
/**
* Update rename map with a specific mapping. Generally used to
* roll back to old mappings on a squash. This version takes a
* unified flattened architectural register index and calls the
* flattened architectural register id and calls the
* appropriate class-specific rename table.
* @param arch_reg The unified architectural register to remap.
* @param arch_reg The architectural register to remap.
* @param phys_reg The physical register to remap it to.
*/
void setEntry(RegIndex arch_reg, PhysRegIndex phys_reg);
void setEntry(RegId arch_reg, PhysRegIndex phys_reg);
/**
* Perform setEntry() on an integer register, given a relative
* Perform setEntry() on an integer register, given a
* integer register index.
*/
void setIntEntry(RegIndex arch_reg, PhysRegIndex phys_reg)
@@ -329,7 +324,7 @@ class UnifiedRenameMap
}
/**
* Perform setEntry() on a floating-point register, given a relative
* Perform setEntry() on a floating-point register, given a
* floating-point register index.
*/
void setFloatEntry(RegIndex arch_reg, PhysRegIndex phys_reg)
@@ -339,7 +334,7 @@ class UnifiedRenameMap
}
/**
* Perform setEntry() on a condition-code register, given a relative
* Perform setEntry() on a condition-code register, given a
* condition-code register index.
*/
void setCCEntry(RegIndex arch_reg, PhysRegIndex phys_reg)

View File

@@ -60,8 +60,6 @@ struct DerivO3CPUParams;
template <class Impl>
class ROB
{
protected:
typedef TheISA::RegIndex RegIndex;
public:
//Typedefs from the Impl.
typedef typename Impl::O3CPU O3CPU;

View File

@@ -36,3 +36,5 @@ const char *RegClassStrings[] = {
"CCRegClass",
"MiscRegClass"
};
const RegId RegId::zeroReg = RegId(IntRegClass, TheISA::ZeroReg);

View File

@@ -1,4 +1,16 @@
/*
* Copyright (c) 2016 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
* not be construed as granting a license to any other intellectual
* property including but not limited to intellectual property relating
* to a hardware implementation of the functionality of the software
* licensed hereunder. You may use the software subject to the license
* terms below provided that you ensure that this notice is replicated
* unmodified and in its entirety in all distributions of the software,
* modified or unmodified, in source code or in binary form.
*
* Copyright (c) 2013 Advanced Micro Devices, Inc.
* All rights reserved
*.
@@ -26,6 +38,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Steve Reinhardt
* Nathanael Premillieu
*/
#ifndef __CPU__REG_CLASS_HH__
@@ -34,6 +47,7 @@
#include <cassert>
#include <cstddef>
#include "arch/generic/types.hh"
#include "arch/registers.hh"
#include "config/the_isa.hh"
@@ -50,50 +64,49 @@ enum RegClass {
/// unhandled cases in some switch statements.
const int NumRegClasses = MiscRegClass + 1;
/**
* Map a 'unified' architectural register index to its register class.
* The unified architectural register index space is used to represent
* all architectural register identifiers in a single contiguous
* index space. See http://gem5.org/Register_Indexing.
*
* @param reg_idx Unified-space register index
* @param rel_reg_idx Optional output param pointer; if non-NULL, location
* will be written with the relative register index for reg_idx
*
* @return Register class of reg_idx
*/
inline
RegClass regIdxToClass(TheISA::RegIndex reg_idx,
TheISA::RegIndex *rel_reg_idx = NULL)
{
assert(reg_idx < TheISA::Max_Reg_Index);
RegClass cl;
int offset;
/// Register ID: describe an architectural register with its class and index.
/// This structure is used instead of just the register index to disambiguate
/// between different classes of registers.
/// For example, a integer register with index 3 is represented by
/// Regid(IntRegClass, 3).
struct RegId {
RegClass regClass;
RegIndex regIdx;
RegId() {};
RegId(RegClass reg_class, RegIndex reg_idx)
: regClass(reg_class), regIdx(reg_idx)
{}
if (reg_idx < TheISA::FP_Reg_Base) {
cl = IntRegClass;
offset = 0;
} else if (reg_idx < TheISA::CC_Reg_Base) {
cl = FloatRegClass;
offset = TheISA::FP_Reg_Base;
} else if (reg_idx < TheISA::Misc_Reg_Base) {
// if there are no CC regs, the ISA should set
// CC_Reg_Base == Misc_Reg_Base so the if above
// never succeeds
cl = CCRegClass;
offset = TheISA::CC_Reg_Base;
} else {
cl = MiscRegClass;
offset = TheISA::Misc_Reg_Base;
bool operator==(const RegId& that) const {
return regClass == that.regClass && regIdx == that.regIdx;
}
if (rel_reg_idx)
*rel_reg_idx = reg_idx - offset;
return cl;
}
bool operator!=(const RegId& that) const {
return !(*this==that);
}
/**
* Returns true if this register is a zero register (needs to have a
* constant zero value throughout the execution)
*/
bool isZeroReg() const
{
return (regIdx == TheISA::ZeroReg &&
(regClass == IntRegClass ||
(THE_ISA == ALPHA_ISA && regClass == FloatRegClass)));
}
/**
* Return true if this register can be renamed
*/
bool isRenameable()
{
return regClass != MiscRegClass;
}
static const RegId zeroReg;
};
/// Map enum values to strings for debugging
extern const char *RegClassStrings[];
#endif // __CPU__REG_CLASS_HH__

View File

@@ -50,6 +50,7 @@
#include "config/the_isa.hh"
#include "cpu/base.hh"
#include "cpu/exec_context.hh"
#include "cpu/reg_class.hh"
#include "cpu/simple/base.hh"
#include "cpu/static_inst_fwd.hh"
#include "cpu/translation.hh"
@@ -164,22 +165,27 @@ class SimpleExecContext : public ExecContext {
IntReg readIntRegOperand(const StaticInst *si, int idx) override
{
numIntRegReads++;
return thread->readIntReg(si->srcRegIdx(idx));
RegId reg = si->srcRegIdx(idx);
assert(reg.regClass == IntRegClass);
return thread->readIntReg(reg.regIdx);
}
/** Sets an integer register to a value. */
void setIntRegOperand(const StaticInst *si, int idx, IntReg val) override
{
numIntRegWrites++;
thread->setIntReg(si->destRegIdx(idx), val);
RegId reg = si->destRegIdx(idx);
assert(reg.regClass == IntRegClass);
thread->setIntReg(reg.regIdx, val);
}
/** Reads a floating point register of single register width. */
FloatReg readFloatRegOperand(const StaticInst *si, int idx) override
{
numFpRegReads++;
int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Reg_Base;
return thread->readFloatReg(reg_idx);
RegId reg = si->srcRegIdx(idx);
assert(reg.regClass == FloatRegClass);
return thread->readFloatReg(reg.regIdx);
}
/** Reads a floating point register in its binary format, instead
@@ -187,8 +193,9 @@ class SimpleExecContext : public ExecContext {
FloatRegBits readFloatRegOperandBits(const StaticInst *si, int idx) override
{
numFpRegReads++;
int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Reg_Base;
return thread->readFloatRegBits(reg_idx);
RegId reg = si->srcRegIdx(idx);
assert(reg.regClass == FloatRegClass);
return thread->readFloatRegBits(reg.regIdx);
}
/** Sets a floating point register of single width to a value. */
@@ -196,8 +203,9 @@ class SimpleExecContext : public ExecContext {
FloatReg val) override
{
numFpRegWrites++;
int reg_idx = si->destRegIdx(idx) - TheISA::FP_Reg_Base;
thread->setFloatReg(reg_idx, val);
RegId reg = si->destRegIdx(idx);
assert(reg.regClass == FloatRegClass);
thread->setFloatReg(reg.regIdx, val);
}
/** Sets the bits of a floating point register of single width
@@ -206,37 +214,42 @@ class SimpleExecContext : public ExecContext {
FloatRegBits val) override
{
numFpRegWrites++;
int reg_idx = si->destRegIdx(idx) - TheISA::FP_Reg_Base;
thread->setFloatRegBits(reg_idx, val);
RegId reg = si->destRegIdx(idx);
assert(reg.regClass == FloatRegClass);
thread->setFloatRegBits(reg.regIdx, val);
}
CCReg readCCRegOperand(const StaticInst *si, int idx) override
{
numCCRegReads++;
int reg_idx = si->srcRegIdx(idx) - TheISA::CC_Reg_Base;
return thread->readCCReg(reg_idx);
RegId reg = si->srcRegIdx(idx);
assert(reg.regClass == CCRegClass);
return thread->readCCReg(reg.regIdx);
}
void setCCRegOperand(const StaticInst *si, int idx, CCReg val) override
{
numCCRegWrites++;
int reg_idx = si->destRegIdx(idx) - TheISA::CC_Reg_Base;
thread->setCCReg(reg_idx, val);
RegId reg = si->destRegIdx(idx);
assert(reg.regClass == CCRegClass);
thread->setCCReg(reg.regIdx, val);
}
MiscReg readMiscRegOperand(const StaticInst *si, int idx) override
{
numIntRegReads++;
int reg_idx = si->srcRegIdx(idx) - TheISA::Misc_Reg_Base;
return thread->readMiscReg(reg_idx);
RegId reg = si->srcRegIdx(idx);
assert(reg.regClass == MiscRegClass);
return thread->readMiscReg(reg.regIdx);
}
void setMiscRegOperand(const StaticInst *si, int idx,
const MiscReg &val) override
{
numIntRegWrites++;
int reg_idx = si->destRegIdx(idx) - TheISA::Misc_Reg_Base;
thread->setMiscReg(reg_idx, val);
RegId reg = si->destRegIdx(idx);
assert(reg.regClass == MiscRegClass);
thread->setMiscReg(reg.regIdx, val);
}
/**
@@ -398,14 +411,14 @@ class SimpleExecContext : public ExecContext {
}
#if THE_ISA == MIPS_ISA
MiscReg readRegOtherThread(int regIdx, ThreadID tid = InvalidThreadID)
MiscReg readRegOtherThread(RegId reg, ThreadID tid = InvalidThreadID)
override
{
panic("Simple CPU models do not support multithreaded "
"register access.");
}
void setRegOtherThread(int regIdx, MiscReg val,
void setRegOtherThread(RegId reg, MiscReg val,
ThreadID tid = InvalidThreadID) override
{
panic("Simple CPU models do not support multithreaded "

View File

@@ -42,6 +42,7 @@
#include "base/types.hh"
#include "config/the_isa.hh"
#include "cpu/op_class.hh"
#include "cpu/reg_class.hh"
#include "cpu/static_inst_fwd.hh"
#include "cpu/thread_context.hh"
#include "enums/StaticInstFlags.hh"
@@ -70,8 +71,6 @@ class StaticInst : public RefCounted, public StaticInstFlags
public:
/// Binary extended machine instruction type.
typedef TheISA::ExtMachInst ExtMachInst;
/// Logical register index type.
typedef TheISA::RegIndex RegIndex;
enum {
MaxInstSrcRegs = TheISA::MaxInstSrcRegs, //< Max source regs
@@ -185,11 +184,11 @@ class StaticInst : public RefCounted, public StaticInstFlags
/// Return logical index (architectural reg num) of i'th destination reg.
/// Only the entries from 0 through numDestRegs()-1 are valid.
RegIndex destRegIdx(int i) const { return _destRegIdx[i]; }
RegId destRegIdx(int i) const { return _destRegIdx[i]; }
/// Return logical index (architectural reg num) of i'th source reg.
/// Only the entries from 0 through numSrcRegs()-1 are valid.
RegIndex srcRegIdx(int i) const { return _srcRegIdx[i]; }
RegId srcRegIdx(int i) const { return _srcRegIdx[i]; }
/// Pointer to a statically allocated "null" instruction object.
/// Used to give eaCompInst() and memAccInst() something to return
@@ -220,9 +219,9 @@ class StaticInst : public RefCounted, public StaticInstFlags
protected:
/// See destRegIdx().
RegIndex _destRegIdx[MaxInstDestRegs];
RegId _destRegIdx[MaxInstDestRegs];
/// See srcRegIdx().
RegIndex _srcRegIdx[MaxInstSrcRegs];
RegId _srcRegIdx[MaxInstSrcRegs];
/**
* Base mnemonic (e.g., "add"). Used by generateDisassembly()

View File

@@ -51,6 +51,7 @@
#include "arch/types.hh"
#include "base/types.hh"
#include "config/the_isa.hh"
#include "cpu/reg_class.hh"
// @todo: Figure out a more architecture independent way to obtain the ITB and
// DTB pointers.
@@ -255,13 +256,13 @@ class ThreadContext
virtual int flattenMiscIndex(int reg) = 0;
virtual uint64_t
readRegOtherThread(int misc_reg, ThreadID tid)
readRegOtherThread(RegId misc_reg, ThreadID tid)
{
return 0;
}
virtual void
setRegOtherThread(int misc_reg, const MiscReg &val, ThreadID tid)
setRegOtherThread(RegId misc_reg, const MiscReg &val, ThreadID tid)
{
}

View File

@@ -58,7 +58,7 @@ TimingExprEvalContext::TimingExprEvalContext(const StaticInstPtr &inst_,
uint64_t TimingExprSrcReg::eval(TimingExprEvalContext &context)
{
return context.inst->srcRegIdx(index);
return context.inst->srcRegIdx(index).regIdx;
}
uint64_t TimingExprReadIntReg::eval(TimingExprEvalContext &context)