cpu,arch: Turn the read|set*Operand methods into get/setRegOperand.
This simplifies and generalizes the ExecContext interface significantly. This does *not* change the "Writeable" accessors for the vec and pred registers, and it also ignores MiscRegs which have some different semantics. Change-Id: I8cb80da890fc8915f03be04e136662a257d06946 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/49114 Reviewed-by: Giacomo Travaglini <giacomo.travaglini@arm.com> Maintainer: Giacomo Travaglini <giacomo.travaglini@arm.com> Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
@@ -122,7 +122,7 @@ Tstart64::completeAcc(PacketPtr pkt, ExecContext *xc,
|
||||
tc->getIsaPtr()->globalClearExclusive();
|
||||
}
|
||||
|
||||
xc->setIntRegOperand(this, 0, (Dest64) & mask(intWidth));
|
||||
xc->setRegOperand(this, 0, (Dest64) & mask(intWidth));
|
||||
|
||||
|
||||
uint64_t final_val = Dest64;
|
||||
@@ -155,7 +155,7 @@ Ttest64::execute(ExecContext *xc, Trace::InstRecord *traceData) const
|
||||
|
||||
if (fault == NoFault) {
|
||||
uint64_t final_val = Dest64;
|
||||
xc->setIntRegOperand(this, 0, (Dest64) & mask(intWidth));
|
||||
xc->setRegOperand(this, 0, (Dest64) & mask(intWidth));
|
||||
if (traceData) { traceData->setData(final_val); }
|
||||
}
|
||||
|
||||
|
||||
@@ -68,16 +68,17 @@
|
||||
* ...
|
||||
* // Usage example, for a macro op:
|
||||
* VecFloat8Add(ExecContext* xd) {
|
||||
* // Request source vector register to the execution context (const as it
|
||||
* // is read only).
|
||||
* const Vec512& vsrc1raw = xc->readVecRegOperand(this, 0);
|
||||
* // Request source vector register to the execution context.
|
||||
* Vec512 vsrc1raw;
|
||||
* xc->getRegOperand(this, 0, &vsrc1raw);
|
||||
* // View it as a vector of floats (we could just specify the first
|
||||
* // template parametre, the second has a default value that works, and the
|
||||
* // last one is derived by the constness of vsrc1raw).
|
||||
* VecRegT<float, 8, true>& vsrc1 = vsrc1raw->as<float, 8>();
|
||||
*
|
||||
* // Second source and view
|
||||
* const Vec512& vsrc2raw = xc->readVecRegOperand(this, 1);
|
||||
* Vec512 vsrc2raw;
|
||||
* xc->getRegOperand(this, 1, &vsrc2raw);
|
||||
* VecRegT<float, 8, true>& vsrc2 = vsrc2raw->as<float, 8>();
|
||||
*
|
||||
* // Destination and view
|
||||
|
||||
@@ -202,16 +202,16 @@ class IntRegOperand(Operand):
|
||||
if (self.ctype == 'float' or self.ctype == 'double'):
|
||||
error('Attempt to read integer register as FP')
|
||||
if self.read_code != None:
|
||||
return self.buildReadCode(predRead, 'readIntRegOperand')
|
||||
return self.buildReadCode(predRead, 'getRegOperand')
|
||||
|
||||
int_reg_val = ''
|
||||
if predRead:
|
||||
int_reg_val = 'xc->readIntRegOperand(this, _sourceIndex++)'
|
||||
int_reg_val = 'xc->getRegOperand(this, _sourceIndex++)'
|
||||
if self.hasReadPred():
|
||||
int_reg_val = '(%s) ? %s : 0' % \
|
||||
(self.read_predicate, int_reg_val)
|
||||
else:
|
||||
int_reg_val = 'xc->readIntRegOperand(this, %d)' % self.src_reg_idx
|
||||
int_reg_val = 'xc->getRegOperand(this, %d)' % self.src_reg_idx
|
||||
|
||||
return '%s = %s;\n' % (self.base_name, int_reg_val)
|
||||
|
||||
@@ -219,7 +219,7 @@ class IntRegOperand(Operand):
|
||||
if (self.ctype == 'float' or self.ctype == 'double'):
|
||||
error('Attempt to write integer register as FP')
|
||||
if self.write_code != None:
|
||||
return self.buildWriteCode(predWrite, 'setIntRegOperand')
|
||||
return self.buildWriteCode(predWrite, 'setRegOperand')
|
||||
|
||||
if predWrite:
|
||||
wp = 'true'
|
||||
@@ -236,7 +236,7 @@ class IntRegOperand(Operand):
|
||||
%s
|
||||
{
|
||||
%s final_val = %s;
|
||||
xc->setIntRegOperand(this, %s, final_val);\n
|
||||
xc->setRegOperand(this, %s, final_val);\n
|
||||
if (traceData) { traceData->setData(final_val); }
|
||||
}''' % (wcond, self.ctype, self.base_name, windex)
|
||||
|
||||
@@ -266,14 +266,14 @@ class FloatRegOperand(Operand):
|
||||
|
||||
def makeRead(self, predRead):
|
||||
if self.read_code != None:
|
||||
return self.buildReadCode(predRead, 'readFloatRegOperandBits')
|
||||
return self.buildReadCode(predRead, 'getRegOperand')
|
||||
|
||||
if predRead:
|
||||
rindex = '_sourceIndex++'
|
||||
else:
|
||||
rindex = '%d' % self.src_reg_idx
|
||||
|
||||
code = 'xc->readFloatRegOperandBits(this, %s)' % rindex
|
||||
code = 'xc->getRegOperand(this, %s)' % rindex
|
||||
if self.ctype == 'float':
|
||||
code = 'bitsToFloat32(%s)' % code
|
||||
elif self.ctype == 'double':
|
||||
@@ -282,7 +282,7 @@ class FloatRegOperand(Operand):
|
||||
|
||||
def makeWrite(self, predWrite):
|
||||
if self.write_code != None:
|
||||
return self.buildWriteCode(predWrite, 'setFloatRegOperandBits')
|
||||
return self.buildWriteCode(predWrite, 'setRegOperand')
|
||||
|
||||
if predWrite:
|
||||
wp = '_destIndex++'
|
||||
@@ -295,7 +295,7 @@ class FloatRegOperand(Operand):
|
||||
elif self.ctype == 'double':
|
||||
val = 'floatToBits64(%s)' % val
|
||||
|
||||
wp = 'xc->setFloatRegOperandBits(this, %s, %s);' % (wp, val)
|
||||
wp = 'xc->setRegOperand(this, %s, %s);' % (wp, val)
|
||||
|
||||
wb = '''
|
||||
{
|
||||
@@ -369,7 +369,7 @@ class VecRegOperand(Operand):
|
||||
return c_read
|
||||
|
||||
def makeReadW(self, predWrite):
|
||||
func = 'getWritableVecRegOperand'
|
||||
func = 'getWritableRegOperand'
|
||||
if self.read_code != None:
|
||||
return self.buildReadCode(predWrite, func)
|
||||
|
||||
@@ -378,8 +378,9 @@ class VecRegOperand(Operand):
|
||||
else:
|
||||
rindex = '%d' % self.dest_reg_idx
|
||||
|
||||
c_readw = '\t\t%s& tmp_d%s = xc->%s(this, %s);\n'\
|
||||
% ('TheISA::VecRegContainer', rindex, func, rindex)
|
||||
c_readw = f'\t\tauto &tmp_d{rindex} = \n' \
|
||||
f'\t\t *(TheISA::VecRegContainer *)xc->{func}(\n' \
|
||||
f'\t\t this, {rindex});\n'
|
||||
if self.elemExt:
|
||||
c_readw += '\t\tauto %s = tmp_d%s.as<%s>();\n' % (self.base_name,
|
||||
rindex, self.parser.operandTypeMap[self.elemExt])
|
||||
@@ -407,7 +408,7 @@ class VecRegOperand(Operand):
|
||||
return c_read
|
||||
|
||||
def makeRead(self, predRead):
|
||||
func = 'readVecRegOperand'
|
||||
func = 'getRegOperand'
|
||||
if self.read_code != None:
|
||||
return self.buildReadCode(predRead, func)
|
||||
|
||||
@@ -420,8 +421,8 @@ class VecRegOperand(Operand):
|
||||
if self.is_dest and self.is_src:
|
||||
name += '_merger'
|
||||
|
||||
c_read = '\t\t%s& tmp_s%s = xc->%s(this, %s);\n' \
|
||||
% ('const TheISA::VecRegContainer', rindex, func, rindex)
|
||||
c_read = f'\t\tTheISA::VecRegContainer tmp_s{rindex};\n' \
|
||||
f'\t\txc->{func}(this, {rindex}, &tmp_s{rindex});\n'
|
||||
# If the parser has detected that elements are being access, create
|
||||
# the appropriate view
|
||||
if self.elemExt:
|
||||
@@ -437,7 +438,7 @@ class VecRegOperand(Operand):
|
||||
return c_read
|
||||
|
||||
def makeWrite(self, predWrite):
|
||||
func = 'setVecRegOperand'
|
||||
func = 'setRegOperand'
|
||||
if self.write_code != None:
|
||||
return self.buildWriteCode(predWrite, func)
|
||||
|
||||
@@ -485,27 +486,22 @@ class VecElemOperand(Operand):
|
||||
return c_src + c_dest
|
||||
|
||||
def makeRead(self, predRead):
|
||||
c_read = 'xc->readVecElemOperand(this, %d)' % self.src_reg_idx
|
||||
c_read = f'xc->getRegOperand(this, {self.src_reg_idx})'
|
||||
|
||||
if self.ctype == 'float':
|
||||
c_read = 'bitsToFloat32(%s)' % c_read
|
||||
c_read = f'bitsToFloat32({c_read})'
|
||||
elif self.ctype == 'double':
|
||||
c_read = 'bitsToFloat64(%s)' % c_read
|
||||
c_read = f'bitsToFloat64({c_read})'
|
||||
|
||||
return '\n\t%s %s = %s;\n' % (self.ctype, self.base_name, c_read)
|
||||
return f'\n\t{self.ctype} {self.base_name} = {c_read};\n'
|
||||
|
||||
def makeWrite(self, predWrite):
|
||||
val = self.base_name
|
||||
if self.ctype == 'float':
|
||||
c_write = 'floatToBits32(%s)' % self.base_name
|
||||
val = f'floatToBits32({val})'
|
||||
elif self.ctype == 'double':
|
||||
c_write = 'floatToBits64(%s)' % self.base_name
|
||||
else:
|
||||
c_write = self.base_name
|
||||
|
||||
c_write = ('\n\txc->setVecElemOperand(this, %d, %s);' %
|
||||
(self.dest_reg_idx, c_write))
|
||||
|
||||
return c_write
|
||||
val = f'floatToBits64({val})'
|
||||
return f'\n\txc->setRegOperand(this, {self.dest_reg_idx}, {val});'
|
||||
|
||||
class VecPredRegOperand(Operand):
|
||||
reg_class = 'VecPredRegClass'
|
||||
@@ -537,7 +533,7 @@ class VecPredRegOperand(Operand):
|
||||
return c_src + c_dest
|
||||
|
||||
def makeRead(self, predRead):
|
||||
func = 'readVecPredRegOperand'
|
||||
func = 'getRegOperand'
|
||||
if self.read_code != None:
|
||||
return self.buildReadCode(predRead, func)
|
||||
|
||||
@@ -546,16 +542,16 @@ class VecPredRegOperand(Operand):
|
||||
else:
|
||||
rindex = '%d' % self.src_reg_idx
|
||||
|
||||
c_read = '\t\t%s& tmp_s%s = xc->%s(this, %s);\n' % (
|
||||
'const TheISA::VecPredRegContainer', rindex, func, rindex)
|
||||
c_read = f'\t\tTheISA::VecPredRegContainer tmp_s{rindex}; ' \
|
||||
f'xc->{func}(this, {rindex}, &tmp_s{rindex});\n'
|
||||
if self.ext:
|
||||
c_read += '\t\tauto %s = tmp_s%s.as<%s>();\n' % (
|
||||
self.base_name, rindex,
|
||||
self.parser.operandTypeMap[self.ext])
|
||||
c_read += f'\t\tauto {self.base_name} = ' \
|
||||
f'tmp_s{rindex}.as<' \
|
||||
f'{self.parser.operandTypeMap[self.ext]}>();\n'
|
||||
return c_read
|
||||
|
||||
def makeReadW(self, predWrite):
|
||||
func = 'getWritableVecPredRegOperand'
|
||||
func = 'getWritableRegOperand'
|
||||
if self.read_code != None:
|
||||
return self.buildReadCode(predWrite, func)
|
||||
|
||||
@@ -564,8 +560,9 @@ class VecPredRegOperand(Operand):
|
||||
else:
|
||||
rindex = '%d' % self.dest_reg_idx
|
||||
|
||||
c_readw = '\t\t%s& tmp_d%s = xc->%s(this, %s);\n' % (
|
||||
'TheISA::VecPredRegContainer', rindex, func, rindex)
|
||||
c_readw = f'\t\tauto &tmp_d{rindex} = \n' \
|
||||
f'\t\t *(TheISA::VecPredRegContainer *)xc->{func}(\n' \
|
||||
f'\t\t this, {rindex});\n'
|
||||
if self.ext:
|
||||
c_readw += '\t\tauto %s = tmp_d%s.as<%s>();\n' % (
|
||||
self.base_name, rindex,
|
||||
@@ -573,7 +570,7 @@ class VecPredRegOperand(Operand):
|
||||
return c_readw
|
||||
|
||||
def makeWrite(self, predWrite):
|
||||
func = 'setVecPredRegOperand'
|
||||
func = 'setRegOperand'
|
||||
if self.write_code != None:
|
||||
return self.buildWriteCode(predWrite, func)
|
||||
|
||||
@@ -621,16 +618,16 @@ class CCRegOperand(Operand):
|
||||
if (self.ctype == 'float' or self.ctype == 'double'):
|
||||
error('Attempt to read condition-code register as FP')
|
||||
if self.read_code != None:
|
||||
return self.buildReadCode(predRead, 'readCCRegOperand')
|
||||
return self.buildReadCode(predRead, 'getRegOperand')
|
||||
|
||||
int_reg_val = ''
|
||||
if predRead:
|
||||
int_reg_val = 'xc->readCCRegOperand(this, _sourceIndex++)'
|
||||
int_reg_val = 'xc->getRegOperand(this, _sourceIndex++)'
|
||||
if self.hasReadPred():
|
||||
int_reg_val = '(%s) ? %s : 0' % \
|
||||
(self.read_predicate, int_reg_val)
|
||||
else:
|
||||
int_reg_val = 'xc->readCCRegOperand(this, %d)' % self.src_reg_idx
|
||||
int_reg_val = 'xc->getRegOperand(this, %d)' % self.src_reg_idx
|
||||
|
||||
return '%s = %s;\n' % (self.base_name, int_reg_val)
|
||||
|
||||
@@ -638,7 +635,7 @@ class CCRegOperand(Operand):
|
||||
if (self.ctype == 'float' or self.ctype == 'double'):
|
||||
error('Attempt to write condition-code register as FP')
|
||||
if self.write_code != None:
|
||||
return self.buildWriteCode(predWrite, 'setCCRegOperand')
|
||||
return self.buildWriteCode(predWrite, 'setRegOperand')
|
||||
|
||||
if predWrite:
|
||||
wp = 'true'
|
||||
@@ -655,7 +652,7 @@ class CCRegOperand(Operand):
|
||||
%s
|
||||
{
|
||||
%s final_val = %s;
|
||||
xc->setCCRegOperand(this, %s, final_val);\n
|
||||
xc->setRegOperand(this, %s, final_val);\n
|
||||
if (traceData) { traceData->setData(final_val); }
|
||||
}''' % (wcond, self.ctype, self.base_name, windex)
|
||||
|
||||
|
||||
@@ -104,11 +104,11 @@ output exec {{
|
||||
assert(sizeof(T) == 4);
|
||||
|
||||
for (int i = 0; i < inst->numSrcRegs(); i++) {
|
||||
uint64_t src_bits = xc->readFloatRegOperandBits(inst, 0);
|
||||
uint64_t src_bits = xc->getRegOperand(inst, 0);
|
||||
|
||||
if (isNan(&src_bits, 32) ) {
|
||||
mips_nan = MIPS32_QNAN;
|
||||
xc->setFloatRegOperandBits(inst, 0, mips_nan);
|
||||
xc->setRegOperand(inst, 0, mips_nan);
|
||||
if (traceData) { traceData->setData(mips_nan); }
|
||||
return true;
|
||||
}
|
||||
@@ -129,7 +129,7 @@ output exec {{
|
||||
mips_nan = MIPS32_QNAN;
|
||||
|
||||
//Set value to QNAN
|
||||
cpu->setFloatRegOperandBits(inst, 0, mips_nan);
|
||||
cpu->setRegOperand(inst, 0, mips_nan);
|
||||
|
||||
//Read FCSR from FloatRegFile
|
||||
uint32_t fcsr_bits =
|
||||
|
||||
@@ -58,11 +58,11 @@ let {{
|
||||
return ('IntReg', 'uqw', idx, 'IsInteger', id)
|
||||
def pickedReg(idx, id, size='dataSize'):
|
||||
return ('IntReg', 'uqw', idx, 'IsInteger', id,
|
||||
'pick(xc->readIntRegOperand(this, %(op_idx)s), '
|
||||
'pick(xc->getRegOperand(this, %(op_idx)s), '
|
||||
'%(reg_idx)s, ' + size + ')')
|
||||
def signedPickedReg(idx, id, size='dataSize'):
|
||||
return ('IntReg', 'uqw', idx, 'IsInteger', id,
|
||||
'signedPick(xc->readIntRegOperand(this, %(op_idx)s), '
|
||||
'signedPick(xc->getRegOperand(this, %(op_idx)s), '
|
||||
'%(reg_idx)s, ' + size + ')')
|
||||
def floatReg(idx, id):
|
||||
return ('FloatReg', 'df', idx, 'IsFloating', id)
|
||||
|
||||
@@ -176,108 +176,35 @@ class CheckerCPU : public BaseCPU, public ExecContext
|
||||
// to do).
|
||||
|
||||
RegVal
|
||||
readIntRegOperand(const StaticInst *si, int idx) override
|
||||
{
|
||||
return thread->getReg(si->srcRegIdx(idx));
|
||||
}
|
||||
|
||||
RegVal
|
||||
readFloatRegOperandBits(const StaticInst *si, int idx) override
|
||||
{
|
||||
return thread->getReg(si->srcRegIdx(idx));
|
||||
}
|
||||
|
||||
/**
|
||||
* Read source vector register operand.
|
||||
*/
|
||||
TheISA::VecRegContainer
|
||||
readVecRegOperand(const StaticInst *si, int idx) const override
|
||||
{
|
||||
TheISA::VecRegContainer val;
|
||||
thread->getReg(si->srcRegIdx(idx), &val);
|
||||
return val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read destination vector register operand for modification.
|
||||
*/
|
||||
TheISA::VecRegContainer &
|
||||
getWritableVecRegOperand(const StaticInst *si, int idx) override
|
||||
{
|
||||
const RegId& reg = si->destRegIdx(idx);
|
||||
return *(TheISA::VecRegContainer *)thread->getWritableReg(reg);
|
||||
}
|
||||
|
||||
RegVal
|
||||
readVecElemOperand(const StaticInst *si, int idx) const override
|
||||
{
|
||||
const RegId& reg = si->srcRegIdx(idx);
|
||||
return thread->readVecElem(reg);
|
||||
}
|
||||
|
||||
TheISA::VecPredRegContainer
|
||||
readVecPredRegOperand(const StaticInst *si, int idx) const override
|
||||
{
|
||||
TheISA::VecPredRegContainer val;
|
||||
thread->getReg(si->srcRegIdx(idx), &val);
|
||||
return val;
|
||||
}
|
||||
|
||||
TheISA::VecPredRegContainer&
|
||||
getWritableVecPredRegOperand(const StaticInst *si, int idx) override
|
||||
{
|
||||
const RegId& reg = si->destRegIdx(idx);
|
||||
return *(TheISA::VecPredRegContainer *)thread->getWritableReg(reg);
|
||||
}
|
||||
|
||||
RegVal
|
||||
readCCRegOperand(const StaticInst *si, int idx) override
|
||||
getRegOperand(const StaticInst *si, int idx) override
|
||||
{
|
||||
return thread->getReg(si->srcRegIdx(idx));
|
||||
}
|
||||
|
||||
void
|
||||
setIntRegOperand(const StaticInst *si, int idx, RegVal val) override
|
||||
getRegOperand(const StaticInst *si, int idx, void *val) override
|
||||
{
|
||||
thread->getReg(si->srcRegIdx(idx), val);
|
||||
}
|
||||
|
||||
void *
|
||||
getWritableRegOperand(const StaticInst *si, int idx) override
|
||||
{
|
||||
return thread->getWritableReg(si->destRegIdx(idx));
|
||||
}
|
||||
|
||||
void
|
||||
setRegOperand(const StaticInst *si, int idx, RegVal val) override
|
||||
{
|
||||
thread->setReg(si->destRegIdx(idx), val);
|
||||
result.emplace(val);
|
||||
}
|
||||
|
||||
void
|
||||
setFloatRegOperandBits(const StaticInst *si, int idx, RegVal val) override
|
||||
setRegOperand(const StaticInst *si, int idx, const void *val) override
|
||||
{
|
||||
thread->setReg(si->destRegIdx(idx), val);
|
||||
result.emplace(val);
|
||||
}
|
||||
|
||||
void
|
||||
setCCRegOperand(const StaticInst *si, int idx, RegVal val) override
|
||||
{
|
||||
thread->setReg(si->destRegIdx(idx), val);
|
||||
result.emplace(val);
|
||||
}
|
||||
|
||||
void
|
||||
setVecRegOperand(const StaticInst *si, int idx,
|
||||
const TheISA::VecRegContainer& val) override
|
||||
{
|
||||
thread->setReg(si->destRegIdx(idx), &val);
|
||||
result.emplace(val);
|
||||
}
|
||||
|
||||
void
|
||||
setVecElemOperand(const StaticInst *si, int idx, RegVal val) override
|
||||
{
|
||||
thread->setReg(si->destRegIdx(idx), val);
|
||||
result.emplace(val);
|
||||
}
|
||||
|
||||
void
|
||||
setVecPredRegOperand(const StaticInst *si, int idx,
|
||||
const TheISA::VecPredRegContainer& val) override
|
||||
{
|
||||
thread->setReg(si->destRegIdx(idx), &val);
|
||||
result.emplace(val);
|
||||
//TODO setVecResult, setVecPredResult setVecElemResult?
|
||||
}
|
||||
|
||||
bool readPredicate() const override { return thread->readPredicate(); }
|
||||
|
||||
@@ -73,87 +73,13 @@ namespace gem5
|
||||
class ExecContext
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @{
|
||||
* @name Integer Register Interfaces
|
||||
*
|
||||
*/
|
||||
|
||||
/** Reads an integer register. */
|
||||
virtual RegVal readIntRegOperand(const StaticInst *si, int idx) = 0;
|
||||
|
||||
/** Sets an integer register to a value. */
|
||||
virtual void setIntRegOperand(const StaticInst *si,
|
||||
int idx, RegVal val) = 0;
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
/**
|
||||
* @{
|
||||
* @name Floating Point Register Interfaces
|
||||
*/
|
||||
|
||||
/** Reads a floating point register in its binary format, instead
|
||||
* of by value. */
|
||||
virtual RegVal readFloatRegOperandBits(const StaticInst *si, int idx) = 0;
|
||||
|
||||
/** Sets the bits of a floating point register of single width
|
||||
* to a binary value. */
|
||||
virtual void setFloatRegOperandBits(const StaticInst *si,
|
||||
int idx, RegVal val) = 0;
|
||||
|
||||
/** @} */
|
||||
|
||||
/** Vector Register Interfaces. */
|
||||
/** @{ */
|
||||
/** Reads source vector register operand. */
|
||||
virtual TheISA::VecRegContainer readVecRegOperand(
|
||||
const StaticInst *si, int idx) const = 0;
|
||||
|
||||
/** Gets destination vector register operand for modification. */
|
||||
virtual TheISA::VecRegContainer& getWritableVecRegOperand(
|
||||
const StaticInst *si, int idx) = 0;
|
||||
|
||||
/** Sets a destination vector register operand to a value. */
|
||||
virtual void setVecRegOperand(const StaticInst *si, int idx,
|
||||
const TheISA::VecRegContainer& val) = 0;
|
||||
/** @} */
|
||||
|
||||
/** Vector Elem Interfaces. */
|
||||
/** @{ */
|
||||
/** Reads an element of a vector register. */
|
||||
virtual RegVal readVecElemOperand(const StaticInst *si, int idx) const = 0;
|
||||
|
||||
/** Sets a vector register to a value. */
|
||||
virtual void setVecElemOperand(
|
||||
const StaticInst *si, int idx, RegVal val) = 0;
|
||||
/** @} */
|
||||
|
||||
/** Predicate registers interface. */
|
||||
/** @{ */
|
||||
/** Reads source predicate register operand. */
|
||||
virtual TheISA::VecPredRegContainer readVecPredRegOperand(
|
||||
const StaticInst *si, int idx) const = 0;
|
||||
|
||||
/** Gets destination predicate register operand for modification. */
|
||||
virtual TheISA::VecPredRegContainer& getWritableVecPredRegOperand(
|
||||
const StaticInst *si, int idx) = 0;
|
||||
|
||||
/** Sets a destination predicate register operand to a value. */
|
||||
virtual void setVecPredRegOperand(
|
||||
const StaticInst *si, int idx,
|
||||
const TheISA::VecPredRegContainer& val) = 0;
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @{
|
||||
* @name Condition Code Registers
|
||||
*/
|
||||
virtual RegVal readCCRegOperand(const StaticInst *si, int idx) = 0;
|
||||
virtual void setCCRegOperand(
|
||||
const StaticInst *si, int idx, RegVal val) = 0;
|
||||
/** @} */
|
||||
virtual RegVal getRegOperand(const StaticInst *si, int idx) = 0;
|
||||
virtual void getRegOperand(const StaticInst *si, int idx, void *val) = 0;
|
||||
virtual void *getWritableRegOperand(const StaticInst *si, int idx) = 0;
|
||||
virtual void setRegOperand(const StaticInst *si, int idx, RegVal val) = 0;
|
||||
virtual void setRegOperand(const StaticInst *si, int idx,
|
||||
const void *val) = 0;
|
||||
|
||||
/**
|
||||
* @{
|
||||
|
||||
@@ -145,101 +145,33 @@ class ExecContext : public gem5::ExecContext
|
||||
}
|
||||
|
||||
RegVal
|
||||
readIntRegOperand(const StaticInst *si, int idx) override
|
||||
getRegOperand(const StaticInst *si, int idx) override
|
||||
{
|
||||
const RegId& reg = si->srcRegIdx(idx);
|
||||
assert(reg.is(IntRegClass));
|
||||
return thread.readIntReg(reg.index());
|
||||
}
|
||||
|
||||
RegVal
|
||||
readFloatRegOperandBits(const StaticInst *si, int idx) override
|
||||
{
|
||||
const RegId& reg = si->srcRegIdx(idx);
|
||||
assert(reg.is(FloatRegClass));
|
||||
return thread.readFloatReg(reg.index());
|
||||
}
|
||||
|
||||
TheISA::VecRegContainer
|
||||
readVecRegOperand(const StaticInst *si, int idx) const override
|
||||
{
|
||||
const RegId& reg = si->srcRegIdx(idx);
|
||||
assert(reg.is(VecRegClass));
|
||||
return thread.readVecReg(reg);
|
||||
}
|
||||
|
||||
TheISA::VecRegContainer &
|
||||
getWritableVecRegOperand(const StaticInst *si, int idx) override
|
||||
{
|
||||
const RegId& reg = si->destRegIdx(idx);
|
||||
assert(reg.is(VecRegClass));
|
||||
return thread.getWritableVecReg(reg);
|
||||
}
|
||||
|
||||
RegVal
|
||||
readVecElemOperand(const StaticInst *si, int idx) const override
|
||||
{
|
||||
const RegId& reg = si->srcRegIdx(idx);
|
||||
assert(reg.is(VecElemClass));
|
||||
return thread.readVecElem(reg);
|
||||
}
|
||||
|
||||
TheISA::VecPredRegContainer
|
||||
readVecPredRegOperand(const StaticInst *si, int idx) const override
|
||||
{
|
||||
const RegId& reg = si->srcRegIdx(idx);
|
||||
assert(reg.is(VecPredRegClass));
|
||||
return thread.readVecPredReg(reg);
|
||||
}
|
||||
|
||||
TheISA::VecPredRegContainer&
|
||||
getWritableVecPredRegOperand(const StaticInst *si, int idx) override
|
||||
{
|
||||
const RegId& reg = si->destRegIdx(idx);
|
||||
assert(reg.is(VecPredRegClass));
|
||||
return thread.getWritableVecPredReg(reg);
|
||||
return thread.getReg(si->srcRegIdx(idx));
|
||||
}
|
||||
|
||||
void
|
||||
setIntRegOperand(const StaticInst *si, int idx, RegVal val) override
|
||||
getRegOperand(const StaticInst *si, int idx, void *val) override
|
||||
{
|
||||
const RegId& reg = si->destRegIdx(idx);
|
||||
assert(reg.is(IntRegClass));
|
||||
thread.setIntReg(reg.index(), val);
|
||||
thread.getReg(si->srcRegIdx(idx), val);
|
||||
}
|
||||
|
||||
void *
|
||||
getWritableRegOperand(const StaticInst *si, int idx) override
|
||||
{
|
||||
return thread.getWritableReg(si->destRegIdx(idx));
|
||||
}
|
||||
|
||||
void
|
||||
setFloatRegOperandBits(const StaticInst *si, int idx, RegVal val) override
|
||||
setRegOperand(const StaticInst *si, int idx, RegVal val) override
|
||||
{
|
||||
const RegId& reg = si->destRegIdx(idx);
|
||||
assert(reg.is(FloatRegClass));
|
||||
thread.setFloatReg(reg.index(), val);
|
||||
thread.setReg(si->destRegIdx(idx), val);
|
||||
}
|
||||
|
||||
void
|
||||
setVecRegOperand(const StaticInst *si, int idx,
|
||||
const TheISA::VecRegContainer& val) override
|
||||
setRegOperand(const StaticInst *si, int idx, const void *val) override
|
||||
{
|
||||
const RegId& reg = si->destRegIdx(idx);
|
||||
assert(reg.is(VecRegClass));
|
||||
thread.setVecReg(reg, val);
|
||||
}
|
||||
|
||||
void
|
||||
setVecPredRegOperand(const StaticInst *si, int idx,
|
||||
const TheISA::VecPredRegContainer& val) override
|
||||
{
|
||||
const RegId& reg = si->destRegIdx(idx);
|
||||
assert(reg.is(VecPredRegClass));
|
||||
thread.setVecPredReg(reg, val);
|
||||
}
|
||||
|
||||
void
|
||||
setVecElemOperand(const StaticInst *si, int idx, RegVal val) override
|
||||
{
|
||||
const RegId& reg = si->destRegIdx(idx);
|
||||
assert(reg.is(VecElemClass));
|
||||
thread.setVecElem(reg, val);
|
||||
thread.setReg(si->destRegIdx(idx), val);
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -361,22 +293,6 @@ class ExecContext : public gem5::ExecContext
|
||||
thread.getMMUPtr()->demapPage(vaddr, asn);
|
||||
}
|
||||
|
||||
RegVal
|
||||
readCCRegOperand(const StaticInst *si, int idx) override
|
||||
{
|
||||
const RegId& reg = si->srcRegIdx(idx);
|
||||
assert(reg.is(CCRegClass));
|
||||
return thread.readCCReg(reg.index());
|
||||
}
|
||||
|
||||
void
|
||||
setCCRegOperand(const StaticInst *si, int idx, RegVal val) override
|
||||
{
|
||||
const RegId& reg = si->destRegIdx(idx);
|
||||
assert(reg.is(CCRegClass));
|
||||
thread.setCCReg(reg.index(), val);
|
||||
}
|
||||
|
||||
BaseCPU *getCpuPtr() { return &cpu; }
|
||||
|
||||
public:
|
||||
|
||||
@@ -1091,38 +1091,29 @@ class DynInst : public ExecContext, public RefCounted
|
||||
const RegId& original_dest_reg = staticInst->destRegIdx(idx);
|
||||
switch (original_dest_reg.classValue()) {
|
||||
case IntRegClass:
|
||||
setIntRegOperand(staticInst.get(), idx,
|
||||
cpu->getReg(prev_phys_reg));
|
||||
break;
|
||||
case FloatRegClass:
|
||||
setFloatRegOperandBits(staticInst.get(), idx,
|
||||
case CCRegClass:
|
||||
setRegOperand(staticInst.get(), idx,
|
||||
cpu->getReg(prev_phys_reg));
|
||||
break;
|
||||
case VecRegClass:
|
||||
{
|
||||
TheISA::VecRegContainer val;
|
||||
cpu->getReg(prev_phys_reg, &val);
|
||||
setVecRegOperand(staticInst.get(), idx, val);
|
||||
setRegOperand(staticInst.get(), idx, &val);
|
||||
}
|
||||
break;
|
||||
case VecElemClass:
|
||||
{
|
||||
RegVal val;
|
||||
cpu->getReg(prev_phys_reg, &val);
|
||||
setVecElemOperand(staticInst.get(), idx, val);
|
||||
}
|
||||
setRegOperand(staticInst.get(), idx,
|
||||
cpu->getReg(prev_phys_reg));
|
||||
break;
|
||||
case VecPredRegClass:
|
||||
{
|
||||
TheISA::VecPredRegContainer val;
|
||||
cpu->getReg(prev_phys_reg, &val);
|
||||
setVecPredRegOperand(staticInst.get(), idx, val);
|
||||
setRegOperand(staticInst.get(), idx, &val);
|
||||
}
|
||||
break;
|
||||
case CCRegClass:
|
||||
setCCRegOperand(staticInst.get(), idx,
|
||||
cpu->getReg(prev_phys_reg));
|
||||
break;
|
||||
case MiscRegClass:
|
||||
// no need to forward misc reg values
|
||||
break;
|
||||
@@ -1149,109 +1140,38 @@ class DynInst : public ExecContext, public RefCounted
|
||||
// to do).
|
||||
|
||||
RegVal
|
||||
readIntRegOperand(const StaticInst *si, int idx) override
|
||||
getRegOperand(const StaticInst *si, int idx) override
|
||||
{
|
||||
return cpu->getReg(renamedSrcIdx(idx));
|
||||
}
|
||||
|
||||
RegVal
|
||||
readFloatRegOperandBits(const StaticInst *si, int idx) override
|
||||
void
|
||||
getRegOperand(const StaticInst *si, int idx, void *val) override
|
||||
{
|
||||
return cpu->getReg(renamedSrcIdx(idx));
|
||||
cpu->getReg(renamedSrcIdx(idx), val);
|
||||
}
|
||||
|
||||
TheISA::VecRegContainer
|
||||
readVecRegOperand(const StaticInst *si, int idx) const override
|
||||
void *
|
||||
getWritableRegOperand(const StaticInst *si, int idx) override
|
||||
{
|
||||
TheISA::VecRegContainer val;
|
||||
cpu->getReg(renamedSrcIdx(idx), &val);
|
||||
return val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read destination vector register operand for modification.
|
||||
*/
|
||||
TheISA::VecRegContainer&
|
||||
getWritableVecRegOperand(const StaticInst *si, int idx) override
|
||||
{
|
||||
return *(TheISA::VecRegContainer *)cpu->getWritableReg(
|
||||
renamedDestIdx(idx));
|
||||
}
|
||||
|
||||
RegVal
|
||||
readVecElemOperand(const StaticInst *si, int idx) const override
|
||||
{
|
||||
RegVal val;
|
||||
cpu->getReg(renamedSrcIdx(idx), &val);
|
||||
return val;
|
||||
}
|
||||
|
||||
TheISA::VecPredRegContainer
|
||||
readVecPredRegOperand(const StaticInst *si, int idx) const override
|
||||
{
|
||||
TheISA::VecPredRegContainer val;
|
||||
cpu->getReg(renamedSrcIdx(idx), &val);
|
||||
return val;
|
||||
}
|
||||
|
||||
TheISA::VecPredRegContainer&
|
||||
getWritableVecPredRegOperand(const StaticInst *si, int idx) override
|
||||
{
|
||||
return *(TheISA::VecPredRegContainer *)cpu->getWritableReg(
|
||||
renamedDestIdx(idx));
|
||||
}
|
||||
|
||||
RegVal
|
||||
readCCRegOperand(const StaticInst *si, int idx) override
|
||||
{
|
||||
return cpu->getReg(renamedSrcIdx(idx));
|
||||
return cpu->getWritableReg(renamedDestIdx(idx));
|
||||
}
|
||||
|
||||
/** @todo: Make results into arrays so they can handle multiple dest
|
||||
* registers.
|
||||
*/
|
||||
void
|
||||
setIntRegOperand(const StaticInst *si, int idx, RegVal val) override
|
||||
setRegOperand(const StaticInst *si, int idx, RegVal val) override
|
||||
{
|
||||
cpu->setReg(renamedDestIdx(idx), val);
|
||||
setResult(val);
|
||||
}
|
||||
|
||||
void
|
||||
setFloatRegOperandBits(const StaticInst *si, int idx, RegVal val) override
|
||||
setRegOperand(const StaticInst *si, int idx, const void *val) override
|
||||
{
|
||||
cpu->setReg(renamedDestIdx(idx), val);
|
||||
setResult(val);
|
||||
}
|
||||
|
||||
void
|
||||
setVecRegOperand(const StaticInst *si, int idx,
|
||||
const TheISA::VecRegContainer& val) override
|
||||
{
|
||||
cpu->setReg(renamedDestIdx(idx), &val);
|
||||
setResult(val);
|
||||
}
|
||||
|
||||
void
|
||||
setVecElemOperand(const StaticInst *si, int idx, RegVal val) override
|
||||
{
|
||||
cpu->setReg(renamedDestIdx(idx), &val);
|
||||
setResult(val);
|
||||
}
|
||||
|
||||
void
|
||||
setVecPredRegOperand(const StaticInst *si, int idx,
|
||||
const TheISA::VecPredRegContainer& val) override
|
||||
{
|
||||
cpu->setReg(renamedDestIdx(idx), &val);
|
||||
setResult(val);
|
||||
}
|
||||
|
||||
void
|
||||
setCCRegOperand(const StaticInst *si, int idx, RegVal val) override
|
||||
{
|
||||
cpu->setReg(renamedDestIdx(idx), val);
|
||||
setResult(val);
|
||||
//TODO setResult
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -288,143 +288,126 @@ class SimpleExecContext : public ExecContext
|
||||
lastDcacheStall(0), execContextStats(cpu, thread)
|
||||
{ }
|
||||
|
||||
/** Reads an integer register. */
|
||||
RegVal
|
||||
readIntRegOperand(const StaticInst *si, int idx) override
|
||||
getRegOperand(const StaticInst *si, int idx) override
|
||||
{
|
||||
execContextStats.numIntRegReads++;
|
||||
const RegId& reg = si->srcRegIdx(idx);
|
||||
assert(reg.is(IntRegClass));
|
||||
return thread->readIntReg(reg.index());
|
||||
}
|
||||
|
||||
/** Sets an integer register to a value. */
|
||||
void
|
||||
setIntRegOperand(const StaticInst *si, int idx, RegVal val) override
|
||||
{
|
||||
execContextStats.numIntRegWrites++;
|
||||
const RegId& reg = si->destRegIdx(idx);
|
||||
assert(reg.is(IntRegClass));
|
||||
thread->setIntReg(reg.index(), val);
|
||||
}
|
||||
|
||||
/** Reads a floating point register in its binary format, instead
|
||||
* of by value. */
|
||||
RegVal
|
||||
readFloatRegOperandBits(const StaticInst *si, int idx) override
|
||||
{
|
||||
execContextStats.numFpRegReads++;
|
||||
const RegId& reg = si->srcRegIdx(idx);
|
||||
assert(reg.is(FloatRegClass));
|
||||
return thread->readFloatReg(reg.index());
|
||||
}
|
||||
|
||||
/** Sets the bits of a floating point register of single width
|
||||
* to a binary value. */
|
||||
void
|
||||
setFloatRegOperandBits(const StaticInst *si, int idx, RegVal val) override
|
||||
{
|
||||
execContextStats.numFpRegWrites++;
|
||||
const RegId& reg = si->destRegIdx(idx);
|
||||
assert(reg.is(FloatRegClass));
|
||||
thread->setFloatReg(reg.index(), val);
|
||||
}
|
||||
|
||||
/** Reads a vector register. */
|
||||
TheISA::VecRegContainer
|
||||
readVecRegOperand(const StaticInst *si, int idx) const override
|
||||
{
|
||||
execContextStats.numVecRegReads++;
|
||||
const RegId& reg = si->srcRegIdx(idx);
|
||||
assert(reg.is(VecRegClass));
|
||||
return thread->readVecReg(reg);
|
||||
}
|
||||
|
||||
/** Reads a vector register for modification. */
|
||||
TheISA::VecRegContainer &
|
||||
getWritableVecRegOperand(const StaticInst *si, int idx) override
|
||||
{
|
||||
execContextStats.numVecRegWrites++;
|
||||
const RegId& reg = si->destRegIdx(idx);
|
||||
assert(reg.is(VecRegClass));
|
||||
return thread->getWritableVecReg(reg);
|
||||
}
|
||||
|
||||
/** Sets a vector register to a value. */
|
||||
void
|
||||
setVecRegOperand(const StaticInst *si, int idx,
|
||||
const TheISA::VecRegContainer& val) override
|
||||
{
|
||||
execContextStats.numVecRegWrites++;
|
||||
const RegId& reg = si->destRegIdx(idx);
|
||||
assert(reg.is(VecRegClass));
|
||||
thread->setVecReg(reg, val);
|
||||
}
|
||||
|
||||
/** Reads an element of a vector register. */
|
||||
RegVal
|
||||
readVecElemOperand(const StaticInst *si, int idx) const override
|
||||
{
|
||||
execContextStats.numVecRegReads++;
|
||||
const RegId& reg = si->srcRegIdx(idx);
|
||||
assert(reg.is(VecElemClass));
|
||||
return thread->readVecElem(reg);
|
||||
}
|
||||
|
||||
/** Sets an element of a vector register to a value. */
|
||||
void
|
||||
setVecElemOperand(const StaticInst *si, int idx, RegVal val) override
|
||||
{
|
||||
execContextStats.numVecRegWrites++;
|
||||
const RegId& reg = si->destRegIdx(idx);
|
||||
assert(reg.is(VecElemClass));
|
||||
thread->setVecElem(reg, val);
|
||||
}
|
||||
|
||||
TheISA::VecPredRegContainer
|
||||
readVecPredRegOperand(const StaticInst *si, int idx) const override
|
||||
{
|
||||
execContextStats.numVecPredRegReads++;
|
||||
const RegId& reg = si->srcRegIdx(idx);
|
||||
assert(reg.is(VecPredRegClass));
|
||||
return thread->readVecPredReg(reg);
|
||||
}
|
||||
|
||||
TheISA::VecPredRegContainer&
|
||||
getWritableVecPredRegOperand(const StaticInst *si, int idx) override
|
||||
{
|
||||
execContextStats.numVecPredRegWrites++;
|
||||
const RegId& reg = si->destRegIdx(idx);
|
||||
assert(reg.is(VecPredRegClass));
|
||||
return thread->getWritableVecPredReg(reg);
|
||||
const RegId ® = si->srcRegIdx(idx);
|
||||
const RegClassType type = reg.classValue();
|
||||
switch (type) {
|
||||
case IntRegClass:
|
||||
execContextStats.numIntRegReads++;
|
||||
break;
|
||||
case FloatRegClass:
|
||||
execContextStats.numFpRegReads++;
|
||||
break;
|
||||
case CCRegClass:
|
||||
execContextStats.numCCRegReads++;
|
||||
break;
|
||||
case VecElemClass:
|
||||
execContextStats.numVecRegReads++;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return thread->getReg(reg);
|
||||
}
|
||||
|
||||
void
|
||||
setVecPredRegOperand(const StaticInst *si, int idx,
|
||||
const TheISA::VecPredRegContainer& val) override
|
||||
getRegOperand(const StaticInst *si, int idx, void *val) override
|
||||
{
|
||||
execContextStats.numVecPredRegWrites++;
|
||||
const RegId& reg = si->destRegIdx(idx);
|
||||
assert(reg.is(VecPredRegClass));
|
||||
thread->setVecPredReg(reg, val);
|
||||
const RegId ® = si->srcRegIdx(idx);
|
||||
const RegClassType type = reg.classValue();
|
||||
switch (type) {
|
||||
case IntRegClass:
|
||||
execContextStats.numIntRegReads++;
|
||||
break;
|
||||
case FloatRegClass:
|
||||
execContextStats.numFpRegReads++;
|
||||
break;
|
||||
case VecRegClass:
|
||||
case VecElemClass:
|
||||
execContextStats.numVecRegReads++;
|
||||
break;
|
||||
case VecPredRegClass:
|
||||
execContextStats.numVecPredRegReads++;
|
||||
break;
|
||||
case CCRegClass:
|
||||
execContextStats.numCCRegReads++;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
thread->getReg(reg, val);
|
||||
}
|
||||
|
||||
RegVal
|
||||
readCCRegOperand(const StaticInst *si, int idx) override
|
||||
void *
|
||||
getWritableRegOperand(const StaticInst *si, int idx) override
|
||||
{
|
||||
execContextStats.numCCRegReads++;
|
||||
const RegId& reg = si->srcRegIdx(idx);
|
||||
assert(reg.is(CCRegClass));
|
||||
return thread->readCCReg(reg.index());
|
||||
const RegId ® = si->destRegIdx(idx);
|
||||
const RegClassType type = reg.classValue();
|
||||
switch (type) {
|
||||
case VecRegClass:
|
||||
execContextStats.numVecRegWrites++;
|
||||
break;
|
||||
case VecPredRegClass:
|
||||
execContextStats.numVecPredRegWrites++;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return thread->getWritableReg(reg);
|
||||
}
|
||||
|
||||
void
|
||||
setCCRegOperand(const StaticInst *si, int idx, RegVal val) override
|
||||
setRegOperand(const StaticInst *si, int idx, RegVal val) override
|
||||
{
|
||||
execContextStats.numCCRegWrites++;
|
||||
const RegId& reg = si->destRegIdx(idx);
|
||||
assert(reg.is(CCRegClass));
|
||||
thread->setCCReg(reg.index(), val);
|
||||
const RegId ® = si->destRegIdx(idx);
|
||||
const RegClassType type = reg.classValue();
|
||||
switch (type) {
|
||||
case IntRegClass:
|
||||
execContextStats.numIntRegWrites++;
|
||||
break;
|
||||
case FloatRegClass:
|
||||
execContextStats.numFpRegWrites++;
|
||||
break;
|
||||
case CCRegClass:
|
||||
execContextStats.numCCRegWrites++;
|
||||
break;
|
||||
case VecElemClass:
|
||||
execContextStats.numVecRegWrites++;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
thread->setReg(reg, val);
|
||||
}
|
||||
|
||||
void
|
||||
setRegOperand(const StaticInst *si, int idx, const void *val) override
|
||||
{
|
||||
const RegId ® = si->destRegIdx(idx);
|
||||
const RegClassType type = reg.classValue();
|
||||
switch (type) {
|
||||
case IntRegClass:
|
||||
execContextStats.numIntRegWrites++;
|
||||
break;
|
||||
case FloatRegClass:
|
||||
execContextStats.numFpRegWrites++;
|
||||
break;
|
||||
case VecRegClass:
|
||||
case VecElemClass:
|
||||
execContextStats.numVecRegWrites++;
|
||||
break;
|
||||
case VecPredRegClass:
|
||||
execContextStats.numVecPredRegWrites++;
|
||||
break;
|
||||
case CCRegClass:
|
||||
execContextStats.numCCRegWrites++;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
thread->setReg(reg, val);
|
||||
}
|
||||
|
||||
RegVal
|
||||
|
||||
Reference in New Issue
Block a user