From f1cd6341eacbe5629cfa164ce00c99129693e058 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 23 Feb 2021 20:51:26 -0800 Subject: [PATCH] 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 Maintainer: Giacomo Travaglini Tested-by: kokoro --- src/arch/arm/isa.cc | 16 +++++++-------- src/arch/arm/registers.hh | 8 -------- src/arch/mips/isa.cc | 16 +++++++-------- src/arch/mips/registers.hh | 2 -- src/arch/null/registers.hh | 7 ++----- src/arch/power/isa.cc | 16 +++++++-------- src/arch/power/registers.hh | 4 ---- src/arch/riscv/isa.cc | 16 +++++++-------- src/arch/riscv/registers.hh | 2 -- src/arch/sparc/isa.cc | 16 +++++++-------- src/arch/sparc/registers.hh | 2 -- src/arch/x86/isa.cc | 16 +++++++-------- src/arch/x86/registers.hh | 3 --- src/cpu/checker/cpu.cc | 4 +++- src/cpu/checker/cpu.hh | 2 ++ src/cpu/checker/cpu_impl.hh | 2 +- src/cpu/minor/dyn_inst.cc | 33 +++++++++++++++++-------------- src/cpu/minor/dyn_inst.hh | 4 +++- src/cpu/minor/exec_context.hh | 4 ++-- src/cpu/minor/execute.cc | 24 ++++++++++++++-------- src/cpu/minor/execute.hh | 4 ++++ src/cpu/minor/fetch2.cc | 3 ++- src/cpu/minor/lsq.cc | 15 ++++++++------ src/cpu/minor/lsq.hh | 14 +++++++++---- src/cpu/minor/scoreboard.cc | 7 +++---- src/cpu/minor/scoreboard.hh | 3 +++ src/cpu/o3/cpu.cc | 18 +++++------------ src/cpu/o3/probe/elastic_trace.cc | 9 ++++++--- src/cpu/o3/probe/elastic_trace.hh | 2 ++ src/cpu/o3/regfile.cc | 7 +++++-- src/cpu/o3/regfile.hh | 8 +++++--- src/cpu/o3/rename_map.cc | 33 ++++++++++--------------------- src/cpu/o3/rename_map.hh | 9 ++------- src/cpu/o3/scoreboard.cc | 12 +++++------ src/cpu/o3/scoreboard.hh | 11 +++++++---- src/cpu/reg_class.hh | 6 +++++- src/cpu/simple/base.cc | 3 ++- src/cpu/simple/base.hh | 2 ++ 38 files changed, 176 insertions(+), 187 deletions(-) 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();