cpu,arch: Move the zero register index into RegClassInfo.

There is a design which has been put forward which eliminates the idea
of a zero register entirely, but in the mean time, to get rid of one
more ISA specific constant, this change moves the ZeroReg constant into
the RegClassInfo class, specifically the IntRegClass instance which is
published by each ISA.

When the idea of zero registers has been eliminated entirely from
non ISA specific code, this and the existing machinery can be
eliminated.

Change-Id: I4302a53220dd5ff6b9b47ecc765bddc6698310ca
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/42685
Reviewed-by: Giacomo Travaglini <giacomo.travaglini@arm.com>
Maintainer: Giacomo Travaglini <giacomo.travaglini@arm.com>
Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
Gabe Black
2021-02-23 20:51:26 -08:00
parent 7036e2174f
commit f1cd6341ea
38 changed files with 176 additions and 187 deletions

View File

@@ -65,15 +65,13 @@ ISA::ISA(const Params &p) : BaseISA(p), system(NULL),
_decoderFlavor(p.decoderFlavor), pmu(p.pmu), impdefAsNop(p.impdef_nop),
afterStartup(false)
{
_regClasses.insert(_regClasses.end(), {
{ NUM_INTREGS },
{ 0 },
{ NumVecRegs },
{ NumVecRegs * TheISA::NumVecElemPerVecReg },
{ NumVecPredRegs },
{ NUM_CCREGS },
{ NUM_MISCREGS }
});
_regClasses.emplace_back(NUM_INTREGS, INTREG_ZERO);
_regClasses.emplace_back(0);
_regClasses.emplace_back(NumVecRegs);
_regClasses.emplace_back(NumVecRegs * TheISA::NumVecElemPerVecReg);
_regClasses.emplace_back(NumVecPredRegs);
_regClasses.emplace_back(NUM_CCREGS);
_regClasses.emplace_back(NUM_MISCREGS);
miscRegs[MISCREG_SCTLR_RST] = 0;

View File

@@ -41,14 +41,6 @@
#ifndef __ARCH_ARM_REGISTERS_HH__
#define __ARCH_ARM_REGISTERS_HH__
#include "arch/arm/regs/int.hh"
#include "arch/arm/regs/vec.hh"
namespace ArmISA
{
const int ZeroReg = INTREG_ZERO;
} // namespace ArmISA
#endif

View File

@@ -94,15 +94,13 @@ ISA::miscRegNames[MISCREG_NUMREGS] =
ISA::ISA(const Params &p) : BaseISA(p), numThreads(p.num_threads),
numVpes(p.num_vpes)
{
_regClasses.insert(_regClasses.end(), {
{ NumIntRegs },
{ NumFloatRegs },
{ 1 }, // Not applicable to MIPS.
{ 2 }, // Not applicable to MIPS.
{ 1 }, // Not applicable to MIPS.
{ 0 }, // Not applicable to MIPS.
{ MISCREG_NUMREGS }
});
_regClasses.emplace_back(NumIntRegs, 0);
_regClasses.emplace_back(NumFloatRegs);
_regClasses.emplace_back(1); // Not applicable to MIPS.
_regClasses.emplace_back(2); // Not applicable to MIPS.
_regClasses.emplace_back(1); // Not applicable to MIPS.
_regClasses.emplace_back(0); // Not applicable to MIPS.
_regClasses.emplace_back(MISCREG_NUMREGS);
miscRegFile.resize(MISCREG_NUMREGS);
bankType.resize(MISCREG_NUMREGS);

View File

@@ -36,8 +36,6 @@
namespace MipsISA
{
const int ZeroReg = 0;
// Not applicable to MIPS
using VecElem = ::DummyVecElem;
using VecRegContainer = ::DummyVecRegContainer;

View File

@@ -40,12 +40,9 @@
#include "arch/generic/vec_pred_reg.hh"
#include "arch/generic/vec_reg.hh"
#include "arch/null/types.hh"
#include "base/types.hh"
namespace NullISA {
const RegIndex ZeroReg = 0;
namespace NullISA
{
// Not applicable to null
using VecElem = ::DummyVecElem;

View File

@@ -48,15 +48,13 @@ namespace PowerISA
ISA::ISA(const Params &p) : BaseISA(p)
{
_regClasses.insert(_regClasses.end(), {
{ NumIntRegs },
{ NumFloatRegs },
{ 1 },
{ 2 },
{ 1 },
{ 0 },
{ NUM_MISCREGS }
});
_regClasses.emplace_back(NumIntRegs, NumIntRegs - 1);
_regClasses.emplace_back(NumFloatRegs);
_regClasses.emplace_back(1);
_regClasses.emplace_back(2);
_regClasses.emplace_back(1);
_regClasses.emplace_back(0);
_regClasses.emplace_back(NUM_MISCREGS);
clear();
}

View File

@@ -33,7 +33,6 @@
#include "arch/generic/vec_pred_reg.hh"
#include "arch/generic/vec_reg.hh"
#include "arch/power/regs/int.hh"
namespace PowerISA
{
@@ -51,9 +50,6 @@ using VecPredRegContainer = ::DummyVecPredRegContainer;
constexpr size_t VecPredRegSizeBits = ::DummyVecPredRegSizeBits;
constexpr bool VecPredRegHasPackedRepr = ::DummyVecPredRegHasPackedRepr;
// There isn't one in Power, but we need to define one somewhere
const int ZeroReg = NumIntRegs - 1;
} // namespace PowerISA
#endif // __ARCH_POWER_REGISTERS_HH__

View File

@@ -182,15 +182,13 @@ M5_VAR_USED const std::array<const char *, NUM_MISCREGS> MiscRegNames = {{
ISA::ISA(const Params &p) : BaseISA(p)
{
_regClasses.insert(_regClasses.begin(), {
{ NumIntRegs },
{ NumFloatRegs },
{ 1 }, // Not applicable to RISCV
{ 2 }, // Not applicable to RISCV
{ 1 }, // Not applicable to RISCV
{ 0 }, // Not applicable to RISCV
{ NUM_MISCREGS }
});
_regClasses.emplace_back(NumIntRegs, 0);
_regClasses.emplace_back(NumFloatRegs);
_regClasses.emplace_back(1); // Not applicable to RISCV
_regClasses.emplace_back(2); // Not applicable to RISCV
_regClasses.emplace_back(1); // Not applicable to RISCV
_regClasses.emplace_back(0); // Not applicable to RISCV
_regClasses.emplace_back(NUM_MISCREGS);
miscRegFile.resize(NUM_MISCREGS);
clear();

View File

@@ -54,8 +54,6 @@
namespace RiscvISA
{
const int ZeroReg = 0;
// Not applicable to RISC-V
using VecElem = ::DummyVecElem;
using VecRegContainer = ::DummyVecRegContainer;

View File

@@ -65,15 +65,13 @@ static const PSTATE PstateMask = buildPstateMask();
ISA::ISA(const Params &p) : BaseISA(p)
{
_regClasses.insert(_regClasses.end(), {
{ NumIntRegs },
{ NumFloatRegs },
{ 1 }, // Not applicable for SPARC
{ 2 }, // Not applicable for SPARC
{ 1 }, // Not applicable for SPARC
{ 0 }, // Not applicable for SPARC
{ NumMiscRegs }
});
_regClasses.emplace_back(NumIntRegs, 0);
_regClasses.emplace_back(NumFloatRegs);
_regClasses.emplace_back(1); // Not applicable for SPARC
_regClasses.emplace_back(2); // Not applicable for SPARC
_regClasses.emplace_back(1); // Not applicable for SPARC
_regClasses.emplace_back(0); // Not applicable for SPARC
_regClasses.emplace_back(NumMiscRegs);
clear();
}

View File

@@ -48,8 +48,6 @@ using VecPredRegContainer = ::DummyVecPredRegContainer;
constexpr size_t VecPredRegSizeBits = ::DummyVecPredRegSizeBits;
constexpr bool VecPredRegHasPackedRepr = ::DummyVecPredRegHasPackedRepr;
const int ZeroReg = 0;
} // namespace SparcISA
#endif

View File

@@ -139,15 +139,13 @@ ISA::ISA(const X86ISAParams &p) : BaseISA(p), vendorString(p.vendor_string)
fatal_if(vendorString.size() != 12,
"CPUID vendor string must be 12 characters\n");
_regClasses.insert(_regClasses.end(), {
{ NumIntRegs },
{ NumFloatRegs },
{ 1 }, // Not applicable to X86
{ 2 }, // Not applicable to X86
{ 1 }, // Not applicable to X86
{ NUM_CCREGS },
{ NUM_MISCREGS },
});
_regClasses.emplace_back(NumIntRegs, NUM_INTREGS);
_regClasses.emplace_back(NumFloatRegs);
_regClasses.emplace_back(1); // Not applicable to X86
_regClasses.emplace_back(2); // Not applicable to X86
_regClasses.emplace_back(1); // Not applicable to X86
_regClasses.emplace_back(NUM_CCREGS);
_regClasses.emplace_back(NUM_MISCREGS);
clear();
}

View File

@@ -61,9 +61,6 @@ enum DependenceTags
Max_Reg_Index = Misc_Reg_Base + NUM_MISCREGS
};
// There is no such register in X86.
const int ZeroReg = NUM_INTREGS;
// Not applicable to x86
using VecElem = ::DummyVecElem;
using VecRegContainer = ::DummyVecRegContainer;

View File

@@ -59,7 +59,9 @@ CheckerCPU::init()
}
CheckerCPU::CheckerCPU(const Params &p)
: BaseCPU(p, true), systemPtr(NULL), icachePort(NULL), dcachePort(NULL),
: BaseCPU(p, true),
zeroReg(params().isa[0]->regClasses().at(IntRegClass).zeroReg()),
systemPtr(NULL), icachePort(NULL), dcachePort(NULL),
tc(NULL), thread(NULL),
unverifiedReq(nullptr),
unverifiedMemData(nullptr)

View File

@@ -84,6 +84,8 @@ class CheckerCPU : public BaseCPU, public ExecContext
/** id attached to all issued requests */
RequestorID requestorId;
const RegIndex zeroReg;
public:
void init() override;

View File

@@ -198,7 +198,7 @@ Checker<Impl>::verify(const DynInstPtr &completed_inst)
Fault fault = NoFault;
// maintain $r0 semantics
thread->setIntReg(TheISA::ZeroReg, 0);
thread->setIntReg(zeroReg, 0);
// Check if any recent PC changes match up with anything we
// expect to happen. This is mostly to check if traps or

View File

@@ -133,13 +133,14 @@ operator <<(std::ostream &os, const MinorDynInst &inst)
return os;
}
/** 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' */
/** Print a register in the form r<n>, f<n>, m<n>(<name>) for integer,
* float, and misc given an 'architectural register number' */
static void
printRegName(std::ostream &os, const RegId& reg)
printRegName(std::ostream &os, const RegId& reg,
const BaseISA::RegClasses &reg_classes)
{
switch (reg.classValue())
{
const auto &reg_class = reg_classes.at(reg.classValue());
switch (reg.classValue()) {
case MiscRegClass:
{
RegIndex misc_reg = reg.index();
@@ -154,24 +155,23 @@ printRegName(std::ostream &os, const RegId& reg)
}
break;
case FloatRegClass:
os << 'f' << static_cast<unsigned int>(reg.index());
os << 'f' << reg.index();
break;
case VecRegClass:
os << 'v' << static_cast<unsigned int>(reg.index());
os << 'v' << reg.index();
break;
case VecElemClass:
os << 'v' << static_cast<unsigned int>(reg.index()) << '[' <<
static_cast<unsigned int>(reg.elemIndex()) << ']';
os << 'v' << reg.index() << '[' << reg.elemIndex() << ']';
break;
case IntRegClass:
if (reg.index() == TheISA::ZeroReg) {
if (reg.index() == reg_class.zeroReg()) {
os << 'z';
} else {
os << 'r' << static_cast<unsigned int>(reg.index());
os << 'r' << reg.index();
}
break;
case CCRegClass:
os << 'c' << static_cast<unsigned int>(reg.index());
os << 'c' << reg.index();
break;
default:
panic("Unknown register class: %d", (int)reg.classValue());
@@ -179,7 +179,8 @@ printRegName(std::ostream &os, const RegId& reg)
}
void
MinorDynInst::minorTraceInst(const Named &named_object) const
MinorDynInst::minorTraceInst(const Named &named_object,
const BaseISA::RegClasses &reg_classes) const
{
if (isFault()) {
MINORINST(&named_object, "id=F;%s addr=0x%x fault=\"%s\"\n",
@@ -197,7 +198,8 @@ MinorDynInst::minorTraceInst(const Named &named_object) const
unsigned int src_reg = 0;
while (src_reg < num_src_regs) {
printRegName(regs_str, staticInst->srcRegIdx(src_reg));
printRegName(regs_str, staticInst->srcRegIdx(src_reg),
reg_classes);
src_reg++;
if (src_reg != num_src_regs)
@@ -208,7 +210,8 @@ MinorDynInst::minorTraceInst(const Named &named_object) const
unsigned int dest_reg = 0;
while (dest_reg < num_dest_regs) {
printRegName(regs_str, staticInst->destRegIdx(dest_reg));
printRegName(regs_str, staticInst->destRegIdx(dest_reg),
reg_classes);
dest_reg++;
if (dest_reg != num_dest_regs)

View File

@@ -48,6 +48,7 @@
#include <iostream>
#include "arch/generic/isa.hh"
#include "base/named.hh"
#include "base/refcnt.hh"
#include "base/types.hh"
@@ -273,7 +274,8 @@ class MinorDynInst : public RefCounted
/** Print (possibly verbose) instruction information for
* MinorTrace using the given Named object's name */
void minorTraceInst(const Named &named_object) const;
void minorTraceInst(const Named &named_object,
const BaseISA::RegClasses &reg_classes) const;
/** ReportIF interface */
void reportData(std::ostream &os) const;

View File

@@ -83,7 +83,7 @@ class ExecContext : public ::ExecContext
ExecContext (
MinorCPU &cpu_,
SimpleThread &thread_, Execute &execute_,
MinorDynInstPtr inst_) :
MinorDynInstPtr inst_, RegIndex zeroReg) :
cpu(cpu_),
thread(thread_),
execute(execute_),
@@ -93,7 +93,7 @@ class ExecContext : public ::ExecContext
pcState(inst->pc);
setPredicate(inst->readPredicate());
setMemAccPredicate(inst->readMemAccPredicate());
thread.setIntReg(TheISA::ZeroReg, 0);
thread.setIntReg(zeroReg, 0);
}
~ExecContext()

View File

@@ -66,6 +66,8 @@ Execute::Execute(const std::string &name_,
inp(inp_),
out(out_),
cpu(cpu_),
zeroReg(cpu.threads[0]->getIsaPtr()->regClasses().
at(IntRegClass).zeroReg()),
issueLimit(params.executeIssueLimit),
memoryIssueLimit(params.executeMemoryIssueLimit),
commitLimit(params.executeCommitLimit),
@@ -84,8 +86,10 @@ Execute::Execute(const std::string &name_,
params.executeLSQRequestsQueueSize,
params.executeLSQTransfersQueueSize,
params.executeLSQStoreBufferSize,
params.executeLSQMaxStoreBufferStoresPerCycle),
executeInfo(params.numThreads, ExecuteThreadInfo(params.executeCommitLimit)),
params.executeLSQMaxStoreBufferStoresPerCycle,
zeroReg),
executeInfo(params.numThreads,
ExecuteThreadInfo(params.executeCommitLimit)),
interruptPriority(0),
issuePriority(0),
commitPriority(0)
@@ -322,7 +326,7 @@ Execute::handleMemResponse(MinorDynInstPtr inst,
ThreadID thread_id = inst->id.threadId;
ThreadContext *thread = cpu.getContext(thread_id);
ExecContext context(cpu, *cpu.threads[thread_id], *this, inst);
ExecContext context(cpu, *cpu.threads[thread_id], *this, inst, zeroReg);
PacketPtr packet = response->packet;
@@ -458,7 +462,7 @@ Execute::executeMemRefInst(MinorDynInstPtr inst, BranchData &branch,
TheISA::PCState old_pc = thread->pcState();
ExecContext context(cpu, *cpu.threads[inst->id.threadId],
*this, inst);
*this, inst, zeroReg);
DPRINTF(MinorExecute, "Initiating memRef inst: %s\n", *inst);
@@ -776,8 +780,10 @@ Execute::issue(ThreadID thread_id)
if (issued) {
/* Generate MinorTrace's MinorInst lines. Do this at commit
* to allow better instruction annotation? */
if (DTRACE(MinorTrace) && !inst->isBubble())
inst->minorTraceInst(*this);
if (DTRACE(MinorTrace) && !inst->isBubble()) {
inst->minorTraceInst(*this,
cpu.threads[0]->getIsaPtr()->regClasses());
}
/* Mark up barriers in the LSQ */
if (!discarded && inst->isInst() &&
@@ -902,7 +908,8 @@ Execute::commitInst(MinorDynInstPtr inst, bool early_memory_issue,
panic("We should never hit the case where we try to commit from a "
"suspended thread as the streamSeqNum should not match");
} else if (inst->isFault()) {
ExecContext context(cpu, *cpu.threads[thread_id], *this, inst);
ExecContext context(cpu, *cpu.threads[thread_id], *this,
inst, zeroReg);
DPRINTF(MinorExecute, "Fault inst reached Execute: %s\n",
inst->fault->name());
@@ -963,7 +970,8 @@ Execute::commitInst(MinorDynInstPtr inst, bool early_memory_issue,
* backwards, so no other branches may evaluate this cycle*/
completed_inst = false;
} else {
ExecContext context(cpu, *cpu.threads[thread_id], *this, inst);
ExecContext context(cpu, *cpu.threads[thread_id], *this,
inst, zeroReg);
DPRINTF(MinorExecute, "Committing inst: %s\n", *inst);

View File

@@ -64,6 +64,7 @@ namespace Minor
class Execute : public Named
{
protected:
/** Input port carrying instructions from Decode */
Latch<ForwardInstData>::Output inp;
@@ -73,6 +74,9 @@ class Execute : public Named
/** Pointer back to the containing CPU */
MinorCPU &cpu;
/** Index of the zero integer register. */
const RegIndex zeroReg;
/** Number of instructions that can be issued per cycle */
unsigned int issueLimit;

View File

@@ -492,7 +492,8 @@ Fetch2::evaluate()
if (DTRACE(MinorTrace) && !dyn_inst->isFault() &&
dyn_inst->staticInst->isMacroop())
{
dyn_inst->minorTraceInst(*this);
dyn_inst->minorTraceInst(*this,
cpu.threads[0]->getIsaPtr()->regClasses());
}
}

View File

@@ -54,9 +54,10 @@ namespace Minor
{
LSQ::LSQRequest::LSQRequest(LSQ &port_, MinorDynInstPtr inst_, bool isLoad_,
PacketDataPtr data_, uint64_t *res_) :
RegIndex zero_reg, PacketDataPtr data_, uint64_t *res_) :
SenderState(),
port(port_),
zeroReg(zero_reg),
inst(inst_),
isLoad(isLoad_),
data(data_),
@@ -76,7 +77,7 @@ LSQ::LSQRequest::tryToSuppressFault()
{
SimpleThread &thread = *port.cpu.threads[inst->id.threadId];
TheISA::PCState old_pc = thread.pcState();
ExecContext context(port.cpu, thread, port.execute, inst);
ExecContext context(port.cpu, thread, port.execute, inst, zeroReg);
M5_VAR_USED Fault fault = inst->translationFault;
// Give the instruction a chance to suppress a translation fault
@@ -99,7 +100,7 @@ LSQ::LSQRequest::completeDisabledMemAccess()
SimpleThread &thread = *port.cpu.threads[inst->id.threadId];
TheISA::PCState old_pc = thread.pcState();
ExecContext context(port.cpu, thread, port.execute, inst);
ExecContext context(port.cpu, thread, port.execute, inst, zeroReg);
context.setMemAccPredicate(false);
inst->staticInst->completeAcc(nullptr, &context, inst->traceData);
@@ -388,7 +389,7 @@ LSQ::SplitDataRequest::finish(const Fault &fault_, const RequestPtr &request_,
LSQ::SplitDataRequest::SplitDataRequest(LSQ &port_, MinorDynInstPtr inst_,
bool isLoad_, PacketDataPtr data_, uint64_t *res_) :
LSQRequest(port_, inst_, isLoad_, data_, res_),
LSQRequest(port_, inst_, isLoad_, port_.zeroReg, data_, res_),
translationEvent([this]{ sendNextFragmentToTranslation(); },
"translationEvent"),
numFragments(0),
@@ -1127,7 +1128,7 @@ LSQ::tryToSendToTransfers(LSQRequestPtr request)
SimpleThread &thread = *cpu.threads[request->inst->id.threadId];
TheISA::PCState old_pc = thread.pcState();
ExecContext context(cpu, thread, execute, request->inst);
ExecContext context(cpu, thread, execute, request->inst, zeroReg);
/* Handle LLSC requests and tests */
if (is_load) {
@@ -1401,10 +1402,12 @@ LSQ::LSQ(std::string name_, std::string dcache_port_name_,
unsigned int in_memory_system_limit, unsigned int line_width,
unsigned int requests_queue_size, unsigned int transfers_queue_size,
unsigned int store_buffer_size,
unsigned int store_buffer_cycle_store_limit) :
unsigned int store_buffer_cycle_store_limit,
RegIndex zero_reg) :
Named(name_),
cpu(cpu_),
execute(execute_),
zeroReg(zero_reg),
dcachePort(dcache_port_name_, *this, cpu_),
lastMemBarrier(cpu.numThreads, 0),
state(MemoryRunning),

View File

@@ -68,6 +68,8 @@ class LSQ : public Named
MinorCPU &cpu;
Execute &execute;
const RegIndex zeroReg;
protected:
/** State of memory access for head access. */
enum MemoryState
@@ -128,6 +130,8 @@ class LSQ : public Named
/** Owning port */
LSQ &port;
const RegIndex zeroReg;
/** Instruction which made this request */
MinorDynInstPtr inst;
@@ -200,7 +204,8 @@ class LSQ : public Named
public:
LSQRequest(LSQ &port_, MinorDynInstPtr inst_, bool isLoad_,
PacketDataPtr data_ = NULL, uint64_t *res_ = NULL);
RegIndex zero_reg, PacketDataPtr data_ = NULL,
uint64_t *res_ = NULL);
virtual ~LSQRequest();
@@ -310,7 +315,7 @@ class LSQ : public Named
public:
SpecialDataRequest(LSQ &port_, MinorDynInstPtr inst_) :
/* Say this is a load, not actually relevant */
LSQRequest(port_, inst_, true, NULL, 0)
LSQRequest(port_, inst_, true, port_.zeroReg, NULL, 0)
{ }
};
@@ -377,7 +382,7 @@ class LSQ : public Named
public:
SingleDataRequest(LSQ &port_, MinorDynInstPtr inst_,
bool isLoad_, PacketDataPtr data_ = NULL, uint64_t *res_ = NULL) :
LSQRequest(port_, inst_, isLoad_, data_, res_),
LSQRequest(port_, inst_, isLoad_, port_.zeroReg, data_, res_),
packetInFlight(false),
packetSent(false)
{ }
@@ -647,7 +652,8 @@ class LSQ : public Named
unsigned int max_accesses_in_memory_system, unsigned int line_width,
unsigned int requests_queue_size, unsigned int transfers_queue_size,
unsigned int store_buffer_size,
unsigned int store_buffer_cycle_store_limit);
unsigned int store_buffer_cycle_store_limit,
RegIndex zero_reg);
virtual ~LSQ();

View File

@@ -52,7 +52,7 @@ Scoreboard::findIndex(const RegId& reg, Index &scoreboard_index)
switch (reg.classValue()) {
case IntRegClass:
if (reg.index() == TheISA::ZeroReg) {
if (reg.index() == zeroReg) {
/* Don't bother with the zero register */
ret = false;
} else {
@@ -132,9 +132,8 @@ Scoreboard::markupInstDests(MinorDynInstPtr inst, Cycles retire_time,
" regIndex: %d final numResults: %d returnCycle: %d\n",
*inst, index, numResults[index], returnCycle[index]);
} else {
/* Use ZeroReg to mark invalid/untracked dests */
inst->flatDestRegIdx[dest_index] = RegId(IntRegClass,
TheISA::ZeroReg);
/* Use zeroReg to mark invalid/untracked dests */
inst->flatDestRegIdx[dest_index] = RegId(IntRegClass, zeroReg);
}
}
}

View File

@@ -78,6 +78,8 @@ class Scoreboard : public Named
* [NumIntRegs+NumCCRegs, NumFloatRegs+NumIntRegs+NumCCRegs-1] */
const unsigned numRegs;
const RegIndex zeroReg;
/** Type to use when indexing numResults */
typedef unsigned short int Index;
@@ -112,6 +114,7 @@ class Scoreboard : public Named
vecRegOffset(ccRegOffset + reg_classes.at(CCRegClass).size()),
vecPredRegOffset(vecRegOffset + reg_classes.at(VecElemClass).size()),
numRegs(vecPredRegOffset + reg_classes.at(VecPredRegClass).size()),
zeroReg(reg_classes.at(IntRegClass).zeroReg()),
numResults(numRegs, 0),
numUnpredictableResults(numRegs, 0),
fuIndices(numRegs, 0),

View File

@@ -95,15 +95,15 @@ FullO3CPU<Impl>::FullO3CPU(const DerivO3CPUParams &params)
params.numPhysVecRegs,
params.numPhysVecPredRegs,
params.numPhysCCRegs,
params.isa[0]->regClasses().at(MiscRegClass).size(),
params.isa[0]->regClasses(),
vecMode),
freeList(name() + ".freelist", &regFile),
rob(this, params),
scoreboard(name() + ".scoreboard",
regFile.totalNumPhysRegs()),
scoreboard(name() + ".scoreboard", regFile.totalNumPhysRegs(),
params.isa[0]->regClasses().at(IntRegClass).zeroReg()),
isa(numThreads, NULL),
@@ -225,16 +225,8 @@ FullO3CPU<Impl>::FullO3CPU(const DerivO3CPUParams &params)
assert(isa[tid]->initVecRegRenameMode() ==
isa[0]->initVecRegRenameMode());
// 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 = regClasses.at(FloatRegClass).size() + 1;
commitRenameMap[tid].init(regClasses, &regFile, TheISA::ZeroReg,
invalidFPReg, &freeList, vecMode);
renameMap[tid].init(regClasses, &regFile, TheISA::ZeroReg,
invalidFPReg, &freeList, vecMode);
commitRenameMap[tid].init(regClasses, &regFile, &freeList, vecMode);
renameMap[tid].init(regClasses, &regFile, &freeList, vecMode);
}
// Initialize rename map to assign physical registers to the

View File

@@ -58,6 +58,10 @@ ElasticTrace::ElasticTrace(const ElasticTraceParams &params)
stats(this)
{
cpu = dynamic_cast<FullO3CPU<O3CPUImpl>*>(params.manager);
const BaseISA::RegClasses &regClasses =
cpu->getContext(0)->getIsaPtr()->regClasses();
zeroReg = regClasses.at(IntRegClass).zeroReg();
fatal_if(!cpu, "Manager of %s is not of type O3CPU and thus does not "\
"support dependency tracing.\n", name());
@@ -241,7 +245,7 @@ ElasticTrace::updateRegDep(const DynInstConstPtr& dyn_inst)
const RegId& src_reg = dyn_inst->srcRegIdx(src_idx);
if (!src_reg.isMiscReg() &&
!(src_reg.isIntReg() && src_reg.index() == TheISA::ZeroReg)) {
!(src_reg.isIntReg() && src_reg.index() == zeroReg)) {
// Get the physical register index of the i'th source register.
PhysRegIdPtr phys_src_reg = dyn_inst->regs.renamedSrcIdx(src_idx);
DPRINTFR(ElasticTrace, "[sn:%lli] Check map for src reg"
@@ -273,8 +277,7 @@ ElasticTrace::updateRegDep(const DynInstConstPtr& dyn_inst)
// CC register and not a Misc register.
const RegId& dest_reg = dyn_inst->destRegIdx(dest_idx);
if (!dest_reg.isMiscReg() &&
!(dest_reg.isIntReg() &&
dest_reg.index() == TheISA::ZeroReg)) {
!(dest_reg.isIntReg() && dest_reg.index() == zeroReg)) {
// Get the physical register index of the i'th destination
// register.
PhysRegIdPtr phys_dest_reg =

View File

@@ -186,6 +186,8 @@ class ElasticTrace : public ProbeListenerObject
*/
bool firstWin;
RegIndex zeroReg;
/**
* @defgroup InstExecInfo Struct for storing information before an
* instruction reaches the commit stage, e.g. execute timestamp.

View File

@@ -50,7 +50,7 @@ PhysRegFile::PhysRegFile(unsigned _numPhysicalIntRegs,
unsigned _numPhysicalVecRegs,
unsigned _numPhysicalVecPredRegs,
unsigned _numPhysicalCCRegs,
unsigned _numPhysicalMiscRegs,
const BaseISA::RegClasses &regClasses,
VecMode vmode)
: intRegFile(_numPhysicalIntRegs),
floatRegFile(_numPhysicalFloatRegs),
@@ -80,6 +80,8 @@ PhysRegFile::PhysRegFile(unsigned _numPhysicalIntRegs,
intRegIds.emplace_back(IntRegClass, phys_reg, flat_reg_idx++);
}
zeroReg = RegId(IntRegClass, regClasses.at(IntRegClass).zeroReg());
// The next batch of the registers are the floating-point physical
// registers; put them onto the floating-point free list.
for (phys_reg = 0; phys_reg < numPhysicalFloatRegs; phys_reg++) {
@@ -116,7 +118,8 @@ PhysRegFile::PhysRegFile(unsigned _numPhysicalIntRegs,
}
// Misc regs have a fixed mapping but still need PhysRegIds.
for (phys_reg = 0; phys_reg < _numPhysicalMiscRegs; phys_reg++) {
for (phys_reg = 0; phys_reg < regClasses.at(MiscRegClass).size();
phys_reg++) {
miscRegIds.emplace_back(MiscRegClass, phys_reg, 0);
}
}

View File

@@ -44,7 +44,8 @@
#include <vector>
#include "arch/types.hh"
#include "arch/generic/isa.hh"
#include "arch/registers.hh"
#include "base/trace.hh"
#include "config/the_isa.hh"
#include "cpu/o3/comm.hh"
@@ -69,6 +70,7 @@ class PhysRegFile
/** Integer register file. */
std::vector<RegVal> intRegFile;
std::vector<PhysRegId> intRegIds;
RegId zeroReg;
/** Floating point register file. */
std::vector<RegVal> floatRegFile;
@@ -136,7 +138,7 @@ class PhysRegFile
unsigned _numPhysicalVecRegs,
unsigned _numPhysicalVecPredRegs,
unsigned _numPhysicalCCRegs,
unsigned _numPhysicalMiscRegs,
const BaseISA::RegClasses &regClasses,
VecMode vmode
);
@@ -274,7 +276,7 @@ class PhysRegFile
DPRINTF(IEW, "RegFile: Setting int register %i to %#x\n",
phys_reg->index(), val);
if (phys_reg->index() != TheISA::ZeroReg)
if (phys_reg->index() != zeroReg.index())
intRegFile[phys_reg->index()] = val;
}

View File

@@ -57,14 +57,14 @@ SimpleRenameMap::SimpleRenameMap()
void
SimpleRenameMap::init(const RegClassInfo &reg_class_info,
SimpleFreeList *_freeList, RegIndex _zeroReg)
SimpleFreeList *_freeList)
{
assert(freeList == NULL);
assert(map.empty());
map.resize(reg_class_info.size());
freeList = _freeList;
zeroReg = RegId(IntRegClass, _zeroReg);
zeroReg = RegId(IntRegClass, reg_class_info.zeroReg());
}
SimpleRenameMap::RenameInfo
@@ -76,7 +76,7 @@ SimpleRenameMap::rename(const RegId& arch_reg)
PhysRegIdPtr prev_reg = map[arch_reg.flatIndex()];
if (arch_reg == zeroReg) {
assert(prev_reg->index() == TheISA::ZeroReg);
assert(prev_reg->index() == zeroReg.index());
renamed_reg = prev_reg;
} else if (prev_reg->getNumPinnedWrites() > 0) {
// Do not rename if the register is pinned
@@ -107,30 +107,17 @@ SimpleRenameMap::rename(const RegId& arch_reg)
void
UnifiedRenameMap::init(const BaseISA::RegClasses &regClasses,
PhysRegFile *_regFile,
RegIndex _intZeroReg,
RegIndex _floatZeroReg,
UnifiedFreeList *freeList,
VecMode _mode)
PhysRegFile *_regFile, UnifiedFreeList *freeList, VecMode _mode)
{
regFile = _regFile;
vecMode = _mode;
intMap.init(regClasses.at(IntRegClass), &(freeList->intList), _intZeroReg);
floatMap.init(regClasses.at(FloatRegClass), &(freeList->floatList),
_floatZeroReg);
vecMap.init(regClasses.at(VecRegClass), &(freeList->vecList),
(RegIndex)-1);
vecElemMap.init(regClasses.at(VecElemClass), &(freeList->vecElemList),
(RegIndex)-1);
predMap.init(regClasses.at(VecPredRegClass), &(freeList->predList),
(RegIndex)-1);
ccMap.init(regClasses.at(CCRegClass), &(freeList->ccList), (RegIndex)-1);
intMap.init(regClasses.at(IntRegClass), &(freeList->intList));
floatMap.init(regClasses.at(FloatRegClass), &(freeList->floatList));
vecMap.init(regClasses.at(VecRegClass), &(freeList->vecList));
vecElemMap.init(regClasses.at(VecElemClass), &(freeList->vecElemList));
predMap.init(regClasses.at(VecPredRegClass), &(freeList->predList));
ccMap.init(regClasses.at(CCRegClass), &(freeList->ccList));
}

View File

@@ -96,8 +96,7 @@ class SimpleRenameMap
* it's awkward to initialize this object via the constructor.
* Instead, this method is used for initialization.
*/
void init(const RegClassInfo &reg_class_info, SimpleFreeList *_freeList,
RegIndex _zeroReg);
void init(const RegClassInfo &reg_class_info, SimpleFreeList *_freeList);
/**
* Pair of a physical register and a physical register. Used to
@@ -210,11 +209,7 @@ class UnifiedRenameMap
/** Initializes rename map with given parameters. */
void init(const BaseISA::RegClasses &regClasses,
PhysRegFile *_regFile,
RegIndex _intZeroReg,
RegIndex _floatZeroReg,
UnifiedFreeList *freeList,
VecMode _mode);
PhysRegFile *_regFile, UnifiedFreeList *freeList, VecMode _mode);
/**
* Tell rename map to get a new free physical register to remap

View File

@@ -29,10 +29,8 @@
#include "cpu/o3/scoreboard.hh"
Scoreboard::Scoreboard(const std::string &_my_name,
unsigned _numPhysicalRegs)
: _name(_my_name),
regScoreBoard(_numPhysicalRegs, true),
numPhysRegs(_numPhysicalRegs)
{
}
Scoreboard::Scoreboard(const std::string &_my_name, unsigned _numPhysicalRegs,
RegIndex zero_reg) :
_name(_my_name), zeroReg(zero_reg), regScoreBoard(_numPhysicalRegs, true),
numPhysRegs(_numPhysicalRegs)
{}

View File

@@ -50,6 +50,9 @@ class Scoreboard
* explicitly because Scoreboard is not a SimObject. */
const std::string _name;
/** Index of the zero integer register. */
const RegIndex zeroReg;
/** Scoreboard of physical integer registers, saying whether or not they
* are ready. */
std::vector<bool> regScoreBoard;
@@ -62,8 +65,8 @@ class Scoreboard
* @param _numPhysicalRegs Number of physical registers.
* @param _numMiscRegs Number of miscellaneous registers.
*/
Scoreboard(const std::string &_my_name,
unsigned _numPhysicalRegs);
Scoreboard(const std::string &_my_name, unsigned _numPhysicalRegs,
RegIndex _zero_reg);
/** Destructor. */
~Scoreboard() {}
@@ -84,7 +87,7 @@ class Scoreboard
bool ready = regScoreBoard[phys_reg->flatIndex()];
if (phys_reg->isIntPhysReg() && phys_reg->index() == TheISA::ZeroReg)
if (phys_reg->isIntPhysReg() && phys_reg->index() == zeroReg)
assert(ready);
return ready;
@@ -121,7 +124,7 @@ class Scoreboard
}
// zero reg should never be marked unready
if (phys_reg->isIntPhysReg() && phys_reg->index() == TheISA::ZeroReg)
if (phys_reg->isIntPhysReg() && phys_reg->index() == zeroReg)
return;
regScoreBoard[phys_reg->flatIndex()] = false;

View File

@@ -66,11 +66,15 @@ class RegClassInfo
{
private:
size_t _size;
const RegIndex _zeroReg;
public:
RegClassInfo(size_t new_size) : _size(new_size) {}
RegClassInfo(size_t new_size, RegIndex new_zero = -1) :
_size(new_size), _zeroReg(new_zero)
{}
size_t size() const { return _size; }
RegIndex zeroReg() const { return _zeroReg; }
};
/** Number of register classes.

View File

@@ -81,6 +81,7 @@ BaseSimpleCPU::BaseSimpleCPU(const BaseSimpleCPUParams &p)
: BaseCPU(p),
curThread(0),
branchPred(p.branchPred),
zeroReg(p.isa[0]->regClasses().at(IntRegClass).zeroReg()),
traceData(NULL),
inst(),
_status(Idle)
@@ -308,7 +309,7 @@ BaseSimpleCPU::preExecute()
SimpleThread* thread = t_info.thread;
// maintain $r0 semantics
thread->setIntReg(TheISA::ZeroReg, 0);
thread->setIntReg(zeroReg, 0);
// resets predicates
t_info.setPredicate(true);

View File

@@ -83,6 +83,8 @@ class BaseSimpleCPU : public BaseCPU
ThreadID curThread;
BPredUnit *branchPred;
const RegIndex zeroReg;
void checkPcEventQueue();
void swapActiveThread();