diff options
64 files changed, 744 insertions, 752 deletions
diff --git a/src/arch/alpha/isa.hh b/src/arch/alpha/isa.hh index 6c06fc397..80d8ab149 100644 --- a/src/arch/alpha/isa.hh +++ b/src/arch/alpha/isa.hh @@ -38,6 +38,7 @@ #include "arch/alpha/registers.hh" #include "arch/alpha/types.hh" #include "base/types.hh" +#include "cpu/reg_class.hh" #include "sim/sim_object.hh" #include "sim/system.hh" @@ -95,6 +96,8 @@ namespace AlphaISA void serialize(CheckpointOut &cp) const override; void unserialize(CheckpointIn &cp) override; + RegId flattenRegId(const RegId& regId) const { return regId; } + int flattenIntIndex(int reg) const { diff --git a/src/arch/alpha/isa/branch.isa b/src/arch/alpha/isa/branch.isa index d4b6db043..a43efff9c 100644 --- a/src/arch/alpha/isa/branch.isa +++ b/src/arch/alpha/isa/branch.isa @@ -130,7 +130,7 @@ output decoder {{ Jump::branchTarget(ThreadContext *tc) const { PCState pc = tc->pcState(); - uint64_t Rb = tc->readIntReg(_srcRegIdx[0].regIdx); + uint64_t Rb = tc->readIntReg(_srcRegIdx[0].index()); pc.set((Rb & ~3) | (pc.pc() & 1)); return pc; } diff --git a/src/arch/alpha/isa/fp.isa b/src/arch/alpha/isa/fp.isa index afece988f..6213c8e08 100644 --- a/src/arch/alpha/isa/fp.isa +++ b/src/arch/alpha/isa/fp.isa @@ -149,7 +149,7 @@ output decoder {{ #ifndef SS_COMPATIBLE_DISASSEMBLY std::string suffix(""); - suffix += ((_destRegIdx[0].regClass == FloatRegClass) + suffix += ((_destRegIdx[0].isFloatReg()) ? fpTrappingModeSuffix[trappingMode] : intTrappingModeSuffix[trappingMode]); suffix += roundingModeSuffix[roundingMode]; diff --git a/src/arch/alpha/isa/main.isa b/src/arch/alpha/isa/main.isa index e75cec524..34e2cb5ad 100644 --- a/src/arch/alpha/isa/main.isa +++ b/src/arch/alpha/isa/main.isa @@ -246,11 +246,11 @@ output decoder {{ void AlphaStaticInst::printReg(std::ostream &os, RegId reg) const { - if (reg.regClass == IntRegClass) { - ccprintf(os, "r%d", reg.regIdx); + if (reg.isIntReg()) { + ccprintf(os, "r%d", reg.index()); } else { - ccprintf(os, "f%d", reg.regIdx); + ccprintf(os, "f%d", reg.index()); } } diff --git a/src/arch/arm/insts/misc.cc b/src/arch/arm/insts/misc.cc index 0114a4aba..059f86f63 100644 --- a/src/arch/arm/insts/misc.cc +++ b/src/arch/arm/insts/misc.cc @@ -51,16 +51,16 @@ MrsOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const ss << ", "; bool foundPsr = false; for (unsigned i = 0; i < numSrcRegs(); i++) { - RegId reg = srcRegIdx(i); - if (reg.regClass != MiscRegClass) { + const RegId& reg = srcRegIdx(i); + if (!reg.isMiscReg()) { continue; } - if (reg.regIdx == MISCREG_CPSR) { + if (reg.index() == MISCREG_CPSR) { ss << "cpsr"; foundPsr = true; break; } - if (reg.regIdx == MISCREG_SPSR) { + if (reg.index() == MISCREG_SPSR) { ss << "spsr"; foundPsr = true; break; @@ -79,16 +79,16 @@ MsrBase::printMsrBase(std::ostream &os) const bool apsr = false; bool foundPsr = false; for (unsigned i = 0; i < numDestRegs(); i++) { - RegId reg = destRegIdx(i); - if (reg.regClass != MiscRegClass) { + const RegId& reg = destRegIdx(i); + if (!reg.isMiscReg()) { continue; } - if (reg.regIdx == MISCREG_CPSR) { + if (reg.index() == MISCREG_CPSR) { os << "cpsr_"; foundPsr = true; break; } - if (reg.regIdx == MISCREG_SPSR) { + if (reg.index() == MISCREG_SPSR) { if (bits(byteMask, 1, 0)) { os << "spsr_"; } else { diff --git a/src/arch/arm/isa.hh b/src/arch/arm/isa.hh index e05f0e18a..8de90dc93 100644 --- a/src/arch/arm/isa.hh +++ b/src/arch/arm/isa.hh @@ -177,6 +177,22 @@ namespace ArmISA void setMiscRegNoEffect(int misc_reg, const MiscReg &val); void setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc); + RegId + flattenRegId(const RegId& regId) const + { + switch (regId.classValue()) { + case IntRegClass: + return RegId(IntRegClass, flattenIntIndex(regId.index())); + case FloatRegClass: + return RegId(FloatRegClass, flattenFloatIndex(regId.index())); + case CCRegClass: + return RegId(CCRegClass, flattenCCIndex(regId.index())); + case MiscRegClass: + return RegId(MiscRegClass, flattenMiscIndex(regId.index())); + } + return RegId(); + } + int flattenIntIndex(int reg) const { diff --git a/src/arch/arm/isa/insts/data64.isa b/src/arch/arm/isa/insts/data64.isa index d60dc60f1..48fc87ccb 100644 --- a/src/arch/arm/isa/insts/data64.isa +++ b/src/arch/arm/isa/insts/data64.isa @@ -328,7 +328,7 @@ let {{ buildDataXImmInst("mrs", ''' MiscRegIndex flat_idx = (MiscRegIndex) xc->tcBase()-> - flattenMiscIndex(op1); + flattenRegId(RegId(MiscRegClass, op1)).index(); CPSR cpsr = Cpsr; ExceptionLevel el = (ExceptionLevel) (uint8_t) cpsr.el; %s @@ -346,7 +346,7 @@ let {{ buildDataXImmInst("msr", ''' MiscRegIndex flat_idx = (MiscRegIndex) xc->tcBase()-> - flattenMiscIndex(dest); + flattenRegId(RegId(MiscRegClass, dest)).index(); CPSR cpsr = Cpsr; ExceptionLevel el = (ExceptionLevel) (uint8_t) cpsr.el; %s @@ -362,7 +362,8 @@ let {{ ''') msrdczva_ea_code = ''' - MiscRegIndex flat_idx = (MiscRegIndex) xc->tcBase()->flattenMiscIndex(dest); + MiscRegIndex flat_idx = (MiscRegIndex) xc->tcBase()->flattenRegId( + RegId(MiscRegClass, dest)).index(); CPSR cpsr = Cpsr; ExceptionLevel el = (ExceptionLevel) (uint8_t) cpsr.el; ''' @@ -391,7 +392,8 @@ let {{ buildDataXImmInst("msrSP", ''' if (!canWriteAArch64SysReg( - (MiscRegIndex) xc->tcBase()->flattenMiscIndex(dest), + (MiscRegIndex) xc->tcBase()->flattenRegId( + RegId(MiscRegClass, dest)).index(), Scr64, Cpsr, xc->tcBase())) { return std::make_shared<UndefinedInstruction>(machInst, false, mnemonic); @@ -401,7 +403,8 @@ let {{ buildDataXImmInst("msrDAIFSet", ''' if (!canWriteAArch64SysReg( - (MiscRegIndex) xc->tcBase()->flattenMiscIndex(dest), + (MiscRegIndex) xc->tcBase()->flattenRegId( + RegId(MiscRegClass, dest)).index(), Scr64, Cpsr, xc->tcBase())) { return std::make_shared<UndefinedInstruction>( machInst, 0, EC_TRAPPED_MSR_MRS_64, @@ -414,7 +417,8 @@ let {{ buildDataXImmInst("msrDAIFClr", ''' if (!canWriteAArch64SysReg( - (MiscRegIndex) xc->tcBase()->flattenMiscIndex(dest), + (MiscRegIndex) xc->tcBase()->flattenRegId( + RegId(MiscRegClass, dest)).index(), Scr64, Cpsr, xc->tcBase())) { return std::make_shared<UndefinedInstruction>( machInst, 0, EC_TRAPPED_MSR_MRS_64, diff --git a/src/arch/arm/isa/insts/fp.isa b/src/arch/arm/isa/insts/fp.isa index dc2f30701..dff906755 100644 --- a/src/arch/arm/isa/insts/fp.isa +++ b/src/arch/arm/isa/insts/fp.isa @@ -224,7 +224,7 @@ let {{ if (!inSecureState(scr, cpsr) && (cpsr.mode != MODE_HYP)) { HCR hcr = Hcr; bool hypTrap = false; - switch(xc->tcBase()->flattenMiscIndex(op1)) { + switch(xc->tcBase()->flattenRegId(RegId(MiscRegClass, op1)).index()) { case MISCREG_FPSID: hypTrap = hcr.tid0; break; diff --git a/src/arch/arm/isa/insts/misc.isa b/src/arch/arm/isa/insts/misc.isa index 6d6e56b8f..5eda615b5 100644 --- a/src/arch/arm/isa/insts/misc.isa +++ b/src/arch/arm/isa/insts/misc.isa @@ -813,7 +813,8 @@ let {{ exec_output += PredOpExecute.subst(bfiIop) mrc14code = ''' - MiscRegIndex miscReg = (MiscRegIndex) xc->tcBase()->flattenMiscIndex(op1); + MiscRegIndex miscReg = (MiscRegIndex) xc->tcBase()->flattenRegId( + RegId(MiscRegClass, op1)).index(); bool can_read, undefined; std::tie(can_read, undefined) = canReadCoprocReg(miscReg, Scr, Cpsr); if (!can_read || undefined) { @@ -837,7 +838,8 @@ let {{ mcr14code = ''' - MiscRegIndex miscReg = (MiscRegIndex) xc->tcBase()->flattenMiscIndex(dest); + MiscRegIndex miscReg = (MiscRegIndex) xc->tcBase()->flattenRegId( + RegId(MiscRegClass, dest)).index(); bool can_write, undefined; std::tie(can_write, undefined) = canWriteCoprocReg(miscReg, Scr, Cpsr); if (undefined || !can_write) { @@ -862,7 +864,8 @@ let {{ mrc15code = ''' int preFlatOp1 = flattenMiscRegNsBanked(op1, xc->tcBase()); MiscRegIndex miscReg = (MiscRegIndex) - xc->tcBase()->flattenMiscIndex(preFlatOp1); + xc->tcBase()->flattenRegId(RegId(MiscRegClass, + preFlatOp1)).index(); bool hypTrap = mcrMrc15TrapToHyp(miscReg, Hcr, Cpsr, Scr, Hdcr, Hstr, Hcptr, imm); bool can_read, undefined; @@ -893,7 +896,8 @@ let {{ mcr15code = ''' int preFlatDest = flattenMiscRegNsBanked(dest, xc->tcBase()); MiscRegIndex miscReg = (MiscRegIndex) - xc->tcBase()->flattenMiscIndex(preFlatDest); + xc->tcBase()->flattenRegId(RegId(MiscRegClass, + preFlatDest)).index(); bool hypTrap = mcrMrc15TrapToHyp(miscReg, Hcr, Cpsr, Scr, Hdcr, Hstr, Hcptr, imm); bool can_write, undefined; @@ -925,7 +929,8 @@ let {{ mrrc15code = ''' int preFlatOp1 = flattenMiscRegNsBanked(op1, xc->tcBase()); MiscRegIndex miscReg = (MiscRegIndex) - xc->tcBase()->flattenMiscIndex(preFlatOp1); + xc->tcBase()->flattenRegId(RegId(MiscRegClass, + preFlatOp1)).index(); bool hypTrap = mcrrMrrc15TrapToHyp(miscReg, Cpsr, Scr, Hstr, Hcr, imm); bool can_read, undefined; std::tie(can_read, undefined) = canReadCoprocReg(miscReg, Scr, Cpsr); @@ -955,7 +960,8 @@ let {{ mcrr15code = ''' int preFlatDest = flattenMiscRegNsBanked(dest, xc->tcBase()); MiscRegIndex miscReg = (MiscRegIndex) - xc->tcBase()->flattenMiscIndex(preFlatDest); + xc->tcBase()->flattenRegId(RegId(MiscRegClass, + preFlatDest)).index(); bool hypTrap = mcrrMrrc15TrapToHyp(miscReg, Cpsr, Scr, Hstr, Hcr, imm); bool can_write, undefined; std::tie(can_write, undefined) = canWriteCoprocReg(miscReg, Scr, Cpsr); diff --git a/src/arch/mips/isa.hh b/src/arch/mips/isa.hh index feb55e473..c751cb168 100644 --- a/src/arch/mips/isa.hh +++ b/src/arch/mips/isa.hh @@ -37,6 +37,7 @@ #include "arch/mips/registers.hh" #include "arch/mips/types.hh" +#include "cpu/reg_class.hh" #include "sim/eventq.hh" #include "sim/sim_object.hh" @@ -165,6 +166,8 @@ namespace MipsISA ISA(Params *p); + RegId flattenRegId(const RegId& regId) const { return regId; } + int flattenIntIndex(int reg) const { diff --git a/src/arch/mips/isa/base.isa b/src/arch/mips/isa/base.isa index c0f259666..946dce6df 100644 --- a/src/arch/mips/isa/base.isa +++ b/src/arch/mips/isa/base.isa @@ -72,11 +72,11 @@ output decoder {{ void MipsStaticInst::printReg(std::ostream &os, RegId reg) const { - if (reg.regClass == IntRegClass) { - ccprintf(os, "r%d", reg.regIdx); + if (reg.isIntReg()) { + ccprintf(os, "r%d", reg.index()); } else { - ccprintf(os, "f%d", reg.regIdx); + ccprintf(os, "f%d", reg.index()); } } diff --git a/src/arch/mips/isa/formats/int.isa b/src/arch/mips/isa/formats/int.isa index 641608e89..c21c1255b 100644 --- a/src/arch/mips/isa/formats/int.isa +++ b/src/arch/mips/isa/formats/int.isa @@ -257,9 +257,9 @@ output decoder {{ ccprintf(ss, "%-10s ", mnemonic); - if (_numDestRegs > 0 && _destRegIdx[0].regIdx < 32) { + if (_numDestRegs > 0 && _destRegIdx[0].index() < 32) { printReg(ss, _destRegIdx[0]); - } else if (_numSrcRegs > 0 && _srcRegIdx[0].regIdx < 32) { + } else if (_numSrcRegs > 0 && _srcRegIdx[0].index() < 32) { printReg(ss, _srcRegIdx[0]); } @@ -272,9 +272,9 @@ output decoder {{ ccprintf(ss, "%-10s ", mnemonic); - if (_numDestRegs > 0 && _destRegIdx[0].regIdx < 32) { + if (_numDestRegs > 0 && _destRegIdx[0].index() < 32) { printReg(ss, _destRegIdx[0]); - } else if (_numSrcRegs > 0 && _srcRegIdx[0].regIdx < 32) { + } else if (_numSrcRegs > 0 && _srcRegIdx[0].index() < 32) { printReg(ss, _srcRegIdx[0]); } @@ -287,9 +287,9 @@ output decoder {{ ccprintf(ss, "%-10s ", mnemonic); - if (_numDestRegs > 0 && _destRegIdx[0].regIdx < 32) { + if (_numDestRegs > 0 && _destRegIdx[0].index() < 32) { printReg(ss, _destRegIdx[0]); - } else if (_numSrcRegs > 0 && _srcRegIdx[0].regIdx < 32) { + } else if (_numSrcRegs > 0 && _srcRegIdx[0].index() < 32) { printReg(ss, _srcRegIdx[0]); } diff --git a/src/arch/power/insts/branch.cc b/src/arch/power/insts/branch.cc index f10e8453a..d13a0a7d3 100644 --- a/src/arch/power/insts/branch.cc +++ b/src/arch/power/insts/branch.cc @@ -153,7 +153,7 @@ BranchNonPCRelCond::generateDisassembly(Addr pc, PowerISA::PCState BranchRegCond::branchTarget(ThreadContext *tc) const { - uint32_t regVal = tc->readIntReg(_srcRegIdx[_numSrcRegs - 1].regIdx); + uint32_t regVal = tc->readIntReg(_srcRegIdx[_numSrcRegs - 1].index()); return regVal & 0xfffffffc; } diff --git a/src/arch/power/insts/static_inst.cc b/src/arch/power/insts/static_inst.cc index 210205db2..85f9cf628 100644 --- a/src/arch/power/insts/static_inst.cc +++ b/src/arch/power/insts/static_inst.cc @@ -38,15 +38,12 @@ using namespace PowerISA; void PowerStaticInst::printReg(std::ostream &os, RegId reg) const { - switch (reg.regClass) { - case IntRegClass: - ccprintf(os, "r%d", reg.regIdx); - break; - case FloatRegClass: - ccprintf(os, "f%d", reg.regIdx); - break; - case MiscRegClass: - switch (reg.regIdx) { + if (reg.isIntReg()) + ccprintf(os, "r%d", reg.index()); + else if (reg.isFloatReg()) + ccprintf(os, "f%d", reg.index()); + else if (reg.isMiscReg()) + switch (reg.index()) { case 0: ccprintf(os, "cr"); break; case 1: ccprintf(os, "xer"); break; case 2: ccprintf(os, "lr"); break; @@ -54,9 +51,8 @@ PowerStaticInst::printReg(std::ostream &os, RegId reg) const default: ccprintf(os, "unknown_reg"); break; } - case CCRegClass: + else if (reg.isCCReg()) panic("printReg: POWER does not implement CCRegClass\n"); - } } std::string diff --git a/src/arch/power/isa.hh b/src/arch/power/isa.hh index aaf5bd92a..475b4d2f8 100644 --- a/src/arch/power/isa.hh +++ b/src/arch/power/isa.hh @@ -36,6 +36,7 @@ #include "arch/power/registers.hh" #include "arch/power/types.hh" #include "base/misc.hh" +#include "cpu/reg_class.hh" #include "sim/sim_object.hh" struct PowerISAParams; @@ -86,6 +87,8 @@ class ISA : public SimObject fatal("Power does not currently have any misc regs defined\n"); } + RegId flattenRegId(const RegId& regId) const { return regId; } + int flattenIntIndex(int reg) const { diff --git a/src/arch/riscv/isa.hh b/src/arch/riscv/isa.hh index d2f38b158..3f2412303 100644 --- a/src/arch/riscv/isa.hh +++ b/src/arch/riscv/isa.hh @@ -44,6 +44,7 @@ #include "arch/riscv/registers.hh" #include "arch/riscv/types.hh" #include "base/misc.hh" +#include "cpu/reg_class.hh" #include "sim/sim_object.hh" struct RiscvISAParams; @@ -78,6 +79,12 @@ class ISA : public SimObject void setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc); + RegId + flattenRegId(const RegId ®Id) const + { + return regId; + } + int flattenIntIndex(int reg) const { diff --git a/src/arch/riscv/isa/base.isa b/src/arch/riscv/isa/base.isa index dafccc981..a7e2fc954 100644 --- a/src/arch/riscv/isa/base.isa +++ b/src/arch/riscv/isa/base.isa @@ -70,13 +70,12 @@ output decoder {{ std::string RiscvStaticInst::regName(RegId reg) const { - switch (reg.regClass) { - case IntRegClass: - return std::string(RegisterNames[reg.regIdx]); - case FloatRegClass: - return std::string("f") + std::to_string(reg.regIdx); - default: - return csprintf("unknown[%i/%i]", reg.regClass, reg.regIdx); + if (reg.isIntReg()) { + return std::string(RegisterNames[reg.index()]); + } else if (reg.isFloatReg()) { + return std::string("f") + std::to_string(reg.index()); + } else { + return csprintf("%s{%i}", reg.className(), reg.index()); } } }}; diff --git a/src/arch/riscv/isa/formats/type.isa b/src/arch/riscv/isa/formats/type.isa index 0f2ffe9c4..f6a563699 100644 --- a/src/arch/riscv/isa/formats/type.isa +++ b/src/arch/riscv/isa/formats/type.isa @@ -210,7 +210,7 @@ output decoder {{ Jump::branchTarget(ThreadContext *tc) const { PCState pc = tc->pcState(); - IntReg Rs1 = tc->readIntReg(_srcRegIdx[0].regIdx); + IntReg Rs1 = tc->readIntReg(_srcRegIdx[0].index()); pc.set((Rs1 + imm)&~0x1); return pc; } diff --git a/src/arch/sparc/isa.hh b/src/arch/sparc/isa.hh index 18ac30857..ded5b34ff 100644 --- a/src/arch/sparc/isa.hh +++ b/src/arch/sparc/isa.hh @@ -37,6 +37,7 @@ #include "arch/sparc/registers.hh" #include "arch/sparc/types.hh" #include "cpu/cpuevent.hh" +#include "cpu/reg_class.hh" #include "sim/sim_object.hh" class Checkpoint; @@ -189,6 +190,22 @@ class ISA : public SimObject void setMiscReg(int miscReg, const MiscReg val, ThreadContext *tc); + RegId + flattenRegId(const RegId& regId) const + { + switch (regId.classValue()) { + case IntRegClass: + return RegId(IntRegClass, flattenIntIndex(regId.index())); + case FloatRegClass: + return RegId(FloatRegClass, flattenFloatIndex(regId.index())); + case CCRegClass: + return RegId(CCRegClass, flattenCCIndex(regId.index())); + case MiscRegClass: + return RegId(MiscRegClass, flattenMiscIndex(regId.index())); + } + return regId; + } + int flattenIntIndex(int reg) const { diff --git a/src/arch/sparc/isa/base.isa b/src/arch/sparc/isa/base.isa index 4a4293e50..b517d462c 100644 --- a/src/arch/sparc/isa/base.isa +++ b/src/arch/sparc/isa/base.isa @@ -290,8 +290,8 @@ output decoder {{ const int MaxLocal = 24; const int MaxInput = 32; const int MaxMicroReg = 40; - RegIndex reg_idx = reg.regIdx; - if (reg.regClass == IntRegClass) { + RegIndex reg_idx = reg.index(); + if (reg.isIntReg()) { // If we used a register from the next or previous window, // take out the offset. while (reg_idx >= MaxMicroReg) @@ -336,7 +336,7 @@ output decoder {{ break; } } - } else if (reg.regClass == FloatRegClass) { + } else if (reg.isFloatReg()) { ccprintf(os, "%%f%d", reg_idx); } else { switch (reg_idx) { diff --git a/src/arch/sparc/isa/formats/integerop.isa b/src/arch/sparc/isa/formats/integerop.isa index 585dfcced..e60c93cd2 100644 --- a/src/arch/sparc/isa/formats/integerop.isa +++ b/src/arch/sparc/isa/formats/integerop.isa @@ -155,7 +155,7 @@ output decoder {{ IntOp::printPseudoOps(std::ostream &os, Addr pc, const SymbolTable *symbab) const { - if (!std::strcmp(mnemonic, "or") && _srcRegIdx[0].regIdx == 0) { + if (!std::strcmp(mnemonic, "or") && _srcRegIdx[0].index() == 0) { printMnemonic(os, "mov"); printSrcReg(os, 1); ccprintf(os, ", "); @@ -170,7 +170,7 @@ output decoder {{ const SymbolTable *symbab) const { if (!std::strcmp(mnemonic, "or")) { - if (_numSrcRegs > 0 && _srcRegIdx[0].regIdx == 0) { + if (_numSrcRegs > 0 && _srcRegIdx[0].index() == 0) { if (imm == 0) { printMnemonic(os, "clr"); } else { diff --git a/src/arch/sparc/isa/formats/mem/util.isa b/src/arch/sparc/isa/formats/mem/util.isa index 9b3132e40..00e09ce54 100644 --- a/src/arch/sparc/isa/formats/mem/util.isa +++ b/src/arch/sparc/isa/formats/mem/util.isa @@ -84,7 +84,7 @@ output decoder {{ ccprintf(response, ", "); } ccprintf(response, "["); - if (_srcRegIdx[!store ? 0 : 1].regIdx != 0) { + if (_srcRegIdx[!store ? 0 : 1].index() != 0) { printSrcReg(response, !store ? 0 : 1); ccprintf(response, " + "); } @@ -111,7 +111,7 @@ output decoder {{ ccprintf(response, ", "); } ccprintf(response, "["); - if (_srcRegIdx[!save ? 0 : 1].regIdx != 0) { + if (_srcRegIdx[!save ? 0 : 1].index() != 0) { printReg(response, _srcRegIdx[!save ? 0 : 1]); ccprintf(response, " + "); } diff --git a/src/arch/sparc/isa/formats/priv.isa b/src/arch/sparc/isa/formats/priv.isa index f5e1a0826..3f6d35330 100644 --- a/src/arch/sparc/isa/formats/priv.isa +++ b/src/arch/sparc/isa/formats/priv.isa @@ -155,7 +155,7 @@ output decoder {{ ccprintf(response, " "); // If the first reg is %g0, don't print it. // This improves readability - if (_srcRegIdx[0].regIdx != 0) { + if (_srcRegIdx[0].index() != 0) { printSrcReg(response, 0); ccprintf(response, ", "); } @@ -175,7 +175,7 @@ output decoder {{ ccprintf(response, " "); // If the first reg is %g0, don't print it. // This improves readability - if (_srcRegIdx[0].regIdx != 0) { + if (_srcRegIdx[0].index() != 0) { printSrcReg(response, 0); ccprintf(response, ", "); } diff --git a/src/arch/x86/insts/microfpop.hh b/src/arch/x86/insts/microfpop.hh index 04ec285d4..d326b5dfc 100644 --- a/src/arch/x86/insts/microfpop.hh +++ b/src/arch/x86/insts/microfpop.hh @@ -66,7 +66,7 @@ namespace X86ISA OpClass __opClass) : X86MicroopBase(_machInst, mnem, _instMnem, setFlags, __opClass), - src1(_src1.regIdx), src2(_src2.regIdx), dest(_dest.regIdx), + src1(_src1.index()), src2(_src2.index()), dest(_dest.index()), dataSize(_dataSize), spm(_spm) {} /* diff --git a/src/arch/x86/insts/microldstop.hh b/src/arch/x86/insts/microldstop.hh index e12a51c4c..1d328d1a1 100644 --- a/src/arch/x86/insts/microldstop.hh +++ b/src/arch/x86/insts/microldstop.hh @@ -75,12 +75,12 @@ namespace X86ISA Request::FlagsType _memFlags, OpClass __opClass) : X86MicroopBase(_machInst, mnem, _instMnem, setFlags, __opClass), - scale(_scale), index(_index.regIdx), base(_base.regIdx), - disp(_disp), segment(_segment.regIdx), + scale(_scale), index(_index.index()), base(_base.index()), + disp(_disp), segment(_segment.index()), dataSize(_dataSize), addressSize(_addressSize), - memFlags(_memFlags | _segment.regIdx) + memFlags(_memFlags | _segment.index()) { - assert(_segment.regIdx < NUM_SEGMENTREGS); + assert(_segment.index() < NUM_SEGMENTREGS); foldOBit = (dataSize == 1 && !_machInst.rex.present) ? 1 << 6 : 0; foldABit = @@ -110,7 +110,7 @@ namespace X86ISA _scale, _index, _base, _disp, _segment, _dataSize, _addressSize, _memFlags, __opClass), - data(_data.regIdx) + data(_data.index()) { } @@ -143,8 +143,8 @@ namespace X86ISA _scale, _index, _base, _disp, _segment, _dataSize, _addressSize, _memFlags, __opClass), - dataLow(_dataLow.regIdx), - dataHi(_dataHi.regIdx) + dataLow(_dataLow.index()), + dataHi(_dataHi.index()) { } diff --git a/src/arch/x86/insts/micromediaop.hh b/src/arch/x86/insts/micromediaop.hh index 547780108..5cb0bdbb0 100644 --- a/src/arch/x86/insts/micromediaop.hh +++ b/src/arch/x86/insts/micromediaop.hh @@ -59,7 +59,7 @@ namespace X86ISA OpClass __opClass) : X86MicroopBase(_machInst, mnem, _instMnem, setFlags, __opClass), - src1(_src1.regIdx), dest(_dest.regIdx), + src1(_src1.index()), dest(_dest.index()), srcSize(_srcSize), destSize(_destSize), ext(_ext) {} @@ -102,7 +102,7 @@ namespace X86ISA MediaOpBase(_machInst, mnem, _instMnem, setFlags, _src1, _dest, _srcSize, _destSize, _ext, __opClass), - src2(_src2.regIdx) + src2(_src2.index()) {} std::string generateDisassembly(Addr pc, diff --git a/src/arch/x86/insts/microregop.hh b/src/arch/x86/insts/microregop.hh index 1accc3555..9838b7cc1 100644 --- a/src/arch/x86/insts/microregop.hh +++ b/src/arch/x86/insts/microregop.hh @@ -64,7 +64,7 @@ namespace X86ISA OpClass __opClass) : X86MicroopBase(_machInst, mnem, _instMnem, setFlags, __opClass), - src1(_src1.regIdx), dest(_dest.regIdx), + src1(_src1.index()), dest(_dest.index()), dataSize(_dataSize), ext(_ext) { foldOBit = (dataSize == 1 && !_machInst.rex.present) ? 1 << 6 : 0; @@ -90,7 +90,7 @@ namespace X86ISA RegOpBase(_machInst, mnem, _instMnem, setFlags, _src1, _dest, _dataSize, _ext, __opClass), - src2(_src2.regIdx) + src2(_src2.index()) { } diff --git a/src/arch/x86/insts/static_inst.cc b/src/arch/x86/insts/static_inst.cc index b9c5486ed..28c268d4e 100644 --- a/src/arch/x86/insts/static_inst.cc +++ b/src/arch/x86/insts/static_inst.cc @@ -132,10 +132,9 @@ namespace X86ISA static const char * microFormats[9] = {"", "t%db", "t%dw", "", "t%dd", "", "", "", "t%d"}; - RegIndex reg_idx = reg.regIdx; + RegIndex reg_idx = reg.index(); - switch (reg.regClass) { - case IntRegClass: { + if (reg.isIntReg()) { const char * suffix = ""; bool fold = reg_idx & IntFoldBit; reg_idx &= ~IntFoldBit; @@ -198,10 +197,8 @@ namespace X86ISA ccprintf(os, microFormats[size], reg_idx - NUM_INTREGS); } ccprintf(os, suffix); - break; - } - case FloatRegClass: { + } else if (reg.isFloatReg()) { if (reg_idx < NumMMXRegs) { ccprintf(os, "%%mmx%d", reg_idx); return; @@ -219,19 +216,15 @@ namespace X86ISA } reg_idx -= NumMicroFpRegs; ccprintf(os, "%%st(%d)", reg_idx); - break; - } - case CCRegClass: + } else if (reg.isCCReg()) { ccprintf(os, "%%cc%d", reg_idx); - break; - case MiscRegClass: + } else if (reg.isMiscReg()) { switch (reg_idx) { default: ccprintf(os, "%%ctrl%d", reg_idx); } - break; } } diff --git a/src/arch/x86/insts/static_inst.hh b/src/arch/x86/insts/static_inst.hh index 0cea0e132..8dac3ec0f 100644 --- a/src/arch/x86/insts/static_inst.hh +++ b/src/arch/x86/insts/static_inst.hh @@ -107,7 +107,7 @@ namespace X86ISA inline uint64_t merge(uint64_t into, uint64_t val, int size) const { X86IntReg reg = into; - if (_destRegIdx[0].regIdx & IntFoldBit) + if (_destRegIdx[0].index() & IntFoldBit) { reg.H = val; return reg; @@ -138,7 +138,7 @@ namespace X86ISA { X86IntReg reg = from; DPRINTF(X86, "Picking with size %d\n", size); - if (_srcRegIdx[idx].regIdx & IntFoldBit) + if (_srcRegIdx[idx].index() & IntFoldBit) return reg.H; switch(size) { @@ -159,7 +159,7 @@ namespace X86ISA { X86IntReg reg = from; DPRINTF(X86, "Picking with size %d\n", size); - if (_srcRegIdx[idx].regIdx & IntFoldBit) + if (_srcRegIdx[idx].index() & IntFoldBit) return reg.SH; switch(size) { diff --git a/src/arch/x86/isa.hh b/src/arch/x86/isa.hh index 90ab619cc..099d27c7c 100644 --- a/src/arch/x86/isa.hh +++ b/src/arch/x86/isa.hh @@ -38,6 +38,7 @@ #include "arch/x86/regs/misc.hh" #include "arch/x86/registers.hh" #include "base/types.hh" +#include "cpu/reg_class.hh" #include "sim/sim_object.hh" class Checkpoint; @@ -69,6 +70,22 @@ namespace X86ISA void setMiscRegNoEffect(int miscReg, MiscReg val); void setMiscReg(int miscReg, MiscReg val, ThreadContext *tc); + RegId + flattenRegId(const RegId& regId) const + { + switch (regId.classValue()) { + case IntRegClass: + return RegId(IntRegClass, flattenIntIndex(regId.index())); + case FloatRegClass: + return RegId(FloatRegClass, flattenFloatIndex(regId.index())); + case CCRegClass: + return RegId(CCRegClass, flattenCCIndex(regId.index())); + case MiscRegClass: + return RegId(MiscRegClass, flattenMiscIndex(regId.index())); + } + return regId; + } + int flattenIntIndex(int reg) const { diff --git a/src/arch/x86/isa/microops/limmop.isa b/src/arch/x86/isa/microops/limmop.isa index 8a832f5d5..c002a1684 100644 --- a/src/arch/x86/isa/microops/limmop.isa +++ b/src/arch/x86/isa/microops/limmop.isa @@ -95,7 +95,7 @@ def template MicroLimmOpConstructor {{ InstRegIndex _dest, uint64_t _imm, uint8_t _dataSize) : %(base_class)s(machInst, "%(mnemonic)s", instMnem, setFlags, %(op_class)s), - dest(_dest.regIdx), imm(_imm), dataSize(_dataSize) + dest(_dest.index()), imm(_imm), dataSize(_dataSize) { foldOBit = (dataSize == 1 && !machInst.rex.present) ? 1 << 6 : 0; %(constructor)s; diff --git a/src/cpu/base_dyn_inst.hh b/src/cpu/base_dyn_inst.hh index 369d7a02a..9c6952310 100644 --- a/src/cpu/base_dyn_inst.hh +++ b/src/cpu/base_dyn_inst.hh @@ -383,7 +383,7 @@ class BaseDynInst : public ExecContext, public RefCounted /** Returns the flattened register index of the i'th destination * register. */ - RegId flattenedDestRegIdx(int idx) const + const RegId& flattenedDestRegIdx(int idx) const { return _flatDestRegIdx[idx]; } @@ -419,7 +419,7 @@ class BaseDynInst : public ExecContext, public RefCounted /** Flattens a destination architectural register index into a logical * index. */ - void flattenDestReg(int idx, RegId flattened_dest) + void flattenDestReg(int idx, const RegId& flattened_dest) { _flatDestRegIdx[idx] = flattened_dest; } @@ -601,10 +601,10 @@ class BaseDynInst : public ExecContext, public RefCounted int8_t numCCDestRegs() const { return staticInst->numCCDestRegs(); } /** Returns the logical register index of the i'th destination register. */ - RegId destRegIdx(int i) const { return staticInst->destRegIdx(i); } + const RegId& destRegIdx(int i) const { return staticInst->destRegIdx(i); } /** Returns the logical register index of the i'th source register. */ - RegId srcRegIdx(int i) const { return staticInst->srcRegIdx(i); } + const RegId& srcRegIdx(int i) const { return staticInst->srcRegIdx(i); } /** Pops a result off the instResult queue */ template <class T> diff --git a/src/cpu/checker/cpu.hh b/src/cpu/checker/cpu.hh index 3afbc31fb..304caaa85 100644 --- a/src/cpu/checker/cpu.hh +++ b/src/cpu/checker/cpu.hh @@ -213,31 +213,31 @@ class CheckerCPU : public BaseCPU, public ExecContext IntReg readIntRegOperand(const StaticInst *si, int idx) override { - RegId reg = si->srcRegIdx(idx); - assert(reg.regClass == IntRegClass); - return thread->readIntReg(reg.regIdx); + const RegId& reg = si->srcRegIdx(idx); + assert(reg.isIntReg()); + return thread->readIntReg(reg.index()); } FloatReg readFloatRegOperand(const StaticInst *si, int idx) override { - RegId reg = si->srcRegIdx(idx); - assert(reg.regClass == FloatRegClass); - return thread->readFloatReg(reg.regIdx); + const RegId& reg = si->srcRegIdx(idx); + assert(reg.isFloatReg()); + return thread->readFloatReg(reg.index()); } FloatRegBits readFloatRegOperandBits(const StaticInst *si, int idx) override { - RegId reg = si->srcRegIdx(idx); - assert(reg.regClass == FloatRegClass); - return thread->readFloatRegBits(reg.regIdx); + const RegId& reg = si->srcRegIdx(idx); + assert(reg.isFloatReg()); + return thread->readFloatRegBits(reg.index()); } CCReg readCCRegOperand(const StaticInst *si, int idx) override { - RegId reg = si->srcRegIdx(idx); - assert(reg.regClass == CCRegClass); - return thread->readCCReg(reg.regIdx); + const RegId& reg = si->srcRegIdx(idx); + assert(reg.isCCReg()); + return thread->readCCReg(reg.index()); } template <class T> @@ -251,35 +251,35 @@ class CheckerCPU : public BaseCPU, public ExecContext void setIntRegOperand(const StaticInst *si, int idx, IntReg val) override { - RegId reg = si->destRegIdx(idx); - assert(reg.regClass == IntRegClass); - thread->setIntReg(reg.regIdx, val); + const RegId& reg = si->destRegIdx(idx); + assert(reg.isIntReg()); + thread->setIntReg(reg.index(), val); setResult<uint64_t>(val); } void setFloatRegOperand(const StaticInst *si, int idx, FloatReg val) override { - RegId reg = si->destRegIdx(idx); - assert(reg.regClass == FloatRegClass); - thread->setFloatReg(reg.regIdx, val); + const RegId& reg = si->destRegIdx(idx); + assert(reg.isFloatReg()); + thread->setFloatReg(reg.index(), val); setResult<double>(val); } void setFloatRegOperandBits(const StaticInst *si, int idx, FloatRegBits val) override { - RegId reg = si->destRegIdx(idx); - assert(reg.regClass == FloatRegClass); - thread->setFloatRegBits(reg.regIdx, val); + const RegId& reg = si->destRegIdx(idx); + assert(reg.isFloatReg()); + thread->setFloatRegBits(reg.index(), val); setResult<uint64_t>(val); } void setCCRegOperand(const StaticInst *si, int idx, CCReg val) override { - RegId reg = si->destRegIdx(idx); - assert(reg.regClass == CCRegClass); - thread->setCCReg(reg.regIdx, val); + const RegId& reg = si->destRegIdx(idx); + assert(reg.isCCReg()); + thread->setCCReg(reg.index(), val); setResult<uint64_t>(val); } @@ -327,27 +327,28 @@ class CheckerCPU : public BaseCPU, public ExecContext MiscReg readMiscRegOperand(const StaticInst *si, int idx) override { - RegId reg = si->srcRegIdx(idx); - assert(reg.regClass == MiscRegClass); - return thread->readMiscReg(reg.regIdx); + const RegId& reg = si->srcRegIdx(idx); + assert(reg.isMiscReg()); + return thread->readMiscReg(reg.index()); } void setMiscRegOperand(const StaticInst *si, int idx, const MiscReg &val) override { - RegId reg = si->destRegIdx(idx); - assert(reg.regClass == MiscRegClass); - return this->setMiscReg(reg.regIdx, val); + const RegId& reg = si->destRegIdx(idx); + assert(reg.isMiscReg()); + return this->setMiscReg(reg.index(), val); } #if THE_ISA == MIPS_ISA - MiscReg readRegOtherThread(RegId misc_reg, ThreadID tid) override + MiscReg readRegOtherThread(const RegId& misc_reg, ThreadID tid) override { panic("MIPS MT not defined for CheckerCPU.\n"); return 0; } - void setRegOtherThread(RegId misc_reg, MiscReg val, ThreadID tid) override + void setRegOtherThread(const RegId& misc_reg, MiscReg val, + ThreadID tid) override { panic("MIPS MT not defined for CheckerCPU.\n"); } diff --git a/src/cpu/checker/cpu_impl.hh b/src/cpu/checker/cpu_impl.hh index 47a088aa6..0c90590c7 100644 --- a/src/cpu/checker/cpu_impl.hh +++ b/src/cpu/checker/cpu_impl.hh @@ -595,40 +595,40 @@ Checker<Impl>::copyResult(DynInstPtr &inst, uint64_t mismatch_val, // We've already popped one dest off the queue, // so do the fix-up then start with the next dest reg; if (start_idx >= 0) { - RegId idx = inst->destRegIdx(start_idx); - switch (idx.regClass) { + const RegId& idx = inst->destRegIdx(start_idx); + switch (idx.classValue()) { case IntRegClass: - thread->setIntReg(idx.regIdx, mismatch_val); + thread->setIntReg(idx.index(), mismatch_val); break; case FloatRegClass: - thread->setFloatRegBits(idx.regIdx, mismatch_val); + thread->setFloatRegBits(idx.index(), mismatch_val); break; case CCRegClass: - thread->setCCReg(idx.regIdx, mismatch_val); + thread->setCCReg(idx.index(), mismatch_val); break; case MiscRegClass: - thread->setMiscReg(idx.regIdx, mismatch_val); + thread->setMiscReg(idx.index(), mismatch_val); break; } } start_idx++; uint64_t res = 0; for (int i = start_idx; i < inst->numDestRegs(); i++) { - RegId idx = inst->destRegIdx(i); + const RegId& idx = inst->destRegIdx(i); inst->template popResult<uint64_t>(res); - switch (idx.regClass) { + switch (idx.classValue()) { case IntRegClass: - thread->setIntReg(idx.regIdx, res); + thread->setIntReg(idx.index(), res); break; case FloatRegClass: - thread->setFloatRegBits(idx.regIdx, res); + thread->setFloatRegBits(idx.index(), res); break; case CCRegClass: - thread->setCCReg(idx.regIdx, res); + thread->setCCReg(idx.index(), res); break; case MiscRegClass: // Try to get the proper misc register index for ARM here... - thread->setMiscReg(idx.regIdx, res); + thread->setMiscReg(idx.index(), res); break; // else Register is out of range... } diff --git a/src/cpu/checker/thread_context.hh b/src/cpu/checker/thread_context.hh index 7b09dde90..e48f5936b 100644 --- a/src/cpu/checker/thread_context.hh +++ b/src/cpu/checker/thread_context.hh @@ -301,10 +301,9 @@ class CheckerThreadContext : public ThreadContext actualTC->setMiscReg(misc_reg, val); } - int flattenIntIndex(int reg) { return actualTC->flattenIntIndex(reg); } - int flattenFloatIndex(int reg) { return actualTC->flattenFloatIndex(reg); } - int flattenCCIndex(int reg) { return actualTC->flattenCCIndex(reg); } - int flattenMiscIndex(int reg) { return actualTC->flattenMiscIndex(reg); } + RegId flattenRegId(const RegId& regId) const { + return actualTC->flattenRegId(regId); + } unsigned readStCondFailures() { return actualTC->readStCondFailures(); } diff --git a/src/cpu/exec_context.hh b/src/cpu/exec_context.hh index 1b6084e27..d33147240 100644 --- a/src/cpu/exec_context.hh +++ b/src/cpu/exec_context.hh @@ -287,9 +287,9 @@ class ExecContext { */ #if THE_ISA == MIPS_ISA - virtual MiscReg readRegOtherThread(RegId reg, + virtual MiscReg readRegOtherThread(const RegId& reg, ThreadID tid = InvalidThreadID) = 0; - virtual void setRegOtherThread(RegId reg, MiscReg val, + virtual void setRegOtherThread(const RegId& reg, MiscReg val, ThreadID tid = InvalidThreadID) = 0; #endif diff --git a/src/cpu/minor/dyn_inst.cc b/src/cpu/minor/dyn_inst.cc index 42c370a70..1ed598833 100644 --- a/src/cpu/minor/dyn_inst.cc +++ b/src/cpu/minor/dyn_inst.cc @@ -133,15 +133,13 @@ operator <<(std::ostream &os, const MinorDynInst &inst) /** Print a register in the form r<n>, f<n>, m<n>(<name>), z for integer, * float, misc and zero registers given an 'architectural register number' */ static void -printRegName(std::ostream &os, RegId reg) +printRegName(std::ostream &os, const RegId& reg) { - RegClass reg_class = reg.regClass; - - switch (reg_class) + switch (reg.classValue()) { case MiscRegClass: { - RegIndex misc_reg = reg.regIdx; + RegIndex misc_reg = reg.index(); /* This is an ugly test because not all archs. have miscRegName */ #if THE_ISA == ARM_ISA @@ -153,17 +151,17 @@ printRegName(std::ostream &os, RegId reg) } break; case FloatRegClass: - os << 'f' << static_cast<unsigned int>(reg.regIdx); + os << 'f' << static_cast<unsigned int>(reg.index()); break; case IntRegClass: if (reg.isZeroReg()) { os << 'z'; } else { - os << 'r' << static_cast<unsigned int>(reg.regIdx); + os << 'r' << static_cast<unsigned int>(reg.index()); } break; case CCRegClass: - os << 'c' << static_cast<unsigned int>(reg.regIdx); + os << 'c' << static_cast<unsigned int>(reg.index()); } } diff --git a/src/cpu/minor/exec_context.hh b/src/cpu/minor/exec_context.hh index d517d5abb..e91b7a6dd 100644 --- a/src/cpu/minor/exec_context.hh +++ b/src/cpu/minor/exec_context.hh @@ -124,51 +124,51 @@ class ExecContext : public ::ExecContext IntReg readIntRegOperand(const StaticInst *si, int idx) override { - RegId reg = si->srcRegIdx(idx); - assert(reg.regClass == IntRegClass); - return thread.readIntReg(reg.regIdx); + const RegId& reg = si->srcRegIdx(idx); + assert(reg.isIntReg()); + return thread.readIntReg(reg.index()); } TheISA::FloatReg readFloatRegOperand(const StaticInst *si, int idx) override { - RegId reg = si->srcRegIdx(idx); - assert(reg.regClass == FloatRegClass); - return thread.readFloatReg(reg.regIdx); + const RegId& reg = si->srcRegIdx(idx); + assert(reg.isFloatReg()); + return thread.readFloatReg(reg.index()); } TheISA::FloatRegBits readFloatRegOperandBits(const StaticInst *si, int idx) override { - RegId reg = si->srcRegIdx(idx); - assert(reg.regClass == FloatRegClass); - return thread.readFloatRegBits(reg.regIdx); + const RegId& reg = si->srcRegIdx(idx); + assert(reg.isFloatReg()); + return thread.readFloatRegBits(reg.index()); } void setIntRegOperand(const StaticInst *si, int idx, IntReg val) override { - RegId reg = si->destRegIdx(idx); - assert(reg.regClass == IntRegClass); - thread.setIntReg(reg.regIdx, val); + const RegId& reg = si->destRegIdx(idx); + assert(reg.isIntReg()); + thread.setIntReg(reg.index(), val); } void setFloatRegOperand(const StaticInst *si, int idx, TheISA::FloatReg val) override { - RegId reg = si->destRegIdx(idx); - assert(reg.regClass == FloatRegClass); - thread.setFloatReg(reg.regIdx, val); + const RegId& reg = si->destRegIdx(idx); + assert(reg.isFloatReg()); + thread.setFloatReg(reg.index(), val); } void setFloatRegOperandBits(const StaticInst *si, int idx, TheISA::FloatRegBits val) override { - RegId reg = si->destRegIdx(idx); - assert(reg.regClass == FloatRegClass); - thread.setFloatRegBits(reg.regIdx, val); + const RegId& reg = si->destRegIdx(idx); + assert(reg.isFloatReg()); + thread.setFloatRegBits(reg.index(), val); } bool @@ -216,18 +216,18 @@ class ExecContext : public ::ExecContext TheISA::MiscReg readMiscRegOperand(const StaticInst *si, int idx) override { - RegId reg = si->srcRegIdx(idx); - assert(reg.regClass == MiscRegClass); - return thread.readMiscReg(reg.regIdx); + const RegId& reg = si->srcRegIdx(idx); + assert(reg.isMiscReg()); + return thread.readMiscReg(reg.index()); } void setMiscRegOperand(const StaticInst *si, int idx, const TheISA::MiscReg &val) override { - RegId reg = si->destRegIdx(idx); - assert(reg.regClass == MiscRegClass); - return thread.setMiscReg(reg.regIdx, val); + const RegId& reg = si->destRegIdx(idx); + assert(reg.isMiscReg()); + return thread.setMiscReg(reg.index(), val); } Fault @@ -279,17 +279,17 @@ class ExecContext : public ::ExecContext TheISA::CCReg readCCRegOperand(const StaticInst *si, int idx) override { - RegId reg = si->srcRegIdx(idx); - assert(reg.regClass == CCRegClass); - return thread.readCCReg(reg.regIdx); + const RegId& reg = si->srcRegIdx(idx); + assert(reg.isCCReg()); + return thread.readCCReg(reg.index()); } void setCCRegOperand(const StaticInst *si, int idx, TheISA::CCReg val) override { - RegId reg = si->destRegIdx(idx); - assert(reg.regClass == CCRegClass); - thread.setCCReg(reg.regIdx, val); + const RegId& reg = si->destRegIdx(idx); + assert(reg.isCCReg()); + thread.setCCReg(reg.index(), val); } void @@ -320,46 +320,46 @@ class ExecContext : public ::ExecContext /* MIPS: other thread register reading/writing */ uint64_t - readRegOtherThread(RegId reg, ThreadID tid = InvalidThreadID) + readRegOtherThread(const RegId& reg, ThreadID tid = InvalidThreadID) { SimpleThread *other_thread = (tid == InvalidThreadID ? &thread : cpu.threads[tid]); - switch(reg.regClass) { + switch (reg.classValue()) { case IntRegClass: - return other_thread->readIntReg(reg.regIdx); + return other_thread->readIntReg(reg.index()); break; case FloatRegClass: - return other_thread->readFloatRegBits(reg.regIdx); + return other_thread->readFloatRegBits(reg.index()); break; case MiscRegClass: - return other_thread->readMiscReg(reg.regIdx); + return other_thread->readMiscReg(reg.index()); default: panic("Unexpected reg class! (%s)", - RegClassStrings[reg.regClass]); + reg.className()); return 0; } } void - setRegOtherThread(RegId reg, const TheISA::MiscReg &val, + setRegOtherThread(const RegId& reg, const TheISA::MiscReg &val, ThreadID tid = InvalidThreadID) { SimpleThread *other_thread = (tid == InvalidThreadID ? &thread : cpu.threads[tid]); - switch(reg.regClass) { + switch (reg.classValue()) { case IntRegClass: - return other_thread->setIntReg(reg.regIdx, val); + return other_thread->setIntReg(reg.index(), val); break; case FloatRegClass: - return other_thread->setFloatRegBits(reg.regIdx, val); + return other_thread->setFloatRegBits(reg.index(), val); break; case MiscRegClass: - return other_thread->setMiscReg(reg.regIdx, val); + return other_thread->setMiscReg(reg.index(), val); default: panic("Unexpected reg class! (%s)", - RegClassStrings[reg.regClass]); + reg.className()); } } diff --git a/src/cpu/minor/scoreboard.cc b/src/cpu/minor/scoreboard.cc index 31657b310..e3497a5cf 100644 --- a/src/cpu/minor/scoreboard.cc +++ b/src/cpu/minor/scoreboard.cc @@ -48,7 +48,7 @@ namespace Minor { bool -Scoreboard::findIndex(RegId reg, Index &scoreboard_index) +Scoreboard::findIndex(const RegId& reg, Index &scoreboard_index) { bool ret = false; @@ -56,19 +56,19 @@ Scoreboard::findIndex(RegId reg, Index &scoreboard_index) /* Don't bother with the zero register */ ret = false; } else { - switch (reg.regClass) + switch (reg.classValue()) { case IntRegClass: - scoreboard_index = reg.regIdx; + scoreboard_index = reg.index(); ret = true; break; case FloatRegClass: scoreboard_index = TheISA::NumIntRegs + TheISA::NumCCRegs + - reg.regIdx; + reg.index(); ret = true; break; case CCRegClass: - scoreboard_index = TheISA::NumIntRegs + reg.regIdx; + scoreboard_index = TheISA::NumIntRegs + reg.index(); ret = true; break; case MiscRegClass: @@ -83,26 +83,9 @@ Scoreboard::findIndex(RegId reg, Index &scoreboard_index) /** Flatten a RegId, irrespective of what reg type it's pointing to */ static RegId -flattenRegIndex(RegId reg, ThreadContext *thread_context) +flattenRegIndex(const RegId& reg, ThreadContext *thread_context) { - switch (reg.regClass) - { - case IntRegClass: - reg.regIdx = thread_context->flattenIntIndex(reg.regIdx); - break; - case FloatRegClass: - reg.regIdx = thread_context->flattenFloatIndex(reg.regIdx); - break; - case CCRegClass: - reg.regIdx = thread_context->flattenCCIndex(reg.regIdx); - break; - case MiscRegClass: - /* Don't bother to flatten misc regs as we don't need them here */ - /* return thread_context->flattenMiscIndex(reg); */ - break; - } - - return reg; + return thread_context->flattenRegId(reg); } void @@ -143,7 +126,8 @@ Scoreboard::markupInstDests(MinorDynInstPtr inst, Cycles retire_time, *inst, index, numResults[index], returnCycle[index]); } else { /* Use ZeroReg to mark invalid/untracked dests */ - inst->flatDestRegIdx[dest_index] = RegId::zeroReg; + inst->flatDestRegIdx[dest_index] = RegId(IntRegClass, + TheISA::ZeroReg); } } } @@ -190,7 +174,7 @@ Scoreboard::clearInstDests(MinorDynInstPtr inst, bool clear_unpredictable) for (unsigned int dest_index = 0; dest_index < num_dests; dest_index++) { - RegId reg = inst->flatDestRegIdx[dest_index]; + const RegId& reg = inst->flatDestRegIdx[dest_index]; Index index; if (findIndex(reg, index)) { diff --git a/src/cpu/minor/scoreboard.hh b/src/cpu/minor/scoreboard.hh index 815d81408..7fe5002f9 100644 --- a/src/cpu/minor/scoreboard.hh +++ b/src/cpu/minor/scoreboard.hh @@ -106,7 +106,7 @@ class Scoreboard : public Named /** Sets scoreboard_index to the index into numResults of the * given register index. Returns true if the given register * is in the scoreboard and false if it isn't */ - bool findIndex(RegId reg, Index &scoreboard_index); + bool findIndex(const RegId& reg, Index &scoreboard_index); /** Mark up an instruction's effects by incrementing * numResults counts. If mark_unpredictable is true, the inst's diff --git a/src/cpu/o3/comm.hh b/src/cpu/o3/comm.hh index c5f1c0144..49e153a52 100644 --- a/src/cpu/o3/comm.hh +++ b/src/cpu/o3/comm.hh @@ -52,47 +52,65 @@ #include "cpu/inst_seq.hh" #include "sim/faults.hh" -// Typedef for physical register index type. Although the Impl would be the -// most likely location for this, there are a few classes that need this -// typedef yet are not templated on the Impl. For now it will be defined here. -typedef short int PhysRegIndex; -// Physical register ID -// Associate a physical register index to a register class and -// so it is easy to track which type of register are used. -// A flat index is also provided for when it is useful to have a unified -// indexing (for the dependency graph and the scoreboard for example) -struct PhysRegId { - RegClass regClass; - PhysRegIndex regIdx; +/** Physical register index type. + * Although the Impl might be a better for this, but there are a few classes + * that need this typedef yet are not templated on the Impl. + */ +using PhysRegIndex = short int; + +/** Physical register ID. + * Like a register ID but physical. The inheritance is private because the + * only relationship between this types is functional, and it is done to + * prevent code replication. */ +class PhysRegId : private RegId { + private: PhysRegIndex flatIdx; - PhysRegId(RegClass _regClass, PhysRegIndex _regIdx, + + public: + explicit PhysRegId() : RegId(IntRegClass, -1), flatIdx(-1) {} + + /** Scalar PhysRegId constructor. */ + explicit PhysRegId(RegClass _regClass, PhysRegIndex _regIdx, PhysRegIndex _flatIdx) - : regClass(_regClass), regIdx(_regIdx), flatIdx(_flatIdx) + : RegId(_regClass, _regIdx), flatIdx(_flatIdx) {} - bool operator==(const PhysRegId& that) const { - return regClass == that.regClass && regIdx == that.regIdx; + /** Visible RegId methods */ + /** @{ */ + using RegId::index; + using RegId::classValue; + using RegId::isZeroReg; + using RegId::className; + /** @} */ + /** + * Explicit forward methods, to prevent comparisons of PhysRegId with + * RegIds. + */ + /** @{ */ + bool operator<(const PhysRegId& that) const { + return RegId::operator<(that); } - bool operator!=(const PhysRegId& that) const { - return !(*this==that); + bool operator==(const PhysRegId& that) const { + return RegId::operator==(that); } - bool isZeroReg() const - { - return (regIdx == TheISA::ZeroReg && - (regClass == IntRegClass || - (THE_ISA == ALPHA_ISA && regClass == FloatRegClass))); + bool operator!=(const PhysRegId& that) const { + return RegId::operator!=(that); } + /** @} */ /** @return true if it is an integer physical register. */ - bool isIntPhysReg() const { return regClass == IntRegClass; } + bool isIntPhysReg() const { return isIntReg(); } /** @return true if it is a floating-point physical register. */ - bool isFloatPhysReg() const { return regClass == FloatRegClass; } + bool isFloatPhysReg() const { return isFloatReg(); } /** @Return true if it is a condition-code physical register. */ - bool isCCPhysReg() const { return regClass == CCRegClass; } + bool isCCPhysReg() const { return isCCReg(); } + + /** @Return true if it is a condition-code physical register. */ + bool isMiscPhysReg() const { return isMiscReg(); } /** * Returns true if this register is always associated to the same @@ -100,8 +118,11 @@ struct PhysRegId { */ bool isFixedMapping() const { - return regClass == MiscRegClass; + return !isRenameable(); } + + /** Flat index accessor */ + const PhysRegIndex& flatIndex() const { return flatIdx; } }; // PhysRegIds only need to be created once and then we can use the following diff --git a/src/cpu/o3/cpu.cc b/src/cpu/o3/cpu.cc index 6e9accdd5..a7a39b72a 100644 --- a/src/cpu/o3/cpu.cc +++ b/src/cpu/o3/cpu.cc @@ -300,20 +300,21 @@ FullO3CPU<Impl>::FullO3CPU(DerivO3CPUParams *params) // Note that we can't use the rename() method because we don't // want special treatment for the zero register at this point PhysRegIdPtr phys_reg = freeList.getIntReg(); - renameMap[tid].setIntEntry(ridx, phys_reg); - commitRenameMap[tid].setIntEntry(ridx, phys_reg); + renameMap[tid].setEntry(RegId(IntRegClass, ridx), phys_reg); + commitRenameMap[tid].setEntry(RegId(IntRegClass, ridx), phys_reg); } for (RegIndex ridx = 0; ridx < TheISA::NumFloatRegs; ++ridx) { PhysRegIdPtr phys_reg = freeList.getFloatReg(); - renameMap[tid].setFloatEntry(ridx, phys_reg); - commitRenameMap[tid].setFloatEntry(ridx, phys_reg); + renameMap[tid].setEntry(RegId(FloatRegClass, ridx), phys_reg); + commitRenameMap[tid].setEntry( + RegId(FloatRegClass, ridx), phys_reg); } for (RegIndex ridx = 0; ridx < TheISA::NumCCRegs; ++ridx) { PhysRegIdPtr phys_reg = freeList.getCCReg(); - renameMap[tid].setCCEntry(ridx, phys_reg); - commitRenameMap[tid].setCCEntry(ridx, phys_reg); + renameMap[tid].setEntry(RegId(CCRegClass, ridx), phys_reg); + commitRenameMap[tid].setEntry(RegId(CCRegClass, ridx), phys_reg); } } @@ -788,24 +789,24 @@ FullO3CPU<Impl>::insertThread(ThreadID tid) //Bind Int Regs to Rename Map - for (RegId reg_id(IntRegClass, 0); reg_id.regIdx < TheISA::NumIntRegs; - reg_id.regIdx++) { + for (RegId reg_id(IntRegClass, 0); reg_id.index() < TheISA::NumIntRegs; + reg_id.index()++) { PhysRegIdPtr phys_reg = freeList.getIntReg(); renameMap[tid].setEntry(reg_id, phys_reg); scoreboard.setReg(phys_reg); } //Bind Float Regs to Rename Map - for (RegId reg_id(FloatRegClass, 0); reg_id.regIdx < TheISA::NumFloatRegs; - reg_id.regIdx++) { + for (RegId reg_id(FloatRegClass, 0); reg_id.index() < TheISA::NumFloatRegs; + reg_id.index()++) { PhysRegIdPtr phys_reg = freeList.getFloatReg(); renameMap[tid].setEntry(reg_id, phys_reg); scoreboard.setReg(phys_reg); } //Bind condition-code Regs to Rename Map - for (RegId reg_id(CCRegClass, 0); reg_id.regIdx < TheISA::NumCCRegs; - reg_id.regIdx++) { + for (RegId reg_id(CCRegClass, 0); reg_id.index() < TheISA::NumCCRegs; + reg_id.index()++) { PhysRegIdPtr phys_reg = freeList.getCCReg(); renameMap[tid].setEntry(reg_id, phys_reg); scoreboard.setReg(phys_reg); @@ -842,24 +843,24 @@ FullO3CPU<Impl>::removeThread(ThreadID tid) // in SMT workloads. // Unbind Int Regs from Rename Map - for (RegId reg_id(IntRegClass, 0); reg_id.regIdx < TheISA::NumIntRegs; - reg_id.regIdx++) { + for (RegId reg_id(IntRegClass, 0); reg_id.index() < TheISA::NumIntRegs; + reg_id.index()++) { PhysRegIdPtr phys_reg = renameMap[tid].lookup(reg_id); scoreboard.unsetReg(phys_reg); freeList.addReg(phys_reg); } // Unbind Float Regs from Rename Map - for (RegId reg_id(FloatRegClass, 0); reg_id.regIdx < TheISA::NumFloatRegs; - reg_id.regIdx++) { + for (RegId reg_id(FloatRegClass, 0); reg_id.index() < TheISA::NumFloatRegs; + reg_id.index()++) { PhysRegIdPtr phys_reg = renameMap[tid].lookup(reg_id); scoreboard.unsetReg(phys_reg); freeList.addReg(phys_reg); } // Unbind condition-code Regs from Rename Map - for (RegId reg_id(CCRegClass, 0); reg_id.regIdx < TheISA::NumCCRegs; - reg_id.regIdx++) { + for (RegId reg_id(CCRegClass, 0); reg_id.index() < TheISA::NumCCRegs; + reg_id.index()++) { PhysRegIdPtr phys_reg = renameMap[tid].lookup(reg_id); scoreboard.unsetReg(phys_reg); freeList.addReg(phys_reg); @@ -1300,7 +1301,8 @@ uint64_t FullO3CPU<Impl>::readArchIntReg(int reg_idx, ThreadID tid) { intRegfileReads++; - PhysRegIdPtr phys_reg = commitRenameMap[tid].lookupInt(reg_idx); + PhysRegIdPtr phys_reg = commitRenameMap[tid].lookup( + RegId(IntRegClass, reg_idx)); return regFile.readIntReg(phys_reg); } @@ -1310,7 +1312,8 @@ float FullO3CPU<Impl>::readArchFloatReg(int reg_idx, ThreadID tid) { fpRegfileReads++; - PhysRegIdPtr phys_reg = commitRenameMap[tid].lookupFloat(reg_idx); + PhysRegIdPtr phys_reg = commitRenameMap[tid].lookup( + RegId(FloatRegClass, reg_idx)); return regFile.readFloatReg(phys_reg); } @@ -1320,7 +1323,8 @@ uint64_t FullO3CPU<Impl>::readArchFloatRegInt(int reg_idx, ThreadID tid) { fpRegfileReads++; - PhysRegIdPtr phys_reg = commitRenameMap[tid].lookupFloat(reg_idx); + PhysRegIdPtr phys_reg = commitRenameMap[tid].lookup( + RegId(FloatRegClass, reg_idx)); return regFile.readFloatRegBits(phys_reg); } @@ -1330,7 +1334,8 @@ CCReg FullO3CPU<Impl>::readArchCCReg(int reg_idx, ThreadID tid) { ccRegfileReads++; - PhysRegIdPtr phys_reg = commitRenameMap[tid].lookupCC(reg_idx); + PhysRegIdPtr phys_reg = commitRenameMap[tid].lookup( + RegId(CCRegClass, reg_idx)); return regFile.readCCReg(phys_reg); } @@ -1340,7 +1345,8 @@ void FullO3CPU<Impl>::setArchIntReg(int reg_idx, uint64_t val, ThreadID tid) { intRegfileWrites++; - PhysRegIdPtr phys_reg = commitRenameMap[tid].lookupInt(reg_idx); + PhysRegIdPtr phys_reg = commitRenameMap[tid].lookup( + RegId(IntRegClass, reg_idx)); regFile.setIntReg(phys_reg, val); } @@ -1350,7 +1356,8 @@ void FullO3CPU<Impl>::setArchFloatReg(int reg_idx, float val, ThreadID tid) { fpRegfileWrites++; - PhysRegIdPtr phys_reg = commitRenameMap[tid].lookupFloat(reg_idx); + PhysRegIdPtr phys_reg = commitRenameMap[tid].lookup( + RegId(FloatRegClass, reg_idx)); regFile.setFloatReg(phys_reg, val); } @@ -1360,7 +1367,8 @@ void FullO3CPU<Impl>::setArchFloatRegInt(int reg_idx, uint64_t val, ThreadID tid) { fpRegfileWrites++; - PhysRegIdPtr phys_reg = commitRenameMap[tid].lookupFloat(reg_idx); + PhysRegIdPtr phys_reg = commitRenameMap[tid].lookup( + RegId(FloatRegClass, reg_idx)); regFile.setFloatRegBits(phys_reg, val); } @@ -1370,7 +1378,8 @@ void FullO3CPU<Impl>::setArchCCReg(int reg_idx, CCReg val, ThreadID tid) { ccRegfileWrites++; - PhysRegIdPtr phys_reg = commitRenameMap[tid].lookupCC(reg_idx); + PhysRegIdPtr phys_reg = commitRenameMap[tid].lookup( + RegId(CCRegClass, reg_idx)); regFile.setCCReg(phys_reg, val); } diff --git a/src/cpu/o3/dyn_inst.hh b/src/cpu/o3/dyn_inst.hh index b200a328a..a6adb4c20 100644 --- a/src/cpu/o3/dyn_inst.hh +++ b/src/cpu/o3/dyn_inst.hh @@ -123,7 +123,7 @@ class BaseO3DynInst : public BaseDynInst<Impl> public: #if TRACING_ON /** Tick records used for the pipeline activity viewer. */ - Tick fetchTick; // instruction fetch is completed. + Tick fetchTick; // instruction fetch is completed. int32_t decodeTick; // instruction enters decode phase int32_t renameTick; // instruction enters rename phase int32_t dispatchTick; @@ -170,9 +170,9 @@ class BaseO3DynInst : public BaseDynInst<Impl> */ TheISA::MiscReg readMiscRegOperand(const StaticInst *si, int idx) { - RegId reg = si->srcRegIdx(idx); - assert(reg.regClass == MiscRegClass); - return this->cpu->readMiscReg(reg.regIdx, this->threadNumber); + const RegId& reg = si->srcRegIdx(idx); + assert(reg.isMiscReg()); + return this->cpu->readMiscReg(reg.index(), this->threadNumber); } /** Sets a misc. register, including any side-effects the write @@ -181,9 +181,9 @@ class BaseO3DynInst : public BaseDynInst<Impl> void setMiscRegOperand(const StaticInst *si, int idx, const MiscReg &val) { - RegId reg = si->destRegIdx(idx); - assert(reg.regClass == MiscRegClass); - setMiscReg(reg.regIdx, val); + const RegId& reg = si->destRegIdx(idx); + assert(reg.isMiscReg()); + setMiscReg(reg.index(), val); } /** Called at the commit stage to update the misc. registers. */ @@ -208,9 +208,9 @@ class BaseO3DynInst : public BaseDynInst<Impl> for (int idx = 0; idx < this->numDestRegs(); idx++) { PhysRegIdPtr prev_phys_reg = this->prevDestRegIdx(idx); - RegId original_dest_reg = + const RegId& original_dest_reg = this->staticInst->destRegIdx(idx); - switch (original_dest_reg.regClass) { + switch (original_dest_reg.classValue()) { case IntRegClass: this->setIntRegOperand(this->staticInst.get(), idx, this->cpu->readIntReg(prev_phys_reg)); @@ -300,13 +300,13 @@ class BaseO3DynInst : public BaseDynInst<Impl> } #if THE_ISA == MIPS_ISA - MiscReg readRegOtherThread(RegId misc_reg, ThreadID tid) + MiscReg readRegOtherThread(const RegId& misc_reg, ThreadID tid) { panic("MIPS MT not defined for O3 CPU.\n"); return 0; } - void setRegOtherThread(RegId misc_reg, MiscReg val, ThreadID tid) + void setRegOtherThread(const RegId& misc_reg, MiscReg val, ThreadID tid) { panic("MIPS MT not defined for O3 CPU.\n"); } diff --git a/src/cpu/o3/free_list.hh b/src/cpu/o3/free_list.hh index 3e6740e57..6fc6cc909 100644 --- a/src/cpu/o3/free_list.hh +++ b/src/cpu/o3/free_list.hh @@ -183,11 +183,11 @@ class UnifiedFreeList inline void UnifiedFreeList::addReg(PhysRegIdPtr freed_reg) { - DPRINTF(FreeList,"Freeing register %i (%s).\n", freed_reg->regIdx, - RegClassStrings[freed_reg->regClass]); + DPRINTF(FreeList,"Freeing register %i (%s).\n", freed_reg->index(), + freed_reg->className()); //Might want to add in a check for whether or not this register is //already in there. A bit vector or something similar would be useful. - switch (freed_reg->regClass) { + switch (freed_reg->classValue()) { case IntRegClass: intList.addReg(freed_reg); break; @@ -199,7 +199,7 @@ UnifiedFreeList::addReg(PhysRegIdPtr freed_reg) break; default: panic("Unexpected RegClass (%s)", - RegClassStrings[freed_reg->regClass]); + freed_reg->className()); } // These assert conditions ensure that the number of free diff --git a/src/cpu/o3/iew_impl.hh b/src/cpu/o3/iew_impl.hh index cdb6b26e2..80d7adc54 100644 --- a/src/cpu/o3/iew_impl.hh +++ b/src/cpu/o3/iew_impl.hh @@ -1434,8 +1434,8 @@ DefaultIEW<Impl>::writebackInsts() for (int i = 0; i < inst->numDestRegs(); i++) { //mark as Ready DPRINTF(IEW,"Setting Destination Register %i (%s)\n", - inst->renamedDestRegIdx(i)->regIdx, - RegClassStrings[inst->renamedDestRegIdx(i)->regClass]); + inst->renamedDestRegIdx(i)->index(), + inst->renamedDestRegIdx(i)->className()); scoreboard->setReg(inst->renamedDestRegIdx(i)); } diff --git a/src/cpu/o3/inst_queue_impl.hh b/src/cpu/o3/inst_queue_impl.hh index c46fd6ba7..f52cf2d6c 100644 --- a/src/cpu/o3/inst_queue_impl.hh +++ b/src/cpu/o3/inst_queue_impl.hh @@ -986,17 +986,17 @@ InstructionQueue<Impl>::wakeDependents(DynInstPtr &completed_inst) // handled by the IQ and thus have no dependency graph entry. if (dest_reg->isFixedMapping()) { DPRINTF(IQ, "Reg %d [%s] is part of a fix mapping, skipping\n", - dest_reg->regIdx, RegClassStrings[dest_reg->regClass]); + dest_reg->index(), dest_reg->className()); continue; } DPRINTF(IQ, "Waking any dependents on register %i (%s).\n", - dest_reg->regIdx, - RegClassStrings[dest_reg->regClass]); + dest_reg->index(), + dest_reg->className()); //Go through the dependency chain, marking the registers as //ready within the waiting instructions. - DynInstPtr dep_inst = dependGraph.pop(dest_reg->flatIdx); + DynInstPtr dep_inst = dependGraph.pop(dest_reg->flatIndex()); while (dep_inst) { DPRINTF(IQ, "Waking up a dependent instruction, [sn:%lli] " @@ -1010,18 +1010,18 @@ InstructionQueue<Impl>::wakeDependents(DynInstPtr &completed_inst) addIfReady(dep_inst); - dep_inst = dependGraph.pop(dest_reg->flatIdx); + dep_inst = dependGraph.pop(dest_reg->flatIndex()); ++dependents; } // Reset the head node now that all of its dependents have // been woken up. - assert(dependGraph.empty(dest_reg->flatIdx)); - dependGraph.clearInst(dest_reg->flatIdx); + assert(dependGraph.empty(dest_reg->flatIndex())); + dependGraph.clearInst(dest_reg->flatIndex()); // Mark the scoreboard as having that register ready. - regScoreboard[dest_reg->flatIdx] = true; + regScoreboard[dest_reg->flatIndex()] = true; } return dependents; } @@ -1233,7 +1233,8 @@ InstructionQueue<Impl>::doSquash(ThreadID tid) if (!squashed_inst->isReadySrcRegIdx(src_reg_idx) && !src_reg->isFixedMapping()) { - dependGraph.remove(src_reg->flatIdx, squashed_inst); + dependGraph.remove(src_reg->flatIndex(), + squashed_inst); } @@ -1308,13 +1309,13 @@ InstructionQueue<Impl>::addToDependents(DynInstPtr &new_inst) // it be added to the dependency graph. if (src_reg->isFixedMapping()) { continue; - } else if (!regScoreboard[src_reg->flatIdx]) { + } else if (!regScoreboard[src_reg->flatIndex()]) { DPRINTF(IQ, "Instruction PC %s has src reg %i (%s) that " "is being added to the dependency chain.\n", - new_inst->pcState(), src_reg->regIdx, - RegClassStrings[src_reg->regClass]); + new_inst->pcState(), src_reg->index(), + src_reg->className()); - dependGraph.insert(src_reg->flatIdx, new_inst); + dependGraph.insert(src_reg->flatIndex(), new_inst); // Change the return value to indicate that something // was added to the dependency graph. @@ -1322,8 +1323,8 @@ InstructionQueue<Impl>::addToDependents(DynInstPtr &new_inst) } else { DPRINTF(IQ, "Instruction PC %s has src reg %i (%s) that " "became ready before it reached the IQ.\n", - new_inst->pcState(), src_reg->regIdx, - RegClassStrings[src_reg->regClass]); + new_inst->pcState(), src_reg->index(), + src_reg->className()); // Mark a register ready within the instruction. new_inst->markSrcRegReady(src_reg_idx); } @@ -1355,17 +1356,17 @@ InstructionQueue<Impl>::addToProducers(DynInstPtr &new_inst) continue; } - if (!dependGraph.empty(dest_reg->flatIdx)) { + if (!dependGraph.empty(dest_reg->flatIndex())) { dependGraph.dump(); panic("Dependency graph %i (%s) (flat: %i) not empty!", - dest_reg->regIdx, RegClassStrings[dest_reg->regClass], - dest_reg->flatIdx); + dest_reg->index(), dest_reg->className(), + dest_reg->flatIndex()); } - dependGraph.setInst(dest_reg->flatIdx, new_inst); + dependGraph.setInst(dest_reg->flatIndex(), new_inst); // Mark the scoreboard to say it's not yet ready. - regScoreboard[dest_reg->flatIdx] = false; + regScoreboard[dest_reg->flatIndex()] = false; } } diff --git a/src/cpu/o3/probe/elastic_trace.cc b/src/cpu/o3/probe/elastic_trace.cc index 76f7e439a..08ef6654d 100644 --- a/src/cpu/o3/probe/elastic_trace.cc +++ b/src/cpu/o3/probe/elastic_trace.cc @@ -242,8 +242,8 @@ ElasticTrace::updateRegDep(const DynInstPtr &dyn_inst) PhysRegIdPtr src_reg = dyn_inst->renamedSrcRegIdx(src_idx); DPRINTFR(ElasticTrace, "[sn:%lli] Check map for src reg" " %i (%s)\n", seq_num, - src_reg->regIdx, RegClassStrings[src_reg->regClass]); - auto itr_last_writer = physRegDepMap.find(src_reg->flatIdx); + src_reg->index(), src_reg->className()); + auto itr_last_writer = physRegDepMap.find(src_reg->flatIndex()); if (itr_last_writer != physRegDepMap.end()) { InstSeqNum last_writer = itr_last_writer->second; // Additionally the dependency distance is kept less than the window @@ -263,16 +263,16 @@ ElasticTrace::updateRegDep(const DynInstPtr &dyn_inst) for (int dest_idx = 0; dest_idx < max_regs; dest_idx++) { // For data dependency tracking the register must be an int, float or // CC register and not a Misc register. - RegId dest_reg = dyn_inst->destRegIdx(dest_idx); - if (dest_reg.isRenameable() && + const RegId& dest_reg = dyn_inst->destRegIdx(dest_idx); + if (!dest_reg.isMiscReg() && !dest_reg.isZeroReg()) { // Get the physical register index of the i'th destination // register. PhysRegIdPtr phys_dest_reg = dyn_inst->renamedDestRegIdx(dest_idx); DPRINTFR(ElasticTrace, "[sn:%lli] Update map for dest reg" - " %i (%s)\n", seq_num, dest_reg.regIdx, - RegClassStrings[dest_reg.regClass]); - physRegDepMap[phys_dest_reg->flatIdx] = seq_num; + " %i (%s)\n", seq_num, dest_reg.index(), + dest_reg.className()); + physRegDepMap[phys_dest_reg->flatIndex()] = seq_num; } } maxPhysRegDepMapSize = std::max(physRegDepMap.size(), diff --git a/src/cpu/o3/regfile.cc b/src/cpu/o3/regfile.cc index ee8d07b3e..ea4370f48 100644 --- a/src/cpu/o3/regfile.cc +++ b/src/cpu/o3/regfile.cc @@ -89,21 +89,21 @@ PhysRegFile::initFreeList(UnifiedFreeList *freeList) // The initial batch of registers are the integer ones for (reg_idx = 0; reg_idx < numPhysicalIntRegs; reg_idx++) { - assert(intRegIds[reg_idx].regIdx == reg_idx); + assert(intRegIds[reg_idx].index() == reg_idx); freeList->addIntReg(&intRegIds[reg_idx]); } // The next batch of the registers are the floating-point physical // registers; put them onto the floating-point free list. for (reg_idx = 0; reg_idx < numPhysicalFloatRegs; reg_idx++) { - assert(floatRegIds[reg_idx].regIdx == reg_idx); + assert(floatRegIds[reg_idx].index() == reg_idx); freeList->addFloatReg(&floatRegIds[reg_idx]); } // The rest of the registers are the condition-code physical // registers; put them onto the condition-code free list. for (reg_idx = 0; reg_idx < numPhysicalCCRegs; reg_idx++) { - assert(ccRegIds[reg_idx].regIdx == reg_idx); + assert(ccRegIds[reg_idx].index() == reg_idx); freeList->addCCReg(&ccRegIds[reg_idx]); } } diff --git a/src/cpu/o3/regfile.hh b/src/cpu/o3/regfile.hh index c7935c55c..c353b2746 100644 --- a/src/cpu/o3/regfile.hh +++ b/src/cpu/o3/regfile.hh @@ -135,8 +135,8 @@ class PhysRegFile assert(phys_reg->isIntPhysReg()); DPRINTF(IEW, "RegFile: Access to int register %i, has data " - "%#x\n", phys_reg->regIdx, intRegFile[phys_reg->regIdx]); - return intRegFile[phys_reg->regIdx]; + "%#x\n", phys_reg->index(), intRegFile[phys_reg->index()]); + return intRegFile[phys_reg->index()]; } /** Reads a floating point register (double precision). */ @@ -145,20 +145,20 @@ class PhysRegFile assert(phys_reg->isFloatPhysReg()); DPRINTF(IEW, "RegFile: Access to float register %i, has " - "data %#x\n", phys_reg->regIdx, - floatRegFile[phys_reg->regIdx].q); + "data %#x\n", phys_reg->index(), + floatRegFile[phys_reg->index()].q); - return floatRegFile[phys_reg->regIdx].d; + return floatRegFile[phys_reg->index()].d; } FloatRegBits readFloatRegBits(PhysRegIdPtr phys_reg) const { assert(phys_reg->isFloatPhysReg()); - FloatRegBits floatRegBits = floatRegFile[phys_reg->regIdx].q; + FloatRegBits floatRegBits = floatRegFile[phys_reg->index()].q; DPRINTF(IEW, "RegFile: Access to float register %i as int, " - "has data %#x\n", phys_reg->regIdx, + "has data %#x\n", phys_reg->index(), (uint64_t)floatRegBits); return floatRegBits; @@ -170,10 +170,10 @@ class PhysRegFile assert(phys_reg->isCCPhysReg()); DPRINTF(IEW, "RegFile: Access to cc register %i, has " - "data %#x\n", phys_reg->regIdx, - ccRegFile[phys_reg->regIdx]); + "data %#x\n", phys_reg->index(), + ccRegFile[phys_reg->index()]); - return ccRegFile[phys_reg->regIdx]; + return ccRegFile[phys_reg->index()]; } /** Sets an integer register to the given value. */ @@ -182,10 +182,10 @@ class PhysRegFile assert(phys_reg->isIntPhysReg()); DPRINTF(IEW, "RegFile: Setting int register %i to %#x\n", - phys_reg->regIdx, val); + phys_reg->index(), val); if (!phys_reg->isZeroReg()) - intRegFile[phys_reg->regIdx] = val; + intRegFile[phys_reg->index()] = val; } /** Sets a double precision floating point register to the given value. */ @@ -194,10 +194,10 @@ class PhysRegFile assert(phys_reg->isFloatPhysReg()); DPRINTF(IEW, "RegFile: Setting float register %i to %#x\n", - phys_reg->regIdx, (uint64_t)val); + phys_reg->index(), (uint64_t)val); if (!phys_reg->isZeroReg()) - floatRegFile[phys_reg->regIdx].d = val; + floatRegFile[phys_reg->index()].d = val; } void setFloatRegBits(PhysRegIdPtr phys_reg, FloatRegBits val) @@ -205,9 +205,9 @@ class PhysRegFile assert(phys_reg->isFloatPhysReg()); DPRINTF(IEW, "RegFile: Setting float register %i to %#x\n", - phys_reg->regIdx, (uint64_t)val); + phys_reg->index(), (uint64_t)val); - floatRegFile[phys_reg->regIdx].q = val; + floatRegFile[phys_reg->index()].q = val; } /** Sets a condition-code register to the given value. */ @@ -216,9 +216,9 @@ class PhysRegFile assert(phys_reg->isCCPhysReg()); DPRINTF(IEW, "RegFile: Setting cc register %i to %#x\n", - phys_reg->regIdx, (uint64_t)val); + phys_reg->index(), (uint64_t)val); - ccRegFile[phys_reg->regIdx] = val; + ccRegFile[phys_reg->index()] = val; } }; diff --git a/src/cpu/o3/rename.hh b/src/cpu/o3/rename.hh index ab7ae5f8b..6d3861ba6 100644 --- a/src/cpu/o3/rename.hh +++ b/src/cpu/o3/rename.hh @@ -298,7 +298,7 @@ class DefaultRename * register for that arch. register, and the new physical register. */ struct RenameHistory { - RenameHistory(InstSeqNum _instSeqNum, RegId _archReg, + RenameHistory(InstSeqNum _instSeqNum, const RegId& _archReg, PhysRegIdPtr _newPhysReg, PhysRegIdPtr _prevPhysReg) : instSeqNum(_instSeqNum), archReg(_archReg), diff --git a/src/cpu/o3/rename_impl.hh b/src/cpu/o3/rename_impl.hh index a92792639..9c9b030f5 100644 --- a/src/cpu/o3/rename_impl.hh +++ b/src/cpu/o3/rename_impl.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2012, 2014-2015 ARM Limited + * Copyright (c) 2010-2012, 2014-2016 ARM Limited * Copyright (c) 2013 Advanced Micro Devices, Inc. * All rights reserved. * @@ -985,8 +985,8 @@ DefaultRename<Impl>::removeFromHistory(InstSeqNum inst_seq_num, ThreadID tid) DPRINTF(Rename, "[tid:%u]: Freeing up older rename of reg %i (%s), " "[sn:%lli].\n", - tid, hb_it->prevPhysReg->regIdx, - RegClassStrings[hb_it->prevPhysReg->regClass], + tid, hb_it->prevPhysReg->index(), + hb_it->prevPhysReg->className(), hb_it->instSeqNum); // Don't free special phys regs like misc and zero regs, which @@ -1013,59 +1013,46 @@ DefaultRename<Impl>::renameSrcRegs(DynInstPtr &inst, ThreadID tid) // Get the architectual register numbers from the source and // operands, and redirect them to the right physical register. for (int src_idx = 0; src_idx < num_src_regs; src_idx++) { - RegId src_reg = inst->srcRegIdx(src_idx); - RegIndex flat_src_reg; + const RegId& src_reg = inst->srcRegIdx(src_idx); PhysRegIdPtr renamed_reg; - switch (src_reg.regClass) { + renamed_reg = map->lookup(tc->flattenRegId(src_reg)); + switch (src_reg.classValue()) { case IntRegClass: - flat_src_reg = tc->flattenIntIndex(src_reg.regIdx); - renamed_reg = map->lookupInt(flat_src_reg); intRenameLookups++; break; - case FloatRegClass: - flat_src_reg = tc->flattenFloatIndex(src_reg.regIdx); - renamed_reg = map->lookupFloat(flat_src_reg); fpRenameLookups++; break; - case CCRegClass: - flat_src_reg = tc->flattenCCIndex(src_reg.regIdx); - renamed_reg = map->lookupCC(flat_src_reg); - break; - case MiscRegClass: - // misc regs don't get flattened - flat_src_reg = src_reg.regIdx; - renamed_reg = map->lookupMisc(flat_src_reg); break; default: - panic("Invalid register class: %d.", src_reg.regClass); + panic("Invalid register class: %d.", src_reg.classValue()); } DPRINTF(Rename, "[tid:%u]: Looking up %s arch reg %i" - " (flattened %i), got phys reg %i (%s)\n", tid, - RegClassStrings[src_reg.regClass], src_reg.regIdx, - flat_src_reg, renamed_reg->regIdx, - RegClassStrings[renamed_reg->regClass]); + ", got phys reg %i (%s)\n", tid, + src_reg.className(), src_reg.index(), + renamed_reg->index(), + renamed_reg->className()); inst->renameSrcReg(src_idx, renamed_reg); // See if the register is ready or not. if (scoreboard->getReg(renamed_reg)) { DPRINTF(Rename, "[tid:%u]: Register %d (flat: %d) (%s)" - " is ready.\n", tid, renamed_reg->regIdx, - renamed_reg->flatIdx, - RegClassStrings[renamed_reg->regClass]); + " is ready.\n", tid, renamed_reg->index(), + renamed_reg->flatIndex(), + renamed_reg->className()); inst->markSrcRegReady(src_idx); } else { DPRINTF(Rename, "[tid:%u]: Register %d (flat: %d) (%s)" - " is not ready.\n", tid, renamed_reg->regIdx, - renamed_reg->flatIdx, - RegClassStrings[renamed_reg->regClass]); + " is not ready.\n", tid, renamed_reg->index(), + renamed_reg->flatIndex(), + renamed_reg->className()); } ++renameRenameLookups; @@ -1082,51 +1069,26 @@ DefaultRename<Impl>::renameDestRegs(DynInstPtr &inst, ThreadID tid) // Rename the destination registers. for (int dest_idx = 0; dest_idx < num_dest_regs; dest_idx++) { - RegId dest_reg = inst->destRegIdx(dest_idx); - RegIndex flat_dest_reg; + const RegId& dest_reg = inst->destRegIdx(dest_idx); typename RenameMap::RenameInfo rename_result; - switch (dest_reg.regClass) { - case IntRegClass: - flat_dest_reg = tc->flattenIntIndex(dest_reg.regIdx); - rename_result = map->renameInt(flat_dest_reg); - break; - - case FloatRegClass: - flat_dest_reg = tc->flattenFloatIndex(dest_reg.regIdx); - rename_result = map->renameFloat(flat_dest_reg); - break; - - case CCRegClass: - flat_dest_reg = tc->flattenCCIndex(dest_reg.regIdx); - rename_result = map->renameCC(flat_dest_reg); - break; - - case MiscRegClass: - // misc regs don't get flattened - flat_dest_reg = dest_reg.regIdx; - rename_result = map->renameMisc(dest_reg.regIdx); - break; - - default: - panic("Invalid register class: %d.", dest_reg.regClass); - } + RegId flat_dest_regid = tc->flattenRegId(dest_reg); - RegId flat_uni_dest_reg(dest_reg.regClass, flat_dest_reg); + rename_result = map->rename(flat_dest_regid); - inst->flattenDestReg(dest_idx, flat_uni_dest_reg); + inst->flattenDestReg(dest_idx, flat_dest_regid); // Mark Scoreboard entry as not ready scoreboard->unsetReg(rename_result.first); DPRINTF(Rename, "[tid:%u]: Renaming arch reg %i (%s) to physical " - "reg %i (%i).\n", tid, dest_reg.regIdx, - RegClassStrings[dest_reg.regClass], - rename_result.first->regIdx, - rename_result.first->flatIdx); + "reg %i (%i).\n", tid, dest_reg.index(), + dest_reg.className(), + rename_result.first->index(), + rename_result.first->flatIndex()); // Record the rename information so that a history can be kept. - RenameHistory hb_entry(inst->seqNum, flat_uni_dest_reg, + RenameHistory hb_entry(inst->seqNum, flat_dest_regid, rename_result.first, rename_result.second); @@ -1439,12 +1401,12 @@ DefaultRename<Impl>::dumpHistory() cprintf("Seq num: %i\nArch reg[%s]: %i New phys reg:" " %i[%s] Old phys reg: %i[%s]\n", (*buf_it).instSeqNum, - RegClassStrings[(*buf_it).archReg.regClass], - (*buf_it).archReg.regIdx, - (*buf_it).newPhysReg->regIdx, - RegClassStrings[(*buf_it).newPhysReg->regClass], - (*buf_it).prevPhysReg->regIdx, - RegClassStrings[(*buf_it).prevPhysReg->regClass]); + (*buf_it).archReg.className(), + (*buf_it).archReg.index(), + (*buf_it).newPhysReg->index(), + (*buf_it).newPhysReg->className(), + (*buf_it).prevPhysReg->index(), + (*buf_it).prevPhysReg->className()); buf_it++; } diff --git a/src/cpu/o3/rename_map.cc b/src/cpu/o3/rename_map.cc index 4555946c2..38ccc7ec9 100644 --- a/src/cpu/o3/rename_map.cc +++ b/src/cpu/o3/rename_map.cc @@ -33,6 +33,7 @@ #include <vector> +#include "cpu/reg_class_impl.hh" #include "debug/Rename.hh" using namespace std; @@ -40,7 +41,7 @@ using namespace std; /**** SimpleRenameMap methods ****/ SimpleRenameMap::SimpleRenameMap() - : freeList(NULL), zeroReg(0) + : freeList(NULL), zeroReg(IntRegClass,0) { } @@ -54,24 +55,23 @@ SimpleRenameMap::init(unsigned size, SimpleFreeList *_freeList, map.resize(size); freeList = _freeList; - zeroReg = _zeroReg; + zeroReg = RegId(IntRegClass, _zeroReg); } SimpleRenameMap::RenameInfo -SimpleRenameMap::rename(RegIndex arch_reg) +SimpleRenameMap::rename(const RegId& arch_reg) { PhysRegIdPtr renamed_reg; - // Record the current physical register that is renamed to the // requested architected register. - PhysRegIdPtr prev_reg = map[arch_reg]; + PhysRegIdPtr prev_reg = map[arch_reg.index()]; // If it's not referencing the zero register, then rename the // register. if (arch_reg != zeroReg) { renamed_reg = freeList->getReg(); - map[arch_reg] = renamed_reg; + map[arch_reg.index()] = renamed_reg; } else { // Otherwise return the zero register so nothing bad happens. assert(prev_reg->isZeroReg()); @@ -80,8 +80,8 @@ SimpleRenameMap::rename(RegIndex arch_reg) DPRINTF(Rename, "Renamed reg %d to physical reg %d (%d) old mapping was" " %d (%d)\n", - arch_reg, renamed_reg->regIdx, renamed_reg->flatIdx, - prev_reg->regIdx, prev_reg->flatIdx); + arch_reg, renamed_reg->index(), renamed_reg->flatIndex(), + prev_reg->index(), prev_reg->flatIndex()); return RenameInfo(renamed_reg, prev_reg); } @@ -105,75 +105,3 @@ UnifiedRenameMap::init(PhysRegFile *_regFile, } - -UnifiedRenameMap::RenameInfo -UnifiedRenameMap::rename(RegId arch_reg) -{ - switch (arch_reg.regClass) { - case IntRegClass: - return renameInt(arch_reg.regIdx); - - case FloatRegClass: - return renameFloat(arch_reg.regIdx); - - case CCRegClass: - return renameCC(arch_reg.regIdx); - - case MiscRegClass: - return renameMisc(arch_reg.regIdx); - - default: - panic("rename rename(): unknown reg class %s\n", - RegClassStrings[arch_reg.regClass]); - } -} - - -PhysRegIdPtr -UnifiedRenameMap::lookup(RegId arch_reg) const -{ - switch (arch_reg.regClass) { - case IntRegClass: - return lookupInt(arch_reg.regIdx); - - case FloatRegClass: - return lookupFloat(arch_reg.regIdx); - - case CCRegClass: - return lookupCC(arch_reg.regIdx); - - case MiscRegClass: - return lookupMisc(arch_reg.regIdx); - - default: - panic("rename lookup(): unknown reg class %s\n", - RegClassStrings[arch_reg.regClass]); - } -} - -void -UnifiedRenameMap::setEntry(RegId arch_reg, PhysRegIdPtr phys_reg) -{ - switch (arch_reg.regClass) { - case IntRegClass: - return setIntEntry(arch_reg.regIdx, phys_reg); - - case FloatRegClass: - return setFloatEntry(arch_reg.regIdx, phys_reg); - - case CCRegClass: - return setCCEntry(arch_reg.regIdx, phys_reg); - - case MiscRegClass: - // Misc registers do not actually rename, so don't change - // their mappings. We end up here when a commit or squash - // tries to update or undo a hardwired misc reg nmapping, - // which should always be setting it to what it already is. - assert(phys_reg == lookupMisc(arch_reg.regIdx)); - return; - - default: - panic("rename setEntry(): unknown reg class %s\n", - RegClassStrings[arch_reg.regClass]); - } -} diff --git a/src/cpu/o3/rename_map.hh b/src/cpu/o3/rename_map.hh index f51cf5922..028c32e3a 100644 --- a/src/cpu/o3/rename_map.hh +++ b/src/cpu/o3/rename_map.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 ARM Limited + * Copyright (c) 2015-2016 ARM Limited * All rights reserved. * * The license below extends only to copyright in the software and shall @@ -65,9 +65,9 @@ class SimpleRenameMap { private: - + using Arch2PhysMap = std::vector<PhysRegIdPtr>; /** The acutal arch-to-phys register map */ - std::vector<PhysRegIdPtr> map; + Arch2PhysMap map; /** * Pointer to the free list from which new physical registers @@ -82,7 +82,7 @@ class SimpleRenameMap * table, it should be set to an invalid index so that it never * matches. */ - RegIndex zeroReg; + RegId zeroReg; public: @@ -112,17 +112,17 @@ class SimpleRenameMap * @return A RenameInfo pair indicating both the new and previous * physical registers. */ - RenameInfo rename(RegIndex arch_reg); + RenameInfo rename(const RegId& arch_reg); /** * Look up the physical register mapped to an architectural register. * @param arch_reg The architectural register to look up. * @return The physical register it is currently mapped to. */ - PhysRegIdPtr lookup(RegIndex arch_reg) const + PhysRegIdPtr lookup(const RegId& arch_reg) const { - assert(arch_reg < map.size()); - return map[arch_reg]; + assert(arch_reg.flatIndex() <= map.size()); + return map[arch_reg.flatIndex()]; } /** @@ -131,9 +131,10 @@ class SimpleRenameMap * @param arch_reg The architectural register to remap. * @param phys_reg The physical register to remap it to. */ - void setEntry(RegIndex arch_reg, PhysRegIdPtr phys_reg) + void setEntry(const RegId& arch_reg, PhysRegIdPtr phys_reg) { - map[arch_reg] = phys_reg; + assert(arch_reg.flatIndex() <= map.size()); + map[arch_reg.flatIndex()] = phys_reg; } /** Return the number of free entries on the associated free list. */ @@ -186,100 +187,63 @@ class UnifiedRenameMap /** * Tell rename map to get a new free physical register to remap * the specified architectural register. This version takes a - * flattened architectural register id and calls the - * appropriate class-specific rename table. - * @param arch_reg The architectural register index to remap. + * RegId and reads the appropriate class-specific rename table. + * @param arch_reg The architectural register id to remap. * @return A RenameInfo pair indicating both the new and previous * physical registers. */ - RenameInfo rename(RegId arch_reg); - - /** - * Perform rename() on an integer register, given a - * integer register index. - */ - RenameInfo renameInt(RegIndex rel_arch_reg) - { - return intMap.rename(rel_arch_reg); - } - - /** - * Perform rename() on a floating-point register, given a - * floating-point register index. - */ - RenameInfo renameFloat(RegIndex rel_arch_reg) - { - return floatMap.rename(rel_arch_reg); - } - - /** - * Perform rename() on a condition-code register, given a - * condition-code register index. - */ - RenameInfo renameCC(RegIndex rel_arch_reg) + RenameInfo rename(const RegId& arch_reg) { - return ccMap.rename(rel_arch_reg); + switch (arch_reg.classValue()) { + case IntRegClass: + return intMap.rename(arch_reg); + case FloatRegClass: + return floatMap.rename(arch_reg); + case CCRegClass: + return ccMap.rename(arch_reg); + case MiscRegClass: + { + // misc regs aren't really renamed, just remapped + PhysRegIdPtr phys_reg = lookup(arch_reg); + // Set the new register to the previous one to keep the same + // mapping throughout the execution. + return RenameInfo(phys_reg, phys_reg); + } + + default: + panic("rename rename(): unknown reg class %s\n", + arch_reg.className()); + } } /** - * Perform rename() on a misc register, given a - * misc register index. - */ - RenameInfo renameMisc(RegIndex rel_arch_reg) - { - // misc regs aren't really renamed, just remapped - PhysRegIdPtr phys_reg = lookupMisc(rel_arch_reg); - // Set the new register to the previous one to keep the same - // mapping throughout the execution. - return RenameInfo(phys_reg, phys_reg); - } - - - /** * Look up the physical register mapped to an architectural register. * This version takes a flattened architectural register id * and calls the appropriate class-specific rename table. * @param arch_reg The architectural register to look up. * @return The physical register it is currently mapped to. */ - PhysRegIdPtr lookup(RegId arch_reg) const; - - /** - * Perform lookup() on an integer register, given a - * integer register index. - */ - PhysRegIdPtr lookupInt(RegIndex rel_arch_reg) const + PhysRegIdPtr lookup(const RegId& arch_reg) const { - return intMap.lookup(rel_arch_reg); - } + switch (arch_reg.classValue()) { + case IntRegClass: + return intMap.lookup(arch_reg); - /** - * Perform lookup() on a floating-point register, given a - * floating-point register index. - */ - PhysRegIdPtr lookupFloat(RegIndex rel_arch_reg) const - { - return floatMap.lookup(rel_arch_reg); - } + case FloatRegClass: + return floatMap.lookup(arch_reg); - /** - * Perform lookup() on a condition-code register, given a - * condition-code register index. - */ - PhysRegIdPtr lookupCC(RegIndex rel_arch_reg) const - { - return ccMap.lookup(rel_arch_reg); - } + case CCRegClass: + return ccMap.lookup(arch_reg); - /** - * Perform lookup() on a misc register, given a relative - * misc register index. - */ - PhysRegIdPtr lookupMisc(RegIndex rel_arch_reg) const - { - // misc regs aren't really renamed, they keep the same - // mapping throughout the execution. - return regFile->getMiscRegId(rel_arch_reg); + case MiscRegClass: + // misc regs aren't really renamed, they keep the same + // mapping throughout the execution. + return regFile->getMiscRegId(arch_reg.flatIndex()); + + default: + panic("rename lookup(): unknown reg class %s\n", + arch_reg.className()); + } } /** @@ -290,36 +254,33 @@ class UnifiedRenameMap * @param arch_reg The architectural register to remap. * @param phys_reg The physical register to remap it to. */ - void setEntry(RegId arch_reg, PhysRegIdPtr phys_reg); - - /** - * Perform setEntry() on an integer register, given a - * integer register index. - */ - void setIntEntry(RegIndex arch_reg, PhysRegIdPtr phys_reg) - { - assert(phys_reg->isIntPhysReg()); - intMap.setEntry(arch_reg, phys_reg); - } - - /** - * Perform setEntry() on a floating-point register, given a - * floating-point register index. - */ - void setFloatEntry(RegIndex arch_reg, PhysRegIdPtr phys_reg) - { - assert(phys_reg->isFloatPhysReg()); - floatMap.setEntry(arch_reg, phys_reg); - } - - /** - * Perform setEntry() on a condition-code register, given a - * condition-code register index. - */ - void setCCEntry(RegIndex arch_reg, PhysRegIdPtr phys_reg) + void setEntry(const RegId& arch_reg, PhysRegIdPtr phys_reg) { - assert(phys_reg->isCCPhysReg()); - ccMap.setEntry(arch_reg, phys_reg); + switch (arch_reg.classValue()) { + case IntRegClass: + assert(phys_reg->isIntPhysReg()); + return intMap.setEntry(arch_reg, phys_reg); + + case FloatRegClass: + assert(phys_reg->isFloatPhysReg()); + return floatMap.setEntry(arch_reg, phys_reg); + + case CCRegClass: + assert(phys_reg->isCCPhysReg()); + return ccMap.setEntry(arch_reg, phys_reg); + + case MiscRegClass: + // Misc registers do not actually rename, so don't change + // their mappings. We end up here when a commit or squash + // tries to update or undo a hardwired misc reg nmapping, + // which should always be setting it to what it already is. + assert(phys_reg == lookup(arch_reg)); + return; + + default: + panic("rename setEntry(): unknown reg class %s\n", + arch_reg.className()); + } } /** diff --git a/src/cpu/o3/scoreboard.hh b/src/cpu/o3/scoreboard.hh index 44e449944..1012bae59 100644 --- a/src/cpu/o3/scoreboard.hh +++ b/src/cpu/o3/scoreboard.hh @@ -80,14 +80,14 @@ class Scoreboard /** Checks if the register is ready. */ bool getReg(PhysRegIdPtr phys_reg) const { - assert(phys_reg->flatIdx < numPhysRegs); + assert(phys_reg->flatIndex() < numPhysRegs); if (phys_reg->isFixedMapping()) { // Fixed mapping regs are always ready return true; } - bool ready = regScoreBoard[phys_reg->flatIdx]; + bool ready = regScoreBoard[phys_reg->flatIndex()]; if (phys_reg->isZeroReg()) assert(ready); @@ -98,7 +98,7 @@ class Scoreboard /** Sets the register as ready. */ void setReg(PhysRegIdPtr phys_reg) { - assert(phys_reg->flatIdx < numPhysRegs); + assert(phys_reg->flatIndex() < numPhysRegs); if (phys_reg->isFixedMapping()) { // Fixed mapping regs are always ready, ignore attempts to change @@ -106,16 +106,16 @@ class Scoreboard return; } - DPRINTF(Scoreboard, "Setting reg %i (%s) as ready\n", phys_reg->regIdx, - RegClassStrings[phys_reg->regClass]); + DPRINTF(Scoreboard, "Setting reg %i (%s) as ready\n", + phys_reg->index(), phys_reg->className()); - regScoreBoard[phys_reg->flatIdx] = true; + regScoreBoard[phys_reg->flatIndex()] = true; } /** Sets the register as not ready. */ void unsetReg(PhysRegIdPtr phys_reg) { - assert(phys_reg->flatIdx < numPhysRegs); + assert(phys_reg->flatIndex() < numPhysRegs); if (phys_reg->isFixedMapping()) { // Fixed mapping regs are always ready, ignore attempts to @@ -127,7 +127,7 @@ class Scoreboard if (phys_reg->isZeroReg()) return; - regScoreBoard[phys_reg->flatIdx] = false; + regScoreBoard[phys_reg->flatIndex()] = false; } }; diff --git a/src/cpu/o3/thread_context.hh b/src/cpu/o3/thread_context.hh index 78b88ac2a..161d70b28 100755 --- a/src/cpu/o3/thread_context.hh +++ b/src/cpu/o3/thread_context.hh @@ -175,37 +175,47 @@ class O3ThreadContext : public ThreadContext virtual void clearArchRegs(); /** Reads an integer register. */ + virtual uint64_t readReg(int reg_idx) { + return readIntRegFlat(flattenRegId(RegId(IntRegClass, + reg_idx)).index()); + } virtual uint64_t readIntReg(int reg_idx) { - return readIntRegFlat(flattenIntIndex(reg_idx)); + return readIntRegFlat(flattenRegId(RegId(IntRegClass, + reg_idx)).index()); } virtual FloatReg readFloatReg(int reg_idx) { - return readFloatRegFlat(flattenFloatIndex(reg_idx)); + return readFloatRegFlat(flattenRegId(RegId(FloatRegClass, + reg_idx)).index()); } virtual FloatRegBits readFloatRegBits(int reg_idx) { - return readFloatRegBitsFlat(flattenFloatIndex(reg_idx)); + return readFloatRegBitsFlat(flattenRegId(RegId(FloatRegClass, + reg_idx)).index()); } virtual CCReg readCCReg(int reg_idx) { - return readCCRegFlat(flattenCCIndex(reg_idx)); + return readCCRegFlat(flattenRegId(RegId(CCRegClass, + reg_idx)).index()); } /** Sets an integer register to a value. */ virtual void setIntReg(int reg_idx, uint64_t val) { - setIntRegFlat(flattenIntIndex(reg_idx), val); + setIntRegFlat(flattenRegId(RegId(IntRegClass, reg_idx)).index(), val); } virtual void setFloatReg(int reg_idx, FloatReg val) { - setFloatRegFlat(flattenFloatIndex(reg_idx), val); + setFloatRegFlat(flattenRegId(RegId(FloatRegClass, + reg_idx)).index(), val); } virtual void setFloatRegBits(int reg_idx, FloatRegBits val) { - setFloatRegBitsFlat(flattenFloatIndex(reg_idx), val); + setFloatRegBitsFlat(flattenRegId(RegId(FloatRegClass, + reg_idx)).index(), val); } virtual void setCCReg(int reg_idx, CCReg val) { - setCCRegFlat(flattenCCIndex(reg_idx), val); + setCCRegFlat(flattenRegId(RegId(CCRegClass, reg_idx)).index(), val); } /** Reads this thread's PC state. */ @@ -245,10 +255,7 @@ class O3ThreadContext : public ThreadContext * write might have as defined by the architecture. */ virtual void setMiscReg(int misc_reg, const MiscReg &val); - virtual int flattenIntIndex(int reg); - virtual int flattenFloatIndex(int reg); - virtual int flattenCCIndex(int reg); - virtual int flattenMiscIndex(int reg); + virtual RegId flattenRegId(const RegId& regId) const; /** Returns the number of consecutive store conditional failures. */ // @todo: Figure out where these store cond failures should go. diff --git a/src/cpu/o3/thread_context_impl.hh b/src/cpu/o3/thread_context_impl.hh index e6a3d5083..c3f894275 100755 --- a/src/cpu/o3/thread_context_impl.hh +++ b/src/cpu/o3/thread_context_impl.hh @@ -270,31 +270,10 @@ O3ThreadContext<Impl>::pcStateNoRecord(const TheISA::PCState &val) } template <class Impl> -int -O3ThreadContext<Impl>::flattenIntIndex(int reg) +RegId +O3ThreadContext<Impl>::flattenRegId(const RegId& regId) const { - return cpu->isa[thread->threadId()]->flattenIntIndex(reg); -} - -template <class Impl> -int -O3ThreadContext<Impl>::flattenFloatIndex(int reg) -{ - return cpu->isa[thread->threadId()]->flattenFloatIndex(reg); -} - -template <class Impl> -int -O3ThreadContext<Impl>::flattenCCIndex(int reg) -{ - return cpu->isa[thread->threadId()]->flattenCCIndex(reg); -} - -template <class Impl> -int -O3ThreadContext<Impl>::flattenMiscIndex(int reg) -{ - return cpu->isa[thread->threadId()]->flattenMiscIndex(reg); + return cpu->isa[thread->threadId()]->flattenRegId(regId); } template <class Impl> diff --git a/src/cpu/reg_class.cc b/src/cpu/reg_class.cc index 75be4679d..53a50ce8e 100644 --- a/src/cpu/reg_class.cc +++ b/src/cpu/reg_class.cc @@ -30,11 +30,10 @@ #include "cpu/reg_class.hh" -const char *RegClassStrings[] = { +const char *RegId::regClassStrings[] = { "IntRegClass", "FloatRegClass", "CCRegClass", "MiscRegClass" }; -const RegId RegId::zeroReg = RegId(IntRegClass, TheISA::ZeroReg); diff --git a/src/cpu/reg_class.hh b/src/cpu/reg_class.hh index 25c882c58..05869e8fb 100644 --- a/src/cpu/reg_class.hh +++ b/src/cpu/reg_class.hh @@ -51,7 +51,7 @@ #include "arch/registers.hh" #include "config/the_isa.hh" -/// Enumerate the classes of registers. +/** Enumerate the classes of registers. */ enum RegClass { IntRegClass, ///< Integer register FloatRegClass, ///< Floating-point register @@ -59,54 +59,91 @@ enum RegClass { MiscRegClass ///< Control (misc) register }; -/// Number of register classes. This value is not part of the enum, -/// because putting it there makes the compiler complain about -/// unhandled cases in some switch statements. +/** Number of register classes. + * This value is not part of the enum, because putting it there makes the + * compiler complain about unhandled cases in some switch statements. + */ const int NumRegClasses = MiscRegClass + 1; -/// Register ID: describe an architectural register with its class and index. -/// This structure is used instead of just the register index to disambiguate -/// between different classes of registers. -/// For example, a integer register with index 3 is represented by -/// Regid(IntRegClass, 3). -struct RegId { +/** Register ID: describe an architectural register with its class and index. + * This structure is used instead of just the register index to disambiguate + * between different classes of registers. For example, a integer register with + * index 3 is represented by Regid(IntRegClass, 3). + */ +class RegId { + private: + static const char* regClassStrings[]; RegClass regClass; RegIndex regIdx; + public: RegId() {}; RegId(RegClass reg_class, RegIndex reg_idx) : regClass(reg_class), regIdx(reg_idx) {} bool operator==(const RegId& that) const { - return regClass == that.regClass && regIdx == that.regIdx; + return regClass == that.classValue() && regIdx == that.index(); } bool operator!=(const RegId& that) const { return !(*this==that); } - /** - * Returns true if this register is a zero register (needs to have a - * constant zero value throughout the execution) + /** Order operator. + * The order is required to implement maps with key type RegId */ - bool isZeroReg() const - { - return (regIdx == TheISA::ZeroReg && - (regClass == IntRegClass || - (THE_ISA == ALPHA_ISA && regClass == FloatRegClass))); + bool operator<(const RegId& that) const { + return regClass < that.classValue() || + (regClass == that.classValue() && regIdx < that.index()); } /** * Return true if this register can be renamed */ - bool isRenameable() + bool isRenameable() const { return regClass != MiscRegClass; } - static const RegId zeroReg; -}; + /** + * Check if this is the zero register. + * Returns true if this register is a zero register (needs to have a + * constant zero value throughout the execution). + */ + + inline bool isZeroReg() const; -/// Map enum values to strings for debugging -extern const char *RegClassStrings[]; + /** @return true if it is an integer physical register. */ + bool isIntReg() const { return regClass == IntRegClass; } + + /** @return true if it is a floating-point physical register. */ + bool isFloatReg() const { return regClass == FloatRegClass; } + + /** @Return true if it is a condition-code physical register. */ + bool isCCReg() const { return regClass == CCRegClass; } + + /** @Return true if it is a condition-code physical register. */ + bool isMiscReg() const { return regClass == MiscRegClass; } + + /** Index accessors */ + /** @{ */ + const RegIndex& index() const { return regIdx; } + RegIndex& index() { return regIdx; } + + /** Index flattening. + * Required to be able to use a vector for the register mapping. + */ + inline RegIndex flatIndex() const; + /** @} */ + + /** Class accessor */ + const RegClass& classValue() const { return regClass; } + /** Return a const char* with the register class name. */ + const char* className() const { return regClassStrings[regClass]; } + + friend std::ostream& + operator<<(std::ostream& os, const RegId& rid) { + return os << rid.className() << "{" << rid.index() << "}"; + } +}; #endif // __CPU__REG_CLASS_HH__ diff --git a/src/cpu/reg_class_impl.hh b/src/cpu/reg_class_impl.hh new file mode 100644 index 000000000..a47328b10 --- /dev/null +++ b/src/cpu/reg_class_impl.hh @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2016 ARM Limited + * All rights reserved + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Rekai Gonzalez + */ + +#ifndef __CPU__REG_CLASS_IMPL_HH__ +#define __CPU__REG_CLASS_IMPL_HH__ + +#include <cassert> +#include <cstddef> +#include <iostream> + +#include "arch/registers.hh" +#include "config/the_isa.hh" +#include "cpu/reg_class.hh" + +bool RegId::isZeroReg() const +{ + return ((regClass == IntRegClass && regIdx == TheISA::ZeroReg) || + (THE_ISA == ALPHA_ISA && regClass == FloatRegClass && + regIdx == TheISA::ZeroReg)); +} + +RegIndex RegId::flatIndex() const { + switch (regClass) { + case IntRegClass: + case FloatRegClass: + case CCRegClass: + case MiscRegClass: + return regIdx; + } + panic("Trying to flatten a register without class!"); + return -1; +} + +#endif // __CPU__REG_CLASS_IMPL_HH__ diff --git a/src/cpu/simple/exec_context.hh b/src/cpu/simple/exec_context.hh index 9689796f3..f221d6c93 100644 --- a/src/cpu/simple/exec_context.hh +++ b/src/cpu/simple/exec_context.hh @@ -165,27 +165,27 @@ class SimpleExecContext : public ExecContext { IntReg readIntRegOperand(const StaticInst *si, int idx) override { numIntRegReads++; - RegId reg = si->srcRegIdx(idx); - assert(reg.regClass == IntRegClass); - return thread->readIntReg(reg.regIdx); + const RegId& reg = si->srcRegIdx(idx); + assert(reg.isIntReg()); + return thread->readIntReg(reg.index()); } /** Sets an integer register to a value. */ void setIntRegOperand(const StaticInst *si, int idx, IntReg val) override { numIntRegWrites++; - RegId reg = si->destRegIdx(idx); - assert(reg.regClass == IntRegClass); - thread->setIntReg(reg.regIdx, val); + const RegId& reg = si->destRegIdx(idx); + assert(reg.isIntReg()); + thread->setIntReg(reg.index(), val); } /** Reads a floating point register of single register width. */ FloatReg readFloatRegOperand(const StaticInst *si, int idx) override { numFpRegReads++; - RegId reg = si->srcRegIdx(idx); - assert(reg.regClass == FloatRegClass); - return thread->readFloatReg(reg.regIdx); + const RegId& reg = si->srcRegIdx(idx); + assert(reg.isFloatReg()); + return thread->readFloatReg(reg.index()); } /** Reads a floating point register in its binary format, instead @@ -193,9 +193,9 @@ class SimpleExecContext : public ExecContext { FloatRegBits readFloatRegOperandBits(const StaticInst *si, int idx) override { numFpRegReads++; - RegId reg = si->srcRegIdx(idx); - assert(reg.regClass == FloatRegClass); - return thread->readFloatRegBits(reg.regIdx); + const RegId& reg = si->srcRegIdx(idx); + assert(reg.isFloatReg()); + return thread->readFloatRegBits(reg.index()); } /** Sets a floating point register of single width to a value. */ @@ -203,9 +203,9 @@ class SimpleExecContext : public ExecContext { FloatReg val) override { numFpRegWrites++; - RegId reg = si->destRegIdx(idx); - assert(reg.regClass == FloatRegClass); - thread->setFloatReg(reg.regIdx, val); + const RegId& reg = si->destRegIdx(idx); + assert(reg.isFloatReg()); + thread->setFloatReg(reg.index(), val); } /** Sets the bits of a floating point register of single width @@ -214,42 +214,42 @@ class SimpleExecContext : public ExecContext { FloatRegBits val) override { numFpRegWrites++; - RegId reg = si->destRegIdx(idx); - assert(reg.regClass == FloatRegClass); - thread->setFloatRegBits(reg.regIdx, val); + const RegId& reg = si->destRegIdx(idx); + assert(reg.isFloatReg()); + thread->setFloatRegBits(reg.index(), val); } CCReg readCCRegOperand(const StaticInst *si, int idx) override { numCCRegReads++; - RegId reg = si->srcRegIdx(idx); - assert(reg.regClass == CCRegClass); - return thread->readCCReg(reg.regIdx); + const RegId& reg = si->srcRegIdx(idx); + assert(reg.isCCReg()); + return thread->readCCReg(reg.index()); } void setCCRegOperand(const StaticInst *si, int idx, CCReg val) override { numCCRegWrites++; - RegId reg = si->destRegIdx(idx); - assert(reg.regClass == CCRegClass); - thread->setCCReg(reg.regIdx, val); + const RegId& reg = si->destRegIdx(idx); + assert(reg.isCCReg()); + thread->setCCReg(reg.index(), val); } MiscReg readMiscRegOperand(const StaticInst *si, int idx) override { numIntRegReads++; - RegId reg = si->srcRegIdx(idx); - assert(reg.regClass == MiscRegClass); - return thread->readMiscReg(reg.regIdx); + const RegId& reg = si->srcRegIdx(idx); + assert(reg.isMiscReg()); + return thread->readMiscReg(reg.index()); } void setMiscRegOperand(const StaticInst *si, int idx, const MiscReg &val) override { numIntRegWrites++; - RegId reg = si->destRegIdx(idx); - assert(reg.regClass == MiscRegClass); - thread->setMiscReg(reg.regIdx, val); + const RegId& reg = si->destRegIdx(idx); + assert(reg.isMiscReg()); + thread->setMiscReg(reg.index(), val); } /** @@ -411,14 +411,15 @@ class SimpleExecContext : public ExecContext { } #if THE_ISA == MIPS_ISA - MiscReg readRegOtherThread(RegId reg, ThreadID tid = InvalidThreadID) + MiscReg readRegOtherThread(const RegId& reg, + ThreadID tid = InvalidThreadID) override { panic("Simple CPU models do not support multithreaded " "register access."); } - void setRegOtherThread(RegId reg, MiscReg val, + void setRegOtherThread(const RegId& reg, MiscReg val, ThreadID tid = InvalidThreadID) override { panic("Simple CPU models do not support multithreaded " diff --git a/src/cpu/simple_thread.hh b/src/cpu/simple_thread.hh index bdf93b0e4..286d91766 100644 --- a/src/cpu/simple_thread.hh +++ b/src/cpu/simple_thread.hh @@ -401,28 +401,10 @@ class SimpleThread : public ThreadState return isa->setMiscReg(misc_reg, val, tc); } - int - flattenIntIndex(int reg) + RegId + flattenRegId(const RegId& regId) const { - return isa->flattenIntIndex(reg); - } - - int - flattenFloatIndex(int reg) - { - return isa->flattenFloatIndex(reg); - } - - int - flattenCCIndex(int reg) - { - return isa->flattenCCIndex(reg); - } - - int - flattenMiscIndex(int reg) - { - return isa->flattenMiscIndex(reg); + return isa->flattenRegId(regId); } unsigned readStCondFailures() { return storeCondFailures; } diff --git a/src/cpu/static_inst.hh b/src/cpu/static_inst.hh index 751301095..d60afc019 100644 --- a/src/cpu/static_inst.hh +++ b/src/cpu/static_inst.hh @@ -43,6 +43,7 @@ #include "config/the_isa.hh" #include "cpu/op_class.hh" #include "cpu/reg_class.hh" +#include "cpu/reg_class_impl.hh" #include "cpu/static_inst_fwd.hh" #include "cpu/thread_context.hh" #include "enums/StaticInstFlags.hh" @@ -184,11 +185,11 @@ class StaticInst : public RefCounted, public StaticInstFlags /// Return logical index (architectural reg num) of i'th destination reg. /// Only the entries from 0 through numDestRegs()-1 are valid. - RegId destRegIdx(int i) const { return _destRegIdx[i]; } + const RegId& destRegIdx(int i) const { return _destRegIdx[i]; } /// Return logical index (architectural reg num) of i'th source reg. /// Only the entries from 0 through numSrcRegs()-1 are valid. - RegId srcRegIdx(int i) const { return _srcRegIdx[i]; } + const RegId& srcRegIdx(int i) const { return _srcRegIdx[i]; } /// Pointer to a statically allocated "null" instruction object. /// Used to give eaCompInst() and memAccInst() something to return diff --git a/src/cpu/thread_context.hh b/src/cpu/thread_context.hh index efa0b2162..43c40481e 100644 --- a/src/cpu/thread_context.hh +++ b/src/cpu/thread_context.hh @@ -250,19 +250,16 @@ class ThreadContext virtual void setMiscReg(int misc_reg, const MiscReg &val) = 0; - virtual int flattenIntIndex(int reg) = 0; - virtual int flattenFloatIndex(int reg) = 0; - virtual int flattenCCIndex(int reg) = 0; - virtual int flattenMiscIndex(int reg) = 0; + virtual RegId flattenRegId(const RegId& regId) const = 0; virtual uint64_t - readRegOtherThread(RegId misc_reg, ThreadID tid) + readRegOtherThread(const RegId& misc_reg, ThreadID tid) { return 0; } virtual void - setRegOtherThread(RegId misc_reg, const MiscReg &val, ThreadID tid) + setRegOtherThread(const RegId& misc_reg, const MiscReg &val, ThreadID tid) { } @@ -291,7 +288,7 @@ class ThreadContext * * Some architectures have different registers visible in * different modes. Such architectures "flatten" a register (see - * flattenIntIndex() and flattenFloatIndex()) to map it into the + * flattenRegId()) to map it into the * gem5 register file. This interface provides a flat interface to * the underlying register file, which allows for example * serialization code to access all registers. @@ -466,17 +463,8 @@ class ProxyThreadContext : public ThreadContext void setMiscReg(int misc_reg, const MiscReg &val) { return actualTC->setMiscReg(misc_reg, val); } - int flattenIntIndex(int reg) - { return actualTC->flattenIntIndex(reg); } - - int flattenFloatIndex(int reg) - { return actualTC->flattenFloatIndex(reg); } - - int flattenCCIndex(int reg) - { return actualTC->flattenCCIndex(reg); } - - int flattenMiscIndex(int reg) - { return actualTC->flattenMiscIndex(reg); } + RegId flattenRegId(const RegId& regId) const + { return actualTC->flattenRegId(regId); } unsigned readStCondFailures() { return actualTC->readStCondFailures(); } diff --git a/src/cpu/timing_expr.cc b/src/cpu/timing_expr.cc index 99b4eb6aa..da5c6489e 100644 --- a/src/cpu/timing_expr.cc +++ b/src/cpu/timing_expr.cc @@ -58,7 +58,7 @@ TimingExprEvalContext::TimingExprEvalContext(const StaticInstPtr &inst_, uint64_t TimingExprSrcReg::eval(TimingExprEvalContext &context) { - return context.inst->srcRegIdx(index).regIdx; + return context.inst->srcRegIdx(index).index(); } uint64_t TimingExprReadIntReg::eval(TimingExprEvalContext &context) |