#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"
void serialize(CheckpointOut &cp) const override;
void unserialize(CheckpointIn &cp) override;
+ RegId flattenRegId(const RegId& regId) const { return regId; }
+
int
flattenIntIndex(int reg) const
{
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;
}
#ifndef SS_COMPATIBLE_DISASSEMBLY
std::string suffix("");
- suffix += ((_destRegIdx[0].regClass == FloatRegClass)
+ suffix += ((_destRegIdx[0].isFloatReg())
? fpTrappingModeSuffix[trappingMode]
: intTrappingModeSuffix[trappingMode]);
suffix += roundingModeSuffix[roundingMode];
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());
}
}
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;
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 {
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
{
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
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
''')
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;
'''
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);
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,
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,
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;
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) {
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) {
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;
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;
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);
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);
#include "arch/mips/registers.hh"
#include "arch/mips/types.hh"
+#include "cpu/reg_class.hh"
#include "sim/eventq.hh"
#include "sim/sim_object.hh"
ISA(Params *p);
+ RegId flattenRegId(const RegId& regId) const { return regId; }
+
int
flattenIntIndex(int reg) const
{
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());
}
}
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]);
}
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]);
}
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]);
}
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;
}
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;
default: ccprintf(os, "unknown_reg");
break;
}
- case CCRegClass:
+ else if (reg.isCCReg())
panic("printReg: POWER does not implement CCRegClass\n");
- }
}
std::string
#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;
fatal("Power does not currently have any misc regs defined\n");
}
+ RegId flattenRegId(const RegId& regId) const { return regId; }
+
int
flattenIntIndex(int reg) const
{
#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;
void
setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc);
+ RegId
+ flattenRegId(const RegId ®Id) const
+ {
+ return regId;
+ }
+
int
flattenIntIndex(int reg) const
{
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());
}
}
}};
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;
}
#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;
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
{
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)
break;
}
}
- } else if (reg.regClass == FloatRegClass) {
+ } else if (reg.isFloatReg()) {
ccprintf(os, "%%f%d", reg_idx);
} else {
switch (reg_idx) {
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, ", ");
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 {
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, " + ");
}
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, " + ");
}
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, ", ");
}
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, ", ");
}
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)
{}
/*
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 =
_scale, _index, _base, _disp, _segment,
_dataSize, _addressSize, _memFlags,
__opClass),
- data(_data.regIdx)
+ data(_data.index())
{
}
_scale, _index, _base, _disp, _segment,
_dataSize, _addressSize, _memFlags,
__opClass),
- dataLow(_dataLow.regIdx),
- dataHi(_dataHi.regIdx)
+ dataLow(_dataLow.index()),
+ dataHi(_dataHi.index())
{
}
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)
{}
MediaOpBase(_machInst, mnem, _instMnem, setFlags,
_src1, _dest, _srcSize, _destSize, _ext,
__opClass),
- src2(_src2.regIdx)
+ src2(_src2.index())
{}
std::string generateDisassembly(Addr pc,
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;
RegOpBase(_machInst, mnem, _instMnem, setFlags,
_src1, _dest, _dataSize, _ext,
__opClass),
- src2(_src2.regIdx)
+ src2(_src2.index())
{
}
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;
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;
}
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;
}
}
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;
{
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)
{
{
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)
{
#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;
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
{
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;
/** 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];
}
/** 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;
}
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>
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>
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);
}
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");
}
// 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...
}
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(); }
*/
#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
/** 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
}
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());
}
}
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
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
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
/* 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());
}
}
{
bool
-Scoreboard::findIndex(RegId reg, Index &scoreboard_index)
+Scoreboard::findIndex(const RegId& reg, Index &scoreboard_index)
{
bool ret = false;
/* 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:
/** 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
*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);
}
}
}
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)) {
/** 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
#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
*/
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
// 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);
}
}
//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);
// 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);
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);
}
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);
}
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);
}
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);
}
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);
}
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);
}
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);
}
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);
}
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;
*/
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
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. */
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));
}
#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");
}
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;
break;
default:
panic("Unexpected RegClass (%s)",
- RegClassStrings[freed_reg->regClass]);
+ freed_reg->className());
}
// These assert conditions ensure that the number of free
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));
}
// 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] "
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;
}
if (!squashed_inst->isReadySrcRegIdx(src_reg_idx) &&
!src_reg->isFixedMapping()) {
- dependGraph.remove(src_reg->flatIdx, squashed_inst);
+ dependGraph.remove(src_reg->flatIndex(),
+ squashed_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.
} 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);
}
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;
}
}
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
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(),
// 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]);
}
}
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). */
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;
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. */
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. */
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)
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. */
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;
}
};
* 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),
/*
- * 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.
*
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
// 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;
// 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);
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++;
}
#include <vector>
+#include "cpu/reg_class_impl.hh"
#include "debug/Rename.hh"
using namespace std;
/**** SimpleRenameMap methods ****/
SimpleRenameMap::SimpleRenameMap()
- : freeList(NULL), zeroReg(0)
+ : freeList(NULL), zeroReg(IntRegClass,0)
{
}
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());
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);
}
}
-
-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]);
- }
-}
/*
- * 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
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
* table, it should be set to an invalid index so that it never
* matches.
*/
- RegIndex zeroReg;
+ RegId zeroReg;
public:
* @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()];
}
/**
* @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. */
/**
* 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
* @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());
+ }
}
/**
* @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());
+ }
}
/**
/** 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);
/** 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
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
if (phys_reg->isZeroReg())
return;
- regScoreBoard[phys_reg->flatIdx] = false;
+ regScoreBoard[phys_reg->flatIndex()] = false;
}
};
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. */
* 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.
}
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>
#include "cpu/reg_class.hh"
-const char *RegClassStrings[] = {
+const char *RegId::regClassStrings[] = {
"IntRegClass",
"FloatRegClass",
"CCRegClass",
"MiscRegClass"
};
-const RegId RegId::zeroReg = RegId(IntRegClass, TheISA::ZeroReg);
#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
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__
--- /dev/null
+/*
+ * 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__
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
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. */
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
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);
}
/**
}
#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 "
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; }
#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"
/// 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
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)
{
}
*
* 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.
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(); }
uint64_t TimingExprSrcReg::eval(TimingExprEvalContext &context)
{
- return context.inst->srcRegIdx(index).regIdx;
+ return context.inst->srcRegIdx(index).index();
}
uint64_t TimingExprReadIntReg::eval(TimingExprEvalContext &context)