arch,cpu: Keep a RegClass pointer in RegId instead of a RegClassType.
This makes it easy to get access to the RegClass that goes with a register without having to look it up in a separate structure. Change-Id: I4cfff2069d63f3c1c3fb0fea5dee3baf357bd478 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/49786 Maintainer: Giacomo Travaglini <giacomo.travaglini@arm.com> Reviewed-by: Giacomo Travaglini <giacomo.travaglini@arm.com> Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
@@ -103,7 +103,7 @@ let {{
|
||||
@overrideInOperand
|
||||
def regId(self):
|
||||
return f'gem5::ArmISA::couldBeZero({self.reg_spec}) ? RegId() : ' \
|
||||
f'RegId({self.reg_class}, {self.reg_spec})'
|
||||
f'{self.reg_class}[{self.reg_spec}]'
|
||||
def __init__(self, idx, ctype='uw', id=srtNormal):
|
||||
super().__init__(ctype, idx, 'IsInteger', id)
|
||||
|
||||
@@ -172,7 +172,7 @@ let {{
|
||||
@overrideInOperand
|
||||
def regId(self):
|
||||
return f'gem5::ArmISA::couldBeZero({self.reg_spec}) ? RegId() : ' \
|
||||
f'RegId({self.reg_class}, {self.reg_spec})'
|
||||
f'{self.reg_class}[{self.reg_spec}]'
|
||||
@overrideInOperand
|
||||
def makeRead(self):
|
||||
'''aarch64 read'''
|
||||
|
||||
@@ -158,36 +158,33 @@ TarmacTracerRecord::TraceRegEntry::TraceRegEntry(
|
||||
const RegId& reg)
|
||||
: RegEntry(*tarmCtx.pc),
|
||||
regValid(false),
|
||||
regClass(reg.classValue()),
|
||||
regRel(reg.index())
|
||||
regId(reg)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
TarmacTracerRecord::TraceRegEntry::update(
|
||||
const TarmacContext& tarmCtx
|
||||
)
|
||||
TarmacTracerRecord::TraceRegEntry::update(const TarmacContext& tarmCtx)
|
||||
{
|
||||
// Fill the register entry data, according to register
|
||||
// class.
|
||||
switch (regClass) {
|
||||
switch (regId.classValue()) {
|
||||
case CCRegClass:
|
||||
updateCC(tarmCtx, regRel);
|
||||
updateCC(tarmCtx);
|
||||
break;
|
||||
case FloatRegClass:
|
||||
updateFloat(tarmCtx, regRel);
|
||||
updateFloat(tarmCtx);
|
||||
break;
|
||||
case IntRegClass:
|
||||
updateInt(tarmCtx, regRel);
|
||||
updateInt(tarmCtx);
|
||||
break;
|
||||
case MiscRegClass:
|
||||
updateMisc(tarmCtx, regRel);
|
||||
updateMisc(tarmCtx);
|
||||
break;
|
||||
case VecRegClass:
|
||||
updateVec(tarmCtx, regRel);
|
||||
updateVec(tarmCtx);
|
||||
break;
|
||||
case VecPredRegClass:
|
||||
updatePred(tarmCtx, regRel);
|
||||
updatePred(tarmCtx);
|
||||
break;
|
||||
default:
|
||||
// If unsupported format, do nothing: non updating
|
||||
@@ -197,21 +194,18 @@ TarmacTracerRecord::TraceRegEntry::update(
|
||||
}
|
||||
|
||||
void
|
||||
TarmacTracerRecord::TraceRegEntry::updateMisc(
|
||||
const TarmacContext& tarmCtx,
|
||||
RegIndex regRelIdx
|
||||
)
|
||||
TarmacTracerRecord::TraceRegEntry::updateMisc(const TarmacContext& tarmCtx)
|
||||
{
|
||||
auto thread = tarmCtx.thread;
|
||||
|
||||
regValid = true;
|
||||
regName = miscRegName[regRelIdx];
|
||||
values[Lo] = thread->readMiscRegNoEffect(regRelIdx);
|
||||
regName = miscRegName[regId.index()];
|
||||
values[Lo] = thread->readMiscRegNoEffect(regId.index());
|
||||
|
||||
// If it is the CPSR:
|
||||
// update the value of the CPSR register and add
|
||||
// the CC flags on top of the value
|
||||
if (regRelIdx == MISCREG_CPSR) {
|
||||
if (regId.index() == MISCREG_CPSR) {
|
||||
CPSR cpsr = thread->readMiscRegNoEffect(MISCREG_CPSR);
|
||||
cpsr.nz = thread->getReg(cc_reg::Nz);
|
||||
cpsr.c = thread->getReg(cc_reg::C);
|
||||
@@ -224,34 +218,25 @@ TarmacTracerRecord::TraceRegEntry::updateMisc(
|
||||
}
|
||||
|
||||
void
|
||||
TarmacTracerRecord::TraceRegEntry::updateCC(
|
||||
const TarmacContext& tarmCtx,
|
||||
RegIndex regRelIdx
|
||||
)
|
||||
TarmacTracerRecord::TraceRegEntry::updateCC(const TarmacContext& tarmCtx)
|
||||
{
|
||||
auto thread = tarmCtx.thread;
|
||||
|
||||
regValid = true;
|
||||
regName = cc_reg::RegName[regRelIdx];
|
||||
values[Lo] = thread->getReg(ccRegClass[regRelIdx]);
|
||||
regName = cc_reg::RegName[regId.index()];
|
||||
values[Lo] = thread->getReg(regId);
|
||||
}
|
||||
|
||||
void
|
||||
TarmacTracerRecord::TraceRegEntry::updateFloat(
|
||||
const TarmacContext& tarmCtx,
|
||||
RegIndex regRelIdx
|
||||
)
|
||||
TarmacTracerRecord::TraceRegEntry::updateFloat(const TarmacContext& tarmCtx)
|
||||
{
|
||||
regValid = true;
|
||||
regName = "f" + std::to_string(regRelIdx);
|
||||
regName = "f" + std::to_string(regId.index());
|
||||
panic("ARM doesn't support float registers.");
|
||||
}
|
||||
|
||||
void
|
||||
TarmacTracerRecord::TraceRegEntry::updateInt(
|
||||
const TarmacContext& tarmCtx,
|
||||
RegIndex regRelIdx
|
||||
)
|
||||
TarmacTracerRecord::TraceRegEntry::updateInt(const TarmacContext& tarmCtx)
|
||||
{
|
||||
auto thread = tarmCtx.thread;
|
||||
|
||||
@@ -267,7 +252,7 @@ TarmacTracerRecord::TraceRegEntry::updateInt(
|
||||
}
|
||||
|
||||
regValid = true;
|
||||
switch (regRelIdx) {
|
||||
switch (regId.index()) {
|
||||
case int_reg::Pc:
|
||||
regName = "pc";
|
||||
break;
|
||||
@@ -281,10 +266,10 @@ TarmacTracerRecord::TraceRegEntry::updateInt(
|
||||
regName = "lr" + reg_suffix;
|
||||
break;
|
||||
default:
|
||||
regName = "r" + std::to_string(regRelIdx);
|
||||
regName = "r" + std::to_string(regId.index());
|
||||
break;
|
||||
}
|
||||
values[Lo] = thread->getReg(intRegClass[regRelIdx]);
|
||||
values[Lo] = thread->getReg(regId);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -140,31 +140,18 @@ class TarmacTracerRecord : public TarmacBaseRecord
|
||||
|
||||
protected:
|
||||
/** Register update functions. */
|
||||
virtual void
|
||||
updateMisc(const TarmacContext& tarmCtx, RegIndex regRelIdx);
|
||||
|
||||
virtual void
|
||||
updateCC(const TarmacContext& tarmCtx, RegIndex regRelIdx);
|
||||
|
||||
virtual void
|
||||
updateFloat(const TarmacContext& tarmCtx, RegIndex regRelIdx);
|
||||
|
||||
virtual void
|
||||
updateInt(const TarmacContext& tarmCtx, RegIndex regRelIdx);
|
||||
|
||||
virtual void
|
||||
updateVec(const TarmacContext& tarmCtx, RegIndex regRelIdx) {};
|
||||
|
||||
virtual void
|
||||
updatePred(const TarmacContext& tarmCtx, RegIndex regRelIdx) {};
|
||||
virtual void updateMisc(const TarmacContext& tarmCtx);
|
||||
virtual void updateCC(const TarmacContext& tarmCtx);
|
||||
virtual void updateFloat(const TarmacContext& tarmCtx);
|
||||
virtual void updateInt(const TarmacContext& tarmCtx);
|
||||
virtual void updateVec(const TarmacContext& tarmCtx) {};
|
||||
virtual void updatePred(const TarmacContext& tarmCtx) {};
|
||||
|
||||
public:
|
||||
/** True if register entry is valid */
|
||||
bool regValid;
|
||||
/** Register class */
|
||||
RegClassType regClass;
|
||||
/** Register arch number */
|
||||
RegIndex regRel;
|
||||
/** Register ID */
|
||||
RegId regId;
|
||||
/** Register name to be printed */
|
||||
std::string regName;
|
||||
};
|
||||
@@ -229,7 +216,9 @@ class TarmacTracerRecord : public TarmacBaseRecord
|
||||
// Find all CC Entries and move them at the end of the queue
|
||||
auto it = std::remove_if(
|
||||
queue.begin(), queue.end(),
|
||||
[] (RegPtr& reg) ->bool { return (reg->regClass == CCRegClass); }
|
||||
[] (RegPtr& reg) ->bool {
|
||||
return (reg->regId.classValue() == CCRegClass);
|
||||
}
|
||||
);
|
||||
|
||||
if (it != queue.end()) {
|
||||
@@ -238,8 +227,8 @@ class TarmacTracerRecord : public TarmacBaseRecord
|
||||
|
||||
auto is_cpsr = [] (RegPtr& reg) ->bool
|
||||
{
|
||||
return (reg->regClass == MiscRegClass) &&
|
||||
(reg->regRel == ArmISA::MISCREG_CPSR);
|
||||
return (reg->regId.classValue()== MiscRegClass) &&
|
||||
(reg->regId.index() == ArmISA::MISCREG_CPSR);
|
||||
};
|
||||
|
||||
// Looking for the presence of a CPSR register entry.
|
||||
|
||||
@@ -90,22 +90,19 @@ TarmacTracerRecordV8::TraceRegEntryV8::TraceRegEntryV8(
|
||||
}
|
||||
|
||||
void
|
||||
TarmacTracerRecordV8::TraceRegEntryV8::updateInt(
|
||||
const TarmacContext& tarmCtx,
|
||||
RegIndex regRelIdx
|
||||
)
|
||||
TarmacTracerRecordV8::TraceRegEntryV8::updateInt(const TarmacContext& tarmCtx)
|
||||
{
|
||||
// Do not trace pseudo register accesses: invalid
|
||||
// register entry.
|
||||
if (regRelIdx > int_reg::NumArchRegs) {
|
||||
if (regId.index() > int_reg::NumArchRegs) {
|
||||
regValid = false;
|
||||
return;
|
||||
}
|
||||
|
||||
TraceRegEntry::updateInt(tarmCtx, regRelIdx);
|
||||
TraceRegEntry::updateInt(tarmCtx);
|
||||
|
||||
if ((regRelIdx != int_reg::Pc) || (regRelIdx != StackPointerReg) ||
|
||||
(regRelIdx != FramePointerReg) || (regRelIdx != ReturnAddressReg)) {
|
||||
if ((regId != int_reg::Pc) || (regId != StackPointerReg) ||
|
||||
(regId != FramePointerReg) || (regId != ReturnAddressReg)) {
|
||||
|
||||
const auto* arm_inst = static_cast<const ArmStaticInst*>(
|
||||
tarmCtx.staticInst.get()
|
||||
@@ -113,33 +110,27 @@ TarmacTracerRecordV8::TraceRegEntryV8::updateInt(
|
||||
|
||||
regWidth = (arm_inst->getIntWidth());
|
||||
if (regWidth == 32) {
|
||||
regName = "W" + std::to_string(regRelIdx);
|
||||
regName = "W" + std::to_string(regId.index());
|
||||
} else {
|
||||
regName = "X" + std::to_string(regRelIdx);
|
||||
regName = "X" + std::to_string(regId.index());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TarmacTracerRecordV8::TraceRegEntryV8::updateMisc(
|
||||
const TarmacContext& tarmCtx,
|
||||
RegIndex regRelIdx
|
||||
)
|
||||
TarmacTracerRecordV8::TraceRegEntryV8::updateMisc(const TarmacContext& tarmCtx)
|
||||
{
|
||||
TraceRegEntry::updateMisc(tarmCtx, regRelIdx);
|
||||
TraceRegEntry::updateMisc(tarmCtx);
|
||||
// System registers are 32bit wide
|
||||
regWidth = 32;
|
||||
}
|
||||
|
||||
void
|
||||
TarmacTracerRecordV8::TraceRegEntryV8::updateVec(
|
||||
const TarmacContext& tarmCtx,
|
||||
RegIndex regRelIdx
|
||||
)
|
||||
TarmacTracerRecordV8::TraceRegEntryV8::updateVec(const TarmacContext& tarmCtx)
|
||||
{
|
||||
auto thread = tarmCtx.thread;
|
||||
ArmISA::VecRegContainer vec_container;
|
||||
thread->getReg(RegId(regClass, regRelIdx), &vec_container);
|
||||
thread->getReg(regId, &vec_container);
|
||||
auto vv = vec_container.as<VecElem>();
|
||||
|
||||
regWidth = ArmStaticInst::getCurSveVecLenInBits(thread);
|
||||
@@ -153,18 +144,15 @@ TarmacTracerRecordV8::TraceRegEntryV8::updateVec(
|
||||
}
|
||||
|
||||
regValid = true;
|
||||
regName = "Z" + std::to_string(regRelIdx);
|
||||
regName = "Z" + std::to_string(regId.index());
|
||||
}
|
||||
|
||||
void
|
||||
TarmacTracerRecordV8::TraceRegEntryV8::updatePred(
|
||||
const TarmacContext& tarmCtx,
|
||||
RegIndex regRelIdx
|
||||
)
|
||||
TarmacTracerRecordV8::TraceRegEntryV8::updatePred(const TarmacContext& tarmCtx)
|
||||
{
|
||||
auto thread = tarmCtx.thread;
|
||||
ArmISA::VecPredRegContainer pred_container;
|
||||
thread->getReg(RegId(regClass, regRelIdx), &pred_container);
|
||||
thread->getReg(regId, &pred_container);
|
||||
|
||||
// Predicate registers are always 1/8 the size of related vector
|
||||
// registers. (getCurSveVecLenInBits(thread) / 8)
|
||||
@@ -181,7 +169,7 @@ TarmacTracerRecordV8::TraceRegEntryV8::updatePred(
|
||||
}
|
||||
|
||||
regValid = true;
|
||||
regName = "P" + std::to_string(regRelIdx);
|
||||
regName = "P" + std::to_string(regId.index());
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -103,17 +103,10 @@ class TarmacTracerRecordV8 : public TarmacTracerRecord
|
||||
const std::string &prefix = "") const override;
|
||||
|
||||
protected:
|
||||
void updateInt(const TarmacContext& tarmCtx,
|
||||
RegIndex regRelIdx) override;
|
||||
|
||||
void updateMisc(const TarmacContext& tarmCtx,
|
||||
RegIndex regRelIdx) override;
|
||||
|
||||
void updateVec(const TarmacContext& tarmCtx,
|
||||
RegIndex regRelIdx) override;
|
||||
|
||||
void updatePred(const TarmacContext& tarmCtx,
|
||||
RegIndex regRelIdx) override;
|
||||
void updateInt(const TarmacContext& tarmCtx) override;
|
||||
void updateMisc(const TarmacContext& tarmCtx) override;
|
||||
void updateVec(const TarmacContext& tarmCtx) override;
|
||||
void updatePred(const TarmacContext& tarmCtx) override;
|
||||
|
||||
/**
|
||||
* Returning a string which contains the formatted
|
||||
|
||||
@@ -1354,7 +1354,7 @@ syncVecElemsToRegs(ThreadContext *tc)
|
||||
for (int ri = 0; ri < NumVecRegs; ri++) {
|
||||
VecRegContainer reg;
|
||||
for (int j = 0; j < NumVecElemPerVecReg; j++, ei++) {
|
||||
RegId elem_id(VecElemClass, ei);
|
||||
RegId elem_id = vecElemClass[ei];
|
||||
reg.as<VecElem>()[j] = tc->getReg(elem_id);
|
||||
}
|
||||
tc->setReg(vecRegClass[ri], ®);
|
||||
|
||||
@@ -114,7 +114,7 @@ class Operand(object):
|
||||
dst_reg_constructor = '\n\tsetDestRegIdx(_numDestRegs++, %s);'
|
||||
|
||||
def regId(self):
|
||||
return f'RegId({self.reg_class}, {self.reg_spec})'
|
||||
return f'{self.reg_class}[{self.reg_spec}]'
|
||||
|
||||
def srcRegId(self):
|
||||
return self.regId()
|
||||
@@ -201,7 +201,7 @@ class RegOperand(Operand):
|
||||
|
||||
if self.is_dest:
|
||||
c_dest = self.dst_reg_constructor % self.destRegId()
|
||||
c_dest += f'\n\t_numTypedDestRegs[{self.reg_class}]++;'
|
||||
c_dest += f'\n\t_numTypedDestRegs[{self.reg_class}.type()]++;'
|
||||
|
||||
return c_src + c_dest
|
||||
|
||||
@@ -240,22 +240,22 @@ class RegOperandDesc(OperandDesc):
|
||||
|
||||
class IntRegOperandDesc(RegOperandDesc):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__('IntRegClass', RegValOperand, *args, **kwargs)
|
||||
super().__init__('intRegClass', RegValOperand, *args, **kwargs)
|
||||
|
||||
class FloatRegOperandDesc(RegOperandDesc):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__('FloatRegClass', RegValOperand, *args, **kwargs)
|
||||
super().__init__('floatRegClass', RegValOperand, *args, **kwargs)
|
||||
|
||||
class CCRegOperandDesc(RegOperandDesc):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__('CCRegClass', RegValOperand, *args, **kwargs)
|
||||
super().__init__('ccRegClass', RegValOperand, *args, **kwargs)
|
||||
|
||||
class VecElemOperandDesc(RegOperandDesc):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__('VecElemClass', RegValOperand, *args, **kwargs)
|
||||
super().__init__('vecElemClass', RegValOperand, *args, **kwargs)
|
||||
|
||||
class VecRegOperand(RegOperand):
|
||||
reg_class = 'VecRegClass'
|
||||
reg_class = 'vecRegClass'
|
||||
|
||||
def __init__(self, parser, full_name, ext, is_src, is_dest):
|
||||
super().__init__(parser, full_name, ext, is_src, is_dest)
|
||||
@@ -365,10 +365,10 @@ class VecRegOperand(RegOperand):
|
||||
|
||||
class VecRegOperandDesc(RegOperandDesc):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__('VecRegClass', VecRegOperand, *args, **kwargs)
|
||||
super().__init__('vecRegClass', VecRegOperand, *args, **kwargs)
|
||||
|
||||
class VecPredRegOperand(RegOperand):
|
||||
reg_class = 'VecPredRegClass'
|
||||
reg_class = 'vecPredRegClass'
|
||||
|
||||
def makeDecl(self):
|
||||
return ''
|
||||
@@ -409,10 +409,10 @@ class VecPredRegOperand(RegOperand):
|
||||
|
||||
class VecPredRegOperandDesc(RegOperandDesc):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__('VecPredRegClass', VecPredRegOperand, *args, **kwargs)
|
||||
super().__init__('vecPredRegClass', VecPredRegOperand, *args, **kwargs)
|
||||
|
||||
class ControlRegOperand(Operand):
|
||||
reg_class = 'MiscRegClass'
|
||||
reg_class = 'miscRegClass'
|
||||
|
||||
def isReg(self):
|
||||
return 1
|
||||
@@ -455,7 +455,7 @@ class ControlRegOperand(Operand):
|
||||
|
||||
class ControlRegOperandDesc(RegOperandDesc):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__('MiscRegClass', ControlRegOperand, *args, **kwargs)
|
||||
super().__init__('miscRegClass', ControlRegOperand, *args, **kwargs)
|
||||
|
||||
class MemOperand(Operand):
|
||||
def isMem(self):
|
||||
|
||||
@@ -44,7 +44,7 @@ let {{
|
||||
@overrideInOperand
|
||||
def regId(self):
|
||||
return f'(({self.reg_spec}) == 0) ? RegId() : ' \
|
||||
f'RegId({self.reg_class}, {self.reg_spec})'
|
||||
f'{self.reg_class}[{self.reg_spec}]'
|
||||
}};
|
||||
|
||||
def operands {{
|
||||
|
||||
@@ -57,6 +57,7 @@ output decoder {{
|
||||
|
||||
#include "arch/power/decoder.hh"
|
||||
#include "arch/power/faults.hh"
|
||||
#include "arch/power/regs/float.hh"
|
||||
#include "arch/power/regs/int.hh"
|
||||
#include "base/loader/symtab.hh"
|
||||
#include "base/cprintf.hh"
|
||||
|
||||
@@ -46,7 +46,7 @@ let {{
|
||||
@overrideInOperand
|
||||
def regId(self):
|
||||
return f'(({self.reg_spec}) == 0) ? RegId() : ' \
|
||||
f'RegId({self.reg_class}, {self.reg_spec})'
|
||||
f'{self.reg_class}[{self.reg_spec}]'
|
||||
}};
|
||||
|
||||
def operands {{
|
||||
|
||||
@@ -60,6 +60,7 @@ output decoder {{
|
||||
#include <algorithm>
|
||||
|
||||
#include "arch/sparc/decoder.hh"
|
||||
#include "arch/sparc/regs/float.hh"
|
||||
#include "base/cprintf.hh"
|
||||
#include "base/fenv.hh"
|
||||
#include "base/loader/symtab.hh"
|
||||
|
||||
@@ -70,7 +70,7 @@ let {{
|
||||
@overrideInOperand
|
||||
def regId(self):
|
||||
return f'(({self.reg_spec}) == 0) ? RegId() : ' \
|
||||
f'RegId({self.reg_class}, {self.reg_spec})'
|
||||
f'{self.reg_class}[{self.reg_spec}]'
|
||||
}};
|
||||
|
||||
def operands {{
|
||||
|
||||
@@ -58,7 +58,7 @@ let {{
|
||||
@overrideInOperand
|
||||
def regId(self):
|
||||
return f'(({self.reg_spec}) == gem5::X86ISA::int_reg::T0) ? ' \
|
||||
f'RegId() : RegId({self.reg_class}, {self.reg_spec})'
|
||||
f'RegId() : {self.reg_class}[{self.reg_spec}]'
|
||||
def __init__(self, idx, id, data_size='dataSize', *args, **kwargs):
|
||||
super().__init__('uqw', idx, 'IsInteger', id, *args, **kwargs)
|
||||
self.attrs['data_size'] = data_size
|
||||
|
||||
@@ -64,6 +64,7 @@ DebugFlag('ExecAsid', 'Format: Include ASID in trace')
|
||||
DebugFlag('ExecFlags', 'Format: Include instruction flags in trace')
|
||||
DebugFlag('Fetch')
|
||||
DebugFlag('HtmCpu', 'Hardware Transactional Memory (CPU side)')
|
||||
DebugFlag('InvalidReg')
|
||||
DebugFlag('O3PipeView')
|
||||
DebugFlag('PCEvent')
|
||||
DebugFlag('Quiesce')
|
||||
|
||||
@@ -84,42 +84,48 @@ PhysRegFile::PhysRegFile(unsigned _numPhysicalIntRegs,
|
||||
|
||||
// The initial batch of registers are the integer ones
|
||||
for (phys_reg = 0; phys_reg < numPhysicalIntRegs; phys_reg++) {
|
||||
intRegIds.emplace_back(IntRegClass, phys_reg, flat_reg_idx++);
|
||||
intRegIds.emplace_back(*reg_classes.at(IntRegClass),
|
||||
phys_reg, flat_reg_idx++);
|
||||
}
|
||||
|
||||
// The next batch of the registers are the floating-point physical
|
||||
// registers; put them onto the floating-point free list.
|
||||
for (phys_reg = 0; phys_reg < numPhysicalFloatRegs; phys_reg++) {
|
||||
floatRegIds.emplace_back(FloatRegClass, phys_reg, flat_reg_idx++);
|
||||
floatRegIds.emplace_back(*reg_classes.at(FloatRegClass),
|
||||
phys_reg, flat_reg_idx++);
|
||||
}
|
||||
|
||||
// The next batch of the registers are the vector physical
|
||||
// registers; put them onto the vector free list.
|
||||
for (phys_reg = 0; phys_reg < numPhysicalVecRegs; phys_reg++) {
|
||||
vecRegIds.emplace_back(VecRegClass, phys_reg, flat_reg_idx++);
|
||||
vecRegIds.emplace_back(*reg_classes.at(VecRegClass), phys_reg,
|
||||
flat_reg_idx++);
|
||||
}
|
||||
// The next batch of the registers are the vector element physical
|
||||
// registers; put them onto the vector free list.
|
||||
for (phys_reg = 0; phys_reg < numPhysicalVecElemRegs; phys_reg++) {
|
||||
vecElemIds.emplace_back(VecElemClass, phys_reg, flat_reg_idx++);
|
||||
vecElemIds.emplace_back(*reg_classes.at(VecElemClass), phys_reg,
|
||||
flat_reg_idx++);
|
||||
}
|
||||
|
||||
// The next batch of the registers are the predicate physical
|
||||
// registers; put them onto the predicate free list.
|
||||
for (phys_reg = 0; phys_reg < numPhysicalVecPredRegs; phys_reg++) {
|
||||
vecPredRegIds.emplace_back(VecPredRegClass, phys_reg, flat_reg_idx++);
|
||||
vecPredRegIds.emplace_back(*reg_classes.at(VecPredRegClass), phys_reg,
|
||||
flat_reg_idx++);
|
||||
}
|
||||
|
||||
// The rest of the registers are the condition-code physical
|
||||
// registers; put them onto the condition-code free list.
|
||||
for (phys_reg = 0; phys_reg < numPhysicalCCRegs; phys_reg++) {
|
||||
ccRegIds.emplace_back(CCRegClass, phys_reg, flat_reg_idx++);
|
||||
ccRegIds.emplace_back(*reg_classes.at(CCRegClass), phys_reg,
|
||||
flat_reg_idx++);
|
||||
}
|
||||
|
||||
// Misc regs have a fixed mapping but still need PhysRegIds.
|
||||
for (phys_reg = 0; phys_reg < reg_classes.at(MiscRegClass)->numRegs();
|
||||
phys_reg++) {
|
||||
miscRegIds.emplace_back(MiscRegClass, phys_reg, 0);
|
||||
miscRegIds.emplace_back(*reg_classes.at(MiscRegClass), phys_reg, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
#include "base/debug.hh"
|
||||
#include "base/intmath.hh"
|
||||
#include "base/types.hh"
|
||||
#include "debug/InvalidReg.hh"
|
||||
|
||||
namespace gem5
|
||||
{
|
||||
@@ -132,6 +133,9 @@ class RegClass
|
||||
inline constexpr RegId operator[](RegIndex idx) const;
|
||||
};
|
||||
|
||||
inline constexpr RegClass
|
||||
invalidRegClass(InvalidRegClass, 0, debug::InvalidReg);
|
||||
|
||||
/** 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
|
||||
@@ -141,7 +145,7 @@ class RegId
|
||||
{
|
||||
protected:
|
||||
static const char* regClassStrings[];
|
||||
RegClassType regClass;
|
||||
const RegClass *_regClass = nullptr;
|
||||
RegIndex regIdx;
|
||||
int numPinnedWrites;
|
||||
|
||||
@@ -149,10 +153,10 @@ class RegId
|
||||
friend class RegClassIterator;
|
||||
|
||||
public:
|
||||
constexpr RegId() : RegId(InvalidRegClass, 0) {}
|
||||
constexpr RegId() : RegId(invalidRegClass, 0) {}
|
||||
|
||||
constexpr RegId(RegClassType reg_class, RegIndex reg_idx)
|
||||
: regClass(reg_class), regIdx(reg_idx), numPinnedWrites(0)
|
||||
constexpr RegId(const RegClass ®_class, RegIndex reg_idx)
|
||||
: _regClass(®_class), regIdx(reg_idx), numPinnedWrites(0)
|
||||
{}
|
||||
|
||||
constexpr operator RegIndex() const
|
||||
@@ -163,7 +167,7 @@ class RegId
|
||||
constexpr bool
|
||||
operator==(const RegId& that) const
|
||||
{
|
||||
return regClass == that.classValue() && regIdx == that.index();
|
||||
return classValue() == that.classValue() && regIdx == that.index();
|
||||
}
|
||||
|
||||
constexpr bool
|
||||
@@ -178,8 +182,8 @@ class RegId
|
||||
constexpr bool
|
||||
operator<(const RegId& that) const
|
||||
{
|
||||
return regClass < that.classValue() ||
|
||||
(regClass == that.classValue() && (regIdx < that.index()));
|
||||
return classValue() < that.classValue() ||
|
||||
(classValue() == that.classValue() && (regIdx < that.index()));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -188,14 +192,14 @@ class RegId
|
||||
constexpr bool
|
||||
isRenameable() const
|
||||
{
|
||||
return regClass != MiscRegClass && regClass != InvalidRegClass;
|
||||
return classValue() != MiscRegClass && classValue() != InvalidRegClass;
|
||||
}
|
||||
|
||||
/** @return true if it is of the specified class. */
|
||||
constexpr bool
|
||||
is(RegClassType reg_class) const
|
||||
{
|
||||
return regClass == reg_class;
|
||||
return _regClass->type() == reg_class;
|
||||
}
|
||||
|
||||
/** Index accessors */
|
||||
@@ -203,12 +207,13 @@ class RegId
|
||||
constexpr RegIndex index() const { return regIdx; }
|
||||
|
||||
/** Class accessor */
|
||||
constexpr RegClassType classValue() const { return regClass; }
|
||||
constexpr const RegClass ®Class() const { return *_regClass; }
|
||||
constexpr RegClassType classValue() const { return _regClass->type(); }
|
||||
/** Return a const char* with the register class name. */
|
||||
constexpr const char*
|
||||
className() const
|
||||
{
|
||||
return regClassStrings[regClass];
|
||||
return regClassStrings[classValue()];
|
||||
}
|
||||
|
||||
int getNumPinnedWrites() const { return numPinnedWrites; }
|
||||
@@ -227,7 +232,7 @@ class RegClassIterator
|
||||
RegId id;
|
||||
|
||||
RegClassIterator(const RegClass ®_class, RegIndex idx) :
|
||||
id(reg_class.type(), idx)
|
||||
id(reg_class, idx)
|
||||
{}
|
||||
|
||||
friend class RegClass;
|
||||
@@ -285,7 +290,7 @@ RegClass::end() const
|
||||
constexpr RegId
|
||||
RegClass::operator[](RegIndex idx) const
|
||||
{
|
||||
return RegId(type(), idx);
|
||||
return RegId(*this, idx);
|
||||
}
|
||||
|
||||
template <typename ValueType>
|
||||
@@ -332,20 +337,21 @@ class PhysRegId : private RegId
|
||||
bool pinned;
|
||||
|
||||
public:
|
||||
explicit PhysRegId() : RegId(InvalidRegClass, -1), flatIdx(-1),
|
||||
explicit PhysRegId() : RegId(invalidRegClass, -1), flatIdx(-1),
|
||||
numPinnedWritesToComplete(0)
|
||||
{}
|
||||
|
||||
/** Scalar PhysRegId constructor. */
|
||||
explicit PhysRegId(RegClassType _regClass, RegIndex _regIdx,
|
||||
explicit PhysRegId(const RegClass ®_class, RegIndex _regIdx,
|
||||
RegIndex _flatIdx)
|
||||
: RegId(_regClass, _regIdx), flatIdx(_flatIdx),
|
||||
: RegId(reg_class, _regIdx), flatIdx(_flatIdx),
|
||||
numPinnedWritesToComplete(0), pinned(false)
|
||||
{}
|
||||
|
||||
/** Visible RegId methods */
|
||||
/** @{ */
|
||||
using RegId::index;
|
||||
using RegId::regClass;
|
||||
using RegId::classValue;
|
||||
using RegId::className;
|
||||
using RegId::is;
|
||||
@@ -433,7 +439,7 @@ struct hash<gem5::RegId>
|
||||
{
|
||||
// Extract unique integral values for the effective fields of a RegId.
|
||||
const size_t index = static_cast<size_t>(reg_id.index());
|
||||
const size_t class_num = static_cast<size_t>(reg_id.regClass);
|
||||
const size_t class_num = static_cast<size_t>(reg_id.classValue());
|
||||
|
||||
const size_t shifted_class_num =
|
||||
class_num << (sizeof(gem5::RegIndex) << 3);
|
||||
|
||||
Reference in New Issue
Block a user