diff --git a/src/arch/arm/isa.cc b/src/arch/arm/isa.cc index 596a861210..80035aed1e 100644 --- a/src/arch/arm/isa.cc +++ b/src/arch/arm/isa.cc @@ -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; diff --git a/src/arch/arm/registers.hh b/src/arch/arm/registers.hh index 8d5cfdf6c7..55ba1412f9 100644 --- a/src/arch/arm/registers.hh +++ b/src/arch/arm/registers.hh @@ -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 diff --git a/src/arch/mips/isa.cc b/src/arch/mips/isa.cc index 11d2e80878..7494e9d5f8 100644 --- a/src/arch/mips/isa.cc +++ b/src/arch/mips/isa.cc @@ -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); diff --git a/src/arch/mips/registers.hh b/src/arch/mips/registers.hh index dfe0271426..7dbe30d09d 100644 --- a/src/arch/mips/registers.hh +++ b/src/arch/mips/registers.hh @@ -36,8 +36,6 @@ namespace MipsISA { -const int ZeroReg = 0; - // Not applicable to MIPS using VecElem = ::DummyVecElem; using VecRegContainer = ::DummyVecRegContainer; diff --git a/src/arch/null/registers.hh b/src/arch/null/registers.hh index d56a6a7a2c..b2332b5208 100644 --- a/src/arch/null/registers.hh +++ b/src/arch/null/registers.hh @@ -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; diff --git a/src/arch/power/isa.cc b/src/arch/power/isa.cc index 04eeed1702..56c25bb9eb 100644 --- a/src/arch/power/isa.cc +++ b/src/arch/power/isa.cc @@ -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(); } diff --git a/src/arch/power/registers.hh b/src/arch/power/registers.hh index 75e9125ac7..07081eb45f 100644 --- a/src/arch/power/registers.hh +++ b/src/arch/power/registers.hh @@ -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__ diff --git a/src/arch/riscv/isa.cc b/src/arch/riscv/isa.cc index b740a04f49..6006c7133d 100644 --- a/src/arch/riscv/isa.cc +++ b/src/arch/riscv/isa.cc @@ -182,15 +182,13 @@ M5_VAR_USED const std::array 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(); diff --git a/src/arch/riscv/registers.hh b/src/arch/riscv/registers.hh index e1317e9979..e4d648fca3 100644 --- a/src/arch/riscv/registers.hh +++ b/src/arch/riscv/registers.hh @@ -54,8 +54,6 @@ namespace RiscvISA { -const int ZeroReg = 0; - // Not applicable to RISC-V using VecElem = ::DummyVecElem; using VecRegContainer = ::DummyVecRegContainer; diff --git a/src/arch/sparc/isa.cc b/src/arch/sparc/isa.cc index 5585ee02c5..8d0e8738da 100644 --- a/src/arch/sparc/isa.cc +++ b/src/arch/sparc/isa.cc @@ -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(); } diff --git a/src/arch/sparc/registers.hh b/src/arch/sparc/registers.hh index 025fa28ecc..9c676c536a 100644 --- a/src/arch/sparc/registers.hh +++ b/src/arch/sparc/registers.hh @@ -48,8 +48,6 @@ using VecPredRegContainer = ::DummyVecPredRegContainer; constexpr size_t VecPredRegSizeBits = ::DummyVecPredRegSizeBits; constexpr bool VecPredRegHasPackedRepr = ::DummyVecPredRegHasPackedRepr; -const int ZeroReg = 0; - } // namespace SparcISA #endif diff --git a/src/arch/x86/isa.cc b/src/arch/x86/isa.cc index 556d73f7bb..849b77638a 100644 --- a/src/arch/x86/isa.cc +++ b/src/arch/x86/isa.cc @@ -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(); } diff --git a/src/arch/x86/registers.hh b/src/arch/x86/registers.hh index f94469bfd6..6993b84647 100644 --- a/src/arch/x86/registers.hh +++ b/src/arch/x86/registers.hh @@ -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; diff --git a/src/cpu/checker/cpu.cc b/src/cpu/checker/cpu.cc index 52daea97a5..2bc89e7474 100644 --- a/src/cpu/checker/cpu.cc +++ b/src/cpu/checker/cpu.cc @@ -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) diff --git a/src/cpu/checker/cpu.hh b/src/cpu/checker/cpu.hh index 1c784b390e..04e10823c3 100644 --- a/src/cpu/checker/cpu.hh +++ b/src/cpu/checker/cpu.hh @@ -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; diff --git a/src/cpu/checker/cpu_impl.hh b/src/cpu/checker/cpu_impl.hh index 7f1a2d725c..b18bb8046a 100644 --- a/src/cpu/checker/cpu_impl.hh +++ b/src/cpu/checker/cpu_impl.hh @@ -198,7 +198,7 @@ Checker::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 diff --git a/src/cpu/minor/dyn_inst.cc b/src/cpu/minor/dyn_inst.cc index ceac89446a..b01755a34a 100644 --- a/src/cpu/minor/dyn_inst.cc +++ b/src/cpu/minor/dyn_inst.cc @@ -133,13 +133,14 @@ operator <<(std::ostream &os, const MinorDynInst &inst) return os; } -/** Print a register in the form r, f, m(), z for integer, - * float, misc and zero registers given an 'architectural register number' */ +/** Print a register in the form r, f, m() 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 ®_classes) { - switch (reg.classValue()) - { + const auto ®_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(reg.index()); + os << 'f' << reg.index(); break; case VecRegClass: - os << 'v' << static_cast(reg.index()); + os << 'v' << reg.index(); break; case VecElemClass: - os << 'v' << static_cast(reg.index()) << '[' << - static_cast(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(reg.index()); + os << 'r' << reg.index(); } break; case CCRegClass: - os << 'c' << static_cast(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 ®_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) diff --git a/src/cpu/minor/dyn_inst.hh b/src/cpu/minor/dyn_inst.hh index 7dcf64eab5..1e47b4685a 100644 --- a/src/cpu/minor/dyn_inst.hh +++ b/src/cpu/minor/dyn_inst.hh @@ -48,6 +48,7 @@ #include +#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 ®_classes) const; /** ReportIF interface */ void reportData(std::ostream &os) const; diff --git a/src/cpu/minor/exec_context.hh b/src/cpu/minor/exec_context.hh index 58f4b4b987..5630b4b9a7 100644 --- a/src/cpu/minor/exec_context.hh +++ b/src/cpu/minor/exec_context.hh @@ -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() diff --git a/src/cpu/minor/execute.cc b/src/cpu/minor/execute.cc index a7f66e2603..a85a2c3a5d 100644 --- a/src/cpu/minor/execute.cc +++ b/src/cpu/minor/execute.cc @@ -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); diff --git a/src/cpu/minor/execute.hh b/src/cpu/minor/execute.hh index 50122c5a43..02e55271ae 100644 --- a/src/cpu/minor/execute.hh +++ b/src/cpu/minor/execute.hh @@ -64,6 +64,7 @@ namespace Minor class Execute : public Named { protected: + /** Input port carrying instructions from Decode */ Latch::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; diff --git a/src/cpu/minor/fetch2.cc b/src/cpu/minor/fetch2.cc index 1342e67b61..58d3ad8737 100644 --- a/src/cpu/minor/fetch2.cc +++ b/src/cpu/minor/fetch2.cc @@ -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()); } } diff --git a/src/cpu/minor/lsq.cc b/src/cpu/minor/lsq.cc index 7e156ea3d1..0b6270916a 100644 --- a/src/cpu/minor/lsq.cc +++ b/src/cpu/minor/lsq.cc @@ -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), diff --git a/src/cpu/minor/lsq.hh b/src/cpu/minor/lsq.hh index a16fd3a2d2..96e3023bb0 100644 --- a/src/cpu/minor/lsq.hh +++ b/src/cpu/minor/lsq.hh @@ -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(); diff --git a/src/cpu/minor/scoreboard.cc b/src/cpu/minor/scoreboard.cc index 5f8df8766d..33b6b40baa 100644 --- a/src/cpu/minor/scoreboard.cc +++ b/src/cpu/minor/scoreboard.cc @@ -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); } } } diff --git a/src/cpu/minor/scoreboard.hh b/src/cpu/minor/scoreboard.hh index cbff2509e3..7fefac8ff6 100644 --- a/src/cpu/minor/scoreboard.hh +++ b/src/cpu/minor/scoreboard.hh @@ -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), diff --git a/src/cpu/o3/cpu.cc b/src/cpu/o3/cpu.cc index 02883defe2..5b42bdb4cc 100644 --- a/src/cpu/o3/cpu.cc +++ b/src/cpu/o3/cpu.cc @@ -95,15 +95,15 @@ FullO3CPU::FullO3CPU(const DerivO3CPUParams ¶ms) params.numPhysVecRegs, params.numPhysVecPredRegs, params.numPhysCCRegs, - params.isa[0]->regClasses().at(MiscRegClass).size(), + params.isa[0]->regClasses(), vecMode), freeList(name() + ".freelist", ®File), 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::FullO3CPU(const DerivO3CPUParams ¶ms) 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, ®File, TheISA::ZeroReg, - invalidFPReg, &freeList, vecMode); - - renameMap[tid].init(regClasses, ®File, TheISA::ZeroReg, - invalidFPReg, &freeList, vecMode); + commitRenameMap[tid].init(regClasses, ®File, &freeList, vecMode); + renameMap[tid].init(regClasses, ®File, &freeList, vecMode); } // Initialize rename map to assign physical registers to the diff --git a/src/cpu/o3/probe/elastic_trace.cc b/src/cpu/o3/probe/elastic_trace.cc index b48504abdf..d7b07fe38a 100644 --- a/src/cpu/o3/probe/elastic_trace.cc +++ b/src/cpu/o3/probe/elastic_trace.cc @@ -58,6 +58,10 @@ ElasticTrace::ElasticTrace(const ElasticTraceParams ¶ms) stats(this) { cpu = dynamic_cast*>(params.manager); + const BaseISA::RegClasses ®Classes = + 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 = diff --git a/src/cpu/o3/probe/elastic_trace.hh b/src/cpu/o3/probe/elastic_trace.hh index faac46fbf5..24148b7d9d 100644 --- a/src/cpu/o3/probe/elastic_trace.hh +++ b/src/cpu/o3/probe/elastic_trace.hh @@ -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. diff --git a/src/cpu/o3/regfile.cc b/src/cpu/o3/regfile.cc index fa081915be..bfdb621fec 100644 --- a/src/cpu/o3/regfile.cc +++ b/src/cpu/o3/regfile.cc @@ -50,7 +50,7 @@ PhysRegFile::PhysRegFile(unsigned _numPhysicalIntRegs, unsigned _numPhysicalVecRegs, unsigned _numPhysicalVecPredRegs, unsigned _numPhysicalCCRegs, - unsigned _numPhysicalMiscRegs, + const BaseISA::RegClasses ®Classes, 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); } } diff --git a/src/cpu/o3/regfile.hh b/src/cpu/o3/regfile.hh index 63f7f3cb3a..b67685f365 100644 --- a/src/cpu/o3/regfile.hh +++ b/src/cpu/o3/regfile.hh @@ -44,7 +44,8 @@ #include -#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 intRegFile; std::vector intRegIds; + RegId zeroReg; /** Floating point register file. */ std::vector floatRegFile; @@ -136,7 +138,7 @@ class PhysRegFile unsigned _numPhysicalVecRegs, unsigned _numPhysicalVecPredRegs, unsigned _numPhysicalCCRegs, - unsigned _numPhysicalMiscRegs, + const BaseISA::RegClasses ®Classes, 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; } diff --git a/src/cpu/o3/rename_map.cc b/src/cpu/o3/rename_map.cc index 88199c2dcf..8ec4862399 100644 --- a/src/cpu/o3/rename_map.cc +++ b/src/cpu/o3/rename_map.cc @@ -57,14 +57,14 @@ SimpleRenameMap::SimpleRenameMap() void SimpleRenameMap::init(const RegClassInfo ®_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 ®Classes, - 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)); } diff --git a/src/cpu/o3/rename_map.hh b/src/cpu/o3/rename_map.hh index 46d5400dcd..4d3c9195dc 100644 --- a/src/cpu/o3/rename_map.hh +++ b/src/cpu/o3/rename_map.hh @@ -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 ®_class_info, SimpleFreeList *_freeList, - RegIndex _zeroReg); + void init(const RegClassInfo ®_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 ®Classes, - 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 diff --git a/src/cpu/o3/scoreboard.cc b/src/cpu/o3/scoreboard.cc index 2712035209..269bf88368 100644 --- a/src/cpu/o3/scoreboard.cc +++ b/src/cpu/o3/scoreboard.cc @@ -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) +{} diff --git a/src/cpu/o3/scoreboard.hh b/src/cpu/o3/scoreboard.hh index 18731165bf..74825f9c77 100644 --- a/src/cpu/o3/scoreboard.hh +++ b/src/cpu/o3/scoreboard.hh @@ -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 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; diff --git a/src/cpu/reg_class.hh b/src/cpu/reg_class.hh index d11dc2e19a..3d3a7f70b1 100644 --- a/src/cpu/reg_class.hh +++ b/src/cpu/reg_class.hh @@ -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. diff --git a/src/cpu/simple/base.cc b/src/cpu/simple/base.cc index b2d66f72c5..7939cfbe30 100644 --- a/src/cpu/simple/base.cc +++ b/src/cpu/simple/base.cc @@ -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); diff --git a/src/cpu/simple/base.hh b/src/cpu/simple/base.hh index 0d0cbec049..926b9a4e03 100644 --- a/src/cpu/simple/base.hh +++ b/src/cpu/simple/base.hh @@ -83,6 +83,8 @@ class BaseSimpleCPU : public BaseCPU ThreadID curThread; BPredUnit *branchPred; + const RegIndex zeroReg; + void checkPcEventQueue(); void swapActiveThread();